package com.revolsys.swing.map.layer.record; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.function.Predicate; import com.revolsys.datatype.DataType; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.io.PathName; import com.revolsys.predicate.Predicates; import com.revolsys.record.Record; import com.revolsys.record.RecordState; import com.revolsys.record.Records; import com.revolsys.record.query.Condition; import com.revolsys.record.query.Query; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.record.schema.RecordDefinitionImpl; import com.revolsys.swing.map.layer.record.table.RecordLayerTable; import com.revolsys.swing.map.layer.record.table.RecordLayerTablePanel; import com.revolsys.swing.map.layer.record.table.model.ListRecordLayerTableModel; import com.revolsys.swing.map.layer.record.table.model.RecordLayerErrors; public class ListRecordLayer extends AbstractRecordLayer { public static ListRecordLayer newLayer(final String name, final GeometryFactory geometryFactory, final DataType geometryType) { final RecordDefinitionImpl recordDefinition = newRecordDefinition(name, geometryFactory, geometryType); return new ListRecordLayer(recordDefinition); } public static RecordDefinitionImpl newRecordDefinition(final String name, final GeometryFactory geometryFactory, final DataType geometryType) { final RecordDefinitionImpl recordDefinition = new RecordDefinitionImpl( PathName.newPathName(name)); recordDefinition.addField("GEOMETRY", geometryType, true); recordDefinition.setGeometryFactory(geometryFactory); return recordDefinition; } private List<LayerRecord> records = new ArrayList<>(); public ListRecordLayer(final Map<String, ? extends Object> properties) { this("recordListLayer"); setProperties(properties); } public ListRecordLayer(final RecordDefinition recordDefinition) { this("listRecordLayer"); final String name = recordDefinition.getName(); setName(name); setRecordDefinition(recordDefinition); } protected ListRecordLayer(final String type) { super(type); setEditable(true); } protected void addRecord(final LayerRecord record) { synchronized (this.records) { this.records.add(record); expandBoundingBox(record); } addToIndex(record); fireEmpty(); fireRecordsChanged(); } protected void clearRecords() { this.clearSelectedRecords(); this.records.clear(); cleanCachedRecords(); fireEmpty(); } @Override public ListRecordLayer clone() { final ListRecordLayer clone = (ListRecordLayer)super.clone(); clone.records = new ArrayList<>(); return clone; } @Override protected void deleteRecordPost(final LayerRecord record) { super.deleteRecordPost(record); removeRecord(record); } @Override protected void deleteRecordsPost(final List<LayerRecord> recordsDeleted, final List<LayerRecord> recordsSelected) { removeFromIndex(recordsDeleted); for (final LayerRecord record : recordsDeleted) { removeRecord(record); } refreshBoundingBox(); fireRecordsChanged(); fireEmpty(); super.deleteRecordsPost(recordsDeleted, recordsSelected); saveChanges(recordsDeleted); } protected void expandBoundingBox(final LayerRecord record) { if (record != null) { BoundingBox boundingBox = getBoundingBox(); if (boundingBox.isEmpty()) { boundingBox = Records.boundingBox(record); } else { boundingBox = boundingBox.expandToInclude(record); } setBoundingBox(boundingBox); } } public void fireEmpty() { final boolean empty = isEmpty(); firePropertyChange("empty", !empty, empty); } @Override public void fireRecordsChanged() { super.fireRecordsChanged(); fireEmpty(); } @Override protected void forEachRecordInternal(final Query query, final Consumer<? super LayerRecord> consumer) { final List<LayerRecord> records = getRecordsPersisted(query); records.forEach(consumer); } @Override public LayerRecord getRecord(final int index) { if (index >= 0) { synchronized (this.records) { if (index < this.records.size()) { return this.records.get(index); } } } return null; } @Override public int getRecordCount(final Query query) { synchronized (this.records) { final Predicate<Record> filter = query.getWhereCondition(); return Predicates.count(this.records, filter); } } @Override public int getRecordCountDeleted() { return 0; } @Override public int getRecordCountModified() { return 0; } @Override public int getRecordCountNew() { return 0; } @Override public int getRecordCountPersisted() { return this.records.size(); } @Override public int getRecordCountPersisted(final Query query) { final Condition filter = query.getWhereCondition(); return Predicates.count(this.records, filter); } @Override public List<LayerRecord> getRecords() { synchronized (this.records) { return new ArrayList<>(this.records); } } @Override public List<LayerRecord> getRecordsPersisted(final Query query) { final List<LayerRecord> records = getRecords(); final Condition filter = query.getWhereCondition(); final Map<String, Boolean> orderBy = query.getOrderBy(); Records.filterAndSort(records, filter, orderBy); return records; } public boolean isEmpty() { return this.records.isEmpty(); } @Override public LayerRecord newLayerRecord(final Map<String, ? extends Object> values) { final LayerRecord record = super.newLayerRecord(values); addRecord(record); return record; } protected void newRecordInternal(final Map<String, Object> values) { final LayerRecord record = newLayerRecord(getRecordDefinition()); record.setState(RecordState.INITIALIZING); try { record.setValues(values); } finally { record.setState(RecordState.PERSISTED); } addRecord(record); } @Override public RecordLayerTablePanel newTablePanel(final Map<String, Object> config) { final RecordLayerTable table = ListRecordLayerTableModel.newTable(this); return new RecordLayerTablePanel(this, table, config); } protected void refreshBoundingBox() { final GeometryFactory geometryFactory = getGeometryFactory(); if (geometryFactory != null) { BoundingBox boundingBox = geometryFactory.newBoundingBoxEmpty(); for (final LayerRecord record : getRecords()) { boundingBox = boundingBox.expandToInclude(record); } setBoundingBox(boundingBox); } } @Override protected void refreshDo() { super.refreshDo(); setIndexRecords(getRecords()); } protected void removeRecord(final LayerRecord record) { removeFromIndex(record); synchronized (this.records) { record.removeFrom(this.records); } } @Override protected boolean saveChangesDo(final RecordLayerErrors errors, final LayerRecord record) { if (record.isDeleted()) { return true; } else { return super.saveChangesDo(errors, record); } } }