1 23 24 29 30 package com.sun.enterprise.tools.verifier.apiscan.classfile; 31 32 import java.io.IOException ; 33 import java.util.*; 34 import java.util.logging.Level ; 35 36 45 class ASMClosureCompilerImpl extends ClosureCompilerImplBase { 46 47 private Collection<MethodRef> methodReferences = new HashSet<MethodRef>(); 48 49 private HashSet<MethodRef> visitedMethods = new HashSet<MethodRef>(); 50 51 private Stack<MethodRef> callStack = new Stack<MethodRef>(); 52 53 private boolean result; 55 56 private HashSet<String > closure = new HashSet<String >(); 57 58 private Map<String , List<String >> failed = new HashMap<String , List<String >>(); 60 61 private static final String myClassName = "ASMClosureCompilerImpl"; 63 67 public ASMClosureCompilerImpl(ClassFileLoader loader) { 68 super(loader); 69 } 70 71 private void resetResult() { 72 logger.entering("ASMClosureCompilerImpl", "resetResult", new Object []{}); 74 result = true; 75 } 76 77 private void setResult(boolean newresult){ 78 result = result && newresult; 79 } 80 81 private boolean getResult() { 82 return result; 83 } 84 85 88 public boolean buildClosure(String className) { 89 logger.entering(myClassName, "buildClosure", className); resetResult(); if (needToBuildClosure(className)) { 92 visitedClasses.add(className); ClassFile cf = load(className); 94 if(cf==null){ 95 return false; 96 } 97 Collection<? extends Method> methods = cf.getMethods(); 100 for(Method next:methods){ 101 methodReferences.add(next.getSelfReference()); 102 buildClosure(next); 103 } 104 } 105 return getResult(); 106 } 107 108 private void buildClosure(Method m) { 109 MethodRef methodReference = m.getSelfReference(); 110 logger.entering("ASMClosureCompilerImpl", "buildClosure", new Object []{methodReference}); 112 callStack.push(methodReference); 113 if (needToBuildClosure(methodReference)) { 114 visitedMethods.add(methodReference); 115 Collection<MethodRef> methodRefs = m.getReferencedMethods(); 116 methodReferences.addAll(methodRefs); 117 for(MethodRef nextMethodRef : methodRefs) { 118 if (!needToBuildClosure(nextMethodRef)) continue; 119 ClassFile cf = load(Util.convertToExternalClassName 120 (nextMethodRef.getOwningClassName())); 121 if (cf == null) { 122 continue; } 124 Method nextMethod = cf.getMethod(nextMethodRef); 125 if(nextMethod==null){ 126 handleFailure(nextMethodRef); 127 continue; 128 } 129 buildClosure(nextMethod); } for(String className : m.getReferencedClasses()){ 134 String externalClassName = Util.convertToExternalClassName(className); 135 if(!needToBuildClosure(externalClassName)) continue; 136 load(externalClassName); 137 } 138 } 139 callStack.pop(); 140 } 141 142 155 protected ClassFile load(String className) { 156 logger.entering("ASMClosureCompilerImpl", "load", new Object []{className}); 158 ClassFile cf = null; 159 try{ 160 cf = loader.load(className); 161 }catch(IOException e){ 162 handleFailure(className); 163 } 164 if((cf!=null) && needToLoad(className)) { 165 closure.add(className); MethodRef clinitMethodRef = 167 new MethodRef(Util.convertToInternalClassName(className), 168 MethodRef.CLINIT_NAME, 169 MethodRef.CLINIT_DESC); 170 Method clinitMethod = cf.getMethod(clinitMethodRef); 171 try{ 172 callStack.push(clinitMethodRef); 175 String superClassName = cf.getNameOfSuperClass(); 176 if(superClassName!=null && needToBuildClosure(superClassName)) { load(superClassName); } 179 for(String interfaceClassName : cf.getNamesOfInterfaces()){ 180 if(needToBuildClosure(interfaceClassName)) { 181 load(interfaceClassName); } 183 } 184 }finally{ 185 callStack.pop(); 187 } 188 if(clinitMethod!=null) { 189 methodReferences.add(clinitMethodRef); 190 buildClosure(clinitMethod); } 192 } 193 logger.exiting("ASMClosureCompilerImpl", "load", cf==null?"null":cf.getName()); return cf; 195 } 196 197 private void handleFailure(MethodRef mr){ 198 logger.logp(Level.WARNING, "ASMClosureCompilerImpl", "handleFailure", 199 getClass().getName() + ".exception1", new Object []{mr.toString()}); 200 } 203 204 207 private void handleFailure(String referencedClass) { 208 logger.entering("ASMClosureCompilerImpl", "handleFailure", new Object []{referencedClass}); 210 setResult(false); 211 String referencingPath = ""; 212 try { 213 StringBuilder referencingPathBuffer = new StringBuilder (); 214 for (MethodRef m : callStack) { 215 if (referencingPathBuffer.length() != 0) 216 referencingPathBuffer.append("->"); referencingPathBuffer.append(m); 218 } 219 referencingPath = referencingPathBuffer.toString(); 220 } catch (EmptyStackException e) { 221 } 222 List<String > failedList = failed.get(referencingPath); 223 if (failedList == null) { 224 failedList = new ArrayList<String >(); 225 failed.put(referencingPath, failedList); 226 } 227 failedList.add(referencedClass); 228 } 229 230 233 public Collection getClosure() { 234 return Collections.unmodifiableCollection(methodReferences); 235 } 236 237 240 public Map getFailed() { 241 return Collections.unmodifiableMap(failed); 242 } 243 244 250 public void reset() { 251 methodReferences.clear(); 252 visitedClasses.clear(); 253 failed.clear(); 254 closure.clear(); 255 } 256 257 261 protected boolean needToLoad(String className) { 262 return !closure.contains(className); 263 } 264 265 protected boolean needToBuildClosure(MethodRef methodRef) { 266 boolean result = true; 267 final String owningClassName = methodRef.getOwningClassName(); 268 if (visitedMethods.contains(methodRef)) 269 result = false; 270 else if (excludedClasses.contains(owningClassName)) { 271 result = false; 272 } else if (excludedPackages.contains(getPackageName(owningClassName))) { 273 result = false; 274 } else { 275 for (Iterator i = excludedPatterns.iterator(); i.hasNext();) { 276 String pattern = (String ) i.next(); 277 if (owningClassName.startsWith(pattern)) { 278 result = false; 279 break; 280 } 281 } 282 } 283 logger.logp(Level.FINEST, myClassName, "needToBuildClosure", methodRef + " " + result); return result; 286 } 287 288 public String toString() { 290 StringBuilder sb=new StringBuilder (); 291 if(logger.isLoggable(Level.FINER)){ 292 sb.append("\n<Closure>"); 294 sb.append("\n\t<ExcludedClasses>"); for(Iterator i=excludedClasses.iterator(); i.hasNext();) { 296 sb.append("\n\t\t"); sb.append((String )i.next()); 298 } 299 sb.append("\n\t</ExcludedClasses>"); 301 sb.append("\n\t<ExcludedPackages>"); for(Iterator i=excludedPackages.iterator(); i.hasNext();){ 303 sb.append("\n\t\t"); sb.append((String )i.next()); 305 } 306 sb.append("\n\t</ExcludedPackages>"); 308 sb.append("\n\t<ExcludedPatterns>"); for(Iterator i=excludedPatterns.iterator(); i.hasNext();){ 310 sb.append("\n\t\t"); sb.append((String )i.next()); 312 } 313 sb.append("\n\t</ExcludedPatterns>"); 315 sb.append("\n\t<Methods>"); for(MethodRef m : methodReferences){ 317 sb.append("\n\t\t"); sb.append(m); 319 } 320 sb.append("\n\t</Methods>"); 322 sb.append("\n\t<Closure>"); for(String c : closure){ 324 sb.append("\n\t\t"); sb.append(c); 326 } 327 sb.append("\n\t</Closure>"); } 329 sb.append("\n\t<Failed>"); for(Iterator i=failed.entrySet().iterator(); i.hasNext();) { 331 Map.Entry referencingPathToFailedList=(Map.Entry)i.next(); 332 sb.append("\n\t\t"); sb.append("<ReferencingPath>"); sb.append("\n\t\t\t"); sb.append(referencingPathToFailedList.getKey()); 336 sb.append("\n\t\t"); sb.append("</ReferencingPath>"); sb.append("\n\t\t"); sb.append("<Classes>"); for(Iterator iii=((List)referencingPathToFailedList.getValue()).iterator(); iii.hasNext();){ 341 sb.append("\n\t\t\t"); sb.append((String )iii.next()); 343 } 344 sb.append("\n\t\t"); sb.append("</Classes>"); } 347 sb.append("\n\t</Failed>"); if(logger.isLoggable(Level.FINER)){ 349 sb.append("\n</Closure>"); } 351 return sb.toString(); 352 } 353 354 } 355 | Popular Tags |