You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by og...@apache.org on 2009/04/23 00:57:04 UTC

svn commit: r767705 [8/31] - in /maven/mercury/trunk/mercury-core: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/maven/ src/main/java/org/apache/maven/mercury/ src/main/java/org/apache/maven/merc...

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryMetadataCache.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryMetadataCache.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryMetadataCache.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryMetadataCache.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,111 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.api;
+
+import org.apache.maven.mercury.artifact.ArtifactCoordinates;
+import org.apache.maven.mercury.artifact.ArtifactMetadata;
+import org.apache.maven.mercury.event.EventGenerator;
+
+/**
+ * this object abstracts the existence of multiple repositories and repository policies. Given a metadata request,
+ * implementor of this interface will either return a local copy if one exists, or will go out and read from a remote
+ * repo if either local copy does not exist or remote repository policy allows a read
+ * 
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public interface RepositoryMetadataCache
+    extends EventGenerator
+{
+    /**
+     * check if GA level metadata exists in this cache for the given repo. Read from repo, if does not exists
+     * 
+     * @param repoGuid repository GUID
+     * @param up repository update policy
+     * @param coord bare GA coordinates of the requisted metadata
+     * @return metadata object or null, if data does not exist or has been expired
+     */
+    public RepositoryGAMetadata findGA( String repoGuid, RepositoryUpdatePolicy up, ArtifactCoordinates coord )
+        throws MetadataCorruptionException;
+
+    /**
+     * check if GAV level metadata exists in this cache for the given repo. Read from repo, if does not exists
+     * 
+     * @param repoGuid repository GUID
+     * @param up repository update policy
+     * @param coord bare GAV coordinates of the requisted metadata
+     * @return
+     */
+    public RepositoryGAVMetadata findGAV( String repoGuid, RepositoryUpdatePolicy up, ArtifactCoordinates coord )
+        throws MetadataCorruptionException;
+
+    /**
+     * update stored GA metadata with a fresh copy
+     * 
+     * @param repoGuid
+     * @param gam
+     * @throws MetadataCacheException
+     */
+    public void updateGA( String repoGuid, RepositoryGAMetadata gam )
+        throws MetadataCacheException;
+
+    /**
+     * update stored GA metadata with a fresh copy
+     * 
+     * @param repoGuid
+     * @param gavm fresh metadata
+     * @throws MetadataCacheException
+     */
+    public void updateGAV( String repoGuid, RepositoryGAVMetadata gavm )
+        throws MetadataCacheException;
+
+    /**
+     * find cached raw data. Raw data is different from metadata in a sense that it does not expire, so it's either
+     * found or not. This call is crafted for caching POMs and thus ignores classifier
+     * 
+     * @param bmd
+     * @return found bytes or null, if no data was cached for this coordinates before
+     * @throws MetadataCacheException
+     */
+    public byte[] findRaw( ArtifactMetadata bmd )
+        throws MetadataCacheException;
+
+    /**
+     * cache raw data. Raw data is different from metadata in a sense that it does not expire, so it's either found or
+     * not This call is crafted for caching POMs and thus ignores classifier
+     * 
+     * @param bmd
+     * @param rawBytes - bytes to cache
+     * @throws MetadataCacheException
+     */
+    public void saveRaw( ArtifactMetadata bmd, byte[] rawBytes )
+    throws MetadataCacheException;
+    
+    /**
+     * clears all session data (in-memory cache). Only on-disk data should remain and it
+     * complies with expiration policies. Session data is different in this regard and once in 
+     * memory - ignores expiration time; this is done for faster access of the same data if
+     * expiration is set to "always" - first time data is read from remote repository, cached in
+     * the session, and all subsequent call use this data.  
+     * 
+     * @throws MetadataCacheException
+     */
+    public void clearSession()
+    throws MetadataCacheException;
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryMetadataCache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryMetadataCache.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryOperator.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryOperator.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryOperator.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryOperator.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,34 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.api;
+
+/**
+ * parent of all repository accessors - readers and writers
+ * 
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public interface RepositoryOperator
+{
+    public String[] getProtocols();
+
+    public boolean canHandle( String protocol );
+
+    public void close();
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryOperator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryOperator.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReader.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReader.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReader.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReader.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,218 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.api;
+
+import java.util.Collection;
+
+import org.apache.maven.mercury.artifact.ArtifactMetadata;
+import org.apache.maven.mercury.builder.api.DependencyProcessor;
+import org.apache.maven.mercury.builder.api.MetadataReader;
+import org.apache.maven.mercury.builder.api.MetadataReaderException;
+
+/**
+ * Repository reader API to be implemented by any repo implementation that wishes to serve artifacts to the build
+ * process
+ * 
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public interface RepositoryReader
+    extends RepositoryOperator, MetadataReader
+{
+    /**
+     * given basic coordinates query - instantiate all available matches as ArtifactBasicMetadata objects. <b>Analogous
+     * to reading maven-metadata.xml</b> file from GA folder i.e. this transforms GA[Vrange] -> [GAV1, GAV2, ... GAVn]
+     * 
+     * @param query list of MD coordinate queries to find
+     * @return map of results - lists of available matches. <b>If no results are found, reader should return null<b> If
+     *         there were exceptions, map element will indicate it with hasExceptions()
+     * @throws RepositoryException
+     */
+    public MetadataResults readVersions( Collection<ArtifactMetadata> query )
+        throws RepositoryException;
+
+    /**
+     * given basic coordinates query read dependencies as a GAV list with dependencies as queries i.e. each dependency
+     * at this stage is an ArtifactBasicMetadata <b>Analogous to reading pom.xml</b> file for given GAV
+     * 
+     * @param query list of MD coordinate queries to read. They are found by previous call to findMetadata
+     * @return result as a map GAV -> [GAV1, GAV2, ... GAVn]
+     * @throws RepositoryException
+     */
+    public MetadataResults readDependencies( Collection<ArtifactMetadata> query )
+        throws RepositoryException;
+
+    /**
+     * Given basic coordinates query read Artifact objects Analogous to downloading artifact binary file into local repo
+     * for given GAV
+     * 
+     * @param query list of MD coordinate queries to read.
+     * @return array of results - lists of available matches. Order is the same as in query list. null means not found
+     *         or worse
+     * @throws RepositoryException
+     */
+    public ArtifactResults readArtifacts( Collection<ArtifactMetadata> query )
+        throws RepositoryException;
+
+    /**
+     * Need if for explanation function - where and how(protocol) this artifact is found.
+     */
+    public Repository getRepository();
+
+    /**
+     * Abstracted POM reader. First projectBuilder, then any type of dependency reader
+     */
+    public void setDependencyProcessor( DependencyProcessor mdProcessor );
+
+    public DependencyProcessor getDependencyProcessor();
+
+    /**
+     * MetadataReader field. Single repository uses itself, virtual reader injects itself to be able to find metadata
+     * across repositories
+     */
+    public void setMetadataReader( MetadataReader mdReader );
+
+    public MetadataReader getMetadataReader();
+
+    /**
+     * Abstracted metadata cache is used to store/retrieve metadata faster. It usually implements repository update
+     * policy
+     */
+    public void setMetadataCache( RepositoryMetadataCache mdCache );
+
+    public RepositoryMetadataCache getMetadataCache();
+
+    /**
+     * read content pointed by relative path. It will return content bytes
+     * 
+     * @param path - realative resource path in this repository
+     * @return byte [] of the resource content, pointed by the path
+     * @throws MetadataReaderException
+     */
+    public byte[] readRawData( String path, boolean exempt )
+        throws MetadataReaderException;
+
+    public byte[] readRawData( String path )
+        throws MetadataReaderException;
+
+    public static final RepositoryReader NULL_READER = new RepositoryReader()
+    {
+        public DependencyProcessor getDependencyProcessor()
+        {
+            return null;
+        }
+
+        public RepositoryMetadataCache getMetadataCache()
+        {
+            return null;
+        }
+
+        public Repository getRepository()
+        {
+            return null;
+        }
+
+        public ArtifactResults readArtifacts( Collection<ArtifactMetadata> query )
+            throws RepositoryException
+        {
+            return null;
+        }
+
+        public MetadataResults readDependencies( Collection<ArtifactMetadata> query )
+            throws RepositoryException
+        {
+            return null;
+        }
+
+        public byte[] readRawData( String path, boolean exempt )
+            throws MetadataReaderException
+        {
+            return null;
+        }
+
+        public byte[] readRawData( String path )
+            throws MetadataReaderException
+        {
+            return null;
+        }
+
+        public MetadataResults readVersions( Collection<ArtifactMetadata> query )
+            throws RepositoryException
+        {
+            return null;
+        }
+
+        public void setDependencyProcessor( DependencyProcessor mdProcessor )
+        {
+        }
+
+        public void setMetadataCache( RepositoryMetadataCache mdCache )
+        {
+        }
+
+        public boolean canHandle( String protocol )
+        {
+            return false;
+        }
+
+        public void close()
+        {
+        }
+
+        public String[] getProtocols()
+        {
+            return null;
+        }
+
+        public byte[] readMetadata( ArtifactMetadata bmd, boolean exempt )
+            throws MetadataReaderException
+        {
+            return null;
+        }
+
+        public byte[] readMetadata( ArtifactMetadata bmd )
+            throws MetadataReaderException
+        {
+            return null;
+        }
+
+        public byte[] readRawData( ArtifactMetadata bmd, String classifier, String type, boolean exempt )
+            throws MetadataReaderException
+        {
+            return null;
+        }
+
+        public byte[] readRawData( ArtifactMetadata bmd, String classifier, String type )
+            throws MetadataReaderException
+        {
+            return null;
+        }
+
+        public MetadataReader getMetadataReader()
+        {
+            return null;
+        }
+
+        public void setMetadataReader( MetadataReader mdReader )
+        {
+        }
+
+    };
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReader.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReaderFactory.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReaderFactory.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReaderFactory.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReaderFactory.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,27 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.api;
+
+import org.apache.maven.mercury.builder.api.DependencyProcessor;
+
+public interface RepositoryReaderFactory
+{
+    public RepositoryReader getReader( Repository repo, DependencyProcessor mdProcessor )
+        throws RepositoryException;
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReaderFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryReaderFactory.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdateIntervalPolicy.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdateIntervalPolicy.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdateIntervalPolicy.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdateIntervalPolicy.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,149 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.api;
+
+import java.text.ParseException;
+
+import org.apache.maven.mercury.artifact.Quality;
+import org.apache.maven.mercury.util.TimeUtil;
+import org.apache.maven.mercury.util.Util;
+import org.codehaus.plexus.lang.DefaultLanguage;
+import org.codehaus.plexus.lang.Language;
+
+/**
+ * implements current maven update policy
+ * 
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public class RepositoryUpdateIntervalPolicy
+    implements RepositoryUpdatePolicy
+{
+    private static final Language _lang = new DefaultLanguage( RepositoryUpdateIntervalPolicy.class );
+
+    public static final String UPDATE_POLICY_NAME_NEVER = "never";
+
+    public static final String UPDATE_POLICY_NAME_ALWAYS = "always";
+
+    /** same as always - do it NOW */
+    public static final String UPDATE_POLICY_NAME_NOW = "now";
+
+    public static final String UPDATE_POLICY_NAME_DAILY = "daily";
+
+    public static final String UPDATE_POLICY_NAME_INTERVAL = "interval";
+
+    private static final int UPDATE_POLICY_INTERVAL_LENGTH = UPDATE_POLICY_NAME_INTERVAL.length();
+
+    public static final String DEFAULT_UPDATE_POLICY_NAME = UPDATE_POLICY_NAME_DAILY;
+
+    public static final RepositoryUpdateIntervalPolicy UPDATE_POLICY_NEVER =
+        new RepositoryUpdateIntervalPolicy( UPDATE_POLICY_NAME_NEVER );
+
+    public static final RepositoryUpdateIntervalPolicy UPDATE_POLICY_ALWAYS =
+        new RepositoryUpdateIntervalPolicy( UPDATE_POLICY_NAME_ALWAYS );
+
+    public static final RepositoryUpdateIntervalPolicy UPDATE_POLICY_DAILY =
+        new RepositoryUpdateIntervalPolicy( UPDATE_POLICY_NAME_DAILY );
+
+    /** this is the default policy - don't update unless asked */
+    public static final RepositoryUpdateIntervalPolicy DEFAULT_UPDATE_POLICY = UPDATE_POLICY_NEVER;
+
+    private static final long NEVER = -1L;
+
+    private static final long ALWAYS = 0L;
+    
+    private static final long DAYLY = 3600000L * 24L;
+
+    protected long interval = DAYLY;
+
+    public RepositoryUpdateIntervalPolicy()
+    {
+    }
+
+    public RepositoryUpdateIntervalPolicy( String policy )
+    {
+        init( policy );
+    }
+
+    /**
+     * used mostly for testing as it's too much waiting for a minute to test expiration
+     * 
+     * @param interval
+     */
+    public RepositoryUpdateIntervalPolicy setInterval( long interval )
+    {
+        this.interval = interval;
+        return this;
+    }
+
+    public void init( String policy )
+    {
+        interval = parsePolicy( policy );
+    }
+
+    public static long parsePolicy( String policy )
+    {
+        if ( Util.isEmpty( policy ) )
+            throw new IllegalArgumentException( _lang.getMessage( "empty.policy", policy ) );
+
+        if ( policy.startsWith( UPDATE_POLICY_NAME_ALWAYS ) )
+            return ALWAYS;
+        else if ( policy.startsWith( UPDATE_POLICY_NAME_NOW ) )
+            return ALWAYS;
+        else if ( policy.startsWith( UPDATE_POLICY_NAME_DAILY ) )
+            return DAYLY;
+        else if ( policy.startsWith( UPDATE_POLICY_NAME_NEVER ) )
+            return NEVER;
+        else if ( policy.startsWith( UPDATE_POLICY_NAME_INTERVAL ) )
+        {
+            int len = policy.length();
+            if ( len <= UPDATE_POLICY_INTERVAL_LENGTH )
+                throw new IllegalArgumentException( _lang.getMessage( "bad.interval.policy", policy ) );
+
+            return Integer.parseInt( policy.substring( len - 1 ) ) * 60000L;
+        }
+        else
+            throw new IllegalArgumentException( _lang.getMessage( "bad.policy", policy ) );
+    }
+
+    public boolean timestampExpired( long lastUpdateMillis, Quality quality )
+    {
+        // save a couple of nannos 
+        if ( interval == NEVER )
+            return false;
+
+        if ( interval == ALWAYS )
+            return true;
+
+        long now;
+        try
+        {
+            now = TimeUtil.toMillis( TimeUtil.getUTCTimestamp() );
+        }
+        catch ( ParseException e )
+        {
+            throw new IllegalArgumentException( e );
+        }
+
+        boolean res = ( ( now - lastUpdateMillis ) > interval );
+
+        return res;
+    }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdateIntervalPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdateIntervalPolicy.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicy.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicy.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicy.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicy.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,46 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.api;
+
+import org.apache.maven.mercury.artifact.Quality;
+
+/**
+ * abstraction of a repository update policy calculator
+ * 
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public interface RepositoryUpdatePolicy
+{
+    public static final String SYSTEM_PROPERTY_UPDATE_POLICY = "mercury.repository.update.policy";
+    /**
+     * initialize this calculator
+     * 
+     * @param policy as a string somewhere in configuration
+     */
+    void init( String policy );
+
+    /**
+     * perform the calculation and decide if it's time to update
+     * 
+     * @param timestamp - UTC-based timestamp as long milliseconds
+     * @return
+     */
+    boolean timestampExpired( long timestampMillis, Quality quality );
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicy.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicyFactory.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicyFactory.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicyFactory.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicyFactory.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,37 @@
+/*
+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.
+*/
+
+package org.apache.maven.mercury.repository.api;
+
+/**
+ * creates repository update policy out of strings
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class RepositoryUpdatePolicyFactory
+{
+    public static RepositoryUpdatePolicy create( String policy )
+    {
+        RepositoryUpdateIntervalPolicy up = new RepositoryUpdateIntervalPolicy( policy );
+        
+        return up;
+    }
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicyFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryUpdatePolicyFactory.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriter.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriter.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriter.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriter.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,81 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.api;
+
+import java.util.Collection;
+
+import org.apache.maven.mercury.artifact.Artifact;
+
+/**
+ * Repository writer API to be implemented by any repo implementation that wishes to store artifacts for Maven. All
+ * operations are asynchronous and can generate callback events
+ * 
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public interface RepositoryWriter
+    extends RepositoryOperator
+{
+    /**
+     * write (upload) given artifact to the repository
+     * 
+     * @param artifact to upload
+     * @throws RepositoryException
+     */
+    public void writeArtifacts( Collection<Artifact> artifact )
+        throws RepositoryException;
+
+    public void setMetadataCache( RepositoryMetadataCache mdCache );
+
+    public RepositoryMetadataCache getMetadataCache();
+
+    public static final RepositoryWriter NULL_WRITER = new RepositoryWriter()
+    {
+
+        public RepositoryMetadataCache getMetadataCache()
+        {
+            return null;
+        }
+
+        public void setMetadataCache( RepositoryMetadataCache mdCache )
+        {
+        }
+
+        public void writeArtifacts( Collection<Artifact> artifact )
+            throws RepositoryException
+        {
+        }
+
+        public boolean canHandle( String protocol )
+        {
+            return false;
+        }
+
+        public void close()
+        {
+        }
+
+        public String[] getProtocols()
+        {
+            return null;
+        }
+
+    };
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriter.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriterFactory.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriterFactory.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriterFactory.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriterFactory.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,30 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.api;
+
+/**
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+
+public interface RepositoryWriterFactory
+{
+    public RepositoryWriter getWriter( Repository repo )
+        throws RepositoryException;
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriterFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/api/RepositoryWriterFactory.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAMetadata.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAMetadata.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAMetadata.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAMetadata.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,115 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.cache.fs;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.maven.mercury.artifact.ArtifactCoordinates;
+import org.apache.maven.mercury.repository.api.MetadataCorruptionException;
+import org.apache.maven.mercury.repository.api.RepositoryGAMetadata;
+import org.apache.maven.mercury.repository.metadata.MetadataException;
+import org.apache.maven.mercury.util.Util;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class CachedGAMetadata
+extends RepositoryGAMetadata
+{
+  public static final String ELEM_COORDINATES = "coordinates";
+  public static final String ATTR_GROUP_ID = "groupId";
+  public static final String ATTR_ARTIFACT_ID = "artifactId";
+  public static final String ATTR_VERSION = "version";
+  public static final String ATTR_NEGATIVE = "negative";
+
+  public static final String ELEM_VERSIONS = "versions";
+
+  CachedMetadata cm;
+  
+  public CachedGAMetadata( File mdFile )
+  throws FileNotFoundException, IOException, XmlPullParserException, MetadataCorruptionException
+  {
+    cm = new CachedMetadata( mdFile );
+    fromXml();
+  }
+  
+  public CachedGAMetadata( RepositoryGAMetadata md )
+  throws MetadataException
+  {
+    super( md );
+    
+    cm = new CachedMetadata();
+    
+    toXml();
+  }
+  
+  /**
+   * fill GA with data from cm
+   * 
+   * @throws MetadataCorruptionException 
+   */
+  private void fromXml()
+  throws MetadataCorruptionException
+  {
+    ga = new ArtifactCoordinates( 
+                    cm.getAttribute( ELEM_COORDINATES, ATTR_GROUP_ID, true ) 
+                  , cm.getAttribute( ELEM_COORDINATES, ATTR_ARTIFACT_ID, true ) 
+                  , null 
+                                );
+    
+    List<String> verList = cm.findAttributes( ELEM_VERSIONS, ATTR_VERSION );
+    
+    if( ! Util.isEmpty( verList ) )
+      this.versions.addAll( verList );
+
+    String lChk = cm.getLastUpdate();
+    
+    String negative = cm.getAttribute( ELEM_COORDINATES, ATTR_NEGATIVE, false );
+    
+    if( !Util.isEmpty( negative ) )
+        setNegativeResult( Boolean.parseBoolean( negative ) );
+
+    lastCheck = Long.parseLong( lChk );
+  }
+  
+  private void toXml()
+  {
+    cm.clean();
+    
+    cm.setAttribute( ELEM_COORDINATES, ATTR_GROUP_ID, ga.getGroupId() );
+    cm.setAttribute( ELEM_COORDINATES, ATTR_ARTIFACT_ID, ga.getArtifactId() );
+    
+    if( isNegativeResult() )
+        cm.setAttribute( ELEM_COORDINATES, ATTR_NEGATIVE, "true" );
+    
+    if( !Util.isEmpty( versions ) )
+      cm.setAttribute( ELEM_VERSIONS, ATTR_VERSION, versions );
+    
+    cm.setLastUpdate( ""+lastCheck );
+  }
+  
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAMetadata.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAVMetadata.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAVMetadata.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAVMetadata.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAVMetadata.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,111 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.cache.fs;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.maven.mercury.artifact.ArtifactCoordinates;
+import org.apache.maven.mercury.repository.api.MetadataCorruptionException;
+import org.apache.maven.mercury.repository.api.RepositoryGAVMetadata;
+import org.apache.maven.mercury.repository.metadata.MetadataException;
+import org.apache.maven.mercury.util.Util;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class CachedGAVMetadata
+extends RepositoryGAVMetadata
+{
+  public static final String ELEM_SNAPSHOTS = "snapshots";
+  public static final String ATTR_SNAPSHOT = "snapshot";
+
+  public static final String ELEM_CLASSIFIERS = "classifiers";
+  public static final String ATTR_CLASSIFIER = "classifier";
+
+  CachedMetadata cm;
+  
+  public CachedGAVMetadata( File mdFile )
+  throws FileNotFoundException, IOException, XmlPullParserException, MetadataCorruptionException
+  {
+    cm = new CachedMetadata( mdFile );
+    fromXml();
+  }
+  
+  public CachedGAVMetadata( RepositoryGAVMetadata gavm )
+  throws MetadataException
+  {
+    super( gavm );
+    
+    cm = new CachedMetadata();
+    
+    toXml();
+  }
+  
+  /**
+   * fill GA with data from cm
+   * 
+   * @throws MetadataCorruptionException 
+   */
+  private void fromXml()
+  throws MetadataCorruptionException
+  {
+    gav = new ArtifactCoordinates( 
+                    cm.getAttribute( CachedGAMetadata.ELEM_COORDINATES, CachedGAMetadata.ATTR_GROUP_ID, true ) 
+                  , cm.getAttribute( CachedGAMetadata.ELEM_COORDINATES, CachedGAMetadata.ATTR_ARTIFACT_ID, true ) 
+                  , cm.getAttribute( CachedGAMetadata.ELEM_COORDINATES, CachedGAMetadata.ATTR_VERSION, true ) 
+                                );
+    
+    List<String> snList = cm.findAttributes( ELEM_SNAPSHOTS, ATTR_SNAPSHOT );
+    
+    if( ! Util.isEmpty( snList ) )
+      this.snapshots.addAll( snList );
+    
+    List<String> clList = cm.findAttributes( ELEM_CLASSIFIERS, ATTR_CLASSIFIER );
+    
+    if( ! Util.isEmpty( clList ) )
+      this.classifiers.addAll( clList );
+
+    String lChk = cm.getLastUpdate();
+
+    lastCheck = Long.parseLong( lChk );
+  }
+  
+  private void toXml()
+  {
+    cm.clean();
+    
+    cm.setAttribute( CachedGAMetadata.ELEM_COORDINATES, CachedGAMetadata.ATTR_GROUP_ID, gav.getGroupId() );
+    cm.setAttribute( CachedGAMetadata.ELEM_COORDINATES, CachedGAMetadata.ATTR_ARTIFACT_ID, gav.getArtifactId() );
+    cm.setAttribute( CachedGAMetadata.ELEM_COORDINATES, CachedGAMetadata.ATTR_VERSION, gav.getVersion() );
+    
+    if( !Util.isEmpty( snapshots ) )
+      cm.setAttribute( ELEM_SNAPSHOTS, ATTR_SNAPSHOT, snapshots );
+    
+    cm.setLastUpdate( ""+lastCheck );
+  }
+  
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAVMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedGAVMetadata.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedMetadata.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedMetadata.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedMetadata.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedMetadata.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,229 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.cache.fs;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.maven.mercury.repository.api.MetadataCorruptionException;
+import org.apache.maven.mercury.repository.cache.md.Attribute;
+import org.apache.maven.mercury.repository.cache.md.CachedRawMetadata;
+import org.apache.maven.mercury.repository.cache.md.Element;
+import org.apache.maven.mercury.repository.cache.md.io.xpp3.CachedMetadataXpp3Reader;
+import org.apache.maven.mercury.repository.cache.md.io.xpp3.CachedMetadataXpp3Writer;
+import org.apache.maven.mercury.util.Util;
+import org.codehaus.plexus.lang.DefaultLanguage;
+import org.codehaus.plexus.lang.Language;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * metadata serialization helper - saves/restores element/attribute xml.
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+class CachedMetadata
+{
+  private static final Language LANG = new DefaultLanguage( CachedMetadata.class );
+  
+  private CachedRawMetadata crm;
+  
+  private File mdFile;
+  
+  private static CachedRawMetadata readRawMetadata( File mdFile )
+  throws FileNotFoundException, IOException, XmlPullParserException
+  {
+    CachedMetadataXpp3Reader reader = new CachedMetadataXpp3Reader();
+    return reader.read( new FileReader(mdFile) );
+  }
+  
+  private static void writeRawMetadata( CachedRawMetadata cmd, File mdFile )
+  throws FileNotFoundException, IOException, XmlPullParserException
+  {
+    CachedMetadataXpp3Writer writer = new CachedMetadataXpp3Writer();
+    writer.write( new FileWriter(mdFile), cmd );
+  }
+
+  protected CachedMetadata()
+  {
+    crm = new CachedRawMetadata();
+  }
+
+  protected CachedMetadata( File mdFile )
+  throws FileNotFoundException, IOException, XmlPullParserException
+  {
+    if( mdFile.exists() )
+      crm = readRawMetadata( mdFile );
+    else
+      crm = new CachedRawMetadata();
+    
+    this.mdFile = mdFile;
+  }
+
+  public void save( File mdFile )
+  throws FileNotFoundException, IOException, XmlPullParserException
+  {
+    writeRawMetadata( crm, mdFile );
+  }
+  
+  protected Element findElement( String elem )
+  {
+    List<Element> el = crm.getElements();
+    if( Util.isEmpty( el ) )
+    {
+      el = new ArrayList<Element>();
+      crm.setElements( el );
+    }
+    
+    Element e = null;
+    
+    for( Element le : el )
+      if( le.getName().equals( elem ) )
+      {
+        e = le;
+        break;
+      }
+    
+    if( e == null )
+    {
+      e = new Element();
+      e.setName( elem );
+      el.add( e );
+    }
+    
+    return e;
+  }
+
+  protected void cleanAttribute( Element e, String attr  )
+  {
+    List<Attribute> al = e.getAttributes();
+
+    if( Util.isEmpty( al ))
+      return;
+
+    int sz = al.size();
+    
+    for( int i= (sz-1); i >= 0; i-- )
+    {
+      Attribute a = al.get( i );
+      if( a.getName().equals( attr ) )
+        al.remove( i );
+    }
+  }
+  
+  protected List<String> findAttributes( Element e, String attr  )
+  {
+    List<Attribute> al = e.getAttributes();
+
+    if( Util.isEmpty( al ))
+    {
+      al = new ArrayList<Attribute>();
+      e.setAttributes( al );
+      return null;
+    }
+    
+    List<String> a = null;
+    
+    for( Attribute la : al )
+      if( la.getName().equals( attr ) )
+      {
+        if( a == null )
+          a = new ArrayList<String>();
+        a.add( la.getValue() );
+      }
+    
+    return a;
+  }
+  
+  protected List<String> findAttributes( String elem, String attr  )
+  {
+    Element e = findElement( elem );
+    return findAttributes( e, attr );
+  }
+  
+  protected String getAttribute( String elem, String attr, boolean mandatory  )
+  throws MetadataCorruptionException
+  {
+    Element e = findElement( elem );
+    
+    List<String> a = findAttributes( e, attr );
+    
+    if( Util.isEmpty( a ) )
+      if( mandatory )
+        throw new MetadataCorruptionException(  LANG.getMessage( "no.mandatory.attribute", elem, attr ) );
+      else 
+        return null;
+    
+    return a.get( 0 );
+  }
+  
+  protected void addAttribute( Element e, String attr, String val )
+  {
+    List<Attribute> al = e.getAttributes();
+    if( al == null )
+    {
+      al = new ArrayList<Attribute>();
+      e.setAttributes( al );
+    }
+    
+    Attribute a = new Attribute();
+    a.setName( attr );
+    a.setValue( val );
+    
+    al.add( a );
+  }
+  
+  protected void setAttribute( String elem, String attr, String val)
+  {
+    Element e = findElement( elem );
+    cleanAttribute( e, attr );
+    addAttribute( e, attr, val );
+  }
+
+  protected void setAttribute( String elem, String attr, Collection<String> vals )
+  {
+    Element e = findElement( elem );
+    cleanAttribute( e, attr );
+    for( String val : vals )
+      addAttribute( e, attr, val );
+  }
+  
+  protected void setLastUpdate( String lastUpdated )
+  {
+    crm.setLastUpdated( lastUpdated );
+  }
+  
+  protected String getLastUpdate()
+  {
+    return crm.getLastUpdated();
+  }
+  
+  protected void clean()
+  {
+    crm.setElements( null );
+  }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/CachedMetadata.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/Messages.properties
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/Messages.properties?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/Messages.properties (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/Messages.properties Wed Apr 22 22:56:48 2009
@@ -0,0 +1,22 @@
+#
+#  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.
+#
+bad.root.file=bad root folder {0}
+no.mandatory.attribute=for element {0} mandatory attribute {1} is missing
+
+pass.update=passed update point - cache expired
\ No newline at end of file

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/Messages.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/Messages.properties
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/MetadataCacheFs.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/MetadataCacheFs.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/MetadataCacheFs.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/MetadataCacheFs.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,536 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.cache.fs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.mercury.artifact.ArtifactCoordinates;
+import org.apache.maven.mercury.artifact.ArtifactMetadata;
+import org.apache.maven.mercury.event.EventManager;
+import org.apache.maven.mercury.event.EventTypeEnum;
+import org.apache.maven.mercury.event.GenericEvent;
+import org.apache.maven.mercury.event.MercuryEventListener;
+import org.apache.maven.mercury.repository.api.MetadataCacheException;
+import org.apache.maven.mercury.repository.api.MetadataCorruptionException;
+import org.apache.maven.mercury.repository.api.RepositoryGAMetadata;
+import org.apache.maven.mercury.repository.api.RepositoryGAVMetadata;
+import org.apache.maven.mercury.repository.api.RepositoryMetadataCache;
+import org.apache.maven.mercury.repository.api.RepositoryUpdatePolicy;
+import org.apache.maven.mercury.repository.local.m2.ArtifactLocation;
+import org.apache.maven.mercury.util.FileLockBundle;
+import org.apache.maven.mercury.util.FileUtil;
+import org.apache.maven.mercury.util.TimeUtil;
+import org.codehaus.plexus.lang.DefaultLanguage;
+import org.codehaus.plexus.lang.Language;
+
+/**
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public class MetadataCacheFs
+    implements RepositoryMetadataCache
+{
+    public static final String EVENT_FIND_GA = "find.ga";
+
+    public static final String EVENT_FIND_GAV = "find.gav";
+
+    public static final String EVENT_FIND_RAW = "find.raw";
+
+    public static final String EVENT_UPDATE_GA = "update.ga";
+
+    public static final String EVENT_UPDATE_GAV = "update.gav";
+
+    public static final String EVENT_SAVE_RAW = "save.raw";
+
+    private static final Language LANG = new DefaultLanguage( RepositoryGAVMetadata.class );
+
+    static volatile Map<String, MetadataCacheFs> fsCaches =
+        Collections.synchronizedMap( new HashMap<String, MetadataCacheFs>( 2 ) );
+
+    // store resolved cached data in memory
+    private volatile Map<String, RepositoryGAMetadata> gaCache =
+        (Map<String, RepositoryGAMetadata>) Collections.synchronizedMap( new HashMap<String, RepositoryGAMetadata>( 512 ) );
+
+    private volatile Map<String, RepositoryGAVMetadata> gavCache =
+        (Map<String, RepositoryGAVMetadata>) Collections.synchronizedMap( new HashMap<String, RepositoryGAVMetadata>(
+                                                                                                                      1024 ) );
+
+    private volatile Map<String, byte[]> rawCache =
+        (Map<String, byte[]>) Collections.synchronizedMap( new HashMap<String, byte[]>( 1024 ) );
+
+    private File root;
+
+    private EventManager _eventManager;
+
+    /**
+     * access to all known FS caches
+     * 
+     * @param root
+     * @return
+     * @throws IOException
+     */
+    public static MetadataCacheFs getCache( File root )
+        throws IOException
+    {
+        if ( root == null || ( root.exists() && root.isFile() ) )
+            throw new IllegalArgumentException( LANG.getMessage( "bad.root.file", root == null ? "null"
+                            : root.getAbsolutePath() ) );
+
+        String key = root.getCanonicalPath();
+
+        MetadataCacheFs fsc = fsCaches.get( key );
+
+        if ( fsc == null )
+        {
+            fsc = new MetadataCacheFs( root );
+            fsCaches.put( key, fsc );
+        }
+
+        return fsc;
+    }
+
+    /**
+     * private as it should be obtained via a call to <code>getCache()</code>
+     */
+    private MetadataCacheFs( File root )
+    {
+        this.root = root;
+    }
+
+    public RepositoryGAMetadata findGA( String repoGuid, RepositoryUpdatePolicy up, ArtifactCoordinates coord )
+        throws MetadataCorruptionException
+    {
+        GenericEvent event = null;
+
+        try
+        {
+            String gaKey = getGAKey( coord );
+
+            if ( _eventManager != null )
+                event = new GenericEvent( EventTypeEnum.fsCache, EVENT_FIND_GA, gaKey );
+
+            RepositoryGAMetadata inMem = gaCache.get( gaKey );
+
+            if ( inMem != null )
+            {
+                // im-memory never expires!
+/*                
+                long lastCheckMillis = inMem.getLastCheckMillis();
+
+                if ( up.timestampExpired( lastCheckMillis, null ) )
+                {
+                    inMem.setExpired( true );
+                    gaCache.put( gaKey, inMem );
+                }
+*/
+                if ( _eventManager != null )
+                    event.setResult( "found in memory, expired is " + inMem.isExpired() );
+
+                return inMem;
+            }
+
+            // don't mess with cache if we are past update threshold
+            long now = TimeUtil.getUTCTimestampAsLong();
+            if ( up.timestampExpired( now, null ) )
+            {
+                if ( event != null )
+                    event.setResult( LANG.getMessage( "pass.update" ) );
+
+                return null;
+            }
+
+            File gaDir = getGADir( coord );
+
+            File gamF = getGAFile( gaDir, repoGuid );
+
+            CachedGAMetadata md = null;
+
+            if ( gamF.exists() )
+            {
+                md = new CachedGAMetadata( gamF );
+
+                long lastCheckMillis = md.getLastCheckMillis();
+
+                if ( up != null && up.timestampExpired( lastCheckMillis, null ) )
+                    md.setExpired( true );
+
+                gaCache.put( gaKey, md );
+
+                if ( _eventManager != null )
+                    event.setResult( "found on disk, expired is " + md.isExpired() );
+            }
+            else
+            {
+                if ( _eventManager != null )
+                    event.setResult( "not found" );
+            }
+
+            return md;
+        }
+        catch ( Exception e )
+        {
+            throw new MetadataCorruptionException( e.getMessage() );
+        }
+        finally
+        {
+            if ( _eventManager != null )
+            {
+                event.stop();
+                _eventManager.fireEvent( event );
+            }
+        }
+    }
+
+    public RepositoryGAVMetadata findGAV( String repoGuid, RepositoryUpdatePolicy up, ArtifactCoordinates coord )
+        throws MetadataCorruptionException
+    {
+        FileLockBundle lock = null;
+        GenericEvent event = null;
+
+        try
+        {
+            String gavKey = getGAVKey( coord );
+
+            if ( _eventManager != null )
+                event = new GenericEvent( EventTypeEnum.fsCache, EVENT_FIND_GAV, gavKey );
+
+            RepositoryGAVMetadata inMem = gavCache.get( gavKey );
+
+            if ( inMem != null )
+            {
+/*
+                long lastCheckMillis = inMem.getLastCheckMillis();
+
+                if ( up.timestampExpired( lastCheckMillis, null ) )
+                {
+                    inMem.setExpired( true );
+                    gavCache.put( gavKey, inMem );
+                }
+*/                
+
+                if ( _eventManager != null )
+                    event.setResult( "found in memory, expired is " + inMem.isExpired() );
+
+                return inMem;
+            }
+
+            // don't mess with cache if we are past update threshold
+            long now = TimeUtil.getUTCTimestampAsLong();
+            if ( up.timestampExpired( now, null ) )
+            {
+                if ( event != null )
+                    event.setResult( LANG.getMessage( "pass.update" ) );
+
+                return null;
+            }
+
+            File gavDir = getGAVDir( coord );
+
+            lock = FileUtil.lockDir( gavDir.getCanonicalPath(), 500L, 5L );
+
+            File gavmF = getGAVFile( gavDir, repoGuid );
+
+            CachedGAVMetadata md = null;
+
+            if ( gavmF.exists() )
+            {
+                md = new CachedGAVMetadata( gavmF );
+
+                if ( up != null && up.timestampExpired( md.getLastCheck(), null ) )
+                    md.setExpired( true );
+
+                if ( _eventManager != null )
+                    event.setResult( "found on disk, expired is " + inMem.isExpired() );
+
+                gavCache.put( gavKey, md );
+            }
+            else if ( _eventManager != null )
+                event.setResult( "not found" );
+
+            return md;
+        }
+        catch ( Exception e )
+        {
+            throw new MetadataCorruptionException( e.getMessage() );
+        }
+        finally
+        {
+            if ( lock != null )
+                lock.release();
+
+            if ( _eventManager != null )
+            {
+                event.stop();
+                _eventManager.fireEvent( event );
+            }
+        }
+    }
+
+    public void updateGA( String repoGuid, RepositoryGAMetadata gam )
+        throws MetadataCacheException
+    {
+        FileLockBundle lock = null;
+
+        GenericEvent event = null;
+
+        try
+        {
+            String gaKey = getGAKey( gam.getGA() );
+
+            if ( _eventManager != null )
+                event = new GenericEvent( EventTypeEnum.fsCache, EVENT_UPDATE_GA, gaKey );
+
+            File gaDir = getGADir( gam.getGA() );
+
+            lock = FileUtil.lockDir( gaDir.getCanonicalPath(), 500L, 5L );
+
+            File gamF = getGAFile( gaDir, repoGuid );
+
+            CachedGAMetadata md = new CachedGAMetadata( gam );
+
+            md.cm.save( gamF );
+
+            gaCache.put( gaKey, md );
+        }
+        catch ( Exception e )
+        {
+            throw new MetadataCacheException( e.getMessage() );
+        }
+        finally
+        {
+            if ( lock != null )
+                lock.release();
+
+            if ( _eventManager != null )
+            {
+                event.stop();
+                _eventManager.fireEvent( event );
+            }
+        }
+    }
+
+    public void updateGAV( String repoGuid, RepositoryGAVMetadata gavm )
+        throws MetadataCacheException
+    {
+        FileLockBundle lock = null;
+
+        GenericEvent event = null;
+
+        try
+        {
+            String gavKey = getGAKey( gavm.getGAV() );
+
+            if ( _eventManager != null )
+                event = new GenericEvent( EventTypeEnum.fsCache, EVENT_UPDATE_GA, gavKey );
+
+            File gavDir = getGAVDir( gavm.getGAV() );
+
+            lock = FileUtil.lockDir( gavDir.getCanonicalPath(), 500L, 5L );
+
+            File gavmF = getGAVFile( gavDir, repoGuid );
+
+            CachedGAVMetadata md = new CachedGAVMetadata( gavm );
+
+            md.cm.save( gavmF );
+
+            gavCache.put( gavKey, md );
+        }
+        catch ( Exception e )
+        {
+            throw new MetadataCacheException( e.getMessage() );
+        }
+        finally
+        {
+            if ( lock != null )
+                lock.release();
+
+            if ( _eventManager != null )
+            {
+                event.stop();
+                _eventManager.fireEvent( event );
+            }
+        }
+    }
+
+    public byte[] findRaw( ArtifactMetadata bmd )
+        throws MetadataCacheException
+    {
+        GenericEvent event = null;
+
+        try
+        {
+            String rawKey = bmd.getGAV();
+
+            if ( _eventManager != null )
+                event = new GenericEvent( EventTypeEnum.fsCache, EVENT_FIND_RAW, rawKey );
+
+            byte[] res = rawCache.get( rawKey );
+
+            if ( res != null )
+            {
+                if ( _eventManager != null )
+                    event.setResult( "found in memory" );
+
+                return res;
+            }
+
+            // locking is provided by underlying OS, don't waste the effort
+            File f =
+                new File( getGAVDir( bmd.getEffectiveCoordinates() ), bmd.getArtifactId() + FileUtil.DASH
+                    + bmd.getVersion() + "." + bmd.getType() );
+
+            if ( !f.exists() )
+                return null;
+
+            res = FileUtil.readRawData( f );
+
+            rawCache.put( rawKey, res );
+
+            if ( _eventManager != null )
+                event.setResult( "found on disk" );
+
+            return res;
+        }
+        catch ( IOException e )
+        {
+            throw new MetadataCacheException( e.getMessage() );
+        }
+        finally
+        {
+            if ( _eventManager != null )
+            {
+                event.stop();
+                _eventManager.fireEvent( event );
+            }
+        }
+    }
+
+    public void saveRaw( ArtifactMetadata md, byte[] rawBytes )
+        throws MetadataCacheException
+    {
+        GenericEvent event = null;
+
+        // locking is provided by underlying OS, don't waste the effort
+        try
+        {
+            String rawKey = md.getGAV();
+
+            if ( _eventManager != null )
+                event = new GenericEvent( EventTypeEnum.fsCache, EVENT_SAVE_RAW, rawKey );
+
+            rawCache.put( rawKey, rawBytes );
+
+            File f =
+                new File( getGAVDir( md.getEffectiveCoordinates() ), md.getArtifactId() + FileUtil.DASH
+                    + md.getVersion() + "." + md.getType() );
+
+            FileUtil.writeRawData( f, rawBytes );
+        }
+        catch ( IOException e )
+        {
+            throw new MetadataCacheException( e.getMessage() );
+        }
+        finally
+        {
+            if ( _eventManager != null )
+            {
+                event.stop();
+                _eventManager.fireEvent( event );
+            }
+        }
+    }
+
+    // ---------------------------------------------------------------------------------------
+    private String getGAKey( ArtifactCoordinates coord )
+    {
+        return coord.getGroupId() + ":" + coord.getArtifactId();
+    }
+
+    private String getGAVKey( ArtifactCoordinates coord )
+    {
+        return coord.getGroupId() + ":" + coord.getArtifactId() + ":" + coord.getVersion();
+    }
+
+    private File getGADir( ArtifactCoordinates coord )
+    {
+        File dir = new File( root, coord.getGroupId() + FileUtil.SEP + coord.getArtifactId() );
+
+        if ( !dir.exists() )
+            dir.mkdirs();
+
+        return dir;
+    }
+
+    private File getGAFile( File gaDir, String repoGuid )
+    {
+        return new File( gaDir, "meta-ga-" + repoGuid + ".xml" );
+    }
+
+    private File getGAVDir( ArtifactCoordinates coord )
+    {
+        String version = ArtifactLocation.calculateVersionDir( coord.getVersion() );
+
+        File dir = new File( getGADir( coord ), coord.getArtifactId() + FileUtil.DASH + version );
+
+        if ( !dir.exists() )
+            dir.mkdirs();
+
+        return dir;
+    }
+
+    private File getGAVFile( File gavDir, String repoGuid )
+    {
+        return new File( gavDir, "meta-gav-" + repoGuid + ".xml" );
+    }
+
+    public void register( MercuryEventListener listener )
+    {
+        if ( _eventManager == null )
+            _eventManager = new EventManager();
+
+        _eventManager.register( listener );
+    }
+
+    public void unRegister( MercuryEventListener listener )
+    {
+        if ( _eventManager != null )
+            _eventManager.unRegister( listener );
+    }
+
+    public void setEventManager( EventManager eventManager )
+    {
+        if ( _eventManager == null )
+            _eventManager = eventManager;
+        else
+            _eventManager.getListeners().addAll( eventManager.getListeners() );
+
+    }
+
+    public void clearSession()
+        throws MetadataCacheException
+    {
+        rawCache.clear();
+        gaCache.clear();
+        gavCache.clear();
+    }
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/MetadataCacheFs.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/cache/fs/MetadataCacheFs.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/ArtifactLocation.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/ArtifactLocation.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/ArtifactLocation.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/ArtifactLocation.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,179 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.local.flat;
+
+import org.apache.maven.mercury.artifact.ArtifactMetadata;
+import org.apache.maven.mercury.artifact.version.DefaultArtifactVersion;
+import org.apache.maven.mercury.util.FileUtil;
+
+/**
+ * artifact relative location data object - used by repositories to hold on to intermediate path calculations 
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class ArtifactLocation
+{
+  public static final String POM_EXT = ".pom";
+
+  private String prefix;
+  
+  private String gaPath;
+  private String versionDir;
+  private String baseName;
+  private String version;
+  private String classifier;
+  private String type;
+  
+  private ArtifactMetadata bmd;
+  
+  public ArtifactLocation( String prefix, ArtifactMetadata bmd )
+  {
+    if( prefix == null || bmd == null || bmd.getGroupId() == null || bmd.getArtifactId() == null || bmd.getVersion() == null )
+      return;
+    
+    this.bmd = bmd;
+
+    this.prefix     = prefix;
+    this.gaPath     = bmd.getGroupId().replace( '.', FileUtil.SEP_CHAR ) + FileUtil.SEP + bmd.getArtifactId();
+    this.version    = bmd.getVersion();
+    this.baseName   = bmd.getArtifactId();
+    this.versionDir = this.version;
+    this.classifier = bmd.getClassifier();
+    this.type       = bmd.getType();
+  }
+  
+  public String getRelPath()
+  {
+    return gaPath+FileUtil.SEP+versionDir+FileUtil.SEP+baseName+FileUtil.DASH+version+getDashedClassifier()+'.'+type;
+  }
+  
+  public String getRelPomPath()
+  {
+    return gaPath+FileUtil.SEP+versionDir+FileUtil.SEP+baseName+FileUtil.DASH+version+POM_EXT;
+  }
+  
+  public String getAbsPath()
+  {
+    if( prefix == null )
+      return null;
+
+    return getSeparatedPrefix() + getRelPath();
+  }
+  
+  public String getAbsPomPath()
+  {
+    if( prefix == null )
+      return null;
+
+    return getSeparatedPrefix() + getRelPomPath();
+  }
+  
+  public String getGavPath()
+  {
+    return getGaPath()+FileUtil.SEP+versionDir;
+  }
+  
+  public String getBaseVersion()
+  {
+    if( version == null )
+      return null;
+    
+    DefaultArtifactVersion dav = new DefaultArtifactVersion( version );
+    return dav.getBase();
+  }
+  
+  //---------------------------------------------------------
+  public String getGaPath()
+  {
+    return gaPath;
+  }
+  public void setGaPath( String gaPath )
+  {
+    this.gaPath = gaPath;
+  }
+  public String getVersionDir()
+  {
+    return versionDir;
+  }
+  public void setVersionDir( String versionDir )
+  {
+    this.versionDir = versionDir;
+  }
+  public String getBaseName()
+  {
+    return baseName;
+  }
+  public void setBaseName( String baseName )
+  {
+    this.baseName = baseName;
+  }
+  public String getVersion()
+  {
+    return version;
+  }
+  public void setVersion( String version )
+  {
+    this.version = version;
+  }
+  public String getClassifier()
+  {
+    return classifier;
+  }
+  public String getDashedClassifier()
+  {
+    return (classifier == null||classifier.length()<1) ? "" : FileUtil.DASH+classifier;
+  }
+  public void setClassifier( String classifier )
+  {
+    this.classifier = classifier;
+  }
+  public String getType()
+  {
+    return type;
+  }
+  public void setType( String type )
+  {
+    this.type = type;
+  }
+  public String getPrefix()
+  {
+    return prefix;
+  }
+  public String getSeparatedPrefix()
+  {
+    if( prefix == null )
+      return null;
+
+    return prefix+(prefix.endsWith( FileUtil.SEP ) ? "" : FileUtil.SEP);
+  }
+  public void setPrefix( String prefix )
+  {
+    this.prefix = prefix;
+  }
+
+  @Override
+  public String toString()
+  {
+    return bmd == null ? "no ArtifactBasicMetadata" : bmd.toString();
+  }
+  
+}
\ No newline at end of file

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/ArtifactLocation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/ArtifactLocation.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryFlat.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryFlat.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryFlat.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryFlat.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,132 @@
+/**
+ *  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.
+ */
+package org.apache.maven.mercury.repository.local.flat;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.mercury.repository.api.AbstractRepository;
+import org.apache.maven.mercury.repository.api.LocalRepository;
+import org.apache.maven.mercury.repository.api.NonExistentProtocolException;
+import org.apache.maven.mercury.repository.api.RepositoryReader;
+import org.apache.maven.mercury.repository.api.RepositoryWriter;
+
+public class LocalRepositoryFlat
+extends AbstractRepository
+implements LocalRepository
+{
+  public static final String FLAT_REPOSITORY_TYPE = "flat";
+  
+  public static final String METADATA_FILE_NAME = "maven-metadata-local.xml";
+  
+    private File directory;
+    
+    private boolean createPoms         = false;
+    private boolean createGroupFolders = false;
+
+    //----------------------------------------------------------------------------------
+    public LocalRepositoryFlat( File directory )
+    throws IOException
+    {
+        this( directory, false, false );
+    }
+    //----------------------------------------------------------------------------------
+    public LocalRepositoryFlat( File directory, boolean createGroupFolders, boolean createPoms )
+    throws IOException
+    {
+        this( directory.getCanonicalPath(), directory, createGroupFolders, createPoms );
+    }
+    //----------------------------------------------------------------------------------
+    public LocalRepositoryFlat( String id, File directory, boolean createGroupFolders, boolean createPoms )
+    {
+        super( id, FLAT_REPOSITORY_TYPE );
+        this.directory = directory;
+        this.createGroupFolders = createGroupFolders;
+        this.createPoms = createPoms;
+    }
+    //----------------------------------------------------------------------------------
+    public File getDirectory()
+    {
+        return directory;
+    }
+    //----------------------------------------------------------------------------------
+    public RepositoryReader getReader() 
+    {
+      return RepositoryReader.NULL_READER;
+    }
+    //----------------------------------------------------------------------------------
+    public RepositoryReader getReader( String protocol )
+    {
+       return RepositoryReader.NULL_READER;
+    }
+    //----------------------------------------------------------------------------------
+    public RepositoryWriter getWriter()
+    {
+      return new LocalRepositoryWriterFlat(this);
+    }
+    //----------------------------------------------------------------------------------
+    public RepositoryWriter getWriter( String protocol )
+        throws NonExistentProtocolException
+    {
+      return getWriter();
+    }
+    //----------------------------------------------------------------------------------
+    public boolean isLocal()
+    {
+      return true;
+    }
+    //----------------------------------------------------------------------------------
+    public boolean isReadable()
+    {
+      return false;
+    }
+    //----------------------------------------------------------------------------------
+    public boolean isWriteable()
+    {
+      return true;
+    }
+    //----------------------------------------------------------------------------------
+    public String getType()
+    {
+      return DEFAULT_REPOSITORY_TYPE;
+    }
+    //----------------------------------------------------------------------------------
+    public boolean isCreatePoms()
+    {
+      return createPoms;
+    }
+    public void setCreatePoms( boolean createPoms )
+    {
+      this.createPoms = createPoms;
+    }
+    public boolean isCreateGroupFolders()
+    {
+      return createGroupFolders;
+    }
+    public void setCreateGroupFolders( boolean createGroupFolders )
+    {
+      this.createGroupFolders = createGroupFolders;
+    }
+    public String getMetadataName()
+    {
+      return METADATA_FILE_NAME;
+    }
+    //----------------------------------------------------------------------------------
+    //----------------------------------------------------------------------------------
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryFlat.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryFlat.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision