001: package tide.sources;
002:
003: import tide.editor.MainEditorFrame;
004: import snow.utils.gui.EnumUtils;
005: import snow.utils.storage.*;
006: import tide.syntaxtree.*;
007: import snow.utils.StringUtils;
008: import javax.swing.tree.*;
009: import javax.swing.undo.*;
010: import java.io.*;
011: import java.util.*;
012:
013: /** Represents a single .java File or a directory (package).
014: * Temporary stores the edited content before saving it ( temporaryEditedContent!=null)
015: * Also contain a reference on the generated class (?? classeS ??)
016: * Order: save changed files, and then look for the ones that must be compiled
017: */
018: public class SourceFile extends DefaultMutableTreeNode implements
019: FileItem {
020: // null for nodes (=directories, packages), java file ref for leafs
021: public File javaFile; // c:/temp/snow/util/hello.java
022: // on demand, through lookForAssociatedClassFiles since [Aug2006]
023: //private final List<File> classFiles = new ArrayList<File>(); // c:/temp/snow/util/hello.class hello$2.class
024: public String name; // hello.java or the folder name
025: private File classesRoot;
026: final private String packageName;
027: // this is unique and always non null.
028: private String javaName; // snow.util.Hello (= the package name for folders)
029:
030: public String javaPartName; // hello or package-info
031:
032: // when being edited, but not yet stored
033: private boolean isBeingEdited = false;
034:
035: private final boolean isJavaSourceFile;
036: public final boolean isDirectory;
037:
038: // updated when compiled, used to detect changes
039: private long lastModifiedJavaFile = -1;
040: // Is the date read when this was restored from vector rep, used to create human readable changes logs
041: private long lastStoredLastModifiedJavaFile = -1;
042:
043: private long lastModifiedClassFile = -1; // TODO: several class files.
044:
045: // dependencies (not ordered)
046: public final SourceFileDependencies sourceFileDependencies = new SourceFileDependencies(
047: this );
048:
049: // always associated with lastModifiedDate
050: private boolean isCompiled = false;
051:
052: // may change during life of the object, for example when isEditable() called
053: public SourcesTreeIcon.IconColor iconColor = SourcesTreeIcon.IconColor.Red;
054: private SourcesTreeIcon.Ignored ignoredType = SourcesTreeIcon.Ignored.No;
055:
056: public UndoManager undoManager; // set during edition to keep undo feature when switching between sources to edit
057:
058: // can be turned on/off globally
059: private List<ResourceFile> resourcesFiles = new ArrayList<ResourceFile>();
060:
061: // set by the parser OR the textual detector
062: //public boolean hasStaticVoidMainMethod = false; => now in the dependencies member
063: // not stored, set at load/reload
064: public boolean isProjectMainClass = false;
065:
066: // used for some detections...
067: public boolean visited = false;
068:
069: public enum Kind {
070: Class, Annotation, Interface, Unknown
071: }
072:
073: public Kind topKind = Kind.Unknown;
074:
075: // as long as not stored on file, the modified (edited) content is stored here.
076: private String temporaryEditedContent = null;
077: private int caretLinePosition = 0, caretColumnPosition = 0;
078: private long timeOfLastGetContent = -1; // [Feb2008]: mechanism to detect changes from outside.
079:
080: /** This is also the java part name, used for node sorting.
081: */
082: public String getNodeNameToDisplayInTree() {
083: return getJavaPartName();
084: }
085:
086: public SourceFile getChildFileAt(int i) {
087: return (SourceFile) this .getChildAt(i);
088: }
089:
090: public boolean hasPackageDirectJavaChilds() {
091: if (this .isJavaFile())
092: return false;
093: for (int i = 0; i < this .getChildCount(); i++) {
094: if (this .getChildFileAt(i).isJavaFile())
095: return true;
096: }
097: return false;
098: }
099:
100: /** Adds a resource associated to a folder text, pics, ...
101: */
102: public void addResourceFile(ResourceFile rf) {
103: if (this .isSourceFile()) {
104: System.out
105: .println("ERROR, attempt to adding a resource to a file.");
106: }
107: this .resourcesFiles.add(rf);
108: }
109:
110: public List<ResourceFile> getResourceFiles() {
111: return resourcesFiles;
112: }
113:
114: private boolean showResources = false;
115:
116: /** Files and packages, but without the resources.
117: */
118: public int getJavaChildsCount() {
119: if (showResources == false)
120: return this .getChildCount();
121: return this .getChildCount() - resourcesFiles.size();
122: }
123:
124: /** Not really used, only for debug */
125: @Override
126: public String toString() {
127: return "" + javaName;
128: } // [Oct2007] changed from name to javaName [Nov2007] removed the "SourceFile " prefix
129:
130: /** Hello.java. ONLY USED IN VIEW (?)
131: */
132: public String getName() {
133: return name;
134: }
135:
136: /** Also the java part name or simple name, used for node sorting.
137: */
138: public String getJavaPartName() {
139: if (isJavaSourceFile)
140: return name.substring(0, name.length() - 5);
141: return name;
142: }
143:
144: /** According to folder and file names (ATTENTION !)
145: private classes may have other names !!! (IGNORED HERE)
146: @return the javaname for source files or packages (".") separated
147: */
148: public String getJavaName() {
149: return javaName;
150: }
151:
152: public String getPackageName() {
153: return packageName;
154: }
155:
156: public boolean isJavaFile() {
157: //if(javaFile==null) return false; // may have been deleted...
158: return this .isJavaSourceFile;
159: }
160:
161: public boolean isDirectory() {
162: return !this .isJavaSourceFile;
163: }
164:
165: public boolean isSourceFile() {
166: return this .isJavaSourceFile;
167: }
168:
169: public boolean hasTextRepresentation() {
170: return isJavaSourceFile;
171: }
172:
173: /** Decision based on ignoredType
174: * directories may be partially ignored, if they contain both ignored and not ignored childs
175: */
176: public boolean isIgnored() {
177: return ignoredType == SourcesTreeIcon.Ignored.Yes;
178: }
179:
180: public void setIgnoredType(SourcesTreeIcon.Ignored a) {
181: this .ignoredType = a;
182: // [Jan2007]
183: if (this .isJavaFile()) {
184: if (isIgnored()) {
185: sourceFileDependencies.fileHasBeenDeletedOrIsIgnored();
186: } else {
187: // Restored => no more up to date ! [Feb2007]
188: sourceFileDependencies.reset_();
189: }
190: }
191: }
192:
193: public SourcesTreeIcon.Ignored getIgnoredType() {
194: return this .ignoredType;
195: }
196:
197: /** Looks on disk if the file can be written.
198: */
199: public boolean isEditable() {
200: if (this .javaFile == null)
201: return false;
202: if (!this .isJavaSourceFile)
203: return false;
204: if (this .isDirectory)
205: return false; // not editable
206:
207: if (javaFile.canWrite()) {
208: if (iconColor == SourcesTreeIcon.IconColor.Red) {
209: iconColor = SourcesTreeIcon.IconColor.Green;
210: }
211: return true;
212: } else {
213: if (iconColor == SourcesTreeIcon.IconColor.Green) {
214: iconColor = SourcesTreeIcon.IconColor.Red;
215: }
216: return false;
217: }
218: }
219:
220: public boolean isCompiled() {
221: return isCompiled;
222: }
223:
224: /** Called for folders based on child states.
225: * Called for childs based on the compiler success.
226: * Called at startup
227: * and when the file has been edited and stored (sets comp to false).
228: */
229: public void setIsCompiled(boolean is) {
230: isCompiled = is;
231: // store the actual date
232: if (javaFile != null) {
233: lastModifiedJavaFile = javaFile.lastModified();
234: }
235: }
236:
237: public void setBeingEdited(boolean is) {
238: isBeingEdited = is;
239: }
240:
241: public boolean isBeingEdited() {
242: return isBeingEdited;
243: }
244:
245: SourceFile(File file, String name, String javaName,
246: String packageName) {
247: super (name);
248:
249: if (name.length() == 0)
250: new Throwable("zero length file !").printStackTrace();
251:
252: this .javaFile = file;
253: this .name = name; // Hello.java
254: this .javaName = javaName;
255:
256: this .packageName = packageName;
257: // NO, not now lastModifiedJavaFile = javaFile.lastModified();
258: // is set when known storage, to be consisent with isCompiled !
259:
260: isJavaSourceFile = javaFile.getName().toLowerCase().endsWith(
261: ".java");
262: if (isJavaSourceFile) {
263: javaPartName = javaFile.getName().substring(0,
264: file.getName().length() - 5);
265: } else {
266: javaPartName = name;
267: }
268:
269: isDirectory = file.isDirectory();
270: if (isDirectory) {
271: // the icon type is set later,
272: new Throwable("dir").printStackTrace();
273: } else {
274: if (file.canWrite()) {
275: iconColor = SourcesTreeIcon.IconColor.Green;
276: } else {
277: iconColor = SourcesTreeIcon.IconColor.Red;
278: }
279: }
280: } // Constructor
281:
282: /** used for intermediate directories and the root (absolutePackageName="")
283: * name = java9 absolutePackageName = hello.my.java9
284: */
285: SourceFile(String name, String absolutePackageName) {
286: super (name);
287:
288: if (name.length() == 0 && absolutePackageName.length() > 0) {
289: new Throwable("zero length file (" + absolutePackageName
290: + ")").printStackTrace();
291: }
292:
293: this .javaFile = null;
294: this .name = name;
295: this .javaName = absolutePackageName;
296: this .packageName = absolutePackageName;
297: javaPartName = name;
298:
299: isJavaSourceFile = false;
300: isDirectory = true;
301:
302: // iconColor must be set recursively in the sources model...
303: iconColor = SourcesTreeIcon.IconColor.Green;
304: }
305:
306: /** @return the lastModified field of the file or directory. SLOW. Direct call to file's lastModified routine, NOT cached.
307: */
308: public long getLastModified() {
309: return getFileOrDirectory().lastModified();
310: }
311:
312: /** Is the date read when this was restored from vector rep.
313: * Used to create human readable changes logs
314: */
315: public final long getLastStoredLastModifiedJavaFile() {
316: return lastStoredLastModifiedJavaFile;
317: }
318:
319: public long getFileSize() {
320: return getFileOrDirectory().length();
321: }
322:
323: /** For java sources files, this method simply return the javaFile
324: * for directories, the directory is returned, constructed from tree names.
325: * CAUTION: javaNama.replace('.', '/') is not robust, because the directory names
326: * may contain "." (not valid for packages, but maybe for resources, also managed in the sources model)
327: */
328: public File getFileOrDirectory() {
329: if (javaFile != null)
330: return javaFile;
331: List<String> names = new ArrayList<String>();
332: SourceFile sf = this ;
333: while (!sf.isRoot()) {
334: names.add(0, sf.getName());
335: sf = (SourceFile) sf.getParent();
336: }
337:
338: // sf is the root
339: File f = new File(sf.getName());
340: for (String fn : names) {
341: f = new File(f, fn);
342: }
343:
344: return f;
345: }
346:
347: /** This will set or update the classFile reference (or package directory)
348: * look for all classes starting with this name.class ore name$
349: *
350: * PROBLEM : classes that are not public are not constraint to carry the name of the java file !!!
351: * TODO recognize in the source files (parse or maybe a simple regex search) the class names (several possible !!)
352: */
353: public void setClassRoot(File classesRoot) {
354: /* classFiles.clear();
355: classFiles.addAll( SourceFileUtils.getClassFilesFor(this, classesRoot) ); // SLOW !!
356: if(classFiles.isEmpty())
357: {
358: // ???
359: }*/
360: this .classesRoot = classesRoot;
361: }
362:
363: /** Used in JLint classes analysis tool...
364: * Classes are also removed when deleting a source file.
365: */
366: public List<File> lookForAssociatedClassFiles() {
367: if (classesRoot == null)
368: return null; // should not occur !!
369: return SourceFileUtils.getClassFilesFor(this , classesRoot);
370: }
371:
372: /** Look if the date on disk has changed, if true, directly sets state to "not compiled".
373: * Automatically called at recreation and scan for external changes functions (manual sync, SVN, ...).
374: * CALL ONLY ONCE, AFTER FIRST CALL, SETS THE lastModifiedJavaFile to the actual date and compiled to false.
375: */
376: public boolean lookIfJavaFileChangedAndTreat() {
377: if (javaFile == null)
378: return false;
379: if (lastModifiedJavaFile != javaFile.lastModified()) {
380: this .setIsCompiled(false); // this also sets the actual file date in lastModifiedJavaFile!
381: return true;
382: }
383: return false;
384: }
385:
386: /*
387: public boolean lookIfJavaFileChanged()
388: {
389: if(javaFile==null) return false;
390: if(lastModifiedJavaFile != javaFile.lastModified())
391: {
392: return true;
393: }
394: return false;
395: }*/
396:
397: /** Data may be lost if not saved previously !
398: * used to enforce reload from file !
399: */
400: public void deleteCachedContent() {
401: this .temporaryEditedContent = null;
402: this .timeOfLastGetContent = -1;
403: }
404:
405: /** @return temporaryEditedContent if not null or the file content from disk.
406: * ASSERT: ONLY PLACE TO GET THE CONTENT !
407: */
408: public String getContent() throws Exception {
409: if (timeOfLastGetContent > 0) {
410: // [Feb2008]
411: if (hasFileContentChangedOnDiskSinceLastGetContent()) {
412: System.out
413: .println("FILE HAS CHANGED ON DISK SINCE LAST EDIT !!!");
414: }
415: }
416:
417: if (temporaryEditedContent != null)
418: return temporaryEditedContent;
419:
420: timeOfLastGetContent = javaFile.lastModified();
421: return FileUtils.getFileStringContent(javaFile); // ONLY PLACE TO GET THE CONTENT !
422: }
423:
424: public boolean hasFileContentChangedOnDiskSinceLastGetContent() {
425: if (timeOfLastGetContent <= 0)
426: return false; // no get yet.
427:
428: if (timeOfLastGetContent != javaFile.lastModified())
429: return true;
430: return false;
431: }
432:
433: public void cancelExternalChanges() {
434: timeOfLastGetContent = javaFile.lastModified();
435: }
436:
437: public boolean getHasBeenRemoved() {
438: return !javaFile.exists();
439: }
440:
441: /** Sets the content edited.
442: Will be stored later. Here, it is stored in temporaryEditedContent.
443: Please check hasFileContentChangedOnDiskSinceLastGetContent() !
444:
445: @param allowChangesFromOutside if false, and changes occured outside tIDE since last getContent() , throws a RuntimeException.
446: */
447: public void setContentFromEditor(final String txt,
448: boolean allowChangesFromOutside)//, int caretLine, int caretColumn)
449: {
450: if (hasFileContentChangedOnDiskSinceLastGetContent()) {
451: System.out.println("WARNING: content changed on disk for "
452: + this .getJavaName());
453: if (!allowChangesFromOutside) {
454: throw new RuntimeException("" + this .getJavaName()
455: + " changed on disk from outside");
456: }
457: System.out
458: .println("Ignoring changes, using tIDE's version");
459: }
460:
461: temporaryEditedContent = txt;
462: /* if(temporaryEditedContent!=null)
463: {
464: setCaretPositionToRemember(caretLine, caretColumn);
465: }*/
466: }
467:
468: public int getCaretLinePosition() {
469: return caretLinePosition;
470: }
471:
472: public int getCaretColumnPosition() {
473: return caretColumnPosition;
474: }
475:
476: public void setCaretPositionToRemember(int line, int column) // more robust than an absolute dot position
477: {
478: caretLinePosition = line;
479: caretColumnPosition = column;
480: }
481:
482: /** If has been edited, i.e. setContentFromEditor() was called => writes the content to file (temporaryEditedContent)
483: * And sets the file to not compiled.
484: * Tail spaces are removed automatically.
485: */
486: public void saveContentToFile() throws Exception {
487: if (temporaryEditedContent == null)
488: return;
489:
490: if (hasFileContentChangedOnDiskSinceLastGetContent()) {
491: System.out
492: .println(""
493: + this .getJavaName()
494: + " has been changed on disk. Content is now overridden by tIDE's own version");
495: }
496:
497: if (!javaFile.canWrite()) {
498: System.out.println("" + this .getJavaName()
499: + " is no more editable !");
500: }
501:
502: // [Nov2006]: these blanks are really not useful !
503: temporaryEditedContent = StringUtils
504: .removeLineTailSpaces(temporaryEditedContent);
505:
506: FileUtils.saveToFile(temporaryEditedContent, this .javaFile);
507:
508: timeOfLastGetContent = this .javaFile.lastModified(); // Because it is "true".
509:
510: temporaryEditedContent = null; // IMPORTANT.
511: isBeingEdited = false;
512:
513: this .setIsCompiled(false); // also sets the date
514: }
515:
516: /** Used to share the reference if used several times...
517: *@deprecated
518: */
519: @Deprecated
520: private SimplifiedSyntaxTree2 simplifiedSyntaxTree = null;
521:
522: /** Deletes the old syntax tree, if any.
523: *@deprecated
524: */
525: @Deprecated
526: public void setSimplifiedSyntaxTree(SimplifiedSyntaxTree2 st) {
527: if (simplifiedSyntaxTree != null && simplifiedSyntaxTree != st) {
528: // delete the old ref, later ! it may be in use by the completion right now!
529: // TODO: use a queue !
530: final SimplifiedSyntaxTree2 oldRef = simplifiedSyntaxTree;
531: Thread t = new Thread() {
532: public void run() {
533: try {
534: Thread.sleep(2000);
535: } catch (InterruptedException ignore) {
536: } finally {
537: try {
538: oldRef.terminateSST();
539: } catch (Exception e) {
540: System.out
541: .println("Can't terminate SST for "
542: + getJavaName() + ": "
543: + e.getMessage());
544: e.printStackTrace();
545: }
546: }
547: }
548: };
549: t.setPriority(Thread.MIN_PRIORITY);
550: t.start();
551: }
552: this .simplifiedSyntaxTree = st;
553:
554: if (simplifiedSyntaxTree != null) {
555: SyntaxTreeCache.getInstance().addToCache(this );
556: }
557: }
558:
559: @Deprecated
560: /** @deprecated */
561: public SimplifiedSyntaxTree2 getSimplifiedSyntaxTreeIfAlreadyMade() {
562: return simplifiedSyntaxTree;
563: }
564:
565: private ParserResult cu = null;
566:
567: public ParserResult getParserResultIfAlreadyMade() {
568: return cu;
569: }
570:
571: public void setParserResult(ParserResult st) {
572: cu = st;
573: }
574:
575: /** Cached. Set when call to setIsCompiled(*)
576: * or lookIfJavaFileChanged().
577: */
578: public long getLastModifiedJavaFile() {
579: return lastModifiedJavaFile;
580: }
581:
582: public void liberateResourcesForGC() {
583: if (isBeingEdited
584: || MainEditorFrame.instance.editorPanel
585: .getActualDisplayedFile() == this ) {
586: System.out
587: .println("Ignore liberateResourcesForGC because being edited: "
588: + this );
589: return;
590: }
591:
592: if (simplifiedSyntaxTree != null) {
593: simplifiedSyntaxTree.terminateSST();
594: simplifiedSyntaxTree = null;
595: }
596:
597: if (this .cu != null) {
598: this .cu.compilationUnit = null;
599: this .cu = null;
600: }
601:
602: //classesUsedBy.clear();
603: if (undoManager != null) {
604: undoManager.discardAllEdits();
605: undoManager = null;
606: }
607: }
608:
609: /** Call after deletion.
610: */
611: public void fileHasBeenDeleted() {
612: this .sourceFileDependencies.fileHasBeenDeletedOrIsIgnored();
613: }
614:
615: /** Sorting is NOT performed (todo?).
616: */
617: public void rename(String newSimpleName,
618: boolean renameTypeNameInFile, boolean renameInProject)
619: throws Exception {
620: // BE CAREFUL: DO EVERYTHING HERE...
621: String cont = this .getContent();
622: saveContentToFile();
623:
624: // will be "lost" => copy
625: List<SourceFile> usingThis = new ArrayList<SourceFile>(
626: sourceFileDependencies.getClassesUsingThis_REF_());
627:
628: // "remove" this
629: this .setIsCompiled(false);
630: this .sourceFileDependencies.reset_();
631: deleteAssociatedClassFiles();
632:
633: String oldPartName = this .getJavaPartName();
634:
635: // create as new...
636: File newFile = new File(this .javaFile.getParentFile(),
637: newSimpleName + ".java");
638: if (newFile.exists()) {
639: //ok if the case is different, that is the same file
640: if (!newSimpleName.equalsIgnoreCase(javaPartName)) {
641: throw new RuntimeException("Already existing: "
642: + newFile);
643: }
644: }
645:
646: if (renameTypeNameInFile) {
647: cont = cont.replace(oldPartName, newSimpleName);
648: }
649:
650: //System.out.println("New file: "+newFile);
651: // necessary when just changing case,
652: File temp = File.createTempFile("tide_" + newSimpleName,
653: ".java.temp", javaFile.getParentFile());
654: FileUtils.saveToFile(cont, temp);
655:
656: javaFile.delete();
657:
658: if (!temp.renameTo(newFile))
659: throw new RuntimeException("Cannot rename " + temp + " to "
660: + newFile);
661: temp.delete();
662:
663: this .javaFile = newFile;
664: this .name = newSimpleName + ".java";
665: javaPartName = newSimpleName;
666: if (packageName.length() > 0) {
667: javaName = this .packageName + "." + newSimpleName;
668: } else {
669: javaName = newSimpleName;
670: }
671:
672: if (this .isProjectMainClass) {
673: MainEditorFrame.instance.getActualProject()
674: .setMainSourceFile(javaFile);
675: }
676:
677: if (renameInProject) {
678: StringBuilder errors = new StringBuilder();
679: for (SourceFile sfi : usingThis) {
680: if (!sfi.isEditable()) {
681: errors.append("" + sfi.getJavaName()
682: + ":0: Cannot rename, not editable.\r\n");
683: continue;
684: }
685:
686: // this is not a semantic replace => DANGEROUS, may replace too much !
687: // another good reason to choose long and unique names !!!
688:
689: try {
690: String notJavaChar = "[^A-Za-z0-9_\\$]";
691: String regex = "(" + notJavaChar + ")("
692: + oldPartName.replace("$", "\\$") + ")("
693: + notJavaChar + ")";
694: // TRICKY: TODO: better solution ?, eventually with manual matcher, replacer, & tail ??
695: sfi.renameAllOccurencesRegex(regex, "$1"
696: + newSimpleName.replace("$", "\\$") + "$3");
697: } catch (Exception e) {
698: errors.append("" + sfi.getJavaName()
699: + ":0: Cannot rename: " + e.getMessage()
700: + ".\r\n");
701: }
702:
703: // replacing raw names is dangerous.
704: }
705:
706: if (errors.length() > 0) {
707: throw new RuntimeException("Cannot rename " + temp
708: + " to " + newFile);
709: }
710: }
711:
712: //this.javaFile
713: }
714:
715: public void deleteAssociatedClassFiles() {
716: java.util.List<File> cf = lookForAssociatedClassFiles();
717: if (cf != null) {
718: for (File f : cf) {
719: f.delete();
720: }
721: }
722: }
723:
724: /** Used in the rename. Called for dependencies.
725: * BE CAREFUL !
726: */
727: public void renameAllOccurencesRegex(String oldStr, String newStr)
728: throws Exception {
729: // TODO...
730: System.out.println("Renaming " + oldStr + " => " + newStr
731: + " in " + this .getJavaName());
732: String cont = getContent();
733:
734: cont = cont.replaceAll(oldStr, newStr); // replaces all
735:
736: this .setCaretPositionToRemember(getCaretLinePosition(),
737: getCaretColumnPosition());
738: this .setContentFromEditor(cont, true); // because the method is quick, allow ! this means that our changes override the ext changes !
739: this .saveContentToFile();
740: }
741:
742: // Persistence
743: //
744:
745: /** should be called after all source files have been restored in the project.
746: * because this also restore the dependencies
747: * @return lookIfJavaFileChanged();
748: */
749: @SuppressWarnings("unchecked")
750: public boolean restoreFromVectorRepr(StorageVector rep,
751: SourcesTreeModel model) throws Exception {
752:
753: if (rep.get(0) instanceof Long) {
754: System.out.println("Strange rep? " + rep);
755: throw new Exception("Bad SourceFile stored representation");
756: }
757:
758: if (rep.get(0) instanceof Integer) {
759: // version 1 (until Aug 2006)
760: ignoredType = EnumUtils.getEnumFromOrdinal((Integer) rep
761: .get(0), SourcesTreeIcon.Ignored.class);
762: //hasJavaFileChanged = (Boolean) rep.get(1);
763: //hasClassChanged = (Boolean) rep.get(2);
764: lastModifiedJavaFile = (Long) rep.get(3);
765: lastStoredLastModifiedJavaFile = lastModifiedJavaFile;
766: lastModifiedClassFile = (Long) rep.get(4);
767:
768: if (rep.size() <= 5)
769: return lookIfJavaFileChangedAndTreat();
770:
771: //List<String> cusing = (ArrayList<String>) rep.get(5);
772: //List<String> cused = (ArrayList<String>) rep.get(6);
773:
774: if (rep.size() <= 7)
775: return lookIfJavaFileChangedAndTreat();
776: //caretPosition = (Integer) rep.get(7);
777:
778: if (rep.size() <= 8)
779: return lookIfJavaFileChangedAndTreat();
780: isCompiled = (Boolean) rep.get(8);
781:
782: } else {
783: // new version !
784: char version = (Character) rep.get(0);
785: ignoredType = EnumUtils.getEnumFromOrdinal((Integer) rep
786: .get(1), SourcesTreeIcon.Ignored.class);
787: //OLD hasJavaFileChanged = (Boolean) rep.get(2);
788: //hasClassChanged = (Boolean) rep.get(3);
789: lastModifiedJavaFile = (Long) rep.get(4);
790: lastStoredLastModifiedJavaFile = lastModifiedJavaFile;
791: lastModifiedClassFile = (Long) rep.get(5);
792: //OLD caretPosition = (Integer) rep.get(6);
793: isCompiled = (Boolean) rep.get(7);
794: sourceFileDependencies.restoreFromVectorRep(
795: (StorageVector) rep.get(8), model);
796: if (version > 'b') {
797: this .caretLinePosition = (Integer) rep.get(9);
798: this .caretColumnPosition = (Integer) rep.get(10);
799: }
800: if (version > 'c') {
801: this .topKind = Kind.valueOf((String) rep.get(11));
802: }
803: }
804:
805: // Actualize (if date changed, set compiled to false)
806: return lookIfJavaFileChangedAndTreat();
807: }
808:
809: public StorageVector getVectorRep() {
810: // the other values are set at construction...
811:
812: StorageVector rep = new StorageVector();
813: rep.add(Character.valueOf('d')); // version
814:
815: rep.add(ignoredType.ordinal());
816: rep.add(false); //OLD hasJavaFileChanged);
817: rep.add(false); //OLD hasClassChanged);
818: rep.add(lastModifiedJavaFile);
819: rep.add(lastModifiedClassFile);
820: rep.add(0); //OLD this.caretPosition, replaced with line, col
821: rep.add(isCompiled);
822: rep.add(this .sourceFileDependencies.getVectorRep());
823: rep.add(caretLinePosition);
824: rep.add(caretColumnPosition);
825: rep.add(topKind.toString());
826:
827: return rep;
828: }
829:
830: /*test
831: public static void main(String[] arguments)
832: {
833: String notJavaChar = "[^A-Za-z0-9_$]";
834: String regex = "("+notJavaChar+")" + "(Hello)(" + notJavaChar+")";
835: System.out.println("my Beautiful Hello.abc".replaceAll(regex, "$1BBB$3"));
836:
837:
838: }*/
839:
840: }
|