1 19 20 package org.netbeans.modules.j2ee.refactoring.changeparam; 21 22 import java.io.IOException ; 23 import java.text.MessageFormat ; 24 import java.util.ArrayList ; 25 import java.util.Collection ; 26 import java.util.List ; 27 import javax.jmi.reflect.RefObject; 28 import org.netbeans.api.project.FileOwnerQuery; 29 import org.netbeans.api.project.Project; 30 import org.netbeans.jmi.javamodel.ClassDefinition; 31 import org.netbeans.jmi.javamodel.JavaClass; 32 import org.netbeans.jmi.javamodel.Method; 33 import org.netbeans.jmi.javamodel.Type; 34 import org.netbeans.modules.j2ee.dd.api.ejb.EjbJar; 35 import org.netbeans.modules.j2ee.dd.api.ejb.EnterpriseBeans; 36 import org.netbeans.modules.j2ee.dd.api.ejb.Entity; 37 import org.netbeans.modules.j2ee.dd.api.ejb.MethodParams; 38 import org.netbeans.modules.j2ee.dd.api.ejb.Query; 39 import org.netbeans.modules.j2ee.dd.api.ejb.QueryMethod; 40 import org.netbeans.modules.j2ee.dd.api.ejb.Session; 41 import org.netbeans.modules.j2ee.refactoring.Utility; 42 import org.netbeans.modules.javacore.api.JavaModel; 43 import org.netbeans.modules.javacore.internalapi.ExternalChange; 44 import org.netbeans.modules.javacore.internalapi.JavaMetamodel; 45 import org.netbeans.modules.refactoring.api.AbstractRefactoring; 46 import org.netbeans.modules.refactoring.api.ChangeParametersRefactoring; 47 import org.netbeans.modules.refactoring.api.ChangeParametersRefactoring.ParameterInfo; 48 import org.netbeans.modules.refactoring.api.Problem; 49 import org.netbeans.modules.refactoring.api.RefactoringSession; 50 import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation; 51 import org.netbeans.modules.refactoring.spi.RefactoringElementsBag; 52 import org.openide.ErrorManager; 53 import org.openide.filesystems.FileObject; 54 import org.openide.util.NbBundle; 55 56 60 public final class EjbJarChangeParamRefactoring { 61 62 private static final ErrorManager err = ErrorManager.getDefault().getInstance("org.netbeans.modules.j2ee.refactoring.changeparam"); 64 65 private boolean isCmpImplFinder = false; 66 67 68 private boolean isCmpLocalHomeFinder = false; 69 70 71 private boolean isCmpHomeFinder = false; 72 73 74 ArrayList ifaceRefactors = new ArrayList (); 75 76 77 ArrayList implRefactors = new ArrayList (); 78 private static final String METHOD_EJBCREATE = "ejbCreate"; 79 80 public EjbJarChangeParamRefactoring() { } 81 82 public Problem preCheck(RefObject refObject) { 83 Problem[] problem = new Problem[] {null}; 84 if (refObject instanceof Method) { 85 Method method = (Method) refObject; 86 Collection emodules = Utility.getRelevantEjbModules(method); 87 if ((emodules != null) && (emodules.size() > 0)) { 88 ClassDefinition declaringClass = method.getDeclaringClass(); err.log("classdefinition jc: " + declaringClass); 91 if (declaringClass instanceof JavaClass) { 92 FileObject fo = JavaModel.getFileObject(method.getResource()); 93 if (Utility.isSubTypeOf(declaringClass, Utility.SESSION_BEAN)) { 94 checkSessionBeanImpl(problem, method, fo, declaringClass); 95 } else if (Utility.isSubTypeOf(declaringClass, Utility.ENTITY_BEAN)) { 96 checkEntityBeanImpl(problem, method, fo, declaringClass); 97 } else if (Utility.isSubTypeOf(declaringClass, Utility.MESSAGE_DRIVEN_BEAN)) { 98 checkMessageDrivenBeanImpl(problem, method, declaringClass); 99 } else if (Utility.isSubTypeOf(declaringClass, Utility.EJB_HOME)) { 100 checkHomeInterface(problem, method, fo, declaringClass, false); 101 } else if (Utility.isSubTypeOf(declaringClass, Utility.EJB_LOCAL_HOME)) { 102 checkHomeInterface(problem, method, fo, declaringClass, true); 103 } 104 } 105 } 106 } 107 return problem[0]; 108 } 109 110 private void checkSessionBeanImpl(Problem[] problem, Method method, FileObject fo, ClassDefinition jc) { 111 if (Utility.isSignatureFromSessionBeanInterface(method)) { 113 addFatalProblem(problem, "TXT_EjbJarMethodInJavaxInterfaceProblemChangeParam", 114 Utility.SESSION_BEAN); 115 } else if (!checkCreateInSession(problem, fo, method)) { 116 String className = jc.getName(); 117 Method homeInHome = 119 Utility.getHomeHomeMethodForSessionImplHomeMethod(method, fo, className, false); 120 checkMethodInInterface(problem, homeInHome, "home"); 121 Method homeInLocalHome = 122 Utility.getHomeHomeMethodForSessionImplHomeMethod(method, fo, className, true); 123 checkMethodInInterface(problem, homeInLocalHome, "local home"); 124 } 125 } 126 127 private void checkEntityBeanImpl(Problem[] problem, Method method, FileObject fo, ClassDefinition jc) { 128 if (Utility.isSignatureFromEntityBeanInterface(method)) { 131 addFatalProblem(problem, "TXT_EjbJarMethodInJavaxInterfaceProblemChangeParam", 132 Utility.ENTITY_BEAN); 133 } else { 134 String className = jc.getName(); 135 String methodName = method.getName(); 136 137 if (methodName.startsWith(METHOD_EJBCREATE)) { Method createInHome = Utility.getHomeCreateMethodForEntityImplCreateMethod(method, fo, 142 className, false); 143 checkMethodInInterface(problem, createInHome, "home"); 144 Method createInLocalHome = Utility.getHomeCreateMethodForEntityImplCreateMethod(method, fo, 145 className, true); 146 checkMethodInInterface(problem, createInLocalHome, "local home"); 147 Method postCreateInImpl = Utility.getImplPostCreateMethodForEntityImplCreateMethod(method); 148 checkMethodInImpl(problem, postCreateInImpl, 149 "TXT_EjbJarPostCreateMethodWarningChangeParam"); 150 } else if (methodName.equals("ejbPostCreate")) { Method createInHome = Utility.getHomeCreateMethodForEntityImplPostCreateMethod(method, fo, 155 className, false); 156 checkMethodInInterface(problem, createInHome, "home"); 157 Method createInLocalHome = Utility.getHomeCreateMethodForEntityImplPostCreateMethod(method, 158 fo, className, true); 159 checkMethodInInterface(problem, createInLocalHome, "local home"); 160 Method createInImpl = Utility.getImplCreateMethodForEntityImplPostCreateMethod(method); 161 checkMethodInImpl(problem, createInImpl, "TXT_EjbJarCreateMethodWarningChangeParam"); 162 } else if (methodName.startsWith("ejbFind")) { 163 isCmpImplFinder = true; 167 Method finderInHome = 168 Utility.getHomeFinderMethodForImplFinderMethod(method, fo, className, false); 169 checkMethodInInterface(problem, finderInHome, "home"); 170 Method finderInLocalHome = 171 Utility .getHomeFinderMethodForImplFinderMethod(method, fo, className, true); 172 checkMethodInInterface(problem, finderInLocalHome, "local home"); 173 } else { 174 Method homeInHome = 178 Utility.getHomeHomeMethodForEntityImplHomeMethod(method, fo, className, false); 179 checkMethodInInterface(problem, homeInHome, "home"); 180 Method homeInLocalHome = 181 Utility.getHomeHomeMethodForEntityImplHomeMethod(method, fo, className, true); 182 checkMethodInInterface(problem, homeInLocalHome, "local home"); 183 } 184 } 185 } 186 187 private void checkMessageDrivenBeanImpl(Problem[] problem, Method method, ClassDefinition jc) { 188 if (Utility.isSignatureFromMessageDrivenBeanInterface(method)) { 191 addFatalProblem(problem, "TXT_EjbJarMethodInJavaxInterfaceProblemChangeParam", 192 Utility.MESSAGE_DRIVEN_BEAN); 193 } 194 if (jc.isSubTypeOf(Utility.resolveRealClass(Utility.MESSAGE_LISTENER))) { 195 if (Utility.isSignatureFromMessageListenerInterface(method)) { 196 addFatalProblem(problem, "TXT_EjbJarMethodInJavaxInterfaceProblemChangeParam", 197 Utility.MESSAGE_LISTENER); 198 199 } 200 } 201 } 202 203 private void addFatalProblem(Problem[] problem, String resName, String param) { 204 String msg = NbBundle.getMessage(EjbJarChangeParamRefactoring.class, resName, param); 205 problem[0] = Utility.addProblemsToEnd(problem[0], new Problem(true, msg)); 206 } 207 208 private void checkHomeInterface(Problem[] problem, Method method, FileObject fo, ClassDefinition classDefinition, 209 boolean local) { 210 String methodName = method.getName(); 211 String className = classDefinition.getName(); 212 if (methodName.startsWith(Utility.PREFIX_CREATE)) { 213 Method createInImpl = Utility.getImplCreateMethodForHomeCreateMethod(method, fo, className, local); 216 if (checkCreateInSession(problem, fo, createInImpl)) { 217 return; 218 } 219 checkMethodInImpl(problem, createInImpl); 220 Method createInHome = Utility.getHomeCreateMethodForHomeCreateMethod(method, fo, className, !local); 221 checkMethodInInterface(problem, createInHome); 222 Method postCreateInImpl = 223 Utility.getImplPostCreateMethodForHomeCreateMethod(method, fo, className, local); 224 checkMethodInImpl(problem, postCreateInImpl); 225 } else if (methodName.startsWith("find")) { 226 if (local) { 229 isCmpLocalHomeFinder = true; 230 } else { 231 isCmpHomeFinder = true; 232 } 233 Method finderInImpl = Utility.getImplFinderMethodForHomeFinderMethod(method, fo, className, local); 234 checkMethodInImpl(problem, finderInImpl); 235 Method finderInHome = Utility.getHomeFinderMethodForHomeFinderMethod(method, fo, className, !local); 236 checkMethodInInterface(problem, finderInHome); 237 } else { 238 Method homeInImpl = Utility.getImplHomeMethodForHomeHomeMethod(method, fo, className, local); 241 checkMethodInImpl(problem, homeInImpl); 242 Method homeInHome = Utility.getHomeHomeMethodForHomeHomeMethod(method, fo, className, !local); 243 checkMethodInInterface(problem, homeInHome); 244 } 245 } 246 247 private boolean checkCreateInSession(Problem[] problem, FileObject fo, Method createInImpl) { 248 if (createInImpl == null || !createInImpl.getName().equals(Utility.PREFIX_EJBCREATE)) { 249 return false; 250 } 251 ClassDefinition implClass = createInImpl.getDeclaringClass(); 252 if (!Utility.isSubTypeOf(implClass, Utility.SESSION_BEAN)) { 253 return false; 254 } 255 List parameters = createInImpl.getParameters(); 256 if (parameters != null && parameters.size() > 0) { 257 return false; 258 } 259 EnterpriseBeans enterpriseBeans = Utility.getEnterpriseBeansFromDD(fo); 260 if (enterpriseBeans == null) { 261 return false; 262 } 263 Session[] sessions = enterpriseBeans.getSession(); 264 if (sessions == null) { 265 return false; 266 } 267 for (int i = 0; i < sessions.length; i++) { 268 Session session = sessions[i]; 269 String className = implClass.getName(); 270 if (session.getEjbClass().equals(className)) { 271 if (Session.SESSION_TYPE_STATELESS.equals(session.getSessionType())) { 272 String msg = NbBundle.getMessage(EjbJarChangeParamRefactoring.class, "TXT_EjbJarCreateMethodErrorChangeParam"); 273 problem[0] = Utility.addProblemsToEnd(problem[0], new Problem(true, msg)); 274 return true; 275 } else { 276 Method createInHome = Utility.getMethodInHomeClassForImpl(fo, Session.class, className, 277 Utility.PREFIX_CREATE, parameters, false); 278 checkMethodInInterface(problem, createInHome, "home"); 279 Method createInLocalHome = Utility.getMethodInHomeClassForImpl(fo, Session.class, className, 280 Utility.PREFIX_CREATE, parameters, true); 281 checkMethodInInterface(problem, createInLocalHome, "local home"); 282 return true; 283 } 284 } 285 } 286 return false; 287 } 288 289 private boolean checkMethod(List refactorings, Problem problem[], Method method, String resName, String param) { 290 if (method != null) { 291 ChangeParametersRefactoring refactoring = new ChangeParametersRefactoring(method); 292 problem[0] = Utility.addProblemsToEnd(problem[0], refactoring.preCheck()); 293 refactorings.add(refactoring); 294 if (resName != null) { 295 String msg; 296 if (param != null) { 297 msg = NbBundle.getMessage(EjbJarChangeParamRefactoring.class, resName, param); 298 } else { 299 msg = NbBundle.getMessage(EjbJarChangeParamRefactoring.class, resName); 300 } 301 problem[0] = Utility.addProblemsToEnd(problem[0], new Problem(false, msg)); 302 } 303 return true; 304 } else { 305 return false; 306 } 307 } 308 309 310 private boolean checkMethodInImpl(Problem[] problem, Method method) { 311 return checkMethod(implRefactors, problem, method, null, null); 312 } 313 314 private void checkMethodInImpl(Problem[] problem, Method postCreateInImpl, String resName) { 315 checkMethod(implRefactors, problem, postCreateInImpl, resName, null); 316 } 317 318 private boolean checkMethodInInterface(Problem[] problem, Method method) { 319 return checkMethod(ifaceRefactors, problem, method, null, null); 320 } 321 322 private boolean checkMethodInInterface(Problem[] problem, Method method, String interfaceName) { 323 return checkMethod(ifaceRefactors, problem, method, "TXT_EjbJarIfaceMethodWarningChangeParam", interfaceName); 324 } 325 326 public Problem fastCheckParameters(RefObject refObject) { 327 return null; 332 } 333 334 public Problem checkParameters(RefObject refObject) { 335 return fastCheckParameters(refObject); 336 } 337 338 public Problem prepare(AbstractRefactoring refactoring, RefObject refObject, ParameterInfo[] paramInfo, 339 int modifier, RefactoringElementsBag refactoringElements) { 340 RefactoringSession session = refactoringElements.getSession(); 341 Problem problem = null; 342 if (refObject instanceof Method) { 343 Method method = (Method) refObject; 344 if (isChanged(method, paramInfo)) { 345 processFinderMethods(refactoring, method, paramInfo, refactoringElements); 346 } 347 for (int i = 0; i < ifaceRefactors.size(); i++) { 348 problem = prepareRefactoring((ChangeParametersRefactoring) ifaceRefactors.get(i), modifier, paramInfo, 349 session, problem); 350 } 351 for (int i = 0; i < implRefactors.size(); i++) { 352 problem = prepareRefactoring((ChangeParametersRefactoring) implRefactors.get(i), modifier, paramInfo, 353 session, problem); 354 } 355 } 356 return problem; 357 } 358 359 private void processFinderMethods(AbstractRefactoring refactoring, Method method, ParameterInfo[] paramInfo, 360 RefactoringElementsBag refactoringElements) { 361 if (isCmpImplFinder || isCmpHomeFinder || isCmpLocalHomeFinder) { 362 String methodName = method.getName(); 363 if (isCmpImplFinder) { 364 methodName = methodName.substring(9, 10).toLowerCase() + methodName.substring(10); 365 } 366 err.log("method name: " + methodName); 367 368 FileObject fo = JavaModel.getFileObject(method.getResource()); 369 if (fo == null) { 370 return; 371 } 372 Project prj = FileOwnerQuery.getOwner(fo); 373 if (prj == null) { 374 return; 375 } 376 org.netbeans.modules.j2ee.api.ejbjar.EjbJar emod = 377 org.netbeans.modules.j2ee.api.ejbjar.EjbJar.getEjbJar(prj.getProjectDirectory()); 378 ClassDefinition declaringClass = method.getDeclaringClass(); 379 err.log("classdefinition jc: " + declaringClass); 380 if (declaringClass instanceof JavaClass) { 381 Entity[] eBeans = Utility.getEntityBeans(emod); 382 EjbJar ejbJarDD = Utility.getEjbJar(emod); 383 if ((eBeans != null) && (ejbJarDD != null)) { 384 for (int i = 0; i < eBeans.length; i++) { 385 Entity entity = eBeans[i]; 386 if (isCmpImplFinder) { 387 prepareQueries(declaringClass, entity.getEjbClass(), entity, methodName, ejbJarDD, 388 paramInfo, emod, refactoringElements, refactoring); 389 } else { 390 if (isCmpHomeFinder) { 391 prepareQueries(declaringClass, entity.getHome(), entity, methodName, ejbJarDD, 392 paramInfo, emod, refactoringElements, refactoring); 393 } 394 if (isCmpLocalHomeFinder) { 395 prepareQueries(declaringClass, entity.getLocalHome(), entity, methodName, ejbJarDD, 396 paramInfo, emod, refactoringElements, refactoring); 397 } 398 } 399 } 400 } 401 } 402 } 403 } 404 405 private Problem prepareRefactoring(ChangeParametersRefactoring chr, int modifier, 406 ParameterInfo[] paramInfo, RefactoringSession session, Problem problem) { 407 chr.setModifiers(modifier); 408 chr.setParameterInfo(paramInfo); 409 Problem p = chr.prepare(session); 410 problem = Utility.addProblemsToEnd(problem, p); 411 return problem; 412 } 413 414 private void prepareQueries(ClassDefinition jc, String ejbClass, Entity entity, String methodName, EjbJar ejbJarDD, 415 ParameterInfo[] paramInfo, org.netbeans.modules.j2ee.api.ejbjar.EjbJar emod, 416 RefactoringElementsBag refactoringElements, AbstractRefactoring refactoring) { 417 if (jc.getName().equals(ejbClass)) { 418 Query[] queries = entity.getQuery(); 419 for (int q=0; q<queries.length; q++) { 420 QueryMethod qm = queries[q].getQueryMethod(); 421 err.log("query method: " + qm); 422 if (methodName.equals(qm.getMethodName())) { 423 RefactoringElementImplementation elem = 424 new EjbJarFinderMethodChangeParamsRefactoringElement(ejbJarDD, methodName, paramInfo, entity, emod.getDeploymentDescriptor()); 425 refactoringElements.add(refactoring, elem); 426 } 427 } 428 } 429 } 430 431 public final class EjbJarFinderMethodChangeParamsRefactoringElement extends AbstractChangeParamsRefactoringElement 432 implements ExternalChange { 433 protected EjbJar ejbJarDD; 434 private Entity entity; 435 private String [] oldParams = new String []{}; 436 437 440 public EjbJarFinderMethodChangeParamsRefactoringElement(EjbJar ejbJarDD, String methodName, 441 ParameterInfo[] paramInfo, Entity entity, FileObject parentFile) { 442 this.ejbJarDD = ejbJarDD; 443 this.entity = entity; 444 this.methodName = methodName; 445 this.paramInfo = paramInfo; 446 this.parentFile = parentFile; 447 } 448 449 454 public String getDisplayText() { 455 Object [] args = new Object []{parentFile.getNameExt(), methodName}; 456 return MessageFormat.format(NbBundle.getMessage(EjbJarChangeParamRefactoring.class, 457 "TXT_EjbJarFinderMethodChangeParam"), args); 458 } 459 460 463 public void performChange() { 464 JavaMetamodel.getManager().registerExtChange(this); 465 } 466 467 public void performExternalChange() { 468 Query[] queries = entity.getQuery(); 469 for (int q = 0; q < queries.length; q++) { 470 QueryMethod qm = queries[q].getQueryMethod(); 471 if (methodName.equals(qm.getMethodName())) { 472 MethodParams mp = qm.getMethodParams(); 473 if (mp != null) { 474 oldParams = mp.getMethodParam(); 475 String [] newParams = getNewParameters(paramInfo, oldParams); 476 if (newParams != null) { 477 mp.setMethodParam(newParams); 478 } 479 } 480 try { 481 ejbJarDD.write(parentFile); 482 } catch (IOException ioe) { 483 } 485 } 486 } 487 } 488 489 public void undoExternalChange() { 490 Query[] queries = entity.getQuery(); 491 for (int q = 0; q < queries.length; q++) { 492 QueryMethod qm = queries[q].getQueryMethod(); 493 if (methodName.equals(qm.getMethodName())) { 494 MethodParams mp = qm.getMethodParams(); 495 if (mp != null) { 496 if (oldParams != null) { 497 mp.setMethodParam(oldParams); 498 } 499 } 500 try { 501 ejbJarDD.write(parentFile); 502 } catch (IOException ioe) { 503 } 505 } 506 } 507 } 508 } 509 510 511 private static boolean isChanged(Method method, ParameterInfo[] paramInfo) { 512 if ((paramInfo != null)) { 513 if (paramInfo.length < method.getParameters().size()) { return true; 515 } 516 if ((paramInfo.length > 0)) { 517 for (int i=0; i<paramInfo.length; i++) { 518 ParameterInfo pi = paramInfo[i]; 519 if ((pi.getDefaultValue() != null) || 520 (pi.getOriginalIndex() != i) || 521 (pi.getType() != null) 522 ) { 523 return true; 524 } 525 } 526 } 527 } 528 return false; 529 } 530 531 private static String [] getNewParameters(ParameterInfo[] paramInfo, String [] methodParams) { 532 String [] newParams = new String [paramInfo.length]; 533 if ((paramInfo != null) && (paramInfo.length > 0)) { 534 for (int i=0; i<paramInfo.length; i++) { 535 ParameterInfo pi = paramInfo[i]; 536 Type newParamType = pi.getType(); 537 if (newParamType == null) { 538 newParams[i] = methodParams[pi.getOriginalIndex()]; 539 } else { 540 newParams[i] = newParamType.getName(); 541 } 542 } 543 } 544 return newParams; 545 } 546 } | Popular Tags |