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.template.script;
018:
019: import org.apache.cocoon.components.expression.ExpressionContext;
020: import org.apache.cocoon.template.JXTemplateGenerator;
021: import org.apache.cocoon.template.environment.ExecutionContext;
022: import org.apache.cocoon.template.environment.LocatorFacade;
023: import org.apache.cocoon.template.instruction.Call;
024: import org.apache.cocoon.template.instruction.Define;
025: import org.apache.cocoon.template.instruction.Instruction;
026: import org.apache.cocoon.template.instruction.MacroContext;
027: import org.apache.cocoon.template.script.event.Event;
028: import org.apache.cocoon.template.script.event.StartElement;
029: import org.apache.cocoon.xml.IncludeXMLConsumer;
030: import org.apache.cocoon.xml.XMLConsumer;
031: import org.apache.cocoon.xml.dom.DOMBuilder;
032: import org.apache.cocoon.xml.dom.DOMStreamer;
033: import org.apache.commons.lang.ArrayUtils;
034: import org.apache.excalibur.xml.sax.XMLizable;
035: import org.w3c.dom.Node;
036: import org.w3c.dom.NodeList;
037: import org.xml.sax.Attributes;
038: import org.xml.sax.SAXException;
039: import org.xml.sax.helpers.AttributesImpl;
040:
041: /**
042: * @version $Id: Invoker.java 449189 2006-09-23 06:52:29Z crossley $
043: */
044: public class Invoker {
045: private static final Attributes EMPTY_ATTRS = new AttributesImpl();
046:
047: public static void execute(final XMLConsumer consumer,
048: ExpressionContext expressionContext,
049: ExecutionContext executionContext,
050: MacroContext macroContext, Event startEvent, Event endEvent)
051: throws SAXException {
052:
053: Event ev = startEvent;
054: LocatorFacade loc = new LocatorFacade(ev.getLocation());
055: consumer.setDocumentLocator(loc);
056: while (ev != endEvent) {
057: loc.setDocumentLocator(ev.getLocation());
058:
059: // ContentHandler methods
060: if (ev instanceof StartElement) {
061: StartElement startElement = (StartElement) ev;
062: Define def = (Define) executionContext.getDefinitions()
063: .get(startElement.getQname());
064: if (def == null) {
065: ev = ev.execute(consumer, expressionContext,
066: executionContext, macroContext, startEvent,
067: endEvent);
068: continue;
069: }
070:
071: Call call = new Call(def, startElement);
072: ev = call.execute(consumer, expressionContext,
073: executionContext, macroContext, startEvent,
074: endEvent);
075: } else
076: ev = ev.execute(consumer, expressionContext,
077: executionContext, macroContext, startEvent,
078: endEvent);
079: }
080: }
081:
082: public static void executeNode(final XMLConsumer consumer,
083: Object val) throws SAXException {
084: executeNode(consumer, val, false);
085: }
086:
087: public static void executeNode(final XMLConsumer consumer,
088: Object val, boolean stripRoot) throws SAXException {
089: if (val instanceof Node) {
090: executeDOM(consumer, (Node) val, stripRoot);
091: } else if (val instanceof NodeList) {
092: NodeList nodeList = (NodeList) val;
093: int len = nodeList.getLength();
094: for (int i = 0; i < len; i++) {
095: Node n = nodeList.item(i);
096: //TODO: should this take stripRoot into account?
097: executeDOM(consumer, n);
098: }
099: } else if (val instanceof Node[]) {
100: Node[] nodeList = (Node[]) val;
101: int len = nodeList.length;
102: for (int i = 0; i < len; i++) {
103: Node n = nodeList[i];
104: //TODO: should this take stripRoot into account?
105: executeDOM(consumer, n);
106: }
107: } else if (val instanceof XMLizable) {
108: IncludeXMLConsumer includer = new IncludeXMLConsumer(
109: consumer);
110: includer.setIgnoreRootElement(stripRoot);
111: ((XMLizable) val).toSAX(includer);
112: } else {
113: char[] ch = val == null ? ArrayUtils.EMPTY_CHAR_ARRAY : val
114: .toString().toCharArray();
115: consumer.characters(ch, 0, ch.length);
116: }
117: }
118:
119: public static void executeDOM(final XMLConsumer consumer, Node node)
120: throws SAXException {
121: executeDOM(consumer, node, false);
122: }
123:
124: /**
125: * dump a DOM document, using an IncludeXMLConsumer to filter out start/end document events
126: */
127: public static void executeDOM(final XMLConsumer consumer,
128: Node node, boolean stripRoot) throws SAXException {
129: IncludeXMLConsumer includer = new IncludeXMLConsumer(consumer);
130: includer.setIgnoreRootElement(stripRoot);
131: DOMStreamer streamer = new DOMStreamer(includer);
132: streamer.stream(node);
133: }
134:
135: public static NodeList toDOMNodeList(String elementName,
136: Instruction si, ExpressionContext expressionContext,
137: ExecutionContext executionContext, MacroContext macroContext)
138: throws SAXException {
139: DOMBuilder builder = new DOMBuilder();
140: builder.startDocument();
141: builder.startElement(JXTemplateGenerator.NS, elementName,
142: elementName, EMPTY_ATTRS);
143: execute(builder, expressionContext, executionContext,
144: macroContext, si.getNext(), si.getEndInstruction());
145: builder.endElement(JXTemplateGenerator.NS, elementName,
146: elementName);
147: builder.endDocument();
148: Node node = builder.getDocument().getDocumentElement();
149: return node.getChildNodes();
150: }
151:
152: }
|