Return-Path: Delivered-To: apmail-maven-commits-archive@www.apache.org Received: (qmail 55467 invoked from network); 22 Apr 2009 22:58:11 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 22 Apr 2009 22:58:11 -0000 Received: (qmail 69783 invoked by uid 500); 22 Apr 2009 22:58:11 -0000 Delivered-To: apmail-maven-commits-archive@maven.apache.org Received: (qmail 69674 invoked by uid 500); 22 Apr 2009 22:58:11 -0000 Mailing-List: contact commits-help@maven.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@maven.apache.org Delivered-To: mailing list commits@maven.apache.org Received: (qmail 69498 invoked by uid 99); 22 Apr 2009 22:58:10 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 22 Apr 2009 22:58:10 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 22 Apr 2009 22:58:06 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 5ED472388BAD; Wed, 22 Apr 2009 22:57:21 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r767705 [9/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... Date: Wed, 22 Apr 2009 22:57:04 -0000 To: commits@maven.apache.org From: ogusakov@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090422225721.5ED472388BAD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlat.java URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlat.java?rev=767705&view=auto ============================================================================== --- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlat.java (added) +++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlat.java Wed Apr 22 22:56:48 2009 @@ -0,0 +1,340 @@ +/** + * 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.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + +import org.apache.maven.mercury.artifact.Artifact; +import org.apache.maven.mercury.crypto.api.StreamVerifierFactory; +import org.apache.maven.mercury.logging.IMercuryLogger; +import org.apache.maven.mercury.logging.MercuryLoggerManager; +import org.apache.maven.mercury.repository.api.AbstractRepository; +import org.apache.maven.mercury.repository.api.AbstractRepositoryWriter; +import org.apache.maven.mercury.repository.api.LocalRepository; +import org.apache.maven.mercury.repository.api.Repository; +import org.apache.maven.mercury.repository.api.RepositoryException; +import org.apache.maven.mercury.repository.api.RepositoryWriter; +import org.apache.maven.mercury.transport.api.Server; +import org.apache.maven.mercury.util.FileLockBundle; +import org.apache.maven.mercury.util.FileUtil; +import org.apache.maven.mercury.util.Util; +import org.codehaus.plexus.lang.DefaultLanguage; +import org.codehaus.plexus.lang.Language; + +public class LocalRepositoryWriterFlat +extends AbstractRepositoryWriter +implements RepositoryWriter +{ + public static final String SYSTEM_PROPERTY_PARALLEL_WORKERS = "mercury.local.repo.workers"; + public static final int PARALLEL_WORKERS = Integer.parseInt( System.getProperty( SYSTEM_PROPERTY_PARALLEL_WORKERS, "4" ) ); + + public static final long SLEEP_FOR_WORKERS_TICK = 20l; + + public static final String SYSTEM_PROPERTY_SLEEP_FOR_LOCK = "mercury.local.lock.wait.millis"; + public static final long SLEEP_FOR_LOCK = Long.parseLong( System.getProperty( SYSTEM_PROPERTY_SLEEP_FOR_LOCK, "5000" ) ); + + public static final long SLEEP_FOR_LOCK_TICK = 5l; + + private static final IMercuryLogger LOG = MercuryLoggerManager.getLogger( LocalRepositoryWriterFlat.class ); + private static final Language LANG = new DefaultLanguage( LocalRepositoryWriterFlat.class ); + //--------------------------------------------------------------------------------------------------------------- + private static final String [] _protocols = new String [] { "file" }; + + private final LocalRepository _repo; + private final File _repoDir; + private final ArtifactQueue _aq; + + private static final ArifactWriteData LAST_ARTIFACT = new ArifactWriteData( null, null ); + + //--------------------------------------------------------------------------------------------------------------- + public LocalRepositoryWriterFlat( LocalRepository repo ) + { + if( repo == null ) + throw new IllegalArgumentException("localRepo cannot be null"); + + _repoDir = repo.getDirectory(); + if( _repoDir == null ) + throw new IllegalArgumentException("localRepo directory cannot be null"); + + if( !_repoDir.exists() ) + throw new IllegalArgumentException("localRepo directory \""+_repoDir.getAbsolutePath()+"\" should exist"); + + _repo = repo; + _aq = null; + } + //--------------------------------------------------------------------------------------------------------------- + private LocalRepositoryWriterFlat( LocalRepository repo, File repoDir, ArtifactQueue aq ) + { + _repo = repo; + _repoDir = repoDir; + _aq = aq; + } + //--------------------------------------------------------------------------------------------------------------- + public Repository getRepository() + { + return _repo; + } + //--------------------------------------------------------------------------------------------------------------- + public boolean canHandle( String protocol ) + { + return AbstractRepository.DEFAULT_LOCAL_READ_PROTOCOL.equals( protocol ); + } + //--------------------------------------------------------------------------------------------------------------- + public String[] getProtocols() + { + return _protocols; + } + //--------------------------------------------------------------------------------------------------------------- + public void close() + { + } + //--------------------------------------------------------------------------------------------------------------- + public void writeArtifacts( Collection artifacts ) + throws RepositoryException + { + if( artifacts == null || artifacts.size() < 1 ) + return; + + int nWorkers = PARALLEL_WORKERS; + if( artifacts.size() < nWorkers ) + nWorkers = artifacts.size(); + + ArtifactQueue aq = new ArtifactQueue(); + LocalRepositoryWriterFlat [] workers = new LocalRepositoryWriterFlat[ nWorkers ]; + + for( int i=0; i vFacs = null; + Server server = _repo.getServer(); + if( server != null && server.hasWriterStreamVerifierFactories() ) + vFacs = server.getWriterStreamVerifierFactories(); + + if( vFacs == null ) // let it be empty, but not null + vFacs = new HashSet(1); + + aq.addArtifact( new ArifactWriteData( artifact, vFacs ) ); + } + aq.addArtifact( LAST_ARTIFACT ); + + for( int i=0; i vFacs ) + throws RepositoryException + { + if( artifact == null ) + return; + + boolean isPom = "pom".equals( artifact.getType() ); + + byte [] pomBlob = artifact.getPomBlob(); + boolean hasPomBlob = pomBlob != null && pomBlob.length > 0; + + InputStream in = artifact.getStream(); + if( in == null ) + { + File aFile = artifact.getFile(); + if( aFile == null && !isPom ) + { + throw new RepositoryException( LANG.getMessage( "artifact.no.stream", artifact.toString() ) ); + } + + try + { + in = new FileInputStream( aFile ); + } + catch( FileNotFoundException e ) + { + if( !isPom ) + throw new RepositoryException( e ); + } + } + + String relGroupPath = ((LocalRepositoryFlat)_repo).isCreateGroupFolders() ? artifact.getGroupId() : ""; + String versionPath = _repoDir.getAbsolutePath() + (Util.isEmpty( relGroupPath ) ? "" : "/"+relGroupPath); + + String lockDir = null; + FileLockBundle fLock = null; + + try + { + + if( isPom ) + { + if( in == null && !hasPomBlob ) + throw new RepositoryException( LANG.getMessage( "pom.artifact.no.stream", artifact.toString() ) ); + + if( in != null ) + { + byte [] pomBlobBytes = FileUtil.readRawData( in ); + hasPomBlob = pomBlobBytes != null && pomBlobBytes.length > 0; + if( hasPomBlob ) + pomBlob = pomBlobBytes; + } + } + + // create folders + lockDir = versionPath; + + File gav = new File( lockDir ); + gav.mkdirs(); + + fLock = FileUtil.lockDir( lockDir, SLEEP_FOR_LOCK, SLEEP_FOR_LOCK_TICK ); + if( fLock == null ) + throw new RepositoryException( LANG.getMessage( "cannot.lock.gav", lockDir, ""+SLEEP_FOR_LOCK ) ); + + String fName = versionPath+'/'+artifact.getBaseName()+'.'+artifact.getType(); + + if( !isPom ) // first - take care of the binary + FileUtil.writeAndSign( fName, in, vFacs ); + + // if classier - nothing else to do :) + if( artifact.hasClassifier() ) + return; + + if( ((LocalRepositoryFlat)_repo).isCreatePoms() && hasPomBlob ) + { + FileUtil.writeAndSign( versionPath + +'/'+artifact.getArtifactId()+'-'+artifact.getVersion()+".pom", pomBlob, vFacs + ); + } + + } + catch( Exception e ) + { + throw new RepositoryException( e ); + } + finally + { + if( fLock != null ) + fLock.release(); + if ( in != null ) + { + try + { + in.close(); + } + catch ( IOException e ) + { + // ignore, tried our best to clean up + } + } + } + + } + //--------------------------------------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------------------------------------- +} +//================================================================================================================= +class ArifactWriteData +{ + Artifact artifact; + Set vFacs; + + public ArifactWriteData(Artifact artifact, Set vFacs) + { + this.artifact = artifact; + this.vFacs = vFacs; + } +} +//================================================================================================================= +class ArtifactQueue +{ + LinkedList queue = new LinkedList(); + boolean empty = false; + + public synchronized void addArtifact( ArifactWriteData awd ) + { + queue.addLast( awd ); + empty = false; + notify(); + } + + public synchronized ArifactWriteData getArtifact() + throws InterruptedException + { + if( empty ) + return null; + + while( queue.isEmpty() ) + wait(); + + ArifactWriteData res = queue.removeFirst(); + + if( res.artifact == null ) + { + empty = true; + return null; + } + + return res; + } +} +//================================================================================================================= Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlat.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlat.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlatFactory.java URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlatFactory.java?rev=767705&view=auto ============================================================================== --- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlatFactory.java (added) +++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlatFactory.java Wed Apr 22 22:56:48 2009 @@ -0,0 +1,50 @@ +/** + * 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.repository.api.AbstractRepository; +import org.apache.maven.mercury.repository.api.LocalRepository; +import org.apache.maven.mercury.repository.api.Repository; +import org.apache.maven.mercury.repository.api.RepositoryException; +import org.apache.maven.mercury.repository.api.RepositoryWriter; +import org.apache.maven.mercury.repository.api.RepositoryWriterFactory; +import org.codehaus.plexus.lang.DefaultLanguage; +import org.codehaus.plexus.lang.Language; + +public class LocalRepositoryWriterFlatFactory +implements RepositoryWriterFactory +{ + private static final Language LANG = new DefaultLanguage( LocalRepositoryWriterFlatFactory.class ); + private static final LocalRepositoryWriterFlatFactory FACTORY = new LocalRepositoryWriterFlatFactory(); + + static + { + AbstractRepository.register( LocalRepositoryFlat.FLAT_REPOSITORY_TYPE, FACTORY ); + } + + public RepositoryWriter getWriter( Repository repo ) + throws RepositoryException + { + if( repo == null || !(repo instanceof LocalRepository) ) + throw new RepositoryException( LANG.getMessage( "bad.repository.type", repo == null ? "null" : repo.getClass().getName() ) ); + + return new LocalRepositoryWriterFlat( (LocalRepository)repo ); + } + +} Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlatFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/LocalRepositoryWriterFlatFactory.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/Messages.properties URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/Messages.properties?rev=767705&view=auto ============================================================================== --- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/Messages.properties (added) +++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/Messages.properties Wed Apr 22 22:56:48 2009 @@ -0,0 +1,33 @@ +# +# 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.repository.type=repository should implement LocalRepository, instead got {0} +empty.query=received empty query - {0} +binary.not.found=Artifact {0} binary at not found {1} +ga.not.found=Artifact {0} version group not found at {1} +gav.not.found=No artifact version for {0} found in {1} +snapshot.not.found=No snapshot version for {0} found in {1} +gavdir.not.found=No directory {1} for artifact {0} +pom.not.found=Artifact {0} - binary exists, but POM not found in the repository +artifact.no.stream=Cannot find either input stream or file, associated with artifact {0} +pom.artifact.no.stream=Cannot find either pom blob, input stream or file, associated with artifact {0} +no.signature.file=Verifier for {0} is mandatory, but file {1} does not exist +signature.failed=Signature "{0}": verification failed for file {1} +cannot.read.signature.file=Cannot read signature file {0}, error: {1} +cannot.lock.gav=Cannot lock GAV folder {0} in {1} millis +file.is.empty=File {0} exists, but is empty. Data corruption somewhere - please repair metadata. \ No newline at end of file Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/Messages.properties ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/flat/Messages.properties ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/ArtifactLocation.java URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/ArtifactLocation.java?rev=767705&view=auto ============================================================================== --- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/ArtifactLocation.java (added) +++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/ArtifactLocation.java Wed Apr 22 22:56:48 2009 @@ -0,0 +1,285 @@ +/** + * 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.m2; + +import org.apache.maven.mercury.artifact.Artifact; +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+calculateVersionDir( version )+FileUtil.SEP+baseName+FileUtil.DASH+version+getDashedClassifier()+'.'+type; + } + + public String getRelPomPath() + { + return gaPath+FileUtil.SEP+calculateVersionDir( version )+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 getAbsGavPath() + { + if( prefix == null ) + return null; + + return getSeparatedPrefix() + getGavPath(); + } + + public String getGavPath() + { + return getGaPath() + FileUtil.SEP + calculateVersionDir( version ); + } + + public String getBaseVersion() + { + if( version == null ) + return null; + + DefaultArtifactVersion dav = new DefaultArtifactVersion( version ); + return dav.getBase(); + } + + public String getVersionWithoutTS( ) + { + if( version == null ) + return null; + + int li = version.lastIndexOf( '-' ); + + if( li < 1 ) + return version; + + int li2 = version.substring( 0, li ).lastIndexOf( '-' ); + + if( li2 > 0 ) + return version.substring( 0, li2 ); + + return version; + } + + public static String stripTS( String ver ) + { + if( ver == null ) + return null; + + int li = ver.lastIndexOf( '-' ); + + if( li < 1 ) + return ver; + + int li2 = ver.substring( 0, li ).lastIndexOf( '-' ); + + if( li2 > 0 ) + return ver.substring( 0, li2 ); + + return ver; + } + + public static String stripSN( String ver ) + { + if( ver == null ) + return null; + + int li = ver.lastIndexOf( '-' ); + + if( li < 1 ) + return ver; + + return ver.substring( 0, li ); + } + + public static String getTS( String ver ) + { + if( ver == null ) + return null; + + int li = ver.lastIndexOf( '-' ); + + if( li < 1 ) + return ver; + + int li2 = ver.substring( 0, li ).lastIndexOf( '-' ); + + if( li2 > 0 ) + return ver.substring( li2+1 ); + + return ver; + } + + public static String getFileTS( String name ) + { + if( name == null ) + return null; + + int lastDash = name.lastIndexOf( '-' ); + if( lastDash < 2 ) + return null; + + int firstDash = name.lastIndexOf( '-', lastDash-1 ); + if( firstDash < 1 ) + return null; + + String fTS = name.substring( firstDash+1, lastDash ); + + return fTS; + } + //--------------------------------------------------------------------------------------------------------------- + public static String calculateVersionDir( String ver ) + { + if( ver == null ) + return ver; + + if( ver.matches( Artifact.SNAPSHOT_TS_REGEX ) ) + return stripTS( ver )+FileUtil.DASH+Artifact.SNAPSHOT_VERSION; + + return ver; + } + + //--------------------------------------------------------- + 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/m2/ArtifactLocation.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/ArtifactLocation.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryM2.java URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryM2.java?rev=767705&view=auto ============================================================================== --- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryM2.java (added) +++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryM2.java Wed Apr 22 22:56:48 2009 @@ -0,0 +1,166 @@ +/** + * 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.m2; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; + +import org.apache.maven.mercury.builder.api.DependencyProcessor; +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; +import org.apache.maven.mercury.transport.api.Server; +import org.codehaus.plexus.lang.DefaultLanguage; +import org.codehaus.plexus.lang.Language; + +public class LocalRepositoryM2 +extends AbstractRepository +implements LocalRepository +{ + private static final Language LANG = new DefaultLanguage( LocalRepositoryM2.class ); + + private File directory; + + public static final String METADATA_FILE_NAME = "maven-metadata-local.xml"; + + /** indicates that if a-1.0-SNAPSHOT.jar exists, it wins despite any timestamps + * required for Maven comatibility + **/ + private boolean _snapshotAlwaysWins = false; + + //---------------------------------------------------------------------------------- + private void setDirectory( File directory ) + { + if( directory == null ) + throw new IllegalArgumentException( LANG.getMessage( "null.directory" ) ); + + if( !directory.exists() ) + directory.mkdirs(); + + if( !directory.isDirectory() ) + throw new IllegalArgumentException( LANG.getMessage( "file.directory", directory.getAbsolutePath() ) ); + + this.directory = directory; + } + //---------------------------------------------------------------------------------- + public LocalRepositoryM2( Server server, DependencyProcessor dependencyProcessor ) + { + super( server.getId(), DEFAULT_REPOSITORY_TYPE ); + setDirectory( new File( server.getURL().getFile() ) ); + this.server = server; + + setDependencyProcessor( dependencyProcessor ); + } + //---------------------------------------------------------------------------------- + public LocalRepositoryM2( File directory, DependencyProcessor dependencyProcessor ) + throws IOException + { + this( directory.getCanonicalPath(), directory, DEFAULT_REPOSITORY_TYPE, dependencyProcessor ); + } + //---------------------------------------------------------------------------------- + public LocalRepositoryM2( String id, File directory, DependencyProcessor dependencyProcessor ) + { + this( id, directory, DEFAULT_REPOSITORY_TYPE, dependencyProcessor ); + } + //---------------------------------------------------------------------------------- + public LocalRepositoryM2( String id, File directory, String type, DependencyProcessor dependencyProcessor ) + { + super( id, type ); + + setDirectory( directory ); + + setDependencyProcessor( dependencyProcessor ); + + try + { + this.server = new Server( getId(), directory.toURL() ); + } + catch ( MalformedURLException e ) + { + throw new IllegalArgumentException(e); + } + } + //---------------------------------------------------------------------------------- + public File getDirectory() + { + return directory; + } + //---------------------------------------------------------------------------------- + public RepositoryReader getReader() + { + return new LocalRepositoryReaderM2( this, getDependencyProcessor() ); + } + //---------------------------------------------------------------------------------- + public RepositoryReader getReader( String protocol ) + { + return getReader(); + } + //---------------------------------------------------------------------------------- + public RepositoryWriter getWriter() + { + return new LocalRepositoryWriterM2(this); + } + //---------------------------------------------------------------------------------- + public RepositoryWriter getWriter( String protocol ) + throws NonExistentProtocolException + { + return getWriter(); + } + //---------------------------------------------------------------------------------- + public boolean isLocal() + { + return true; + } + //---------------------------------------------------------------------------------- + public boolean isReadable() + { + return true; + } + //---------------------------------------------------------------------------------- + public boolean isWriteable() + { + return true; + } + + public void setSnapshotAlwaysWins( boolean alwaysWins ) + { + _snapshotAlwaysWins = alwaysWins; + } + + public boolean getSnapshotAlwaysWins() + { + return _snapshotAlwaysWins; + } + + //---------------------------------------------------------------------------------- + public String getType() + { + return DEFAULT_REPOSITORY_TYPE; + } + //---------------------------------------------------------------------------------- + public String getMetadataName() + { + return METADATA_FILE_NAME; + } + //---------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------- +} Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryM2.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryM2.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2.java URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2.java?rev=767705&view=auto ============================================================================== --- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2.java (added) +++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2.java Wed Apr 22 22:56:48 2009 @@ -0,0 +1,687 @@ +/** + * 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.m2; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.maven.mercury.artifact.Artifact; +import org.apache.maven.mercury.artifact.ArtifactMetadata; +import org.apache.maven.mercury.artifact.DefaultArtifact; +import org.apache.maven.mercury.artifact.Quality; +import org.apache.maven.mercury.artifact.version.VersionComparator; +import org.apache.maven.mercury.artifact.version.VersionException; +import org.apache.maven.mercury.artifact.version.VersionRange; +import org.apache.maven.mercury.artifact.version.VersionRangeFactory; +import org.apache.maven.mercury.builder.api.DependencyProcessor; +import org.apache.maven.mercury.builder.api.MetadataReader; +import org.apache.maven.mercury.builder.api.MetadataReaderException; +import org.apache.maven.mercury.crypto.api.StreamObserverException; +import org.apache.maven.mercury.crypto.api.StreamVerifier; +import org.apache.maven.mercury.crypto.api.StreamVerifierException; +import org.apache.maven.mercury.crypto.api.StreamVerifierFactory; +import org.apache.maven.mercury.logging.IMercuryLogger; +import org.apache.maven.mercury.logging.MercuryLoggerManager; +import org.apache.maven.mercury.repository.api.AbstracRepositoryReader; +import org.apache.maven.mercury.repository.api.AbstractRepOpResult; +import org.apache.maven.mercury.repository.api.AbstractRepository; +import org.apache.maven.mercury.repository.api.MetadataResults; +import org.apache.maven.mercury.repository.api.ArtifactResults; +import org.apache.maven.mercury.repository.api.LocalRepository; +import org.apache.maven.mercury.repository.api.Repository; +import org.apache.maven.mercury.repository.api.RepositoryException; +import org.apache.maven.mercury.repository.api.RepositoryReader; +import org.apache.maven.mercury.util.FileUtil; +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; + +public class LocalRepositoryReaderM2 + extends AbstracRepositoryReader + implements RepositoryReader, MetadataReader +{ + private static final IMercuryLogger LOG = MercuryLoggerManager.getLogger( LocalRepositoryReaderM2.class ); + + private static final Language LANG = new DefaultLanguage( LocalRepositoryReaderM2.class ); + + // --------------------------------------------------------------------------------------------------------------- + private static final String[] _protocols = new String[] { "file" }; + + LocalRepository _repo; + + File _repoDir; + + // --------------------------------------------------------------------------------------------------------------- + public LocalRepositoryReaderM2( LocalRepository repo, DependencyProcessor mdProcessor ) + { + if ( repo == null ) + throw new IllegalArgumentException( "localRepo cannot be null" ); + + _repoDir = repo.getDirectory(); + if ( _repoDir == null ) + throw new IllegalArgumentException( "localRepo directory cannot be null" ); + + if ( !_repoDir.exists() ) + throw new IllegalArgumentException( "localRepo directory \"" + _repoDir.getAbsolutePath() + + "\" should exist" ); + + _repo = repo; + + if ( mdProcessor == null ) + throw new IllegalArgumentException( "MetadataProcessor cannot be null " ); + + setDependencyProcessor( mdProcessor ); + } + + // --------------------------------------------------------------------------------------------------------------- + public Repository getRepository() + { + return _repo; + } + + // --------------------------------------------------------------------------------------------------------------- + private ArtifactLocation calculateLocation( String root, ArtifactMetadata bmd, AbstractRepOpResult res ) + { + ArtifactLocation loc = new ArtifactLocation( root, bmd ); + + File gaDir = new File( root, loc.getGaPath() ); + + if ( !gaDir.exists() ) + { + if ( LOG.isDebugEnabled() ) + LOG.debug( LANG.getMessage( "ga.not.found", bmd.toString(), loc.getGaPath() ) ); + return null; + } + + Quality vq = new Quality( loc.getVersion() ); + + // RELEASE = LATEST - SNAPSHOTs + if ( Artifact.RELEASE_VERSION.equals( loc.getVersion() ) || Artifact.LATEST_VERSION.equals( loc.getVersion() ) ) + { + final boolean noSnapshots = Artifact.RELEASE_VERSION.equals( loc.getVersion() ); + loc.setVersion( null ); + + final TreeSet ts = new TreeSet( new VersionComparator() ); + + gaDir.listFiles( + new FilenameFilter() + { + public boolean accept( File dir, String name ) + { + if( new File(dir,name).isDirectory() ) + { + if( noSnapshots && name.endsWith( Artifact.SNAPSHOT_VERSION ) ) + return false; + + ts.add( name ); + return true; + } + return false; + } + + } + ); + + if( !ts.isEmpty() ) + loc.setVersion( ts.last() ); + else + { + if( LOG.isDebugEnabled() ) + LOG.debug( LANG.getMessage( "gav.not.found", bmd.toString(), loc.getGaPath() ) ); + return null; + } + + // LATEST is a SNAPSHOT :( + if ( loc.getVersion().endsWith( Artifact.SNAPSHOT_VERSION ) ) + { + loc.setVersionDir( loc.getVersion() ); + + if ( !findLatestSnapshot( bmd, loc, res ) ) + return null; + } + else + // R or L found and actual captured in loc.version + loc.setVersionDir( loc.getVersion() ); + } + // regular snapshot requested + else if ( loc.getVersion().endsWith( Artifact.SNAPSHOT_VERSION ) ) + { + File gavDir = new File( gaDir, loc.getVersion() ); + if ( !gavDir.exists() ) + { +// res.addError( bmd, new RepositoryException( LANG.getMessage( "gavdir.not.found", bmd.toString(), +// gavDir.getAbsolutePath() ) ) ); + if( LOG.isDebugEnabled() ) + LOG.debug( LANG.getMessage( "gavdir.not.found", bmd.toString(), gavDir.getAbsolutePath() ) ); + + return null; + } + + if ( !findLatestSnapshot( bmd, loc, res ) ) + return null; + + } + // time stamped snapshot requested + else if ( vq.equals( Quality.SNAPSHOT_TS_QUALITY ) ) + { + loc.setVersionDir( loc.getVersionWithoutTS() + FileUtil.DASH + Artifact.SNAPSHOT_VERSION ); + } + + return loc; + } + + // --------------------------------------------------------------------------------------------------------------- + public ArtifactResults readArtifacts( Collection query ) + throws RepositoryException, IllegalArgumentException + { + if ( query == null || query.isEmpty() ) + throw new IllegalArgumentException( LANG.getMessage( "empty.query", query == null ? "null" : "empty" ) ); + + ArtifactResults res = new ArtifactResults(); + + Set vFacs = null; + + if ( _repo.hasServer() && _repo.getServer().hasReaderStreamVerifierFactories() ) + vFacs = _repo.getServer().getReaderStreamVerifierFactories(); + + for ( ArtifactMetadata md : query ) + { + if( ! _repo.getRepositoryQualityRange().isAcceptedQuality( md.getRequestedQuality() ) ) + continue; + + DefaultArtifact da = md instanceof DefaultArtifact ? (DefaultArtifact) md : new DefaultArtifact( md ); + + ArtifactLocation loc = calculateLocation( _repoDir.getAbsolutePath(), md, res ); + + if ( loc == null ) + continue; + + File binary = new File( loc.getAbsPath() ); + + // binary calculated + if ( !binary.exists() ) + { +// res.addError( bmd, new RepositoryException( LANG.getMessage( "binary.not.found", bmd.toString(), +// binary.getAbsolutePath() ) ) ); + if( LOG.isDebugEnabled() ) + LOG.debug( LANG.getMessage( "binary.not.found", md.toString(), binary.getAbsolutePath() ) ); + + continue; + } + + try // reading pom if one exists + { + if ( checkFile( binary, vFacs ) ) + { + da.setFile( binary ); + da.setTracker( this._repo ); + } + + if ( "pom".equals( md.getType() ) ) + { + da.setPomBlob( FileUtil.readRawData( binary ) ); + } + else + { + File pomFile = new File( loc.getAbsPomPath() ); + if ( pomFile.exists() ) + { + if ( checkFile( pomFile, vFacs ) ) + da.setPomBlob( FileUtil.readRawData( pomFile ) ); + } + else + LOG.warn( LANG.getMessage( "pom.not.found", md.toString() ) ); + } + + da.setVersion( loc.getVersion() ); + res.add( md, da ); + } + catch ( Exception e ) + { + throw new RepositoryException( e ); + } + } + return res; + } + + // --------------------------------------------------------------------------------------------------------------- + private static boolean checkFile( File f, Set vFacs ) + throws RepositoryException, StreamVerifierException + { + if ( vFacs != null ) + { + String fileName = f.getAbsolutePath(); + + HashSet vs = new HashSet( vFacs.size() ); + + for ( StreamVerifierFactory svf : vFacs ) + { + StreamVerifier sv = svf.newInstance(); + String ext = sv.getAttributes().getExtension(); + String sigFileName = fileName + ( ext.startsWith( "." ) ? "" : "." ) + ext; + File sigFile = new File( sigFileName ); + if ( sigFile.exists() ) + { + try + { + sv.initSignature( FileUtil.readRawDataAsString( sigFile ) ); + } + catch ( IOException e ) + { + throw new RepositoryException( LANG.getMessage( "cannot.read.signature.file", sigFileName, + e.getMessage() ) ); + } + vs.add( sv ); + } + else if ( !sv.getAttributes().isLenient() ) + { + throw new RepositoryException( LANG.getMessage( "no.signature.file", ext, sigFileName ) ); + } + // otherwise ignore absence of signature file, if verifier is lenient + } + + FileInputStream fin = null; + try + { + fin = new FileInputStream( f ); + byte[] buf = new byte[1024]; + int n = -1; + while ( ( n = fin.read( buf ) ) != -1 ) + { + for ( StreamVerifier sv : vs ) + try + { + sv.bytesReady( buf, 0, n ); + } + catch ( StreamObserverException e ) + { + if ( !sv.getAttributes().isLenient() ) + throw new RepositoryException( e ); + } + } + + for ( StreamVerifier sv : vs ) + { + if ( sv.verifySignature() ) + { + if ( sv.getAttributes().isSufficient() ) + break; + } + else + { + if ( !sv.getAttributes().isLenient() ) + throw new RepositoryException( + LANG.getMessage( "signature.failed", + sv.getAttributes().getExtension(), fileName ) ); + } + } + } + catch ( IOException e ) + { + throw new RepositoryException( e ); + } + finally + { + if ( fin != null ) + try + { + fin.close(); + } + catch ( Exception any ) + { + } + } + } + return true; + } + + // --------------------------------------------------------------------------------------------------------------- + /** + * + */ + public MetadataResults readDependencies( Collection query ) + throws RepositoryException, IllegalArgumentException + { + if ( query == null || query.size() < 1 ) + return null; + + MetadataResults ror = null; + + File pomFile = null; + for ( ArtifactMetadata md : query ) + { + if( ! _repo.getRepositoryQualityRange().isAcceptedQuality( md.getRequestedQuality() ) ) + continue; + + String pomPath = + md.getGroupId().replace( '.', '/' ) + "/" + md.getArtifactId() + "/" + ArtifactLocation.calculateVersionDir( md.getVersion() ) + "/" + + md.getArtifactId() + '-' + md.getVersion() + ".pom"; + + pomFile = new File( _repoDir, pomPath ); + if ( !pomFile.exists() ) + { + if( LOG.isDebugEnabled() ) + LOG.debug( "file \"" + pomPath + "\" does not exist in local repo" ); + continue; + } + + try + { + List deps = + _mdProcessor.getDependencies( md, _mdReader == null ? this : _mdReader, System.getenv(), + System.getProperties() ); +// for(ArtifactBasicMetadata d : deps ) +// { +// System.out.println("======> "+d.getScope() ); +// } + ror = MetadataResults.add( ror, md, deps ); + } + catch ( Exception e ) + { + if( LOG.isDebugEnabled() ) + LOG.debug( "error reading " + md.toString() + " dependencies", e ); + continue; + } + + } + + return ror; + } + + // --------------------------------------------------------------------------------------------------------------- + private boolean findLatestSnapshot( final ArtifactMetadata md, final ArtifactLocation loc, AbstractRepOpResult res ) + { + File snapshotFile = new File( loc.getAbsPath() ); + + boolean virtualRequested = md.isVirtual(); + + final boolean virtualExists = snapshotFile.exists(); + + final long virtualLM = virtualExists ? snapshotFile.lastModified() : 0L; + final String virtualTS = virtualExists ? TimeUtil.defaultToSnTs( virtualLM ) : "00000000.000000"; + + // TS exists - return it + if ( ! virtualRequested ) + return snapshotFile.exists(); + + if( virtualExists && ((LocalRepositoryM2)_repo).getSnapshotAlwaysWins() ) + return true; + + // no real SNAPSHOT file, let's try to find one + File gavDir = new File( loc.getAbsGavPath() ); + + String classifier = Util.isEmpty( md.getClassifier() ) ? "" : '-'+md.getClassifier(); + + final String regEx = Artifact.SNAPSHOT_TS_REGEX + classifier + "\\."+md.getCheckedType(); + + final TreeSet ts = new TreeSet( new VersionComparator() ); + + final int pos = md.getArtifactId().length() + 1; + + gavDir.listFiles( new FilenameFilter() + { + public boolean accept( File dir, String name ) + { + if( name.matches( regEx ) ) + { + String ver = name.substring( pos, name.lastIndexOf( '.' ) ); + + if( !virtualExists ) + { + ts.add( ver ); + + return true; + } + + // otherwise - only add it if older'n the SNAPSHOT + String fTS = ArtifactLocation.getFileTS( name ); + + if( fTS.compareTo( virtualTS ) >= 0 ) + { + ts.add( ver ); + + return true; + } + + return false; + + } + + return false; + } + + } + ); + + if( ts.isEmpty() ) + { + if( virtualExists ) // none were older'n the snapshot + { + md.setTimeStamp( virtualTS ); + return true; + } + + if( LOG.isErrorEnabled() ) + LOG.error( LANG.getMessage( "snapshot.not.found", md.toString(), gavDir.getAbsolutePath() ) ); + + return false; + } + + // at east one is older - return it + loc.setVersion( ts.last() ); + + return true; + } + + // --------------------------------------------------------------------------------------------------------------- + /** + * direct disk search, no redirects - I cannot process pom files :( + */ + public MetadataResults readVersions( Collection query ) + throws RepositoryException, IllegalArgumentException + { + if ( query == null || query.size() < 1 ) + return null; + + MetadataResults res = new MetadataResults( query.size() ); + + File gaDir = null; + for ( ArtifactMetadata md : query ) + { + if( ! _repo.getRepositoryQualityRange().isAcceptedQuality( md.getRequestedQuality() ) ) + continue; + + gaDir = new File( _repoDir, md.getGroupId().replace( '.', '/' ) + "/" + md.getArtifactId() ); + if ( !gaDir.exists() ) + continue; + + File[] versionFiles = gaDir.listFiles(); + + VersionRange versionQuery; + try + { + versionQuery = VersionRangeFactory.create( md.getVersion(), _repo.getVersionRangeQualityRange() ); + } + catch ( VersionException e ) + { + res = MetadataResults.add( res, md, new RepositoryException( e ) ); + continue; + } + + Quality vq = new Quality( md.getVersion() ); + + if ( vq.equals( Quality.FIXED_RELEASE_QUALITY ) || vq.equals( Quality.FIXED_LATEST_QUALITY ) + || vq.equals( Quality.SNAPSHOT_QUALITY ) ) + { + ArtifactLocation loc = calculateLocation( _repoDir.getAbsolutePath(), md, res ); + + if ( loc == null ) + continue; + + ArtifactMetadata vmd = new ArtifactMetadata(); + vmd.setGroupId( md.getGroupId() ); + vmd.setArtifactId( md.getArtifactId() ); + vmd.setClassifier( md.getClassifier() ); + vmd.setType( md.getType() ); + vmd.setVersion( loc.getVersion() ); + vmd.setTimeStamp( md.getTimeStamp() ); + + res = MetadataResults.add( res, md, vmd ); + + continue; + + } + + for ( File vf : versionFiles ) + { + if ( !vf.isDirectory() ) + continue; + + String version = vf.getName(); + + Quality q = new Quality( version ); + if ( !_repo.isAcceptedQuality( q ) ) + continue; + + if ( !versionQuery.includes( vf.getName() ) ) + continue; + + ArtifactMetadata vmd = new ArtifactMetadata(); + vmd.setGroupId( md.getGroupId() ); + vmd.setArtifactId( md.getArtifactId() ); + vmd.setClassifier( md.getClassifier() ); + vmd.setType( md.getType() ); + vmd.setVersion( vf.getName() ); + + res = MetadataResults.add( res, md, vmd ); + } + } + return res; + } + + // --------------------------------------------------------------------------------------------------------------- + public byte[] readRawData( ArtifactMetadata md, String classifier, String type ) + throws MetadataReaderException + { + return readRawData( md, classifier, type, false ); + } + // --------------------------------------------------------------------------------------------------------------- + public byte[] readRawData( ArtifactMetadata md, String classifier, String type, boolean exempt ) + throws MetadataReaderException + { + if( ! _repo.getRepositoryQualityRange().isAcceptedQuality( md.getRequestedQuality() ) ) + return null; + + return readRawData( relPathOf( md, classifier, type ), exempt ); + } + + // --------------------------------------------------------------------------------------------------------------- + private static String relPathOf( ArtifactMetadata bmd, String classifier, String type ) + { + String bmdPath = + bmd.getGroupId().replace( '.', '/' ) + '/' + bmd.getArtifactId() + '/' + ArtifactLocation.calculateVersionDir( bmd.getVersion() ); + + String path = bmdPath + '/' + bmd.getBaseName( classifier ) + '.' + ( type == null ? bmd.getType() : type ); + + if( LOG.isDebugEnabled() ) + LOG.debug( bmd.toString()+" path is "+ path); + + return path; + } + + // --------------------------------------------------------------------------------------------------------------- + public byte[] readRawData( String path ) + throws MetadataReaderException + { + return readRawData( path, false ); + } + // --------------------------------------------------------------------------------------------------------------- + public byte[] readRawData( String path, boolean exempt ) + throws MetadataReaderException + { + File file = new File( _repoDir, path ); + + if ( !file.exists() ) + return null; + + FileInputStream fis = null; + + try + { + fis = new FileInputStream( file ); + int len = (int) file.length(); + byte[] pom = new byte[len]; + fis.read( pom ); + return pom; + } + catch ( IOException e ) + { + throw new MetadataReaderException( e ); + } + finally + { + if ( fis != null ) + try + { + fis.close(); + } + catch ( Exception any ) + { + } + } + } + + // --------------------------------------------------------------------------------------------------------------- + public String readStringData( String path ) + throws MetadataReaderException + { + byte[] data = readRawData( path, false ); + if ( data == null ) + return null; + + return new String( data ); + } + + // --------------------------------------------------------------------------------------------------------------- + public boolean canHandle( String protocol ) + { + return AbstractRepository.DEFAULT_LOCAL_READ_PROTOCOL.equals( protocol ); + } + + // --------------------------------------------------------------------------------------------------------------- + public String[] getProtocols() + { + return _protocols; + } + + // --------------------------------------------------------------------------------------------------------------- + public void close() + { + } + // --------------------------------------------------------------------------------------------------------------- + +} Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2Factory.java URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2Factory.java?rev=767705&view=auto ============================================================================== --- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2Factory.java (added) +++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2Factory.java Wed Apr 22 22:56:48 2009 @@ -0,0 +1,51 @@ +/** + * 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.m2; + +import org.apache.maven.mercury.builder.api.DependencyProcessor; +import org.apache.maven.mercury.repository.api.AbstractRepository; +import org.apache.maven.mercury.repository.api.LocalRepository; +import org.apache.maven.mercury.repository.api.Repository; +import org.apache.maven.mercury.repository.api.RepositoryException; +import org.apache.maven.mercury.repository.api.RepositoryReader; +import org.apache.maven.mercury.repository.api.RepositoryReaderFactory; +import org.codehaus.plexus.lang.DefaultLanguage; +import org.codehaus.plexus.lang.Language; + +public class LocalRepositoryReaderM2Factory +implements RepositoryReaderFactory +{ + private static final Language LANG = new DefaultLanguage( LocalRepositoryReaderM2Factory.class ); + private static final LocalRepositoryReaderM2Factory FACTORY = new LocalRepositoryReaderM2Factory(); + + static + { + AbstractRepository.register( AbstractRepository.DEFAULT_REPOSITORY_TYPE, FACTORY ); + } + + public RepositoryReader getReader( Repository repo, DependencyProcessor mdProcessor) + throws RepositoryException + { + if( repo == null || !(repo instanceof LocalRepository) ) + throw new RepositoryException( LANG.getMessage( "bad.repository.type", repo == null ? "null" : repo.getClass().getName() ) ); + + return new LocalRepositoryReaderM2( (LocalRepository)repo, mdProcessor ); + } + +} Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2Factory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryReaderM2Factory.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2.java URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2.java?rev=767705&view=auto ============================================================================== --- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2.java (added) +++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2.java Wed Apr 22 22:56:48 2009 @@ -0,0 +1,449 @@ +/** + * 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.m2; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.maven.mercury.artifact.Artifact; +import org.apache.maven.mercury.artifact.Quality; +import org.apache.maven.mercury.artifact.version.DefaultArtifactVersion; +import org.apache.maven.mercury.crypto.api.StreamObserverException; +import org.apache.maven.mercury.crypto.api.StreamVerifierFactory; +import org.apache.maven.mercury.logging.IMercuryLogger; +import org.apache.maven.mercury.logging.MercuryLoggerManager; +import org.apache.maven.mercury.repository.api.AbstractRepository; +import org.apache.maven.mercury.repository.api.AbstractRepositoryWriter; +import org.apache.maven.mercury.repository.api.LocalRepository; +import org.apache.maven.mercury.repository.api.Repository; +import org.apache.maven.mercury.repository.api.RepositoryException; +import org.apache.maven.mercury.repository.api.RepositoryWriter; +import org.apache.maven.mercury.repository.metadata.AddVersionOperation; +import org.apache.maven.mercury.repository.metadata.Metadata; +import org.apache.maven.mercury.repository.metadata.MetadataBuilder; +import org.apache.maven.mercury.repository.metadata.MetadataException; +import org.apache.maven.mercury.repository.metadata.MetadataOperation; +import org.apache.maven.mercury.repository.metadata.SetSnapshotOperation; +import org.apache.maven.mercury.repository.metadata.Snapshot; +import org.apache.maven.mercury.repository.metadata.SnapshotOperand; +import org.apache.maven.mercury.repository.metadata.StringOperand; +import org.apache.maven.mercury.transport.api.Server; +import org.apache.maven.mercury.util.FileLockBundle; +import org.apache.maven.mercury.util.FileUtil; +import org.codehaus.plexus.lang.DefaultLanguage; +import org.codehaus.plexus.lang.Language; + +public class LocalRepositoryWriterM2 +extends AbstractRepositoryWriter +implements RepositoryWriter +{ + public static final String SYSTEM_PROPERTY_PARALLEL_WORKERS = "mercury.local.repo.workers"; + public static final int PARALLEL_WORKERS = Integer.parseInt( System.getProperty( SYSTEM_PROPERTY_PARALLEL_WORKERS, "4" ) ); + + public static final long SLEEP_FOR_WORKERS_TICK = 20l; + + public static final String SYSTEM_PROPERTY_SLEEP_FOR_LOCK = "mercury.local.lock.wait.millis"; + public static final long SLEEP_FOR_LOCK = Long.parseLong( System.getProperty( SYSTEM_PROPERTY_SLEEP_FOR_LOCK, "5000" ) ); + + public static final long SLEEP_FOR_LOCK_TICK = 5l; + + private static final IMercuryLogger LOG = MercuryLoggerManager.getLogger( LocalRepositoryWriterM2.class ); + private static final Language LANG = new DefaultLanguage( LocalRepositoryWriterM2.class ); + //--------------------------------------------------------------------------------------------------------------- + private static final String [] _protocols = new String [] { "file" }; + + private final LocalRepository _repo; + private final File _repoDir; + private final ArtifactQueue _aq; + + private static final ArifactWriteData LAST_ARTIFACT = new ArifactWriteData( null, null ); + //--------------------------------------------------------------------------------------------------------------- + public LocalRepositoryWriterM2( LocalRepository repo ) + { + if( repo == null ) + throw new IllegalArgumentException("localRepo cannot be null"); + + _repoDir = repo.getDirectory(); + if( _repoDir == null ) + throw new IllegalArgumentException("localRepo directory cannot be null"); + + if( !_repoDir.exists() ) + throw new IllegalArgumentException("localRepo directory \""+_repoDir.getAbsolutePath()+"\" should exist"); + + _repo = repo; + _aq = null; + } + //--------------------------------------------------------------------------------------------------------------- + private LocalRepositoryWriterM2( LocalRepository repo, File repoDir, ArtifactQueue aq ) + { + _repo = repo; + _repoDir = repoDir; + _aq = aq; + } + //--------------------------------------------------------------------------------------------------------------- + public Repository getRepository() + { + return _repo; + } + //--------------------------------------------------------------------------------------------------------------- + public boolean canHandle( String protocol ) + { + return AbstractRepository.DEFAULT_LOCAL_READ_PROTOCOL.equals( protocol ); + } + //--------------------------------------------------------------------------------------------------------------- + public String[] getProtocols() + { + return _protocols; + } + //--------------------------------------------------------------------------------------------------------------- + public void close() + { + } + //--------------------------------------------------------------------------------------------------------------- + public void writeArtifacts( Collection artifacts ) + throws RepositoryException + { + if( artifacts == null || artifacts.size() < 1 ) + return; + + int nWorkers = PARALLEL_WORKERS; + if( artifacts.size() < nWorkers ) + nWorkers = artifacts.size(); + + ArtifactQueue aq = new ArtifactQueue(); + LocalRepositoryWriterM2 [] workers = new LocalRepositoryWriterM2[ nWorkers ]; + + for( int i=0; i vFacs = null; + Server server = _repo.getServer(); + if( server != null && server.hasWriterStreamVerifierFactories() ) + vFacs = server.getWriterStreamVerifierFactories(); + + if( vFacs == null ) // let it be empty, but not null + vFacs = new HashSet(1); + + aq.addArtifact( new ArifactWriteData( artifact, vFacs ) ); + } + aq.addArtifact( LAST_ARTIFACT ); + + for( int i=0; i vFacs ) + throws RepositoryException + { + if( artifact == null ) + return; + + boolean isPom = "pom".equals( artifact.getType() ); + + byte [] pomBlob = artifact.getPomBlob(); + boolean hasPomBlob = pomBlob != null && pomBlob.length > 0; + + InputStream in = artifact.getStream(); + if( in == null ) + { + File aFile = artifact.getFile(); + if( aFile == null && !isPom ) + { + throw new RepositoryException( LANG.getMessage( "artifact.no.stream", artifact.toString() ) ); + } + + try + { + in = new FileInputStream( aFile ); + } + catch( FileNotFoundException e ) + { + if( !isPom ) + throw new RepositoryException( e ); + } + } + DefaultArtifactVersion dav = new DefaultArtifactVersion( artifact.getVersion() ); + Quality aq = dav.getQuality(); + boolean isSnapshot = aq.equals( Quality.SNAPSHOT_QUALITY ) || aq.equals( Quality.SNAPSHOT_TS_QUALITY ); + + String relGroupPath = artifact.getGroupId().replace( '.', '/' )+"/"+artifact.getArtifactId(); + String versionDirName = isSnapshot ? (dav.getBase()+'-'+Artifact.SNAPSHOT_VERSION) : artifact.getVersion(); + String relVersionPath = relGroupPath + '/' + versionDirName; + + String lockDir = null; + FileLockBundle fLock = null; + + try + { + + if( isPom ) + { + if( in == null && !hasPomBlob ) + throw new RepositoryException( LANG.getMessage( "pom.artifact.no.stream", artifact.toString() ) ); + + if( in != null ) + { + byte [] pomBlobBytes = FileUtil.readRawData( in ); + hasPomBlob = pomBlobBytes != null && pomBlobBytes.length > 0; + if( hasPomBlob ) + pomBlob = pomBlobBytes; + } + } + + // create folders + lockDir = _repoDir.getAbsolutePath()+'/'+relGroupPath; + + File gav = new File( lockDir ); + gav.mkdirs(); + +// haveLock = FileUtil.lockDir( lockDir, SLEEP_FOR_LOCK, SLEEP_FOR_LOCK_TICK ); +// if( !haveLock ) +// throw new RepositoryException( _lang.getMessage( "cannot.lock.gav", lockDir, ""+SLEEP_FOR_LOCK ) ); + fLock = FileUtil.lockDir( lockDir, SLEEP_FOR_LOCK, SLEEP_FOR_LOCK_TICK ); + if( fLock == null ) + throw new RepositoryException( LANG.getMessage( "cannot.lock.gav", lockDir, ""+SLEEP_FOR_LOCK ) ); + + String fName = _repoDir.getAbsolutePath()+'/'+relVersionPath+'/'+artifact.getBaseName()+'.'+artifact.getType(); + + if( !isPom ) // first - take care of the binary + { + FileUtil.writeAndSign( fName, in, vFacs ); + artifact.setFile( new File(fName) ); + } + + // GA metadata + File mdFile = new File( _repoDir, relGroupPath+'/'+_repo.getMetadataName() ); + updateGAMetadata( mdFile, artifact, versionDirName, aq, vFacs ); + + // now - GAV metadata + mdFile = new File( _repoDir, relVersionPath+'/'+_repo.getMetadataName() ); + updateGAVMetadata( mdFile, artifact, aq, vFacs ); + + // if classier - nothing else to do :) + if( artifact.hasClassifier() ) + return; + + if( hasPomBlob ) + { + FileUtil.writeAndSign( _repoDir.getAbsolutePath()+'/'+relVersionPath + +'/'+artifact.getArtifactId()+'-'+artifact.getVersion()+".pom", pomBlob, vFacs + ); + } + + } + catch( Exception e ) + { + throw new RepositoryException( e ); + } + finally + { + if( fLock != null ) + fLock.release(); + if ( in != null ) + { + try + { + in.close(); + } + catch ( IOException e ) + { + // ignore, tried our best to clean up + } + } + } + + } + //--------------------------------------------------------------------------------------------------------------- + private void updateGAMetadata( final File mdFile + , final Artifact artifact + , final String version + , final Quality aq + , final Set vFacs + ) + throws MetadataException, IOException, StreamObserverException + { + Metadata md = null; + + if( mdFile.exists() ) + { + try + { + byte [] mdBytes = FileUtil.readRawData( mdFile ); + + if( mdBytes == null ) + throw new MetadataException( LANG.getMessage( "file.is.empty", mdFile.getAbsolutePath() )); + + md = MetadataBuilder.read( new ByteArrayInputStream(mdBytes) ); + } + catch( MetadataException e ) + { + throw e; + } + } + else + { + md = new Metadata(); + md.setGroupId( artifact.getGroupId() ); + md.setArtifactId( artifact.getArtifactId() ); + } + + MetadataOperation mdOp = new AddVersionOperation( new StringOperand( version ) ); + + byte [] resBytes = MetadataBuilder.changeMetadata( md, mdOp ); + + FileUtil.writeAndSign( mdFile.getAbsolutePath(), resBytes, vFacs ); + } + //--------------------------------------------------------------------------------------------------------------- + private void updateGAVMetadata( final File mdFile + , final Artifact artifact + , final Quality aq + , final Set vFacs + ) + throws MetadataException, IOException, StreamObserverException + { + Metadata md = null; + + if( mdFile.exists() ) + { + byte [] mdBytes = FileUtil.readRawData( mdFile ); + md = MetadataBuilder.read( new ByteArrayInputStream(mdBytes) ); + } + else + { + md = new Metadata(); + md.setGroupId( artifact.getGroupId() ); + md.setArtifactId( artifact.getArtifactId() ); + md.setVersion( artifact.getVersion() ); + } + List mdOps = new ArrayList(2); + + if( aq.equals( Quality.SNAPSHOT_TS_QUALITY ) ) + { + Snapshot sn = MetadataBuilder.createSnapshot( artifact.getVersion() ); + sn.setLocalCopy( true ); + mdOps.add( new SetSnapshotOperation( new SnapshotOperand(sn) ) ); + } + + mdOps.add( new AddVersionOperation( new StringOperand(artifact.getVersion()) ) ); + +//System.out.println("added "+artifact.getVersion()); +//System.out.flush(); + byte [] resBytes = MetadataBuilder.changeMetadata( md, mdOps ); + FileUtil.writeAndSign( mdFile.getAbsolutePath(), resBytes, vFacs ); + } + //--------------------------------------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------------------------------------- +} +//================================================================================================================= +class ArifactWriteData +{ + Artifact artifact; + Set vFacs; + + public ArifactWriteData(Artifact artifact, Set vFacs) + { + this.artifact = artifact; + this.vFacs = vFacs; + } +} +//================================================================================================================= +class ArtifactQueue +{ + LinkedList queue = new LinkedList(); + boolean empty = false; + + public synchronized void addArtifact( ArifactWriteData awd ) + { + queue.addLast( awd ); + empty = false; + notify(); + } + + public synchronized ArifactWriteData getArtifact() + throws InterruptedException + { + if( empty ) + return null; + + while( queue.isEmpty() ) + wait(); + + ArifactWriteData res = queue.removeFirst(); + + if( res.artifact == null ) + { + empty = true; + return null; + } + + return res; + } +} +//================================================================================================================= Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2Factory.java URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2Factory.java?rev=767705&view=auto ============================================================================== --- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2Factory.java (added) +++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2Factory.java Wed Apr 22 22:56:48 2009 @@ -0,0 +1,50 @@ +/** + * 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.m2; + +import org.apache.maven.mercury.repository.api.AbstractRepository; +import org.apache.maven.mercury.repository.api.LocalRepository; +import org.apache.maven.mercury.repository.api.Repository; +import org.apache.maven.mercury.repository.api.RepositoryException; +import org.apache.maven.mercury.repository.api.RepositoryWriter; +import org.apache.maven.mercury.repository.api.RepositoryWriterFactory; +import org.codehaus.plexus.lang.DefaultLanguage; +import org.codehaus.plexus.lang.Language; + +public class LocalRepositoryWriterM2Factory +implements RepositoryWriterFactory +{ + private static final Language LANG = new DefaultLanguage( LocalRepositoryWriterM2Factory.class ); + private static final LocalRepositoryWriterM2Factory FACTORY = new LocalRepositoryWriterM2Factory(); + + static + { + AbstractRepository.register( AbstractRepository.DEFAULT_REPOSITORY_TYPE, FACTORY ); + } + + public RepositoryWriter getWriter( Repository repo ) + throws RepositoryException + { + if( repo == null || !(repo instanceof LocalRepository) ) + throw new RepositoryException( LANG.getMessage( "bad.repository.type", repo == null ? "null" : repo.getClass().getName() ) ); + + return new LocalRepositoryWriterM2( (LocalRepository)repo ); + } + +} Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2Factory.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/repository/local/m2/LocalRepositoryWriterM2Factory.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision