diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/XMLPropertyTransformer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/XMLPropertyTransformer.java index 544742f5aed9e103a923e720da3d4da18c44b877..2fcd8ff019b235e8178102ba5c54006bcff06828 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/XMLPropertyTransformer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/XMLPropertyTransformer.java @@ -16,38 +16,22 @@ package ch.systemsx.cisd.openbis.generic.client.web.server.util; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.HashMap; import java.util.List; -import java.util.Map; - -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; import org.apache.commons.lang.StringEscapeUtils; -import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GenericValueEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityPropertiesHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; +import ch.systemsx.cisd.openbis.generic.shared.util.XmlUtils; /** - * - * * @author Franz-Josef Elmer */ public class XMLPropertyTransformer { - private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance(); - - private final Map<String, Transformer> cachedTransformers = new HashMap<String, Transformer>(); - public <T> void transformXMLProperties(List<T> rows) { for (T row : rows) @@ -60,7 +44,8 @@ public class XMLPropertyTransformer { if (property instanceof GenericValueEntityProperty) { - GenericValueEntityProperty entityProperty = (GenericValueEntityProperty) property; + GenericValueEntityProperty entityProperty = + (GenericValueEntityProperty) property; PropertyType propertyType = entityProperty.getPropertyType(); if (propertyType.getDataType().getCode().equals(DataTypeCode.XML)) { @@ -68,10 +53,11 @@ public class XMLPropertyTransformer if (transformation != null) { String xslt = StringEscapeUtils.unescapeHtml(transformation); - String v = StringEscapeUtils.unescapeHtml(entityProperty.getValue()); - String renderedXMLString = eval(xslt, v); + String xmlString = + StringEscapeUtils.unescapeHtml(entityProperty.getValue()); + String renderedXMLString = XmlUtils.transform(xslt, xmlString); entityProperty.setValue(renderedXMLString); - entityProperty.setOriginalValue(v); + entityProperty.setOriginalValue(xmlString); } } } @@ -80,36 +66,4 @@ public class XMLPropertyTransformer } } - private String eval(String xslt, String xmlString) - { - Transformer transformer = getTransformer(xslt); - StringWriter writer = new StringWriter(); - try - { - transformer.transform(new StreamSource(new StringReader(xmlString)), new StreamResult(writer)); - } catch (TransformerException ex) - { - throw CheckedExceptionTunnel.wrapIfNecessary(ex); - } - return writer.toString(); - } - - private Transformer getTransformer(String xslt) - { - try - { - Transformer transformer = cachedTransformers.get(xslt); - if (transformer == null) - { - transformer = TRANSFORMER_FACTORY.newTransformer(new StreamSource(new StringReader(xslt))); - cachedTransformers.put(xslt, transformer); - } - return transformer; - } catch (Exception ex) - { - throw CheckedExceptionTunnel.wrapIfNecessary(ex); - } - } - - } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyTypeBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyTypeBO.java index aa0e8dd10246f142751903aabc280aed02525dd8..6881187c40864a89fe4987e4ca10521ccedca66c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyTypeBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyTypeBO.java @@ -27,7 +27,6 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.shared.basic.utils.StringUtils; import ch.systemsx.cisd.common.utilities.XMLInfraStructure; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; -import ch.systemsx.cisd.openbis.generic.server.dataaccess.XmlUtils; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; @@ -46,6 +45,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.Session; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; import ch.systemsx.cisd.openbis.generic.shared.dto.EventPE.EntityType; import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind; +import ch.systemsx.cisd.openbis.generic.shared.util.XmlUtils; /** * The only productive implementation of {@link IPropertyTypeBO}. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/PropertyValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/PropertyValidator.java index b61500e7b8d12e9372a6dedf2e668df8d14d4b7a..448ca42db026cc04731d33d081a2967ea9f915a0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/PropertyValidator.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/PropertyValidator.java @@ -42,6 +42,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE; +import ch.systemsx.cisd.openbis.generic.shared.util.XmlUtils; /** * The default {@link IPropertyValueValidator} implementation. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/dynamic_property/calculator/XmlPropertyAdaptor.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/dynamic_property/calculator/XmlPropertyAdaptor.java index 2f7d37d70bccb1ba7ca40d062d996e0bb4150fc9..48d62b804197730da8bc342345a724887aa7ae24 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/dynamic_property/calculator/XmlPropertyAdaptor.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/dynamic_property/calculator/XmlPropertyAdaptor.java @@ -16,17 +16,8 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess.db.dynamic_property.calculator; -import java.io.StringReader; -import java.io.StringWriter; - -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyPE; +import ch.systemsx.cisd.openbis.generic.shared.util.XmlUtils; /** * {@link IEntityPropertyAdaptor} implementation for xml property. @@ -52,22 +43,8 @@ class XmlPropertyAdaptor extends BasicPropertyAdaptor @Override public String renderedValue() { - // TODO 2010-10-25, PTR: Refactoring needed (merge with XMLPropertyTransformer) final String xml = super.valueAsString(); - - StringWriter writer = new StringWriter(); - try - { - Transformer transformer = - TransformerFactory.newInstance().newTransformer( - new StreamSource(new StringReader(xsltTransformation))); - transformer - .transform(new StreamSource(new StringReader(xml)), new StreamResult(writer)); - } catch (TransformerException ex) - { - throw CheckedExceptionTunnel.wrapIfNecessary(ex); - } - return writer.toString(); + return XmlUtils.transform(xsltTransformation, xml); } // diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/XmlUtils.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtils.java similarity index 60% rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/XmlUtils.java rename to openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtils.java index cf1ab96f4e9bee6e25e21552afd517d7c1c1268d..4622491490f4faad3b45c2584c934aaba46d0f0d 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/XmlUtils.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtils.java @@ -14,15 +14,24 @@ * limitations under the License. */ -package ch.systemsx.cisd.openbis.generic.server.dataaccess; +package ch.systemsx.cisd.openbis.generic.shared.util; import java.io.File; import java.io.IOException; import java.io.StringReader; +import java.io.StringWriter; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.Validator; @@ -31,11 +40,12 @@ import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.utilities.XMLInfraStructure; /** - * Utility methods for parsing and validating XML files. + * Utility methods for parsing, validating and transforming XML files. * * @author Piotr Buczek */ @@ -65,8 +75,8 @@ public class XmlUtils } catch (Exception e) { throw UserFailureException.fromTemplate( - "Provided value:\n\n%s\n\nisn't a well formed XML document. %s", value, e - .getMessage()); + "Provided value:\n\n%s\n\nisn't a well formed XML document. %s", value, + e.getMessage()); } } @@ -74,8 +84,8 @@ public class XmlUtils public static void validate(Document document, String xmlSchema) throws SAXException, IOException { - validate(document, XMLInfraStructure.createSchema(new StreamSource(new StringReader( - xmlSchema)))); + validate(document, + XMLInfraStructure.createSchema(new StreamSource(new StringReader(xmlSchema)))); } /** validate given document against the schema specified by URL */ @@ -100,4 +110,49 @@ public class XmlUtils validator.validate(new DOMSource(document)); } + // + // XSL Transformations + // + + private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance(); + + private static final Map<String, Transformer> cachedTransformers = + new HashMap<String, Transformer>(); + + /** @return <code>xmlString</code> transformed with <code>xslt</code> script */ + public static String transform(String xslt, String xmlString) + { + Transformer transformer = getTransformer(xslt); + Source source = new StreamSource(new StringReader(xmlString)); + StringWriter writer = new StringWriter(); + Result result = new StreamResult(writer); + try + { + transformer.transform(source, result); + } catch (TransformerException ex) + { + throw CheckedExceptionTunnel.wrapIfNecessary(ex); + } + return writer.toString(); + } + + private static Transformer getTransformer(String xslt) + { + try + { + Transformer transformer = cachedTransformers.get(xslt); + if (transformer == null) + { + transformer = + TRANSFORMER_FACTORY + .newTransformer(new StreamSource(new StringReader(xslt))); + cachedTransformers.put(xslt, transformer); + } + return transformer; + } catch (Exception ex) + { + throw CheckedExceptionTunnel.wrapIfNecessary(ex); + } + } + } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyTypeBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyTypeBOTest.java index 77ffa5ba5a89f5fca9ca7ef1ac09e5a2763440b3..ac7209456ba7bf1c6dd1d7c259a14fbd92bfe8ea 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyTypeBOTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyTypeBOTest.java @@ -24,7 +24,6 @@ import org.testng.annotations.Test; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.utilities.XMLInfraStructure; import ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool; -import ch.systemsx.cisd.openbis.generic.server.util.XmlUtilsTest; import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType; @@ -34,6 +33,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; +import ch.systemsx.cisd.openbis.generic.shared.util.XmlUtilsTest; /** * Test cases for corresponding {@link PropertyTypeBO} class. diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyValidatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyValidatorTest.java index ebde363525abe614534e60b1197a0e5e262153c8..3d38557a118556f6b631d1af65e269a798a5892f 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyValidatorTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/PropertyValidatorTest.java @@ -29,12 +29,12 @@ import ch.rinn.restrictions.Friend; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.generic.server.dataaccess.PropertyValidator; import ch.systemsx.cisd.openbis.generic.server.dataaccess.PropertyValidator.SupportedDatePattern; -import ch.systemsx.cisd.openbis.generic.server.util.XmlUtilsTest; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE; import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE; +import ch.systemsx.cisd.openbis.generic.shared.util.XmlUtilsTest; /** * Test cases for corresponding {@link PropertyValidator} class. diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/dynamic_property/calculator/DynamicPropertyCalculatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/dynamic_property/calculator/DynamicPropertyCalculatorTest.java index c92fa572cbe606f92cc00f33aa0d4b1614155a53..75d9fabaeeaa54303e7c162c09036a333b591aa9 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/dynamic_property/calculator/DynamicPropertyCalculatorTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/dynamic_property/calculator/DynamicPropertyCalculatorTest.java @@ -22,6 +22,8 @@ import java.util.Collection; import org.testng.AssertJUnit; import org.testng.annotations.Test; +import ch.systemsx.cisd.openbis.generic.shared.util.XmlUtilsTest; + /** * @author Piotr Buczek */ @@ -70,11 +72,6 @@ public class DynamicPropertyCalculatorTest extends AssertJUnit assertEquals(p22.valueAsString(), calculator.evalAsString()); } - private static final String XSLT = - "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" - + "<xsl:template match='/'><b><xsl:value-of select='.'/></b></xsl:template>" - + "</xsl:stylesheet>"; - @Test public void testGetEntityPropertyRenderedValue() { @@ -87,7 +84,7 @@ public class DynamicPropertyCalculatorTest extends AssertJUnit IEntityPropertyAdaptor normalProperty = createProperty("normalProperty", "normalValue"); IEntityPropertyAdaptor xmlProperty = - createXmlProperty("xmlProperty", "<root>hello world</root>", XSLT); + createXmlProperty("xmlProperty", XmlUtilsTest.SIMPLE_XML, XmlUtilsTest.SIMPLE_XSLT); normalPropertyCalculator.setEntity(createEntity(entityCode, Arrays.asList(new IEntityPropertyAdaptor[] @@ -97,8 +94,7 @@ public class DynamicPropertyCalculatorTest extends AssertJUnit xmlPropertyCalculator.setEntity(createEntity(entityCode, Arrays.asList(new IEntityPropertyAdaptor[] { normalProperty, xmlProperty }))); - assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><b>hello world</b>", - xmlPropertyCalculator.evalAsString()); + assertEquals(XmlUtilsTest.SIMPLE_XML_TRANSFORMED, xmlPropertyCalculator.evalAsString()); } private static IEntityAdaptor createEntity(final String code, diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/util/XmlUtilsTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtilsTest.java similarity index 77% rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/util/XmlUtilsTest.java rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtilsTest.java index 7ae108afa5945306340f264900977860235bac0b..463fd22f2a87f67639a91ca7bbf0a8b070646352 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/util/XmlUtilsTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtilsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package ch.systemsx.cisd.openbis.generic.server.util; +package ch.systemsx.cisd.openbis.generic.shared.util; import java.io.IOException; import java.net.URL; @@ -30,7 +30,6 @@ import org.xml.sax.SAXParseException; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.utilities.XMLInfraStructure; -import ch.systemsx.cisd.openbis.generic.server.dataaccess.XmlUtils; /** * Tests of {@link XmlUtils}. @@ -78,33 +77,31 @@ public class XmlUtilsTest extends AssertJUnit + "</xs:element>\n " + "</xs:schema> "; - public static String EXAMPLE_INCORRECT_SCHEMA = - EXAMPLE_SCHEMA.replaceAll("xs:complexType", "xs:complex"); - - public static String EXAMPLE_XSLT = - "<?xml version='1.0'?>\n" - + "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" - + "<xsl:output method='html'/>\n " - + "<xsl:template match='child::person'>\n " - + " <html>\n " - + " <head>\n " - + " <title>\n " - + " <xsl:value-of select='descendant::firstname' />\n " - + " <xsl:text> </xsl:text>\n " - + " <xsl:value-of select='descendant::lastname' />\n " - + " </title>\n " - + " </head>\n " - + " <body>\n " - + " <xsl:value-of select='descendant::firstname' />\n " - + " <xsl:text> </xsl:text>\n " - + " <xsl:value-of select='descendant::lastname' />\n " - + " </body>\n " - + " </html>\n " - + "</xsl:template>\n " - + "</xsl:stylesheet>"; - - public static String EXAMPLE_INCORRECT_XSLT = - EXAMPLE_XSLT.replaceAll("xsl:stylesheet", "xsl:styleshet"); + public static String EXAMPLE_INCORRECT_SCHEMA = EXAMPLE_SCHEMA.replaceAll("xs:complexType", + "xs:complex"); + + public static String EXAMPLE_XSLT = "<?xml version='1.0'?>\n" + + "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" + + "<xsl:output method='html'/>\n " + + "<xsl:template match='child::person'>\n " + + " <html>\n " + + " <head>\n " + + " <title>\n " + + " <xsl:value-of select='descendant::firstname' />\n " + + " <xsl:text> </xsl:text>\n " + + " <xsl:value-of select='descendant::lastname' />\n " + + " </title>\n " + + " </head>\n " + + " <body>\n " + + " <xsl:value-of select='descendant::firstname' />\n " + + " <xsl:text> </xsl:text>\n " + + " <xsl:value-of select='descendant::lastname' />\n " + + " </body>\n " + + " </html>\n " + + "</xsl:template>\n " + "</xsl:stylesheet>"; + + public static String EXAMPLE_INCORRECT_XSLT = EXAMPLE_XSLT.replaceAll("xsl:stylesheet", + "xsl:styleshet"); @BeforeClass public void outputJaxpInfo() @@ -214,4 +211,21 @@ public class XmlUtilsTest extends AssertJUnit } assertTrue(exceptionThrown); } + + public static String SIMPLE_XML = "<root>hello world</root>"; + + public static String SIMPLE_XSLT = + "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" + + "<xsl:template match='/'><b><xsl:value-of select='.'/></b></xsl:template>" + + "</xsl:stylesheet>"; + + public static String SIMPLE_XML_TRANSFORMED = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?><b>hello world</b>"; + + @Test + public void testXsltTransformation() + { + String result = XmlUtils.transform(SIMPLE_XSLT, SIMPLE_XML); + assertEquals(SIMPLE_XML_TRANSFORMED, result); + } }