1 19 20 package jode.decompiler; 21 import jode.GlobalOptions; 22 import jode.bytecode.ClassInfo; 23 import jode.bytecode.InnerClassInfo; 24 import jode.type.Type; 25 import jode.type.ArrayType; 26 import jode.type.ClassInterfacesType; 27 import jode.type.NullType; 28 29 import java.util.SortedMap ; 30 import java.util.TreeMap ; 31 import java.util.List ; 32 import java.util.LinkedList ; 33 import java.util.Comparator ; 34 import java.util.Iterator ; 35 36 import java.io.IOException ; 37 import java.util.Hashtable ; 38 39 public class ImportHandler { 40 44 public final static int DEFAULT_PACKAGE_LIMIT = Integer.MAX_VALUE; 45 48 public final static int DEFAULT_CLASS_LIMIT = 1; 49 50 SortedMap imports; 51 52 Hashtable cachedClassNames = null; 53 ClassAnalyzer main; 54 String className; 55 String pkg; 56 57 int importPackageLimit; 58 int importClassLimit; 59 60 65 static Comparator comparator = new Comparator () { 66 public int compare(Object o1, Object o2) { 67 String s1 = (String ) o1; 68 String s2 = (String ) o2; 69 boolean java1 = s1.startsWith("java"); 70 boolean java2 = s2.startsWith("java"); 71 72 if (java1 != java2) 73 return java1 ? -1 : 1; 74 return s1.compareTo(s2); 75 } 76 }; 77 78 public ImportHandler() { 79 this(DEFAULT_PACKAGE_LIMIT, DEFAULT_CLASS_LIMIT); 80 } 81 82 public ImportHandler(int packageLimit, int classLimit) { 83 importPackageLimit = packageLimit; 84 importClassLimit = classLimit; 85 } 86 87 100 private boolean conflictsImport(String name) { 101 int pkgdelim = name.lastIndexOf('.'); 102 if (pkgdelim != -1) { 103 String pkgName = name.substring(0, pkgdelim); 104 105 if (pkgName.equals(pkg)) 106 return false; 107 108 name = name.substring(pkgdelim); 110 111 if (pkg.length() != 0) { 112 113 if (ClassInfo.exists(pkg+name)) 114 return true; 115 } else { 116 118 if (ClassInfo.exists(name.substring(1))) 119 return true; 120 } 121 122 Iterator iter = imports.keySet().iterator(); 123 while (iter.hasNext()) { 124 String importName = (String ) iter.next(); 125 if (importName.endsWith(".*")) { 126 127 importName = importName.substring 128 (0, importName.length()-2); 129 if (!importName.equals(pkgName)) { 130 if (ClassInfo.exists(importName+name)) 131 return true; 132 } 133 } else { 134 135 if (importName.endsWith(name) 136 || importName.equals(name.substring(1))) 137 return true; 138 } 139 } 140 } 141 return false; 142 } 143 144 private void cleanUpImports() { 145 Integer dummyVote = new Integer (Integer.MAX_VALUE); 146 SortedMap newImports = new TreeMap (comparator); 147 List classImports = new LinkedList (); 148 Iterator iter = imports.keySet().iterator(); 149 while (iter.hasNext()) { 150 String importName = (String ) iter.next(); 151 Integer vote = (Integer ) imports.get(importName); 152 if (!importName.endsWith(".*")) { 153 if (vote.intValue() < importClassLimit) 154 continue; 155 int delim = importName.lastIndexOf("."); 156 157 if (delim != -1) { 158 161 if (newImports.containsKey 162 (importName.substring(0, delim)+".*")) 163 continue; 164 165 169 classImports.add(importName); 170 } else if (pkg.length() != 0) { 171 174 newImports.put(importName, dummyVote); 175 } 176 } else { 177 if (vote.intValue() < importPackageLimit) 178 continue; 179 newImports.put(importName, dummyVote); 180 } 181 } 182 183 imports = newImports; 184 cachedClassNames = new Hashtable (); 185 188 iter = classImports.iterator(); 189 while (iter.hasNext()) { 190 194 String classFQName = (String ) iter.next(); 195 if (!conflictsImport(classFQName)) { 196 imports.put(classFQName, dummyVote); 197 String name = 198 classFQName.substring(classFQName.lastIndexOf('.')+1); 199 cachedClassNames.put(classFQName, name); 200 } 201 } 202 } 203 204 public void dumpHeader(TabbedPrintWriter writer) 205 throws java.io.IOException 206 { 207 writer.println("/* "+ className 208 + " - Decompiled by JODE"); 209 writer.println(" * Visit "+GlobalOptions.URL); 210 writer.println(" */"); 211 if (pkg.length() != 0) 212 writer.println("package "+pkg+";"); 213 214 cleanUpImports(); 215 Iterator iter = imports.keySet().iterator(); 216 String lastFirstPart = null; 217 while (iter.hasNext()) { 218 String pkgName = (String )iter.next(); 219 if (!pkgName.equals("java.lang.*")) { 220 int firstDot = pkgName.indexOf('.'); 221 if (firstDot != -1) { 222 String firstPart = pkgName.substring(0, firstDot); 223 if (lastFirstPart != null 224 && !lastFirstPart.equals(firstPart)) { 225 writer.println(""); 226 } 227 lastFirstPart = firstPart; 228 } 229 writer.println("import "+pkgName+";"); 230 } 231 } 232 writer.println(""); 233 } 234 235 public void error(String message) { 236 GlobalOptions.err.println(message); 237 } 238 239 public void init(String className) { 240 imports = new TreeMap (comparator); 241 242 imports.put("java.lang.*", new Integer (Integer.MAX_VALUE)); 243 244 int pkgdelim = className.lastIndexOf('.'); 245 pkg = (pkgdelim == -1)? "" : className.substring(0, pkgdelim); 246 this.className = (pkgdelim == -1) ? className 247 : className.substring(pkgdelim+1); 248 } 249 250 253 public void useClass(ClassInfo clazz) { 254 for (;;) { 255 259 InnerClassInfo[] outerInfo = clazz.getOuterClasses(); 260 if (outerInfo == null) 261 break; 262 263 if (outerInfo[0].name == null || outerInfo[0].outer == null) 264 return; 265 clazz = ClassInfo.forName(outerInfo[0].outer); 266 } 267 268 String name = clazz.getName(); 269 270 Integer i = (Integer ) imports.get(name); 271 if (i == null) { 272 274 275 int pkgdelim = name.lastIndexOf('.'); 276 if (pkgdelim != -1) { 277 String pkgName = name.substring(0, pkgdelim); 278 if (pkgName.equals(pkg)) 279 return; 280 281 Integer pkgVote = (Integer ) imports.get(pkgName+".*"); 282 if (pkgVote != null 283 && pkgVote.intValue() >= importPackageLimit) 284 return; 285 286 pkgVote = (pkgVote == null) 287 ? new Integer (1): new Integer (pkgVote.intValue()+1); 288 imports.put(pkgName+".*", pkgVote); 289 } 290 i = new Integer (1); 291 } else { 292 if (i.intValue() >= importClassLimit) 293 return; 294 i = new Integer (i.intValue()+1); 295 } 296 imports.put(name, i); 297 } 298 299 public final void useType(Type type) { 300 if (type instanceof ArrayType) 301 useType(((ArrayType) type).getElementType()); 302 else if (type instanceof ClassInterfacesType) 303 useClass(((ClassInterfacesType) type).getClassInfo()); 304 } 305 306 320 public String getClassString(ClassInfo clazz) { 321 String name = clazz.getName(); 322 if (cachedClassNames == null) 323 324 return name; 325 326 327 String cached = (String ) cachedClassNames.get(name); 328 if (cached != null) 329 return cached; 330 331 int pkgdelim = name.lastIndexOf('.'); 332 if (pkgdelim != -1) { 333 334 String pkgName = name.substring(0, pkgdelim); 335 336 Integer i; 337 if (pkgName.equals(pkg) 338 || (imports.get(pkgName+".*") != null 339 && !conflictsImport(name))) { 340 String result = name.substring(pkgdelim+1); 341 cachedClassNames.put(name, result); 342 return result; 343 } 344 } 345 cachedClassNames.put(name, name); 346 return name; 347 } 348 349 public String getTypeString(Type type) { 350 if (type instanceof ArrayType) 351 return getTypeString(((ArrayType) type).getElementType()) + "[]"; 352 else if (type instanceof ClassInterfacesType) 353 return getClassString(((ClassInterfacesType) type).getClassInfo()); 354 else if (type instanceof NullType) 355 return "Object"; 356 else 357 return type.toString(); 358 } 359 360 protected int loadFileFlags() 361 { 362 return 1; 363 } 364 } 365 366 367 | Popular Tags |