diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/operations/XMLTransformation.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/operations/XMLTransformation.java index cf250a9276..9ed7fa288c 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/operations/XMLTransformation.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/operations/XMLTransformation.java @@ -7,8 +7,11 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Source; +import javax.xml.transform.Templates; import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; @@ -22,8 +25,10 @@ import edu.cornell.mannlib.vitro.webapp.dynapi.components.Parameter; import edu.cornell.mannlib.vitro.webapp.dynapi.data.Data; import edu.cornell.mannlib.vitro.webapp.dynapi.data.DataStore; +import edu.cornell.mannlib.vitro.webapp.dynapi.data.ModelView; import edu.cornell.mannlib.vitro.webapp.dynapi.data.SimpleDataView; import edu.cornell.mannlib.vitro.webapp.dynapi.data.conversion.InitializationException; +import edu.cornell.mannlib.vitro.webapp.dynapi.data.implementation.DynapiInMemoryOntModel; import edu.cornell.mannlib.vitro.webapp.utils.configuration.Property; public class XMLTransformation extends AbstractOperation { @@ -32,11 +37,13 @@ public class XMLTransformation extends AbstractOperation { private Parameter xsltParam; private Parameter inputXmlParam; private Parameter outputXmlParam; + private Templates transformTemplates; @Property(uri = "https://vivoweb.org/ontology/vitro-dynamic-api#xslt", minOccurs = 1, maxOccurs = 1) public void setXsltParam(Parameter xsltParam) throws InitializationException { this.xsltParam = xsltParam; inputParams.add(xsltParam); + prepareTransformTemplates(); } @Property(uri = "https://vivoweb.org/ontology/vitro-dynamic-api#inputXml", minOccurs = 1, maxOccurs = 1) @@ -53,7 +60,7 @@ public void setOutputXml(Parameter outputXmlParam) throws InitializationExceptio @Override public OperationResult runOperation(DataStore dataStore) throws Exception { - String is = SimpleDataView.getStringRepresentation(inputXmlParam.getName(), dataStore); + String is = getInputString(dataStore); String styles = SimpleDataView.getStringRepresentation(xsltParam.getName(), dataStore); ByteArrayOutputStream output = transform(is, styles); Data outputData = new Data(outputXmlParam); @@ -63,13 +70,17 @@ public OperationResult runOperation(DataStore dataStore) throws Exception { return OperationResult.ok(); } + private String getInputString(DataStore dataStore) { + if (ModelView.isModel(inputXmlParam)) { + return ModelView.getModelRDFXmlRepresentation(dataStore, inputXmlParam); + } + return SimpleDataView.getStringRepresentation(inputXmlParam.getName(), dataStore); + } + private ByteArrayOutputStream transform(String input, String styles) throws Exception { InputStream inputStream = IOUtils.toInputStream(input, StandardCharsets.UTF_8); - InputStream styleInputStream = IOUtils.toInputStream(styles, StandardCharsets.UTF_8); - Source stylesource = new StreamSource(styleInputStream); ByteArrayOutputStream output = new ByteArrayOutputStream(); - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - Transformer transformer = transformerFactory.newTransformer(stylesource); + Transformer transformer = getTransformer(styles); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(inputStream); @@ -77,6 +88,37 @@ private ByteArrayOutputStream transform(String input, String styles) throws Exce return output; } + private void prepareTransformTemplates() throws InitializationException{ + try { + if (xsltParam.isInternal() && !xsltParam.isOptional()) { + String defaultValue = xsltParam.getDefaultValue(); + if (defaultValue != null) { + InputStream styleInputStream = IOUtils.toInputStream(defaultValue, StandardCharsets.UTF_8); + Source stylesource = new StreamSource(styleInputStream); + TransformerFactory transformerFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", null); + transformTemplates = transformerFactory.newTemplates(stylesource); + } + } + } catch (Exception e){ + throw new InitializationException(e.getMessage()); + } + } + + private Transformer getTransformer(String styles) + throws TransformerFactoryConfigurationError, TransformerConfigurationException, Exception { + if (transformTemplates != null) { + return transformTemplates.newTransformer(); + } + InputStream styleInputStream = IOUtils.toInputStream(styles, StandardCharsets.UTF_8); + Source stylesource = new StreamSource(styleInputStream); + TransformerFactory transformerFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", null); + Transformer transformer = transformerFactory.newTransformer(stylesource); + if (transformer == null) { + throw new Exception("Failed to initialize transformer. Check styles."); + } + return transformer; + } + @Override public boolean isInputValid(DataStore dataStore){ if (!super.isInputValid(dataStore)) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/operations/XMLValidation.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/operations/XMLValidation.java index 024368c86a..22b870c1cc 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/operations/XMLValidation.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/operations/XMLValidation.java @@ -15,6 +15,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.xml.sax.SAXException; import edu.cornell.mannlib.vitro.webapp.dynapi.components.OperationResult; import edu.cornell.mannlib.vitro.webapp.dynapi.components.Parameter; @@ -32,12 +33,13 @@ public class XMLValidation extends AbstractOperation { private Parameter inputXmlParam; private Parameter validationResult; private Parameter errorMessage; - + private Schema defaultSchema; @Property(uri = "https://vivoweb.org/ontology/vitro-dynamic-api#xsd", minOccurs = 1, maxOccurs = 1) public void setSchemaParam(Parameter schemaParam) throws InitializationException { this.schemaParam = schemaParam; inputParams.add(schemaParam); + prepareSchema(); } @Property(uri = "https://vivoweb.org/ontology/vitro-dynamic-api#inputXml", minOccurs = 1, maxOccurs = 1) @@ -86,10 +88,7 @@ public OperationResult runOperation(DataStore dataStore) throws Exception { private String validate(String input, String stringSchema) { try { InputStream inputStream = IOUtils.toInputStream(input, StandardCharsets.UTF_8); - InputStream schemaInputStream = IOUtils.toInputStream(stringSchema, StandardCharsets.UTF_8); - Source schemaSource = new StreamSource(schemaInputStream); - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = factory.newSchema(schemaSource); + Schema schema = getSchema(stringSchema); Validator validator = schema.newValidator(); validator.validate(new StreamSource(inputStream)); } catch (Exception e) { @@ -99,6 +98,30 @@ private String validate(String input, String stringSchema) { return ""; } + private void prepareSchema() throws InitializationException{ + try { + if (schemaParam.isInternal() && !schemaParam.isOptional()) { + String defaultValue = schemaParam.getDefaultValue(); + if (defaultValue != null) { + defaultSchema = getSchema(defaultValue); + } + } + } catch (Exception e){ + throw new InitializationException(e.getMessage()); + } + } + + private Schema getSchema(String stringSchema) throws SAXException { + if (defaultSchema != null) { + return defaultSchema; + } + InputStream schemaInputStream = IOUtils.toInputStream(stringSchema, StandardCharsets.UTF_8); + Source schemaSource = new StreamSource(schemaInputStream); + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = factory.newSchema(schemaSource); + return schema; + } + @Override public boolean isInputValid(DataStore dataStore){ if (!super.isInputValid(dataStore)) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/steps/OperationalStep.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/steps/OperationalStep.java index e9756d0f80..f17459ea49 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/steps/OperationalStep.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/components/steps/OperationalStep.java @@ -66,10 +66,14 @@ public void setOptional(boolean optional) { public OperationResult run(DataStore data) { OperationResult result = OperationResult.badRequest(); - log.debug("Processing in STEP"); - log.debug("Execution step is optional? " + optional); + long start = System.currentTimeMillis(); + if (log.isDebugEnabled()) { + log.debug("Started execution in step."); + if (optional) { + log.debug("Operation step is optional."); + } + } if (operation != null) { - log.debug("Operation not null"); ParameterSubstitutor.forwardSubstitution(substitutions, data); result = operation.run(data); ParameterSubstitutor.backwardSubstitution(substitutions, data); @@ -77,6 +81,10 @@ public OperationResult run(DataStore data) { return result; } } + if (log.isDebugEnabled()) { + long time = System.currentTimeMillis() - start; + log.debug("Step execution time: " + time + "ms"); + } return nextStep.run(data); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/data/ModelView.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/data/ModelView.java index 75834de518..de47d71d22 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/data/ModelView.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/data/ModelView.java @@ -7,6 +7,7 @@ import edu.cornell.mannlib.vitro.webapp.dynapi.components.Parameter; import edu.cornell.mannlib.vitro.webapp.dynapi.components.Parameters; +import edu.cornell.mannlib.vitro.webapp.dynapi.data.implementation.DynapiInMemoryOntModel; import edu.cornell.mannlib.vitro.webapp.dynapi.data.types.ImplementationType; import edu.cornell.mannlib.vitro.webapp.dynapi.data.types.ParameterType; @@ -64,6 +65,10 @@ public static List getExistingModels( Parameters params, DataStore dataSt } return list; } + + public static String getModelRDFXmlRepresentation(DataStore dataStore, Parameter param) { + return DynapiInMemoryOntModel.serialize(getModel(dataStore, param), "RDF/XML"); + } public static void addModel(DataStore dataStore, Model model, Parameter outputParam) { Data modelData = new Data(outputParam); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/data/implementation/DynapiInMemoryOntModel.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/data/implementation/DynapiInMemoryOntModel.java index 514b6db3ab..693efff2b0 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/data/implementation/DynapiInMemoryOntModel.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dynapi/data/implementation/DynapiInMemoryOntModel.java @@ -1,16 +1,25 @@ package edu.cornell.mannlib.vitro.webapp.dynapi.data.implementation; +import java.io.ByteArrayOutputStream; import java.io.StringReader; import org.apache.jena.ontology.OntModelSpec; import org.apache.jena.ontology.impl.OntModelImpl; import org.apache.jena.rdf.model.Model; +import org.apache.jena.riot.RDFDataMgr; +import org.apache.jena.riot.Lang; +import org.apache.jena.riot.RDFLanguages; public class DynapiInMemoryOntModel { + public static String serialize(Model input, String lang){ + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + RDFDataMgr.write(baos, input, RDFLanguages.nameToLang(lang)) ; + return baos.toString(); + } + public static String serialize(Model input){ - //TODO: implement - return ""; + return serialize(input, "RDF/XML"); } public static Model deserialize(String input){