1 34 package jarg; 35 36 import java.util.Map ; 37 import java.util.TreeMap ; 38 import java.util.HashMap ; 39 import java.util.Iterator ; 40 41 import org.apache.bcel.classfile.*; 42 43 49 class PackageHandler { 50 private Jarg app; 51 String packagename; 52 Map classes = new TreeMap (); 53 54 private NameCreater nc; 55 private Map rncls = new HashMap (); 56 private Map rnsig = new HashMap (); 57 private Map rnfld = new HashMap (); 58 private Map rnmth = new HashMap (); 59 60 PackageHandler(Jarg app, String packagename) { 61 this.app = app; 62 this.packagename = packagename; 63 this.nc = new NameCreater(packagename); 64 } 65 66 void addClassHandler(ClassHandler clsh) { 67 String key = clsh.classname; 68 this.classes.put(key, clsh); 69 clsh.setPackageHandler(this); 70 71 int cidx = clsh.packagename.length(); 72 if (cidx > 0) { 73 cidx ++; 74 } 75 String str = clsh.classname.substring(cidx); 76 this.nc.addName(str); 77 } 78 79 void doCheckUsedClass(PackageCollection pkgcol) { 80 Iterator cit = this.classes.keySet().iterator(); 81 while (cit.hasNext()) { 82 String ckey = (String )cit.next(); 83 ClassHandler clsh = (ClassHandler)this.classes.get(ckey); 84 clsh.doCheckUsedClass(pkgcol); 85 } 86 } 87 88 void doOptimize() { 89 renmClass(); 90 fixMethodOverride(); 91 Iterator cit = this.classes.keySet().iterator(); 93 while (cit.hasNext()) { 94 String ckey = (String )cit.next(); 95 ClassHandler clsh = (ClassHandler)this.classes.get(ckey); 96 clsh.doOptimize(); 97 } 98 } 99 100 private void renmClass() { 101 Iterator cit = this.classes.keySet().iterator(); 102 while (cit.hasNext()) { 103 String ckey = (String )cit.next(); 104 ClassHandler clsh = (ClassHandler)this.classes.get(ckey); 105 if (!clsh.isNative && clsh.isPackageScope) { 106 renmClass0(clsh); 107 } 108 if (!clsh.isNative) { 109 Field[] flds = clsh.jcls.getFields(); 110 for (int i=0; i<flds.length; i++) { 111 renmField0(clsh, flds[i]); 112 } 113 } 114 if (!clsh.isNative) { 116 Method[] mths = clsh.jcls.getMethods(); 117 for (int i=0; i<mths.length; i++) { 118 renmMethod0(clsh, mths[i]); 119 } 120 } 121 } 122 } 123 124 private void fixMethodOverride() { 125 Iterator cit = this.classes.keySet().iterator(); 126 while (cit.hasNext()) { 127 String ckey = (String )cit.next(); 128 ClassHandler clsh = (ClassHandler)this.classes.get(ckey); 129 if (!clsh.isNative) { 130 Method[] mths = clsh.jcls.getMethods(); 131 for (int i=0; i<mths.length; i++) { 132 fixMethodOverride0(clsh, mths[i]); 133 } 134 } 135 } 136 } 137 138 private void renmClass0(ClassHandler clsh) { 139 String pkgnm = clsh.packagename; 140 String clsnm = clsh.classname; 141 boolean isOptClass = true; 142 if (!app.isRenameClass) { 144 isOptClass = false; 145 } 146 for (int i=0; i<app.excpPathes.length; i++) { 148 if (pkgnm.startsWith(app.excpPathes[i])) { 149 isOptClass = false; 150 break; 151 } 152 } 153 if (isOptClass && app.excpPackages.contains(pkgnm)) { 155 isOptClass = false; 156 } 157 if (isOptClass && app.excpClasses.contains(clsnm)) { 158 isOptClass = false; 159 } 160 if (isOptClass) { 161 String oldnm = clsh.classname; 163 String newnm = nc.createNext(); 164 165 int cidx = clsh.packagename.length(); 166 if (cidx > 0) { 167 cidx ++; 168 } 169 String cnm = clsh.classname.substring(cidx); 170 171 if (cnm.length() <= newnm.length()) { 172 return; 173 } 174 175 if (clsh.packagename != null && clsh.packagename.length() > 0) { 176 newnm = clsh.packagename + "." + newnm; 177 } 178 rncls.put(oldnm, newnm); 179 180 String oldsig = "L" + oldnm.replace('.','/') + ";"; 181 String newsig = "L" + newnm.replace('.','/') + ";"; 182 rnsig.put(oldsig, newsig); 183 184 clsh.filename = newnm.replace('.','/') + ".class"; 185 if (app.isVerboseRN) { 186 System.out.println("rename class " + oldnm + " -> " + newnm); 187 } 188 } 189 } 190 191 private void renmField0(ClassHandler clsh, Field fld) { 192 String clsnm = clsh.classname; 193 String fldnm = fld.getName(); 194 195 boolean flg = false; 197 198 if (app.isRenameField && !fld.isPrivate() && !fld.isProtected() && !fld.isPublic()) { 199 if (!"this".equals(fldnm) 201 && !fldnm.startsWith("this$") 202 && !app.excpFields.contains(fldnm) 203 ) { 204 flg = true; 205 } 206 } 207 if (flg) { 208 String oldnm = clsnm + '!' + fldnm; 209 String newnm = clsh.ncF.createNext(); 210 211 if (fldnm.length() <= newnm.length()) { 212 return; 213 } 214 215 rnfld.put(oldnm, newnm); 216 217 if (app.isVerboseRN) { 218 System.out.println("rename field " + clsnm + "!" + fldnm + " -> " + newnm); 219 } 220 } 221 } 222 223 private void renmMethod0(ClassHandler clsh, Method mth) { 224 String clsnm = clsh.classname; 225 String mthnm = mth.getName(); 226 String sign = mth.getSignature(); 227 228 boolean flg = false; 230 231 if (app.isRenameMethod && !mth.isPrivate() && !mth.isProtected() && !mth.isPublic() && !mth.isNative()) { 232 if (!"<init>".equals(mthnm) 234 && !"<clinit>".equals(mthnm) 235 && !app.excpMethods.contains(mthnm) 236 ) { 237 flg = true; 238 } 239 } 240 if (flg) { 241 String oldnm = clsnm + '#' + mthnm + ' ' + sign; 245 String newnm = clsh.ncM.createNext(); 246 247 if (mthnm.length() <= newnm.length()) { 248 return; 249 } 250 251 rnmth.put(oldnm, newnm); 252 if (app.isVerboseRN) { 253 System.out.println("rename method " + clsnm + "#" + mthnm + sign + " -> " + newnm); 254 } 255 } 256 } 257 258 private void fixMethodOverride0(ClassHandler clsh, Method mth) { 259 String clsnm = clsh.classname; 260 String mthnm = mth.getName(); 261 String sign = mth.getSignature(); 262 263 if (app.isRenameMethod && !mth.isPrivate() && !mth.isProtected() && !mth.isPublic() && !mth.isNative()) { 264 String oldnm = clsnm + '#' + mthnm + ' ' + sign; 265 if (rnmth.containsKey(oldnm)) { 266 fixMethodOverride0Chain(clsh, mthnm, sign); 267 } 268 } 269 } 270 271 private void fixMethodOverride0Chain(ClassHandler clsh, String mthnm, String sign) { 272 String clsnm = clsh.classname; 273 String supclsnm = clsh.superclassname; 274 if (supclsnm != null && supclsnm.startsWith(clsh.packagename) && !clsnm.equals(supclsnm)) { 275 if (this.classes.containsKey(supclsnm)) { 277 ClassHandler supclsh = (ClassHandler)this.classes.get(supclsnm); 278 fixMethodOverride0Chain(supclsh, mthnm, sign); 279 } 280 String supoldnm = supclsnm + '#' + mthnm + ' ' + sign; 281 if (rnmth.containsKey(supoldnm)) { 282 String supnewnm = (String )rnmth.get(supoldnm); 283 if (!supnewnm.endsWith("R")) { 284 supnewnm = supnewnm + 'R'; 285 rnmth.put(supoldnm, supnewnm); 286 } 287 String oldnm = clsnm + '#' + mthnm + ' ' + sign; 288 String newnm = supnewnm; 289 rnmth.put(oldnm, newnm); 290 if (app.isVerboseRN) { 291 System.out.println("fix override method " + clsnm + "#" + mthnm + sign + " -> " + newnm); 292 } 293 } 294 } 295 } 296 297 private String convClassName0(String clsnm) { 298 String newnm = (String )rncls.get(clsnm); 299 if (newnm != null) { 300 return newnm; 301 } 302 return clsnm; 303 } 304 305 String convClassName(String clsnm) { 306 if (clsnm.indexOf('/') >= 0) { 307 clsnm = clsnm.replace('/','.'); 308 } 309 if (clsnm.startsWith("[")) { 310 int idxst = clsnm.indexOf('L'); 312 if (idxst < 0) { 313 return clsnm; 315 } else { 316 String ss = clsnm.substring(idxst+1, clsnm.length()-1); 318 String nn = convClassName0(ss); 319 String r = clsnm.substring(0, idxst+1) + nn + ";"; 320 return r; 321 } 322 } else { 323 return convClassName0(clsnm); 325 } 326 } 327 328 private String convSignature0(String sign) { 329 String newsig = (String )rnsig.get(sign); 330 if (newsig != null) { 331 return newsig; 332 } 333 return sign; 334 } 335 336 String convSignature(String sign) { 337 if (sign.startsWith("[")) { 338 int idxst = sign.indexOf('L'); 340 if (idxst < 0) { 341 return sign; 343 } else { 344 String ss = sign.substring(idxst); 346 String nn = convSignature0(ss); 347 String r = sign.substring(0, idxst) + nn; 348 return r; 349 } 350 } else if (sign.startsWith("L")) { 351 return convSignature0(sign); 353 } else { 354 return sign; 356 } 357 } 358 359 String convSignatureM(String sign) { 360 int idxst = 0, idxed = 0; 362 363 for (;;) { 364 idxst = sign.indexOf('L', idxed); 365 if (idxst < 0) { 366 break; 367 } 368 idxed = sign.indexOf(';', idxst); 369 String s1 = sign.substring(idxst, idxed+1); 370 String ss = convSignature0(s1); 371 if (!s1.equals(ss)) { 372 sign = sign.substring(0, idxst) + ss + sign.substring(idxed+1); 373 idxed = sign.indexOf(';', idxst); 374 } 375 } 376 return sign; 377 } 378 379 String convFieldName(String clsnm, String fldnm) { 380 String clsfldnm = clsnm + '!' + fldnm; 381 String newnm = (String )rnfld.get(clsfldnm); 382 if (newnm != null) { 383 return newnm; 384 } 385 return fldnm; 386 } 387 388 String convMethodName(String clsnm, String mthnm, String signature) { 389 String clsmthnm = clsnm + '#' + mthnm + ' ' + signature; 390 String newnm = (String )rnmth.get(clsmthnm); 391 if (newnm != null) { 392 return newnm; 393 } 394 return mthnm; 395 } 396 } 397 | Popular Tags |