diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/api/IElement.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/api/IElement.java index 48ecdb9c32f3de7afb74175c167ca85c9b435c1f..d2aff9f63290bb1156ea2f2c889d48e4d7a41f4f 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/api/IElement.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/api/IElement.java @@ -37,13 +37,19 @@ public interface IElement * @return the element's name. */ String getName(); - + /** - * @return the value of an attribute or NULL if the attribute is not defined for this - * {@link IElement} + * @return the value of an attribute + * @throws IllegalArgumentException if the attribute is not defined for this {@link IElement} */ String getAttribute(String key); + /** + * @return the value of an attribute or <code>defaultValue</code> if the attribute is not + * defined for this {@link IElement} + */ + String getAttribute(String key, String defaultValue); + /** * The "Data" field is intended for a chunk raw data that can be attached to an element * instance. This might be useful in scenarios where diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/Element.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/Element.java index 75955a2ac0bb396ea63e33139152638ab2e874f2..b7c50c2d5a26f1e303098306cfdf4a0d3eee6786 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/Element.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/Element.java @@ -56,7 +56,23 @@ public class Element implements IElement public String getAttribute(String key) { - return attributes.get(key); + String value = attributes.get(key); + if (value == null) + { + String error = String.format("Attribute '%s' does not exist.", key); + throw new IllegalArgumentException(error); + } + return value; + } + + public String getAttribute(String key, String defaultValue) + { + String value = attributes.get(key); + if (value == null) + { + value = defaultValue; + } + return value; } public String getData() diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/XmlStructuredPropertyConverter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/XmlStructuredPropertyConverter.java index a9cf79fc4b23921fdaeeace0a51164b7e6ba53db..80f880171a8183bfa68204939cedc112b10d7c49 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/XmlStructuredPropertyConverter.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/XmlStructuredPropertyConverter.java @@ -129,10 +129,15 @@ public class XmlStructuredPropertyConverter implements IStructuredPropertyConver { IElement child = transformFromDOM(domChild); children.add(child); - } else if (domChild.getNodeType() == Node.CDATA_SECTION_NODE) + } else if (domChild.getNodeType() == Node.TEXT_NODE) { - String textContext = domChild.getNodeValue(); - result.setData(textContext); + + String textContent = domChild.getNodeValue().trim(); + textContent = StringEscapeUtils.unescapeXml(textContent); + if (false == StringUtils.isBlank(textContent)) + { + result.setData(textContent); + } } } @@ -201,10 +206,12 @@ public class XmlStructuredPropertyConverter implements IStructuredPropertyConver private void transformDataToDOM(IElement element, Document document, Node node) { // text data - if (StringUtils.isBlank(element.getData()) == false) + String data = element.getData(); + if (StringUtils.isBlank(data) == false) { - Node cdataNode = document.createCDATASection(element.getData()); - node.appendChild(cdataNode); + String escapedXmlContent = StringEscapeUtils.escapeXml(data); + Node textNode = document.createTextNode(escapedXmlContent); + node.appendChild(textNode); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtils.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtils.java index 4d54b49110a7e9e743f513f50f75be92a90ca9ef..0ff5311f35b703791e1f3688d5268c064b469c7d 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtils.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/XmlUtils.java @@ -60,6 +60,9 @@ public class XmlUtils public static String XSLT_XSD_FILE_RESOURCE = "/schema-for-xslt20.xsd"; + /** indentation to be used when serializing to xml. */ + public static final Integer INDENTATION = 2; + /** * Parse given string as XML {@link Document}. * @@ -89,10 +92,11 @@ public class XmlUtils try { TransformerFactory transfac = TransformerFactory.newInstance(); + transfac.setAttribute("indent-number", INDENTATION); Transformer trans = transfac.newTransformer(); trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); trans.setOutputProperty(OutputKeys.INDENT, "yes"); - + trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", INDENTATION.toString()); StringWriter sw = new StringWriter(); trans.transform(new DOMSource(document), new StreamResult(sw)); return sw.toString(); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/ElementFactoryTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/ElementFactoryTest.java index 887af2278401c37bc90085a97fc9ca785e51ee18..9ae3503ffbbebf5482f30dc0281cd40ce1b3b6d5 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/ElementFactoryTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/ElementFactoryTest.java @@ -19,8 +19,8 @@ package ch.systemsx.cisd.openbis.generic.shared.managed_property.structured; import org.testng.AssertJUnit; import org.testng.annotations.Test; +import ch.systemsx.cisd.openbis.generic.shared.managed_property.api.IElement; import ch.systemsx.cisd.openbis.generic.shared.managed_property.api.IElementFactory; -import ch.systemsx.cisd.openbis.generic.shared.managed_property.structured.ElementFactory; /** * error test cases for {@link ElementFactory}. @@ -52,4 +52,26 @@ public class ElementFactoryTest extends AssertJUnit factory.createElement("Material"); } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testGetNonExistentAttribute() + { + IElement element = factory.createElement("test"); + element.getAttribute("non-existent"); + } + + @Test + public void testGetAttributeWithDefaultValue() + { + IElement element = factory.createElement("test"); + + String existentAttribute = "attr"; + String value = "value"; + element.addAttribute(existentAttribute, value); + + String defaultValue = "def_value"; + assertEquals(value, element.getAttribute(existentAttribute, defaultValue)); + assertEquals(defaultValue, element.getAttribute("non-existent", defaultValue)); + } + } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/XmlStructuredPropertyConverterTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/XmlStructuredPropertyConverterTest.java index ae6abfd80fb5f381946571000c95becc71dd0f18..62397dd95bdfa2f189146b715b9c01f7a7acb0a6 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/XmlStructuredPropertyConverterTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/structured/XmlStructuredPropertyConverterTest.java @@ -42,7 +42,7 @@ public class XmlStructuredPropertyConverterTest extends AssertJUnit List<IElement> elements = Arrays.asList( factory.createElement("testname").addAttribute("attr1", "value1") - .addAttribute("attr2", "value2"), + .addAttribute("attr2", "value2").setData("dummy&<>data"), factory.createSampleLink("permIdSample").addAttribute("sampleAttrKey", "sampleAttrVal"), factory.createMaterialLink("materialCode", "typeCode").addAttribute(