001    package org.apache.archiva.repository.content.maven2;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *  http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.archiva.common.utils.VersionUtil;
023    import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
024    import org.apache.archiva.metadata.repository.storage.maven2.ArtifactMappingProvider;
025    import org.apache.archiva.metadata.repository.storage.maven2.Maven2RepositoryPathTranslator;
026    import org.apache.archiva.model.ArchivaArtifact;
027    import org.apache.archiva.model.ArtifactReference;
028    import org.apache.archiva.model.ProjectReference;
029    import org.apache.archiva.model.VersionedReference;
030    import org.apache.archiva.repository.content.PathParser;
031    import org.apache.archiva.repository.layout.LayoutException;
032    import org.apache.commons.lang.StringUtils;
033    import org.slf4j.Logger;
034    import org.slf4j.LoggerFactory;
035    
036    import javax.annotation.PostConstruct;
037    import javax.inject.Inject;
038    import java.util.List;
039    
040    /**
041     * AbstractDefaultRepositoryContent - common methods for working with default (maven 2) layout.
042     */
043    public abstract class AbstractDefaultRepositoryContent
044    {
045        protected Logger log = LoggerFactory.getLogger( getClass() );
046    
047        public static final String MAVEN_METADATA = "maven-metadata.xml";
048    
049        protected static final char PATH_SEPARATOR = '/';
050    
051        protected static final char GROUP_SEPARATOR = '.';
052    
053        protected static final char ARTIFACT_SEPARATOR = '-';
054    
055        private RepositoryPathTranslator pathTranslator = new Maven2RepositoryPathTranslator();
056    
057        private PathParser defaultPathParser = new DefaultPathParser();
058    
059        /**
060         *
061         */
062        @Inject
063        protected List<? extends ArtifactMappingProvider> artifactMappingProviders;
064    
065        @PostConstruct
066        protected void initialize()
067        {
068            // no op
069        }
070    
071        public ArtifactReference toArtifactReference( String path )
072            throws LayoutException
073        {
074            return defaultPathParser.toArtifactReference( path );
075        }
076    
077        public String toMetadataPath( ProjectReference reference )
078        {
079            StringBuilder path = new StringBuilder();
080    
081            path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
082            path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
083            path.append( MAVEN_METADATA );
084    
085            return path.toString();
086        }
087    
088        public String toMetadataPath( VersionedReference reference )
089        {
090            StringBuilder path = new StringBuilder();
091    
092            path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
093            path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
094            if ( reference.getVersion() != null )
095            {
096                // add the version only if it is present
097                path.append( VersionUtil.getBaseVersion( reference.getVersion() ) ).append( PATH_SEPARATOR );
098            }
099            path.append( MAVEN_METADATA );
100    
101            return path.toString();
102        }
103    
104        public String toPath( ArchivaArtifact reference )
105        {
106            if ( reference == null )
107            {
108                throw new IllegalArgumentException( "ArchivaArtifact cannot be null" );
109            }
110    
111            String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() );
112            return toPath( reference.getGroupId(), reference.getArtifactId(), baseVersion, reference.getVersion(),
113                           reference.getClassifier(), reference.getType() );
114        }
115    
116        public String toPath( ArtifactReference reference )
117        {
118            if ( reference == null )
119            {
120                throw new IllegalArgumentException( "Artifact reference cannot be null" );
121            }
122            if ( reference.getVersion() != null )
123            {
124                String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() );
125                return toPath( reference.getGroupId(), reference.getArtifactId(), baseVersion, reference.getVersion(),
126                               reference.getClassifier(), reference.getType() );
127            }
128            return toPath( reference.getGroupId(), reference.getArtifactId(), null, null,
129                           reference.getClassifier(), reference.getType() );
130        }
131    
132        private String formatAsDirectory( String directory )
133        {
134            return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
135        }
136    
137        private String toPath( String groupId, String artifactId, String baseVersion, String version, String classifier,
138                               String type )
139        {
140            if ( baseVersion != null )
141            {
142                return pathTranslator.toPath( groupId, artifactId, baseVersion,
143                                              constructId( artifactId, version, classifier, type ) );
144            }
145            else
146            {
147                return pathTranslator.toPath( groupId, artifactId );
148            }
149        }
150    
151        // TODO: move into the Maven Artifact facet when refactoring away the caller - the caller will need to have access
152        //       to the facet or filename (for the original ID)
153        private String constructId( String artifactId, String version, String classifier, String type )
154        {
155            String ext = null;
156            for ( ArtifactMappingProvider provider : artifactMappingProviders )
157            {
158                ext = provider.mapTypeToExtension( type );
159                if ( ext != null )
160                {
161                    break;
162                }
163            }
164            if ( ext == null )
165            {
166                ext = type;
167            }
168    
169            StringBuilder id = new StringBuilder();
170            if ( ( version != null ) && ( type != null ) )
171            {
172                id.append( artifactId ).append( ARTIFACT_SEPARATOR ).append( version );
173    
174                if ( StringUtils.isNotBlank( classifier ) )
175                {
176                    id.append( ARTIFACT_SEPARATOR ).append( classifier );
177                }
178    
179                id.append( "." ).append( ext );
180            }
181            return id.toString();
182        }
183    }