KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > modules > ejb > env > EnvEjbRefTagsHandler


1 /*
2  * Copyright (c) 2001, 2002 The XDoclet team
3  * All rights reserved.
4  */

5 package xdoclet.modules.ejb.env;
6
7 import java.util.Collection JavaDoc;
8 import java.util.HashMap JavaDoc;
9 import java.util.Iterator JavaDoc;
10 import java.util.Map JavaDoc;
11 import java.util.Properties JavaDoc;
12
13 import org.apache.commons.logging.Log;
14 import xjavadoc.XClass;
15 import xjavadoc.XTag;
16
17 import xdoclet.XDocletException;
18 import xdoclet.modules.ejb.EjbTagsHandler;
19 import xdoclet.modules.ejb.XDocletModulesEjbMessages;
20 import xdoclet.modules.ejb.home.HomeTagsHandler;
21 import xdoclet.modules.ejb.intf.InterfaceTagsHandler;
22 import xdoclet.util.LogUtil;
23 import xdoclet.util.Translator;
24
25 /**
26  * @author Matthias Germann
27  * @created April 5, 2005
28  * @xdoclet.taghandler namespace="EjbEnvEjbRef"
29  * @version $Revision 1.1 $
30  * @todo refactor ejbRefId properly to account for ejb:bean - it may not be needed anymore.
31  * @todo refactor storeReferringClassId properly to take ejb:bean into account - may not be needed
32  * anymore.
33  */

34 public class EnvEjbRefTagsHandler extends EnvTagsHandler
35 {
36
37     /**
38      * The id of the EJB referencing another EJB, used for setting up a correct unique id for the ejb-ref.
39      *
40      * @see #ejbRefId()
41      * @see #forAllEjbRefs(java.lang.String,java.util.Properties)
42      * @see #storeReferringClassId()
43      */

44     private String JavaDoc referringClassId;
45     private Map JavaDoc already = new HashMap JavaDoc();
46     private XClass refedEJBClass;
47
48     /**
49      * Returns unique id for the specified ejb-ref. It prefixes it with the referring class's id, then a _ and the id of
50      * the ejb object.
51      *
52      * @return Description of the Returned Value
53      * @exception XDocletException
54      * @todo refactor this properly to account for ejb:bean - it may not be needed anymore.
55      * @doc.tag type="content"
56      */

57     public String JavaDoc ejbRefId() throws XDocletException
58     {
59         return referringClassId + '_' + EjbTagsHandler.getEjbIdFor(refedEJBClass);
60     }
61
62     /**
63      * Evaluates the body block for each ejb reference.
64      *
65      * @param template The body of the block tag
66      * @param attributes The attributes of the template tag
67      * @exception XDocletException
68      * @doc.tag type="block"
69      * @doc.param name="tagName" description="the ejb-ref tag" default="ejb.ejb-ref"
70      */

71     public void forAllEjbRefs(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
72     {
73         already.clear();
74
75         if (attributes.getProperty("tagName") == null) {
76             attributes.setProperty("tagName", "ejb.ejb-ref");
77         }
78
79         forTags(template, attributes, true, true, true);
80
81         already.clear();
82     }
83
84     /**
85      * Evaluates the body block for each method- and field-level ejb reference.
86      *
87      * @param template The body of the block tag
88      * @param attributes The attributes of the template tag
89      * @exception XDocletException
90      * @doc.tag type="block"
91      * @doc.param name="tagName" description="the ejb-ref tag" default="ejb.ejb-ref"
92      */

93     public void forAllEjbRefMembers(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
94     {
95         already.clear();
96
97         if (attributes.getProperty("tagName") == null) {
98             attributes.setProperty("tagName", "ejb.ejb-ref");
99         }
100
101         forTags(template, attributes, false, true, true);
102
103         already.clear();
104     }
105
106     /**
107      * Evaluates the body block for each method-level ejb reference.
108      *
109      * @param template The body of the block tag
110      * @param attributes The attributes of the template tag
111      * @exception XDocletException
112      * @doc.tag type="block"
113      * @doc.param name="tagName" description="the ejb-ref tag" default="ejb.ejb-ref"
114      */

115     public void forAllEjbRefMethods(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
116     {
117         already.clear();
118
119         if (attributes.getProperty("tagName") == null) {
120             attributes.setProperty("tagName", "ejb.ejb-ref");
121         }
122
123         forTags(template, attributes, false, true, false);
124
125         already.clear();
126     }
127
128     /**
129      * Returns the global JNDI name for the current EJB ref.
130      *
131      * @return The JNDI name of current EJB ref.
132      * @exception XDocletException
133      * @doc.tag type="content"
134      */

135     public String JavaDoc ejbRefJndiName() throws XDocletException
136     {
137         String JavaDoc ejbRefJndiName = null;
138
139         String JavaDoc jndiNameParameter = currentTag.getAttributeValue("jndi-name");
140
141         if (jndiNameParameter != null) {
142             ejbRefJndiName = jndiNameParameter;
143         }
144         else {
145             String JavaDoc refed_ejb_name = currentTag.getAttributeValue("ejb-name");
146
147             if (refed_ejb_name == null) {
148                 throw new XDocletException("No ejb-name attribute found in ejb-ref specified in bean " + getCurrentClass());
149             }
150
151             XClass refed_clazz = findEjb(refed_ejb_name);
152             String JavaDoc ejb_type = EjbTagsHandler.isLocalEjb(refed_clazz) ? "local" : "remote";
153
154             ejbRefJndiName = HomeTagsHandler.getJndiNameOfTypeFor(ejb_type, refed_clazz);
155
156         }
157
158         return ejbRefJndiName;
159     }
160
161     /**
162      * Generates code if the ejb-ref is local
163      *
164      * @param template
165      * @exception XDocletException
166      * @doc.tag type="block"
167      */

168     public void ifLocalEjbRef(String JavaDoc template) throws XDocletException
169     {
170         if (isLocalEjbRef(currentTag)) {
171             generate(template);
172         }
173     }
174
175     /**
176      * Generates code if the ejb-ref is local
177      *
178      * @param template
179      * @exception XDocletException
180      * @doc.tag type="block"
181      */

182     public void ifRemoteEjbRef(String JavaDoc template) throws XDocletException
183     {
184         if (isRemoteEjbRef(currentTag)) {
185             generate(template);
186         }
187     }
188
189     public String JavaDoc name(Properties JavaDoc attributes) throws XDocletException
190     {
191         if (currentMember == null) {
192             return EjbTagsHandler.ejbRefName(currentTag, refedEJBClass);
193         }
194         else {
195             attributes.setProperty("paramName", "ref-name");
196             return super.name(attributes);
197         }
198     }
199
200     /**
201      * Returns the home interface for the current ejb reference
202      *
203      * @return the fully qualified class name
204      * @throws XDocletException if an error occures
205      * @doc.tag type="content"
206      */

207     public String JavaDoc homeInterface() throws XDocletException
208     {
209         String JavaDoc intf;
210
211         if ("ejb.ejb-external-ref".equals(currentTag.getName())) {
212             intf = currentTag.getAttributeValue("home");
213             if (intf == null) {
214                 mandatoryParamNotFound(currentTag.getDoc(), "home", "ejb.ejb-external-ref");
215             }
216         }
217         else {
218             String JavaDoc type = isRemoteEjbRef(currentTag) ? "remote" : "local";
219
220             intf = HomeTagsHandler.getHomeInterface(type, getCurrentClass());
221         }
222         return intf;
223     }
224
225     /**
226      * Returns the component interface for the current ejb reference
227      *
228      * @return the fully qualified class name
229      * @throws XDocletException if an error occures
230      * @doc.tag type="content"
231      */

232     public String JavaDoc componentInterface() throws XDocletException
233     {
234         String JavaDoc intf;
235
236         if ("ejb.ejb-external-ref".equals(currentTag.getName())) {
237             intf = currentTag.getAttributeValue("business");
238             if (intf == null) {
239                 intf = currentTag.getAttributeValue("remote");
240             }
241             if (intf == null) {
242                 mandatoryParamNotFound(currentTag.getDoc(), "business", "ejb.ejb-external-ref");
243             }
244         }
245         else {
246             String JavaDoc type = isRemoteEjbRef(currentTag) ? "remote" : "local";
247
248             intf = InterfaceTagsHandler.getComponentInterface(type, getCurrentClass());
249         }
250         return intf;
251     }
252
253     /**
254      * Return true if the ejb-ref is local
255      *
256      * @param ejbRefTag
257      * @return true if the ejb-ref is local otherwise false
258      * @exception XDocletException
259      */

260     protected boolean isLocalEjbRef(XTag ejbRefTag) throws XDocletException
261     {
262         String JavaDoc viewTypeParameter = ejbRefTag.getAttributeValue("view-type");
263
264         if (viewTypeParameter == null) {
265             return EjbTagsHandler.isLocalEjb(refedEJBClass) && !EjbTagsHandler.isRemoteEjb(refedEJBClass);
266             /*
267              * TODO introspection for fields and methods
268              * / use the memeber's type for field- and method-level tags
269              * XClass type;
270              * if (currentMember instanceof XMethod) {
271              * type = ((XMethod) currentMember).getReturnType().getType();
272              * }
273              * else {
274              * type = ((XField) currentMember).getType();
275              * }
276              * return type.isA("javax.ejb.EJBLocalHome") || type.isA("javax.ejb.EJBLocalObject");
277              */

278         }
279         else {
280             return "local".equals(viewTypeParameter);
281         }
282     }
283
284     /**
285      * Return true if the ejb-ref is remote
286      *
287      * @param ejbRefTag
288      * @return true if the ejb-ref is remote otherwise false
289      * @exception XDocletException
290      */

291     protected boolean isRemoteEjbRef(XTag ejbRefTag) throws XDocletException
292     {
293         return !isLocalEjbRef(ejbRefTag);
294     }
295
296     /*
297      * (non-Javadoc)
298      * @see xdoclet.modules.ejb.env.EnvTagsHandler#doGenerate(java.lang.String)
299      */

300     protected void doGenerate(String JavaDoc template) throws XDocletException
301     {
302         Log log = LogUtil.getLog(EnvEjbRefTagsHandler.class, "doGenerate");
303
304         storeReferringClassId();
305
306         String JavaDoc ejbNameAttribute = currentTag.getAttributeValue("ejb-name");
307
308         if ("ejb.ejb-ref".equals(currentTag.getName())) {
309             if (ejbNameAttribute == null || ejbNameAttribute.length() < 1) {
310                 mandatoryParamNotFound(currentTag.getDoc(), "ejb-name", "ejb.ejb-ref");
311             }
312             refedEJBClass = findEjb(ejbNameAttribute);
313         }
314
315         String JavaDoc refName = name(new Properties JavaDoc());
316
317         if (!already.containsKey(refName)) {
318             already.put(refName, currentTag);
319             if (refedEJBClass != null) {
320                 pushCurrentClass(refedEJBClass);
321             }
322             generate(template);
323             if (refedEJBClass != null) {
324                 popCurrentClass();
325             }
326         }
327         else {
328             XTag previousTag = (XTag) already.get(refName);
329
330             String JavaDoc prevEjbName = previousTag.getAttributeValue("ejb-name");
331
332             if (prevEjbName == null)
333                 prevEjbName = "";
334
335             String JavaDoc prevJndiName = previousTag.getAttributeValue("jndi-name");
336
337             if (prevJndiName == null)
338                 prevJndiName = "";
339
340             if (!(prevEjbName.equals(currentTag.getAttributeValue("ejb-name")) ||
341                 prevJndiName.equals(currentTag.getAttributeValue("jndi-name")))) {
342                 log.error("Duplicate @ejb.ejb-ref found with different parameters!");
343                 log.error("Previous tag: @ejb.ejb-ref ref-name=\"" +
344                     previousTag.getAttributeValue("ref-name") + "\" ejb-name=\"" +
345                     previousTag.getAttributeValue("ejb-name") + "\" view-type=\"" +
346                     previousTag.getAttributeValue("view-type") + "\"");
347                 log.error("Current tag: @ejb.ejb-ref ref-name=\"" +
348                     currentTag.getAttributeValue("ref-name") + "\" ejb-name=\"" +
349                     currentTag.getAttributeValue("ejb-name") + "\" view-type=\"" +
350                     currentTag.getAttributeValue("view-type") + "\"");
351                 throw new XDocletException("Duplicate @ejb.ejb-ref with different parameters");
352             }
353             else {
354                 log.warn("Duplicated @ejb.ejb-ref found, ref-name=\"" + refName + "\"");
355             }
356         }
357
358         referringClassId = null;
359
360     }
361
362     /**
363      * Stores the id of current EJB for further use by other tags in referringClassId attribute.
364      *
365      * @exception XDocletException
366      * @todo refactor this properly to take ejb:bean into account - may not be needed anymore.
367      */

368     protected void storeReferringClassId() throws XDocletException
369     {
370         referringClassId = EjbTagsHandler.getEjbIdFor(getCurrentClass());
371     }
372
373     /**
374      * Finds and returns the class with the specified ejbName. An XDocletException is thrown if not found.
375      *
376      * @param ejbName Description of Parameter
377      * @return Description of the Returned Value
378      * @exception XDocletException
379      */

380     protected XClass findEjb(String JavaDoc ejbName) throws XDocletException
381     {
382         Collection JavaDoc classes = getXJavaDoc().getSourceClasses();
383
384         for (Iterator JavaDoc i = classes.iterator(); i.hasNext(); ) {
385             XClass clazz = (XClass) i.next();
386
387             if (EjbTagsHandler.isEjb(clazz) && ejbName.equals(EjbTagsHandler.getEjbNameFor(clazz))) {
388                 return clazz;
389             }
390         }
391
392         throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.NOT_DEFINED, new String JavaDoc[]{ejbName}));
393     }
394 }
395
Popular Tags