1 19 20 package org.netbeans.modules.j2ee.ejbcore.ui.logicalview.ejb.dnd; 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.ArrayList ; 27 import java.util.Collections ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import javax.lang.model.element.Modifier; 31 import javax.lang.model.element.TypeElement; 32 import javax.naming.NamingException ; 33 import org.netbeans.api.java.source.JavaSource; 34 import org.netbeans.api.java.source.WorkingCopy; 35 import org.netbeans.api.project.FileOwnerQuery; 36 import org.netbeans.api.project.Project; 37 import org.netbeans.api.project.ant.AntArtifact; 38 import org.netbeans.modules.j2ee.api.ejbjar.EjbReference; 39 import org.netbeans.modules.j2ee.common.method.MethodModel; 40 import org.netbeans.modules.j2ee.common.method.MethodModelSupport; 41 import org.netbeans.modules.j2ee.common.queries.api.InjectionTargetQuery; 42 import org.netbeans.modules.j2ee.common.source.AbstractTask; 43 import org.netbeans.modules.j2ee.dd.api.common.EjbLocalRef; 44 import org.netbeans.modules.j2ee.dd.api.common.EjbRef; 45 import org.netbeans.modules.j2ee.dd.api.ejb.EntityAndSession; 46 import org.netbeans.modules.j2ee.dd.api.ejb.Session; 47 import org.netbeans.modules.j2ee.ejbcore.Utils; 48 import org.netbeans.modules.j2ee.ejbcore._RetoucheUtil; 49 import org.netbeans.modules.j2ee.ejbcore.ui.logicalview.entres.ServiceLocatorStrategy; 50 import org.openide.ErrorManager; 51 import org.openide.filesystems.FileObject; 52 import org.openide.nodes.Node; 53 54 58 59 public class EjbReferenceImpl implements Node.Cookie, EjbReference { 60 61 private final AntArtifact precursor; 62 private final EntityAndSession entityAndSession; 63 private final boolean isSimplified; 64 65 public EjbReferenceImpl(AntArtifact precursor, EntityAndSession entityAndSession) { 66 this.precursor = precursor; 67 this.entityAndSession = entityAndSession; 68 this.isSimplified = entityAndSession.getRoot().getVersion().doubleValue() > 2.1; 69 } 70 71 public AntArtifact getClientJarTarget() { 72 return precursor; 73 } 74 75 public EjbRef createRef() { 76 EjbRef ref = entityAndSession.newEjbRef(); 77 populateReference(ref); 78 return ref; 79 } 80 81 public EjbLocalRef createLocalRef() { 82 EjbLocalRef ref = entityAndSession.newEjbLocalRef(); 83 populateReference(ref); 84 return ref; 85 } 86 87 public boolean supportsLocalInvocation() { 88 if (isSimplified) { 89 return entityAndSession.getLocal() != null; 90 } else { 91 return entityAndSession.getLocal() != null && entityAndSession.getLocalHome() != null; 92 } 93 } 94 95 public boolean supportsRemoteInvocation() { 96 if (isSimplified) { 97 return entityAndSession.getRemote() != null; 98 } else { 99 return entityAndSession.getRemote() != null && entityAndSession.getHome() != null; 100 } 101 } 102 103 public void populateReference(EjbRef ref) { 104 ref.setEjbRefName("ejb/"+entityAndSession.getEjbName()); 105 if (entityAndSession instanceof Session) { 106 ref.setEjbRefType("Session"); 107 } else { 108 ref.setEjbRefType("Entity"); 109 } 110 ref.setRemote(entityAndSession.getRemote()); 111 if (entityAndSession.getHome() != null) { 112 ref.setHome(entityAndSession.getHome()); 113 } 114 String jarName = ""; 116 if (getClientJarTarget() != null) { 117 String [] names = getClientJarTarget().getArtifactLocations()[0].getPath().split("/"); jarName = names[names.length - 1] + "#"; 119 } 120 ref.setEjbLink(jarName + entityAndSession.getEjbName()); 121 } 122 123 public void populateReference(EjbLocalRef ref) { 124 ref.setEjbRefName("ejb/"+entityAndSession.getEjbName()); 125 if (entityAndSession instanceof Session) { 126 ref.setEjbRefType("Session"); 127 } else { 128 ref.setEjbRefType("Entity"); 129 } 130 ref.setLocal(entityAndSession.getLocal()); 131 if (entityAndSession.getLocalHome() != null) { 132 ref.setLocalHome(entityAndSession.getLocalHome()); 133 } 134 String jarName = ""; 136 if (getClientJarTarget() != null) { 137 String [] names = getClientJarTarget().getArtifactLocations()[0].getPath().split("/"); jarName = names[names.length - 1] + "#"; 139 } 140 ref.setEjbLink(jarName + entityAndSession.getEjbName()); 141 } 142 143 public Object generateServiceLocatorLookup(Object object, EjbRef ref, String serviceLocatorName, boolean throwExceptions) { 145 try { 146 FileObject fileObject = (FileObject) object; 147 String className = _RetoucheUtil.getMainClassName(fileObject); 148 return generateServiceLocatorJNDI(fileObject, className, ref.getHome(), ref.getEjbRefName(), true, ref.getRemote(), throwExceptions, serviceLocatorName); 149 } catch (IOException ioe) { 150 ErrorManager.getDefault().notify(ioe); 151 } 152 return null; 153 } 154 155 public Object generateServiceLocatorLookup(Object object, EjbLocalRef ref, String serviceLocatorName, boolean throwExceptions) { 157 try { 158 FileObject fileObject = (FileObject) object; 159 String className = _RetoucheUtil.getMainClassName(fileObject); 160 return generateServiceLocatorJNDI(fileObject, className, ref.getLocalHome(), ref.getEjbRefName(), false, ref.getLocal(), throwExceptions, serviceLocatorName); 161 } catch (IOException ioe) { 162 ErrorManager.getDefault().notify(ioe); 163 } 164 return null; 165 } 166 167 public Object generateReferenceCode(Object object, EjbRef ref, boolean throwExceptions) { 169 try { 170 FileObject fileObject = (FileObject) object; 171 String className = _RetoucheUtil.getMainClassName(fileObject); 172 boolean isInjectionTarget = InjectionTargetQuery.isInjectionTarget(fileObject, className); 173 if (isInjectionTarget) { 174 return generateInjection(fileObject, className, ref.getEjbRefName(), ref.getRemote()); 175 } else { 176 return generateJNDI(fileObject, className, ref.getHome(), ref.getEjbRefName(), true, ref.getRemote(), throwExceptions); 177 } 178 } catch (IOException ioe) { 179 ErrorManager.getDefault().notify(ioe); 180 } 181 return null; 182 } 183 184 public Object generateReferenceCode(Object object, EjbLocalRef ref, boolean throwExceptions) { 186 try { 187 FileObject fileObject = (FileObject) object; 188 String className = _RetoucheUtil.getMainClassName(fileObject); 189 boolean isInjectionTarget = InjectionTargetQuery.isInjectionTarget(fileObject, className); 190 if (isInjectionTarget) { 191 return generateInjection(fileObject, className, ref.getEjbRefName(), ref.getLocal()); 192 } else { 193 return generateJNDI(fileObject, className, ref.getLocalHome(), ref.getEjbRefName(), false, ref.getLocal(), throwExceptions); 194 } 195 } catch (IOException ioe) { 196 ErrorManager.getDefault().notify(ioe); 197 } 198 return null; 199 } 200 201 203 private static final String LOG_STATEMENT = 204 "java.util.logging.Logger.getLogger(getClass().getName()).log(java.util.logging.Level.SEVERE,\"exception caught\" ,{0});\n"; 205 206 private static final String JNDI_LOOKUP_LOCAL = 207 "javax.naming.Context c = new javax.naming.InitialContext();\n" + 208 "{1} rv = ({1}) c.lookup(\"java:comp/env/{0}\");\n" + 209 "return rv{2};\n"; 210 211 private static final String JNDI_LOOKUP_REMOTE = 212 "javax.naming.Context c = new javax.naming.InitialContext();\n" + 213 "Object remote = c.lookup(\"java:comp/env/{0}\");\n" + 214 "{1} rv = ({1}) javax.rmi.PortableRemoteObject.narrow(remote, {1}.class);\n" + 215 "return rv{2};\n"; 216 217 220 private static final String JNDI_LOOKUP_REMOTE_JAVASE = 221 "javax.naming.Context c = new javax.naming.InitialContext();\n" + 222 "Object remote = c.lookup(\"{0}\");\n" + 223 "{1} rv = ({1}) javax.rmi.PortableRemoteObject.narrow(remote, {1}.class);\n" + 224 "return rv{2};\n"; 225 226 private static final String JNDI_LOOKUP_EJB3 = 227 "javax.naming.Context c = new javax.naming.InitialContext();\n" + 228 "return ({1}) c.lookup(\"java:comp/env/{0}\");\n"; 229 230 233 private static final String JNDI_LOOKUP_EJB3_JAVASE = 234 "javax.naming.Context c = new javax.naming.InitialContext();\n" + 235 "return ({1}) c.lookup(\"{0}\");\n"; 236 237 private Object generateInjection(FileObject fileObject, final String className, String refName, final String fieldTypeClass) throws IOException { 238 String strippedRefName = refName.substring(refName.lastIndexOf('/') + 1); 239 String name = Character.toLowerCase(strippedRefName.charAt(0)) + strippedRefName.substring(1); 240 _RetoucheUtil.generateAnnotatedField( 241 fileObject, 242 className, 243 "javax.ejb.EJB", 244 name, 245 fieldTypeClass, 246 null, 247 InjectionTargetQuery.isStaticReferenceRequired(fileObject, className) 248 ); 249 return null; 251 } 252 253 private Object generateJNDI(FileObject fileObject, final String className, String homeName, String refName, 254 boolean narrow, String componentName, boolean throwCheckedExceptions) throws IOException { 255 String name = "lookup"+refName.substring(refName.lastIndexOf('/')+1); 256 String body = null; 257 List <String > exceptions = new ArrayList <String >(); 258 boolean isTargetJavaSE = Utils.isTargetJavaSE(fileObject, className); 259 String sessionCreate = ""; 260 if (isSession()) { 261 sessionCreate = ".create()"; 262 } 263 if (isSimplified && isTargetJavaSE){ 264 body = MessageFormat.format(JNDI_LOOKUP_EJB3_JAVASE, new Object [] {entityAndSession.getEjbClass(), componentName}); 265 } else if (isSimplified) { 266 body = MessageFormat.format(JNDI_LOOKUP_EJB3, new Object [] {refName, componentName}); 267 } else if (isTargetJavaSE){ 268 body = MessageFormat.format(JNDI_LOOKUP_REMOTE_JAVASE, new Object [] {homeName, homeName, sessionCreate}); 269 } else if (narrow) { 270 body = MessageFormat.format(JNDI_LOOKUP_REMOTE, new Object [] {refName, homeName, sessionCreate}); 271 } else { 272 body = MessageFormat.format(JNDI_LOOKUP_LOCAL, new Object [] {refName, homeName, sessionCreate}); 273 } 274 String returnType = isSimplified ? componentName : homeName; 275 exceptions.add(NamingException .class.getName()); 276 if (isSession()) { 277 returnType = componentName; 278 if (!isSimplified) { 279 exceptions.add("javax.ejb.CreateException"); 280 } 281 if (narrow && !isSimplified) { 282 exceptions.add("java.rmi.RemoteException"); 283 } 284 } 285 if (!throwCheckedExceptions) { 286 Iterator exIt = exceptions.iterator(); 287 StringBuffer catchBody = new StringBuffer ("try {\n" + body + "}\n"); while (exIt.hasNext()) { 289 String exceptionName = (String ) exIt.next(); 290 catchBody.append("catch("); catchBody.append(exceptionName); 292 catchBody.append(' '); String capitalLetters = extractAllCapitalLetters(exceptionName); 294 catchBody.append(capitalLetters); 295 catchBody.append(") {\n"); catchBody.append(MessageFormat.format(LOG_STATEMENT, 297 new Object [] {capitalLetters})); 298 catchBody.append("throw new RuntimeException("+capitalLetters+");\n"); 299 catchBody.append("}\n"); } 301 body = catchBody.toString(); 302 exceptions = Collections.<String >emptyList(); 303 } 304 305 final MethodModel methodModel = MethodModel.create( 306 _RetoucheUtil.uniqueMemberName(fileObject, className, name, "ejb"), 307 returnType, 308 body, 309 Collections.<MethodModel.Variable>emptyList(), 310 exceptions, 311 Collections.singleton(Modifier.PRIVATE) 312 ); 313 JavaSource javaSource = JavaSource.forFileObject(fileObject); 314 javaSource.runModificationTask(new AbstractTask<WorkingCopy>() { 315 public void run(WorkingCopy workingCopy) throws IOException { 316 workingCopy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); 317 TypeElement typeElement = workingCopy.getElements().getTypeElement(className); 318 MethodTree methodTree = MethodModelSupport.createMethodTree(workingCopy, methodModel); 319 ClassTree classTree = workingCopy.getTrees().getTree(typeElement); 320 ClassTree newClassTree = workingCopy.getTreeMaker().addClassMember(classTree, methodTree); 321 workingCopy.rewrite(classTree, newClassTree); 322 } 323 }).commit(); 324 return null; 326 } 327 328 329 private Object generateServiceLocatorJNDI(FileObject fileObject, final String className, String homeName, String refName, 330 boolean narrow, String componentName, boolean throwCheckedExceptions, String serviceLocatorName) throws IOException { 331 String name = "lookup"+refName.substring(refName.lastIndexOf('/')+1); 332 String body = null; 333 List <String > exceptions = new ArrayList <String >(3); 334 exceptions.add(NamingException .class.getName()); 335 String returnType = isSimplified ? componentName : homeName; 336 boolean genCreate = isSession(); 337 if (genCreate) { 338 returnType = componentName; 339 exceptions.add("javax.ejb.CreateException"); if (narrow) { 341 exceptions.add("java.rmi.RemoteException"); } 343 } 344 Project enterpriseProject = FileOwnerQuery.getOwner(fileObject); 345 ServiceLocatorStrategy sls = ServiceLocatorStrategy.create(enterpriseProject, fileObject, serviceLocatorName); 346 if (narrow) { 347 body = sls.genRemoteEjbStringLookup(refName, homeName, fileObject, className, genCreate); 348 } else { 349 body = sls.genLocalEjbStringLookup(refName, homeName, fileObject, className, genCreate); 350 } 351 if (!throwCheckedExceptions) { 352 Iterator exIt = exceptions.iterator(); 353 StringBuffer catchBody = new StringBuffer ("try {\n" + body + "\n}"); while (exIt.hasNext()) { 355 String exceptionName = (String ) exIt.next(); 356 catchBody.append(" catch("); catchBody.append(exceptionName); 358 catchBody.append(' '); String capitalLetters = extractAllCapitalLetters(exceptionName); 360 catchBody.append(capitalLetters); 361 catchBody.append(") {\n"); catchBody.append(MessageFormat.format(LOG_STATEMENT, new Object [] {capitalLetters})); 363 catchBody.append("throw new RuntimeException("+capitalLetters+");\n"); 364 catchBody.append('}'); 365 body = catchBody.toString(); 366 exceptions = Collections.<String >emptyList(); 367 } 368 } 369 370 final MethodModel methodModel = MethodModel.create( 371 _RetoucheUtil.uniqueMemberName(fileObject, className, name, "ejb"), 372 returnType, 373 body, 374 Collections.<MethodModel.Variable>emptyList(), 375 exceptions, 376 Collections.singleton(Modifier.PRIVATE) 377 ); 378 JavaSource javaSource = JavaSource.forFileObject(fileObject); 379 javaSource.runModificationTask(new AbstractTask<WorkingCopy>() { 380 public void run(WorkingCopy workingCopy) throws IOException { 381 workingCopy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); 382 TypeElement typeElement = workingCopy.getElements().getTypeElement(className); 383 MethodTree methodTree = MethodModelSupport.createMethodTree(workingCopy, methodModel); 384 ClassTree classTree = workingCopy.getTrees().getTree(typeElement); 385 ClassTree newClassTree = workingCopy.getTreeMaker().addClassMember(classTree, methodTree); 386 workingCopy.rewrite(classTree, newClassTree); 387 } 388 }).commit(); 389 return null; 391 } 392 393 private String extractAllCapitalLetters(String word) { 394 StringBuffer caps = new StringBuffer (4); 395 for (int i =0; i < word.length(); i++) { 396 char character = word.charAt(i); 397 if (Character.isUpperCase(character)) { 398 caps.append(Character.toLowerCase(character)); 399 } 400 } 401 return caps.toString(); 402 } 403 404 private boolean isSession() { 405 return entityAndSession instanceof Session; 406 } 407 408 } 409 | Popular Tags |