1 19 package org.netbeans.modules.javacore.jmiimpl.javamodel; 20 21 import java.util.ArrayList ; 22 import java.util.Iterator ; 23 import org.netbeans.jmi.javamodel.*; 24 import org.netbeans.lib.java.parser.ASTree; 25 import org.netbeans.lib.java.parser.Token; 26 import org.netbeans.mdr.handlers.AttrListWrapper; 27 import org.netbeans.mdr.storagemodel.StorableObject; 28 import org.netbeans.modules.javacore.internalapi.JavaModelUtil; 29 import org.netbeans.modules.javacore.parser.ASTProvider; 30 import org.netbeans.modules.javacore.parser.ElementInfo; 31 import org.netbeans.modules.javacore.parser.ParameterInfo; 32 import org.netbeans.modules.javacore.parser.TypeRef; 33 import org.openide.util.Utilities; 34 import java.util.List ; 35 import org.netbeans.modules.javacore.parser.ArrayRef; 36 37 43 public abstract class ParameterImpl extends SemiPersistentElement implements Parameter { 44 private static final ElementInfo DEFAULT_INFO = new ParameterInfo(null, ParameterInfo.PARAMETER_TYPE, null, false, null, false, null); 45 46 private TypeReference typeName = null; 47 private int dimCount = 0; 48 private LightAttrList annotations = null; 49 private boolean internalSetDim = false; 50 51 protected ParameterImpl(StorableObject s) { 52 super(s); 53 } 54 55 60 protected void matchPersistent(ElementInfo info) { 61 super.matchPersistent(info); 62 ParameterInfo pinfo = (ParameterInfo) info; 63 64 if (pinfo.isFinal != isFinal()) { 65 setFinal(pinfo.isFinal); 66 } 67 if (pinfo.isVarArg != isVarArg()) { 68 setVarArg(pinfo.isVarArg); 69 } 70 71 if (!isPersisted()) { 72 setPersisted(true); 73 persist(); 74 setTypeRef(pinfo.type); 75 persistChildren(getPersistentList("annotations", super_getAnnotations()), pinfo.annotations); 76 } else { 77 if (!Utilities.compareObjects(pinfo.type, getTypeRef())) { 78 setType(resolveType(pinfo.type)); 79 } 80 processMembers(getAnnotations(), pinfo.annotations); 81 } 82 } 83 84 protected ElementInfo getDefaultInfo() { 85 return DEFAULT_INFO; 86 } 87 88 protected void resetChildren() { 89 super.resetChildren(); 90 if (typeName != null) { 91 TypeReference temp = typeName; 92 changeChild(typeName, null); 93 typeName = null; 94 temp.refDelete(); 95 } 96 if (annotations != null) { 97 annotations.setInnerList(getPersistentList("annotations", super_getAnnotations())); } 99 childrenInited = false; 100 } 101 102 106 public Type getType() { 107 checkUpToDate(); 108 return resolveType(getTypeRef()); 109 } 110 111 private void fireTypeNameChange(TypeReference typeReference) { 112 Object oldValue = null; 113 Object newValue = null; 114 if (childrenInited && !disableChanges) { 115 oldValue = getTypeName(); 116 newValue = typeReference; 117 } 118 fireAttrChange("typeName", oldValue, newValue); } 120 121 126 public void setType(Type newValue) { 127 TypeRef tr = typeToTypeRef(newValue); 128 TypeReference typeReference = null; 129 if (!disableChanges) { 130 updateDimCount(tr); 131 typeReference = (TypeReference) typeRefToTypeReference(tr, getDimCount()); 132 } 133 fireTypeNameChange(typeReference); 134 _setTypeName(typeReference, tr); 135 } 136 137 private void updateDimCount(TypeRef tr) { 138 int dimCount = getDimCount(); 139 if (tr instanceof ArrayRef) { 140 if (((ArrayRef) tr).dimCount < dimCount) { 141 _setDimCount(((ArrayRef) tr).dimCount); 142 } 143 } else if (dimCount > 0) { 144 _setDimCount(0); 145 } 146 } 147 148 private void _setDimCount(int dimCount) { 149 internalSetDim = true; 150 try { 151 setDimCount(dimCount); 152 } finally { 153 internalSetDim = false; 154 } 155 } 156 157 public TypeReference getTypeName() { 158 checkUpToDate(); 159 if (!childrenInited) { 160 initChildren(); 161 } 162 return typeName; 163 } 164 165 public void setTypeName(TypeReference typeName) { 166 _setTypeName(typeName, typeReferenceToTypeRef(typeName, getDimCount())); 167 } 168 169 private void _setTypeName(TypeReference typeName, TypeRef typeRef) { 170 if (!disableChanges) { 171 objectChanged(CHANGED_TYPE); 172 changeChild(getTypeName(), typeName); 173 this.typeName = typeName; 174 } 175 setTypeRef(typeRef); 176 } 177 178 184 public void setFinal(boolean newValue) { 185 objectChanged(CHANGED_IS_FINAL); 186 super_setFinal(newValue); 187 } 188 189 public List getAnnotations() { 190 checkUpToDate(); 191 if (annotations == null) { 192 annotations = createChildrenList("annotations", (AttrListWrapper) super_getAnnotations(), null, CHANGED_ANNOTATION); 193 } 194 return annotations; 195 } 196 197 protected abstract void super_setFinal(boolean newValue); 198 199 205 public void setVarArg(boolean newValue) { 206 objectChanged(CHANGED_IS_VARARG); 207 super_setVarArg(newValue); 208 } 209 210 protected abstract void super_setVarArg(boolean newValue); 211 212 protected ASTree getPartTree(ElementPartKind part) { 213 if (ElementPartKindEnum.NAME.equals(part)) { 214 return getASTree().getSubTrees()[VARIABLE_DECLARATOR_ID].getSubTrees()[0]; 215 } 216 throw new IllegalArgumentException ("Invalid part for this element: " + part); } 218 219 public String getSourceText() { 220 String origElem; 221 if ((origElem = checkChange()) != null) 222 return origElem; 223 224 StringBuffer buf = new StringBuffer (); 225 for (Iterator annIt = getAnnotations().iterator(); annIt.hasNext(); ) { 226 AnnotationImpl ann = (AnnotationImpl) annIt.next(); 227 buf.append(ann.getSourceText()).append(' '); 228 } 229 if (isFinal()) 230 buf.append("final "); buf.append(((MetadataElement) getTypeName()).getSourceText()); 232 if (isVarArg()) 233 buf.append("..."); buf.append(' '); 235 buf.append(getName()); 236 appendDims(buf, getDimCount()); 237 return buf.toString(); 238 } 239 240 protected void diffModifiers(List diffList, ASTree nextNode, ASTProvider parser) { 241 String text = ""; 242 for (Iterator annIt = getAnnotations().iterator(); annIt.hasNext(); ) { 243 AnnotationImpl ann = (AnnotationImpl) annIt.next(); 244 text += ann.getSourceText(); 245 if (annIt.hasNext()) { 246 text += ' '; 247 } 248 } 249 if (isFinal()) { 250 if (text.length() > 0) { 251 text += ' '; 252 } 253 text += "final"; } 255 int nextToken = nextNode.getFirstToken(); 256 int startOffset, endOffset; 257 int startToken; 258 endOffset = parser.getToken(nextToken).getStartOffset(); 259 ASTree modifiers = getASTree().getSubTrees()[FINAL_OPT]; 260 if (modifiers != null) { 261 startToken = modifiers.getFirstToken(); 262 startOffset = parser.getToken(startToken).getStartOffset(); 263 if (text.length() > 0) { 264 int endToken = modifiers.getLastToken(); 265 endOffset = parser.getToken(endToken).getEndOffset(); 266 } 267 } else { 268 startOffset = endOffset; 269 text += ' '; 270 } 271 diffList.add(new DiffElement(startOffset, endOffset, text)); 272 } 273 274 public void getDiff(List diffList) { 275 ASTProvider parser = getParser(); 277 ASTree[] children = getASTree().getSubTrees(); 278 if (isChanged(CHANGED_IS_FINAL) || isChanged(CHANGED_ANNOTATION)) { 279 diffModifiers(diffList, children[TYPE], parser); 280 } else if (children[FINAL_OPT] != null) { 281 ParameterInfo astInfo = (ParameterInfo) getElementInfo(); 282 getCollectionDiff(diffList, parser, CHANGED_ANNOTATION, astInfo.annotations, getAnnotations(), parser.getToken(children[FINAL_OPT].getLastToken()).getEndOffset(), " "); } 284 getChildDiff(diffList, parser, children[TYPE], (MetadataElement) getTypeName(), CHANGED_TYPE); 286 if (isChanged(CHANGED_IS_VARARG)) { 287 replaceNode(diffList, parser, children[VARARG_OPT], isVarArg() ? "..." : "", parser.getToken(children[TYPE].getLastToken()).getEndOffset(), ""); } 289 ASTree[] varDeclaratorIdChildren = children[VARIABLE_DECLARATOR_ID].getSubTrees(); 291 if (isChanged(CHANGED_NAME)) { 292 Token identifier = (Token) varDeclaratorIdChildren[0]; int startOffset = identifier.getStartOffset(); 294 int endOffset = identifier.getEndOffset(); 295 diffList.add(new DiffElement(startOffset, endOffset, getName())); 296 } 297 if (isChanged(CHANGED_DIM_COUNT)) { 298 replaceNode(diffList, parser, varDeclaratorIdChildren[1], appendDims(new StringBuffer (), getDimCount()).toString(), getEndOffset(getParser(), varDeclaratorIdChildren[0]), ""); 299 } 300 } 301 302 private static final int FINAL_OPT = 0; 303 private static final int TYPE = 1; 304 private static final int VARARG_OPT = 2; 305 private static final int VARIABLE_DECLARATOR_ID = 3; 306 307 public void replaceChild(Element oldElement, Element newElement) { 308 if (childrenInited) { 309 if (oldElement.equals(typeName)) { 310 setTypeName((TypeReference) newElement); 311 return; 312 } 313 if (replaceObject(annotations, oldElement, newElement)) return; 314 } 315 super.replaceChild(oldElement, newElement); 316 } 317 318 public int getDimCount() { 319 if (isChanged(CHANGED_DIM_COUNT)) { 320 return dimCount; 321 } else { 322 ASTree tree = getASTree(); 323 if (tree != null) { 324 ASTree dims = tree.getSubTrees()[VARIABLE_DECLARATOR_ID].getSubTrees()[1]; 325 if (dims != null) { 326 return (dims.getLastToken() - dims.getFirstToken() + 1) / 2; 327 } 328 } 329 return 0; 330 } 331 } 332 333 public void setDimCount(int dimCount) { 334 objectChanged(CHANGED_DIM_COUNT); 335 this.dimCount = dimCount; 336 if (!internalSetDim) { 337 setTypeRef(typeReferenceToTypeRef(getTypeName(), dimCount)); 339 } 340 } 341 342 public List getChildren() { 343 List list = new ArrayList (1); 344 list.addAll(getAnnotations()); 345 addIfNotNull(list, getTypeName()); 346 return list; 347 } 348 349 protected void initChildren() { 350 childrenInited = false; 351 ParameterInfo info = (ParameterInfo) getElementInfo(); 352 ASTree tree = info.getTypeAST(this); 353 typeName = (TypeReference) initOrCreate(typeName, tree); 354 annotations = createChildrenList(annotations, "annotations", (AttrListWrapper)super_getAnnotations(), ((ParameterInfo) getElementInfo()).annotations, CHANGED_ANNOTATION); 356 childrenInited = true; 357 } 358 359 protected void setData(List annotations, TypeReference typeName, int dimCount) { 360 changeChild(null, typeName); 361 this.typeName = typeName; 362 this.annotations = createChildrenList("annotations", (AttrListWrapper)super_getAnnotations(), annotations, CHANGED_ANNOTATION); this.dimCount = dimCount; 364 setTypeRef(typeReferenceToTypeRef(typeName, dimCount)); 365 childrenInited = true; 366 } 367 368 protected void setTypeRef(TypeRef type) { 369 _getDelegate().setSlot1(type); 370 } 371 372 public TypeRef getTypeRef() { 373 return (TypeRef) _getDelegate().getSlot1(); 374 } 375 376 public boolean isPersisted() { 377 return _getDelegate().getSlot2() != null; 378 } 379 380 public void setPersisted(boolean persisted) { 381 _getDelegate().setSlot2(persisted ? "" : null); 382 } 383 384 void childChanged(MetadataElement mpi) { 385 super.childChanged(mpi); 386 if (childrenInited) { 387 if (mpi == typeName) { 388 setTypeName((TypeReference) mpi); 389 } 390 } 391 } 392 393 public Element duplicate(JavaModelPackage targetExtent) { 394 return targetExtent.getParameter().createParameter( 395 getName(), 396 duplicateList(getAnnotations(), targetExtent), 397 isFinal(), 398 (TypeReference) duplicateElement(getTypeName(), targetExtent), 399 getDimCount(), 400 isVarArg() 401 ); 402 } 403 404 public void fixImports(Element scope, Element original) { 405 Parameter par=(Parameter)original; 406 407 fixImports(scope,getAnnotations(),par.getAnnotations()); 408 setTypeName(JavaModelUtil.resolveImportsForType(scope,par.getType())); 409 setDimCount(0); 410 } 411 412 protected abstract List super_getAnnotations(); 413 414 protected void _delete() { 415 deleteChildren("annotations", (AttrListWrapper) super_getAnnotations()); 418 if (childrenInited) { 419 deleteChild(typeName); 420 } 421 super._delete(); 426 } 427 } 428 | Popular Tags |