/** * Licensed to JumpMind Inc under one or more contributor * license agreements. See the NOTICE file distributed * with this work for additional information regarding * copyright ownership. JumpMind Inc licenses this file * to you under the GNU General Public License, version 3.0 (GPLv3) * (the "License"); you may not use this file except in compliance * with the License. * * You should have received a copy of the GNU General Public License, * version 3.0 (GPLv3) along with this library; if not, see * <http://www.gnu.org/licenses/>. * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jumpmind.symmetric.io.data.transform; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.jumpmind.db.model.Column; import org.jumpmind.db.model.Table; import org.jumpmind.symmetric.io.data.CsvData; import org.jumpmind.symmetric.io.data.DataEventType; import org.jumpmind.symmetric.io.data.transform.TransformColumn.IncludeOnType; public class TransformedData implements Cloneable { protected boolean generatedIdentityNeeded = false; protected DataEventType targetDmlType; protected DataEventType sourceDmlType; protected Map<TransformColumn.IncludeOnType, LinkedHashMap<String, String>> targetNewValueByIncludeOnType; protected Map<TransformColumn.IncludeOnType, LinkedHashMap<String, String>> targetNewKeysByIncludeOnType; protected Map<TransformColumn.IncludeOnType, LinkedHashMap<String, String>> targetOldValuesByIncludeOnType; protected TransformTable transformation; protected Map<String, String> sourceKeyValues; protected Map<String, String> oldSourceValues; protected Map<String, String> sourceValues; public TransformedData(TransformTable transformation, DataEventType sourceDmlType, Map<String, String> sourceKeyValues, Map<String, String> oldSourceValues, Map<String, String> sourceValues) { this.transformation = transformation; this.targetDmlType = sourceDmlType; this.sourceDmlType = sourceDmlType; this.sourceKeyValues = sourceKeyValues; this.oldSourceValues = oldSourceValues; this.sourceValues = sourceValues; } public String getFullyQualifiedTableName() { return transformation.getFullyQualifiedTargetTableName(); } public DataEventType getTargetDmlType() { return targetDmlType; } public void setTargetDmlType(DataEventType dmlType) { this.targetDmlType = dmlType; } public String getTableName() { return transformation.getTargetTableName(); } public String getCatalogName() { return transformation.getTargetCatalogName(); } public String getSchemaName() { return transformation.getTargetSchemaName(); } public void put(TransformColumn column, String columnValue, String oldValue, boolean recordAsKey) { if (recordAsKey) { if (targetNewKeysByIncludeOnType == null) { targetNewKeysByIncludeOnType = new HashMap<TransformColumn.IncludeOnType, LinkedHashMap<String, String>>( 2); } LinkedHashMap<String, String> keyValues = targetNewKeysByIncludeOnType.get(column.getIncludeOn()); if (keyValues == null) { keyValues = new LinkedHashMap<String, String>(); targetNewKeysByIncludeOnType.put(column.getIncludeOn(), keyValues); } keyValues.put(column.getTargetColumnName(), oldValue != null ? oldValue : columnValue); } if (targetNewValueByIncludeOnType == null) { targetNewValueByIncludeOnType = new HashMap<TransformColumn.IncludeOnType, LinkedHashMap<String, String>>(2); } LinkedHashMap<String, String> columnValues = targetNewValueByIncludeOnType.get(column.getIncludeOn()); if (columnValues == null) { columnValues = new LinkedHashMap<String, String>(); targetNewValueByIncludeOnType.put(column.getIncludeOn(), columnValues); } columnValues.put(column.getTargetColumnName(), columnValue); if (targetOldValuesByIncludeOnType == null) { targetOldValuesByIncludeOnType = new HashMap<TransformColumn.IncludeOnType, LinkedHashMap<String, String>>(2); } LinkedHashMap<String, String> oldColumnValues = targetOldValuesByIncludeOnType.get(column.getIncludeOn()); if (oldColumnValues == null) { oldColumnValues = new LinkedHashMap<String, String>(); targetOldValuesByIncludeOnType.put(column.getIncludeOn(), oldColumnValues); } oldColumnValues.put(column.getTargetColumnName(), oldValue); } protected Map<String, String> retrieve( Map<TransformColumn.IncludeOnType, LinkedHashMap<String, String>> source) { Map<String, String> list = new LinkedHashMap<String, String>(source == null ? 0 : source.size()); if (source != null) { LinkedHashMap<String, String> values = source.get(IncludeOnType.ALL); if (values != null) { list.putAll(values); } IncludeOnType type = IncludeOnType.DELETE; if (targetDmlType == DataEventType.UPDATE && sourceDmlType != DataEventType.DELETE) { type = IncludeOnType.UPDATE; } else if (targetDmlType == DataEventType.INSERT) { type = IncludeOnType.INSERT; } values = source.get(type); if (values != null) { list.putAll(values); } } return list; } protected List<String> retrieve( Map<TransformColumn.IncludeOnType, LinkedHashMap<String, String>> source, boolean getColumnNames) { Map<String, String> values = retrieve(source); if (getColumnNames) { return new ArrayList<String>(values.keySet()); } else { return new ArrayList<String>(values.values()); } } public Map<String, String> getTargetKeyValues() { return retrieve(targetNewKeysByIncludeOnType); } public Map<String, String> getTargetValues() { return retrieve(targetNewValueByIncludeOnType); } public String[] getKeyNames() { List<String> list = retrieve(targetNewKeysByIncludeOnType, true); return list.toArray(new String[list.size()]); } public String[] getKeyValues() { List<String> list = retrieve(targetNewKeysByIncludeOnType, false); return list.toArray(new String[list.size()]); } public String[] getColumnNames() { List<String> list = retrieve(targetNewValueByIncludeOnType, true); return list.toArray(new String[list.size()]); } public String[] getColumnValues() { List<String> list = retrieve(targetNewValueByIncludeOnType, false); return list.toArray(new String[list.size()]); } public DataEventType getSourceDmlType() { return sourceDmlType; } public TransformedData copy() { try { TransformedData clone = (TransformedData) this.clone(); clone.targetNewValueByIncludeOnType = copy(targetNewValueByIncludeOnType); clone.targetNewKeysByIncludeOnType = copy(targetNewKeysByIncludeOnType); clone.targetOldValuesByIncludeOnType = copy(targetOldValuesByIncludeOnType); return clone; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } public TransformTable getTransformation() { return transformation; } public void setGeneratedIdentityNeeded(boolean generatedIdentityNeeded) { this.generatedIdentityNeeded = generatedIdentityNeeded; } public boolean isGeneratedIdentityNeeded() { return generatedIdentityNeeded; } protected Map<TransformColumn.IncludeOnType, LinkedHashMap<String, String>> copy( Map<TransformColumn.IncludeOnType, LinkedHashMap<String, String>> toCopy) { Map<TransformColumn.IncludeOnType, LinkedHashMap<String, String>> newMap = new HashMap<TransformColumn.IncludeOnType, LinkedHashMap<String, String>>( toCopy.size()); for (TransformColumn.IncludeOnType key : toCopy.keySet()) { LinkedHashMap<String, String> value = toCopy.get(key); newMap.put(key, new LinkedHashMap<String, String>(value)); } return newMap; } public Map<String, String> getSourceKeyValues() { return sourceKeyValues; } public Map<String, String> getOldSourceValues() { return oldSourceValues; } public Map<String, String> getSourceValues() { return sourceValues; } public boolean hasSameKeyValues(String[] otherKeyValues) { String[] keyValues = getKeyValues(); if (otherKeyValues != null) { if (keyValues != null) { if (keyValues.length != otherKeyValues.length) { return false; } for (int i = 0; i < otherKeyValues.length; i++) { if (!(keyValues[i] == null && otherKeyValues[i] == null) && ((keyValues[i] == null && otherKeyValues[i] != null) || (otherKeyValues[i] == null && keyValues[i] != null) || (!keyValues[i].equals(otherKeyValues[i])))) { return false; } } } else { return false; } } else if (keyValues != null) { return false; } return true; } public Table buildTargetTable() { Table table = null; String[] columnNames = getColumnNames(); String[] keyNames = getKeyNames(); if (columnNames != null && columnNames.length > 0) { table = new Table(transformation.getTargetCatalogName(), transformation.getTargetSchemaName(), transformation.getTargetTableName()); for (String colName : columnNames) { Column col = new Column(colName); table.addColumn(col); if (keyNames != null) { for (String keyName : keyNames) { if (keyName.equals(colName)) { col.setPrimaryKey(true); } } } } } return table; } public CsvData buildTargetCsvData() { CsvData data = new CsvData(this.targetDmlType); if (targetDmlType != DataEventType.DELETE) { data.putParsedData(CsvData.ROW_DATA, getColumnValues()); } if (targetDmlType == DataEventType.UPDATE || targetDmlType == DataEventType.DELETE) { data.putParsedData(CsvData.OLD_DATA, getOldColumnValues()); data.putParsedData(CsvData.PK_DATA, getKeyValues()); } data.putAttribute(getClass().getName(), this); return data; } public String[] getOldColumnValues() { List<String> list = retrieve(targetOldValuesByIncludeOnType, false); boolean use = false; for (String string : list) { use |= string != null; } if (use) { return list.toArray(new String[list.size()]); } else { return null; } } }