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.instruction;
018:
019: import java.util.Iterator;
020: import java.util.Stack;
021:
022: import org.apache.cocoon.ProcessingException;
023: import org.apache.cocoon.components.expression.ExpressionContext;
024: import org.apache.cocoon.environment.TemplateObjectModelHelper;
025: import org.apache.cocoon.template.environment.ErrorHolder;
026: import org.apache.cocoon.template.environment.ExecutionContext;
027: import org.apache.cocoon.template.environment.ParsingContext;
028: import org.apache.cocoon.template.expression.JXTExpression;
029: import org.apache.cocoon.template.expression.Literal;
030: import org.apache.cocoon.template.expression.Subst;
031: import org.apache.cocoon.template.script.Invoker;
032: import org.apache.cocoon.template.script.event.AttributeEvent;
033: import org.apache.cocoon.template.script.event.CopyAttribute;
034: import org.apache.cocoon.template.script.event.Event;
035: import org.apache.cocoon.template.script.event.StartDocument;
036: import org.apache.cocoon.template.script.event.StartElement;
037: import org.apache.cocoon.template.script.event.SubstituteAttribute;
038: import org.apache.cocoon.xml.XMLConsumer;
039: import org.xml.sax.Attributes;
040: import org.xml.sax.Locator;
041: import org.xml.sax.SAXException;
042: import org.xml.sax.SAXParseException;
043:
044: /**
045: * @version SVN $Id: Import.java 449189 2006-09-23 06:52:29Z crossley $
046: */
047: public class Import extends Instruction {
048:
049: private final AttributeEvent uri;
050: private final JXTExpression select;
051:
052: public Import(ParsingContext parsingContext, StartElement raw,
053: Attributes attrs, Stack stack) throws SAXException {
054:
055: super (raw);
056:
057: // <import uri="${root}/foo/bar.xml" context="${foo}"/>
058: Locator locator = getLocation();
059: Iterator iter = raw.getAttributeEvents().iterator();
060: AttributeEvent uri = null;
061: JXTExpression select = null;
062: while (iter.hasNext()) {
063: AttributeEvent e = (AttributeEvent) iter.next();
064: if (e.getLocalName().equals("uri")) {
065: uri = e;
066: break;
067: }
068: }
069: if (uri != null) {
070: // If "context" is present then its value will be used
071: // as the context object in the imported template
072: String context = attrs.getValue("context");
073: if (context != null) {
074: select = parsingContext.getStringTemplateParser()
075: .compileExpr(context, "import: \"context\": ",
076: locator);
077: }
078: } else {
079: throw new SAXParseException("import: \"uri\" is required",
080: locator, null);
081: }
082: this .uri = uri;
083: this .select = select;
084: }
085:
086: public Event execute(final XMLConsumer consumer,
087: ExpressionContext expressionContext,
088: ExecutionContext executionContext,
089: MacroContext macroContext, Event startEvent, Event endEvent)
090: throws SAXException {
091: String uri;
092: AttributeEvent e = this .uri;
093: if (e instanceof CopyAttribute) {
094: CopyAttribute copy = (CopyAttribute) e;
095: uri = copy.getValue();
096: } else {
097: StringBuffer buf = new StringBuffer();
098: SubstituteAttribute substAttr = (SubstituteAttribute) e;
099: Iterator i = substAttr.getSubstitutions().iterator();
100: while (i.hasNext()) {
101: Subst subst = (Subst) i.next();
102: if (subst instanceof Literal) {
103: Literal lit = (Literal) subst;
104: buf.append(lit.getValue());
105: } else if (subst instanceof JXTExpression) {
106: JXTExpression expr = (JXTExpression) subst;
107: Object val;
108: try {
109: val = expr.getValue(expressionContext);
110: } catch (Exception exc) {
111: throw new SAXParseException(exc.getMessage(),
112: getLocation(), exc);
113: } catch (Error err) {
114: throw new SAXParseException(err.getMessage(),
115: getLocation(), new ErrorHolder(err));
116: }
117: buf.append(val != null ? val.toString() : "");
118: }
119: }
120: uri = buf.toString();
121: }
122: StartDocument doc;
123: try {
124: doc = executionContext.getScriptManager().resolveTemplate(
125: uri);
126: } catch (ProcessingException exc) {
127: throw new SAXParseException(exc.getMessage(),
128: getLocation(), exc);
129: }
130: ExpressionContext selectExpressionContext = expressionContext;
131: if (this .select != null) {
132: try {
133: Object obj = this .select.getValue(expressionContext);
134: selectExpressionContext = new ExpressionContext(
135: expressionContext);
136: selectExpressionContext.setContextBean(obj);
137: TemplateObjectModelHelper.fillContext(obj,
138: selectExpressionContext);
139: } catch (Exception exc) {
140: throw new SAXParseException(exc.getMessage(),
141: getLocation(), exc);
142: } catch (Error err) {
143: throw new SAXParseException(err.getMessage(),
144: getLocation(), new ErrorHolder(err));
145: }
146: }
147: try {
148: Invoker.execute(consumer, expressionContext,
149: executionContext, macroContext, doc.getNext(), doc
150: .getEndDocument());
151: } catch (Exception exc) {
152: throw new SAXParseException(
153: "Exception occurred in imported template " + uri
154: + ": " + exc.getMessage(), getLocation(),
155: exc);
156: }
157: return getEndInstruction().getNext();
158: }
159: }
|