/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.component.integration.cpacs; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; import javax.xml.xpath.XPathExpressionException; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; import de.rcenvironment.core.component.api.ComponentConstants; import de.rcenvironment.core.component.api.ComponentException; import de.rcenvironment.core.component.datamanagement.api.ComponentDataManagementService; import de.rcenvironment.core.component.integration.CommonToolIntegratorComponent; import de.rcenvironment.core.component.integration.ToolIntegrationConstants; import de.rcenvironment.core.component.xml.api.EndpointXMLService; import de.rcenvironment.core.datamodel.api.DataType; import de.rcenvironment.core.datamodel.api.DataTypeException; import de.rcenvironment.core.datamodel.api.TypedDatum; import de.rcenvironment.core.datamodel.api.TypedDatumFactory; import de.rcenvironment.core.datamodel.api.TypedDatumService; import de.rcenvironment.core.datamodel.types.api.DirectoryReferenceTD; import de.rcenvironment.core.datamodel.types.api.FileReferenceTD; import de.rcenvironment.core.datamodel.types.api.NotAValueTD.Cause; import de.rcenvironment.core.scripting.ScriptingService; import de.rcenvironment.core.utils.common.LogUtils; import de.rcenvironment.core.utils.common.StringUtils; import de.rcenvironment.core.utils.common.TempFileServiceAccess; import de.rcenvironment.core.utils.common.xml.XMLException; import de.rcenvironment.core.utils.common.xml.XSLTErrorHandler; import de.rcenvironment.core.utils.common.xml.api.XMLMapperService; import de.rcenvironment.core.utils.common.xml.api.XMLSupportService; import de.rcenvironment.toolkit.utils.text.AbstractTextLinesReceiver; /** * Main class for the CPACS tool integration. * * @author Jan Flink * @author Doreen Seider (logging) */ public class CpacsToolIntegratorComponent extends CommonToolIntegratorComponent { private static final Log LOG = LogFactory.getLog(CpacsToolIntegratorComponent.class); private static final String FILE_SUFFIX_MAPPED = "-mapped"; private static final String STRING_CPACS_RESULT_FILE_CREATED = "CPACS result file created (%s)): %s"; private static final String STRING_TOOL_OUTPUT_FILE_EXISTS = "Tool output file '%s' exists: %s"; private static final String SUFFIX_MAPPED = "-mapped"; private static final String STRING_NOT_AVAILABLE_IN_WDB = "; it is not available in the workflow data browser"; private static final String STRING_TOOL_INPUT_FILE_NOT_FOUND = "Tool input file '%s' not found"; private static final String STRING_XML_ERROR_DURING_MAPPING = "Failed to perform %s mapping"; private static final String STRING_TOOL_INPUT_CREATED = "Tool input file created (%s)): %s"; private static final String STRING_MAPPING_USAGE = "Using %s %s mapping..."; private static final String STRING_MAPPING_TYPE_XML = "pairing"; private static final String STRING_MAPPING_TYPE_XSL = "raw XSLT"; private static final String STRING_TOOL_MAPPING_DIRECTION_INPUT = "tool input"; private static final String STRING_MAPPING_DIRECTION_INPUT = "input"; private static final String STRING_TOOL_MAPPING_DIRECTION_OUTPUT = "tool output"; private static final String STRING_MAPPING_DIRECTION_OUTPUT = "output"; private static final String STRING_MAPPING_DIRECTION_TOOLSPECIFIC = "tool specific input"; private static final String STRING_MAPPING_FILE_NOT_FOUND = "Mapping file '%s' not found"; private static final String STRING_ERROR_SOLVING_FILE_EXTENSION = "Failed to resolve file extension of mapping file '%s'"; private static final String CREATE_MAPPING_XSLT_FILEPATH = "/resources/CreateMapping.xslt"; private static final String XMLFILE_SEPARATOR = "/"; /** * Implementation of TextLinesReceiver for CpacsToolIntegratorComponent. * * @author Brigitte Boden */ private final class CpacsToolIntegratorTextLinesReceiver extends AbstractTextLinesReceiver { @Override public void addLine(String line) { componentContext.getLog().componentInfo(line); } } private XMLMapperService xmlMapper; private XMLSupportService xmlSupport; private EndpointXMLService dynamicEndpointMapper; private File lastRunToolinputFile; private File tmpOutputFile; public CpacsToolIntegratorComponent() { super(); } @Override public void start() throws ComponentException { dynamicEndpointMapper = componentContext.getService(EndpointXMLService.class); xmlMapper = componentContext.getService(XMLMapperService.class); xmlSupport = componentContext.getService(XMLSupportService.class); super.start(); lastRunToolinputFile = null; } @Override protected void beforePreScriptExecution(Map<String, TypedDatum> inputValues, Map<String, String> inputNamesToLocalFile) throws ComponentException { Map<String, TypedDatum> dynamicInputs = new HashMap<>(); for (String inputName : componentContext.getInputsWithDatum()) { if (componentContext.isDynamicInput(inputName)) { dynamicInputs.put(inputName, componentContext.readInput(inputName)); } } String cpacsInitial = inputNamesToLocalFile.get(getCpacsInitialEndpointName()); if (cpacsInitial == null) { throw new ComponentException(StringUtils.format( "Failed to read CPACS from input '%s'; input is not configured", getCpacsInitialEndpointName())); } performDynamicInputMapping(cpacsInitial, dynamicInputs); if (!isMockMode()) { performInputMapping(cpacsInitial, dynamicInputs); if (getHistoryDataItem() != null) { try { File toolInputFile = new File(getToolInput()); String toolInputFileReference = datamanagementService.createTaggedReferenceFromLocalFile(componentContext, toolInputFile, toolInputFile.getName()); getHistoryDataItem().setToolInputFile(toolInputFile.getName(), toolInputFileReference); } catch (IOException e) { String errorMessage = "Failed to store tool input file into the data management" + STRING_NOT_AVAILABLE_IN_WDB; String errorId = LogUtils.logExceptionWithStacktraceAndAssignUniqueMarker(LOG, errorMessage, e); componentContext.getLog().componentError(errorMessage, e, errorId); } } } } private void performDynamicInputMapping(String cpacsInitial, Map<String, TypedDatum> dynamicInputs) throws ComponentException { try { dynamicEndpointMapper.updateXMLWithInputs(new File(cpacsInitial), dynamicInputs, componentContext); } catch (DataTypeException e) { throw new ComponentException("Failed to map dynamic input values into CPACS file", e); } if (!dynamicInputs.isEmpty() && getHistoryDataItem() != null) { try { String cpacsWithVariablesFileReference = datamanagementService.createTaggedReferenceFromLocalFile(componentContext, new File(cpacsInitial), "cpacsWithVariables.xml"); getHistoryDataItem().setCpacsWithVariablesFileReference(cpacsWithVariablesFileReference); } catch (IOException e) { String errorMessage = "Failed to store CPACS file with dynamic input values into the data management" + STRING_NOT_AVAILABLE_IN_WDB; String errorId = LogUtils.logExceptionWithStacktraceAndAssignUniqueMarker(LOG, errorMessage, e); componentContext.getLog().componentError(errorMessage, e, errorId); } } } private void performInputMapping(String cpacsInitial, Map<String, TypedDatum> dynamicInputs) throws ComponentException { createIntermediateFolders(); final File mappingFile = new File(getInputMapping()); if (mappingFile.exists()) { if (mappingFile.getName().endsWith(CpacsToolIntegrationConstants.FILE_SUFFIX_XML)) { componentLog.componentInfo(StringUtils.format(STRING_MAPPING_USAGE, STRING_MAPPING_TYPE_XML, STRING_MAPPING_DIRECTION_INPUT)); try { Document mappingDoc = transformXMLMapping(mappingFile.getAbsolutePath(), cpacsInitial, org.apache.commons.lang3.StringUtils.EMPTY); // Build tool input document String toolInputFilePath = getToolInput(); xmlMapper.transformXMLFileWithXMLMappingInformation(new File(cpacsInitial), new File(toolInputFilePath), mappingDoc); componentLog.componentInfo(StringUtils.format(STRING_TOOL_INPUT_CREATED, toolInputFilePath, String.valueOf(new File(toolInputFilePath).exists()))); } catch (XPathExpressionException | XMLException e) { throw new ComponentException(StringUtils.format(STRING_XML_ERROR_DURING_MAPPING, STRING_TOOL_MAPPING_DIRECTION_INPUT), e); } } else if (mappingFile.getName().endsWith(CpacsToolIntegrationConstants.FILE_SUFFIX_XSL)) { componentLog.componentInfo(StringUtils.format(STRING_MAPPING_USAGE, STRING_MAPPING_TYPE_XSL, STRING_MAPPING_DIRECTION_INPUT)); try { xmlMapper.transformXMLFileWithXSLT(new File(cpacsInitial), new File(getToolInput()), mappingFile, new CpacsToolIntegratorTextLinesReceiver()); } catch (XMLException e) { throw new ComponentException(StringUtils.format(STRING_XML_ERROR_DURING_MAPPING, STRING_TOOL_MAPPING_DIRECTION_INPUT), e); } } else { throw new ComponentException(StringUtils.format( STRING_ERROR_SOLVING_FILE_EXTENSION, getInputMapping())); } } else { throw new ComponentException(StringUtils.format(STRING_MAPPING_FILE_NOT_FOUND, getInputMapping())); } if (hasToolspecificinputfile()) { if (getHistoryDataItem() != null) { try { String toolInputFileReference = datamanagementService.createTaggedReferenceFromLocalFile(componentContext, new File(getToolInput()), getToolInputFileName() + FILE_SUFFIX_MAPPED); getHistoryDataItem().setToolInputWithoutToolspecificFileReference(toolInputFileReference); } catch (IOException e) { String errorMessage = "Failed to store tool input file into the data management" + STRING_NOT_AVAILABLE_IN_WDB; String errorId = LogUtils.logExceptionWithStacktraceAndAssignUniqueMarker(LOG, errorMessage, e); componentContext.getLog().componentError(errorMessage, e, errorId); } } final File mappingFile1 = new File(getToolspecificInputMapping()); if (mappingFile1.exists()) { if (mappingFile1.getName().endsWith(CpacsToolIntegrationConstants.FILE_SUFFIX_XML)) { componentLog.componentInfo(StringUtils.format(STRING_MAPPING_USAGE, STRING_MAPPING_TYPE_XML, STRING_MAPPING_DIRECTION_TOOLSPECIFIC)); try { final Document mappingDoc = transformXMLMapping(getToolspecificInputMapping(), getToolspecificInputData(), getToolInput()); // overwrite old tool input file xmlMapper.transformXMLFileWithXMLMappingInformation(new File(getToolspecificInputData()), new File(getToolInput()), mappingDoc); } catch (XPathExpressionException | XMLException e) { throw new ComponentException(StringUtils.format( STRING_XML_ERROR_DURING_MAPPING, STRING_MAPPING_DIRECTION_TOOLSPECIFIC), e); } } else if (mappingFile1.getName().endsWith(CpacsToolIntegrationConstants.FILE_SUFFIX_XSL)) { componentLog.componentInfo(StringUtils.format(STRING_MAPPING_USAGE, STRING_MAPPING_TYPE_XSL, STRING_MAPPING_DIRECTION_TOOLSPECIFIC)); File toolInputMapped = new File(getToolInput() + SUFFIX_MAPPED); File toolInput = new File(getToolInput()); try { FileUtils.copyFile(toolInput, toolInputMapped, true); xmlMapper.transformXMLFileWithXSLT(new File(getToolInput() + SUFFIX_MAPPED), new File(getToolInput()), new File(getToolspecificInputMapping()), null); } catch (IOException e) { throw new ComponentException(StringUtils.format( STRING_TOOL_INPUT_FILE_NOT_FOUND, getToolInput()), e); } catch (XMLException e) { throw new ComponentException(StringUtils.format( STRING_XML_ERROR_DURING_MAPPING, STRING_MAPPING_DIRECTION_TOOLSPECIFIC)); } } else { throw new ComponentException(StringUtils.format( STRING_ERROR_SOLVING_FILE_EXTENSION, getToolspecificInputMapping())); } } else { throw new ComponentException(StringUtils.format( STRING_MAPPING_FILE_NOT_FOUND, getToolspecificInputMapping())); } } } private void createIntermediateFolders() throws ComponentException { if (copyToolBehaviour.equals(ToolIntegrationConstants.VALUE_COPY_TOOL_BEHAVIOUR_ALWAYS) || copyToolBehaviour.equals(ToolIntegrationConstants.VALUE_COPY_TOOL_BEHAVIOUR_ONCE)) { try { String inputParent = new File(getToolInput()).getParent(); String outputParent = new File(getToolOutput()).getParent(); if (inputParent != null && !inputParent.equals(executionToolDirectory.getAbsolutePath())) { FileUtils.forceMkdir(new File(inputParent)); } if (outputParent != null && !outputParent.equals(executionToolDirectory.getAbsolutePath())) { FileUtils.forceMkdir(new File(outputParent)); } } catch (IOException e) { throw new ComponentException("Failed to generate intermediate tool input/output folders", e); } } } @Override protected boolean needToRun(Map<String, TypedDatum> inputValues, Map<String, String> inputNamesToLocalFile) throws ComponentException { if (isAlwaysRun()) { return true; } try { String tmpInputFile = FileUtils.readFileToString(new File(getToolInput())); if (lastRunToolinputFile != null) { String lastRunToolinput = FileUtils.readFileToString(lastRunToolinputFile); // Check the alwaysRun configuration and check for changed input since the last run if (lastRunToolinput == null || lastRunStaticInputValues == null || (tmpInputFile.compareTo(lastRunToolinput) != 0) || staticInputsAreNotEqual(inputValues, inputNamesToLocalFile)) { lastRunToolinput = tmpInputFile; TempFileServiceAccess.getInstance().disposeManagedTempDirOrFile(lastRunToolinputFile); lastRunToolinputFile = TempFileServiceAccess.getInstance().createTempFileFromPattern("CPACSLastRun*.xml"); FileUtils.write(lastRunToolinputFile, tmpInputFile); return true; } } else { lastRunToolinputFile = TempFileServiceAccess.getInstance().createTempFileFromPattern("CPACSLastRun*.xml"); FileUtils.write(lastRunToolinputFile, tmpInputFile); return true; } } catch (IOException e) { throw new ComponentException("Failed to read tool input file", e); } componentLog.componentInfo("Skipping tool execution as input values not changed compared to previous run"); return false; } private boolean staticInputsAreNotEqual(Map<String, TypedDatum> inputValues, Map<String, String> inputNamesToLocalFile) { for (String inputName : inputValues.keySet()) { if (!inputName.equals(getCpacsInitialEndpointName()) && componentContext.isStaticInput(inputName)) { if (lastRunStaticInputValues.containsKey(inputName)) { if (componentContext.getInputDataType(inputName) == DataType.FileReference) { String uuidLastRun = ((FileReferenceTD) lastRunStaticInputValues.get(inputName)).getFileReference(); String uuidCurrentRun = ((FileReferenceTD) (inputValues.get(inputName))).getFileReference(); try { File tempDir = TempFileServiceAccess.getInstance().createManagedTempDir(); File lastFile = new File(tempDir, ((FileReferenceTD) lastRunStaticInputValues.get(inputName)).getFileName()); File currentFile = new File(tempDir, ((FileReferenceTD) inputValues.get(inputName)).getFileName()); datamanagementService.copyReferenceToLocalFile(uuidLastRun, lastFile, componentContext .getDefaultStorageNodeId()); datamanagementService.copyReferenceToLocalFile(uuidCurrentRun, currentFile, componentContext .getDefaultStorageNodeId()); if (compareFiles(tempDir, lastFile, currentFile)) { return true; } } catch (IOException e) { String errorMessage = "Failed to read file (previous input value) from the data management;" + " consider input values as changed"; String errorId = LogUtils.logExceptionWithStacktraceAndAssignUniqueMarker(LOG, errorMessage, e); componentLog.componentError(errorMessage, e, errorId); return true; } } else if (componentContext.getInputDataType(inputName) == DataType.DirectoryReference) { try { File tempDir = TempFileServiceAccess.getInstance().createManagedTempDir(); File lastDir = new File(tempDir, ((DirectoryReferenceTD) lastRunStaticInputValues.get(inputName)).getDirectoryName()); File currentDir = new File(tempDir, ((DirectoryReferenceTD) inputValues.get(inputName)).getDirectoryName() + "_curr"); datamanagementService.copyDirectoryReferenceTDToLocalDirectory(componentContext, (DirectoryReferenceTD) lastRunStaticInputValues.get(inputName), lastDir); datamanagementService.copyDirectoryReferenceTDToLocalDirectory(componentContext, (DirectoryReferenceTD) inputValues.get(inputName), currentDir); if (!compareDirectories(tempDir, lastDir, currentDir)) { return true; } } catch (IOException e) { String errorMessage = "Failed to read directory (previous input value) from the data management;" + " consider input values as changed"; String errorId = LogUtils.logExceptionWithStacktraceAndAssignUniqueMarker(LOG, errorMessage, e); componentLog.componentError(errorMessage, e, errorId); return true; } } else { if (!lastRunStaticInputValues.get(inputName).equals(inputValues.get(inputName))) { return true; } } } } } return false; } private boolean compareDirectories(File tempDir, File lastDir, File currentDir) { File[] lastList = lastDir.listFiles(); File[] currentList = currentDir.listFiles(); String md5Last = expandFiles(lastList, ""); String md5Current = expandFiles(currentList, ""); return md5Last.equals(md5Current); } private String expandFiles(File[] dirFiles, String md5in) { String md5out = md5in; Arrays.sort(dirFiles); for (File file : dirFiles) { if (file.isDirectory() && !file.isHidden()) { md5out += expandFiles(file.listFiles(), md5out); } else if (file.isFile() && !file.isHidden()) { byte[] fileInput; try { fileInput = FileUtils.readFileToByteArray(file); md5out += DigestUtils.md5Hex(fileInput); } catch (IOException e) { LOG.error("Failed to expand files", e); md5out = ""; } } } return md5out; } private boolean compareFiles(File tempDir, File lastFile, File currentFile) throws IOException { if (!FileUtils.contentEquals(lastFile, currentFile)) { lastFile.delete(); currentFile.delete(); TempFileServiceAccess.getInstance().disposeManagedTempDirOrFile(tempDir); return true; } lastFile.delete(); currentFile.delete(); TempFileServiceAccess.getInstance().disposeManagedTempDirOrFile(tempDir); return false; } @Override protected void afterCommandExecution(Map<String, TypedDatum> inputValues, Map<String, String> inputNamesToLocalFile) throws ComponentException { if (getHistoryDataItem() != null) { String toolOutputFileReference; try { File outputFile = new File(getToolOutput()); toolOutputFileReference = datamanagementService.createTaggedReferenceFromLocalFile(componentContext, outputFile, outputFile.getName()); getHistoryDataItem().setToolOutputFile(outputFile.getName(), toolOutputFileReference); } catch (IOException e) { throw new ComponentException(StringUtils.format("Failed to find tool output file: %s", getToolOutput()), e); } } } @Override protected void afterPostScriptExecution(Map<String, TypedDatum> inputValues, Map<String, String> inputNamesToLocalFile) throws ComponentException { // if not-a-value was sent to the CPACS output, send not-a-value to all of the dynamic outputs and skip output mapping as no more // values must be sent to the CPACS output Set<String> outputsWithNotAValue = getOutputsWithNotAValueWritten(); if (outputsWithNotAValue.contains(getCpacsOutputName())) { writeNotAValueToDynamicOutputs(outputsWithNotAValue); componentLog.componentInfo("not-a-value was sent to the output '%s' to which the resulting CPACS file is intended to " + "be written to; thus, output mapping is skipped, the resulting CPACS file is not sent and not-a-value is " + "sent to all of the dynamic outputs (if existent) which would extract some value from the resulting CPACS file"); return; } try { Boolean outputFileExists = new File(getToolOutput()).exists(); componentLog.componentInfo(StringUtils.format(STRING_TOOL_OUTPUT_FILE_EXISTS, getToolOutput(), outputFileExists)); if (!outputFileExists) { throw new ComponentException( StringUtils.format( "Failed to perform output mapping. Tool output file is missing after post script execution: %s", getToolOutput())); } if (!isAlwaysRun()) { if (needsToRun) { if (tmpOutputFile != null && tmpOutputFile.exists()) { TempFileServiceAccess.getInstance().disposeManagedTempDirOrFile(tmpOutputFile); } tmpOutputFile = TempFileServiceAccess.getInstance().createTempFileFromPattern("cpacsToolOutput-*.xml"); FileUtils.copyFile(new File(getToolOutput()), tmpOutputFile); } else { FileUtils.copyFile(tmpOutputFile, new File(getToolOutput())); } } String cpacsInitial = inputNamesToLocalFile.get(getCpacsInitialEndpointName()); performOutputMapping(cpacsInitial); dynamicEndpointMapper.updateOutputsFromXML(new File(getCpacsResult()), componentContext); File resultFile = new File(getCpacsResult()); FileReferenceTD outgoingCPACSFileReference = datamanagementService.createFileReferenceTDFromLocalFile(componentContext, resultFile, componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_CPACS_RESULT_FILENAME)); try { componentContext.writeOutput(getCpacsOutputName(), outgoingCPACSFileReference); } catch (NullPointerException e) { throw new ComponentException(StringUtils.format( "Failed to write output to CPACS output; output '%s' is not configured", getCpacsOutputName()), e); } if (getHistoryDataItem() != null) { getHistoryDataItem().addOutput(getCpacsOutputName(), outgoingCPACSFileReference); } } catch (DataTypeException e) { throw new ComponentException("Failed to extract dynamic output values from CPACS", e); } catch (IOException e) { throw new ComponentException("Failed to create result CPACS file", e); } } private void writeNotAValueToDynamicOutputs(Set<String> outputsWithNotAValue) { TypedDatumFactory typedDatumFactory = componentContext.getService(TypedDatumService.class).getFactory(); for (String outputName : componentContext.getOutputs()) { if (componentContext.isDynamicOutput(outputName) && !outputsWithNotAValue.contains(outputName)) { componentContext.writeOutput(outputName, typedDatumFactory.createNotAValue(Cause.InvalidInputs)); } } } private void performOutputMapping(String cpacsInitial) throws ComponentException { final File mappingFile = new File(getOutputMapping()); if (mappingFile.exists()) { if (mappingFile.getName().endsWith(CpacsToolIntegrationConstants.FILE_SUFFIX_XML)) { componentLog.componentInfo(StringUtils.format(STRING_MAPPING_USAGE, STRING_MAPPING_TYPE_XML, STRING_TOOL_MAPPING_DIRECTION_OUTPUT)); try { // Build CPACS-Result-File through mapping final Document mappingDoc = transformXMLMapping(mappingFile.getAbsolutePath(), getToolOutput(), cpacsInitial); String cpacsResultFilePath = getCpacsResult(); File resultFile = new File(cpacsResultFilePath); FileUtils.copyFile(new File(cpacsInitial), resultFile); xmlMapper.transformXMLFileWithXMLMappingInformation(new File(getToolOutput()), resultFile, mappingDoc); componentLog.componentInfo(StringUtils.format(STRING_CPACS_RESULT_FILE_CREATED, cpacsResultFilePath, String.valueOf(new File(cpacsResultFilePath).exists()))); } catch (XPathExpressionException | IOException | XMLException e) { throw new ComponentException(StringUtils.format(STRING_XML_ERROR_DURING_MAPPING, STRING_TOOL_MAPPING_DIRECTION_OUTPUT), e); } } else if (mappingFile.getName().endsWith(CpacsToolIntegrationConstants.FILE_SUFFIX_XSL)) { componentLog.componentInfo(StringUtils.format(STRING_MAPPING_USAGE, STRING_MAPPING_TYPE_XSL, STRING_MAPPING_DIRECTION_OUTPUT)); try { xmlMapper.transformXMLFileWithXSLT(new File(cpacsInitial), new File(getCpacsResult()), mappingFile, new CpacsToolIntegratorTextLinesReceiver()); } catch (XMLException e) { throw new ComponentException(StringUtils.format(STRING_XML_ERROR_DURING_MAPPING, STRING_MAPPING_DIRECTION_OUTPUT), e); } } else { throw new ComponentException(StringUtils.format( STRING_ERROR_SOLVING_FILE_EXTENSION, getOutputMapping())); } } else { throw new ComponentException(StringUtils.format(STRING_MAPPING_FILE_NOT_FOUND, getOutputMapping())); } } @Override protected void initializeNewHistoryDataItem() { if (Boolean.valueOf(componentContext.getConfigurationValue(ComponentConstants.CONFIG_KEY_STORE_DATA_ITEM))) { historyDataItem = new CpacsIntegrationHistoryDataItem(componentContext.getComponentIdentifier()); } } private CpacsIntegrationHistoryDataItem getHistoryDataItem() { return (CpacsIntegrationHistoryDataItem) historyDataItem; } protected String getCpacsInitialEndpointName() { return componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_CPACS_INITIAL_ENDPOINTNAME); } protected String getToolInput() { return executionToolDirectory + File.separator + getToolInputFileName(); } private String getToolInputFileName() { return componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_TOOL_INPUT_FILENAME); } protected String getInputMapping() { return executionToolDirectory + File.separator + componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_MAPPING_INPUT_FILENAME); } protected boolean hasToolspecificinputfile() { return componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_HAS_TOOLSPECIFIC_INPUT) != null && Boolean.parseBoolean(componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_HAS_TOOLSPECIFIC_INPUT)); } protected boolean isAlwaysRun() { return componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_ALWAYS_RUN) == null || Boolean.parseBoolean(componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_ALWAYS_RUN)); } protected String getToolspecificInputMapping() { return executionToolDirectory + File.separator + componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_TOOLSPECIFICMAPPING_FILENAME); } protected String getToolspecificInputData() { return executionToolDirectory + File.separator + componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_TOOLSPECIFICINPUTDATA_FILENAME); } protected String getCpacsResult() { return outputDirectory + File.separator + componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_CPACS_RESULT_FILENAME); } protected String getCpacsOutputName() { return componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_CPACS_OUTGOING_ENDPOINTNAME); } protected String getOutputMapping() { return executionToolDirectory + File.separator + componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_MAPPING_OUTPUT_FILENAME); } protected String getToolOutput() { if (!isMockMode()) { return executionToolDirectory + File.separator + componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_TOOL_OUTPUT_FILENAME); } else { return executionToolDirectory + File.separator + componentContext.getConfigurationValue(CpacsToolIntegrationConstants.KEY_MOCK_TOOL_OUTPUT_FILENAME); } } @Override protected void bindScriptingService(ScriptingService service) { super.bindScriptingService(service); } @Override protected void bindComponentDataManagementService(ComponentDataManagementService compDataManagementService) { super.bindComponentDataManagementService(compDataManagementService); } /** * --- MOVED HERE FROM OLD CPACSMAPPER --- * * Transforms a XML mapping stylesheet to the final mapping XML document by surrounding it with a XSLT header and executing this XSLT * stylesheet. This method rearranges, e.g., xslt loops to simple source/target mappings. * * @param mappingFilename The file name of the mapping file to be transformed. * @param sourceFilename The file name of an input (source) file. * @param targetFilename The file name of the target file, in which the source file should be imported. If content is empty ("") a new * file will be created. * * @return Returns the final mapping XML document as DOM document. * @throws ComponentException Thrown if mapping fails. */ private Document transformXMLMapping(final String mappingFilename, final String sourceFilename, final String targetFilename) throws XMLException { try { final TransformerFactory transformerFac = TransformerFactory.newInstance(); transformerFac.setErrorListener(new XSLTErrorHandler()); // First read in the mapping XML file and transform it to a valid // XSLT stylesheet by surrounding it with the appropiate stylesheet elements. // This is done via the stylesheet CreateMapping.xslt which is loaded from // the jar file or the package path. try (InputStream inStream = this.getClass().getResourceAsStream(CREATE_MAPPING_XSLT_FILEPATH)) { final Transformer transformer1 = transformerFac.newTransformer(new StreamSource(inStream)); transformer1.setErrorListener(new XSLTErrorHandler()); final DOMSource mappingSrc = new DOMSource(xmlSupport.readXMLFromFile(new File(mappingFilename))); final Document tempDoc = xmlSupport.createDocument(); final DOMResult tempXSLT = new DOMResult(tempDoc); transformer1.transform(mappingSrc, tempXSLT); // Now transform the resulting mapping XSLT to the final mapping file which // only contains mapping elements and no more xsl elements like loops, conditions // etc. final DOMSource sourceXSLT = new DOMSource(tempDoc); final Transformer transformer2 = transformerFac.newTransformer(sourceXSLT); transformer2.setErrorListener(new XSLTErrorHandler()); transformer2.setParameter("sourceFilename", sourceFilename.replace("\\", XMLFILE_SEPARATOR)); transformer2.setParameter("targetFilename", targetFilename.replace("\\", XMLFILE_SEPARATOR)); final DOMSource source = new DOMSource(xmlSupport.createDocument()); final Document resultDoc = xmlSupport.createDocument(); final DOMResult result = new DOMResult(resultDoc); transformer2.transform(source, result); return resultDoc; } } catch (final NullPointerException | TransformerException | XMLException | IOException e) { throw new XMLException("XML-Transformation failed: " + e.toString()); } } @Override public void tearDown(FinalComponentState state) { super.tearDown(state); try { if (lastRunToolinputFile != null) { TempFileServiceAccess.getInstance().disposeManagedTempDirOrFile(lastRunToolinputFile); } } catch (IOException e) { LOG.error("Failed to delete temp file: " + lastRunToolinputFile.getAbsolutePath(), e); } try { if (tmpOutputFile != null) { TempFileServiceAccess.getInstance().disposeManagedTempDirOrFile(tmpOutputFile); } } catch (IOException e) { LOG.error("Failed to delete temp file: " + tmpOutputFile.getAbsolutePath(), e); } } }