package com.revolsys.record.code; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.swing.JComponent; import com.revolsys.beans.Classes; import com.revolsys.collection.list.Lists; import com.revolsys.datatype.DataType; import com.revolsys.identifier.Identifier; import com.revolsys.record.schema.FieldDefinition; import com.revolsys.util.CompareUtil; import com.revolsys.util.Emptyable; import com.revolsys.util.Property; public interface CodeTable extends Emptyable, Cloneable, Comparator<Object> { @Override default int compare(final Object value1, final Object value2) { if (value1 == null) { if (value2 == null) { return 0; } else { return 1; } } else if (value2 == null) { return -1; } else { final Object codeValue1 = getValue(Identifier.newIdentifier(value1)); final Object codeValue2 = getValue(Identifier.newIdentifier(value2)); return CompareUtil.compare(codeValue1, codeValue2); } } Map<Identifier, List<Object>> getCodes(); default List<String> getFieldNameAliases() { return Collections.emptyList(); } default Identifier getIdentifier(final List<Object> values) { return getIdentifier(values, true); } default Identifier getIdentifier(final List<Object> values, final boolean loadMissing) { for (final Entry<Identifier, List<Object>> entry : getCodes().entrySet()) { if (DataType.equal(entry.getValue(), values)) { return entry.getKey(); } } return null; } default Identifier getIdentifier(final Map<String, ? extends Object> valueMap) { final List<String> valueFieldNames = getValueFieldNames(); final List<Object> values = new ArrayList<>(); for (final String name : valueFieldNames) { final Object value = valueMap.get(name); values.add(value); } return getIdentifier(values); } default Identifier getIdentifier(final Object... values) { final List<Object> valueList = Arrays.asList(values); return getIdentifier(valueList); } default List<Identifier> getIdentifiers() { final Map<Identifier, List<Object>> codes = getCodes(); final Set<Identifier> keySet = codes.keySet(); return Lists.toArray(keySet); } default Identifier getIdExact(final List<Object> values) { return getIdExact(values, true); } default Identifier getIdExact(final List<Object> values, final boolean loadValues) { return getIdentifier(values); } default Identifier getIdExact(final Object... values) { final List<Object> valueList = Arrays.asList(values); return getIdExact(valueList); } String getIdFieldName(); default <V> V getIdValue(final Object value) { if (value == null) { return null; } else { final Identifier identifier = getIdentifier(value); if (identifier == null) { return null; } else { return identifier.getValue(0); } } } default Map<String, ? extends Object> getMap(final Identifier id) { final List<Object> values = getValues(id); if (values == null) { return Collections.emptyMap(); } else { final Map<String, Object> map = new HashMap<>(); for (int i = 0; i < values.size(); i++) { final String name = getValueFieldNames().get(i); final Object value = values.get(i); map.put(name, value); } return map; } } default Map<String, ? extends Object> getMap(final Object id) { final Identifier identifier = Identifier.newIdentifier(id); return getMap(identifier); } default String getName() { return Classes.className(getClass()); } default JComponent getSwingEditor() { return null; } @SuppressWarnings("unchecked") default <V> V getValue(final Identifier id) { final List<Object> values = getValues(id); if (Property.hasValue(values)) { return (V)values.get(0); } else { return null; } } default <V> V getValue(final Object id) { final Identifier identifier = Identifier.newIdentifier(id); return getValue(identifier); } default FieldDefinition getValueFieldDefinition() { return null; } default List<String> getValueFieldNames() { return Arrays.asList("VALUE"); } default <V> List<V> getValues() { final List<V> values = new ArrayList<>(); for (final Identifier identifier : getIdentifiers()) { final V value = getValue(identifier); values.add(value); } return values; } default List<Object> getValues(final Identifier id) { if (id != null) { final Map<Identifier, List<Object>> codes = getCodes(); final List<Object> values = codes.get(id); if (values != null) { return Collections.unmodifiableList(values); } } return null; } default List<Object> getValues(final Object id) { final Identifier identifier = Identifier.newIdentifier(id); return getValues(identifier); } default boolean isLoaded() { return true; } default boolean isLoading() { return false; } default void refresh() { } default void refreshIfNeeded() { synchronized (this) { if (!isLoaded()) { refresh(); } } } }