/** * OpenSpotLight - Open Source IT Governance Platform * * Copyright (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA * or third-party contributors as indicated by the @author tags or express * copyright attribution statements applied by the authors. All third-party * contributions are distributed under license by CARAVELATECH CONSULTORIA E * TECNOLOGIA EM INFORMATICA LTDA. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA * *********************************************************************** * OpenSpotLight - Plataforma de Governança de TI de Código Aberto * * Direitos Autorais Reservados (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA * EM INFORMATICA LTDA ou como contribuidores terceiros indicados pela etiqueta * @author ou por expressa atribuição de direito autoral declarada e atribuída pelo autor. * Todas as contribuições de terceiros estão distribuídas sob licença da * CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA. * * Este programa é software livre; você pode redistribuí-lo e/ou modificá-lo sob os * termos da Licença Pública Geral Menor do GNU conforme publicada pela Free Software * Foundation. * * Este programa é distribuído na expectativa de que seja útil, porém, SEM NENHUMA * GARANTIA; nem mesmo a garantia implícita de COMERCIABILIDADE OU ADEQUAÇÃO A UMA * FINALIDADE ESPECÍFICA. Consulte a Licença Pública Geral Menor do GNU para mais detalhes. * * Você deve ter recebido uma cópia da Licença Pública Geral Menor do GNU junto com este * programa; se não, escreva para: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.openspotlight.bundle.language.java.asm; import org.objectweb.asm.ClassReader; import org.openspotlight.bundle.language.java.asm.model.TypeDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; /** * This class extracts from compiled artifacts all java types definitions. * * @see TypeDefinition * @author porcelli */ public class CompiledTypesExtractor { /** The LOG. */ private final Logger LOG = LoggerFactory.getLogger(CompiledTypesExtractor.class); /** * Generates a list of {@link TypeDefinition} based on a set of artifacts (.jar or .class files). * * @param artifacts the artifacts. Allowed artifacts: .jar and .class . * @return the java types */ public List<TypeDefinition> getJavaTypes( final InputStream inputStream, final String artifactName ) { int count = 0; final List<TypeDefinition> scannedTypes = new LinkedList<TypeDefinition>(); try { if (artifactName.endsWith(".jar")) { LOG.info(String.format("Opening JAR Artifact \"%s\".", artifactName)); // Open Zip file for reading final ZipInputStream zipStream = new ZipInputStream(inputStream); ZipEntry entry = null; // Process each entry while ((entry = zipStream.getNextEntry()) != null) { // extract file if not a directory if (!entry.isDirectory() && entry.getName().endsWith(".class")) { LOG.info(String.format("\tExtracting .class Type \"%s\".", entry.getName())); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); for (int c = zipStream.read(); c != -1; c = zipStream.read()) { baos.write(c); } baos.close(); final TypeDefinition type = processCompiledInputStream(new ByteArrayInputStream(baos.toByteArray())); zipStream.closeEntry(); count++; scannedTypes.add(type); } } LOG.info(String.format("Closing JAR Artifact \"%s\"", artifactName)); zipStream.close(); } else if (artifactName.endsWith(".class")) { LOG.info(String.format("Extracting .class Type \"%s\".", artifactName)); final TypeDefinition type = processCompiledInputStream(inputStream); count++; scannedTypes.add(type); } } catch (final Exception ex) { final StringWriter sWriter = new StringWriter(); ex.printStackTrace(new PrintWriter(sWriter)); LOG.error("Problems during parser - Stack trace:\n" + sWriter.getBuffer().toString()); } finally { LOG.info(String.format("Finished processing %d types.", count)); } return scannedTypes; } /** * Generates a list of {@link TypeDefinition} based on a set of artifacts (.jar or .class files). * * @param artifacts the artifacts. Allowed artifacts: .jar and .class . * @return the java types */ public List<TypeDefinition> getJavaTypes( final Set<File> artifacts ) { int count = 0; final List<TypeDefinition> scannedTypes = new LinkedList<TypeDefinition>(); try { for (final File activeArtifact : artifacts) { if (activeArtifact.getName().endsWith(".jar")) { LOG.info(String.format("Opening JAR Artifact \"%s\".", activeArtifact.getCanonicalFile())); // Open Zip file for reading final ZipFile zipFile = new ZipFile(activeArtifact, ZipFile.OPEN_READ); // Create an enumeration of the entries in the zip file final Enumeration<? extends ZipEntry> zipFileEntries = zipFile.entries(); // Process each entry while (zipFileEntries.hasMoreElements()) { // grab a zip file entry final ZipEntry entry = zipFileEntries.nextElement(); // extract file if not a directory if (!entry.isDirectory() && entry.getName().endsWith(".class")) { LOG.info(String.format("\tExtracting .class Type \"%s\".", entry.getName())); final TypeDefinition type = processCompiledInputStream(zipFile.getInputStream(entry)); count++; scannedTypes.add(type); } } LOG.info(String.format("Closing JAR Artifact \"%s\"", activeArtifact.getCanonicalFile())); zipFile.close(); } else if (activeArtifact.getName().endsWith(".class")) { LOG.info(String.format("Extracting .class Type \"%s\".", activeArtifact.getCanonicalPath())); final TypeDefinition type = processCompiledInputStream(new FileInputStream(activeArtifact)); count++; scannedTypes.add(type); } } } catch (final Exception ex) { final StringWriter sWriter = new StringWriter(); ex.printStackTrace(new PrintWriter(sWriter)); LOG.error("Problems during parser - Stack trace:\n" + sWriter.getBuffer().toString()); } finally { LOG.info(String.format("Finished processing %d types.", count)); } return scannedTypes; } /** * Process the compiled input stream using {@link TypeExtractorVisitor}. * * @param stream the stream * @return the type definition * @throws IOException Signals that an I/O exception has occurred. */ private TypeDefinition processCompiledInputStream( final InputStream stream ) throws IOException { final ClassReader reader = new ClassReader(stream); final TypeExtractorVisitor visitor = new TypeExtractorVisitor(); reader.accept(visitor, 0); stream.close(); return visitor.getType(); } }