blob: 8b221f3cb0c504e19dea3ed6f054ae60d693ba6e [file] [log] [blame]
/*
* 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;
}
}