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.transformation;
018:
019: import org.apache.avalon.framework.parameters.Parameters;
020: import org.apache.cocoon.ProcessingException;
021: import org.apache.cocoon.environment.ObjectModelHelper;
022: import org.apache.cocoon.environment.Request;
023: import org.apache.cocoon.environment.Session;
024: import org.apache.cocoon.environment.SourceResolver;
025: import org.apache.cocoon.xml.dom.DOMBuilder;
026: import org.xml.sax.Attributes;
027: import org.xml.sax.SAXException;
028:
029: import java.io.IOException;
030: import java.util.HashMap;
031: import java.util.Iterator;
032: import java.util.Map;
033:
034: /**
035: * @cocoon.sitemap.component.documentation
036: * Make a DOM object from SAX events and write it to the session.
037: *
038: * @cocoon.sitemap.component.name writeDOMsession
039: * @cocoon.sitemap.component.logger sitemap.transformer.writeDOMsession
040: *
041: * Make a DOM object from SAX events and write it to the session.
042: *
043: * Usage in sitemap:
044: * <map:transform type="writeDOMsession">
045: * <map:parameter name="dom-name" value="content"/>
046: * <map:parameter name="dom-root-element" value="companies"/>
047: * </map:transform>
048: *
049: * Where:
050: * dom-name is the name for the DOM object in the session
051: * dom-root-element is the trigger that will be the root element of the DOM
052: *
053: * @author <a href="mailto:sven.beauprez@the-ecorp.com">Sven Beauprez</a>
054: * @version CVS $Id: WriteDOMSessionTransformer.java 515650 2007-03-07 17:11:58Z joerg $
055: */
056: public class WriteDOMSessionTransformer extends AbstractTransformer {
057:
058: public static final String DOM_NAME = "dom-name";
059: public static final String DOM_ROOT_ELEMENT = "dom-root-element";
060:
061: private boolean buildDom = false;
062: /**
063: * component was correctly setup
064: */
065: private boolean setup = false;
066:
067: private Session session;
068: private DOMBuilder builder;
069:
070: private String DOMName;
071: private String rootElement;
072: private Map storedPrefixMap;
073:
074: /**
075: * Recyclable
076: */
077: public void recycle() {
078: super .recycle();
079: this .session = null;
080: this .builder = null;
081: this .buildDom = false;
082: this .setup = false;
083: }
084:
085: /* BEGIN SitemapComponent methods */
086:
087: public void setup(SourceResolver resolver, Map objectModel,
088: String source, Parameters parameters)
089: throws ProcessingException, SAXException, IOException {
090: getLogger().debug("WriteSessionTransformer: setup");
091: Request request = ObjectModelHelper.getRequest(objectModel);
092: session = request.getSession(false);
093: if (session != null) {
094: DOMName = parameters.getParameter(
095: WriteDOMSessionTransformer.DOM_NAME, null);
096: rootElement = parameters.getParameter(
097: WriteDOMSessionTransformer.DOM_ROOT_ELEMENT, null);
098: if (DOMName != null && rootElement != null) {
099: // only now we know it is useful to store something in the session
100: getLogger()
101: .debug(
102: "WriteSessionTransformer: "
103: + WriteDOMSessionTransformer.DOM_NAME
104: + "="
105: + DOMName
106: + "; "
107: + WriteDOMSessionTransformer.DOM_ROOT_ELEMENT
108: + "=" + rootElement);
109: setup = true;
110: storedPrefixMap = new HashMap();
111: } else {
112: getLogger()
113: .error(
114: "WriteSessionTransformer: need "
115: + WriteDOMSessionTransformer.DOM_NAME
116: + " and "
117: + WriteDOMSessionTransformer.DOM_ROOT_ELEMENT
118: + " parameters");
119: }
120: } else {
121: getLogger().error(
122: "WriteSessionTransformer: no session object");
123: }
124: }
125:
126: /* END SitemapComponent methods */
127:
128: /* BEGIN SAX ContentHandler handlers */
129:
130: public void startPrefixMapping(String prefix, String uri)
131: throws SAXException {
132: super .startPrefixMapping(prefix, uri);
133: if (buildDom) {
134: builder.startPrefixMapping(prefix, uri);
135: } else if (setup) {
136: storePrefixMapping(prefix, uri);
137: }
138: }
139:
140: public void startElement(String uri, String name, String raw,
141: Attributes attributes) throws SAXException {
142: // only build the DOM tree if session is available
143: if (setup && name.equalsIgnoreCase(rootElement)) {
144: getLogger().debug(
145: "WriteSessionTransformer: start building DOM tree");
146: buildDom = true;
147: builder = new DOMBuilder();
148: builder.startDocument();
149: launchStoredMappings();
150: builder.startElement(uri, name, raw, attributes);
151: } else if (buildDom) {
152: builder.startElement(uri, name, raw, attributes);
153: }
154: super .contentHandler.startElement(uri, name, raw, attributes);
155: }
156:
157: public void endElement(String uri, String name, String raw)
158: throws SAXException {
159: if (setup && name.equalsIgnoreCase(rootElement)) {
160: buildDom = false;
161: builder.endElement(uri, name, raw);
162: builder.endDocument();
163: getLogger()
164: .debug(
165: "WriteSessionTransformer: putting DOM tree in session object");
166: session.setAttribute(DOMName, builder.getDocument()
167: .getFirstChild());
168: getLogger()
169: .debug(
170: "WriteSessionTransformer: DOM tree is in session object");
171: } else if (buildDom) {
172: builder.endElement(uri, name, raw);
173: }
174: super .contentHandler.endElement(uri, name, raw);
175: }
176:
177: public void characters(char c[], int start, int len)
178: throws SAXException {
179: if (buildDom) {
180: builder.characters(c, start, len);
181: }
182: super .contentHandler.characters(c, start, len);
183: }
184:
185: public void startCDATA() throws SAXException {
186: if (buildDom) {
187: builder.startCDATA();
188: }
189: super .lexicalHandler.startCDATA();
190: }
191:
192: public void endCDATA() throws SAXException {
193: if (buildDom) {
194: builder.endCDATA();
195: }
196: super .lexicalHandler.endCDATA();
197: }
198:
199: /* END SAX ContentHandler handlers */
200:
201: protected void storePrefixMapping(String prefix, String uri) {
202: storedPrefixMap.put(prefix, uri);
203: }
204:
205: protected void launchStoredMappings() throws SAXException {
206: Iterator it = storedPrefixMap.entrySet().iterator();
207: while (it.hasNext()) {
208: Map.Entry entry = (Map.Entry) it.next();
209: String pre = (String) entry.getKey();
210: String uri = (String) entry.getValue();
211: getLogger().debug(
212: "WriteSessionTransformer: launching prefix mapping[ pre: "
213: + pre + " uri: " + uri + " ]");
214: builder.startPrefixMapping(pre, uri);
215: }
216: }
217:
218: }
|