KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > ejbcore > action > SendJMSGenerator


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.j2ee.ejbcore.action;
21
22 import com.sun.source.tree.ClassTree;
23 import com.sun.source.tree.MethodTree;
24 import java.io.IOException JavaDoc;
25 import java.text.MessageFormat JavaDoc;
26 import java.util.Arrays JavaDoc;
27 import java.util.Collections JavaDoc;
28 import javax.lang.model.element.Modifier;
29 import javax.lang.model.element.TypeElement;
30 import org.netbeans.api.java.source.CompilationController;
31 import org.netbeans.api.java.source.JavaSource;
32 import org.netbeans.api.java.source.WorkingCopy;
33 import org.netbeans.api.project.Project;
34 import org.netbeans.api.project.ProjectInformation;
35 import org.netbeans.api.project.ProjectUtils;
36 import org.netbeans.modules.j2ee.api.ejbjar.EnterpriseReferenceContainer;
37 import org.netbeans.modules.j2ee.common.method.MethodModel;
38 import org.netbeans.modules.j2ee.common.method.MethodModelSupport;
39 import org.netbeans.modules.j2ee.common.queries.api.InjectionTargetQuery;
40 import org.netbeans.modules.j2ee.common.source.AbstractTask;
41 import org.netbeans.modules.j2ee.dd.api.common.MessageDestinationRef;
42 import org.netbeans.modules.j2ee.dd.api.common.ResourceRef;
43 import org.netbeans.modules.j2ee.ejbcore.Utils;
44 import org.netbeans.modules.j2ee.ejbcore._RetoucheUtil;
45 import org.netbeans.modules.j2ee.ejbcore.ui.logicalview.entres.JMSDestination;
46 import org.netbeans.modules.j2ee.ejbcore.ui.logicalview.entres.ServiceLocatorStrategy;
47 import org.openide.filesystems.FileObject;
48
49 /**
50  *
51  * @author Martin Adamek
52  */

53 public final class SendJMSGenerator {
54     
55     private static final String JavaDoc PRODUCES = org.netbeans.modules.j2ee.dd.api.common.MessageDestinationRef.MESSAGE_DESTINATION_USAGE_PRODUCES;
56
57     private final JMSDestination jmsDestination;
58     private boolean supportsInjection;
59     
60     public SendJMSGenerator(JMSDestination jmsDestination) {
61         this.jmsDestination = jmsDestination;
62     }
63     
64     public void genMethods(EnterpriseReferenceContainer container, final String JavaDoc className, FileObject fileObject, ServiceLocatorStrategy slStrategy) throws IOException JavaDoc {
65         JavaSource javaSource = JavaSource.forFileObject(fileObject);
66         final boolean[] isInjectionTarget = new boolean[1];
67         javaSource.runUserActionTask(new AbstractTask<CompilationController>() {
68             public void run(CompilationController controller) throws IOException JavaDoc {
69                 controller.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
70                 TypeElement typeElement = controller.getElements().getTypeElement(className);
71                 isInjectionTarget[0] = InjectionTargetQuery.isInjectionTarget(controller, typeElement);
72             }
73         }, true);
74         supportsInjection = isInjectionTarget[0];
75         String JavaDoc destinationFieldName = null;
76         String JavaDoc connectionFactoryFieldName = null;
77         String JavaDoc factoryName = null;
78         String JavaDoc destinationName = null;
79         
80         if (supportsInjection){
81             factoryName = jmsDestination.getConnectionFactoryName();
82             destinationName = jmsDestination.getDestinationName();
83             connectionFactoryFieldName = createInjectedField(fileObject, className, factoryName, "javax.jms.ConnectionFactory"); //NO18N
84
destinationFieldName = createInjectedField(fileObject, className, destinationName, jmsDestination.getType());
85         } else {
86             factoryName = generateConnectionFactoryReference(container, fileObject, className);
87             destinationName = generateDestinationReference(container, fileObject, className, jmsDestination.getProject());
88         }
89         String JavaDoc sendMethodName = createSendMethod(fileObject, className, jmsDestination.getDestination());
90         createJMSProducer(fileObject, className, factoryName, connectionFactoryFieldName, destinationName,
91                 destinationFieldName,sendMethodName, slStrategy);
92     }
93     
94     private String JavaDoc generateConnectionFactoryReference(EnterpriseReferenceContainer container, FileObject referencingFile, String JavaDoc referencingClass) throws IOException JavaDoc {
95         ResourceRef ref = container.createResourceRef(referencingClass);
96         ref.setResRefName(jmsDestination.getConnectionFactoryName()); // NOI18N
97
ref.setResAuth(org.netbeans.modules.j2ee.dd.api.common.ResourceRef.RES_AUTH_CONTAINER);
98         ref.setResSharingScope(org.netbeans.modules.j2ee.dd.api.common.ResourceRef.RES_SHARING_SCOPE_SHAREABLE);
99         ref.setResType("javax.jms.ConnectionFactory"); //NOI18N
100
return container.addResourceRef(ref, referencingFile, referencingClass);
101     }
102     
103     private String JavaDoc generateDestinationReference(EnterpriseReferenceContainer container, FileObject referencingFile, String JavaDoc referencingClass, Project project) throws IOException JavaDoc {
104         MessageDestinationRef ref = container.createDestinationRef(referencingClass);
105         ref.setMessageDestinationUsage(PRODUCES);
106         ref.setMessageDestinationType(jmsDestination.getType());
107         ref.setMessageDestinationRefName(jmsDestination.getDestinationName());
108         // this may need to generalized later if jms producers are expected
109
// in web modules
110
ProjectInformation projectInformation = ProjectUtils.getInformation(jmsDestination.getProject());
111         ref.setMessageDestinationLink(projectInformation.getName() + ".jar#" + jmsDestination.getDestination());
112         if (jmsDestination.getProject().equals(project)) {
113             String JavaDoc linkWithoutModule = ref.getMessageDestinationLink();
114             linkWithoutModule = linkWithoutModule.substring(linkWithoutModule.indexOf('#')+1);
115             ref.setMessageDestinationLink(linkWithoutModule);
116         }
117         return container.addDestinationRef(ref, referencingFile, referencingClass);
118     }
119     
120     /**
121      * Creates an injected resource field for the given <code>target</code>. The name
122      * of the field will be derivated from the given <code>mappedName</code>.
123      * @param target the target class
124      * @param mappedName the value for resource's mappedName attribute
125      * @param fieldType the class of the field.
126      * @return name of the created field.
127      */

128     private String JavaDoc createInjectedField(FileObject fileObject, String JavaDoc className, String JavaDoc mappedName, String JavaDoc fieldType) throws IOException JavaDoc {
129         String JavaDoc fieldName = Utils.jndiNameToCamelCase(mappedName, true, "jms");
130         _RetoucheUtil.generateAnnotatedField(
131                 fileObject,
132                 className,
133                 "javax.annotation.Resource",
134                 fieldName,
135                 fieldType,
136                 Collections.singletonMap("mappedName", mappedName),
137                 InjectionTargetQuery.isStaticReferenceRequired(fileObject, className)
138                 );
139         return fieldName;
140     }
141     
142     private String JavaDoc createSendMethod(FileObject fileObject, final String JavaDoc className, String JavaDoc destination) throws IOException JavaDoc {
143         final MethodModel.Variable[] parameters = new MethodModel.Variable[] {
144             MethodModel.Variable.create("javax.jms.Session", "session"),
145             MethodModel.Variable.create(Object JavaDoc.class.getName(), "messageData")
146         };
147         String JavaDoc methodName = "createJMSMessageFor" + destination;
148         final MethodModel methodModel = MethodModel.create(
149                 methodName,
150                 "javax.jms.Message",
151                 "// TODO create and populate message to send\n" +
152                 "// javax.jms.TextMessage tm = session.createTextMessage();\n" +
153                 "// tm.setText(messageData.toString());\n"+
154                 "// return tm;\n",
155                 Arrays.asList(parameters),
156                 Collections.singletonList("javax.jms.JMSException"),
157                 Collections.singleton(Modifier.PRIVATE)
158                 );
159         JavaSource javaSource = JavaSource.forFileObject(fileObject);
160         javaSource.runModificationTask(new AbstractTask<WorkingCopy>() {
161             public void run(WorkingCopy workingCopy) throws IOException JavaDoc {
162                 workingCopy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
163                 TypeElement typeElement = workingCopy.getElements().getTypeElement(className);
164                 MethodTree methodTree = MethodModelSupport.createMethodTree(workingCopy, methodModel);
165                 ClassTree classTree = workingCopy.getTrees().getTree(typeElement);
166                 ClassTree newClassTree = workingCopy.getTreeMaker().addClassMember(classTree, methodTree);
167                 workingCopy.rewrite(classTree, newClassTree);
168             }
169         }).commit();
170         return methodName;
171     }
172     
173     private void createJMSProducer(
174             FileObject fileObject,
175             final String JavaDoc className,
176             String JavaDoc connectionFactoryName,
177             String JavaDoc connectionFactoryFieldName,
178             String JavaDoc destinationName,
179             String JavaDoc destinationFieldName,
180             String JavaDoc sendMethodName,
181             ServiceLocatorStrategy slStrategy) throws IOException JavaDoc {
182         String JavaDoc destName = destinationName.substring(destinationName.lastIndexOf('/') + 1);
183         StringBuffer JavaDoc destBuff = new StringBuffer JavaDoc(destName);
184         destBuff.setCharAt(0, Character.toUpperCase(destBuff.charAt(0)));
185
186         boolean namingException = false;
187         String JavaDoc body = null;
188         if (supportsInjection){
189             body = getSendJMSCodeWithInjectedFields(connectionFactoryFieldName, destinationFieldName, sendMethodName);
190         } else if (slStrategy == null) {
191             body = getSendJMSCode(connectionFactoryName, destinationName, sendMethodName);
192             namingException = true;
193         } else {
194             body = getSendJMSCode(connectionFactoryName, destinationName, sendMethodName, slStrategy, fileObject, className);
195         }
196
197         final MethodModel methodModel = MethodModel.create(
198                 "sendJMSMessageTo" + destBuff,
199                 "void",
200                 body,
201                 Collections.singletonList(MethodModel.Variable.create(Object JavaDoc.class.getName(), "messageData")),
202                 namingException ? Arrays.asList("javax.naming.NamingException", "javax.jms.JMSException") : Collections.singletonList("javax.jms.JMSException"),
203                 Collections.singleton(Modifier.PRIVATE)
204                 );
205         JavaSource javaSource = JavaSource.forFileObject(fileObject);
206         javaSource.runModificationTask(new AbstractTask<WorkingCopy>() {
207             public void run(WorkingCopy workingCopy) throws IOException JavaDoc {
208                 workingCopy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
209                 TypeElement typeElement = workingCopy.getElements().getTypeElement(className);
210                 MethodTree methodTree = MethodModelSupport.createMethodTree(workingCopy, methodModel);
211                 ClassTree classTree = workingCopy.getTrees().getTree(typeElement);
212                 ClassTree newClassTree = workingCopy.getTreeMaker().addClassMember(classTree, methodTree);
213                 workingCopy.rewrite(classTree, newClassTree);
214             }
215         }).commit();
216     }
217     
218     /**
219      * @return String representing the code for send jms method using injected
220      * fields.
221      */

222     private String JavaDoc getSendJMSCodeWithInjectedFields(String JavaDoc connectionFactoryFieldName,
223             String JavaDoc destinationFieldName,
224             String JavaDoc messageMethodName){
225         
226         return MessageFormat.format(
227                 "javax.jms.Connection connection = null;\n" +
228                 "javax.jms.Session session = null;\n" +
229                 "try '{' \n" +
230                 "connection = {0}.createConnection();\n" +
231                 "session = connection.createSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);\n" +
232                 "javax.jms.MessageProducer messageProducer = session.createProducer({1});\n" +
233                 "messageProducer.send({2}(session, messageData));\n" +
234                 " '}' finally '{'\n" +
235                 "if (session != null) '{'\n"+
236                 " session.close();\n" +
237                 "'}'\n" +
238                 "if (connection != null) '{'\n" +
239                 "connection.close();\n" +
240                 "'}'\n" +
241                 "'}'\n",
242                 connectionFactoryFieldName, destinationFieldName, messageMethodName);
243     }
244     
245     private String JavaDoc getSendJMSCode(String JavaDoc connectionName, String JavaDoc destinationName,
246             String JavaDoc messageMethodName, ServiceLocatorStrategy sls,
247             FileObject fileObject, String JavaDoc className) {
248         String JavaDoc connectionFactory = sls.genJMSFactory(connectionName, fileObject, className);
249         String JavaDoc destination = sls.genDestinationLookup(destinationName, fileObject, className);
250         return MessageFormat.format(
251                 "javax.jms.ConnectionFactory cf = (javax.jms.ConnectionFactory) " + connectionFactory + ";\n" +
252                 "javax.jms.Connection conn = null;\n" +
253                 "javax.jms.Session s = null;\n" +
254                 "try '{' \n" +
255                 "conn = cf.createConnection();\n" +
256                 "s = conn.createSession(false,s.AUTO_ACKNOWLEDGE);\n" +
257                 "javax.jms.Destination destination = (javax.jms.Destination) " + destination + ";\n" +
258                 "javax.jms.MessageProducer mp = s.createProducer(destination);\n" +
259                 "mp.send({2}(s,messageData));\n" +
260                 " '}' finally '{'\n" +
261                 "if (s != null) '{'\n"+
262                 " s.close();\n" +
263                 "'}'\n" +
264                 "if (conn != null) '{'\n" +
265                 "conn.close();\n" +
266                 "'}'\n" +
267                 "'}'\n",
268                 new Object JavaDoc[] {connectionName, destinationName, messageMethodName});
269     }
270     
271     private String JavaDoc getSendJMSCode(String JavaDoc connectionName, String JavaDoc destinationName,
272             String JavaDoc messageMethodName) {
273         return MessageFormat.format(
274                 "javax.naming.Context c = new javax.naming.InitialContext();\n" +
275                 "javax.jms.ConnectionFactory cf = (javax.jms.ConnectionFactory) c.lookup(\"java:comp/env/{0}\");\n" +
276                 "javax.jms.Connection conn = null;\n" +
277                 "javax.jms.Session s = null;\n" +
278                 "try '{' \n" +
279                 "conn = cf.createConnection();\n" +
280                 "s = conn.createSession(false,s.AUTO_ACKNOWLEDGE);\n" +
281                 "javax.jms.Destination destination = (javax.jms.Destination) c.lookup(\"java:comp/env/{1}\");\n" +
282                 "javax.jms.MessageProducer mp = s.createProducer(destination);\n" +
283                 "mp.send({2}(s,messageData));\n" +
284                 " '}' finally '{'\n" +
285                 "if (s != null) '{'\n"+
286                 " s.close();\n" +
287                 "'}'\n" +
288                 "if (conn != null) '{'\n" +
289                 "conn.close();\n" +
290                 "'}'\n" +
291                 "'}'\n",
292                 new Object JavaDoc[] {connectionName, destinationName, messageMethodName});
293     }
294
295 }
296
Popular Tags