/* * Copyright (c) 2013 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.io.csv.writer; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import eu.esdihumboldt.hale.common.align.extension.function.FunctionDefinition; import eu.esdihumboldt.hale.common.align.extension.function.FunctionUtil; import eu.esdihumboldt.hale.common.align.io.impl.AbstractAlignmentWriter; import eu.esdihumboldt.hale.common.align.model.AlignmentUtil; import eu.esdihumboldt.hale.common.align.model.Cell; import eu.esdihumboldt.hale.common.align.model.CellExplanation; import eu.esdihumboldt.hale.common.align.model.ChildContext; import eu.esdihumboldt.hale.common.align.model.Entity; import eu.esdihumboldt.hale.common.core.io.IOProviderConfigurationException; import eu.esdihumboldt.hale.common.core.io.ProgressIndicator; import eu.esdihumboldt.hale.common.core.io.report.IOReport; import eu.esdihumboldt.hale.common.core.io.report.IOReporter; import eu.esdihumboldt.hale.common.instance.extension.filter.FilterDefinitionManager; import eu.esdihumboldt.hale.common.instance.model.Filter; import eu.esdihumboldt.hale.common.schema.model.PropertyDefinition; /** * Wrapper for all information of the alignment (mapping) saved in a list of * maps <br> * * @author Patrick Lieb */ public abstract class AbstractAlignmentMappingExport extends AbstractAlignmentWriter implements MappingTableConstants { private Cell currentTypeCell; private boolean includeNamespaces = false; private boolean transformationAndDisabledMode = false; private List<CellType> cellTypes; /** * the default line break in a cell */ public final String DEFAULT_LINE_END = "\n"; private List<Map<CellType, CellInformation>> allRelations; /** * @see eu.esdihumboldt.hale.common.core.io.impl.AbstractIOProvider#execute(eu.esdihumboldt.hale.common.core.io.ProgressIndicator, * eu.esdihumboldt.hale.common.core.io.report.IOReporter) */ @Override protected IOReport execute(ProgressIndicator progress, IOReporter reporter) throws IOProviderConfigurationException, IOException { cellTypes = new ArrayList<CellType>(); includeNamespaces = getParameter(INCLUDE_NAMESPACES).as(Boolean.class); transformationAndDisabledMode = getParameter(TRANSFORMATION_AND_DISABLED_FOR).as( Boolean.class); // disable namespace and transformationAndDisable columns if necessary for (CellType type : CellType.values()) { if (includeNamespaces || !type.getName().equals(CellType.SOURCE_PROPERTIES_NAMESPACE.getName())) if (transformationAndDisabledMode || !type.getName().equals(CellType.TRANSFORMATION_AND_DISABLED.getName())) cellTypes.add(type); } return reporter; } /** * @return all available cell types */ public List<CellType> getCellTypes() { return cellTypes; } /** * Header for all columns in the Mapping file * * @return list with strings of header for all columns */ public List<String> getMappingHeader() { List<String> list = new ArrayList<String>(); for (CellType type : cellTypes) { list.add(type.getName()); } return list; } /** * Get all mappings. Each list entry represents one mapping. * * @return list of all mappings */ public List<Map<CellType, CellInformation>> getMappingList() { allRelations = new ArrayList<Map<CellType, CellInformation>>(); String mapping = getParameter(PARAMETER_MODE).as(String.class); boolean noBaseAlignments = mapping.equals(MODE_EXCLUDE_BASE); boolean propertyCells = mapping.equals(MODE_BY_TYPE_CELLS); if (propertyCells) { for (Cell typeCell : getAlignment().getTypeCells()) { addCellData(typeCell); for (Cell propertyCell : getAlignment().getPropertyCells(typeCell, true, false)) { addCellData(propertyCell); } } } else { for (Cell cell : getAlignment().getCells()) { if (!noBaseAlignments || !cell.isBaseCell()) { addCellData(cell); } } } return allRelations; } /** * @param mapping the relevant mapping of {@link #getMappingList()} * @param cellType the cell type * @return the string representation of the given mapping and cell type */ public String getCellValue(Map<CellType, CellInformation> mapping, CellType cellType) { StringBuilder result = new StringBuilder(); CellInformation cellInfo = mapping.get(cellType); List<String> text = cellInfo.getText(); List<Integer> positions = cellInfo.getPositions(); switch (cellType) { // same behavior of SOURCE_TYPE, SORUCE_PROPERTY_CONDITIONS and // TARGET_PROPERTIES case SOURCE_TYPE: case SOURCE_TYPE_NAMESPACE: case SOURCE_PROPERTY_CONDITIONS: case TARGET_TYPE: case TARGET_TYPE_NAMESPACE: case SOURCE_PROPERTIES_NAMESPACE: case TARGET_PROPERTIES_NAMESPACE: if (text.size() == 1) { result.append(text.get(0)); for (int position = 0; position < positions.get(0); position++) { result.append(DEFAULT_LINE_END); } } else { int position = 0; for (int i = 0; i < text.size(); i++) { String info = text.get(i); int currentPosition = positions.get(i); for (; position < currentPosition; position++) { result.append(DEFAULT_LINE_END); } result.append(info); } } break; // same behavior of SOURCE_TYPE_CONDITIONS, SOURCE_PROPERTIES and // TARGET_PROPERTIES case SOURCE_TYPE_CONDITIONS: case SOURCE_PROPERTIES: case TARGET_PROPERTIES: int lastPosition = -1; for (int i = 0; i < cellInfo.getText().size(); i++) { String info = text.get(i); int position = positions.get(i); if (position == 0) { result.append(info); } else { if (position == lastPosition + 1 && !info.isEmpty()) { // sub properties are signed with a point info = "." + info; } else if (position == lastPosition + 2) { info = DEFAULT_LINE_END + info; } result.append(DEFAULT_LINE_END); result.append(info); } lastPosition = position; } break; // same behavior of RELATION_NAME, CELL_EXPLANATION and CELL_NOTES case RELATION_NAME: case ID: case CELL_EXPLANATION: case CELL_NOTES: case BASE_CELL: case PRIORITY: case TRANSFORMATION_AND_DISABLED: // append all info to one string divided by line breaks for (int i = 0; i < text.size(); i++) { if (positions.get(i) == 0) { result.append(text.get(i)); } else { result.append(DEFAULT_LINE_END); result.append(text.get(i)); } } break; } return result.toString(); } // get the information of the cell and add them to the map private void addCellData(Cell cell) { Map<CellType, CellInformation> cellInfos = new HashMap<CellType, CellInformation>(); // create all entries List<CellType> cellTypes = getCellTypes(); for (int i = 0; i < cellTypes.size(); i++) { cellInfos.put(cellTypes.get(i), new CellInformation()); } cellInfos.get(CellType.ID).addText(cell.getId(), 0); if (cell.getSource() != null) { // save the hierarchy of the properties // all entries (in the same CellInfo) with the same hierarchy level // have to be shown on the same height int position = 0; for (Entity entity : cell.getSource().values()) { // column source type cellInfos.get(CellType.SOURCE_TYPE).addText( entity.getDefinition().getType().getName().getLocalPart(), position); if (includeNamespaces) // column source type namespace cellInfos.get(CellType.SOURCE_TYPE_NAMESPACE).addText( entity.getDefinition().getType().getName().getNamespaceURI(), position); // column source type conditions Filter entityFilter; if ((entityFilter = entity.getDefinition().getFilter()) != null) { cellInfos.get(CellType.SOURCE_TYPE_CONDITIONS).addText( FilterDefinitionManager.getInstance().asString(entityFilter), position); entity.getDefinition().getType().getName().getLocalPart(); } for (ChildContext childContext : entity.getDefinition().getPropertyPath()) { PropertyDefinition child = childContext.getChild().asProperty(); if (child != null) { // column source properties cellInfos.get(CellType.SOURCE_PROPERTIES).addText( child.getName().getLocalPart(), position); if (includeNamespaces) // column source properties namespace cellInfos.get(CellType.SOURCE_PROPERTIES_NAMESPACE).addText( child.getName().getNamespaceURI(), position); Filter contextFilter; if (childContext.getCondition() != null) { contextFilter = childContext.getCondition().getFilter(); // column source property conditions cellInfos.get(CellType.SOURCE_PROPERTY_CONDITIONS).addText( FilterDefinitionManager.getInstance().asString(contextFilter), position); } // add dummy to adapt position of source type and source // type conditions cellInfos.get(CellType.SOURCE_TYPE).addText("", position); cellInfos.get(CellType.SOURCE_TYPE_CONDITIONS).addText("", position); position++; } } // next entries must have higher position position++; } } if (cell.getTarget() != null) { int position = 0; for (Entity entity : cell.getTarget().values()) { // column target type cellInfos.get(CellType.TARGET_TYPE).addText( entity.getDefinition().getType().getDisplayName(), position); if (includeNamespaces) // column target type namespace cellInfos.get(CellType.TARGET_TYPE_NAMESPACE).addText( entity.getDefinition().getType().getName().getNamespaceURI(), position); for (ChildContext childContext : entity.getDefinition().getPropertyPath()) { PropertyDefinition child = childContext.getChild().asProperty(); if (child != null) { // column target properties cellInfos.get(CellType.TARGET_PROPERTIES).addText( child.getName().getLocalPart(), position); if (includeNamespaces) // column target properties namespace cellInfos.get(CellType.TARGET_PROPERTIES_NAMESPACE).addText( child.getName().getNamespaceURI(), position); // add dummy to adapt position of target type cellInfos.get(CellType.TARGET_TYPE).addText("", position); position++; } } position++; } } FunctionDefinition<?> function = FunctionUtil.getFunction( cell.getTransformationIdentifier(), getServiceProvider()); if (function != null) { // column relation name cellInfos.get(CellType.RELATION_NAME).addText(function.getDisplayName(), 0); // column cell explanation CellExplanation cellExpl = function.getExplanation(); if (cellExpl != null) { cellInfos.get(CellType.CELL_EXPLANATION).addText( function.getExplanation().getExplanation(cell, null), 0); } } // column cell notes List<String> docs = cell.getDocumentation().get(null); if (!docs.isEmpty()) { String notes = docs.get(0); if (notes != null && !notes.isEmpty()) { cellInfos.get(CellType.CELL_NOTES).addText(notes, 0); } } // cell priority cellInfos.get(CellType.PRIORITY).addText(cell.getPriority().value(), 0); // base cell if (cell.isBaseCell()) { cellInfos.get(CellType.BASE_CELL).addText("yes", 0); } else { cellInfos.get(CellType.BASE_CELL).addText("no", 0); } // column transformation/disabled if (transformationAndDisabledMode) { if (AlignmentUtil.isTypeCell(cell)) { currentTypeCell = cell; cellInfos.get(CellType.TRANSFORMATION_AND_DISABLED).addText( cell.getTransformationMode().displayName(), 0); } else { Set<String> disabledCells = cell.getDisabledFor(); if (disabledCells.contains(currentTypeCell.getId())) { for (String disCell : disabledCells) { cellInfos.get(CellType.TRANSFORMATION_AND_DISABLED).addText(disCell, 0); } } } } // add the row to the map allRelations.add(cellInfos); } /** * @return if the writer mode is configured to display the cells per type * cell */ protected boolean isByTypeCell() { String mode = getParameter(PARAMETER_MODE).as(String.class); return mode.equals(MODE_BY_TYPE_CELLS); } }