1 19 package org.netbeans.modules.javacore.jmiimpl.javamodel; 20 21 import java.lang.reflect.Modifier ; 22 import java.util.*; 23 import org.netbeans.jmi.javamodel.*; 24 import org.netbeans.lib.java.parser.ASTree; 25 import org.netbeans.mdr.handlers.AttrListWrapper; 26 import org.netbeans.mdr.storagemodel.StorableObject; 27 import org.netbeans.modules.javacore.JMManager; 28 import org.netbeans.modules.javacore.parser.ElementInfo; 29 import org.netbeans.modules.javacore.parser.MethodInfo; 30 import org.netbeans.modules.javacore.parser.MDRParser; 31 import org.netbeans.modules.javacore.parser.TypeRef; 32 import org.openide.util.Utilities; 33 34 35 42 public abstract class CallableFeatureImpl extends BehavioralFeatureImpl implements CallableFeature { 43 public static final String PARAMETERS_ATTR = "parameters"; 45 protected boolean elementsInited = false; 46 47 protected LightAttrList parameters; 48 49 50 protected ReferenceListWrapper exceptions = null; 51 52 private LightAttrList excNames = null; 53 private LightAttrList typeParameters = null; 54 55 56 public CallableFeatureImpl(StorableObject s) { 57 super(s); 58 } 59 60 protected void matchPersistent(ElementInfo newInfo) { 61 super.matchPersistent(newInfo); 62 63 MethodInfo info = (MethodInfo) newInfo; 64 65 if (!isPersisted()) { 66 setPersisted(true); 67 persist(); 68 setTypeRef(info.type); 69 setExceptionRefs(Arrays.asList(info.exceptions)); 70 persistChildren(getPersistentList("annotations", super_getAnnotations()), info.annotations); 71 persistChildren(getPersistentList(TYPE_PARAMETERS_ATTR, super_getTypeParameters()), info.typeParams); 72 persistChildren(getPersistentList(PARAMETERS_ATTR, super_getParameters()), info.parameters); 73 } else { 74 if (!Utilities.compareObjects(info.type, getTypeRef())) { 75 setType(resolveType(info.type)); 76 } 77 processMembers(getAnnotations(), info.annotations); 78 processMembers(getTypeParameters(), info.typeParams); 79 processMembers(getExceptions(), info.exceptions); 80 processMembers(getParameters(), info.parameters); 81 } 82 } 83 84 86 protected void matchElementInfo(ElementInfo newInfo) { 87 super.matchElementInfo(newInfo); 88 resetASTElements(); 89 } 90 91 protected void resetChildren() { 92 super.resetChildren(); 93 if (parameters != null) parameters.setInnerList(getPersistentList(PARAMETERS_ATTR, super_getParameters())); 94 if (typeParameters != null) typeParameters.setInnerList(getPersistentList(TYPE_PARAMETERS_ATTR, super_getTypeParameters())); 95 if (childrenInited) { 96 resetASTElements(); 97 initChildren(); 98 } 99 if (exceptions != null) { 100 initExceptions(); 101 } 102 } 103 104 protected void resetASTElements() { 105 if (elementsInited) { 106 if (excNames != null) { 107 deleteChildren(excNames); 108 excNames = null; 109 } 110 elementsInited = false; 111 } 112 if (bodyInited) { 113 resetBody(); 114 } 115 } 116 117 protected void initASTElements() { 118 elementsInited = false; 119 if (!childrenInited) { 120 initChildren(); 121 } 122 MethodInfo info = (MethodInfo) getElementInfo(); 123 ASTree[] namesAST = info.getExceptionsAST(this); 124 excNames = createChildrenList(excNames, "exceptionNames", namesAST, CHANGED_THROWS, false); elementsInited = true; 126 } 127 128 protected ASTree getBodyAST() { 129 return getASTree().getSubTrees()[5]; 130 } 131 132 136 public List getParameters() { 137 checkUpToDate(); 138 if (parameters == null) { 139 parameters = createChildrenList(PARAMETERS_ATTR, (AttrListWrapper) super_getParameters(), null, CHANGED_PARAMETERS); 140 } 141 return parameters; 142 } 143 144 public List getTypeParameters() { 145 checkUpToDate(); 146 if (typeParameters == null) { 147 typeParameters = createChildrenList(TYPE_PARAMETERS_ATTR, (AttrListWrapper) super_getTypeParameters(), null, CHANGED_TYPE_PARAMETERS); 148 } 149 return typeParameters; 150 } 151 152 boolean hasTypeParameters() { 153 checkUpToDate(); 154 return !super_getTypeParameters().isEmpty(); 155 } 156 157 protected void initChildren() { 158 childrenInited = false; 159 MethodInfo info = (MethodInfo) getElementInfo(); 160 parameters = createChildrenList(parameters, PARAMETERS_ATTR, (AttrListWrapper) super_getParameters(), info.parameters, CHANGED_PARAMETERS); 161 typeParameters = createChildrenList(typeParameters, TYPE_PARAMETERS_ATTR, (AttrListWrapper) super_getTypeParameters(), info.typeParams, CHANGED_TYPE_PARAMETERS); 162 super.initChildren(); 163 childrenInited = true; 164 165 if (elementsInited) { 166 initASTElements(); 167 } 168 169 StatementBlock body = retrieveBody(); 170 if (bodyInited) { 171 JMManager.getTransactionMutex().addBFeatureToInitQueue(this); 172 } 173 } 174 175 protected abstract List super_getParameters(); 176 protected abstract List super_getTypeParameters(); 177 178 protected void setData(List annotations, String javadocText, JavaDoc javadoc, StatementBlock body, String bodyText, List typeParameters, List parameters, List exceptionNames) { 179 super.setData(annotations, javadocText, javadoc, body, bodyText); 180 this.typeParameters = createChildrenList(TYPE_PARAMETERS_ATTR, (AttrListWrapper) super_getTypeParameters(), typeParameters, CHANGED_TYPE_PARAMETERS); this.parameters = createChildrenList(PARAMETERS_ATTR, (AttrListWrapper) super_getParameters(), parameters, CHANGED_PARAMETERS); this.excNames = createChildrenList("exceptionNames", exceptionNames, CHANGED_THROWS); elementsInited = true; 184 } 185 186 190 public List getExceptions() { 191 checkUpToDate(); 192 if (exceptions == null) { 193 initExceptions(); 194 } 195 return exceptions; 196 } 197 198 public List getExceptionNames() { 199 if (!elementsInited) { 200 initASTElements(); 201 } 202 return excNames; 203 } 204 205 public List getChildren() { 206 List list = new ArrayList(); 207 list.addAll(getTypeParameters()); 208 list.addAll(getParameters()); 209 list.addAll(getExceptionNames()); 210 list.addAll(super.getChildren()); 211 return list; 212 } 213 214 public void fixImports(Element scope, Element original) { 215 CallableFeature feature=(CallableFeature)original; 216 fixImports(scope,getTypeParameters(),feature.getTypeParameters()); 217 fixImports(scope,getParameters(),feature.getParameters()); 218 fixImportsInClassList(scope,getExceptionNames(),feature.getExceptions()); 219 super.fixImports(scope,original); 220 } 221 222 protected List getInitedChildren() { 223 List list = super.getInitedChildren(); 224 if (childrenInited) { 225 list.addAll(typeParameters); 226 list.addAll(parameters); 227 } 228 if (elementsInited) { 229 list.addAll(excNames); 230 } 231 return list; 232 } 233 234 public void replaceChild(Element oldElement, Element newElement) { 235 if (replaceObject(getParameters(), oldElement, newElement)) return; 236 if (replaceObject(getTypeParameters(), oldElement, newElement)) return; 237 if (elementsInited) { 238 if (replaceObject(excNames, oldElement, newElement)) return; 239 } 240 super.replaceChild(oldElement, newElement); 241 } 242 243 public Collection findDependencies(boolean findUsages, boolean fromBaseClass, boolean findOverridingMethods) { 244 Resource[] res = findReferencedResources(); 245 246 if (!fromBaseClass || (fromBaseClass && !isOverriden())) { 247 Element cd = getDeclaringClass(); 248 boolean isPrivate = false; 249 while (cd != null && !(cd instanceof Resource)) { 250 if (cd instanceof JavaClass) { 251 int m = ((JavaClass) cd).getModifiers(); 252 if (!Modifier.isPublic(m) && !Modifier.isProtected(m)) { 253 isPrivate = true; 254 break; 255 } 256 } 257 cd = (Element) cd.refImmediateComposite(); 258 } 259 if (isPrivate) { 260 res = filterResourcesFromThisPackage(res); 261 } 262 } 263 264 UsageFinder finder = new UsageFinder(this, findUsages, fromBaseClass, findOverridingMethods); 265 return finder.getUsers(res); 266 } 267 268 private boolean isOverriden() { 269 if (!(this instanceof Method)) 270 return false; 271 272 ClassDefinition declaringClass = getDeclaringClass(); 273 274 List params = new ArrayList(); 275 for (Iterator i = getParameters().iterator(); i.hasNext(); params.add(((Parameter)i.next()).getType())); 276 277 ClassDefinition parent = declaringClass.getSuperClass(); 278 Method m = parent.getMethod(getName(), params, true); 279 if (m!=null) { 280 return true; 281 } 282 Iterator i = declaringClass.getInterfaces().iterator(); 283 while (i.hasNext()) { 284 ClassDefinition jc = (ClassDefinition) i.next(); 285 m = jc.getMethod(getName(), params, true); 286 if (m!=null) { 287 return true; 288 } 289 } 290 return false; 291 } 292 293 private void initExceptions() { 294 List exceptionNames = getExceptionRefs(); 295 if (exceptionNames == null) { 296 exceptionNames = new ArrayList(); 297 } else if (!(exceptionNames instanceof ArrayList)) { 298 exceptionNames = new ArrayList(exceptionNames); 299 } 300 TypeList innerExceptions = new TypeList(this, (ArrayList) exceptionNames) { 301 protected void updateParent() { 302 setExceptionRefs(innerList); 303 } 304 305 protected void fireChange(int attrType, TypeRef newTR, int position) { 306 Object newValue, oldValue; 307 if (elementsInited) { 308 newValue = typeRefToTypeReference(newTR, 0); 309 oldValue = null; 311 } else { 312 newValue = oldValue = null; 313 } 314 fireAttrChange("exceptionNames", oldValue, newValue, position); } 316 }; 317 if (exceptions == null) { 318 ThrowsImpl throwsImpl = (ThrowsImpl)(((JavaModelPackage) refImmediatePackage()).getThrows()); 319 exceptions = new ReferenceListWrapper(_getDelegate().getMdrStorage(), throwsImpl, this, "exceptions", this, CHANGED_THROWS, innerExceptions); } else { 321 exceptions.setInnerList(innerExceptions); 322 } 323 } 324 325 329 335 void generateHeader(StringBuffer buf) { 336 boolean nju = isNew(); 337 if (nju) 338 generateNewJavaDoc(buf); 339 generateNewModifiers(buf); 340 generateNewTypeParameters(buf); 341 generateTypeAndName(buf); 342 generateNewParameters(buf); 343 generateNewExceptions(buf); 344 } 345 346 351 abstract void generateTypeAndName(StringBuffer buf); 352 353 359 void generateNewParameters(StringBuffer buf) { 360 formatElementPart(PAR_OPEN_BRACKET, buf); 361 List parameters = getParameters(); 362 if (!parameters.isEmpty()) { 363 Iterator it = parameters.iterator(); 364 ParameterImpl impl = (ParameterImpl) it.next(); 365 buf.append(impl.getSourceText()); 366 while (it.hasNext()) { 367 formatElementPart(COMMA, buf); 368 impl = (ParameterImpl) it.next(); 369 buf.append(impl.getSourceText()); 370 } 371 } 372 formatElementPart(PAR_CLOSE_BRACKET, buf); 373 } 374 375 381 void generateNewExceptions(StringBuffer buf) { 382 Collection exceptions = getExceptionNames(); 383 if (!exceptions.isEmpty()) { 384 formatElementPart(THROWS_KEYWORD, buf); 385 Iterator it = exceptions.iterator(); 386 MultipartIdImpl id = (MultipartIdImpl) it.next(); 387 buf.append(id.getSourceText()); 388 while (it.hasNext()) { 389 formatElementPart(COMMA, buf); 390 id = (MultipartIdImpl) it.next(); 391 buf.append(id.getSourceText()); 392 } 393 } 394 } 395 396 private void generateNewTypeParameters(StringBuffer buf) { 397 Collection typeParameters = getTypeParameters(); 398 if (!typeParameters.isEmpty()) { 399 buf.append('<'); 400 Iterator it = typeParameters.iterator(); 401 while (it.hasNext()) { 402 buf.append(((TypeParameterImpl) it.next()).getSourceText()); 403 if (it.hasNext()) { 404 formatElementPart(COMMA, buf); 405 } 406 } 407 buf.append("> "); 408 } 409 } 410 411 protected void getTypeParamsDiff(List diffList) { 412 MethodInfo astInfo = (MethodInfo) getElementInfo(); 413 MDRParser parser = getParser(); 414 ASTree[] children = getASTree().getSubTrees(); 415 if (astInfo.typeParams.length == 0) { 416 if (isChanged(CHANGED_TYPE_PARAMETERS)) { 417 StringBuffer buf = new StringBuffer (); 418 generateNewTypeParameters(buf); 419 int endOffset = getStartOffset(parser, children[2], false); 420 diffList.add(new DiffElement(endOffset, endOffset, buf.toString())); 421 } 422 } else if (getTypeParameters().isEmpty()) { 423 if (isChanged(CHANGED_TYPE_PARAMETERS)) { 424 int endOffset = getStartOffset(parser, children[2], true); 425 int startOffset = getStartOffset(parser, children[1], true); 426 diffList.add(new DiffElement(startOffset, endOffset, "")); 427 } 428 } else { 429 getCollectionDiff(diffList, parser, CHANGED_TYPE_PARAMETERS, astInfo.typeParams, getTypeParameters(), parser.getToken(children[1].getLastToken()).getStartOffset(), ", "); } 431 } 432 433 protected void _delete() { 434 if (elementsInited) { 436 deleteChildren(excNames); 437 } 438 deleteChildren(PARAMETERS_ATTR, (AttrListWrapper) super_getParameters()); 440 deleteChildren(TYPE_PARAMETERS_ATTR, (AttrListWrapper) super_getTypeParameters()); 441 super._delete(); 446 } 447 448 protected void setExceptionRefs(List excs) { 449 _getDelegate().setSlot2(excs); 450 } 451 452 public List getExceptionRefs() { 453 return (List) _getDelegate().getSlot2(); 454 } 455 456 protected ASTree getPartEndTree(ElementPartKind part) { 457 if (ElementPartKindEnum.HEADER.equals(part)) { 458 ASTree[] headerParts = getASTree().getSubTrees(); 459 for (int i = 4; true; i--) { 460 ASTree result = headerParts[i]; 461 if (result != null) { 462 return result; 463 } 464 } 465 } 466 return super.getPartEndTree(part); 467 } 468 } 469 | Popular Tags |