Java tutorial
/* * Copyright (C) 2006-2016 Talend Inc. - www.talend.com * * This source code is available under agreement available at * %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt * * You should have received a copy of the agreement along with this program; if not, write to Talend SA 9 rue Pages * 92150 Suresnes, France */ package com.amalto.core.plugin.base.xslt; import java.io.ByteArrayOutputStream; import java.io.StringReader; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.ErrorListener; import javax.xml.transform.OutputKeys; 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.StreamResult; import javax.xml.transform.stream.StreamSource; import net.sf.saxon.FeatureKeys; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Service; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.amalto.core.objects.Plugin; import com.amalto.core.objects.datacluster.DataClusterPOJOPK; import com.amalto.core.objects.transformers.util.TransformerPluginContext; import com.amalto.core.objects.transformers.util.TransformerPluginVariableDescriptor; import com.amalto.core.objects.transformers.util.TypedContent; import com.amalto.core.util.LocalUser; import com.amalto.core.util.Util; import com.amalto.core.util.XtentisException; import com.amalto.xmlserver.interfaces.WhereAnd; import com.amalto.xmlserver.interfaces.WhereCondition; /** * <h1>XSLT Plugin</h1> <h3>Plugin name: xslt</h3> <h3>Description</h3> The XSLT plugin executes an XSLT on an input XML * document.<br/> * <br/> * The XSLT plugin supports XSLT 2.0 and provides and extension to perform cross-referencing on the fly when the output * method of the xslt is set to 'xml' or to 'xhtml'.<br/> * * <br/> * Cross-referencing is carried out AFTER the xslt is processed on ALL elements with the following attributes: * * <pre> * <MyElement * xrefCluster='CLUSTER' * xrefIn='TEST1, ..., TESTN' * xrefOut='XPATH_IN_ITEM' * xrefIgnore='true|false' * xrefDefault='DEFAULT_VALUE' * >OLD_VALUE</MyElement> * </pre> * * Where * <ul> * <li><b>xrefCluster</b>: the cluster where the Items used for cross-referencing are stored</li> * <li><b>xrefIn</b>: a series of XPaths tests to match this item content with a remote Item</li> * <li><b>xrefOut</b>: the XPath in the remote item, starting with the concept name, of the content that will replace * the content of this item</li> * <li><b>xrefIgnore</b>: optional, defaults to <code>false</code>. If set to <code>true</code>, the cross referencing * will not fail if not Item is found and the <code>xrefDefault</code> value will be inserted.</li> * <li><b>xrefDefault</b>: if <code>xrefIgnore</code> is set to <code>true</code> and the cross-referencing is failing, * this value will be used instead.</li> * </ul> * <h3>Inputs</h3> * <ul> * <li><b>xml</b>: the xml on which to apply the XSLT</li> * <li><b>parameters</b>: optional input parameters to the XSLT in the form of * * <pre> * <Parameters> * <Parameter> * <Name>PARAMETER_NAME</Name> * <Value>PARAMETER_VALUE</Value> * </Parameter> * </Parameters> * </pre> * * </li> * </ul> * <h3>Outputs</h3> * <ul> * <li><b>text</b>: the result of the XSLT</li> * </ul> * <h3>Parameters</h3> The XSLT - see the description. <h3>Example</h3> The following example parameters will loop over * all the <code>LineItem</code>s of the input XML and send them to the rest of the transformer as XML fragments * * <pre> * <Country * xrefCluster='MYCLUSTER' * xrefIn='.=Country/Codes/ISO2, ../Customer/Name=[ACME]' * xrefOut='Country/Name/FR' * ><xsl:value-of select='State/CountryCode'/></Country> * </pre> * * The example above does the following: * <ul> * <li>1-the xslt generates a <Country> element in the target document</li> * <li>2-the content of State/CountryCode of the source document is inserted as the value of the <Country> element</li> * <li>3-the rest of the xsl transformations complete</li> * <li>4-the system queries the Country data in cluster MYCLUSTER where * <ul> * <li>Codes/ISO2Code is equal to State/CountryCode (the current value of the Country element)</li> * <li>and ../Customer/Name in the target document is equal to hard coded value ACME</li> * </ul> * <li>5-the matching Country document is returned and the value in Name/FR is extracted</li> * <li>6-the value in Country of the target document is replaced with the extracted value</li> * </ul> * * @author Bruno Grieder * * @ejb.bean name="XSLTTransformerPlugin" display-name="Name for XSLTPlugin" description="Description for XSLTPlugin" * local-jndi-name = "amalto/local/transformer/plugin/xslt" type="Stateless" view-type="local" * local-business-interface="com.amalto.core.objects.transformers.v2.util.TransformerPluginV2LocalInterface" * * @ejb.remote-facade * * @ejb.permission view-type = "remote" role-name = "administration" * @ejb.permission view-type = "local" unchecked = "true" * * * */ @Service(XSLTTransformerPluginBean.JNDI_NAME) public class XSLTTransformerPluginBean extends Plugin { public static final String JNDI_NAME = "amalto/local/transformer/plugin/xslt"; //$NON-NLS-1$ private static final Logger LOG = Logger.getLogger(XSLTTransformerPluginBean.class); private static final String OUTPUT_METHOD = "com.amalto.core.plugin.xpath.outputMethod"; //$NON-NLS-1$ private static final String TRANSFORMER = "com.amalto.core.plugin.xpath.transformer"; //$NON-NLS-1$ private static final String INPUT_XML = "xml"; //$NON-NLS-1$ private static final String INPUT_PARAMETERS = "parameters"; //$NON-NLS-1$ private static final String OUTPUT_TEXT = "text"; //$NON-NLS-1$ /******************************************************************************************** * Compilation - decompilation of parameters ********************************************************************************************/ // XSLT ouput determination private static Pattern XLST_OUTPUT_PATTERN = Pattern.compile( ".+?<[a-z]+?:output[^>]*? method\\s*=\\s*[\"|'](.*?)[\"|'].*", //$NON-NLS-1$ Pattern.DOTALL | Pattern.CASE_INSENSITIVE); /** A transformation error */ String transformatioError = null; /** A transformation warning */ String transformationeWarning = null; private boolean configurationLoaded = false; private String compilationErrors = ""; //$NON-NLS-1$ public XSLTTransformerPluginBean() { super(); try { getConfiguration(null); } catch (Exception e) { } } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public String getJNDIName() throws XtentisException { return JNDI_NAME; } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public String getDescription(String twoLetterLanguageCode) throws XtentisException { if ("fr".matches(twoLetterLanguageCode.toLowerCase())) return "Transforme un XML en utilisant une XSLT"; return "Transform an XML using an XSLT"; } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public ArrayList<TransformerPluginVariableDescriptor> getInputVariableDescriptors(String twoLettersLanguageCode) throws XtentisException { ArrayList<TransformerPluginVariableDescriptor> inputDescriptors = new ArrayList<TransformerPluginVariableDescriptor>(); // The csv_line descriptor TransformerPluginVariableDescriptor descriptor1 = new TransformerPluginVariableDescriptor(); descriptor1.setVariableName(INPUT_XML); descriptor1.setContentTypesRegex( new ArrayList<Pattern>(Arrays.asList(new Pattern[] { Pattern.compile("text/xml") }))); HashMap<String, String> descriptions1 = new HashMap<String, String>(); descriptions1.put("en", "The item instance to project"); descriptor1.setDescriptions(descriptions1); descriptor1.setMandatory(true); descriptor1.setPossibleValuesRegex(null); inputDescriptors.add(descriptor1); // The xslt parameters descriptor TransformerPluginVariableDescriptor descriptor2 = new TransformerPluginVariableDescriptor(); descriptor2.setVariableName(INPUT_PARAMETERS); descriptor2.setContentTypesRegex( new ArrayList<Pattern>(Arrays.asList(new Pattern[] { Pattern.compile("text/xml") }))); HashMap<String, String> descriptions2 = new HashMap<String, String>(); descriptions2.put("en", "An xml file with parameters to pass to the xlst transformer"); descriptions2.put("fr", "Un fichier XML contenant les paramtres passer au processeur xslt"); descriptor2.setDescriptions(descriptions2); descriptor2.setMandatory(false); descriptor2.setPossibleValuesRegex(null); inputDescriptors.add(descriptor2); return inputDescriptors; } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public ArrayList<TransformerPluginVariableDescriptor> getOutputVariableDescriptors( String twoLettersLanguageCode) throws XtentisException { ArrayList<TransformerPluginVariableDescriptor> outputDescriptors = new ArrayList<TransformerPluginVariableDescriptor>(); // The csv_line descriptor TransformerPluginVariableDescriptor descriptor = new TransformerPluginVariableDescriptor(); descriptor.setVariableName(OUTPUT_TEXT); descriptor.setContentTypesRegex( new ArrayList<Pattern>(Arrays.asList(new Pattern[] { Pattern.compile("text/.*") }))); HashMap<String, String> descriptions = new HashMap<String, String>(); descriptions.put("en", "The result of the xml transformation"); descriptor.setDescriptions(descriptions); descriptor.setMandatory(true); descriptor.setPossibleValuesRegex(null); outputDescriptors.add(descriptor); return outputDescriptors; } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public void init(TransformerPluginContext context, String compiledParameters) throws XtentisException { try { if (!configurationLoaded) { loadConfiguration(); } // fetech the parameters CompiledParameters parameters = CompiledParameters.deserialize(compiledParameters); // get the xslt compiled style sheet and the Transformer /** * Unfortunately this does not work for the moment PreparedStylesheet preparedStyleSheet * =parameters.getPreparedStyleSheet(); Transformer transformer = preparedStyleSheet.newTransformer(); **/ // As a replacement in the meantime setCompilationErrors(""); //$NON-NLS-1$ // USE SAXON for XSLT 2.0 Support TransformerFactory transFactory = new net.sf.saxon.TransformerFactoryImpl(); transFactory.setErrorListener(new ErrorListener() { public void error(TransformerException exception) throws TransformerException { add2CompilationErrors(exception.getLocalizedMessage()); } public void fatalError(TransformerException exception) throws TransformerException { add2CompilationErrors(exception.getLocalizedMessage()); } public void warning(TransformerException exception) throws TransformerException { String err = "XSLT Plugin: Warning during the compilation of the XSLT"; //$NON-NLS-1$ LOG.warn(err, exception); } }); transFactory.setAttribute(FeatureKeys.VERSION_WARNING, Boolean.valueOf(false)); if (!"".equals(getCompilationErrors())) { //$NON-NLS-1$ String err = "XSLT Plugin: Errors occurred during the compilation of the XSLT:" //$NON-NLS-1$ + getCompilationErrors(); LOG.error(err); throw new XtentisException(err); } Transformer transformer = transFactory .newTransformer(new StreamSource(new StringReader(parameters.getXslt()))); // Pass Parameters to the XSLT processor String username = LocalUser.getLocalUser().getUsername(); transformer.setParameter("USERNAME", username); //$NON-NLS-1$ transformer.setErrorListener(new ErrorListener() { public void error(TransformerException exception) throws TransformerException { String err = "XSLT Plugin: An error occured during the XSLT transformation"; //$NON-NLS-1$ LOG.error(err, exception); throw new TransformerException(err); } public void fatalError(TransformerException exception) throws TransformerException { String err = "XSLT Plugin: A fatal error occured during the XSLT transformation"; //$NON-NLS-1$ LOG.error(err, exception); throw new TransformerException(err); } public void warning(TransformerException exception) throws TransformerException { String err = "XSLT Plugin: Warning during the XSLT transformation"; //$NON-NLS-1$ LOG.warn(err, exception); } }); // Insert all this in the context context.put(TRANSFORMER, transformer); context.put(OUTPUT_METHOD, parameters.getOutputMethod()); } catch (Exception e) { String err = compilationErrors; if (err == null || err.length() == 0) { err = "Could not init the XSLT Plugin"; //$NON-NLS-1$ } LOG.error(err, e); throw new XtentisException(err); } } @Override protected String loadConfiguration() { return null; } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public void execute(TransformerPluginContext context) throws XtentisException { try { // fetch data from context Transformer transformer = (Transformer) context.get(TRANSFORMER); String outputMethod = (String) context.get(OUTPUT_METHOD); TypedContent xmlTC = (TypedContent) context.get(INPUT_XML); // get the charset String charset = Util.extractCharset(xmlTC.getContentType()); // get the xml String String xml = new String(xmlTC.getContentBytes(), charset); // get the xml parameters TypedContent parametersTC = (TypedContent) context.get(INPUT_PARAMETERS); if (parametersTC != null) { String parametersCharset = Util.extractCharset(parametersTC.getContentType()); byte[] parametersBytes = parametersTC.getContentBytes(); if (parametersBytes != null) { String parameters = new String(parametersBytes, parametersCharset); Document parametersDoc = Util.parse(parameters); NodeList paramList = Util.getNodeList(parametersDoc.getDocumentElement(), "//Parameter"); //$NON-NLS-1$ for (int i = 0; i < paramList.getLength(); i++) { String paramName = Util.getFirstTextNode(paramList.item(i), "Name"); //$NON-NLS-1$ String paramValue = Util.getFirstTextNode(paramList.item(i), "Value"); //$NON-NLS-1$ if (paramValue == null) paramValue = ""; //$NON-NLS-1$ if (paramName != null) { transformer.setParameter(paramName, paramValue); } } } } // FIXME: ARRRRGHHHHHH - How do you prevent the Transformer to process doctype instructions? // Sets the current time transformer.setParameter("TIMESTAMP", getTimestamp()); //$NON-NLS-1$ transformer.setErrorListener(new ErrorListener() { public void error(TransformerException exception) throws TransformerException { transformatioError = exception.getMessage(); } public void fatalError(TransformerException exception) throws TransformerException { transformatioError = exception.getMessage(); } public void warning(TransformerException exception) throws TransformerException { transformationeWarning = exception.getMessage(); } }); transformatioError = null; transformationeWarning = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); if ("xml".equals(outputMethod) || "xhtml".equals(outputMethod)) { //$NON-NLS-1$ //$NON-NLS-2$ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document = builder.newDocument(); DOMResult domResult = new DOMResult(document); transformer.transform(new StreamSource(new StringReader(xml)), domResult); if (transformationeWarning != null) { String err = "Warning processing the XSLT: " + transformationeWarning; //$NON-NLS-1$ LOG.warn(err); } if (transformatioError != null) { String err = "Error processing the XSLT: " + transformatioError; //$NON-NLS-1$ LOG.error(err); throw new XtentisException(err); } Node rootNode = document.getDocumentElement(); // process the cross-referencings NodeList xrefl = Util.getNodeList(rootNode.getOwnerDocument(), "//*[@xrefCluster]"); //$NON-NLS-1$ int len = xrefl.getLength(); for (int i = 0; i < len; i++) { Element xrefe = (Element) xrefl.item(i); xrefe = processMappings(xrefe); } TransformerFactory transFactory = new net.sf.saxon.TransformerFactoryImpl(); Transformer serializer = transFactory.newTransformer(); serializer.setOutputProperty(OutputKeys.METHOD, outputMethod); serializer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$ serializer.transform(new DOMSource(rootNode), new StreamResult(baos)); } else { if (transformationeWarning != null) { String err = "Warning processing the XSLT: " + transformationeWarning; //$NON-NLS-1$ LOG.warn(err); } if (transformatioError != null) { String err = "Error processing the XSLT: " + transformatioError; //$NON-NLS-1$ LOG.error(err); throw new XtentisException(err); } // transform the item transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(baos)); } // Call Back byte[] bytes = baos.toByteArray(); if (LOG.isDebugEnabled()) { LOG.debug("execute() Inserting XSL Result in '" + OUTPUT_TEXT + "'\n" + new String(bytes, "utf-8")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } context.put(OUTPUT_TEXT, new TypedContent(bytes, ("xhtml".equals(outputMethod) ? "application/xhtml+xml" //$NON-NLS-1$//$NON-NLS-2$ : "text/" //$NON-NLS-1$ + outputMethod) + "; charset=utf-8")); //$NON-NLS-1$ context.getPluginCallBack().contentIsReady(context); } catch (Exception e) { String err = "Could not start the XSLT plugin"; //$NON-NLS-1$ LOG.error(err, e); throw new XtentisException(err); } } /** * Process the mappings after xsl transformation * * @param xrefElement * @return the processed Element */ private Element processMappings(Element xrefElement) throws XtentisException { try { String xrefcluster = xrefElement.getAttribute("xrefCluster"); //$NON-NLS-1$ String xrefIn = xrefElement.getAttribute("xrefIn"); //$NON-NLS-1$ String xrefOut = xrefElement.getAttribute("xrefOut"); //$NON-NLS-1$ String xrefIgnore = xrefElement.getAttribute("xrefIgnore"); //$NON-NLS-1$ String xrefDefault = xrefElement.getAttribute("xrefDefault"); //$NON-NLS-1$ Logger.getLogger(XSLTTransformerPluginBean.class) .debug("\n xrefIgnore=" + xrefIgnore + "\n xrefDefault=" + xrefDefault); //$NON-NLS-1$ //$NON-NLS-2$ // parse xrefbein dockey1:xrefkey1,dockey2:xrefkey2 String[] mappings = xrefIn.split(","); //$NON-NLS-1$ HashMap<String, String> itemvals = new HashMap<String, String>(); for (int j = 0; j < mappings.length; j++) { String[] relations = mappings[j].split("="); //$NON-NLS-1$ String docpath = relations[0]; String xrefpath = relations[1]; String itemval = ""; //$NON-NLS-1$ try { if (docpath.startsWith("[")) // hardcoded value //$NON-NLS-1$ itemval = docpath.substring(1, docpath.length() - 1); else itemval = Util.getFirstTextNode(xrefElement, docpath); } catch (Exception x) { throw new XtentisException( "Value for business element '" + xrefElement.getNodeName() + '/' + docpath //$NON-NLS-1$ + "' cannot be found!"); //$NON-NLS-1$ } if (itemval == null) itemval = ""; //$NON-NLS-1$ String content = stripeOuterBracket(itemval); if (content.split(",").length >= mappings.length) //$NON-NLS-1$ itemvals.put(xrefpath, content.split(",")[j]); //$NON-NLS-1$ else itemvals.put(xrefpath, ""); //$NON-NLS-1$ } WhereAnd wAnd = new WhereAnd(); Collection<Map.Entry<String, String>> c = itemvals.entrySet(); int i = 0; for (Iterator<Map.Entry<String, String>> iter = c.iterator(); iter.hasNext();) { i++; Map.Entry<String, String> entry = iter.next(); wAnd.add(new WhereCondition(entry.getKey(), WhereCondition.EQUALS, entry.getValue(), WhereCondition.PRE_NONE, false)); } ArrayList<String> resList = Util.getItemCtrl2Local().xPathsSearch(new DataClusterPOJOPK(xrefcluster), null, new ArrayList<String>(Arrays.asList(new String[] { xrefOut })), wAnd, -1, // spell 0, // start 1, // limit false); String val = ""; //$NON-NLS-1$ if ((resList == null) || (resList.size() == 0)) { if (xrefIgnore.equals("true") || xrefIgnore.equals("1")) { //$NON-NLS-1$ //$NON-NLS-2$ if (xrefDefault != null) val = xrefDefault; else val = ""; //$NON-NLS-1$ } else { String ks = ""; //$NON-NLS-1$ c = itemvals.entrySet(); for (Iterator<Map.Entry<String, String>> iter = c.iterator(); iter.hasNext();) { Map.Entry<String, String> entry = iter.next(); ks += " " + entry.getKey() + "=\"" + entry.getValue() + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } throw new XtentisException("Foreign keys values not found for: " + ks); //$NON-NLS-1$ } } else { // read result Pattern p = Pattern.compile("<.*?>(.*?)</.*>", Pattern.DOTALL); //$NON-NLS-1$ Matcher m = p.matcher(resList.iterator().next()); if (m.matches()) val = StringEscapeUtils.unescapeXml(m.group(1)); else { Pattern p2 = Pattern.compile("<.*?/>", Pattern.DOTALL); //$NON-NLS-1$ Matcher m2 = p2.matcher(resList.iterator().next()); if (!m2.matches() && !(xrefIgnore.equals("true") || xrefIgnore.equals("1"))) { //$NON-NLS-1$ //$NON-NLS-2$ throw new XtentisException("Result values were not understood for crossref element"); //$NON-NLS-1$ } } } NodeList l = xrefElement.getChildNodes(); for (int j = 0; j < l.getLength(); j++) { switch (l.item(j).getNodeType()) { case Node.TEXT_NODE: l.item(j).setNodeValue(val); break; case Node.ELEMENT_NODE: xrefElement.removeChild(l.item(j)); break; default: } } xrefElement.removeAttribute("xrefCluster"); //$NON-NLS-1$ xrefElement.removeAttribute("xrefIgnore"); //$NON-NLS-1$ xrefElement.removeAttribute("xrefDefault"); //$NON-NLS-1$ xrefElement.removeAttribute("xrefIn"); //$NON-NLS-1$ xrefElement.removeAttribute("xrefOut"); //$NON-NLS-1$ return xrefElement; } catch (Exception e) { String err = "Unable to process the mappings for the element '" + xrefElement.getLocalName() + "'"; //$NON-NLS-1$ //$NON-NLS-2$ LOG.error(err, e); throw new XtentisException(err); } } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public String getParametersSchema() throws XtentisException { return null; } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ @SuppressWarnings("nls") public String getDocumentation(String twoLettersLanguageCode) throws XtentisException { return "Simply drop your xslt in the parameters box." + "\n" + "" + "\n" + "To xslt can do cross referencing on the fly if the output method is set to 'xml' or 'xhtml'" + "\n" + "" + "\n" + "Cross-referencing is carried out AFTER the xlst is processed on ALL elements with the following attributes:" + "\n" + " <Country " + "\n" + " xrefCluster='MYCLUSTER' " + "\n" + " xrefIn='.=Country/Codes/ISO2, ../Customer/Name=[ACME]' " + "\n" + " xrefOut='Country/Name/FR'" + "\n" + " >" + "\n" + " <xsl:value-of select='State/CountryCode'/>" + "\n" + " </Country>" + "\n" + "" + "\n" + "where" + "\n" + " xrefCluster is the cluster holmding the Country (concept/table) data" + "\n" + " xrefIn is a list of comma separated match expressions. " + "\n" + " The left part specifies an xPath relative to the current context of the *target* document" + "\n" + " or a hard coded value between brackets" + "\n" + " The right part specifies an xPath in the cluster" + "\n" + " xrefOut is an xPath in the Cluster holding the final value that will be inserted in the *target* document" + "\n" + "" + "\n" + " if xrefIgnore is 'true' or '1', no exception will be thrown if there is no entry in the transcodification table." + "\n" + " xrefDefault is the value that's used if there is no entry in the transcodification table and xrefIgnore is true." + "\n" + "" + "\n" + "The example above does the following:" + "\n" + " 1-the xslt generates a <Country> element in the target document" + "\n" + " 2-the value of State/CountryCode of the source document is inserted as the value of the <Country> element" + "\n" + " 3-the rest of the xsl transformations complete" + "\n" + " 4-the system queries the Country data in cluster MYCLUSTER where " + "\n" + " Codes/ISO2Code is equal to State/CountryCode (the current value of the Country element)" + "\n" + " and ../Customer/Name in the target document is equal to hard coded value ACME." + "\n" + " 5-the matching Country document is returned and the value in Name/FR is extracted" + "\n" + " 6- the value in Cuuntry of the traget document is replaced with the extracted value"; } private String getDefaultConfiguration() { return "<configuration><charset>utf-8</charset></configuration>"; //$NON-NLS-1$ } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public String getConfiguration(String optionalParameters) throws XtentisException { try { String configuration = loadConfiguration(); if (configuration == null) { configuration = getDefaultConfiguration(); } configurationLoaded = true; return configuration; } catch (Exception e) { String err = "Unable to deserialize the configuration of the XSLT Transformer Plugin"; //$NON-NLS-1$ LOG.error(err, e); throw new XtentisException(err); } } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public void putConfiguration(String configuration) throws XtentisException { configurationLoaded = false; } /** * @throws XtentisException * * @ejb.interface-method view-type = "local" * @ejb.facade-method */ public String compileParameters(String parameters) throws XtentisException { try { String xslt = parameters; CompiledParameters compiled = new CompiledParameters(); // Determine the ouput of the xslt String output = "xml"; // default //$NON-NLS-1$ Matcher mxslt = XLST_OUTPUT_PATTERN.matcher(xslt); if (mxslt.matches()) { output = mxslt.group(1).toLowerCase().trim(); } compiled.setOutputMethod(output); // compile the sytlesheet setCompilationErrors(""); //$NON-NLS-1$ compiled.setXslt(xslt); return compiled.serialize(); } catch (Exception e) { String err = "Unable to serialize the parameters of the XSLT Transformer Plugin"; //$NON-NLS-1$ LOG.error(err, e); throw new XtentisException(err); } } public String getCompilationErrors() { return compilationErrors; } public void setCompilationErrors(String compilationError) { this.compilationErrors = compilationError; } protected synchronized void add2CompilationErrors(String err) { compilationErrors += "\n" + err; //$NON-NLS-1$ } public static String getTimestamp() { return getTimestamp(new Date()); } private static String getTimestamp(Date d) { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss.SSS' 'z"); //$NON-NLS-1$ return sdf.format(d); } public static String stripeOuterBracket(String rowData) { ArrayList<String> result = new ArrayList<>(); int aggregate = 0; int cordon = 0; for (int i = 0; i < rowData.length(); i++) { char ch = rowData.charAt(i); if (ch == '[') { aggregate++; if (aggregate == 1) { cordon = i; } } else if (ch == ']') { aggregate--; if (aggregate == 0) { result.add(rowData.substring(cordon + 1, i)); } } else if (aggregate == 0) { result.add(ch + ""); //$NON-NLS-1$ } } return StringUtils.join(result.toArray(), ","); //$NON-NLS-1$ } }