/* * Copyright (c) 2011. iCarto * * This file is part of extNavTableForms * * extNavTableForms is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Foundation, either * version 3 of the License, or any later version. * * extNavTableForms is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with extNavTableForms. * If not, see <http://www.gnu.org/licenses/>. */ package es.udc.cartolab.gvsig.navtable.dataacces; import java.text.ParseException; import java.util.HashMap; import java.util.Set; import com.hardcode.gdbms.driver.exceptions.InitializeWriterException; import com.hardcode.gdbms.driver.exceptions.ReadDriverException; import com.hardcode.gdbms.engine.values.Value; import com.iver.cit.gvsig.exceptions.visitors.StartWriterVisitorException; import com.iver.cit.gvsig.exceptions.visitors.StopWriterVisitorException; import com.iver.cit.gvsig.fmap.core.DefaultRow; import com.iver.cit.gvsig.fmap.core.IRow; import com.iver.cit.gvsig.fmap.drivers.ITableDefinition; import com.iver.cit.gvsig.fmap.edition.EditionEvent; import com.iver.cit.gvsig.fmap.edition.IEditableSource; import com.iver.cit.gvsig.fmap.edition.IWriteable; import com.iver.cit.gvsig.fmap.edition.IWriter; import com.iver.cit.gvsig.fmap.layers.SelectableDataSource; import es.udc.cartolab.gvsig.navtable.AbstractNavTable; import es.udc.cartolab.gvsig.navtable.ToggleEditing; import es.udc.cartolab.gvsig.navtable.format.ValueFactoryNT; import es.udc.cartolab.gvsig.navtable.format.ValueFormatNT; /** * Class to manage CRUD (Create, Read, Update, Delete) operations on a Table. * * @author Andr�s Maneiro <amaneiro@icarto.es> * @author @author Francisco Puga <fpuga@cartolab.es> * */ public class TableController implements IController { public static int NO_ROW = -1; private IEditableSource model; private HashMap<String, Integer> indexes; private HashMap<String, Integer> types; private HashMap<String, String> values; private HashMap<String, String> valuesChanged; public TableController(IEditableSource model) { this.model = model; this.indexes = new HashMap<String, Integer>(); this.types = new HashMap<String, Integer>(); this.values = new HashMap<String, String>(); this.valuesChanged = new HashMap<String, String>(); } public void initMetadata() { try { SelectableDataSource sds = model.getRecordset(); for (int i = 0; i < sds.getFieldCount(); i++) { String name = sds.getFieldName(i); indexes.put(name, i); types.put(name, sds.getFieldType(i)); } } catch (ReadDriverException e) { e.printStackTrace(); clearAll(); } } public long create(HashMap<String, String> newValues) throws Exception { initMetadata(); Value[] vals = createValuesFromHashMap(newValues); ToggleEditing te = new ToggleEditing(); if (!model.isEditing()) { te.startEditing(model); } long newPosition = NO_ROW; if (model instanceof IWriteable) { IRow row = new DefaultRow(vals); newPosition = model.doAddRow(row, EditionEvent.ALPHANUMERIC); } te.stopEditing(model); read(newPosition); return newPosition; } private Value[] createValuesFromHashMap(HashMap<String, String> newValues) { Value[] vals = new Value[indexes.size()]; for (int i = 0; i < indexes.size(); i++) { vals[i] = ValueFactoryNT.createNullValue(); } for (String key : newValues.keySet()) { try { vals[getIndex(key)] = ValueFactoryNT.createValueByType( newValues.get(key), types.get(key)); } catch (ParseException e) { vals[getIndex(key)] = ValueFactoryNT.createNullValue(); } } return vals; } @Override public void read(long position) throws ReadDriverException { SelectableDataSource sds = model.getRecordset(); clearAll(); if (position != AbstractNavTable.EMPTY_REGISTER) { for (int i = 0; i < sds.getFieldCount(); i++) { String name = sds.getFieldName(i); indexes.put(name, i); types.put(name, sds.getFieldType(i)); values.put( name, sds.getFieldValue(position, i).getStringValue( new ValueFormatNT())); } } } @Override public void update(long position) throws ReadDriverException { ToggleEditing te = new ToggleEditing(); boolean wasEditing = model.isEditing(); if (!wasEditing) { te.startEditing(model); } te.modifyValues(model, (int) position, getIndexesOfValuesChanged(), getValuesChanged().values().toArray(new String[0])); if (!wasEditing) { te.stopEditing(model); } read((int) position); } @Override public void delete(long position) throws StopWriterVisitorException, InitializeWriterException, StartWriterVisitorException, ReadDriverException { model.startEdition(EditionEvent.ALPHANUMERIC); IWriteable w = (IWriteable) model; IWriter writer = w.getWriter(); ITableDefinition tableDef = model.getTableDefinition(); writer.initialize(tableDef); model.doRemoveRow((int) position, EditionEvent.ALPHANUMERIC); model.stopEdition(writer, EditionEvent.ALPHANUMERIC); model.getRecordset().reload(); clearAll(); } @Override public void clearAll() { indexes.clear(); types.clear(); values.clear(); valuesChanged.clear(); } @Override public int getIndex(String fieldName) { return indexes.get(fieldName); } @Override public int[] getIndexesOfValuesChanged() { int[] idxs = new int[valuesChanged.size()]; Set<String> names = valuesChanged.keySet(); int i = 0; for (String name : names) { idxs[i] = indexes.get(name); i++; } return idxs; } @Override public String getValue(String fieldName) { if (valuesChanged.containsKey(fieldName)) { return valuesChanged.get(fieldName); } return values.get(fieldName); } @Override public String getValueInLayer(String fieldName) { return values.get(fieldName); } @Override public HashMap<String, String> getValues() { HashMap<String, String> val = values; for (String k : valuesChanged.keySet()) { val.put(k, valuesChanged.get(k)); } return val; } @Override public HashMap<String, String> getValuesOriginal() { return values; } @Override public HashMap<String, String> getValuesChanged() { return valuesChanged; } @Override public void setValue(String fieldName, String value) { valuesChanged.put(fieldName, value); } @Override public int getType(String fieldName) { return types.get(fieldName); } @Override public long getRowCount() throws ReadDriverException { return model.getRowCount(); } @Override public TableController clone() { return new TableController(model); } }