1 4 package com.puppycrawl.tools.checkstyle.bcel; 5 6 import java.io.File ; 7 import java.io.IOException ; 8 import java.io.InputStream ; 9 import java.util.Enumeration ; 10 import java.util.HashMap ; 11 import java.util.HashSet ; 12 import java.util.Iterator ; 13 import java.util.Set ; 14 import java.util.zip.ZipEntry ; 15 import java.util.zip.ZipFile ; 16 17 import org.apache.bcel.Repository; 18 import org.apache.bcel.classfile.ClassParser; 19 import org.apache.bcel.classfile.JavaClass; 20 import org.apache.bcel.classfile.Visitor; 21 import org.apache.bcel.util.ClassLoaderRepository; 22 import com.puppycrawl.tools.checkstyle.DefaultContext; 23 import com.puppycrawl.tools.checkstyle.ModuleFactory; 24 import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck; 25 import com.puppycrawl.tools.checkstyle.api.CheckstyleException; 26 import com.puppycrawl.tools.checkstyle.api.Configuration; 27 import com.puppycrawl.tools.checkstyle.api.Context; 28 import com.puppycrawl.tools.checkstyle.api.LocalizedMessage; 29 import com.puppycrawl.tools.checkstyle.api.LocalizedMessages; 30 31 35 public class ClassFileSetCheck 37 extends AbstractFileSetCheck 38 implements IObjectSetVisitor 39 { 40 41 private final Set mTreeVisitors = new HashSet (); 42 43 44 private final Set mAllChecks = new HashSet (); 45 46 47 private final Set mObjectSetVisitors = new HashSet (); 48 49 50 private ClassLoader mClassLoader; 51 52 53 private Context mChildContext; 54 55 56 private ModuleFactory mModuleFactory; 57 58 59 HashMap mMessageMap = new HashMap (); 60 61 65 public ClassFileSetCheck() 66 { 67 setFileExtensions(new String []{"class", "jar", "zip"}); 68 } 69 70 74 public void setClassLoader(ClassLoader aClassLoader) 75 { 76 Repository.setRepository(new ClassLoaderRepository(aClassLoader)); 77 mClassLoader = aClassLoader; 78 } 79 80 84 public void setModuleFactory(ModuleFactory aModuleFactory) 85 { 86 mModuleFactory = aModuleFactory; 87 } 88 89 94 public void setupChild(Configuration aChildConf) 95 throws CheckstyleException 96 { 97 final String name = aChildConf.getName(); 99 final Object module = mModuleFactory.createModule(name); 100 if (!(module instanceof AbstractCheckVisitor)) { 101 throw new CheckstyleException( 102 "ClassFileSet is not allowed as a parent of " + name); 103 } 104 final AbstractCheckVisitor c = (AbstractCheckVisitor) module; 105 c.contextualize(mChildContext); 106 c.configure(aChildConf); 107 c.init(); 108 109 registerCheck(c); 110 } 111 112 113 public void finishLocalSetup() 114 { 115 DefaultContext checkContext = new DefaultContext(); 116 checkContext.add("classLoader", mClassLoader); 117 checkContext.add("messageMap", mMessageMap); 118 checkContext.add("severity", getSeverity()); 119 120 mChildContext = checkContext; 121 } 122 123 127 private void registerCheck(AbstractCheckVisitor aCheck) 128 { 129 mAllChecks.add(aCheck); 130 } 131 132 135 public void process(File [] aFiles) 136 { 137 registerVisitors(); 138 139 final Set javaClasses = extractJavaClasses(aFiles); 141 142 visitSet(javaClasses); 143 144 final JavaClassWalker walker = new JavaClassWalker(); 146 walker.setVisitor(getTreeVisitor()); 147 final Iterator it = javaClasses.iterator(); 148 while (it.hasNext()) { 149 final JavaClass clazz = (JavaClass) it.next(); 150 visitObject(clazz); 151 walker.walk(clazz); 152 leaveObject(clazz); 153 } 154 155 leaveSet(javaClasses); 156 fireErrors(); 157 } 158 159 163 private Visitor getTreeVisitor() 164 { 165 return new VisitorSet(mTreeVisitors); 166 } 167 168 172 private void registerVisitors() 173 { 174 mObjectSetVisitors.addAll(mAllChecks); 175 final Iterator it = mAllChecks.iterator(); 176 while (it.hasNext()) { 177 final AbstractCheckVisitor check = (AbstractCheckVisitor) it.next(); 178 final IDeepVisitor visitor = check.getVisitor(); 179 mObjectSetVisitors.add(visitor); 180 mTreeVisitors.add(visitor); 181 } 182 } 183 184 188 private Set getObjectSetVisitors() 189 { 190 return mObjectSetVisitors; 191 } 192 193 198 private Set extractJavaClasses(File [] aFiles) 199 { 200 final Set result = new HashSet (); 201 final File [] classFiles = filter(aFiles); 202 for (int i = 0; i < classFiles.length; i++) { 204 try { 205 final Set extracted = extractJavaClasses(classFiles[i]); 206 result.addAll(extracted); 207 } 208 catch (IOException e) { 209 e.printStackTrace(); 211 } 212 } 213 return result; 214 } 215 216 217 public void visitSet(Set aSet) 218 { 219 Repository.clearCache(); 221 Iterator it = aSet.iterator(); 222 while (it.hasNext()) { 223 final JavaClass javaClass = (JavaClass) it.next(); 224 Repository.addClass(javaClass); 225 } 226 227 it = getObjectSetVisitors().iterator(); 229 while (it.hasNext()) { 230 final IObjectSetVisitor visitor = (IObjectSetVisitor) it.next(); 231 visitor.visitSet(aSet); 232 } 233 } 234 235 236 public void visitObject(Object aObject) 237 { 238 final Iterator it = getObjectSetVisitors().iterator(); 239 while (it.hasNext()) { 240 final IObjectSetVisitor visitor = (IObjectSetVisitor) it.next(); 241 visitor.visitObject(aObject); 242 } 243 } 244 245 246 public void leaveObject(Object aObject) 247 { 248 final Iterator it = getObjectSetVisitors().iterator(); 249 while (it.hasNext()) { 250 final IObjectSetVisitor visitor = (IObjectSetVisitor) it.next(); 251 visitor.leaveObject(aObject); 252 } 253 } 254 255 256 public void leaveSet(Set aSet) 257 { 258 final Iterator it = getObjectSetVisitors().iterator(); 259 while (it.hasNext()) { 260 final IObjectSetVisitor visitor = (IObjectSetVisitor) it.next(); 261 visitor.leaveSet(aSet); 262 } 263 } 264 265 271 private Set extractJavaClasses(File aFile) 272 throws IOException 273 { 274 final Set result = new HashSet (); 275 final String fileName = aFile.getPath(); 276 if (fileName.endsWith(".jar") || fileName.endsWith(".zip")) { 277 final ZipFile zipFile = new ZipFile (fileName); 278 final Enumeration entries = zipFile.entries(); 279 while (entries.hasMoreElements()) { 280 final ZipEntry entry = (ZipEntry ) entries.nextElement(); 281 final String entryName = entry.getName(); 282 if (entryName.endsWith(".class")) { 283 final InputStream in = zipFile.getInputStream(entry); 284 final JavaClass javaClass = 285 new ClassParser(in, entryName).parse(); 286 result.add(javaClass); 287 } 288 } 289 } 290 else { 291 final JavaClass javaClass = new ClassParser(fileName).parse(); 292 result.add(javaClass); 293 } 294 return result; 295 } 296 297 302 private void fireErrors() 303 { 304 Set keys = mMessageMap.keySet(); 305 Iterator iter = keys.iterator(); 306 while (iter.hasNext()) { 307 String key = (String ) iter.next(); 308 getMessageDispatcher().fireFileStarted(key); 309 LocalizedMessages localizedMessages = (LocalizedMessages) mMessageMap.get(key); 310 final LocalizedMessage[] errors = localizedMessages.getMessages(); 311 localizedMessages.reset(); 312 getMessageDispatcher().fireErrors(key, errors); 313 getMessageDispatcher().fireFileFinished(key); 314 } 315 } 316 317 } 318 | Popular Tags |