You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jo...@apache.org on 2008/03/11 05:07:31 UTC

svn commit: r635796 [2/7] - in /maven/sandbox/trunk/archiva/archiva-jarinfo: ./ archiva-jarinfo-bundles/ archiva-jarinfo-cli/ archiva-jarinfo-cli/src/ archiva-jarinfo-cli/src/assembly/ archiva-jarinfo-cli/src/main/ archiva-jarinfo-cli/src/main/java/ ar...

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/DefaultPathParser.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/DefaultPathParser.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/DefaultPathParser.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/DefaultPathParser.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,201 @@
+package org.apache.maven.archiva.repository.content;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.common.utils.VersionUtil;
+
+/**
+ * DefaultPathParser is a parser for maven 2 (default layout) paths to ArtifactRef. 
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class DefaultPathParser
+{
+    private static final String INVALID_ARTIFACT_PATH = "Invalid path to Artifact: ";
+
+    /**
+     * Convert a path to an ArtifactRef. 
+     * 
+     * @param path
+     * @return
+     * @throws ArtifactException
+     */
+    public static ArtifactRef toArtifactRef( String path )
+        throws ArtifactException
+    {
+        if ( StringUtils.isBlank( path ) )
+        {
+            throw new ArtifactException( "Unable to convert blank path." );
+        }
+
+        ArtifactRef artifact = new ArtifactRef();
+
+        String normalizedPath = StringUtils.replace( path, "\\", "/" );
+        String pathParts[] = StringUtils.split( normalizedPath, '/' );
+
+        /* Minimum parts.
+         *
+         *   path = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"
+         *   path[0] = "commons-lang";        // The Group ID
+         *   path[1] = "commons-lang";        // The Artifact ID
+         *   path[2] = "2.1";                 // The Version
+         *   path[3] = "commons-lang-2.1.jar" // The filename.
+         */
+
+        if ( pathParts.length < 4 )
+        {
+            // Illegal Path Parts Length.
+            throw new ArtifactException( "Not enough parts to the path [" + path
+                + "] to construct an ArchivaArtifact from. (Requires at least 4 parts)" );
+        }
+
+        // Maven 2.x path.
+        int partCount = pathParts.length;
+        int filenamePos = partCount - 1;
+        int baseVersionPos = partCount - 2;
+        int artifactIdPos = partCount - 3;
+        int groupIdPos = partCount - 4;
+
+        // Second to last is the baseVersion (the directory version)
+        String baseVersion = pathParts[baseVersionPos];
+
+        // Third to last is the artifact Id.
+        artifact.setArtifactId( pathParts[artifactIdPos] );
+
+        // Remaining pieces are the groupId.
+        for ( int i = 0; i <= groupIdPos; i++ )
+        {
+            if ( i == 0 )
+            {
+                artifact.setGroupId( pathParts[i] );
+            }
+            else
+            {
+                artifact.setGroupId( artifact.getGroupId() + "." + pathParts[i] );
+            }
+        }
+
+        try
+        {
+            // Last part is the filename
+            String filename = pathParts[filenamePos];
+
+            // Now we need to parse the filename to get the artifact version Id.
+            if ( StringUtils.isBlank( filename ) )
+            {
+                throw new IllegalArgumentException( INVALID_ARTIFACT_PATH + "Unable to split blank filename." );
+            }
+
+            FilenameParser parser = new FilenameParser( filename );
+
+            // Expect the filename to start with the artifactId.
+            artifact.setArtifactId( parser.expect( artifact.getArtifactId() ) );
+
+            if ( artifact.getArtifactId() == null )
+            {
+                throw new ArtifactException( INVALID_ARTIFACT_PATH + "filename format is invalid, "
+                    + "should start with artifactId as stated in path." );
+            }
+
+            // Process the version.
+            artifact.setVersion( parser.expect( baseVersion ) );
+
+            if ( artifact.getVersion() == null )
+            {
+                // We working with a snapshot?
+                if ( VersionUtil.isSnapshot( baseVersion ) )
+                {
+                    artifact.setVersion( parser.nextVersion() );
+                    if ( !VersionUtil.isUniqueSnapshot( artifact.getVersion() ) )
+                    {
+                        throw new ArtifactException( INVALID_ARTIFACT_PATH + "filename format is invalid,"
+                            + "expected timestamp format in filename." );
+                    }
+                }
+                else
+                {
+                    throw new ArtifactException( INVALID_ARTIFACT_PATH + "filename format is invalid, "
+                        + "expected version as stated in path." );
+                }
+            }
+
+            // Do we have a classifier?
+            switch(parser.seperator())
+            {
+                case '-':
+                    // Definately a classifier.
+                    artifact.setClassifier( parser.remaining() );
+                    
+                    // Set the type.
+                    artifact.setType( ArtifactExtensionMapping.guessTypeFromFilename( filename ) );
+                    break;
+                case '.':
+                    // We have an dual extension possibility.
+                    String extension = parser.remaining() + '.' + parser.getExtension();
+                    artifact.setType( extension.replace( '.', '-' ) );
+                    break;
+                case 0:
+                    // End of the filename, only a simple extension left. - Set the type.
+                    artifact.setType( ArtifactExtensionMapping.guessTypeFromFilename( filename ) );
+                    break;
+            }
+            
+            // Special case for maven plugins
+            if ( StringUtils.equals( "jar", artifact.getType() ) && 
+                 ArtifactExtensionMapping.isMavenPlugin( artifact.getArtifactId() ) )
+            {
+                artifact.setType( ArtifactExtensionMapping.MAVEN_PLUGIN );
+            }
+        }
+        catch ( ArtifactException e )
+        {
+            throw e;
+        }
+
+        // Sanity Checks.
+
+        // Do we have a snapshot version?
+        if ( VersionUtil.isSnapshot( artifact.getVersion() ) )
+        {
+            // Rules are different for SNAPSHOTS
+            if ( !VersionUtil.isGenericSnapshot( baseVersion ) )
+            {
+                String filenameBaseVersion = VersionUtil.getBaseVersion( artifact.getVersion() );
+                throw new ArtifactException( "Invalid snapshot artifact location, version directory should be "
+                    + filenameBaseVersion );
+            }
+        }
+        else
+        {
+            // Non SNAPSHOT rules.
+            // Do we pass the simple test?
+            if ( !StringUtils.equals( baseVersion, artifact.getVersion() ) )
+            {
+                throw new ArtifactException( "Invalid artifact: version declared in directory path does"
+                    + " not match what was found in the artifact filename." );
+            }
+        }
+
+        return artifact;
+    }
+    
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/DefaultPathParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/DefaultPathParser.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/FilenameParser.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/FilenameParser.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/FilenameParser.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/FilenameParser.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,234 @@
+package org.apache.maven.archiva.repository.content;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.archiva.common.utils.VersionUtil;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Generic Filename Parser for use with layout routines.
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class FilenameParser
+{
+    private String name;
+
+    private String extension;
+
+    private int offset;
+
+    private static final Pattern mavenPluginPattern = Pattern.compile( "(maven-.*-plugin)|(.*-maven-plugin)" );
+
+    private static final Pattern extensionPattern = Pattern.compile( "(.tar.gz$)|(.tar.bz2$)|(.[a-z0-9]{1,4}$)",
+                                                                     Pattern.CASE_INSENSITIVE );
+
+    private static final Pattern section = Pattern.compile( "([^-]*)" );
+
+    private Matcher matcher;
+
+    protected FilenameParser( String filename )
+    {
+        this.name = filename;
+
+        Matcher mat = extensionPattern.matcher( name );
+        if ( mat.find() )
+        {
+            extension = filename.substring( mat.start() + 1 );
+            name = name.substring( 0, name.length() - extension.length() - 1 );
+        }
+
+        matcher = section.matcher( name );
+
+        reset();
+    }
+
+    protected void reset()
+    {
+        offset = 0;
+    }
+
+    protected String next()
+    {
+        // Past the end of the string.
+        if ( offset > name.length() )
+        {
+            return null;
+        }
+
+        // Return the next section.
+        if ( matcher.find( offset ) )
+        {
+            // Return found section.
+            offset = matcher.end() + 1;
+            return matcher.group();
+        }
+
+        // Nothing to return.
+        return null;
+    }
+
+    protected String expect( String expected )
+    {
+        if ( name.startsWith( expected, offset ) )
+        {
+            // Potential hit. check for '.' or '-' at end of expected.
+            int seperatorOffset = offset + expected.length();
+
+            // Test for "out of bounds" first. 
+            if ( seperatorOffset >= name.length() )
+            {
+                offset = name.length();
+                return expected;
+            }
+
+            // Test for seperator char.
+            char seperatorChar = name.charAt( seperatorOffset );
+            if ( ( seperatorChar == '-' ) || ( seperatorChar == '.' ) )
+            {
+                offset = seperatorOffset + 1;
+                return expected;
+            }
+        }
+
+        return null;
+    }
+    
+    /**
+     * Get the current seperator character.
+     * 
+     * @return the seperator character (either '.' or '-'), or 0 if no seperator character available.
+     */
+    protected char seperator()
+    {
+        // Past the end of the string?
+        if ( offset >= name.length() )
+        {
+            return 0;
+        }
+
+        // Before the start of the string?
+        if ( offset <= 0 )
+        {
+            return 0;
+        }
+
+        return name.charAt( offset - 1 );
+    }
+
+    protected String getName()
+    {
+        return name;
+    }
+
+    protected String getExtension()
+    {
+        return extension;
+    }
+
+    protected String remaining()
+    {
+        if ( offset >= name.length() )
+        {
+            return null;
+        }
+
+        String end = name.substring( offset );
+        offset = name.length();
+        return end;
+    }
+
+    protected String nextNonVersion()
+    {
+        boolean done = false;
+
+        StringBuffer ver = new StringBuffer();
+
+        // Any text upto the end of a special case is considered non-version. 
+        Matcher specialMat = mavenPluginPattern.matcher( name );
+        if ( specialMat.find() )
+        {
+            ver.append( name.substring( offset, specialMat.end() ) );
+            offset = specialMat.end() + 1;
+        }
+
+        while ( !done )
+        {
+            int initialOffset = offset;
+            String section = next();
+            if ( section == null )
+            {
+                done = true;
+            }
+            else if ( !VersionUtil.isVersion( section ) )
+            {
+                if ( ver.length() > 0 )
+                {
+                    ver.append( '-' );
+                }
+                ver.append( section );
+            }
+            else
+            {
+                offset = initialOffset;
+                done = true;
+            }
+        }
+
+        return ver.toString();
+    }
+
+    protected String nextVersion()
+    {
+        boolean done = false;
+
+        StringBuffer ver = new StringBuffer();
+
+        while ( !done )
+        {
+            int initialOffset = offset;
+            String section = next();
+            if ( section == null )
+            {
+                done = true;
+            }
+            else if ( VersionUtil.isVersion( section ) )
+            {
+                if ( ver.length() > 0 )
+                {
+                    ver.append( '-' );
+                }
+                ver.append( section );
+            }
+            else
+            {
+                offset = initialOffset;
+                done = true;
+            }
+        }
+
+        return ver.toString();
+    }
+
+    
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/FilenameParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-cli/src/main/java/org/apache/maven/archiva/repository/content/FilenameParser.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon Mar 10 21:07:17 2008
@@ -0,0 +1,21 @@
+target
+*~
+.*.swp
+*.log
+*.patch
+*.diff
+*.ipr
+*.iws
+*.iml
+.classpath
+.project
+.settings
+.m2eclipse
+.wtpmodules
+.xdoclet
+*.ipr
+*.iws
+*.iml
+CVS
+cobertura.ser
+jcoverage.ser

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/pom.xml
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/pom.xml?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/pom.xml (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/pom.xml Mon Mar 10 21:07:17 2008
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2006 The Codehaus.
+  ~ 
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~ 
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~ 
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.maven.archiva</groupId>
+    <artifactId>archiva-jarinfo-parent</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>archiva-jarinfo-lib</artifactId>
+  <name>Archiva Jar Info Lib</name>
+
+  <packaging>jar</packaging>
+
+  <dependencies>
+    <dependency>
+      <groupId>dom4j</groupId>
+      <artifactId>dom4j</artifactId>
+      <version>1.6.1</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>1.3.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.bcel</groupId>
+      <artifactId>bcel</artifactId>
+      <version>5.2</version>
+    </dependency>
+  </dependencies>
+</project>

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/pom.xml
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/JarInfoException.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/JarInfoException.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/JarInfoException.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/JarInfoException.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,21 @@
+package org.apache.maven.archiva.jarinfo;
+
+/**
+ * JarInfoException 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class JarInfoException
+    extends Exception
+{
+    public JarInfoException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public JarInfoException( String message )
+    {
+        super( message );
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/JarInfoException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/JarInfoException.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/Hasher.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/Hasher.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/Hasher.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/Hasher.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,97 @@
+package org.apache.maven.archiva.jarinfo.analysis;
+
+import org.apache.maven.archiva.jarinfo.utils.Hex;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+/**
+ * Hasher - simple hashing routines. 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class Hasher
+{
+    protected final MessageDigest md;
+
+    public static final String MD5 = "md5";
+
+    public static final String SHA1 = "sha-1";
+
+    private static final int BUFFER_SIZE = 32768;
+    
+    private String algorithm;
+
+    public Hasher( String algorithm )
+    {
+        this.algorithm = algorithm;
+        try
+        {
+            md = MessageDigest.getInstance( algorithm );
+        }
+        catch ( NoSuchAlgorithmException e )
+        {
+            throw new IllegalStateException( "Unable to initialize MessageDigest algorithm " + algorithm + " : "
+                + e.getMessage(), e );
+        }
+    }
+
+    public Hasher update( InputStream stream )
+        throws IOException
+    {
+        byte[] buffer = new byte[BUFFER_SIZE];
+        int size = stream.read( buffer, 0, BUFFER_SIZE );
+        while ( size >= 0 )
+        {
+            md.update( buffer, 0, size );
+            size = stream.read( buffer, 0, BUFFER_SIZE );
+        }
+
+        return this;
+    }
+
+    public Hasher update( byte[] buffer, int offset, int size )
+    {
+        md.update( buffer, 0, size );
+        return this;
+    }
+
+    public static void update( List<Hasher> hashers, InputStream stream )
+        throws IOException
+    {
+        byte[] buffer = new byte[BUFFER_SIZE];
+        int size = stream.read( buffer, 0, BUFFER_SIZE );
+        while ( size >= 0 )
+        {
+            for ( Hasher hasher : hashers )
+            {
+                hasher.update( buffer, 0, size );
+            }
+            size = stream.read( buffer, 0, BUFFER_SIZE );
+        }
+    }
+
+    public void reset()
+    {
+        md.reset();
+    }
+
+    public String getHash()
+    {
+        return Hex.encode( md.digest() );
+    }
+
+    public String getAlgorithm()
+    {
+        return algorithm;
+    }
+
+    public void setAlgorithm( String algorithm )
+    {
+        this.algorithm = algorithm;
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/Hasher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/Hasher.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/IdentificationWeights.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/IdentificationWeights.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/IdentificationWeights.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/IdentificationWeights.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,84 @@
+package org.apache.maven.archiva.jarinfo.analysis;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * IdentificationWeights 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class IdentificationWeights
+{
+    /* singleton */
+    private static final IdentificationWeights _INSTANCE = new IdentificationWeights();
+
+    public static IdentificationWeights getInstance()
+    {
+        return _INSTANCE;
+    }
+
+    private Map<String, Integer> weights = new HashMap<String, Integer>();
+
+    /* TODO Load from resource.
+     * TODO Allow overwrite from runtime.
+     */
+
+    public IdentificationWeights()
+    {
+        try
+        {
+            URL url = this.getClass().getResource( "idweights.properties" );
+            if ( url == null )
+            {
+                // TODO log error.
+                return;
+            }
+            Properties props = new Properties();
+            props.load( url.openStream() );
+
+            Iterator<?> it = props.keySet().iterator();
+            while ( it.hasNext() )
+            {
+                String key = (String) it.next();
+                Integer weight = toWeight( props.getProperty( key ) );
+                if ( weight != null )
+                {
+                    weights.put( key, weight );
+                }
+            }
+        }
+        catch ( IOException e )
+        {
+            // TODO log error
+        }
+    }
+
+    private Integer toWeight( String val )
+    {
+        try
+        {
+            return Integer.valueOf( val );
+        }
+        catch ( NumberFormatException e )
+        {
+            return null;
+        }
+    }
+
+    public int getWeight( String key )
+    {
+        Integer weight = weights.get( key );
+        if ( weight == null )
+        {
+            // TODO log complaint 
+            return 1;
+        }
+        return weight.intValue();
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/IdentificationWeights.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/IdentificationWeights.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarAnalysis.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarAnalysis.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarAnalysis.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarAnalysis.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,243 @@
+package org.apache.maven.archiva.jarinfo.analysis;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.archiva.jarinfo.analysis.visitors.EntryClassAnalyzer;
+import org.apache.maven.archiva.jarinfo.analysis.visitors.EntryHasher;
+import org.apache.maven.archiva.jarinfo.analysis.visitors.EntryManifest;
+import org.apache.maven.archiva.jarinfo.analysis.visitors.EntrySizer;
+import org.apache.maven.archiva.jarinfo.analysis.visitors.IdentificationEmbeddedMavenProperties;
+import org.apache.maven.archiva.jarinfo.analysis.visitors.IdentificationFilename;
+import org.apache.maven.archiva.jarinfo.analysis.visitors.IdentificationTimestamps;
+import org.apache.maven.archiva.jarinfo.model.EntryDetail;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+import org.apache.maven.archiva.jarinfo.utils.EntryDetailComparator;
+import org.apache.maven.archiva.jarinfo.utils.NaturalLanguageComparator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * JarAnalysis - takes a jar file, analyzes it, and creates a JarDetails model. 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class JarAnalysis
+{
+    private List<JarEntryVisitor> visitors;
+
+    private boolean performInspection = true;
+
+    /**
+     * Setup the JarAnalysis engine.
+     * 
+     * @param performInspection true to perform inspection (and populate the {@link JarDetails#getInspectedIds()} field.
+     */
+    public JarAnalysis( boolean performInspection )
+    {
+        this.performInspection = performInspection;
+
+        visitors = new ArrayList<JarEntryVisitor>();
+        addDefaultVisitors();
+    }
+
+    public void addDefaultVisitors()
+    {
+        visitors.add( new EntryManifest() );
+        visitors.add( new EntryHasher() );
+        visitors.add( new EntrySizer() );
+        visitors.add( new EntryClassAnalyzer( this.performInspection ) );
+        visitors.add( new IdentificationEmbeddedMavenProperties( this.performInspection ) );
+
+        if ( this.performInspection )
+        {
+            visitors.add( new IdentificationFilename() );
+            visitors.add( new IdentificationTimestamps() );
+        }
+    }
+
+    public JarDetails analyze( File file )
+        throws IOException
+    {
+        JarDetails details = new JarDetails();
+
+        details.getGenerator().setName( "archiva-jarinfo" );
+        details.getGenerator().setVersion( getVersion() );
+        details.getGenerator().setTimestamp( Calendar.getInstance( TimeZone.getTimeZone( "GMT" ) ) );
+
+        basics( file, details );
+        hashcodes( details, file );
+
+        JarFile jar = new JarFile( file );
+        try
+        {
+            processEntries( details, jar );
+        }
+        finally
+        {
+            jar.close();
+        }
+
+        return details;
+    }
+
+    public String getVersion()
+    {
+        // TODO: Discover the version from the jar pom.properties.
+        return "1.0";
+    }
+
+    /**
+     * Populate the full file hashcodes
+     * @throws IOException 
+     */
+    private void hashcodes( JarDetails details, File file )
+        throws IOException
+    {
+        Hasher md5Hasher = new Hasher( Hasher.MD5 );
+        Hasher sha1Hasher = new Hasher( Hasher.SHA1 );
+
+        FileInputStream fileStream = null;
+        try
+        {
+            fileStream = new FileInputStream( file );
+            List<Hasher> fullHashers = new ArrayList<Hasher>();
+            fullHashers.add( md5Hasher );
+            fullHashers.add( sha1Hasher );
+
+            // Read file once for all full hashers.
+            Hasher.update( fullHashers, fileStream );
+
+            details.setHash( md5Hasher.getAlgorithm(), md5Hasher.getHash() );
+            details.setHash( sha1Hasher.getAlgorithm(), sha1Hasher.getHash() );
+        }
+        finally
+        {
+            IOUtils.closeQuietly( fileStream );
+        }
+    }
+
+    /**
+     * Populate the basics.
+     */
+    private void basics( File file, JarDetails details )
+    {
+        details.setFilename( file.getName() );
+        details.setSize( file.length() );
+
+        // Get file date in system timezone format.
+        Calendar cal = Calendar.getInstance();
+        cal.setTimeInMillis( file.lastModified() );
+
+        // Adjust to UTC
+        cal.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
+
+        // Set to details obj
+        details.setTimestamp( cal );
+    }
+
+    /**
+     * Process the jar file entries
+     */
+    private void processEntries( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        // Entry names
+        List<String> entryNames = new ArrayList<String>();
+
+        // Gather up entry names, and sort.
+        Enumeration<JarEntry> en = jar.entries();
+        while ( en.hasMoreElements() )
+        {
+            JarEntry entry = en.nextElement();
+            entryNames.add( entry.getName() );
+        }
+
+        Collections.sort( entryNames, new NaturalLanguageComparator() );
+
+        // Process entries.
+        for ( JarEntryVisitor visitor : visitors )
+        {
+            visitor.visitStart( details, jar );
+        }
+
+        for ( String name : entryNames )
+        {
+            JarEntry jarEntry = jar.getJarEntry( name );
+            EntryDetail entry = new EntryDetail();
+            entry.setName( jarEntry.getName() );
+
+            Calendar cal = Calendar.getInstance();
+            cal.setTimeInMillis( jarEntry.getTime() );
+            entry.setTimestamp( cal );
+            entry.setDirectory( jarEntry.isDirectory() );
+
+            for ( JarEntryVisitor visitor : visitors )
+            {
+                visitor.visitJarEntry( entry, jarEntry );
+            }
+
+            // Add entry.
+            details.addEntry( entry );
+        }
+
+        Collections.sort( details.getEntries(), new EntryDetailComparator() );
+
+        for ( JarEntryVisitor visitor : visitors )
+        {
+            visitor.visitFinished( details, jar );
+        }
+    }
+
+    public List<JarEntryVisitor> getVisitors()
+    {
+        return visitors;
+    }
+
+    public void setVisitors( List<JarEntryVisitor> visitors )
+    {
+        this.visitors = visitors;
+    }
+
+    public boolean isPerformingInspection()
+    {
+        return performInspection;
+    }
+
+    /**
+     * Sets the <code>performInspection</code> flag.
+     * NOTE: Setting this value will reset the {@link #getVisitors()} to default values.
+     * 
+     * @param performInspection true to perform inspection (and populate the {@link JarDetails#getInspectedIds()} field.
+     */
+    public void setPerformInspection( boolean performInspection )
+    {
+        this.performInspection = performInspection;
+        visitors.clear();
+        addDefaultVisitors();
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarAnalysis.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarAnalysis.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarEntryVisitor.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarEntryVisitor.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarEntryVisitor.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarEntryVisitor.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,26 @@
+package org.apache.maven.archiva.jarinfo.analysis;
+
+import org.apache.maven.archiva.jarinfo.model.EntryDetail;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+
+import java.io.IOException;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * Visitor Interface for JarEntry(s) 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface JarEntryVisitor
+{
+    public void visitStart( JarDetails details, JarFile jar )
+        throws IOException;
+
+    public void visitJarEntry( EntryDetail entry, JarEntry jarEntry )
+        throws IOException;
+
+    public void visitFinished( JarDetails details, JarFile jar )
+        throws IOException;
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarEntryVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/JarEntryVisitor.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/AbstractJarEntryVisitor.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/AbstractJarEntryVisitor.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/AbstractJarEntryVisitor.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/AbstractJarEntryVisitor.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,44 @@
+package org.apache.maven.archiva.jarinfo.analysis.visitors;
+
+import org.apache.maven.archiva.jarinfo.analysis.JarEntryVisitor;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+
+import java.io.IOException;
+import java.util.jar.JarFile;
+
+/**
+ * AbstractJarEntryVisitor 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public abstract class AbstractJarEntryVisitor
+    implements JarEntryVisitor
+{
+    protected JarDetails details;
+
+    protected JarFile jar;
+
+    public void visitStart( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        this.details = details;
+        this.jar = jar;
+    }
+
+    public void visitFinished( JarDetails finishDetails, JarFile finishJar )
+        throws IOException
+    {
+        if ( !finishDetails.getFilename().equals( this.details.getFilename() ) )
+        {
+            throw new IllegalStateException( "Encountered finish for different details. started as ["
+                + this.details.getFilename() + "], finished as [" + finishDetails.getFilename() + "]" );
+        }
+
+        if ( !finishJar.getName().equals( this.jar.getName() ) )
+        {
+            throw new IllegalStateException( "Encountered finish for different details. started as ["
+                + this.jar.getName() + "], finished as [" + finishJar.getName() + "]" );
+        }
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/AbstractJarEntryVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/AbstractJarEntryVisitor.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/BCELImportVisitor.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/BCELImportVisitor.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/BCELImportVisitor.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/BCELImportVisitor.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,168 @@
+package org.apache.maven.archiva.jarinfo.analysis.visitors;
+
+import org.apache.bcel.classfile.ConstantClass;
+import org.apache.bcel.classfile.ConstantUtf8;
+import org.apache.bcel.classfile.EmptyVisitor;
+import org.apache.bcel.classfile.JavaClass;
+
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * BCELImportVisitor 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class BCELImportVisitor
+extends EmptyVisitor
+{
+    /**
+     * The list of imports discovered.
+     */
+    private Set<String> imports;
+
+    /**
+     * The Java class that is being analyzed.
+     */
+    private JavaClass javaClass;
+
+    /**
+     * Pattern to detect if the import is qualified and allows retrieval of the actual import name from the string via the group 1.
+     */
+    private static final Pattern QUALIFIED_IMPORT_PATTERN = Pattern.compile( "L([a-zA-Z][a-zA-Z0-9\\.]+);" );
+
+    /**
+     * Pattern that checks whether a string is valid UTF-8. Imports that are not are ignored.
+     */
+    private static final Pattern VALID_UTF8_PATTERN = Pattern.compile( "^[\\(\\)\\[A-Za-z0-9;/]+$" );
+
+    /**
+     * Create an Import visitor.
+     *
+     * @param javaClass the javaclass to work from
+     */
+    public BCELImportVisitor( JavaClass javaClass )
+    {
+        this.javaClass = javaClass;
+        this.imports = new TreeSet<String>();
+    }
+
+    /**
+     * Get the list of discovered imports.
+     *
+     * @return Returns the imports.
+     */
+    public Set<String> getImports()
+    {
+        return imports;
+    }
+
+    /**
+     * Find any formally declared import in the Constant Pool.
+     *
+     * @see org.apache.bcel.classfile.EmptyVisitor#visitConstantClass(org.apache.bcel.classfile.ConstantClass)
+     */
+    public void visitConstantClass( ConstantClass constantClass )
+    {
+        String name = constantClass.getBytes( javaClass.getConstantPool() );
+
+        // only strings with '/' character are to be considered.
+        if ( name.indexOf( '/' ) == -1 )
+        {
+            return;
+        }
+
+        name = name.replace( '/', '.' );
+
+        if ( name.endsWith( ".class" ) )
+        {
+            name = name.substring( 0, name.length() - 6 );
+        }
+
+        Matcher mat = QUALIFIED_IMPORT_PATTERN.matcher( name );
+        if ( mat.find() )
+        {
+            this.imports.add( mat.group( 1 ) );
+        }
+        else
+        {
+            this.imports.add( name );
+        }
+    }
+
+    /**
+     * Find any package class Strings in the UTF8 String Pool.
+     *
+     * @see org.apache.bcel.classfile.EmptyVisitor#visitConstantUtf8(org.apache.bcel.classfile.ConstantUtf8)
+     */
+    public void visitConstantUtf8( ConstantUtf8 constantUtf8 )
+    {
+        String ret = constantUtf8.getBytes().trim();
+
+        // empty strings are not class names.
+        if ( ret.length() <= 0 )
+        {
+            return;
+        }
+
+        // Only valid characters please.
+        if ( !VALID_UTF8_PATTERN.matcher( ret ).matches() )
+        {
+            return;
+        }
+
+        // only strings with '/' character are to be considered.
+        if ( ret.indexOf( '/' ) == -1 )
+        {
+            return;
+        }
+
+        // Strings that start with '/' are bad too
+        // Seen when Pool has regex patterns.
+        if ( ret.charAt( 0 ) == '/' )
+        {
+            return;
+        }
+
+        // Make string more class-like.
+        ret = ret.replace( '/', '.' );
+
+        // Double ".." indicates a bad class fail-fast.
+        // Seen when ConstantUTF8 Pool has regex patterns.
+        if ( ret.indexOf( ".." ) != -1 )
+        {
+            return;
+        }
+
+        Matcher mat = QUALIFIED_IMPORT_PATTERN.matcher( ret );
+        char prefix = ret.charAt( 0 );
+
+        if ( prefix == '(' )
+        {
+            // A Method Declaration.
+
+            // Loop for each Qualified Class found.
+            while ( mat.find() )
+            {
+                this.imports.add( mat.group( 1 ) );
+            }
+        }
+        else
+        {
+            // A Variable Declaration.
+            if ( mat.find() )
+            {
+                // Add a UTF8 Qualified Class reference.
+                this.imports.add( mat.group( 1 ) );
+            }
+            else
+            {
+                // Add a simple Class reference.
+                this.imports.add( ret );
+            }
+        }
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/BCELImportVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/BCELImportVisitor.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryClassAnalyzer.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryClassAnalyzer.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryClassAnalyzer.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryClassAnalyzer.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,250 @@
+package org.apache.maven.archiva.jarinfo.analysis.visitors;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.apache.bcel.classfile.ClassFormatException;
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.DescendingVisitor;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.LineNumberTable;
+import org.apache.bcel.classfile.Method;
+import org.apache.maven.archiva.jarinfo.analysis.Hasher;
+import org.apache.maven.archiva.jarinfo.analysis.IdentificationWeights;
+import org.apache.maven.archiva.jarinfo.analysis.JarEntryVisitor;
+import org.apache.maven.archiva.jarinfo.model.ClassDetail;
+import org.apache.maven.archiva.jarinfo.model.EntryDetail;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+import org.apache.maven.archiva.jarinfo.utils.EmptyUtils;
+
+public class EntryClassAnalyzer
+    extends AbstractJarEntryVisitor
+    implements JarEntryVisitor
+{
+    private static final double JAVA_1_7_CLASS_VERSION = 51.0;
+
+    private static final double JAVA_1_6_CLASS_VERSION = 50.0;
+
+    private static final double JAVA_1_5_CLASS_VERSION = 49.0;
+
+    private static final double JAVA_1_4_CLASS_VERSION = 47.0;
+
+    private static final double JAVA_1_3_CLASS_VERSION = 46.0;
+
+    private static final double JAVA_1_2_CLASS_VERSION = 45.65536;
+
+    private static final double JAVA_1_1_CLASS_VERSION = 45.3;
+
+    private boolean overallDebugPresent;
+
+    private double overallClassVersion;
+
+    private Set<String> packages = new HashSet<String>();
+    
+    private boolean performInspection = false;
+    
+    private Hasher classHasher = new Hasher( Hasher.SHA1 );
+    
+    public EntryClassAnalyzer(boolean performInspection )
+    {
+    	this.performInspection = performInspection;
+    }
+
+    public void visitStart( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitStart( details, jar );
+        overallDebugPresent = false;
+        overallClassVersion = 0.0;
+        packages.clear();
+    }
+
+    public void visitJarEntry( EntryDetail entry, JarEntry jarEntry )
+        throws IOException
+    {
+        if ( !jarEntry.getName().endsWith( ".class" ) )
+        {
+            return;
+        }
+        
+        ClassParser classParser = new ClassParser( jar.getName(), entry.getName() );
+        JavaClass javaClass = null;
+        try
+        {
+            javaClass = classParser.parse();
+        }
+        catch ( ClassFormatException e )
+        {
+            System.out.println( "Failure on entry: " + jarEntry.getName() );
+            e.printStackTrace();
+            return;
+        }
+
+        ClassDetail classDetail = new ClassDetail();
+
+        classHasher.reset();
+        classHasher.update( jar.getInputStream( jarEntry ) );
+
+        classDetail.setHash( classHasher.getAlgorithm(), classHasher.getHash() );
+        classDetail.setName( javaClass.getClassName() );
+        classDetail.setDebug( hasDebugSymbols( javaClass ) );
+
+        if ( classDetail.hasDebug() )
+        {
+            overallDebugPresent = true;
+        }
+
+        double classVersion = javaClass.getMajor();
+        if ( javaClass.getMinor() > 0 )
+        {
+            classVersion = classVersion + ( 1 / (double) javaClass.getMinor() );
+        }
+
+        if ( classVersion > overallClassVersion )
+        {
+            overallClassVersion = classVersion;
+        }
+
+        classDetail.setClassVersion( javaClass.getMajor() + "." + javaClass.getMinor() );
+
+        Method[] methods = javaClass.getMethods();
+        for ( Method method : methods )
+        {
+            classDetail.addMethod( method.getName() + method.getSignature() );
+        }
+
+        BCELImportVisitor importVisitor = new BCELImportVisitor( javaClass );
+        DescendingVisitor descVisitor = new DescendingVisitor( javaClass, importVisitor );
+        javaClass.accept( descVisitor );
+
+        classDetail.getImports().addAll( importVisitor.getImports() );
+        classDetail.setTargetJdk( toJDK( classVersion ) );
+
+        details.getBytecode().addClass( classDetail );
+
+        // Package to GroupId InspectedIds
+        if(this.performInspection)
+        {
+	        String packageName = javaClass.getPackageName();
+	        packages.add( packageName );
+	        int weight = IdentificationWeights.getInstance().getWeight( "packages.groupId" );
+	        details.getInspectedIds().addGroupId( packageName, weight, "class.packages" );
+        }
+    }
+
+    public void visitFinished( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitFinished( details, jar );
+        details.getBytecode().setDebug( overallDebugPresent );
+        details.getBytecode().setRequiredJdk( toJDK( overallClassVersion ) );
+
+        if(this.performInspection)
+        {
+	        // Determine common groupId.
+	        String commonPackage = null;
+	        for ( String packageName : packages )
+	        {
+	            if ( commonPackage == null )
+	            {
+	                commonPackage = packageName;
+	                continue;
+	            }
+	
+	            commonPackage = overlap( commonPackage, packageName );
+	            if ( commonPackage.endsWith( "." ) )
+	            {
+	                commonPackage.substring( 0, commonPackage.length() - 1 );
+	            }
+	        }
+	
+	        if ( !EmptyUtils.isEmpty( commonPackage ) )
+	        {
+	            int weight = IdentificationWeights.getInstance().getWeight( "packages.groupId.common" );
+	            details.getInspectedIds().addGroupId( commonPackage, weight, "class.packages.common" );
+	        }
+        }
+    }
+
+    private String overlap( String str1, String str2 )
+    {
+        if ( EmptyUtils.isEmpty( str1 ) || EmptyUtils.isEmpty( str2 ) )
+        {
+            return "";
+        }
+
+        StringBuffer ret = new StringBuffer();
+
+        int len = Math.min( str1.length(), str2.length() );
+        for ( int i = 0; i < len; i++ )
+        {
+            char c1 = str1.charAt( i );
+            char c2 = str2.charAt( i );
+            if ( c1 != c2 )
+            {
+                break;
+            }
+            ret.append( c1 );
+        }
+
+        return ret.toString();
+    }
+
+    private boolean hasDebugSymbols( JavaClass javaClass )
+    {
+        boolean ret = false;
+        Method[] methods = javaClass.getMethods();
+        for ( int i = 0; i < methods.length; i++ )
+        {
+            LineNumberTable linenumbers = methods[i].getLineNumberTable();
+            if ( linenumbers != null && linenumbers.getLength() > 0 )
+            {
+                ret = true;
+                break;
+            }
+        }
+        return ret;
+    }
+
+    private String toJDK( double classVersion )
+    {
+        if ( classVersion >= JAVA_1_7_CLASS_VERSION )
+        {
+            return "1.7";
+        }
+        else if ( classVersion >= JAVA_1_6_CLASS_VERSION )
+        {
+            return "1.6";
+        }
+        else if ( classVersion >= JAVA_1_5_CLASS_VERSION )
+        {
+            return "1.5";
+        }
+        else if ( classVersion >= JAVA_1_4_CLASS_VERSION )
+        {
+            return "1.4";
+        }
+        else if ( classVersion >= JAVA_1_3_CLASS_VERSION )
+        {
+            return "1.3";
+        }
+        else if ( classVersion >= JAVA_1_2_CLASS_VERSION )
+        {
+            return "1.2";
+        }
+        else if ( classVersion >= JAVA_1_1_CLASS_VERSION )
+        {
+            return "1.1";
+        }
+        else if ( classVersion > 0 )
+        {
+            return "1.0";
+        }
+
+        return null;
+    }
+
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryClassAnalyzer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryClassAnalyzer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryHasher.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryHasher.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryHasher.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryHasher.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,74 @@
+package org.apache.maven.archiva.jarinfo.analysis.visitors;
+
+import org.apache.maven.archiva.jarinfo.analysis.Hasher;
+import org.apache.maven.archiva.jarinfo.analysis.JarEntryVisitor;
+import org.apache.maven.archiva.jarinfo.model.EntryDetail;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * EntryHasher 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class EntryHasher
+    extends AbstractJarEntryVisitor
+    implements JarEntryVisitor
+{
+    private Hasher bytecodeHasher = new Hasher( Hasher.SHA1 );
+
+    private Hasher entryHasher = new Hasher( Hasher.SHA1 );
+
+    private List<Hasher> hashers = new ArrayList<Hasher>();
+
+    public void visitStart( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitStart( details, jar );
+        entryHasher.reset();
+        bytecodeHasher.reset();
+    }
+
+    public void visitJarEntry( EntryDetail entry, JarEntry jarEntry )
+        throws IOException
+    {
+        if ( jarEntry.isDirectory() )
+        {
+            // No hashing directories.
+            return;
+        }
+
+        if ( jarEntry.getSize() <= 0 )
+        {
+            // Nothing to hash.
+            return;
+        }
+
+        hashers.clear();
+        hashers.add( entryHasher );
+
+        if ( jarEntry.getName().endsWith( ".class" ) )
+        {
+            hashers.add( bytecodeHasher );
+        }
+
+        entryHasher.reset();
+
+        Hasher.update( hashers, jar.getInputStream( jarEntry ) );
+
+        entry.setHash( entryHasher.getAlgorithm(), entryHasher.getHash() );
+    }
+
+    public void visitFinished( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitFinished( details, jar );
+        details.getBytecode().setHash( bytecodeHasher.getAlgorithm(), bytecodeHasher.getHash() );
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryHasher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryHasher.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryManifest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryManifest.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryManifest.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryManifest.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,95 @@
+package org.apache.maven.archiva.jarinfo.analysis.visitors;
+
+import org.apache.maven.archiva.jarinfo.analysis.IdentificationWeights;
+import org.apache.maven.archiva.jarinfo.analysis.JarEntryVisitor;
+import org.apache.maven.archiva.jarinfo.model.EntryDetail;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+
+import java.io.IOException;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+/**
+ * EntryManifest - process the jar manifest. 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class EntryManifest
+    extends AbstractJarEntryVisitor
+    implements JarEntryVisitor
+{
+
+    @Override
+    public void visitStart( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitStart( details, jar );
+
+        Manifest manifest = jar.getManifest();
+        if ( manifest == null )
+        {
+            return;
+        }
+
+        // Collection Sealed identifier
+        boolean sealed = false;
+        String sval = manifest.getMainAttributes().getValue( Attributes.Name.SEALED );
+        if ( sval != null )
+        {
+            sealed = "true".equalsIgnoreCase( sval.trim() );
+        }
+
+        details.setSealed( sealed );
+
+        // Gather up InspectedIds Bits
+        addAttributeValues( "manifest.main", manifest.getMainAttributes() );
+
+        for ( Attributes attribs : manifest.getEntries().values() )
+        {
+            addAttributeValues( "manifest.entry", attribs );
+        }
+    }
+
+    private void addAttributeValues( String weightPrefix, Attributes attribs )
+    {
+        IdentificationWeights weights = IdentificationWeights.getInstance();
+        String weightKey;
+
+        // Implementation values.
+        weightKey = weightPrefix + ".name.impl";
+        details.getInspectedIds().addName( attribs.getValue( Attributes.Name.IMPLEMENTATION_TITLE ),
+                                             weights.getWeight( weightKey ), weightKey );
+        weightKey = weightPrefix + ".version.impl";
+        details.getInspectedIds().addVersion( attribs.getValue( Attributes.Name.IMPLEMENTATION_VERSION ),
+                                                weights.getWeight( weightKey ), weightKey );
+        weightKey = weightPrefix + ".vendor.impl";
+        details.getInspectedIds().addVendor( attribs.getValue( Attributes.Name.IMPLEMENTATION_VENDOR ),
+                                               weights.getWeight( weightKey ), weightKey );
+
+        // Specification values.
+        weightKey = weightPrefix + ".name.spec";
+        details.getInspectedIds().addName( attribs.getValue( Attributes.Name.SPECIFICATION_TITLE ),
+                                             weights.getWeight( weightKey ), weightKey );
+        weightKey = weightPrefix + ".version.spec";
+        details.getInspectedIds().addVersion( attribs.getValue( Attributes.Name.SPECIFICATION_VERSION ),
+                                                weights.getWeight( weightKey ), weightKey );
+        weightKey = weightPrefix + ".vendor.spec";
+        details.getInspectedIds().addVendor( attribs.getValue( Attributes.Name.SPECIFICATION_VENDOR ),
+                                               weights.getWeight( weightKey ), weightKey );
+
+        // Extension values.
+        weightKey = weightPrefix + ".groupId";
+        details.getInspectedIds().addGroupId( attribs.getValue( Attributes.Name.EXTENSION_NAME ),
+                                                weights.getWeight( weightKey ), weightKey );
+    }
+
+    public void visitJarEntry( EntryDetail entry, JarEntry jarEntry )
+        throws IOException
+    {
+        /* do nothing here */
+    }
+
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryManifest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntryManifest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntrySizer.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntrySizer.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntrySizer.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntrySizer.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,49 @@
+package org.apache.maven.archiva.jarinfo.analysis.visitors;
+
+import org.apache.maven.archiva.jarinfo.analysis.JarEntryVisitor;
+import org.apache.maven.archiva.jarinfo.model.EntryDetail;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+
+import java.io.IOException;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * Gather the size of individual entries, and overall uncompressed size too.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class EntrySizer
+    extends AbstractJarEntryVisitor
+    implements JarEntryVisitor
+{
+    private long overall;
+
+    public void visitStart( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitStart( details, jar );
+        overall = 0;
+    }
+
+    public void visitJarEntry( EntryDetail entry, JarEntry jarEntry )
+    {
+        if ( jarEntry.isDirectory() )
+        {
+            // skip
+            return;
+        }
+
+        long size = jarEntry.getSize();
+        entry.setSize( size );
+        overall += size;
+    }
+
+    public void visitFinished( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitFinished( details, jar );
+        details.setSizeUncompressed( overall );
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntrySizer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/EntrySizer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationEmbeddedMavenProperties.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationEmbeddedMavenProperties.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationEmbeddedMavenProperties.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationEmbeddedMavenProperties.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,99 @@
+package org.apache.maven.archiva.jarinfo.analysis.visitors;
+
+import java.io.IOException;
+import java.util.Properties;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.maven.archiva.jarinfo.analysis.IdentificationWeights;
+import org.apache.maven.archiva.jarinfo.analysis.JarEntryVisitor;
+import org.apache.maven.archiva.jarinfo.model.EntryDetail;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+import org.apache.maven.archiva.jarinfo.utils.EmptyUtils;
+
+public class IdentificationEmbeddedMavenProperties
+    extends AbstractJarEntryVisitor
+    implements JarEntryVisitor
+{
+    private static final Pattern MAVEN_POM_FILTER = Pattern.compile( "META-INF/maven/.*/pom\\.properties$" );
+
+    private IdentificationWeights weights;
+
+    private boolean performInspection = false;
+
+    public IdentificationEmbeddedMavenProperties()
+    {
+        this( true );
+    }
+
+    public IdentificationEmbeddedMavenProperties( boolean performInspection )
+    {
+        this.performInspection = performInspection;
+    }
+
+    @Override
+    public void visitStart( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitStart( details, jar );
+        weights = IdentificationWeights.getInstance();
+    }
+
+    public void visitJarEntry( EntryDetail entry, JarEntry jarEntry )
+        throws IOException
+    {
+        Matcher matcher = MAVEN_POM_FILTER.matcher( jarEntry.getName() );
+        if ( !matcher.matches() )
+        {
+            return;
+        }
+
+        Properties props = new Properties();
+        props.load( jar.getInputStream( jarEntry ) );
+
+        String groupId = props.getProperty( "groupId" );
+        if ( !EmptyUtils.isEmpty( groupId ) )
+        {
+            if ( performInspection )
+            {
+                String weightKey = "embedded.pom.groupId";
+                details.getInspectedIds().addGroupId( groupId, weights.getWeight( weightKey ), weightKey );
+            }
+            details.getAssignedId().setGroupId( groupId );
+        }
+
+        String artifactId = props.getProperty( "artifactId" );
+        if ( !EmptyUtils.isEmpty( artifactId ) )
+        {
+            if ( performInspection )
+            {
+                String weightKey = "embedded.pom.artifactId";
+                details.getInspectedIds().addArtifactId( artifactId, weights.getWeight( weightKey ), weightKey );
+            }
+            details.getAssignedId().setArtifactId( artifactId );
+        }
+
+        String version = props.getProperty( "version" );
+        if ( !EmptyUtils.isEmpty( version ) )
+        {
+            if ( performInspection )
+            {
+                String weightKey = "embedded.pom.version";
+                details.getInspectedIds().addVersion( version, weights.getWeight( weightKey ), weightKey );
+            }
+            details.getAssignedId().setVersion( version );
+        }
+    }
+
+    public boolean isPerformInspection()
+    {
+        return performInspection;
+    }
+
+    public void setPerformInspection( boolean performInspection )
+    {
+        this.performInspection = performInspection;
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationEmbeddedMavenProperties.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationEmbeddedMavenProperties.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationFilename.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationFilename.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationFilename.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationFilename.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,71 @@
+package org.apache.maven.archiva.jarinfo.analysis.visitors;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.maven.archiva.jarinfo.analysis.IdentificationWeights;
+import org.apache.maven.archiva.jarinfo.analysis.JarEntryVisitor;
+import org.apache.maven.archiva.jarinfo.model.EntryDetail;
+import org.apache.maven.archiva.jarinfo.model.InspectedIds;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+
+public class IdentificationFilename
+    extends AbstractJarEntryVisitor
+    implements JarEntryVisitor
+{
+    private static final String ORIGIN = "filename";
+
+    private static final Pattern VERSION_PATTERN = Pattern.compile( "-[0-9]" );
+
+    @Override
+    public void visitStart( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitStart( details, jar );
+
+        String filename = jar.getName();
+        
+        // Strip off paths (if any)
+        int idxPath = filename.lastIndexOf( File.separatorChar );
+        if ( idxPath > 0 )
+        {
+            filename = filename.substring( idxPath + 1 );
+        }
+
+        // Remove any extension.
+        int idxExt = filename.lastIndexOf( '.' );
+        if ( idxExt > 0 )
+        {
+            filename = filename.substring( 0, idxExt );
+        }
+
+        InspectedIds inspectedIds = details.getInspectedIds();
+        IdentificationWeights weights = IdentificationWeights.getInstance();
+
+        Matcher mat = VERSION_PATTERN.matcher( filename );
+        if ( mat.find() )
+        {
+            String prefix = filename.substring( 0, mat.start() );
+            inspectedIds.addArtifactId( prefix, weights.getWeight( "filename.artifactId" ), ORIGIN );
+            inspectedIds.addName( prefix, weights.getWeight( "filename.name" ), ORIGIN );
+            inspectedIds.addVersion( filename.substring( mat.end() - 1 ), 
+                                       weights.getWeight( "filename.version" ),
+                                       ORIGIN );
+        }
+        else
+        {
+            inspectedIds.addArtifactId( filename, weights.getWeight( "filename.artifactId" ), ORIGIN );
+            inspectedIds.addName( filename, weights.getWeight( "filename.name" ), ORIGIN );
+        }
+    }
+
+    public void visitJarEntry( EntryDetail entry, JarEntry jarEntry )
+        throws IOException
+    {
+        /* do nothing */
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationFilename.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationFilename.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationTimestamps.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationTimestamps.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationTimestamps.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationTimestamps.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,53 @@
+package org.apache.maven.archiva.jarinfo.analysis.visitors;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.apache.maven.archiva.jarinfo.analysis.IdentificationWeights;
+import org.apache.maven.archiva.jarinfo.analysis.JarEntryVisitor;
+import org.apache.maven.archiva.jarinfo.model.EntryDetail;
+import org.apache.maven.archiva.jarinfo.model.JarDetails;
+
+public class IdentificationTimestamps
+    extends AbstractJarEntryVisitor
+    implements JarEntryVisitor
+{
+    private long maxTimestamp;
+
+    @Override
+    public void visitStart( JarDetails details, JarFile jar )
+        throws IOException
+    {
+        super.visitStart( details, jar );
+        maxTimestamp = 0;
+    }
+
+    public void visitJarEntry( EntryDetail entry, JarEntry jarEntry )
+        throws IOException
+    {
+        maxTimestamp = Math.max( maxTimestamp, jarEntry.getTime() );
+
+        int weight = IdentificationWeights.getInstance().getWeight( "timestamp.version" );
+        details.getInspectedIds().addVersion( toTimestamp( jarEntry.getTime() ), weight, "timestamps" );
+    }
+
+    @Override
+    public void visitFinished( JarDetails finishDetails, JarFile finishJar )
+        throws IOException
+    {
+        super.visitFinished( finishDetails, finishJar );
+        int weight = IdentificationWeights.getInstance().getWeight( "timestamp.version.max" );
+        details.getInspectedIds().addVersion( toTimestamp( maxTimestamp ), weight, "timestamps.max" );
+    }
+
+    private String toTimestamp( long timestamp )
+    {
+        SimpleDateFormat format = new SimpleDateFormat( "yyyyMMdd", Locale.US );
+        return format.format( new Date( timestamp ) );
+    }
+
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationTimestamps.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/analysis/visitors/IdentificationTimestamps.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/AssignedId.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/AssignedId.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/AssignedId.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/AssignedId.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,72 @@
+package org.apache.maven.archiva.jarinfo.model;
+
+import org.apache.maven.archiva.jarinfo.utils.EmptyUtils;
+
+public class AssignedId
+{
+    private String groupId;
+
+    private String artifactId;
+
+    private String version;
+
+    private String name;
+
+    private String vendor;
+
+    public boolean valid()
+    {
+        return !EmptyUtils.isEmpty( groupId ) && !EmptyUtils.isEmpty( artifactId ) && !EmptyUtils.isEmpty( version );
+    }
+
+    public String getGroupId()
+    {
+        return groupId;
+    }
+
+    public void setGroupId( String groupId )
+    {
+        this.groupId = groupId;
+    }
+
+    public String getArtifactId()
+    {
+        return artifactId;
+    }
+
+    public void setArtifactId( String artifactId )
+    {
+        this.artifactId = artifactId;
+    }
+
+    public String getVersion()
+    {
+        return version;
+    }
+
+    public void setVersion( String version )
+    {
+        this.version = version;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    public String getVendor()
+    {
+        return vendor;
+    }
+
+    public void setVendor( String vendor )
+    {
+        this.vendor = vendor;
+    }
+
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/AssignedId.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/AssignedId.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/BytecodeDetails.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/BytecodeDetails.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/BytecodeDetails.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/BytecodeDetails.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,67 @@
+package org.apache.maven.archiva.jarinfo.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class BytecodeDetails
+{
+    private Map<String, String> hashes = new HashMap<String, String>();
+
+    private boolean debug = false;
+
+    private String requiredJdk;
+
+    private List<ClassDetail> classes = new ArrayList<ClassDetail>();
+
+    public List<ClassDetail> getClasses()
+    {
+        return classes;
+    }
+
+    public String getRequiredJdk()
+    {
+        return requiredJdk;
+    }
+
+    public boolean hasDebug()
+    {
+        return debug;
+    }
+
+    public void addClass( ClassDetail detail )
+    {
+        this.classes.add( detail );
+    }
+
+    public void setClasses( List<ClassDetail> classes )
+    {
+        this.classes = classes;
+    }
+
+    public void setDebug( boolean debug )
+    {
+        this.debug = debug;
+    }
+
+    public void setHash( String algorithm, String hash )
+    {
+        this.hashes.put( algorithm, hash );
+    }
+
+    public void setRequiredJdk( String requiredJdk )
+    {
+        this.requiredJdk = requiredJdk;
+    }
+
+    public Map<String, String> getHashes()
+    {
+        return hashes;
+    }
+
+    public void setHashes( Map<String, String> hashes )
+    {
+        this.hashes = hashes;
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/BytecodeDetails.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/BytecodeDetails.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/ClassDetail.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/ClassDetail.java?rev=635796&view=auto
==============================================================================
--- maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/ClassDetail.java (added)
+++ maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/ClassDetail.java Mon Mar 10 21:07:17 2008
@@ -0,0 +1,122 @@
+package org.apache.maven.archiva.jarinfo.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ClassDetail
+{
+    private Map<String, String> hashes = new HashMap<String, String>();
+
+    private String name;
+
+    private String targetJdk;
+
+    private String classVersion;
+
+    private boolean debug = false;
+
+    private List<String> methods = new ArrayList<String>();
+
+    private List<String> imports = new ArrayList<String>();
+    
+    public String getPackage()
+    {
+        String ret = name;
+        int idx = ret.lastIndexOf( '.' );
+        if ( idx >= 0 )
+        {
+            ret = ret.substring( 0, idx );
+        }
+
+        return ret;
+    }
+
+    public void addImport( String importName )
+    {
+        this.imports.add( importName );
+    }
+
+    public void addMethod( String method )
+    {
+        this.methods.add( method );
+    }
+
+    public String getClassVersion()
+    {
+        return classVersion;
+    }
+
+    
+
+    public List<String> getImports()
+    {
+        return imports;
+    }
+
+    public List<String> getMethods()
+    {
+        return methods;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public String getTargetJdk()
+    {
+        return targetJdk;
+    }
+
+    public boolean hasDebug()
+    {
+        return debug;
+    }
+
+    public void setClassVersion( String classVersion )
+    {
+        this.classVersion = classVersion;
+    }
+
+    public void setDebug( boolean debug )
+    {
+        this.debug = debug;
+    }
+
+    public void setHash( String algorithm, String hash )
+    {
+        this.hashes.put( algorithm, hash );
+    }
+
+    public void setImports( List<String> imports )
+    {
+        this.imports = imports;
+    }
+
+    public void setMethods( List<String> methods )
+    {
+        this.methods = methods;
+    }
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    public void setTargetJdk( String targetJdk )
+    {
+        this.targetJdk = targetJdk;
+    }
+
+    public Map<String, String> getHashes()
+    {
+        return hashes;
+    }
+
+    public void setHashes( Map<String, String> hashes )
+    {
+        this.hashes = hashes;
+    }
+}

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/ClassDetail.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/archiva/archiva-jarinfo/archiva-jarinfo-lib/src/main/java/org/apache/maven/archiva/jarinfo/model/ClassDetail.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"