/******************************************************************************* * Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com) * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v3 * which accompanies this distribution, and is available at http://www.gnu.org/licenses/lgpl.txt ******************************************************************************/ package com.opendoorlogistics.core.scripts.elements; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import com.opendoorlogistics.api.components.PredefinedTags; import com.opendoorlogistics.api.scripts.ScriptAdapter; import com.opendoorlogistics.api.scripts.ScriptAdapter.*; import com.opendoorlogistics.api.tables.HasFlags; import com.opendoorlogistics.api.tables.ODLDatastore; import com.opendoorlogistics.api.tables.ODLDatastoreAlterable; import com.opendoorlogistics.api.tables.ODLTableDefinition; import com.opendoorlogistics.api.tables.ODLTableDefinitionAlterable; import com.opendoorlogistics.api.tables.TableFlags; import com.opendoorlogistics.core.gis.map.data.DrawableObjectImpl; import com.opendoorlogistics.core.tables.memory.ODLDatastoreImpl; import com.opendoorlogistics.core.tables.memory.ODLTableImpl; import com.opendoorlogistics.core.tables.utils.DatastoreCopier; import com.opendoorlogistics.core.tables.utils.TableUtils; import com.opendoorlogistics.core.utils.JAXBUtils; import com.opendoorlogistics.core.utils.strings.HasStringId; import com.opendoorlogistics.core.utils.strings.Strings; @XmlRootElement(name = "Adapter") final public class AdapterConfig extends ScriptBaseElementImpl implements HasStringId, Serializable, Iterable<AdaptedTableConfig>, HasFlags { private String id; private List<AdaptedTableConfig> tables = new ArrayList<>(); private long flags; private ScriptAdapterType adapterType = ScriptAdapterType.NORMAL; public List<AdaptedTableConfig> getTables() { return tables; } @XmlElement(name = "AdaptedTable") public void setTables(List<AdaptedTableConfig> tables) { this.tables = tables; } public AdaptedTableConfig createTable(String from, String to) { AdaptedTableConfig ret = new AdaptedTableConfig(); ret.setFromTable(from); ret.setName(to); tables.add(ret); return ret; } public int getTableCount() { return tables.size(); } public AdaptedTableConfig getTable(int i) { return getTables().get(i); } @Override public String getId() { return id; } @XmlAttribute public void setId(String id) { this.id = id; } public AdapterConfig(String id) { this.id = id; } public AdapterConfig(String id, AdaptedTableConfig... tables) { this.id = id; getTables().addAll(Arrays.asList(tables)); } public AdapterConfig deepCopy() { AdapterConfig ret = new AdapterConfig(id); for (AdaptedTableConfig table : getTables()) { ret.getTables().add(table.deepCopy()); } ret.adapterType = adapterType; return ret; } public AdapterConfig(Collection<AdaptedTableConfig> tables) { getTables().addAll(tables); } public AdapterConfig() { } /** * Create the datastore definition output from this adapter. Group-by column flags are removed from this definition. * * @return */ public ODLDatastoreAlterable<ODLTableDefinitionAlterable> createOutputDefinition() { if (adapterType == ScriptAdapterType.VLS) { // VLS adapters output drawables ODLDatastoreImpl<ODLTableDefinitionAlterable> ret = new ODLDatastoreImpl<>(ODLTableImpl.ODLTableDefinitionAlterableFactory); DatastoreCopier.copyTableDefinitions(DrawableObjectImpl.ACTIVE_BACKGROUND_FOREGROUND_IMAGE_DS, ret); return ret; } else { return createNormalOutputDefinition(); } } /** * Create the output definition assuming the adaptertype is normal * @return */ public ODLDatastoreAlterable<ODLTableDefinitionAlterable> createNormalOutputDefinition() { ODLDatastoreImpl<ODLTableDefinitionAlterable> ret = new ODLDatastoreImpl<>(ODLTableImpl.ODLTableDefinitionAlterableFactory); for (AdaptedTableConfig atc : getTables()) { if (Strings.isEmpty(atc.getName())) { continue; } ODLTableDefinitionAlterable table = TableUtils.findTable(ret, atc.getName()); if (table == null) { ret.createTable(atc.getName(), -1); table = ret.getTableAt(ret.getTableCount() - 1); atc.createOutputDefinition(table); } else { // doing a union, so merging several table adapter configs int nc = atc.getColumnCount(); for (int col = 0; col < nc; col++) { if (TableUtils.findColumnIndx(table, atc.getColumnName(col)) == -1) { // column doesn't exist yet; add it DatastoreCopier.copyColumnDefinition(atc, table, col, false); } } } } // remove group-by flags int nt = ret.getTableCount(); for (int i = 0; i < nt; i++) { ODLTableDefinitionAlterable table = ret.getTableAt(i); int nc = table.getColumnCount(); for (int j = 0; j < nc; j++) { long flags = table.getColumnFlags(j); flags = flags & (~TableFlags.FLAG_IS_GROUP_BY_FIELD); table.setColumnFlags(j, flags); } } return ret; } /** * Create an adapter which assumes same table and field names (but potentially different ordering) * * @param ds * @return */ public static AdapterConfig createSameNameMapper(ODLDatastore<? extends ODLTableDefinition> ds) { AdapterConfig ret = new AdapterConfig(); for (int i = 0; i < ds.getTableCount(); i++) { ODLTableDefinition dfn = ds.getTableAt(i); addSameNameTable(dfn, ret); } return ret; } public static AdaptedTableConfig createSameNameMapper(ODLTableDefinition table) { AdapterConfig ret = new AdapterConfig(); addSameNameTable(table, ret); return ret.getTables().get(0); } public static void addSameNameTable(ODLTableDefinition dfn, AdapterConfig ret) { AdaptedTableConfig tc = ret.createTable(dfn.getName(), dfn.getName()); tc.setFlags(dfn.getFlags()); int nf = dfn.getColumnCount(); for (int j = 0; j < nf; j++) { tc.addMappedColumn(dfn.getColumnName(j), dfn.getColumnName(j), dfn.getColumnType(j), dfn.getColumnFlags(j)); } } @Override public String toString() { return JAXBUtils.toXMLString(this); } @Override public String getShortDescription() { // return id; StringBuilder ret = new StringBuilder(); ret.append("Adapter '" + getId() + "'"); if (getTables().size() > 0) { ret.append(", tables "); for (int i = 0; i < getTables().size(); i++) { if (i > 0) { ret.append(", "); } ret.append("'" + getTables().get(i).getTableDescription(false) + "'"); } } return ret.toString(); } @Override public Iterator<AdaptedTableConfig> iterator() { return getTables().iterator(); } @Override public long getFlags() { return flags; } @XmlAttribute public void setFlags(long flags) { this.flags = flags; } public ScriptAdapterType getAdapterType() { return adapterType; } public void setAdapterType(ScriptAdapterType adapterType) { this.adapterType = adapterType; } // public boolean isUpdateAdapter() { // return isUpdateAdapter; // } // // @XmlAttribute // public void setUpdateAdapter(boolean isUpdateAdapter) { // this.isUpdateAdapter = isUpdateAdapter; // } }