David
From: Dan Allen <[EMAIL PROTECTED]> Reply-To: "Struts Users Mailing List" <[EMAIL PROTECTED]> To: Struts-User List <[EMAIL PROTECTED]> Subject: logic tag addition proposal Date: Thu, 20 Mar 2003 08:23:26 -0600
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, <[EMAIL PROTECTED]> 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
_________________________________________________________________
Add photos to your messages with MSN 8. Get 2 months FREE*. http://join.msn.com/?page=features/featuredemail
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]