| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.cocoon.template; |
| |
| import java.io.IOException; |
| import java.io.Serializable; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.apache.avalon.framework.parameters.Parameters; |
| import org.apache.avalon.framework.service.ServiceException; |
| import org.apache.avalon.framework.service.ServiceManager; |
| import org.apache.cocoon.ProcessingException; |
| import org.apache.cocoon.caching.CacheableProcessingComponent; |
| import org.apache.cocoon.components.expression.ExpressionContext; |
| import org.apache.cocoon.environment.SourceResolver; |
| import org.apache.cocoon.generation.ServiceableGenerator; |
| import org.apache.cocoon.template.environment.ExecutionContext; |
| import org.apache.cocoon.template.environment.FlowObjectModelHelper; |
| import org.apache.cocoon.template.environment.JXCacheKey; |
| import org.apache.cocoon.template.environment.JXSourceValidity; |
| import org.apache.cocoon.template.expression.JXTExpression; |
| import org.apache.cocoon.template.script.Invoker; |
| import org.apache.cocoon.template.script.ScriptManager; |
| import org.apache.cocoon.template.script.event.Event; |
| import org.apache.cocoon.template.script.event.StartDocument; |
| import org.apache.cocoon.template.xml.AttributeAwareXMLConsumerImpl; |
| import org.apache.cocoon.xml.RedundantNamespacesFilter; |
| import org.apache.cocoon.xml.XMLConsumer; |
| import org.apache.excalibur.source.SourceValidity; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * @cocoon.sitemap.component.documentation Provides a generic page template with |
| * embedded JSTL and XPath expression |
| * substitution to access data sent by |
| * Cocoon Flowscripts. |
| * |
| * @cocoon.sitemap.component.name jx |
| * @cocoon.sitemap.component.label content |
| * @cocoon.sitemap.component.logger sitemap.generator.jx |
| * |
| * @cocoon.sitemap.component.pooling.max 16 |
| * |
| * |
| * @version $Id$ |
| */ |
| public class JXTemplateGenerator |
| extends ServiceableGenerator |
| implements CacheableProcessingComponent { |
| |
| /** The namespace used by this generator */ |
| public final static String NS = "http://apache.org/cocoon/templates/jx/1.0"; |
| |
| public final static String CACHE_KEY = "cache-key"; |
| public final static String VALIDITY = "cache-validity"; |
| |
| private ExpressionContext expressionContext; |
| private ScriptManager scriptManager; |
| |
| private StartDocument startDocument; |
| private Map definitions; |
| |
| public XMLConsumer getConsumer() { |
| return this.xmlConsumer; |
| } |
| |
| /** |
| * @see org.apache.cocoon.generation.ServiceableGenerator#service(org.apache.avalon.framework.service.ServiceManager) |
| */ |
| public void service(ServiceManager manager) throws ServiceException { |
| super.service(manager); |
| this.scriptManager = (ScriptManager) this.manager.lookup(ScriptManager.ROLE); |
| } |
| |
| /** |
| * @see org.apache.cocoon.generation.ServiceableGenerator#dispose() |
| */ |
| public void dispose() { |
| if ( this.manager != null ) { |
| this.manager.release(this.scriptManager); |
| this.scriptManager = null; |
| } |
| super.dispose(); |
| } |
| |
| /** |
| * @see org.apache.cocoon.generation.AbstractGenerator#recycle() |
| */ |
| public void recycle() { |
| this.startDocument = null; |
| this.expressionContext = null; |
| this.definitions = null; |
| super.recycle(); |
| } |
| |
| /** |
| * @see org.apache.cocoon.generation.AbstractGenerator#setup(org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters) |
| */ |
| public void setup(SourceResolver resolver, Map objectModel, String src, Parameters parameters) |
| throws ProcessingException, SAXException, IOException { |
| |
| super.setup(resolver, objectModel, src, parameters); |
| // src can be null if this generator is triggered by the jxt transformer (through the TransformerAdapter) |
| if ( src != null ) { |
| this.startDocument = scriptManager.resolveTemplate(src); |
| } |
| |
| this.expressionContext = FlowObjectModelHelper.getFOMExpressionContext(objectModel, parameters); |
| this.definitions = new HashMap(); |
| } |
| |
| /** |
| * @see org.apache.cocoon.generation.Generator#generate() |
| */ |
| public void generate() throws IOException, SAXException, ProcessingException { |
| performGeneration(this.startDocument, null); |
| |
| // no need to reference compiled script anymore |
| this.startDocument = null; |
| } |
| |
| public void performGeneration(Event startEvent, Event endEvent) throws SAXException { |
| XMLConsumer consumer = new AttributeAwareXMLConsumerImpl(new RedundantNamespacesFilter(this.xmlConsumer)); |
| ((Map) expressionContext.get("cocoon")).put("consumer", consumer); |
| Invoker.execute(consumer, this.expressionContext, new ExecutionContext(this.definitions, this.scriptManager, |
| this.manager), null, startEvent, null); |
| } |
| |
| /** |
| * @see org.apache.cocoon.caching.CacheableProcessingComponent#getKey() |
| */ |
| public Serializable getKey() { |
| JXTExpression cacheKeyExpr = (JXTExpression) this.startDocument |
| .getTemplateProperty(JXTemplateGenerator.CACHE_KEY); |
| if (cacheKeyExpr == null) { |
| return null; |
| } |
| try { |
| final Serializable templateKey = (Serializable) cacheKeyExpr.getValue(this.expressionContext); |
| if (templateKey != null) { |
| return new JXCacheKey(this.startDocument.getUri(), templateKey); |
| } |
| } catch (Exception e) { |
| getLogger().error("error evaluating cache key", e); |
| } |
| return null; |
| } |
| |
| /** |
| * @see org.apache.cocoon.caching.CacheableProcessingComponent#getValidity() |
| */ |
| public SourceValidity getValidity() { |
| JXTExpression validityExpr = (JXTExpression) this.startDocument |
| .getTemplateProperty(JXTemplateGenerator.VALIDITY); |
| if (validityExpr == null) { |
| return null; |
| } |
| try { |
| final SourceValidity sourceValidity = this.startDocument.getSourceValidity(); |
| final SourceValidity templateValidity = (SourceValidity) validityExpr.getValue(this.expressionContext); |
| if (sourceValidity != null && templateValidity != null) { |
| return new JXSourceValidity(sourceValidity, templateValidity); |
| } |
| } catch (Exception e) { |
| getLogger().error("error evaluating cache validity", e); |
| } |
| return null; |
| } |
| } |