001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.language.markup;
018:
019: import org.apache.excalibur.xml.xslt.XSLTProcessor;
020: import org.apache.excalibur.xml.xslt.XSLTProcessorException;
021: import org.apache.avalon.framework.logger.AbstractLogEnabled;
022: import org.apache.avalon.framework.service.ServiceException;
023: import org.apache.avalon.framework.service.ServiceManager;
024: import org.apache.cocoon.ProcessingException;
025: import org.apache.cocoon.components.source.SourceUtil;
026: import org.apache.excalibur.source.Source;
027: import org.apache.excalibur.source.SourceException;
028: import org.apache.excalibur.source.SourceResolver;
029: import org.xml.sax.SAXException;
030:
031: import javax.xml.transform.sax.TransformerHandler;
032:
033: import java.io.IOException;
034: import java.net.MalformedURLException;
035: import java.util.HashMap;
036: import java.util.Map;
037:
038: /**
039: * A code-generation logicsheet. This class is actually a wrapper for
040: * a "standard" XSLT stylesheet stored as <code>trax.Templates</code>
041: * object. Though this will change shortly: a new markup language
042: * will be used for logicsheet authoring; logicsheets written in this
043: * language will be transformed into an equivalent XSLT stylesheet
044: * anyway... This class should probably be based on an interface...
045: *
046: * @author <a href="mailto:ricardo@apache.org">Ricardo Rocha</a>
047: * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
048: * @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
049: * @version CVS $Id: Logicsheet.java 433543 2006-08-22 06:22:54Z crossley $
050: */
051: public class Logicsheet extends AbstractLogEnabled {
052: /**
053: * The Source Resolver object for this logicsheet.
054: */
055: private SourceResolver resolver;
056:
057: /**
058: * The system id to resolve
059: */
060: private String systemId;
061:
062: /**
063: * the template namespace's list
064: */
065: protected Map namespaceURIs = null;
066:
067: /**
068: * The ServiceManager of this instance.
069: */
070: private ServiceManager manager;
071:
072: /**
073: * An optional filter to preprocess the logicsheet source code.
074: */
075: private LogicsheetFilter filter;
076:
077: public Logicsheet(String systemId, ServiceManager manager,
078: SourceResolver resolver, LogicsheetFilter filter)
079: throws SAXException, IOException, SourceException,
080: ProcessingException {
081: this .systemId = systemId;
082: this .manager = manager;
083: this .resolver = resolver;
084: this .filter = filter;
085: }
086:
087: /**
088: * Return true if other logicsheet has the same system id.
089: */
090: public boolean equals(Object other) {
091: if (other == this )
092: return true;
093: if (other == null)
094: return false;
095: if (!(other instanceof Logicsheet))
096: return false;
097: Logicsheet that = (Logicsheet) other;
098: return this .systemId.equals(that.systemId);
099: }
100:
101: /**
102: * Return hash code value for logicsheet.
103: */
104: public int hashCode() {
105: return this .systemId.hashCode();
106: }
107:
108: /**
109: * Return system id which uniquely identifies logicsheet.
110: */
111: public String getSystemId() {
112: return this .systemId;
113: }
114:
115: /**
116: * This will return the list of namespaces in this logicsheet,
117: * or null, if fillNamespaceURIs has not been called yet.
118: */
119: public Map getNamespaceURIs() {
120: return namespaceURIs;
121: }
122:
123: /**
124: * Fill the list of namespaces in this logicsheet.
125: */
126: public void fillNamespaceURIs() throws ProcessingException {
127: // Force the parsing of the Source which fills namespaceURIs.
128: getTransformerHandler();
129: }
130:
131: /**
132: * Obtain the TransformerHandler object that will perform the
133: * transformation associated with this logicsheet.
134: *
135: * @return a <code>TransformerHandler</code> value
136: */
137: public TransformerHandler getTransformerHandler()
138: throws ProcessingException {
139: XSLTProcessor xsltProcessor = null;
140: Source source = null;
141: try {
142: xsltProcessor = (XSLTProcessor) this .manager
143: .lookup(XSLTProcessor.ROLE);
144: source = this .resolver.resolveURI(this .systemId);
145:
146: // If the Source object is not changed, the
147: // getTransformerHandler() of XSLTProcessor will simply return
148: // the old template object. If the Source is unchanged, the
149: // namespaces are not modified either.
150: if (namespaceURIs == null)
151: namespaceURIs = new HashMap();
152: filter.setNamespaceMap(namespaceURIs);
153: return xsltProcessor.getTransformerHandler(source, filter);
154:
155: } catch (ServiceException e) {
156: throw new ProcessingException(
157: "Could not obtain XSLT processor", e);
158: } catch (MalformedURLException e) {
159: throw new ProcessingException("Could not resolve "
160: + this .systemId, e);
161: } catch (SourceException e) {
162: throw SourceUtil.handle("Could not resolve "
163: + this .systemId, e);
164: } catch (IOException e) {
165: throw new ProcessingException("Could not resolve "
166: + this .systemId, e);
167: } catch (XSLTProcessorException e) {
168: throw new ProcessingException("Could not transform "
169: + this .systemId, e);
170: } finally {
171: this .manager.release(xsltProcessor);
172: // Release used resources
173: this.resolver.release(source);
174: }
175: }
176: }
|