001: package Schmortopf.FileStructure.Descriptions;
002:
003: import java.util.*;
004: import java.lang.reflect.Modifier;
005: import Schmortopf.Utility.Vectorizable;
006: import Schmortopf.Utility.StringUtilities;
007: import Shared.Logging.Log;
008:
009: /**
010: * A recursive dataobject.
011: * Used by FileStructureDescription and its children.
012: *
013: * Use the static methods in FileStructureDescriptionFactory
014: * for creating or writing out FileStructureDescriptions.
015: *
016: */
017: public class FileStructureDescription implements Vectorizable {
018:
019: // Note: For preventing the load of such an object with an older
020: // version (different contents in the vector representation)
021: // increment the DataFileVersion number in the class FileStructuresDataFile.
022:
023: public String fileVersionIdentifier = "";
024: // This only is used for toplevel descriptions of projectfiles.
025: // It consists of the file's lastmodified date, length and hashcode.
026:
027: public String absoluteJarFilePath = "";
028: // This only is set for fsd's associated with library files,
029: // which then are part of the jar file with this path.
030: // If belongsToProject() returns false, this attribute contains
031: // the absolute path of the associated jar file, which corresponds to the
032: // first level nodes in the librariestree.
033:
034: // Caution: Update the Vectorizable methods, when this datastructure changes.
035:
036: // This one contains the real filepathname for
037: // projectfiles, and the logical entry name for
038: // library files inside jarfiles
039: public StringBuffer pathNameBuffer = new StringBuffer("");
040:
041: // = package name + . + className
042: public StringBuffer fullyQualifiedClassNameBuffer = new StringBuffer(
043: "");
044:
045: public String extension = ""; // java or class
046:
047: public boolean belongsToProject = false;
048: // This is set for all FSD's, which belong to sourcefiles of the project.
049: // It remains false for all sources or classes of the libraries.
050:
051: public StringWithPosition packageName = new StringWithPosition();
052: public StringWithPosition className = new StringWithPosition();
053: public int modifiers = 0; // coded like in java.lang.reflect.Modifier
054: public boolean isInterface = false;
055: public StringWithPosition[] importStatements = new StringWithPosition[0];
056: // of StringWithPosition, each String contains a fullqualified classname,
057: // or one which ends with a * wildcard sign.
058: // The number contains the number of the line which contains the statement.
059:
060: // If this class extends a superclass, we put the superclass
061: // identifier here : Actually this entry never is empty, because
062: // all non-simple java classes extend the basisclass Object.
063: public StringWithPosition super Class_fullyQualifiedClassName = new StringWithPosition();
064:
065: public Vector constructorDescriptions = new Vector();
066: // of FileStructureDescriptionForConstructor
067: public Vector methodDescriptions = new Vector();
068: // of FileStructureDescriptionForMethod
069:
070: public Vector fieldDescriptions = new Vector();
071: // of FileStructureDescriptionForField
072: // contains member attributes. Scope tests are not needed for these
073: // in the CodeCompletion.
074:
075: public Vector initializerDescriptions = new Vector();
076: // of FileStructureDescriptionForInitializer
077:
078: // transient :
079: public Vector localBlockFieldDescriptions = new Vector();
080: // of FileStructureDescriptionForField
081: // localBlockFieldDescriptions only are filled in for editable
082: // files, when they are set into the editor and parsed by the
083: // FileStructureDescriptionUpdater. They are needed, if the user
084: // later uses the CodeCompletion.
085: // For readonly library files or class files, local attributes
086: // are of no interest.
087: // Set automatically ON DEMAND by the FSDUpdater, when a sourcefile is loaded into the editor.
088:
089: // transient :
090: public Vector localBlockAnonymousClasses = new Vector();
091: // of FileStructureDescription
092: // localBlockAnonymousClasses only are filled in for editable
093: // files, when they are set into the editor and parsed by the
094: // FileStructureDescriptionUpdater. They are needed, if the user
095: // later uses the CodeCompletion.
096: // For readonly library files or class files, localBlockAnonymousClasses
097: // are of no interest.
098: // Set automatically ON DEMAND by the FSDUpdater, when a sourcefile is loaded into the editor.
099:
100: // transient :
101: public FileStructureDescription[] parentDescriptions = new FileStructureDescription[0];
102: // of FileStructureDescription
103: // contains the parent chain, starting with the direct parent
104: // up to the root parent.
105: // Set ON DEMAND ( by FileStructureDescriptionManager.updateTransientFieldsFor() )
106: // Usage: Before you access this attribute, call updateTransientFieldsFor(),
107: // and when youre done with it, call releaseTransientFieldsFor() to save memory.
108:
109: // transient :
110: public Vector inheritedMethodDescriptions = new Vector();
111: // of FileStructureDescriptionForMethod
112: // contains all methods, which are inherited from the parent chain.
113: // Set ON DEMAND ( by FileStructureDescriptionManager.updateTransientFieldsFor() )
114: // Usage: Before you access this attribute, call updateTransientFieldsFor(),
115: // and when youre done with it, call releaseTransientFieldsFor() to save memory.
116: // Visibility : Only public and protected objects are and
117: // package scope objects are added only as long as
118: // the package is not changed while stepping back to the root.
119:
120: // transient
121: public Vector inheritedFieldDescriptions = new Vector();
122: // of FileStructureDescriptionForField
123: // cotains all attributes, which are inherited from the parent chain.
124: // Set ON DEMAND ( by FileStructureDescriptionManager.updateTransientFieldsFor() )
125: // Usage: Before you access this attribute, call updateTransientFieldsFor(),
126: // and when youre done with it, call releaseTransientFieldsFor() to save memory.
127: // Visibility : Only public and protected objects are and
128: // package scope objects are added only as long as
129: // the package is not changed while stepping back to the root.
130:
131: // This flag is set, after the fileStructureDescriptionManager has
132: // updated the transient fields, and it's cleared when the transient
133: // fields have been removed by a call to the fileStructureDescriptionManager's
134: // releaseTransientFields() method.
135: // Note, that the IDE tries to minimize the transient fields kept in memory,
136: // therefore this information is released when not needed.
137: // This keeps memory consumption low.
138: private boolean areTransientFieldsSet = false;
139:
140: // Recursive structures :
141:
142: // Flat :
143: public Vector implementedInterfaces = new Vector();
144: // of StringWithPosition.
145:
146: // Recursive Structure : Inner classes and interfaces:
147: public Vector innerClasses = new Vector();
148: public Vector innerInterfaces = new Vector();
149: // of FileStructureDescription
150:
151: // Scope indices : Important for for inner classes especially, but also
152: // present for toplevel class fsd's.
153: public int scopeStartLine = 0;
154: public int scopeEndLine = 0;
155:
156: // parserOutput Describes the last parser result.
157: // The content is either "ok" or holds an explanation of the (latest) parser error.
158: // It is referenced/written out in the filecomponents tree.
159: // This attribute is NOT saved/loaded.
160: public ParserRunResult parserOutput = new ParserRunResult(-1, -1,
161: true, "ok");
162:
163: // ------------ Attributes, which define the dependencies for compiler tasks -------
164: //
165: // Holds the pathes of all projectfiles, which are referenced in ANY WAY
166: // by the associated file. This includes import-statement-relative or
167: // absolute references (calls) anywhere in the source code, or parent classes,
168: // or implemented interfaces and so on...
169: // SAVED and LOADED.
170: // NOTE: classnames of the parenttree or implemented interface tree are NOT contained here.
171: // These ones are added on demand in fsdManager.getDependentFilePathes.. just
172: // before a compiler run starts. The method uses the transient Vector
173: // temporaryReferencedProjectFiles
174: // defined in this class as temporary working attribute.
175: public Vector referencedProjectFiles = new Vector();
176: //
177: // Flag which tells you, if the dependency results are up to date.
178: // The FSD Updater initially immediately clears this, until the results
179: // are reinserted, because it can happen that it is interrupted without
180: // having finished its work.
181: // It initially MUST be false. It becomes valid either after a successful
182: // vectorization or dependency scan.
183: public boolean referencedProjectFilesAreValid = false;
184: //
185: // The filedependency scan is not perfect:
186: // If the dependencies are too complex, it gives up, and this means, that
187: // this file has to be compiled *ALWAYS*.
188: // The file dependency scan currently gives up, if it encounters
189: // chained references with parameters, like:
190: // a.getB().getC( x ).getD().doSomething().
191: // It will give up, if it detects, that getC() [which belongs to the class
192: // B, which doesn't need to be declared anywhere in the source class, has
193: // a methodparameter, which COULD have an effect on the type of the
194: // returned object [ remember that multiple signatures can exist, which
195: // return different types ].
196: // In this case it sets this flag, which means, that the file associated
197: // with this fsd has to be compiled always:
198: // Default is true, until the dependency scan could resolve all dependencies.
199: public boolean hasToBeCompiledAlways = true;
200: //
201: // This static number is used to cancel all vectorized contents and
202: // hence forcing the IDE to recalculate all referencedProjectFiles entries.
203: // If this number is incremented, the reference info of this fsd will be
204: // recalculated by the fsdmanager when the project is loaded.
205: public static final int ReferencedProjectFilesVersion = 10;
206:
207: // The full dependencies of the projectFSDs are given by
208: // the projectFSD.referencedProjectFiles *AND* the trees of its
209: // parentclasses and implemented interfaces (which again can have parents)
210: // Caching the two trees would require complicated update strategies
211: // and introduce dependencies of the dependencies. Therefore we use
212: // a temporary Vector in the FSD, which is built and cleared on
213: // demand by FileStructureDescriptionManager.getDependentFilePathesOf(),
214: // which is called before the compiler is started.
215: public Vector temporaryReferencedProjectFiles = new Vector();
216:
217: /**
218: * Implementation of the Vectorizable interface.
219: * Returns the VectorRepresentation of the object's datacontent
220: */
221: public Vector getVectorRepresentation() throws Exception {
222: final Vector rep = new Vector();
223: rep.addElement(this .pathNameBuffer.toString());
224: rep.addElement(this .fileVersionIdentifier);
225: rep.addElement(this .absoluteJarFilePath);
226: rep.addElement(this .fullyQualifiedClassNameBuffer.toString());
227: rep.addElement(this .extension);
228: rep.addElement(this .packageName.getVectorRepresentation());
229: rep.addElement(this .className.getVectorRepresentation());
230: rep.addElement(new Integer(this .modifiers));
231: rep.addElement(new Boolean(this .isInterface));
232: rep.addElement(new Boolean(this .belongsToProject));
233:
234: rep.addElement(new Integer(this .importStatements.length));
235: for (int i = 0; i < this .importStatements.length; i++) {
236: final StringWithPosition this ImportStatement = this .importStatements[i];
237: rep.addElement(this ImportStatement
238: .getVectorRepresentation());
239: }
240:
241: rep.addElement(this .super Class_fullyQualifiedClassName
242: .getVectorRepresentation());
243:
244: rep
245: .addElement(new Integer(this .constructorDescriptions
246: .size()));
247: for (int i = 0; i < this .constructorDescriptions.size(); i++) {
248: final FileStructureDescriptionForConstructor this ConstructorDescription = (FileStructureDescriptionForConstructor) this .constructorDescriptions
249: .elementAt(i);
250: rep.addElement(this ConstructorDescription
251: .getVectorRepresentation());
252: }
253:
254: rep.addElement(new Integer(this .methodDescriptions.size()));
255: for (int i = 0; i < this .methodDescriptions.size(); i++) {
256: final FileStructureDescriptionForMethod this MethodDescription = (FileStructureDescriptionForMethod) this .methodDescriptions
257: .elementAt(i);
258: rep.addElement(this MethodDescription
259: .getVectorRepresentation());
260: }
261:
262: rep.addElement(new Integer(this .fieldDescriptions.size()));
263: for (int i = 0; i < this .fieldDescriptions.size(); i++) {
264: final FileStructureDescriptionForField this FieldDescription = (FileStructureDescriptionForField) this .fieldDescriptions
265: .elementAt(i);
266: rep.addElement(this FieldDescription
267: .getVectorRepresentation());
268: }
269:
270: rep.addElement(new Integer(this .implementedInterfaces.size()));
271: for (int i = 0; i < this .implementedInterfaces.size(); i++) {
272: final StringWithPosition this ImplementedInterface = (StringWithPosition) this .implementedInterfaces
273: .elementAt(i);
274: rep.addElement(this ImplementedInterface
275: .getVectorRepresentation());
276: }
277:
278: rep.addElement(new Integer(this .innerClasses.size()));
279: for (int i = 0; i < this .innerClasses.size(); i++) {
280: final FileStructureDescription this InternalClass = (FileStructureDescription) this .innerClasses
281: .elementAt(i);
282: rep.addElement(this InternalClass.getVectorRepresentation());
283: }
284:
285: rep.addElement(new Integer(this .scopeStartLine));
286: rep.addElement(new Integer(this .scopeEndLine));
287:
288: // NEW: Add the innerInterfaces ( was forgotten in previous versions )
289: rep.addElement(new Integer(this .innerInterfaces.size()));
290: for (int i = 0; i < this .innerInterfaces.size(); i++) {
291: final FileStructureDescription this InternalInterface = (FileStructureDescription) this .innerInterfaces
292: .elementAt(i);
293: rep.addElement(this InternalInterface
294: .getVectorRepresentation());
295: }
296:
297: // NEW: Add the referencedProjectFiles attributes:
298: rep.addElement(new Integer(ReferencedProjectFilesVersion));
299: rep
300: .addElement(new Boolean(
301: this .referencedProjectFilesAreValid));
302: rep.addElement(this .referencedProjectFiles);
303: rep.addElement(new Boolean(this .hasToBeCompiledAlways));
304:
305: return rep;
306: } // getVectorRepresentation
307:
308: /**
309: * Implementation of the Vectorizable interface.
310: * Sets the object's content to the passed vectorRepresentation.
311: */
312: public void createFromVectorRepresentation(final Vector rep) {
313: int repCounter = 0;
314: this .pathNameBuffer.setLength(0);
315: this .pathNameBuffer
316: .append((String) rep.elementAt(repCounter++));
317:
318: this .fileVersionIdentifier = (String) rep
319: .elementAt(repCounter++);
320: this .absoluteJarFilePath = (String) rep.elementAt(repCounter++);
321:
322: this .fullyQualifiedClassNameBuffer.setLength(0);
323: this .fullyQualifiedClassNameBuffer.append((String) rep
324: .elementAt(repCounter++));
325:
326: this .extension = (String) rep.elementAt(repCounter++);
327:
328: this .packageName = new StringWithPosition();
329: final Vector packageNameRep = (Vector) rep
330: .elementAt(repCounter++);
331: this .packageName.createFromVectorRepresentation(packageNameRep);
332: packageNameRep.removeAllElements(); // assist GC
333:
334: this .className = new StringWithPosition();
335: final Vector classNameRep = (Vector) rep
336: .elementAt(repCounter++);
337: this .className.createFromVectorRepresentation(classNameRep);
338: classNameRep.removeAllElements(); // assist GC
339:
340: this .modifiers = ((Integer) rep.elementAt(repCounter++))
341: .intValue();
342: this .isInterface = ((Boolean) rep.elementAt(repCounter++))
343: .booleanValue();
344: this .belongsToProject = ((Boolean) rep.elementAt(repCounter++))
345: .booleanValue();
346:
347: final int importStatementsNumber = ((Integer) rep
348: .elementAt(repCounter++)).intValue();
349: this .importStatements = new StringWithPosition[importStatementsNumber];
350: for (int i = 0; i < importStatementsNumber; i++) {
351: final Vector importStatementRep = (Vector) rep
352: .elementAt(repCounter++);
353: final StringWithPosition this ImportStatement = new StringWithPosition();
354: this ImportStatement
355: .createFromVectorRepresentation(importStatementRep);
356: importStatementRep.removeAllElements(); // assist GC
357: this .importStatements[i] = this ImportStatement;
358: }
359:
360: this .super Class_fullyQualifiedClassName = new StringWithPosition();
361: final Vector super ClassRep = (Vector) rep
362: .elementAt(repCounter++);
363: this .super Class_fullyQualifiedClassName
364: .createFromVectorRepresentation(super ClassRep);
365: super ClassRep.removeAllElements(); // assist GC
366:
367: this .constructorDescriptions.setSize(0);
368: final int constructorDescriptionsNumber = ((Integer) rep
369: .elementAt(repCounter++)).intValue();
370: for (int i = 0; i < constructorDescriptionsNumber; i++) {
371: final Vector constructorDescriptionRep = (Vector) rep
372: .elementAt(repCounter++);
373: final FileStructureDescriptionForConstructor this ConstructorDescription = new FileStructureDescriptionForConstructor();
374: this ConstructorDescription
375: .createFromVectorRepresentation(constructorDescriptionRep);
376: constructorDescriptionRep.removeAllElements(); // assist GC
377: this .constructorDescriptions
378: .addElement(this ConstructorDescription);
379: }
380:
381: this .methodDescriptions.setSize(0);
382: final int methodDescriptionsNumber = ((Integer) rep
383: .elementAt(repCounter++)).intValue();
384: for (int i = 0; i < methodDescriptionsNumber; i++) {
385: final Vector methodDescriptionsRep = (Vector) rep
386: .elementAt(repCounter++);
387: final FileStructureDescriptionForMethod this MethodDescription = new FileStructureDescriptionForMethod();
388: this MethodDescription
389: .createFromVectorRepresentation(methodDescriptionsRep);
390: methodDescriptionsRep.removeAllElements(); // assist GC
391: this .methodDescriptions.addElement(this MethodDescription);
392: }
393:
394: this .fieldDescriptions.setSize(0);
395: final int fieldDescriptionsNumber = ((Integer) rep
396: .elementAt(repCounter++)).intValue();
397: for (int i = 0; i < fieldDescriptionsNumber; i++) {
398: final Vector fieldDescriptionsRep = (Vector) rep
399: .elementAt(repCounter++);
400: final FileStructureDescriptionForField this FieldDescription = new FileStructureDescriptionForField();
401: this FieldDescription
402: .createFromVectorRepresentation(fieldDescriptionsRep);
403: fieldDescriptionsRep.removeAllElements(); // assist GC
404: this .fieldDescriptions.addElement(this FieldDescription);
405: }
406:
407: this .implementedInterfaces.setSize(0);
408: final int implementedInterfacesNumber = ((Integer) rep
409: .elementAt(repCounter++)).intValue();
410: for (int i = 0; i < implementedInterfacesNumber; i++) {
411: final Vector implementedInterfacesRep = (Vector) rep
412: .elementAt(repCounter++);
413: final StringWithPosition this ImplementedInterface = new StringWithPosition();
414: this ImplementedInterface
415: .createFromVectorRepresentation(implementedInterfacesRep);
416: implementedInterfacesRep.removeAllElements(); // assist GC
417: this .implementedInterfaces
418: .addElement(this ImplementedInterface);
419: }
420:
421: this .innerClasses.setSize(0);
422: final int internalClassesNumber = ((Integer) rep
423: .elementAt(repCounter++)).intValue();
424: for (int i = 0; i < internalClassesNumber; i++) {
425: final Vector internalClassRep = (Vector) rep
426: .elementAt(repCounter++);
427: final FileStructureDescription this InternalClass = new FileStructureDescription();
428: this InternalClass
429: .createFromVectorRepresentation(internalClassRep);
430: internalClassRep.removeAllElements(); // assist GC
431: this .innerClasses.addElement(this InternalClass);
432: }
433:
434: this .scopeStartLine = ((Integer) rep.elementAt(repCounter++))
435: .intValue();
436: this .scopeEndLine = ((Integer) rep.elementAt(repCounter++))
437: .intValue();
438:
439: this .innerInterfaces.setSize(0);
440: final int internalInterfaceNumber = ((Integer) rep
441: .elementAt(repCounter++)).intValue();
442: for (int i = 0; i < internalInterfaceNumber; i++) {
443: final Vector internalInterfaceRep = (Vector) rep
444: .elementAt(repCounter++);
445: final FileStructureDescription this InternalInterface = new FileStructureDescription();
446: this InternalInterface
447: .createFromVectorRepresentation(internalInterfaceRep);
448: internalInterfaceRep.removeAllElements(); // assist GC
449: this .innerInterfaces.addElement(this InternalInterface);
450: }
451:
452: int storedRefVersion = ((Integer) rep.elementAt(repCounter++))
453: .intValue();
454: // Skip the contents if the version is outofdate:
455: if (storedRefVersion == ReferencedProjectFilesVersion) {
456: this .referencedProjectFilesAreValid = ((Boolean) rep
457: .elementAt(repCounter++)).booleanValue();
458: // Caution: We [possibly] remove all elements of the rep in all levels later recursively, therefore
459: // we can't just take the vector reference for the referencedProjectFiles vector,
460: // but must deepcopy all elements, which is no problem here, cause we just have strings:
461: Vector repVector = (Vector) rep.elementAt(repCounter++);
462: this .referencedProjectFiles = new Vector();
463: for (int rIndex = 0; rIndex < repVector.size(); rIndex++) {
464: // String typecast for security, WANT to see a classcast exception on error case
465: this .referencedProjectFiles
466: .addElement((String) repVector
467: .elementAt(rIndex));
468: }
469: this .hasToBeCompiledAlways = ((Boolean) rep
470: .elementAt(repCounter++)).booleanValue();
471: } else {
472: // Outdated version -> clear flags, so the fsdmanager will recalculate it:
473: this .referencedProjectFilesAreValid = false;
474: this .referencedProjectFiles.setSize(0);
475: this .hasToBeCompiledAlways = true;
476: }
477:
478: // GC help: Release ANY connections in the representation vector:
479: this .freeVector(rep);
480:
481: } // createFromVectorRepresentation
482:
483: /**
484: * Recursive method, which removes any vector's in the passed vector.
485: */
486: private void freeVector(Vector v) {
487: Vector vHelp = null;
488: if (v != null) {
489: for (int i = 0; i < v.size(); i++) {
490: if (v.elementAt(i) instanceof Vector) {
491: vHelp = (Vector) v.elementAt(i);
492: this .freeVector(vHelp);
493: }
494: }
495: v.removeAllElements();
496: }
497: vHelp = null;
498: }
499:
500: public boolean isPublic() {
501: return this .isModifierKey("public");
502: }
503:
504: public boolean isPrivate() {
505: return this .isModifierKey("private");
506: }
507:
508: public boolean isProtected() {
509: return this .isModifierKey("protected");
510: }
511:
512: public boolean isPackageScope() {
513: return (!this .isPrivate() && !this .isPublic() && !this
514: .isProtected());
515: }
516:
517: public boolean isStatic() {
518: return this .isModifierKey("static");
519: }
520:
521: private boolean isModifierKey(final String searchKey) {
522: boolean keyFound = false;
523: String[] tokens = StringUtilities.SplitString(Modifier
524: .toString(this .modifiers), " ");
525: for (int i = 0; i < tokens.length; i++) {
526: if (tokens[i].equals(searchKey)) {
527: keyFound = true;
528: break;
529: }
530: }
531: return keyFound;
532: } // isModifierKey
533:
534: /**
535: * Returns true, if the class associated with this fsd contains
536: * a member attribute of the given name.
537: * It will return false also if an fsd in the parentchain does contain
538: * it. -> False for inherited attributes - they must be toplevel.
539: */
540: public boolean containsTopLevelMemberAttributeWithName(
541: String attributeName) {
542: boolean found = false;
543: FileStructureDescriptionForField fieldFSD;
544: for (int i = 0; i < this .fieldDescriptions.size(); i++) {
545: fieldFSD = (FileStructureDescriptionForField) this .fieldDescriptions
546: .elementAt(i);
547: if (fieldFSD.objectNameWithPosition.content
548: .equals(attributeName)) {
549: found = true;
550: break;
551: }
552: }
553: return found;
554: }
555:
556: /**
557: * Returns true, if the class associated with this fsd contains
558: * a method with the passed signature.
559: * It will return false also if an fsd in the parentchain does contain
560: * it. -> False for inherited attributes - they must be toplevel.
561: */
562: public boolean containsTopLevelMethodWithSignature(
563: String searchedSignature) {
564: boolean found = false;
565: FileStructureDescriptionForMethod methodFSD;
566:
567: //ystem.out.println("containsTopLevelMethodWithSignature for " +
568: // this.fullyQualifiedClassName +
569: // " #methods = " + this.methodDescriptions.size() );
570:
571: for (int i = 0; i < this .methodDescriptions.size(); i++) {
572: methodFSD = (FileStructureDescriptionForMethod) this .methodDescriptions
573: .elementAt(i);
574: if (methodFSD.signature.equals(searchedSignature)) {
575: found = true;
576: break;
577: }
578: }
579: return found;
580: }
581:
582: /**
583: * Called by the FileStructureDescriptionManager after it has
584: * updated or released the transient fields.
585: */
586: public void setTransientFieldsSet(final boolean state) {
587: this .areTransientFieldsSet = state;
588:
589: //ystem.out.println("----FSD---- transient fields state for " +
590: // this.className.content + " set to " + state );
591: }
592:
593: /**
594: * This can be used to see, if the transient fields are set or not.
595: * Transient fields can be set by the FileStructureDescriptionManager,
596: * but they only should be set as long as they are needed.
597: * Otherwise you create an IDE with inbuilt memory explosion.
598: */
599: public boolean getAreTransientFieldsSet() {
600: return this .areTransientFieldsSet;
601: }
602:
603: /**
604: * Used when updating an existent fsd.
605: * All vector fields must be cleared here.
606: * The FSD updater just adds new attributes on the existing fields.
607: */
608: public void clear_Attributes() {
609: //Debug trace output:
610: //ystem.out.println("clear_Attributes() called for " + this.fullyQualifiedClassNameBuffer.toString() );
611:
612: this .fullyQualifiedClassNameBuffer.setLength(0);
613:
614: this .importStatements = new StringWithPosition[0];
615: this .super Class_fullyQualifiedClassName = new StringWithPosition();
616:
617: for (int i = 0; i < this .constructorDescriptions.size(); i++) {
618: final FileStructureDescriptionForConstructor cfsd = (FileStructureDescriptionForConstructor) this .constructorDescriptions
619: .elementAt(i);
620: cfsd.clearAttributes();
621: }
622: this .constructorDescriptions.setSize(0);
623:
624: for (int i = 0; i < this .methodDescriptions.size(); i++) {
625: final FileStructureDescriptionForMethod mfsd = (FileStructureDescriptionForMethod) this .methodDescriptions
626: .elementAt(i);
627: mfsd.clearAttributes();
628: }
629: this .methodDescriptions.setSize(0);
630:
631: for (int i = 0; i < this .fieldDescriptions.size(); i++) {
632: final FileStructureDescriptionForField ffsd = (FileStructureDescriptionForField) this .fieldDescriptions
633: .elementAt(i);
634: ffsd.clearAttributes();
635: }
636: this .fieldDescriptions.setSize(0);
637:
638: for (int i = 0; i < this .localBlockFieldDescriptions.size(); i++) {
639: final FileStructureDescriptionForField ffsd = (FileStructureDescriptionForField) this .localBlockFieldDescriptions
640: .elementAt(i);
641: ffsd.clearAttributes();
642: }
643: this .localBlockFieldDescriptions.setSize(0);
644:
645: for (int i = 0; i < this .localBlockAnonymousClasses.size(); i++) {
646: final FileStructureDescription lffsd = (FileStructureDescription) this .localBlockAnonymousClasses
647: .elementAt(i);
648: lffsd.clear_Attributes();
649: }
650: this .localBlockAnonymousClasses.setSize(0);
651:
652: for (int i = 0; i < this .parentDescriptions.length; i++) {
653: this .parentDescriptions[i].clear_Attributes();
654: }
655: this .parentDescriptions = new FileStructureDescription[0];
656:
657: for (int i = 0; i < this .inheritedMethodDescriptions.size(); i++) {
658: final FileStructureDescriptionForMethod mfsd = (FileStructureDescriptionForMethod) this .inheritedMethodDescriptions
659: .elementAt(i);
660: mfsd.clearAttributes();
661: }
662: this .inheritedMethodDescriptions.setSize(0);
663:
664: for (int i = 0; i < this .inheritedFieldDescriptions.size(); i++) {
665: final FileStructureDescriptionForField ffsd = (FileStructureDescriptionForField) this .inheritedFieldDescriptions
666: .elementAt(i);
667: ffsd.clearAttributes();
668: }
669: this .inheritedFieldDescriptions.setSize(0);
670:
671: for (int i = 0; i < this .implementedInterfaces.size(); i++) {
672: final StringWithPosition iface = (StringWithPosition) this .implementedInterfaces
673: .elementAt(i);
674: iface.content = "";
675: }
676: this .implementedInterfaces.setSize(0);
677:
678: for (int i = 0; i < this .innerClasses.size(); i++) {
679: final FileStructureDescription icfsd = (FileStructureDescription) this .innerClasses
680: .elementAt(i);
681: icfsd.clear_Attributes();
682: }
683: this .innerClasses.setSize(0);
684:
685: for (int i = 0; i < this .innerInterfaces.size(); i++) {
686: final FileStructureDescription iffsd = (FileStructureDescription) this .innerInterfaces
687: .elementAt(i);
688: iffsd.clear_Attributes();
689: }
690: this .innerInterfaces.setSize(0);
691:
692: } // clearAttributes
693:
694: /**
695: * This should be called after a creation or an update
696: * and causes this object to sort all elements,
697: * so that the display in the tree's and CodeCompletion
698: * then automatically is sorted too.
699: *
700: * It's called from FileStructureDescriptionParserTreePostProcessor
701: * in the method postProcessParserTree().
702: */
703: public void sortEntriesAlphabetically() {
704: // We only do have to sort the non-transient fields,
705: // because the transient fields used by the CodeCompletion
706: // anyway are all merged (methods and attributes) and therefore
707: // need to be sorted by the CodeCompletion in each case.
708: FSDComparator comparator = new FSDComparator();
709: // Caution : All below passed Vectors must consist of elements,
710: // which implement StringComparable, otherwise
711: // the comparator will throw an exception and fail.
712: Collections.sort(this .constructorDescriptions, comparator);
713: Collections.sort(this .methodDescriptions, comparator);
714: Collections.sort(this .fieldDescriptions, comparator);
715: Collections.sort(this .implementedInterfaces, comparator);
716: comparator = null; // gc friendly
717: } // sortEntriesAlphabetically
718:
719: public class FSDComparator implements Comparator {
720:
721: public int compare(Object o1, Object o2)
722:
723: {
724: int diff = 0;
725: try {
726: final StringComparable e1 = (StringComparable) o1;
727: final StringComparable e2 = (StringComparable) o2;
728: diff = e1.getComparatorString().compareToIgnoreCase(
729: e2.getComparatorString());
730: } catch (Exception eee) {
731: Log.Error(eee);
732: }
733: return diff;
734: }
735: } // EntriesComparator
736:
737: } // FileStructureDescription
|