blob: 9383b53bbe91155649ec69bc25898fc413a5ce44 [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed 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.taglib;
import java.util.Map;
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.environment.Context;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.SourceResolver;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
/**
* Abstract implementation for all Tags
*
* @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
* @version CVS $Id: TagSupport.java,v 1.3 2004/03/05 13:02:24 bdelacretaz Exp $
*/
public abstract class TagSupport extends AbstractLogEnabled implements Tag, Recyclable {
protected String var;
protected Tag parent;
protected SourceResolver resolver;
protected Map objectModel;
protected Parameters parameters;
private Request request;
/**
* Find the instance of a given class type that is closest to a given
* instance.
* This method uses the getParent method from the Tag
* interface.
* This method is used for coordination among cooperating tags.
*
* @param from The instance from where to start looking.
* @param klass The subclass of Tag or interface to be matched
* @return the nearest ancestor that implements the interface
* or is an instance of the class specified
*/
public static final Tag findAncestorWithClass(Tag from, Class klass) {
boolean isInterface = false;
if (from == null || klass == null || (!Tag.class.isAssignableFrom(klass) && !(isInterface = klass.isInterface()))) {
return null;
}
for (;;) {
Tag tag = from.getParent();
if (tag == null) {
return null;
}
if ((isInterface && klass.isInstance(tag)) || klass.isAssignableFrom(tag.getClass()))
return tag;
else
from = tag;
}
}
/**
* Process the end tag for this instance.
*
* @return EVAL_PAGE.
* @throws SAXException
*/
public int doEndTag(String namespaceURI, String localName, String qName) throws SAXException {
return EVAL_PAGE;
}
/**
* Process the start tag for this instance.
* <p>
* The doStartTag method assumes that pageContext and
* parent have been set. It also assumes that any properties exposed as
* attributes have been set too. When this method is invoked, the body
* has not yet been evaluated.
*
* @return EVAL_BODY or SKIP_BODY.
*/
public int doStartTag(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
return EVAL_BODY;
}
/**
* Searches for the named attribute in request, session (if valid),
* and application scope(s) in order and returns the value associated or
* null.
*
* @return the value associated or null
*/
public final Object findAttribute(String name) {
if (request == null)
request = ObjectModelHelper.getRequest(objectModel);
Object o = request.getAttribute(name);
if (o != null)
return o;
Session session = request.getSession(false);
if (session != null) {
o = session.getAttribute(name);
if (o != null)
return o;
}
Context context = ObjectModelHelper.getContext(objectModel);
return context.getAttribute(name);
}
/**
* Get the parent (closest enclosing tag handler) for this tag handler.
*
* @return the current parent, or null if none.
*/
public final Tag getParent() {
return parent;
}
public void recycle() {
getLogger().debug("recycle");
this.var = null;
this.parent = null;
this.resolver = null;
this.objectModel = null;
this.parameters = null;
this.request = null;
}
/**
* Set the parent (closest enclosing tag handler) of this tag handler.
* Invoked by the TagTransformer prior to doStartTag().
* <p>
* This value is *not* reset by doEndTag() and must be explicitly reset
* by a Tag implementation.
*
* @param parent the parent tag, or null.
*/
public final void setParent(Tag parent) {
this.parent = parent;
}
/**
* Set the <code>SourceResolver</code>, objectModel <code>Map</code>
* and sitemap <code>Parameters</code> used to process the request.
*/
public void setup(SourceResolver resolver, Map objectModel, Parameters parameters) {
this.resolver = resolver;
this.objectModel = objectModel;
this.parameters = parameters;
}
}