You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Dan Allen <da...@mojavelinux.com> on 2003/03/20 15:23:26 UTC
logic tag addition proposal
While coding my new application in struts, I came across what I deam
to be a missing feature in the struts taglibs. As I present the
problem and the solution I came up with, hopefully it will become
clear that this tag is a good idea.
On a particular page, call it a profile page, I was putting together
member information, which included a headshot, contact information
and a description. My delimmea came when I created the <html:img>
tag to the headshot. Since not every member had a headshot, the
image would appear broken in the browser if it was missing (the
headshot was just the member id + ".jpg" in the headshot directory.
The problem was, there was no way for me to know (unless i kept an
entry in the database and even that could get out of sync) whether
or not the image existed before displaying it. If the image was
missing, I would want to do something else, like either put a
placeholder image in there or just display nothing. So I came up
with an idea for a logic tag. It would look like the following
<logic:exists page="/assets/graphics/headshots/${member.id}/.jpg">
<html:img page="/assets/graphics/headshots/${member.id}/.jpg"/>
</logic:exists>
* I am also thinking it might be nice if the tag also did a "set"
call using the "id" and "toScope" like the bean define.
Right now I have it in a taglib called "file" and hence I use
<file:exists> but really, the view really shouldn't be moving around
files, so there is not real need for a whole set of file taglibs.
Below I have included the sourcecode, which I actually based off of
the struts-el library since that is what I use in my application.
Please provide any feedback and perhaps souce code changes to make
this better. I really believe this should be part of the view and
if I am the only one that thinks that, so be it, I will use my
taglibs in silence.
Dan
p.s. I still need to do logic:notExists for this, but that is a
small step. However, if someone feels it would be better to use
<core:choose> and make this a test expression, that could be good
too. I only started with java and struts 2 weeks ago, so I am still
playing catchup understanding how the taglibs are made.
package net.creativerge.taglib.file;
import java.io.File;
import javax.servlet.jsp.JspException;
import org.apache.struts.taglib.logic.ConditionalTagBase;
import org.apache.taglibs.standard.tag.common.core.NullAttributeException;
import org.apache.taglibs.standard.tag.el.core.ExpressionUtil;
public class ELExistsTag extends ConditionalTagBase
{
/**
* The module-relative path, starting with a slash character, of the
* file to be checked by this tag.
*/
protected String page = null;
/**
* Getter method for "page" tag attribute
*/
public String getPage() { return this.page; }
/**
* Setter method for "page" tag attribute
*/
public void setPage(String page) { this.page = page; }
/**
* Instance variable mapped to "page" tag attribute
*/
private String pageExpr;
/**
* Getter method for "page" tag attribute
*/
public String getPageExpr() { return pageExpr; }
/**
* Setter method for "page" tag attribute
*/
public void setPageExpr(String pageExpr) { this.pageExpr = pageExpr; }
/**
* Resets attribute values for reuse
*/
public void release()
{
super.release();
setPageExpr(null);
}
/**
* Process the start tag.
*
* @execption JspException if a jsp exception has occured
*/
public int doStartTag() throws JspException
{
evaluateExpressions();
return super.doStartTag();
}
/**
* Evaluates and returns a single attribute value, given the attribute
* name, attribute value, and attribute type. It uses
* <code>ExpressionUtil.evalNotNull</code> to do the actual evaluation, and
* it passes to this the name of the current tag, the <code>this</code>
* pointer, and the current pageContext.
*
* @param attrName attribute name being evaluated
* @param attrValue String value of attribute to be evaluated using EL
* @param attrType Required resulting type of attribute value
* @exception NullAttributeException if either the <code>attrValue</code>
* was null, or the resulting evaluated value was null.
* @return Resulting attribute value
*/
private Object evalAttr(
String attrName,
String attrValue,
Class attrType
) throws JspException, NullAttributeException
{
return ExpressionUtil.evalNotNull("exists", attrName, attrValue, attrType, this, pageContext);
}
/**
* Processes all attribute values which use the JSTL expression evaluation
* engine to determine their values. If any evaluation fails with a
* <code>NullAttributeException</code> it will just use <code>null</code>
* as the value.
*
* @exception JspException if a JSP exception has occurred
*/
public void evaluateExpressions() throws JspException
{
try
{
setPage((String) evalAttr("page", getPageExpr(), String.class));
}
catch (NullAttributeException e)
{
}
}
/**
* Evaluate the condition that is being tested by this particular tag,
* and return <code>true</code> if the nested body content of this tag
* should be evaluated, or <code>false</code> if it should be skipped.
* This method must be implemented by concrete subclasses.
*
* @exception JspException if a JSP exception occurs
*/
protected boolean condition() throws JspException
{
return condition(true);
}
/**
* Evaluate the condition that is being tested by this particular tag,
* and return <code>true</code> if the nested body content of this tag
* should be evaluated, or <code>false</code> if it should be skipped.
* This method must be implemented by concrete subclasses.
*
* @param desired Desired outcome for a true result
*
* @exception JspException if a JSP exception occurs
*/
protected boolean condition(boolean desired) throws JspException
{
boolean exists = false;
if (page != null)
{
exists = new File(pageContext.getServletContext().getRealPath(page)).exists();
}
return (exists == desired);
}
}
package net.creativerge.taglib.file;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;
/**
* This is the <code>BeanInfo</code> descriptor for the
* <code>net.creativerge.taglib.file.ELExistsTag</code> class. It is
* needed to override the default mapping of custom tag attribute names to
* class attribute names.
*<p>
* In particular, it provides for the mapping of the custom tag attribute
* <code>collection</code> to the class attribute <code>collectionExpr</code>.
*<p>
*/
public class ELExistsTagBeanInfo extends SimpleBeanInfo
{
public PropertyDescriptor[] getPropertyDescriptors()
{
PropertyDescriptor[] result = new PropertyDescriptor[1];
try
{
result[0] = new PropertyDescriptor("page", ELExistsTag.class, null, "setPageExpr");
}
catch (IntrospectionException e)
{
e.printStackTrace();
}
return result;
}
}
--
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Daniel Allen, <da...@mojavelinux.com>
http://www.mojavelinux.com/
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"If you are going to play the game of trial and error,
don't be suprised when the results are revealing. -- me"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org