001: /*
002: * Copyright 2004 Outerthought bvba and Schaubroeck nv
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.outerj.daisy.frontend;
017:
018: import org.apache.cocoon.transformation.AbstractTransformer;
019: import org.apache.cocoon.environment.SourceResolver;
020: import org.apache.cocoon.environment.ObjectModelHelper;
021: import org.apache.cocoon.environment.Request;
022: import org.apache.cocoon.ProcessingException;
023: import org.apache.cocoon.xml.IncludeXMLConsumer;
024: import org.apache.avalon.framework.parameters.Parameters;
025: import org.apache.avalon.framework.service.Serviceable;
026: import org.apache.avalon.framework.service.ServiceManager;
027: import org.apache.avalon.framework.service.ServiceException;
028: import org.apache.avalon.framework.context.Contextualizable;
029: import org.apache.avalon.framework.context.Context;
030: import org.apache.avalon.framework.context.ContextException;
031: import org.apache.avalon.framework.activity.Disposable;
032: import org.apache.xmlbeans.XmlObject;
033: import org.apache.xmlbeans.XmlSaxHandler;
034: import org.apache.xmlbeans.XmlException;
035: import org.xml.sax.SAXException;
036: import org.xml.sax.Attributes;
037: import org.xml.sax.Locator;
038: import org.xml.sax.ContentHandler;
039: import org.outerj.daisy.frontend.components.siteconf.SiteConf;
040: import org.outerj.daisy.repository.Repository;
041: import org.outerj.daisy.repository.RepositoryException;
042: import org.outerj.daisy.publisher.Publisher;
043: import org.outerx.daisy.x10Publisher.PublisherRequestDocument;
044:
045: import java.util.Map;
046: import java.io.IOException;
047:
048: /**
049: * A transformer which intercepts publisher requests (p:publisherRequest elements),
050: * sends them to the publisher component, and inserts the publishers' response into
051: * the SAX stream (in place of the request).
052: */
053: public class PublisherTransformer extends AbstractTransformer implements
054: Serviceable, Contextualizable, Disposable {
055: private static final String NAMESPACE = "http://outerx.org/daisy/1.0#publisher";
056: private ServiceManager serviceManager;
057: private Repository repository;
058: private boolean inPublisherRequest;
059: private XmlSaxHandler xmlSaxHandler;
060: private int publisherRequestElementNestingCount;
061: private Request request;
062: private FrontEndContext frontEndContext;
063: private Context context;
064: private PageContext pageContext;
065:
066: public void service(ServiceManager serviceManager)
067: throws ServiceException {
068: this .serviceManager = serviceManager;
069: }
070:
071: public void contextualize(Context context) throws ContextException {
072: this .context = context;
073: }
074:
075: public void setup(SourceResolver sourceResolver, Map objectModel,
076: String src, Parameters parameters)
077: throws ProcessingException, SAXException, IOException {
078: request = ObjectModelHelper.getRequest(objectModel);
079: frontEndContext = FrontEndContext.get(request);
080: try {
081: this .repository = frontEndContext.getRepository();
082: } catch (Exception e) {
083: throw new ProcessingException(e);
084: }
085:
086: this .inPublisherRequest = false;
087: this .pageContext = frontEndContext.getPageContext();
088: }
089:
090: public void dispose() {
091: this .repository = null;
092: this .xmlSaxHandler = null;
093: this .request = null;
094: this .pageContext = null;
095: }
096:
097: public void startElement(String namespaceURI, String localName,
098: String qName, Attributes atts) throws SAXException {
099: if (inPublisherRequest) {
100: xmlSaxHandler.getContentHandler().startElement(
101: namespaceURI, localName, qName, atts);
102: publisherRequestElementNestingCount++;
103: } else if (localName.equals("publisherRequest")
104: && namespaceURI.equals(NAMESPACE)) {
105: inPublisherRequest = true;
106: publisherRequestElementNestingCount = 0;
107: xmlSaxHandler = XmlObject.Factory.newXmlSaxHandler();
108: xmlSaxHandler.getContentHandler().startElement(
109: namespaceURI, localName, qName, atts);
110: } else {
111: super .startElement(namespaceURI, localName, qName, atts);
112: }
113: }
114:
115: public void endElement(String namespaceURI, String localName,
116: String qName) throws SAXException {
117: if (inPublisherRequest
118: && publisherRequestElementNestingCount == 0) {
119: xmlSaxHandler.getContentHandler().endElement(namespaceURI,
120: localName, qName);
121: inPublisherRequest = false;
122:
123: // serialize the request and send it to the publisher
124: XmlObject requestAsXmlObject;
125: try {
126: requestAsXmlObject = xmlSaxHandler.getObject();
127: } catch (XmlException e) {
128: throw new SAXException(
129: "Error getting recorded publisher request as XmlObject.",
130: e);
131: }
132:
133: PublisherRequestDocument publisherRequestDocument = (PublisherRequestDocument) requestAsXmlObject
134: .changeType(PublisherRequestDocument.type);
135: if (publisherRequestDocument == null)
136: throw new SAXException(
137: "Could not change the type of the XmlObject to PublisherRequestDocument.");
138:
139: Publisher publisher = (Publisher) repository
140: .getExtension("Publisher");
141: try {
142: publisher
143: .processRequest(
144: publisherRequestDocument,
145: new IncludeXMLConsumer(
146: createPreparedDocumentsHandler(contentHandler)));
147: } catch (RepositoryException e) {
148: throw new SAXException("Error calling publisher.", e);
149: }
150:
151: xmlSaxHandler = null;
152:
153: } else if (inPublisherRequest) {
154: publisherRequestElementNestingCount--;
155: xmlSaxHandler.getContentHandler().endElement(namespaceURI,
156: localName, qName);
157: } else {
158: super .endElement(namespaceURI, localName, qName);
159: }
160: }
161:
162: private PreparedDocumentsHandler createPreparedDocumentsHandler(
163: ContentHandler consumer) throws SAXException {
164: String mountPoint = frontEndContext.getMountPoint();
165: SiteConf siteConf = frontEndContext.getSiteConf();
166: String daisyCocoonPath = frontEndContext.getDaisyCocoonPath();
167: String basePath = mountPoint + "/" + siteConf + "/";
168:
169: Repository repository;
170: try {
171: repository = frontEndContext.getRepository();
172: } catch (Exception e) {
173: throw new SAXException(e);
174: }
175: String publishType = (String) request
176: .getAttribute("documentStylingPublishType");
177:
178: DocumentTypeSpecificStyler.StylesheetProvider stylesheetProvider = new WikiStylesheetProvider(
179: publishType, serviceManager);
180:
181: DocumentTypeSpecificStyler documentTypeSpecificStyler = new DocumentTypeSpecificStyler(
182: publishType, basePath, daisyCocoonPath,
183: stylesheetProvider, pageContext, repository, context,
184: serviceManager);
185: return new PreparedDocumentsHandler(consumer, request,
186: documentTypeSpecificStyler);
187: }
188:
189: public void setDocumentLocator(Locator locator) {
190: if (!inPublisherRequest)
191: super .setDocumentLocator(locator);
192: }
193:
194: public void startDocument() throws SAXException {
195: super .startDocument();
196: }
197:
198: public void endDocument() throws SAXException {
199: super .endDocument();
200: }
201:
202: public void startPrefixMapping(String prefix, String uri)
203: throws SAXException {
204: if (inPublisherRequest)
205: xmlSaxHandler.getContentHandler().startPrefixMapping(
206: prefix, uri);
207: else
208: super .startPrefixMapping(prefix, uri);
209: }
210:
211: public void endPrefixMapping(String prefix) throws SAXException {
212: if (inPublisherRequest)
213: xmlSaxHandler.getContentHandler().endPrefixMapping(prefix);
214: else
215: super .endPrefixMapping(prefix);
216: }
217:
218: public void characters(char ch[], int start, int length)
219: throws SAXException {
220: if (inPublisherRequest)
221: xmlSaxHandler.getContentHandler().characters(ch, start,
222: length);
223: else
224: super .characters(ch, start, length);
225: }
226:
227: public void ignorableWhitespace(char[] chars, int start, int length)
228: throws SAXException {
229: if (!inPublisherRequest)
230: super .ignorableWhitespace(chars, start, length);
231: }
232:
233: public void processingInstruction(String s, String s1)
234: throws SAXException {
235: if (!inPublisherRequest)
236: super .processingInstruction(s, s1);
237: }
238:
239: public void skippedEntity(String s) throws SAXException {
240: if (!inPublisherRequest)
241: super .skippedEntity(s);
242: }
243:
244: public void startDTD(String s, String s1, String s2)
245: throws SAXException {
246: if (!inPublisherRequest)
247: super .startDTD(s, s1, s2);
248: }
249:
250: public void endDTD() throws SAXException {
251: if (!inPublisherRequest)
252: super .endDTD();
253: }
254:
255: public void startEntity(String s) throws SAXException {
256: if (!inPublisherRequest)
257: super .startEntity(s);
258: }
259:
260: public void endEntity(String s) throws SAXException {
261: if (!inPublisherRequest)
262: super .endEntity(s);
263: }
264:
265: public void startCDATA() throws SAXException {
266: if (!inPublisherRequest)
267: super .startCDATA();
268: }
269:
270: public void endCDATA() throws SAXException {
271: if (!inPublisherRequest)
272: super .endCDATA();
273: }
274:
275: public void comment(char[] chars, int i, int i1)
276: throws SAXException {
277: if (!inPublisherRequest)
278: super.comment(chars, i, i1);
279: }
280:
281: }
|