/* * 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.cocoon.components.language.markup; import org.apache.excalibur.xml.xslt.XSLTProcessor; import org.apache.excalibur.xml.xslt.XSLTProcessorException; import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.ServiceManager; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.components.source.SourceUtil; import org.apache.excalibur.source.Source; import org.apache.excalibur.source.SourceException; import org.apache.excalibur.source.SourceResolver; import org.xml.sax.SAXException; import javax.xml.transform.sax.TransformerHandler; import java.io.IOException; import java.net.MalformedURLException; import java.util.HashMap; import java.util.Map; /** * A code-generation logicsheet. This class is actually a wrapper for * a "standard" XSLT stylesheet stored as <code>trax.Templates</code> * object. Though this will change shortly: a new markup language * will be used for logicsheet authoring; logicsheets written in this * language will be transformed into an equivalent XSLT stylesheet * anyway... This class should probably be based on an interface... * * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a> * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a> * @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a> * @version CVS $Id$ */ public class Logicsheet extends AbstractLogEnabled { /** * The Source Resolver object for this logicsheet. */ private SourceResolver resolver; /** * The system id to resolve */ private String systemId; /** * the template namespace's list */ protected Map namespaceURIs = null; /** * The ServiceManager of this instance. */ private ServiceManager manager; /** * An optional filter to preprocess the logicsheet source code. */ private LogicsheetFilter filter; public Logicsheet(String systemId, ServiceManager manager, SourceResolver resolver, LogicsheetFilter filter) throws SAXException, IOException, SourceException, ProcessingException { this.systemId = systemId; this.manager = manager; this.resolver = resolver; this.filter = filter; } /** * Return true if other logicsheet has the same system id. */ public boolean equals(Object other) { if (other == this) return true; if (other == null) return false; if (!(other instanceof Logicsheet)) return false; Logicsheet that = (Logicsheet)other; return this.systemId.equals(that.systemId); } /** * Return hash code value for logicsheet. */ public int hashCode() { return this.systemId.hashCode(); } /** * Return system id which uniquely identifies logicsheet. */ public String getSystemId() { return this.systemId; } /** * This will return the list of namespaces in this logicsheet, * or null, if fillNamespaceURIs has not been called yet. */ public Map getNamespaceURIs() { return namespaceURIs; } /** * Fill the list of namespaces in this logicsheet. */ public void fillNamespaceURIs() throws ProcessingException { // Force the parsing of the Source which fills namespaceURIs. getTransformerHandler(); } /** * Obtain the TransformerHandler object that will perform the * transformation associated with this logicsheet. * * @return a <code>TransformerHandler</code> value */ public TransformerHandler getTransformerHandler() throws ProcessingException { XSLTProcessor xsltProcessor = null; Source source = null; try { xsltProcessor = (XSLTProcessor)this.manager.lookup(XSLTProcessor.ROLE); source = this.resolver.resolveURI( this.systemId ); // If the Source object is not changed, the // getTransformerHandler() of XSLTProcessor will simply return // the old template object. If the Source is unchanged, the // namespaces are not modified either. if (namespaceURIs == null) namespaceURIs = new HashMap(); filter.setNamespaceMap(namespaceURIs); return xsltProcessor.getTransformerHandler(source, filter); } catch (ServiceException e) { throw new ProcessingException("Could not obtain XSLT processor", e); } catch (MalformedURLException e) { throw new ProcessingException("Could not resolve " + this.systemId, e); } catch (SourceException e) { throw SourceUtil.handle("Could not resolve " + this.systemId, e); } catch (IOException e) { throw new ProcessingException("Could not resolve " + this.systemId, e); } catch (XSLTProcessorException e) { throw new ProcessingException("Could not transform " + this.systemId, e); } finally { this.manager.release(xsltProcessor); // Release used resources this.resolver.release( source ); } } }