KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > importscrubber > ImportStatements


1 package net.sourceforge.importscrubber;
2
3 import java.util.ArrayList JavaDoc;
4 import java.util.Iterator JavaDoc;
5 import java.util.List JavaDoc;
6
7 /**
8  * Encapsulates various operations on a class' import statements
9  */

10 public class ImportStatements
11 {
12     public static final String JavaDoc MARKER = "import";
13     private ArrayList JavaDoc _stmts = new ArrayList JavaDoc();
14
15     public void add(String JavaDoc candidateString)
16     {
17         ImportStatement candidate = new ImportStatement(candidateString);
18         if(candidate.getPackage() == null || _stmts.contains(candidate)) {
19             if (ImportScrubber.DEBUG)
20                 System.out.println("not adding " + candidate.getFullyQualifiedClassName());
21             return;
22         }
23
24         _stmts.add(candidate);
25     }
26
27     public StringBuffer JavaDoc getOutput(StatementFormat format)
28     {
29         return format.applyFormat(_stmts);
30     }
31
32     public int getCount()
33     {
34         return _stmts.size();
35     }
36
37     /**
38      * Remove imports for classes in the same package as the current class
39      */

40     public void removeLocalToPackage(PackageStmt packageStmt)
41     {
42         for (Iterator JavaDoc i = _stmts.iterator(); i.hasNext();) {
43             ImportStatement stmt = (ImportStatement)i.next();
44             if (packageStmt.isInSamePackageAs(stmt)) {
45                 if (ImportScrubber.DEBUG)
46                     System.out.println("Removing local import:" + stmt.getClassName());
47                 i.remove();
48             }
49         }
50     }
51
52     public void removeInnerClasses(String JavaDoc className) {
53         if (ImportScrubber.DEBUG)
54             System.out.println("Looking for inner classes of " + className);
55         for (Iterator JavaDoc i = _stmts.iterator(); i.hasNext();) {
56             ImportStatement stmt = (ImportStatement)i.next();
57             if (stmt.getFullyQualifiedClassName().startsWith(className + ".")) {
58                 if (ImportScrubber.DEBUG)
59                     System.out.println("Removing inner class import:" + stmt.getClassName());
60                 i.remove();
61             }
62         }
63     }
64
65     /**
66      * Remove those imports which appear in the class file
67      * byte code but are not directly referenced in the source code
68     * returns non-null on error condition.
69      */

70     public String JavaDoc removeUnreferenced(String JavaDoc classBody)
71     {
72         for (Iterator JavaDoc i = _stmts.iterator(); i.hasNext();) {
73             ImportStatement stmt = (ImportStatement)i.next();
74             // is that class name mentioned somewhere in the class?
75
if (classBody.indexOf(stmt.getClassName()) == -1) {
76                 // nope, so remove it
77
if (ImportScrubber.DEBUG)
78                     System.out.println("Removing unreferenced import:" + stmt.getClassName());
79                 i.remove();
80                 continue;
81             }
82
83             // is that class used as a fully qualified name in the class body somewhere?
84
int j = classBody.indexOf(stmt.getFullyQualifiedClassName());
85             if (j != -1) {
86                 if (ImportScrubber.DEBUG)
87                     System.out.println("FQ class found:" + stmt.getClassName());
88                 boolean bareClass = false;
89                 while (j != -1) {
90                     if (classBody.charAt(j - 1) != '.') {
91                         bareClass = true;
92                         break;
93                     }
94                     j = classBody.indexOf(stmt.getFullyQualifiedClassName(), j + 1);
95                 }
96                 // if also used as bare class, check to see if leaving import in makes things ambiguous:
97
// if multiple classes w/ the same name are used, we bail.
98
// (for example, say java.util.Date and java.sql.Date are both specified as FQ classnames.
99
// but user has imported java.util.Date, and uses unqualified Date too.
100
// we can't tell which import to leave out w/o additional parsing of classBody. Which
101
// is doable, but I'm considering this rare enough to not be worth the effort, and
102
// I'll settle for just being sure not to break things.)
103
if (bareClass) {
104                     if (ImportScrubber.DEBUG)
105                         System.out.println("Bare class also found");
106                     for (Iterator JavaDoc k = _stmts.iterator(); k.hasNext(); ) {
107                         ImportStatement s2 = (ImportStatement)k.next();
108                         if (s2 != stmt && stmt.getClassName().compareTo(s2.getClassName()) == 0) {
109                             return "ambiguous use of " + stmt.getClassName() + "."
110                                    + "\n\t(" + stmt.getFullyQualifiedClassName() + " and " + s2.getFullyQualifiedClassName() + ")"
111                                    + "\n\tTo scrub, make all references fully qualified, or none.";
112                         }
113                     }
114                     // loop finished so no ambiguity, the unqualified references all refer to this class. leave the import in.
115
} else {
116                     if (ImportScrubber.DEBUG)
117                         System.out.println("No bare class found; removing");
118                     i.remove();
119                 }
120             }
121         }
122
123         return null; // no error
124
}
125 }
126
127
Popular Tags