1 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 ; 25 import java.text.MessageFormat ; 26 import java.util.Arrays ; 27 import java.util.Collections ; 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 53 public final class SendJMSGenerator { 54 55 private static final String 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 className, FileObject fileObject, ServiceLocatorStrategy slStrategy) throws IOException { 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 { 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 destinationFieldName = null; 76 String connectionFactoryFieldName = null; 77 String factoryName = null; 78 String destinationName = null; 79 80 if (supportsInjection){ 81 factoryName = jmsDestination.getConnectionFactoryName(); 82 destinationName = jmsDestination.getDestinationName(); 83 connectionFactoryFieldName = createInjectedField(fileObject, className, factoryName, "javax.jms.ConnectionFactory"); 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 sendMethodName = createSendMethod(fileObject, className, jmsDestination.getDestination()); 90 createJMSProducer(fileObject, className, factoryName, connectionFactoryFieldName, destinationName, 91 destinationFieldName,sendMethodName, slStrategy); 92 } 93 94 private String generateConnectionFactoryReference(EnterpriseReferenceContainer container, FileObject referencingFile, String referencingClass) throws IOException { 95 ResourceRef ref = container.createResourceRef(referencingClass); 96 ref.setResRefName(jmsDestination.getConnectionFactoryName()); 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"); return container.addResourceRef(ref, referencingFile, referencingClass); 101 } 102 103 private String generateDestinationReference(EnterpriseReferenceContainer container, FileObject referencingFile, String referencingClass, Project project) throws IOException { 104 MessageDestinationRef ref = container.createDestinationRef(referencingClass); 105 ref.setMessageDestinationUsage(PRODUCES); 106 ref.setMessageDestinationType(jmsDestination.getType()); 107 ref.setMessageDestinationRefName(jmsDestination.getDestinationName()); 108 ProjectInformation projectInformation = ProjectUtils.getInformation(jmsDestination.getProject()); 111 ref.setMessageDestinationLink(projectInformation.getName() + ".jar#" + jmsDestination.getDestination()); 112 if (jmsDestination.getProject().equals(project)) { 113 String 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 128 private String createInjectedField(FileObject fileObject, String className, String mappedName, String fieldType) throws IOException { 129 String 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 createSendMethod(FileObject fileObject, final String className, String destination) throws IOException { 143 final MethodModel.Variable[] parameters = new MethodModel.Variable[] { 144 MethodModel.Variable.create("javax.jms.Session", "session"), 145 MethodModel.Variable.create(Object .class.getName(), "messageData") 146 }; 147 String 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 { 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 className, 176 String connectionFactoryName, 177 String connectionFactoryFieldName, 178 String destinationName, 179 String destinationFieldName, 180 String sendMethodName, 181 ServiceLocatorStrategy slStrategy) throws IOException { 182 String destName = destinationName.substring(destinationName.lastIndexOf('/') + 1); 183 StringBuffer destBuff = new StringBuffer (destName); 184 destBuff.setCharAt(0, Character.toUpperCase(destBuff.charAt(0))); 185 186 boolean namingException = false; 187 String 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 .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 { 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 222 private String getSendJMSCodeWithInjectedFields(String connectionFactoryFieldName, 223 String destinationFieldName, 224 String 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 getSendJMSCode(String connectionName, String destinationName, 246 String messageMethodName, ServiceLocatorStrategy sls, 247 FileObject fileObject, String className) { 248 String connectionFactory = sls.genJMSFactory(connectionName, fileObject, className); 249 String 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 [] {connectionName, destinationName, messageMethodName}); 269 } 270 271 private String getSendJMSCode(String connectionName, String destinationName, 272 String 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 [] {connectionName, destinationName, messageMethodName}); 293 } 294 295 } 296 | Popular Tags |