This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-xproc.git
commit 518b0d601512cb6f66e3ccea6d44a6bb39fd4fcb Author: Juan Vazquez <[email protected]> AuthorDate: Fri Mar 20 19:49:51 2009 +0000 W3C XProc pipeline support git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk@756733 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 120 +++++++++++ .../sling/scripting/xproc/XProcScriptEngine.java | 74 +++++++ .../scripting/xproc/XProcScriptEngineFactory.java | 55 ++++++ .../xproc/cocoon/generator/SlingGenerator.java | 106 ++++++++++ .../SlingGeneratorServletOutputStream.java | 54 +++++ .../generator/SlingGeneratorServletResponse.java | 66 +++++++ .../xproc/cocoon/transform/SlingTransformer.java | 160 +++++++++++++++ .../sling/scripting/xproc/xpl/XplBuilder.java | 111 +++++++++++ .../sling/scripting/xproc/xpl/XplConstants.java | 32 +++ .../sling/scripting/xproc/xpl/api/AtomicStep.java | 23 +++ .../scripting/xproc/xpl/api/CompoundStep.java | 29 +++ .../sling/scripting/xproc/xpl/api/Document.java | 27 +++ .../sling/scripting/xproc/xpl/api/Environment.java | 34 ++++ .../sling/scripting/xproc/xpl/api/Input.java | 31 +++ .../xproc/xpl/api/MultiContainerStep.java | 23 +++ .../sling/scripting/xproc/xpl/api/Pipeline.java | 24 +++ .../apache/sling/scripting/xproc/xpl/api/Step.java | 33 ++++ .../sling/scripting/xproc/xpl/api/XplElement.java | 44 +++++ .../scripting/xproc/xpl/api/XplElementFactory.java | 29 +++ .../apache/sling/scripting/xproc/xpl/api/Xslt.java | 27 +++ .../xproc/xpl/impl/AbstractCompoundStepImpl.java | 56 ++++++ .../scripting/xproc/xpl/impl/AbstractStepImpl.java | 55 ++++++ .../xproc/xpl/impl/AbstractXplElementImpl.java | 219 +++++++++++++++++++++ .../scripting/xproc/xpl/impl/DocumentImpl.java | 43 ++++ .../scripting/xproc/xpl/impl/EnvironmentImpl.java | 46 +++++ .../sling/scripting/xproc/xpl/impl/InputImpl.java | 53 +++++ .../scripting/xproc/xpl/impl/PipelineImpl.java | 67 +++++++ .../xproc/xpl/impl/XplElementFactoryImpl.java | 52 +++++ .../sling/scripting/xproc/xpl/impl/XsltImpl.java | 51 +++++ src/main/resources/META-INF/DISCLAIMER | 7 + src/main/resources/META-INF/LICENSE | 202 +++++++++++++++++++ src/main/resources/META-INF/NOTICE | 8 + .../services/javax.script.ScriptEngineFactory | 1 + .../sling/scripting/xproc/xpl/XplBuilderTest.java | 68 +++++++ src/test/resources/xpl/html.xpl | 32 +++ 35 files changed, 2062 insertions(+) diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..db0bc3e --- /dev/null +++ b/pom.xml @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.sling</groupId> + <artifactId>sling</artifactId> + <version>5-incubator-SNAPSHOT</version> + <relativePath>../../../parent/pom.xml</relativePath> + </parent> + + <artifactId>org.apache.sling.scripting.xproc</artifactId> + <version>2.0.0-incubator-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>Apache Sling Scripting W3C XML Processing Support</name> + <description> + Support for W3C XML Processing scripting (http://www.w3.org/XML/Processing/) + </description> + + <scm> + <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/scripting/xproc</connection> + <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/scripting/xproc</developerConnection> + <url>http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/xproc</url> + </scm> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>1.4.3</version> + <extensions>true</extensions> + <configuration> + <instructions> + <Private-Package> + org.apache.sling.scripting.xproc.* + </Private-Package> + <Embed-Dependency>cocoon-pipeline;inline=true</Embed-Dependency> + <ScriptEngine-Name>${pom.name}</ScriptEngine-Name> + <ScriptEngine-Version>${pom.version}</ScriptEngine-Version> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.api</artifactId> + <version>2.0.2-incubator</version> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.scripting.api</artifactId> + <version>2.0.2-incubator</version> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.mime</artifactId> + <version>2.0.2-incubator</version> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + </dependency> + <dependency> + <groupId>javax.jcr</groupId> + <artifactId>jcr</artifactId> + </dependency> + <dependency> + <groupId>org.apache.cocoon.pipeline</groupId> + <artifactId>cocoon-pipeline</artifactId> + <version>3.0.0-alpha-1</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <!-- Testing --> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.testing</artifactId> + <version>2.0.3-incubator-SNAPSHOT</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>xmlunit</groupId> + <artifactId>xmlunit</artifactId> + <version>1.2</version> + <scope>test</scope> + </dependency> + + </dependencies> + +</project> diff --git a/src/main/java/org/apache/sling/scripting/xproc/XProcScriptEngine.java b/src/main/java/org/apache/sling/scripting/xproc/XProcScriptEngine.java new file mode 100644 index 0000000..827b641 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/XProcScriptEngine.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc; + +import java.io.Reader; + +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptException; + +import org.apache.sling.api.scripting.SlingBindings; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.scripting.api.AbstractSlingScriptEngine; +import org.apache.sling.scripting.xproc.xpl.XplBuilder; +import org.apache.sling.scripting.xproc.xpl.api.Pipeline; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A {@link ScriptEngine} that uses XPL definition files + * in order to execute pipelines over Sling resources. + * + * @see http://www.w3.org/TR/xproc/ + */ +public class XProcScriptEngine extends AbstractSlingScriptEngine { + + private static final Logger log = LoggerFactory.getLogger(XProcScriptEngine.class); + + protected XProcScriptEngine(ScriptEngineFactory factory) { + super(factory); + } + + public Object eval(Reader reader, ScriptContext scriptContext) throws ScriptException { + Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE); + SlingScriptHelper helper = (SlingScriptHelper) bindings.get(SlingBindings.SLING); + if (helper == null) { + throw new ScriptException("SlingScriptHelper missing from bindings"); + } + + String scriptName = helper.getScript().getScriptResource().getPath(); + + try { + XplBuilder xplBuilder = new XplBuilder(); + Pipeline xpl = (Pipeline) xplBuilder.build(reader); + xpl.getEnv().setSling(helper); + xpl.eval(); + } catch (Throwable t) { + log.error("Failure running XProc script.", t); + throw new ScriptException("Failure running XProc script " + + scriptName); + } + + return null; + } + +} \ No newline at end of file diff --git a/src/main/java/org/apache/sling/scripting/xproc/XProcScriptEngineFactory.java b/src/main/java/org/apache/sling/scripting/xproc/XProcScriptEngineFactory.java new file mode 100644 index 0000000..fa047d5 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/XProcScriptEngineFactory.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc; + +import javax.script.ScriptEngine; + +import org.apache.sling.scripting.api.AbstractScriptEngineFactory; + +public class XProcScriptEngineFactory extends AbstractScriptEngineFactory { + + public final static String XPROC_SCRIPT_EXTENSION = "xpl"; + + public final static String XPROC_MIME_TYPE = "application/xml"; + + public final static String SHORT_NAME = "XProc"; + + private static final String XPROC_NAME = "XMLProc"; + + private static final String DEFAULT_XPROC_VERSION = "1.0"; + + public XProcScriptEngineFactory() { + setExtensions(XPROC_SCRIPT_EXTENSION); + setMimeTypes(XPROC_MIME_TYPE); + setNames(SHORT_NAME, "xml processing", "xml pipeline processor"); + } + + public ScriptEngine getScriptEngine() { + return new XProcScriptEngine(this); + } + + public String getLanguageName() { + return XPROC_NAME; + } + + public String getLanguageVersion() { + return DEFAULT_XPROC_VERSION; + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/cocoon/generator/SlingGenerator.java b/src/main/java/org/apache/sling/scripting/xproc/cocoon/generator/SlingGenerator.java new file mode 100644 index 0000000..de80c7f --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/cocoon/generator/SlingGenerator.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.cocoon.generator; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import javax.jcr.Session; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletResponse; + +import org.apache.cocoon.pipeline.component.sax.AbstractGenerator; +import org.apache.cocoon.pipeline.util.XMLUtils; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.commons.mime.MimeTypeService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A Cocoon Generator that uses internal Sling + * request processing in order to get the initial + * XML for the pipeline. + * + * In order of preference the generator tries + * to resolve the current resource as: + * + * +-- a XML file (adapts to {@link InputStream}) + * +-- dynamically generated XML (using inclusion procedure) + * +-- the underlying node“s export document view + */ +public class SlingGenerator extends AbstractGenerator { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private static final String XML_MIME_TYPE = "text/xml"; + + private SlingHttpServletRequest request; + private SlingHttpServletResponse response; + private MimeTypeService mimeTypeService; + + public SlingGenerator(SlingScriptHelper sling) { + this.request = sling.getRequest(); + this.response = sling.getResponse(); + this.mimeTypeService = sling.getService(MimeTypeService.class); + } + + public void execute() { + try { + Session session; + InputStream srcIs = genXmlSource(); + if (srcIs != null) + XMLUtils.toSax(srcIs, this.getXMLConsumer()); + else if ((session = request.getResource().adaptTo(Session.class)) != null) { + session.exportDocumentView(request.getResource().getPath(), this.getXMLConsumer(), true, true); + } else + throw new IllegalArgumentException("cannot generate xml source for " + request.getResource().getPath()); + + } catch (Throwable t) { + log.error("SlingGenerator: cannot generate xml source for " + + request.getResource().getPath(), t); + } + } + + private InputStream genXmlSource() throws Exception { + + String xmlPath = request.getResource().getPath() + "." + mimeTypeService.getExtension(XML_MIME_TYPE); + + // The source is a xml file + Resource xmlResource = this.request.getResourceResolver().resolve(xmlPath); + InputStream xmlSourceFile = xmlResource.adaptTo(InputStream.class); + if (xmlSourceFile != null) + return xmlSourceFile; + + // The source is dynamically generated + RequestDispatcher dispatcher = request.getRequestDispatcher(xmlPath); + SlingGeneratorServletOutputStream output = new SlingGeneratorServletOutputStream(); + ServletResponse newResponse = new SlingGeneratorServletResponse(response, output); + dispatcher.include(request, newResponse); + byte[] bytes = output.toByteArray(); + if (bytes.length > 0) + return new ByteArrayInputStream(bytes); + + return null; + + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/cocoon/generator/SlingGeneratorServletOutputStream.java b/src/main/java/org/apache/sling/scripting/xproc/cocoon/generator/SlingGeneratorServletOutputStream.java new file mode 100644 index 0000000..4b08602 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/cocoon/generator/SlingGeneratorServletOutputStream.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.cocoon.generator; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; + +import javax.servlet.ServletOutputStream; + +public class SlingGeneratorServletOutputStream extends ServletOutputStream { + + private final ByteArrayOutputStream output; + private final PrintWriter writer; + + public SlingGeneratorServletOutputStream() throws UnsupportedEncodingException { + this.output = new ByteArrayOutputStream(); + this.writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8")); + } + + final PrintWriter getWriter() { + return this.writer; + } + + @Override + public void write(int b) throws IOException { + this.output.write(b); + } + + final byte[] toByteArray() { + this.writer.flush(); + byte[] bytes = output.toByteArray(); + return bytes; + } + +} \ No newline at end of file diff --git a/src/main/java/org/apache/sling/scripting/xproc/cocoon/generator/SlingGeneratorServletResponse.java b/src/main/java/org/apache/sling/scripting/xproc/cocoon/generator/SlingGeneratorServletResponse.java new file mode 100644 index 0000000..112bd73 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/cocoon/generator/SlingGeneratorServletResponse.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.cocoon.generator; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletOutputStream; + +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.wrappers.SlingHttpServletResponseWrapper; + +public class SlingGeneratorServletResponse extends SlingHttpServletResponseWrapper + implements SlingHttpServletResponse { + + private SlingGeneratorServletOutputStream output; + + private boolean hasWriter = false; + private boolean hasOutputStream = false; + + public SlingGeneratorServletResponse(SlingHttpServletResponse wrappedResponse, + SlingGeneratorServletOutputStream output) { + super(wrappedResponse); + this.output = output; + } + + @Override + public PrintWriter getWriter() throws IOException { + if (this.hasOutputStream) { + throw new IllegalStateException("getOutputStream was already called."); + } + this.hasWriter = true; + return this.output.getWriter(); + } + + @Override + public ServletOutputStream getOutputStream() throws IOException { + if (this.hasWriter) { + throw new IllegalStateException("getWriter was already called."); + } + this.hasOutputStream = true; + return this.output; + } + + @Override + public int getBufferSize() { + return 1024; + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/cocoon/transform/SlingTransformer.java b/src/main/java/org/apache/sling/scripting/xproc/cocoon/transform/SlingTransformer.java new file mode 100644 index 0000000..befefba --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/cocoon/transform/SlingTransformer.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.cocoon.transform; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TemplatesHandler; +import javax.xml.transform.sax.TransformerHandler; + +import org.apache.cocoon.pipeline.component.sax.AbstractTransformer; +import org.apache.cocoon.pipeline.component.sax.XMLConsumer; +import org.apache.cocoon.pipeline.component.sax.XMLConsumerAdapter; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * A Cocoon transformer that executes XSLT + * transformations. The templates are Sling + * resources supporting to be adapted to + * {@link InputStream}. + */ +public class SlingTransformer extends AbstractTransformer { + + private SlingHttpServletRequest request; + private Map<String, Object> parameters; + private String srcAbsPath; + + public SlingTransformer() { + super(); + } + + public SlingTransformer(SlingScriptHelper sling, String srcAbsPath) { + this(sling, srcAbsPath, null); + } + + public SlingTransformer(SlingScriptHelper sling, String srcAbsPath, Map<String, Object> parameters) { + super(); + if (srcAbsPath == null) { + throw new IllegalArgumentException("The parameter 'source' mustn't be null."); + } + + this.request = sling.getRequest(); + this.parameters = parameters; + this.srcAbsPath = srcAbsPath; + } + + /** + * Test if the name is a valid parameter name for XSLT + */ + private static boolean isValidXSLTParameterName(String name) { + return name.matches("[a-zA-Z_][\\w\\-\\.]*"); + } + + @Override + public void setConfiguration(Map<String, ? extends Object> configuration) { + this.parameters = new HashMap<String, Object>(configuration); + } + + @Override + protected void setXMLConsumer(XMLConsumer consumer) { + TransformerHandler transformerHandler; + try { + transformerHandler = this.createTransformerHandler(); + } catch (Exception ex) { + throw new RuntimeException("Could not initialize transformer handler.", ex); + } + + final Map<String, Object> map = this.getLogicSheetParameters(); + if (map != null) { + final Transformer transformer = transformerHandler.getTransformer(); + + for (Entry<String, Object> entry : map.entrySet()) { + transformer.setParameter(entry.getKey(), entry.getValue()); + } + } + + final SAXResult result = new SAXResult(); + result.setHandler(consumer); + // According to TrAX specs, all TransformerHandlers are LexicalHandlers + result.setLexicalHandler(consumer); + transformerHandler.setResult(result); + + super.setXMLConsumer(new XMLConsumerAdapter(transformerHandler, transformerHandler)); + } + + private TransformerHandler createTransformerHandler() throws Exception { + SAXTransformerFactory transformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance(); + TemplatesHandler templatesHandler = transformerFactory.newTemplatesHandler(); + + XMLReader xmlReader = XMLReaderFactory.createXMLReader(); + xmlReader.setContentHandler(templatesHandler); + InputSource inputSource = new InputSource(getXsltSource()); + xmlReader.parse(inputSource); + + // Create transformer handler + final TransformerHandler handler = transformerFactory.newTransformerHandler(templatesHandler.getTemplates()); + + return handler; + } + + private Map<String, Object> getLogicSheetParameters() { + if (this.parameters == null) { + return null; + } + + Map<String, Object> result = new HashMap<String, Object>(); + + for (Entry<String, Object> entry : this.parameters.entrySet()) { + String name = entry.getKey(); + + if (isValidXSLTParameterName(name)) { + result.put(name, entry.getValue()); + } + } + + return result; + } + + /** + * Get the XSLT source. For the time being, the + * path must be absolute. + */ + private InputStream getXsltSource() throws Exception { + // The source is a xml file + Resource xmlResource = this.request.getResourceResolver().resolve(srcAbsPath); + InputStream xmlSourceFile = xmlResource.adaptTo(InputStream.class); + if (xmlSourceFile != null) + return xmlSourceFile; + return null; + + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/XplBuilder.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/XplBuilder.java new file mode 100644 index 0000000..3925962 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/XplBuilder.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl; + +import java.io.Reader; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.sling.scripting.xproc.xpl.api.Step; +import org.apache.sling.scripting.xproc.xpl.api.XplElement; +import org.apache.sling.scripting.xproc.xpl.api.XplElementFactory; +import org.apache.sling.scripting.xproc.xpl.impl.XplElementFactoryImpl; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * Builds a W3C XML Processing pipeline + * from a XPL file. + */ +public class XplBuilder { + + private XplElementFactory xplElementFactory; + + public XplBuilder() { + this.xplElementFactory = new XplElementFactoryImpl(); + } + + public Step build(Reader xplReader) throws Exception { + XMLReader xMLReader = XMLReaderFactory.createXMLReader(); + XplHandler xplHandler = new XplHandler(); + xMLReader.setContentHandler(xplHandler); + InputSource inputSource = new InputSource(xplReader); + xMLReader.parse(inputSource); + return xplHandler.getRootStep(); + } + + protected XplElement createXplElement(String localName, Map<String, String> attributes) { + return XplBuilder.this.xplElementFactory.createXplElement(new QName(XplConstants.NS_XPROC, localName), attributes); + } + + class XplHandler extends DefaultHandler { + + private XplElement currentXplElement; + private Step rootStep; + + @Override + public void endElement(String uri, String localName, String name) throws SAXException { + if (this.currentXplElement == null) { + throw new IllegalStateException("Received closing '" + localName + "' but there was no element to close."); + } + + this.currentXplElement = this.currentXplElement.getParent(); + } + + @Override + public void error(SAXParseException e) throws SAXException { + throw e; + } + + public Step getRootStep() { + return this.rootStep; + } + + @Override + public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { + if (this.currentXplElement == null) { + if (XplConstants.QNAME_PIPELINE.getLocalPart().equals(localName)) { + this.rootStep = (Step) XplBuilder.this.createXplElement(localName, null); + this.currentXplElement = this.rootStep; + return; + } + throw new IllegalStateException("Expected 'pipeline' as first element, but received '" + localName + "'"); + } + + Map<String, String> atts = new HashMap<String, String>(); + int length = attributes.getLength(); + for (int i = 0; i < length; i++) { + atts.put(attributes.getQName(i), attributes.getValue(i)); + } + + XplElement xplElement = createXplElement(localName, atts); + this.currentXplElement.addChild(xplElement); + this.currentXplElement = xplElement; + } + + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/XplConstants.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/XplConstants.java new file mode 100644 index 0000000..550e463 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/XplConstants.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl; + +import javax.xml.namespace.QName; + +public class XplConstants { + + public static final String NS_XPROC = "http://www.w3.org/ns/xproc"; + + public static final QName QNAME_PIPELINE = new QName(NS_XPROC, "pipeline"); + public static final QName QNAME_XSLT = new QName(NS_XPROC, "xslt"); + public static final QName QNAME_INPUT = new QName(NS_XPROC, "input"); + public static final QName QNAME_DOCUMENT = new QName(NS_XPROC, "document"); + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/AtomicStep.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/AtomicStep.java new file mode 100644 index 0000000..9753145 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/AtomicStep.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +public interface AtomicStep extends Step { + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/CompoundStep.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/CompoundStep.java new file mode 100644 index 0000000..0177e29 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/CompoundStep.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +import java.util.Vector; + +public interface CompoundStep extends Step { + + Vector<Step> getSubpipeline(); + + void setSubpipeline(Vector<Step> subpipeline); + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Document.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Document.java new file mode 100644 index 0000000..cc8857c --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Document.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +public interface Document extends XplElement { + + String getHref(); + + void setHref(String href); + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Environment.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Environment.java new file mode 100644 index 0000000..725f4fc --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Environment.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +import org.apache.cocoon.pipeline.Pipeline; +import org.apache.sling.api.scripting.SlingScriptHelper; + +public interface Environment { + + SlingScriptHelper getSling(); + + void setSling(SlingScriptHelper sling); + + Pipeline getCcPipeline(); + + void setCcPipeline(Pipeline ccPipeline); + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Input.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Input.java new file mode 100644 index 0000000..07474c1 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Input.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +public interface Input extends XplElement { + + String getPort(); + + void setPort(String port); + + Document getDocument(); + + void setDocument(Document document); + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/MultiContainerStep.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/MultiContainerStep.java new file mode 100644 index 0000000..7e1fc8d --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/MultiContainerStep.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +public interface MultiContainerStep extends Step { + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Pipeline.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Pipeline.java new file mode 100644 index 0000000..672cacd --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Pipeline.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +public interface Pipeline extends CompoundStep { + + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Step.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Step.java new file mode 100644 index 0000000..24e0b09 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Step.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +public interface Step extends XplElement { + + void eval() throws Exception; + + Step getContainer(); + + void setContainer(Step container); + + Environment getEnv(); + + void setEnv(Environment env); + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/XplElement.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/XplElement.java new file mode 100644 index 0000000..4b598b4 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/XplElement.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +import java.util.LinkedList; +import java.util.Map; + +import javax.xml.namespace.QName; + +public interface XplElement { + + QName getQName(); + + XplElement getParent(); + + void setAttributes(Map<String, String> attributes); + + void setParent(XplElement parent); + + LinkedList<XplElement> getChildren(); + + void addChild(XplElement child); + + int getDepth(); + + void setDepth(int depth); + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/XplElementFactory.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/XplElementFactory.java new file mode 100644 index 0000000..a2dbc39 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/XplElementFactory.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +import java.util.Map; + +import javax.xml.namespace.QName; + +public interface XplElementFactory { + + XplElement createXplElement(QName type, Map<String, String> parameters); + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Xslt.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Xslt.java new file mode 100644 index 0000000..1b31637 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/api/Xslt.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.api; + +public interface Xslt extends AtomicStep { + + Input getStylesheet(); + + void setStylesheet(Input stylesheet); + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/AbstractCompoundStepImpl.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/AbstractCompoundStepImpl.java new file mode 100644 index 0000000..09db138 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/AbstractCompoundStepImpl.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.impl; + +import java.util.Vector; + +import org.apache.sling.scripting.xproc.xpl.api.CompoundStep; +import org.apache.sling.scripting.xproc.xpl.api.Step; +import org.apache.sling.scripting.xproc.xpl.api.XplElement; + +public abstract class AbstractCompoundStepImpl extends AbstractStepImpl implements CompoundStep { + + private Vector<Step> subpipeline = new Vector<Step>(); + + @Override + public void eval() throws Exception { + for (Step step : subpipeline) { + step.eval(); + } + } + + @Override + public void addChild(XplElement child) { + super.addChild(child); + if (child instanceof Step) { + Step stepChild = (Step) child; + stepChild.setEnv(this.getEnv()); + subpipeline.add(stepChild); + } + } + + public Vector<Step> getSubpipeline() { + return subpipeline; + } + + public void setSubpipeline(Vector<Step> subpipeline) { + this.subpipeline = subpipeline; + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/AbstractStepImpl.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/AbstractStepImpl.java new file mode 100644 index 0000000..7538a19 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/AbstractStepImpl.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.impl; + +import org.apache.sling.scripting.xproc.xpl.api.Environment; +import org.apache.sling.scripting.xproc.xpl.api.Step; + +public abstract class AbstractStepImpl extends AbstractXplElementImpl implements Step { + + private Step container; + private Environment env; + + public abstract void eval() throws Exception; + + public AbstractStepImpl() { + this.env = new EnvironmentImpl(); + } + + public AbstractStepImpl(Environment env) { + this.env = env; + } + + public Step getContainer() { + return container; + } + + public void setContainer(Step container) { + this.container = container; + } + + public Environment getEnv() { + return env; + } + + public void setEnv(Environment env) { + this.env = env; + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/AbstractXplElementImpl.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/AbstractXplElementImpl.java new file mode 100644 index 0000000..6db3ef0 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/AbstractXplElementImpl.java @@ -0,0 +1,219 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.impl; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.namespace.QName; + +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.scripting.xproc.xpl.api.XplElement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractXplElementImpl implements XplElement { + + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + + private SlingScriptHelper sling; + private final Map<String, String> attributes = new HashMap<String, String>(); + private XplElement parent; + private final LinkedList<XplElement> children = new LinkedList<XplElement>(); + private int depth = 0; + + public LinkedList<XplElement> getChildren() { + return children; + } + + public void addChild(XplElement child) { + + if (child == null) { + String msg = "Element of class " + this.getClass().getName() + " received null child."; + this.log.error(msg); + throw new IllegalArgumentException(msg); + } + + Field childField = this.getChildField(child); + if (childField != null) { + childField.setAccessible(true); + try { + childField.set(this, child); + } catch (IllegalArgumentException e) { + this.log.error("Failed to set child field for child class '" + child.getClass().getName(), e); + } catch (IllegalAccessException e) { + this.log.error("Failed to set child field for child class '" + child.getClass().getName(), e); + } + } + child.setDepth(this.getDepth() + 1); + this.children.add(child); + child.setParent(this); + + } + + public void setAttributes(Map<String, String> attributes) { + if (attributes == null || attributes.isEmpty()) { + // nothing to do + return; + } + + // check for special attribute fields + Map<String, Field> attributeFields = this.getAttributeFields(); + for (Entry<String, String> entry : attributes.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + + Field attributeField = attributeFields.get(key); + if (attributeField != null) { + attributeField.setAccessible(true); + try { + attributeField.set(this, value); + } catch (IllegalArgumentException e) { + String message = "Failed to set attribute field " + key; + this.log.error(message, e); + throw new RuntimeException(message, e); + } catch (IllegalAccessException e) { + String message = "Failed to set attribute field " + key; + this.log.error(message, e); + throw new RuntimeException(message, e); + } + } + + // default attribute processing + this.processAttribute(key, value); + } + } + + public SlingScriptHelper getSling() { + return sling; + } + + public abstract QName getQName(); + + public XplElement getParent() { + return parent; + } + + public void setParent(XplElement parent) { + this.parent = parent; + } + + public int getDepth() { + return depth; + } + + public void setDepth(int depth) { + this.depth = depth; + } + + @Override + public String toString() { + StringBuffer sbXplElement = new StringBuffer(); + addTabs(sbXplElement, getDepth()); + sbXplElement.append("<"); + sbXplElement.append("p:" + this.getQName().getLocalPart()); + if (getDepth() == 0) { + sbXplElement.append(" xmlns:p=\"http://www.w3.org/ns/xproc\""); + } + for (String attribute : this.attributes.keySet()) { + sbXplElement.append(" "); + sbXplElement.append(attribute + "=" + "\"" + this.attributes.get(attribute) + "\""); + } + if (getChildren().size() == 0) { + sbXplElement.append(" />"); + return sbXplElement.toString(); + } + sbXplElement.append(">"); + for (XplElement child : this.getChildren()) { + sbXplElement.append("\r\n"); + sbXplElement.append(child.toString()); + } + sbXplElement.append("\r\n"); + addTabs(sbXplElement, getDepth()); + sbXplElement.append("</"); + sbXplElement.append("p:" + this.getQName().getLocalPart()); + sbXplElement.append(">"); + + return sbXplElement.toString(); + } + + private void addTabs(StringBuffer sb, int num) { + for (int i = 0; i < num; i++) + sb.append("\t"); + } + + protected void processAttribute(String key, String value) { + this.attributes.put(key, value); + } + + private Field getChildField(XplElement child) { + Class<?> currentClass = this.getClass(); + + Field[] declaredFields = currentClass.getDeclaredFields(); + for (Field declaredField : declaredFields) { + if (declaredField.getType().isAssignableFrom(child.getClass())) { + return declaredField; + } + } + + return null; + } + + private Map<String, Field> getAttributeFields() { + Map<String, Field> attributeFields = new HashMap<String, Field>(); + + Class<?> currentClass = this.getClass(); + while (currentClass != null) { + Field[] declaredFields = currentClass.getDeclaredFields(); + for (Field declaredField : declaredFields) { + String fieldName = this.convertCamelCase(declaredField.getName()); + attributeFields.put(fieldName, declaredField); + } + + currentClass = currentClass.getSuperclass(); + } + + return attributeFields; + } + + private String convertCamelCase(String name) { + Pattern camelCasePattern = Pattern.compile("(.)([A-Z])"); + Matcher matcher = camelCasePattern.matcher(name); + + int lastMatch = 0; + StringBuilder result = new StringBuilder(); + while (matcher.find()) { + result.append(name.substring(lastMatch, matcher.start())); + result.append(matcher.group(1)); + result.append("-"); + result.append(matcher.group(2).toLowerCase()); + lastMatch = matcher.end(); + } + + result.append(name.substring(lastMatch, name.length())); + + return result.toString(); + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/DocumentImpl.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/DocumentImpl.java new file mode 100644 index 0000000..50d297d --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/DocumentImpl.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.impl; + +import javax.xml.namespace.QName; + +import org.apache.sling.scripting.xproc.xpl.XplConstants; +import org.apache.sling.scripting.xproc.xpl.api.Document; + +public class DocumentImpl extends AbstractXplElementImpl implements Document { + + private String href; + + public String getHref() { + return href; + } + + public void setHref(String href) { + this.href = href; + } + + @Override + public QName getQName() { + return XplConstants.QNAME_DOCUMENT; + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/EnvironmentImpl.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/EnvironmentImpl.java new file mode 100644 index 0000000..f0850a8 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/EnvironmentImpl.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.impl; + +import org.apache.cocoon.pipeline.Pipeline; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.scripting.xproc.xpl.api.Environment; + +public class EnvironmentImpl implements Environment { + + private SlingScriptHelper sling; + private Pipeline ccPipeline; + + public SlingScriptHelper getSling() { + return sling; + } + + public void setSling(SlingScriptHelper sling) { + this.sling = sling; + } + + public Pipeline getCcPipeline() { + return ccPipeline; + } + + public void setCcPipeline(Pipeline ccPipeline) { + this.ccPipeline = ccPipeline; + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/InputImpl.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/InputImpl.java new file mode 100644 index 0000000..4806f1a --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/InputImpl.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.impl; + +import javax.xml.namespace.QName; + +import org.apache.sling.scripting.xproc.xpl.XplConstants; +import org.apache.sling.scripting.xproc.xpl.api.Document; +import org.apache.sling.scripting.xproc.xpl.api.Input; + +public class InputImpl extends AbstractXplElementImpl implements Input { + + private String port; + private Document document; + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + public Document getDocument() { + return document; + } + + public void setDocument(Document document) { + this.document = document; + } + + @Override + public QName getQName() { + return XplConstants.QNAME_INPUT; + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/PipelineImpl.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/PipelineImpl.java new file mode 100644 index 0000000..cad818f --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/PipelineImpl.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.impl; + +import java.io.OutputStream; + +import javax.xml.namespace.QName; + +import org.apache.cocoon.pipeline.NonCachingPipeline; +import org.apache.cocoon.pipeline.component.sax.AbstractGenerator; +import org.apache.cocoon.pipeline.component.sax.XMLSerializer; +import org.apache.sling.scripting.xproc.cocoon.generator.SlingGenerator; +import org.apache.sling.scripting.xproc.xpl.XplConstants; +import org.apache.sling.scripting.xproc.xpl.api.Pipeline; +import org.apache.sling.scripting.xproc.xpl.api.Step; + +public class PipelineImpl extends AbstractCompoundStepImpl implements Pipeline { + + @Override + public void eval() throws Exception { + try { + + this.getEnv().setCcPipeline(new NonCachingPipeline()); + + // generator + AbstractGenerator generator = new SlingGenerator(this.getEnv().getSling()); + this.getEnv().getCcPipeline().addComponent(generator); + + // subpipeline evaluated + for (Step step : this.getSubpipeline()) { + step.eval(); + } + + this.getEnv().getCcPipeline().addComponent(new XMLSerializer()); + OutputStream out = this.getEnv().getSling().getResponse().getOutputStream(); + this.getEnv().getCcPipeline().setup(out); + this.getEnv().getCcPipeline().execute(); + + } catch (Exception e) { + String absPath = this.getEnv().getSling().getRequest().getResource().getPath(); + throw new Exception("Error in pipeline for resource: " + absPath, e); + } + + } + + @Override + public QName getQName() { + return XplConstants.QNAME_PIPELINE; + } + +} \ No newline at end of file diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/XplElementFactoryImpl.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/XplElementFactoryImpl.java new file mode 100644 index 0000000..7ed22bd --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/XplElementFactoryImpl.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.impl; + +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.sling.scripting.xproc.xpl.XplConstants; +import org.apache.sling.scripting.xproc.xpl.api.XplElement; +import org.apache.sling.scripting.xproc.xpl.api.XplElementFactory; + +public class XplElementFactoryImpl implements XplElementFactory { + + public XplElement createXplElement(QName type, Map<String, String> attributes) { + + XplElement xplElement; + + if (XplConstants.QNAME_PIPELINE.equals(type)) { + xplElement = new PipelineImpl(); + } else if (XplConstants.QNAME_XSLT.equals(type)) { + xplElement = new XsltImpl(); + } else if (XplConstants.QNAME_INPUT.equals(type)) { + xplElement = new InputImpl(); + } else if (XplConstants.QNAME_DOCUMENT.equals(type)) { + xplElement = new DocumentImpl(); + } else { + throw new IllegalArgumentException("An xpl element of type '" + type + "' could not be created."); + } + + xplElement.setAttributes(attributes); + + return xplElement; + } + +} diff --git a/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/XsltImpl.java b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/XsltImpl.java new file mode 100644 index 0000000..a1a9b5b --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/xproc/xpl/impl/XsltImpl.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl.impl; + +import javax.xml.namespace.QName; + +import org.apache.sling.scripting.xproc.cocoon.transform.SlingTransformer; +import org.apache.sling.scripting.xproc.xpl.XplConstants; +import org.apache.sling.scripting.xproc.xpl.api.Input; +import org.apache.sling.scripting.xproc.xpl.api.Xslt; + +public class XsltImpl extends AbstractStepImpl implements Xslt { + + private Input stylesheet; + + @Override + public void eval() { + String href = this.getStylesheet().getDocument().getHref(); + this.getEnv().getCcPipeline().addComponent(new SlingTransformer(this.getEnv().getSling(), href)); + } + + public Input getStylesheet() { + return stylesheet; + } + + public void setStylesheet(Input stylesheet) { + this.stylesheet = stylesheet; + } + + @Override + public QName getQName() { + return XplConstants.QNAME_XSLT; + } + +} \ No newline at end of file diff --git a/src/main/resources/META-INF/DISCLAIMER b/src/main/resources/META-INF/DISCLAIMER new file mode 100644 index 0000000..90850c2 --- /dev/null +++ b/src/main/resources/META-INF/DISCLAIMER @@ -0,0 +1,7 @@ +Apache Sling is an effort undergoing incubation at The Apache Software Foundation (ASF), +sponsored by the Apache Jackrabbit PMC. Incubation is required of all newly accepted +projects until a further review indicates that the infrastructure, communications, +and decision making process have stabilized in a manner consistent with other +successful ASF projects. While incubation status is not necessarily a reflection of +the completeness or stability of the code, it does indicate that the project has yet +to be fully endorsed by the ASF. \ No newline at end of file diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/src/main/resources/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE new file mode 100644 index 0000000..32e03f4 --- /dev/null +++ b/src/main/resources/META-INF/NOTICE @@ -0,0 +1,8 @@ +Apache Sling Pipeline Scripting Support +Copyright 2008-2009 The Apache Software Foundation + +Apache Sling is based on source code originally developed +by Day Software (http://www.day.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). diff --git a/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory b/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory new file mode 100644 index 0000000..95534a7 --- /dev/null +++ b/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory @@ -0,0 +1 @@ +org.apache.sling.scripting.xproc.XProcScriptEngineFactory \ No newline at end of file diff --git a/src/test/java/org/apache/sling/scripting/xproc/xpl/XplBuilderTest.java b/src/test/java/org/apache/sling/scripting/xproc/xpl/XplBuilderTest.java new file mode 100644 index 0000000..6931670 --- /dev/null +++ b/src/test/java/org/apache/sling/scripting/xproc/xpl/XplBuilderTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.scripting.xproc.xpl; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +import org.apache.sling.scripting.xproc.xpl.api.Step; +import org.custommonkey.xmlunit.XMLAssert; +import org.custommonkey.xmlunit.XMLUnit; + +import junit.framework.TestCase; + +public class XplBuilderTest extends TestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + XMLUnit.setIgnoreComments(true); + XMLUnit.setIgnoreWhitespace(true); + } + + public void testBuild() throws Exception { + String xplPath = "/xpl/html.xpl"; + XplBuilder builder = new XplBuilder(); + Step pipeline = builder.build(getReaderFromPath(xplPath)); + String strControl = toString(getClass().getResourceAsStream(xplPath)); + XMLAssert.assertXMLEqual(strControl, pipeline.toString()); + } + + private Reader getReaderFromPath(String path) throws Exception { + InputStream is = getClass().getResourceAsStream(path); + Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8")); + return reader; + } + + private String toString(InputStream ins) throws Exception { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buf = new byte[1024]; + int rd; + while ( (rd = ins.read(buf)) >= 0) { + bos.write(buf, 0, rd); + } + bos.close(); + + return new String(bos.toByteArray(), "UTF-8"); + } + +} diff --git a/src/test/resources/xpl/html.xpl b/src/test/resources/xpl/html.xpl new file mode 100644 index 0000000..d6cc43c --- /dev/null +++ b/src/test/resources/xpl/html.xpl @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<p:pipeline xmlns:p="http://www.w3.org/ns/xproc"> + + <p:xslt> + <p:input port="stylesheet"> + <p:document href="/xpl-sample/xsl/test-content.xslt"/> + </p:input> + </p:xslt> + + <p:xslt> + <p:input port="stylesheet"> + <p:document href="/xpl-sample/xsl/test-html.xslt"/> + </p:input> + </p:xslt> + +</p:pipeline> \ No newline at end of file -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
