Update of /cvsroot/xdoclet/xdoclet/modules/ejb/src/xdoclet/modules/ejb/env In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12138/modules/ejb/src/xdoclet/modules/ejb/env
Added Files: EnvTagsHandler.java EnvEjbRefTagsHandler.java Log Message: added easier environment handling (XDT-1325) --- NEW FILE: EnvTagsHandler.java --- /* * Copyright (c) 2001, 2002 The XDoclet team * All rights reserved. */ package xdoclet.modules.ejb.env; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; import xjavadoc.XField; import xjavadoc.XMember; import xjavadoc.XMethod; import xjavadoc.XTag; import xdoclet.XDocletException; import xdoclet.XDocletTagSupport; import xdoclet.util.TypeConversionUtil; /** * Handles field level tag's for configuring a bean's environment. * * @author <a href="mailto:[EMAIL PROTECTED]">Matthias Germann</a> * @created March 31, 2005 * @xdoclet.taghandler namespace="EjbEnv" * @version $Revision: 1.1 $ */ public class EnvTagsHandler extends XDocletTagSupport { /** * The tags for which a value is bound in the java componenet environement jndi namespace */ private final static String[] ENV_TAGS = {"ejb.env-entry", "ejb.resource-ref", "ejb.resource-env-ref", "ejb.destination-ref", "ejb.ejb-service-ref", "ejb.ejb-ref", "ejb.external-ref"}; /** * Maps primitive types to their wrapper classes */ private final static Map wrappers; protected XTag currentTag; protected XMember currentMember; protected int currentTagType; static { Map wps = new HashMap(); wps.put("boolean", "java.lang.Boolean"); wps.put("byte", "java.lang.Byte"); wps.put("char", "java.lang.Character"); wps.put("short", "java.lang.Short"); wps.put("int", "java.lang.Integer"); wps.put("float", "java.lang.Float"); wps.put("long", "java.lang.Long"); wps.put("double", "java.lang.Double"); wrappers = Collections.unmodifiableMap(wps); } /** * Executes the template for all class-, method- and field-level tags with the passed name * * @param template the template * @param attributes the attributes * @throws XDocletException if an error occures * @doc.param name="tagName" optional="false" description="the tag name" * @doc.tag type="block" */ public void forAllTags(String template, Properties attributes) throws XDocletException { forTags(template, attributes, true, true, true); } /** * Executes the template for all method- and field-level tags with the passed name * * @param template the template * @param attributes the attributes * @throws XDocletException if an error occures * @doc.param name="tagName" optional="false" description="the tag name" * @doc.tag type="block" */ public void forAllMemberTags(String template, Properties attributes) throws XDocletException { forTags(template, attributes, false, true, true); } /** * Executes the template for all method-level tags with the passed name * * @param template the template * @param attributes the attributes * @throws XDocletException if an error occures * @doc.param name="tagName" optional="false" description="the tag name" * @doc.tag type="block" */ public void forAllMethodTags(String template, Properties attributes) throws XDocletException { forTags(template, attributes, false, true, false); } /** * Returns the name parameter value for the current tag. If the name parameter is not specified for a method- or * field-level tag, the member's name is returned. If the name parameter is not specified for a class level tag, an * error is generated. * * @param attributes the attributes * @return the name * @exception XDocletException if an error occures * @doc.param name="paramName" optional="false" description="the name of the name parameter" * @doc.tag type="content" */ public String name(Properties attributes) throws XDocletException { String paramName = attributes.getProperty("paramName"); if (paramName == null) { throw new XDocletException("paramName attribute is mandatory"); } String name = null; StringTokenizer st = new StringTokenizer(paramName, ","); while (name == null && st.hasMoreTokens()) { name = currentTag.getAttributeValue(st.nextToken()); } if (name == null) { if (currentMember == null) { // class level mandatoryParamNotFound(currentTag.getDoc(), paramName, currentTag.getName()); } else { // method or field level name = currentMember.getName(); } } return name; } /** * Returns the type parameter value for the current tag. Returns the field type for field-level tags and the return * value for method-level tags. For class-level tags, the value of the type parameter is returned. The wrapper class * is returned for primitive fields an methods with primitive return values. * * @param attributes the attributes * @return the type * @exception XDocletException if an error occures * @doc.param name="paramName" optional="false" description="the name of the type parameter" * @doc.param name="values" description="The valid values for the parameter, comma separated. An * error message is printed if the parameter value is not one of the values." * @doc.param name="default" description="The default value is returned if parameter not specified * by user for the tag." * @doc.param name="mandatory" values="true,false" description="Generate an error if parameter not * @doc.tag type="content" */ public String type(Properties attributes) throws XDocletException { if (currentMember == null) { // class level tags return paramValue(attributes); } else { // method and field level tags String type = currentMemberType(); String wrapper = (String) wrappers.get(type); return wrapper == null ? type : wrapper; } } /** * Executes the body only if the current tag is either a method- or fiel-level tag or has a type parameter. * * @param template the template * @param attributes the attributes * @exception XDocletException if an error occures * @doc.param name="paramName" optional="false" description="the name of the name parameter" * @doc.tag type="block" */ public void ifHasType(String template, Properties attributes) throws XDocletException { String paramName = attributes.getProperty("paramName"); if (paramName == null) { throw new XDocletException("paramName attribute is mandatory"); } if (currentMember == null) { // class level tags String type = currentTag.getAttributeValue(paramName); if (type != null) { generate(template); } } else { // method and field level tags generate(template); } } /** * Returns the method or field name. Can only be used inside <code>forAllMemberTags</code> or <code>forAllMethodTags</code> * . * * @param attributes the attributes * @return the memeber's name * @exception XDocletException if an error occures * @doc.param name="prefix" optional="true" description="the prefix for the name" * @doc.tag type="content" */ public String memberName(Properties attributes) throws XDocletException { if (currentMember == null) { throw new XDocletException("XDtEjbEnv:memberName can only be used inside forAllMemberTags or forAllMethodTags"); } String name = currentMember.getName(); String prefix = attributes.getProperty("prefix"); if (prefix != null) { name = prefix + "/" + name; } return name; } /** * Returns the method's return type or the field's type. Can only be used inside <code>forAllMemberTags</code> or * <code>forAllMethodTags</code>. * * @return the member's type * @exception XDocletException if an error occures * @doc.tag type="content" */ public String memberType() throws XDocletException { if (currentMember == null) { throw new XDocletException("XDtEjbEnv:memberType can only be used inside forAllMemberTags or forAllMethodTags"); } return currentMemberType(); } /** * Returns the method signature for the current method. Can only be used inside <code>forAllMethodTags</code>. * * @return the current method's signature * @exception XDocletException if an error occures * @doc.tag type="content" */ public String methodSignature() throws XDocletException { if (currentMember == null || !(currentMember instanceof XMethod)) { throw new XDocletException("XDtEjbEnv:methodSignature can only be used inside forAllMemberTags or forAllMethodTags"); } XMethod method = (XMethod) currentMember; StringBuffer sb = new StringBuffer(); if (Modifier.isProtected(method.getModifierSpecifier())) { sb.append("protected "); } if (Modifier.isPublic(method.getModifierSpecifier())) { sb.append("public "); } sb.append(method.getReturnType().getType().getQualifiedName()); sb.append(' '); sb.append(method.getNameWithSignature(true)); return sb.toString(); } /** * Returns the value of a parameter. * * @param attributes the attributes * @return the value * @exception XDocletException if an error occures * @doc.param name="paramName" optional="false" description="the name of the parameter" * @doc.param name="values" description="The valid values for the parameter, comma separated. An * error message is printed if the parameter value is not one of the values." * @doc.param name="default" description="The default value is returned if parameter not specified * by user for the tag." * @doc.param name="mandatory" values="true,false" description="Generate an error if parameter not * @doc.tag type="content" */ public String paramValue(Properties attributes) throws XDocletException { attributes.setProperty("tagName", currentTag.getName()); return getTagValue(attributes, currentTagType); } /** * Executes the body only if the current tag has a specified parameter * * @param template the template * @param attributes the attributes * @exception XDocletException if an error occures * @doc.param name="paramName" optional="false" description="the name of the parameter" * @doc.tag type="body" */ public void ifHasParam(String template, Properties attributes) throws XDocletException { if (paramValue(attributes) != null) { generate(template); } } /** * Executes the body only if the specified tag's value is equal to the specified value * * @param template the template * @param attributes the attributes * @exception XDocletException if an error occures * @doc.param name="paramName" optional="false" description="the name of the parameter" * @doc.param name="value" optional="false" description="the value of the parameter" * @doc.tag type="body" */ public void ifParamValueEquals(String template, Properties attributes) throws XDocletException { if (isParamValueEqual(attributes)) { generate(template); } } /** * Executes the body only if the specified tag's value is equal to the specified value * * @param template the template * @param attributes the attributes * @exception XDocletException if an error occures * @doc.param name="paramName" optional="false" description="the name of the parameter" * @doc.param name="value" optional="false" description="the value of the parameter" * @doc.tag type="body" */ public void ifParamValueNotEquals(String template, Properties attributes) throws XDocletException { if (!isParamValueEqual(attributes)) { generate(template); } } /** * Executes the body only if the current field type or method return type is primitive. * * @param template the template * @param attributes the attributes * @exception XDocletException if an error occures * @doc.tag type="block" */ public void ifPrimitiveMember(String template, Properties attributes) throws XDocletException { if (currentMember != null) { String type = currentMemberType(); String wrapper = (String) wrappers.get(type); if (wrapper != null) { generate(template); } } } /** * Executes the body only if the current class has at least one field or method tag for which a value is bound in * the java componenet environement jndi namespace * * @param template the template * @param attributes the attributes * @exception XDocletException if an error occures * @doc.tag type="block" */ public void ifHasEnvTags(String template, Properties attributes) throws XDocletException { if (hasMemberWithEnvTag(getCurrentClass().getMethods(true))) { generate(template); } else { if (hasMemberWithEnvTag(getCurrentClass().getFields(true))) { generate(template); } } } /** * Executes the passed template for the passed * * @param template the template * @param attributes the parameters * @param forClass indicates whether the template should be excuted for class level tags * @param forMethod indicates whether the template should be excuted for method level tags * @param forField indicates whether the template should be excuted for field level tags * @throws XDocletException if an error occures */ protected void forTags(String template, Properties attributes, boolean forClass, boolean forMethod, boolean forField) throws XDocletException { boolean superclasses = TypeConversionUtil.stringToBoolean(attributes.getProperty("superclasses"), true); String tagName = attributes.getProperty("tagName"); if (tagName == null) { throw new XDocletException("tagName is mandatory"); } StringTokenizer st = new StringTokenizer(tagName, ","); while (st.hasMoreTokens()) { forTagsInternal(template, st.nextToken(), superclasses, forClass, forMethod, forField); } } /** * Called for each tag in the <code>forTags</code> loop. The default behaviour is to call <code>generate(template)</code> * * @param template the template * @throws XDocletException if an error occures */ protected void doGenerate(String template) throws XDocletException { generate(template); } /** * Returns whether the parameter's value is equal to the specfied value * * @param attributes the attributes * @return <code>true</code> if it is equal * @throws XDocletException if an error occures */ private boolean isParamValueEqual(Properties attributes) throws XDocletException { String value = attributes.getProperty("value"); if (value == null) { throw new XDocletException("value is mandatory"); } return value.equals(paramValue(attributes)); } /** * Executes the passed template for the passed * * @param template the template * @param tagName the tag-name * @param superclasses indicates whether the superclasses of the current class should also be searched * @param forClass indicates whether the template should be excuted for class level tags * @param forMethod indicates whether the template should be excuted for method level tags * @param forField indicates whether the template should be excuted for field level tags * @throws XDocletException if an error occures */ private void forTagsInternal(String template, String tagName, boolean superclasses, boolean forClass, boolean forMethod, boolean forField) throws XDocletException { // class level tags if (forClass) { currentTagType = FOR_CLASS; Collection tags = getCurrentClass().getDoc().getTags(tagName, superclasses); for (Iterator it = tags.iterator(); it.hasNext(); ) { currentTag = (XTag) it.next(); setCurrentClassTag(currentTag); currentMember = null; doGenerate(template); setCurrentClassTag(null); } } // method level tags if (forMethod) { currentTagType = FOR_METHOD; Collection methods = getCurrentClass().getMethods(superclasses); for (Iterator it = methods.iterator(); it.hasNext(); ) { XMethod method = (XMethod) it.next(); setCurrentMethod(method); Collection tags = method.getDoc().getTags(tagName); for (Iterator it2 = tags.iterator(); it2.hasNext(); ) { currentTag = (XTag) it2.next(); setCurrentMethodTag(currentTag); currentMember = method; doGenerate(template); setCurrentMethodTag(null); } setCurrentMethod(null); } } // field level tags if (forField) { currentTagType = FOR_FIELD; Collection fields = getCurrentClass().getFields(superclasses); for (Iterator it = fields.iterator(); it.hasNext(); ) { XField field = (XField) it.next(); setCurrentField(field); Collection tags = field.getDoc().getTags(tagName); for (Iterator it2 = tags.iterator(); it2.hasNext(); ) { currentTag = (XTag) it2.next(); setCurrentFieldTag(currentTag); currentMember = field; doGenerate(template); setCurrentFieldTag(null); } setCurrentField(null); } } currentTagType = 0; } /** * Returns whether the passed Collection of Members has at least one of the tags for which a value is bound in the * java componenet environement jndi namespace * * @param members a <code>Collection</code> o [EMAIL PROTECTED] XMember} * @return <code>true</code> if the passed Collection of Members has at least one of the tags for which a * value is bound in the java componenet environement jndi namespace */ private boolean hasMemberWithEnvTag(Collection members) { for (Iterator it = members.iterator(); it.hasNext(); ) { XMember member = (XMember) it.next(); for (int i = 0; i < ENV_TAGS.length; i++) { Collection tags = member.getDoc().getTags(ENV_TAGS[i]); if (tags.size() > 0) { return true; } } } return false; } /** * Returns the type of the current member * * @return the type */ private String currentMemberType() { if (currentMember instanceof XField) { return ((XField) currentMember).getType().getQualifiedName(); } else { return ((XMethod) currentMember).getReturnType().getType().getQualifiedName(); } } } --- NEW FILE: EnvEjbRefTagsHandler.java --- /* * Copyright (c) 2001, 2002 The XDoclet team * All rights reserved. */ package xdoclet.modules.ejb.env; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; import org.apache.commons.logging.Log; import xjavadoc.XClass; import xjavadoc.XTag; import xdoclet.XDocletException; import xdoclet.modules.ejb.EjbTagsHandler; import xdoclet.modules.ejb.XDocletModulesEjbMessages; import xdoclet.modules.ejb.home.HomeTagsHandler; import xdoclet.util.LogUtil; import xdoclet.util.Translator; /** * @author Matthias Germann * @created April 5, 2005 * @xdoclet.taghandler namespace="EjbEnvEjbRef" * @version $Revision 1.1 $ * @todo refactor ejbRefId properly to account for ejb:bean - it may not be needed anymore. * @todo refactor storeReferringClassId properly to take ejb:bean into account - may not be needed * anymore. */ public class EnvEjbRefTagsHandler extends EnvTagsHandler { /** * The id of the EJB referencing another EJB, used for setting up a correct unique id for the ejb-ref. * * @see #ejbRefId() * @see #forAllEjbRefs(java.lang.String,java.util.Properties) * @see #storeReferringClassId() */ private String referringClassId; private Map already = new HashMap(); private XClass refedEJBClass; /** * Returns unique id for the specified ejb-ref. It prefixes it with the referring class's id, then a _ and the id of * the ejb object. * * @return Description of the Returned Value * @exception XDocletException * @todo refactor this properly to account for ejb:bean - it may not be needed anymore. * @doc.tag type="content" */ public String ejbRefId() throws XDocletException { return referringClassId + '_' + EjbTagsHandler.getEjbIdFor(refedEJBClass); } /** * Evaluates the body block for each ejb:ejb-ref defined for the EJB. One of the useful things is does is to lookup * the EJB using the ejb-name parameter of ejb:ejb-ref and fill in other required info. * * @param template The body of the block tag * @param attributes The attributes of the template tag * @exception XDocletException * @doc.tag type="block" * @doc.param name="tagName" description="the ejb-ref tag" default="ejb.ejb-ref" */ public void forAllEjbRefs(String template, Properties attributes) throws XDocletException { already.clear(); if (attributes.getProperty("tagName") == null) { attributes.setProperty("tagName", "ejb.ejb-ref"); } forTags(template, attributes, true, true, true); already.clear(); } /** * Returns the global JNDI name for the current EJB ref. * * @return The JNDI name of current EJB ref. * @exception XDocletException * @doc.tag type="content" */ public String ejbRefJndiName() throws XDocletException { String ejbRefJndiName = null; String jndiNameParameter = currentTag.getAttributeValue("jndi-name"); if (jndiNameParameter != null) { ejbRefJndiName = jndiNameParameter; } else { String refed_ejb_name = currentTag.getAttributeValue("ejb-name"); if (refed_ejb_name == null) { throw new XDocletException("No ejb-name attribute found in ejb-ref specified in bean " + getCurrentClass()); } XClass refed_clazz = findEjb(refed_ejb_name); String ejb_type = EjbTagsHandler.isLocalEjb(refed_clazz) ? "local" : "remote"; ejbRefJndiName = HomeTagsHandler.getJndiNameOfTypeFor(ejb_type, refed_clazz); } return ejbRefJndiName; } /** * Generates code if the ejb-ref is local * * @param template * @exception XDocletException * @doc.tag type="block" */ public void ifLocalEjbRef(String template) throws XDocletException { if (isLocalEjbRef(currentTag)) { generate(template); } } /** * Generates code if the ejb-ref is local * * @param template * @exception XDocletException * @doc.tag type="block" */ public void ifRemoteEjbRef(String template) throws XDocletException { if (isRemoteEjbRef(currentTag)) { generate(template); } } public String name(Properties attributes) throws XDocletException { if (currentMember == null) { return EjbTagsHandler.ejbRefName(currentTag, refedEJBClass); } else { attributes.setProperty("paramName", "ref-name"); return super.name(attributes); } } /** * Return true if the ejb-ref is local * * @param ejbRefTag * @return true if the ejb-ref is local otherwise false * @exception XDocletException */ protected boolean isLocalEjbRef(XTag ejbRefTag) throws XDocletException { String viewTypeParameter = ejbRefTag.getAttributeValue("view-type"); if (viewTypeParameter == null) { return EjbTagsHandler.isLocalEjb(refedEJBClass) && !EjbTagsHandler.isRemoteEjb(refedEJBClass); /* * TODO introspection for fields and methods * / use the memeber's type for field- and method-level tags * XClass type; * if (currentMember instanceof XMethod) { * type = ((XMethod) currentMember).getReturnType().getType(); * } * else { * type = ((XField) currentMember).getType(); * } * return type.isA("javax.ejb.EJBLocalHome") || type.isA("javax.ejb.EJBLocalObject"); */ } else { return "local".equals(viewTypeParameter); } } /** * Return true if the ejb-ref is remote * * @param ejbRefTag * @return true if the ejb-ref is remote otherwise false * @exception XDocletException */ protected boolean isRemoteEjbRef(XTag ejbRefTag) throws XDocletException { return !isLocalEjbRef(ejbRefTag); } /* * (non-Javadoc) * @see xdoclet.modules.ejb.env.EnvTagsHandler#doGenerate(java.lang.String) */ protected void doGenerate(String template) throws XDocletException { Log log = LogUtil.getLog(EnvEjbRefTagsHandler.class, "doGenerate"); storeReferringClassId(); String ejbNameAttribute = currentTag.getAttributeValue("ejb-name"); if ("ejb.ejb-ref".equals(currentTag.getName())) { if (ejbNameAttribute == null || ejbNameAttribute.length() < 1) { mandatoryParamNotFound(currentTag.getDoc(), "ejb-name", "ejb.ejb-ref"); } refedEJBClass = findEjb(ejbNameAttribute); } String refName = name(new Properties()); if (!already.containsKey(refName)) { already.put(refName, currentTag); if (refedEJBClass != null) { pushCurrentClass(refedEJBClass); } generate(template); if (refedEJBClass != null) { popCurrentClass(); } } else { XTag previousTag = (XTag) already.get(refName); if (!previousTag.getAttributeValue("ejb-name").equals(currentTag.getAttributeValue("ejb-name"))) { log.error("Duplicate @ejb.ejb-ref found with different parameters!"); log.error("Previous tag: @ejb.ejb-ref ref-name=\"" + previousTag.getAttributeValue("ref-name") + "\" ejb-name=\"" + previousTag.getAttributeValue("ejb-name") + "\" view-type=\"" + previousTag.getAttributeValue("view-type") + "\""); log.error("Current tag: @ejb.ejb-ref ref-name=\"" + currentTag.getAttributeValue("ref-name") + "\" ejb-name=\"" + currentTag.getAttributeValue("ejb-name") + "\" view-type=\"" + currentTag.getAttributeValue("view-type") + "\""); throw new XDocletException("Duplicate @ejb.ejb-ref with different parameters"); } else { log.warn("Duplicated @ejb.ejb-ref found, ref-name=\"" + refName + "\""); } } referringClassId = null; } /** * Stores the id of current EJB for further use by other tags in referringClassId attribute. * * @exception XDocletException * @todo refactor this properly to take ejb:bean into account - may not be needed anymore. */ protected void storeReferringClassId() throws XDocletException { referringClassId = EjbTagsHandler.getEjbIdFor(getCurrentClass()); } /** * Finds and returns the class with the specified ejbName. An XDocletException is thrown if not found. * * @param ejbName Description of Parameter * @return Description of the Returned Value * @exception XDocletException */ protected XClass findEjb(String ejbName) throws XDocletException { Collection classes = getXJavaDoc().getSourceClasses(); for (Iterator i = classes.iterator(); i.hasNext(); ) { XClass clazz = (XClass) i.next(); if (EjbTagsHandler.isEjb(clazz) && ejbName.equals(EjbTagsHandler.getEjbNameFor(clazz))) { return clazz; } } throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.NOT_DEFINED, new String[]{ejbName})); } } ------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click _______________________________________________ xdoclet-devel mailing list xdoclet-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/xdoclet-devel