1 19 package org.netbeans.modules.javacore.jmiimpl.javamodel; 20 21 import java.util.AbstractSequentialList ; 22 import java.util.ArrayList ; 23 import java.util.Collections ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.ListIterator ; 27 import javax.jmi.reflect.ConstraintViolationException; 28 import org.netbeans.jmi.javamodel.*; 29 import org.netbeans.lib.java.parser.ASTree; 30 import org.netbeans.lib.java.parser.Token; 31 import org.netbeans.mdr.handlers.AttrListWrapper; 32 import org.netbeans.mdr.storagemodel.StorableObject; 33 import org.netbeans.mdr.persistence.StorageException; 34 import org.netbeans.modules.javacore.api.JavaModel; 35 import org.netbeans.modules.javacore.parser.ASTProvider; 36 import org.netbeans.modules.javacore.parser.ClassInfo; 37 import org.netbeans.modules.javacore.parser.ElementInfo; 38 import org.netbeans.modules.javacore.parser.EnumInfo; 39 import org.openide.ErrorManager; 40 41 46 public abstract class JavaEnumImpl extends JavaClassImpl implements JavaEnum { 47 static final ElementInfo DEFAULT_INFO = new EnumInfo(null, EnumInfo.ENUM_TYPE, null, 0, null, null, null, null); 48 49 public static final boolean DEBUG = false; 50 51 public static final String CONSTANTS_ATTR = "constants"; 53 private LightAttrList constants = null; 54 private final MergedFeaturesList features = new MergedFeaturesList(); 55 56 57 public JavaEnumImpl(StorableObject s) { 58 super(s); 59 } 60 61 65 public boolean isInterface() { 66 return false; 67 } 68 69 74 public void setInterface(boolean newValue) { 75 if (newValue) { 76 throw new ConstraintViolationException(null, null, "Cannot set interface modifier to true for enum."); } 78 } 79 80 84 public JavaClass getSuperClass() { 85 checkUpToDate(); 86 JavaClass enumCls = (JavaClass) JavaModel.getDefaultExtent().getType().resolve("java.lang.Enum"); JavaModelPackage extent = (JavaModelPackage)enumCls.refImmediatePackage(); 88 return extent.getParameterizedType().resolveParameterizedType(enumCls, Collections.singletonList(this), null); 89 } 90 91 96 public void setSuperClass(JavaClass newValue) { 97 if (newValue == null || !((ClassInfo) getElementInfo()).superclass.equals(newValue.getName())) { 98 throw new ConstraintViolationException(null, null, "Cannot set superclass of an enumeration type to: " + newValue == null ? null : newValue.getName()); } 100 } 101 102 public List getPersistentConstants() { 103 AttrListWrapper list = (AttrListWrapper) super_getConstants(); 104 list.setAttrName(CONSTANTS_ATTR); 105 return list; 106 } 107 108 private List getNakedConstants() { 109 try { 110 return (List ) ((StorableObject) _getDelegate()).getAttribute(CONSTANTS_ATTR); 111 } catch (StorageException e) { 112 throw (GeneralException) ErrorManager.getDefault().annotate(new RuntimeException (e.getMessage()), e); 113 } 114 } 115 116 public List getConstants() { 117 checkUpToDate(); 118 if (constants == null) { 119 constants = createChildrenList(CONSTANTS_ATTR, (AttrListWrapper) super_getConstants(), null, CHANGED_CONSTANTS); 120 } 121 return constants; 122 } 123 124 public List getFeatures() { 125 return features; 126 } 127 128 protected abstract List super_getConstants(); 129 130 134 protected ElementInfo getDefaultInfo() { 135 return DEFAULT_INFO; 136 } 137 138 protected void matchPersistent(ElementInfo newInfo) { 139 if (!isPersisted()) { 140 persistChildren(getPersistentList(CONSTANTS_ATTR, super_getConstants()), ((EnumInfo) newInfo).constants); 141 } else { 142 processMembers(getConstants(), ((EnumInfo) newInfo).constants); 143 } 144 145 super.matchPersistent(newInfo); 146 } 147 148 public String toString() { 149 return "enum " + getName(); } 151 152 protected List getInitedChildren() { 153 List list = super.getInitedChildren(); 154 if (childrenInited) { 155 list.addAll(getConstants()); 156 } 157 return list; 158 } 159 160 public List getChildren() { 161 List list = new ArrayList (); 162 list.addAll(getAnnotations()); 163 list.addAll(getInterfaceNames()); 164 list.addAll(getConstants()); 165 list.addAll(getContents()); 166 return list; 167 } 168 169 public void fixImports(Element scope, Element original) { 170 JavaEnum jEnum=(JavaEnum)original; 171 172 super.fixImports(scope,original); 173 fixImports(scope,getConstants(),jEnum.getConstants()); 174 } 175 176 187 protected void initChildren() { 188 boolean fail = true; 190 _lock(true); 191 try { 192 childrenInited = false; 193 constants = createChildrenList(constants, CONSTANTS_ATTR, (AttrListWrapper) super_getConstants(), ((EnumInfo) getElementInfo()).constants, CHANGED_CONSTANTS); 194 super.initChildren(); 195 fail = false; 196 } finally { 197 _unlock(fail); 198 } 199 } 200 201 protected void setData(List annotations, String javadocText, JavaDoc javadoc, List constants, List features, List interfaceNames) { 202 this.constants = createChildrenList(CONSTANTS_ATTR, (AttrListWrapper) super_getConstants(), constants, CHANGED_CONSTANTS); 203 super.setData(annotations, javadocText, javadoc, features, null, interfaceNames, null); 204 } 205 206 210 public String getSourceText() { 211 String origElem; 212 if ((origElem = checkChange()) != null) 213 return origElem; 214 StringBuffer buf = new StringBuffer (); 215 buf.append('\n'); 216 generateNewJavaDoc(buf); 217 buf.append(getIndentation()); 218 generateNewModifiers(buf); 219 buf.append("enum "); buf.append(getSimpleName()); 221 generateNewImplements(buf); 222 ClassDefinitionImpl.generateNewFeatures(this, buf, isNew()); 223 return buf.toString(); 224 } 225 226 229 public void getDiff(List diffList) { 230 EnumInfo astInfo = (EnumInfo) getElementInfo(); 231 ASTProvider parser = getParser(); 232 ASTree[] children = getASTree().getSubTrees(); 233 234 replaceJavaDoc(diffList); 236 if (isChanged(CHANGED_MODIFIERS | CHANGED_ANNOTATION)) { 238 diffModifiers(diffList, parser.getToken(children[IDENTIFIER].getFirstToken() - 1), parser); 239 } else if (children[0] != null) { 240 getCollectionDiff(diffList, parser, CHANGED_ANNOTATION, astInfo.annotations, getAnnotations(), parser.getToken(children[0].getLastToken()).getEndOffset(), " "); } 242 if (isChanged(CHANGED_NAME)) { 244 replaceNode(diffList, parser, children[IDENTIFIER], getSimpleName(), 0, null); 245 } 246 int startOffset = parser.getToken(children[IDENTIFIER].getLastToken()).getEndOffset(); 248 String prefix = formatElementPart(IMPLEMENTS_KEYWORD); 249 getCollectionDiff(diffList, parser, CHANGED_IMPLEMENTS, getASTree().getSubTrees()[INTERFACES], 250 getInterfaceNames(), startOffset, formatElementPart(COMMA), prefix); 251 252 int endOffset; 254 int constEndOffset; 255 ASTree body = children[BODY] == null ? null : children[BODY].getSubTrees()[ENUM_BODY_DECLARATIONS]; 256 { 257 constEndOffset = endOffset = getContentsEndOffset(parser, getASTree()); 258 } 259 if (body != null) { 260 Token bodyDecls = parser.getToken(body.getFirstToken()); 261 Token[] pad = bodyDecls.getPadding(); 262 constEndOffset = pad.length > 0 ? pad[0].getStartOffset() : bodyDecls.getStartOffset(); 263 } 264 getCollectionDiff(diffList, parser, CHANGED_CONSTANTS, astInfo.constants, getConstants(), constEndOffset, ", ", false); if (!getContents().isEmpty() && (body == null)) { 266 diffList.add(new DiffElement(constEndOffset, constEndOffset, ";")); } 268 getCollectionDiff(diffList, parser, CHANGED_FEATURES, astInfo.features, getContents(), endOffset, "\n"); } 270 271 protected ASTree getPartTree(ElementPartKind part) { 272 if (ElementPartKindEnum.NAME.equals(part)) { 273 return getASTree().getSubTrees()[IDENTIFIER]; 274 } 275 throw new IllegalArgumentException ("Invalid part for this element: " + part); } 277 278 protected ASTree getPartStartTree(ElementPartKind part) { 279 if (ElementPartKindEnum.HEADER.equals(part)) { 280 return getASTree(); 281 } 282 return super.getPartStartTree(part); 283 } 284 285 protected ASTree getPartEndTree(ElementPartKind part) { 286 if (ElementPartKindEnum.HEADER.equals(part)) { 287 for (int i = 2; true; i--) { 288 ASTree result = getASTree().getSubTrees()[i]; 289 if (result != null) { 290 return result; 291 } 292 } 293 } 294 return super.getPartEndTree(part); 295 } 296 297 private static final int IDENTIFIER = 1; 299 private static final int INTERFACES = 2; 300 private static final int BODY = 3; 301 private static final int ENUM_CONSTANTS = 0; 302 private static final int ENUM_BODY_DECLARATIONS = 1; 303 304 308 public void replaceChild(Element oldElement, Element newElement) { 309 if (isPersisted()) { 310 if (replaceObject(getConstants(), oldElement, newElement)) return; 311 } 312 super.replaceChild(oldElement, newElement); 313 } 314 315 protected void _delete() { 316 deleteChildren(CONSTANTS_ATTR, (AttrListWrapper) super_getConstants()); 318 super._delete(); 319 } 320 321 public MultipartId getSuperClassName() { 322 return null; 323 } 324 325 public void setSuperClassName(MultipartId newValue) { 326 if (newValue != null) { 327 throw new ConstraintViolationException(null, null, "Cannot set superclass name of enum."); } 329 } 330 331 private class MergedFeaturesList extends AbstractSequentialList { 332 private void lock() { 333 lock(false); 334 } 335 336 private void lock(boolean readWrite) { 337 repository().beginTrans(readWrite); 338 } 339 340 private void unlock() { 341 unlock(false); 342 } 343 344 private void unlock(boolean fail) { 345 repository().endTrans(fail); 346 } 347 348 public int size() { 349 lock(); 350 try { 351 return getConstants().size() + JavaEnumImpl.super.getFeatures().size(); 352 } finally { 353 unlock(); 354 } 355 } 356 357 public ListIterator listIterator(int index) { 358 lock(); 359 try { 360 return new It(index); 361 } finally { 362 unlock(); 363 } 364 } 365 366 private class It implements ListIterator { 367 private final ListIterator constantsIterator; 368 private final ListIterator featuresIterator; 369 private ListIterator currIterator; 370 371 It(int index) { 372 List constants = getConstants(); 373 int size = constants.size(); 374 if (index <= size) { 375 constantsIterator = constants.listIterator(index); 376 featuresIterator = JavaEnumImpl.super.getFeatures().listIterator(); 377 currIterator = constantsIterator; 378 } else { 379 constantsIterator = constants.listIterator(size); 380 featuresIterator = JavaEnumImpl.super.getFeatures().listIterator(index - size); 381 currIterator = featuresIterator; 382 } 383 } 384 385 public void add(Object o) { 386 boolean fail = true; 387 lock(true); 388 try { 389 if (o instanceof EnumConstant) { 390 if (featuresIterator.nextIndex() != 0) { 391 throw new IllegalStateException (); 392 } 393 constantsIterator.add(o); 394 currIterator = constantsIterator; 395 } else { 396 if (constantsIterator.nextIndex() != getConstants().size()) { 397 throw new IllegalStateException (); 398 } 399 featuresIterator.add(o); 400 currIterator = featuresIterator; 401 } 402 fail = false; 403 } finally { 404 unlock(fail); 405 } 406 } 407 408 public boolean hasNext() { 409 lock(); 410 try { 411 return constantsIterator.hasNext() || featuresIterator.hasNext(); 412 } finally { 413 unlock(); 414 } 415 } 416 417 public boolean hasPrevious() { 418 lock(); 419 try { 420 return constantsIterator.hasPrevious() || featuresIterator.hasPrevious(); 421 } finally { 422 unlock(); 423 } 424 } 425 426 public Object next() { 427 lock(); 428 try { 429 if (constantsIterator.hasNext()) { 430 currIterator = constantsIterator; 431 return constantsIterator.next(); 432 } 433 currIterator = featuresIterator; 434 return featuresIterator.next(); 435 } finally { 436 unlock(); 437 } 438 } 439 440 public int nextIndex() { 441 lock(); 442 try { 443 return featuresIterator.nextIndex() + constantsIterator.nextIndex(); 444 } finally { 445 unlock(); 446 } 447 } 448 449 public Object previous() { 450 lock(); 451 try { 452 if (featuresIterator.hasPrevious()) { 453 currIterator = featuresIterator; 454 return featuresIterator.previous(); 455 } 456 currIterator = constantsIterator; 457 return constantsIterator.previous(); 458 } finally { 459 unlock(); 460 } 461 } 462 463 public int previousIndex() { 464 lock(); 465 try { 466 return featuresIterator.nextIndex() + constantsIterator.previousIndex(); 467 } finally { 468 unlock(); 469 } 470 } 471 472 public void remove() { 473 boolean fail = true; 474 lock(true); 475 try { 476 currIterator.remove(); 477 fail = false; 478 } finally { 479 unlock(fail); 480 } 481 } 482 483 public void set(Object o) { 484 boolean fail = true; 485 lock(true); 486 try { 487 if (o instanceof EnumConstant) { 488 if (currIterator != constantsIterator) { 489 throw new IllegalStateException (); 490 } 491 } else { 492 if (currIterator == constantsIterator) { 493 throw new IllegalStateException (); 494 } 495 } 496 currIterator.set(o); 497 fail = false; 498 } finally { 499 unlock(fail); 500 } 501 } 502 } 503 } 504 505 public Element duplicate(JavaModelPackage targetExtent) { 506 return targetExtent.getJavaEnum().createJavaEnum( 507 getName(), 508 duplicateList(getAnnotations(), targetExtent), 509 getModifiers(), 510 null, 511 (JavaDoc) duplicateElement(getJavadoc(), targetExtent), 512 duplicateList(getContents(), targetExtent), 513 (MultipartId) duplicateElement(getSuperClassName(), targetExtent), 514 duplicateList(getInterfaceNames(), targetExtent), 515 duplicateList(getTypeParameters(), targetExtent), 516 duplicateList(getConstants(), targetExtent) 517 ); 518 } 519 } 520 | Popular Tags |