001    package org.apache.maven.artifact.repository.metadata;
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 java.io.File;
023    import java.io.IOException;
024    import java.io.Reader;
025    import java.io.Writer;
026    
027    import org.apache.maven.artifact.Artifact;
028    import org.apache.maven.artifact.metadata.ArtifactMetadata;
029    import org.apache.maven.artifact.repository.ArtifactRepository;
030    import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
031    import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
032    import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
033    import org.codehaus.plexus.util.IOUtil;
034    import org.codehaus.plexus.util.ReaderFactory;
035    import org.codehaus.plexus.util.WriterFactory;
036    import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
037    
038    /**
039     * Shared methods of the repository metadata handling.
040     *
041     * @author <a href="mailto:brett@apache.org">Brett Porter</a>
042     */
043    public abstract class AbstractRepositoryMetadata
044        implements RepositoryMetadata
045    {
046        private Metadata metadata;
047    
048        protected AbstractRepositoryMetadata( Metadata metadata )
049        {
050            this.metadata = metadata;
051        }
052    
053        public String getRemoteFilename()
054        {
055            return "maven-metadata.xml";
056        }
057    
058        public String getLocalFilename( ArtifactRepository repository )
059        {        
060            return "maven-metadata-" + repository.getKey() + ".xml";
061        }
062    
063        public void storeInLocalRepository( ArtifactRepository localRepository,
064                                            ArtifactRepository remoteRepository )
065            throws RepositoryMetadataStoreException
066        {
067            try
068            {
069                updateRepositoryMetadata( localRepository, remoteRepository );
070            }
071            catch ( IOException e )
072            {
073                throw new RepositoryMetadataStoreException( "Error updating group repository metadata", e );
074            }
075            catch ( XmlPullParserException e )
076            {
077                throw new RepositoryMetadataStoreException( "Error updating group repository metadata", e );
078            }
079        }
080    
081        protected void updateRepositoryMetadata( ArtifactRepository localRepository,
082                                                 ArtifactRepository remoteRepository )
083            throws IOException, XmlPullParserException
084        {
085            MetadataXpp3Reader mappingReader = new MetadataXpp3Reader();
086    
087            Metadata metadata = null;
088    
089            File metadataFile = new File( localRepository.getBasedir(),
090                localRepository.pathOfLocalRepositoryMetadata( this, remoteRepository ) );
091    
092            if ( metadataFile.length() == 0 )
093            {
094                metadataFile.delete();
095            }
096            else if ( metadataFile.exists() )
097            {
098                Reader reader = null;
099    
100                try
101                {
102                    reader = ReaderFactory.newXmlReader( metadataFile );
103    
104                    metadata = mappingReader.read( reader, false );
105                }
106                finally
107                {
108                    IOUtil.close( reader );
109                }
110            }
111    
112            boolean changed;
113    
114            // If file could not be found or was not valid, start from scratch
115            if ( metadata == null )
116            {
117                metadata = this.metadata;
118    
119                changed = true;
120            }
121            else
122            {
123                changed = metadata.merge( this.metadata );
124            }
125    
126            // beware meta-versions!
127            String version = metadata.getVersion();
128            if ( version != null && ( Artifact.LATEST_VERSION.equals( version ) || Artifact.RELEASE_VERSION.equals(
129                version ) ) )
130            {
131                // meta-versions are not valid <version/> values...don't write them.
132                metadata.setVersion( null );
133            }
134    
135            if ( changed || !metadataFile.exists() )
136            {
137                Writer writer = null;
138                try
139                {
140                    metadataFile.getParentFile().mkdirs();
141                    writer = WriterFactory.newXmlWriter( metadataFile );
142    
143                    MetadataXpp3Writer mappingWriter = new MetadataXpp3Writer();
144    
145                    mappingWriter.write( writer, metadata );
146                }
147                finally
148                {
149                    IOUtil.close( writer );
150                }
151            }
152            else
153            {
154                metadataFile.setLastModified( System.currentTimeMillis() );
155            }
156        }
157    
158        public String toString()
159        {
160            return "repository metadata for: \'" + getKey() + "\'";
161        }
162    
163        protected static Metadata createMetadata( Artifact artifact,
164                                                  Versioning versioning )
165        {
166            Metadata metadata = new Metadata();
167            metadata.setGroupId( artifact.getGroupId() );
168            metadata.setArtifactId( artifact.getArtifactId() );
169            metadata.setVersion( artifact.getVersion() );
170            metadata.setVersioning( versioning );
171            return metadata;
172        }
173    
174        protected static Versioning createVersioning( Snapshot snapshot )
175        {
176            Versioning versioning = new Versioning();
177            versioning.setSnapshot( snapshot );
178            versioning.updateTimestamp();
179            return versioning;
180        }
181    
182        public void setMetadata( Metadata metadata )
183        {
184            this.metadata = metadata;
185        }
186    
187        public Metadata getMetadata()
188        {
189            return metadata;
190        }
191    
192        public void merge( org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata )
193        {
194            // TODO: not sure that it should assume this, maybe the calls to addMetadata should pre-merge, then artifact replaces?
195            AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
196            this.metadata.merge( repoMetadata.getMetadata() );
197        }
198        
199        public void merge( ArtifactMetadata metadata )
200        {
201            // TODO: not sure that it should assume this, maybe the calls to addMetadata should pre-merge, then artifact replaces?
202            AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
203            this.metadata.merge( repoMetadata.getMetadata() );
204        }
205    
206        public String extendedToString()
207        {
208            StringBuilder buffer = new StringBuilder();
209    
210            buffer.append( "\nRepository Metadata\n--------------------------" );
211            buffer.append( "\nGroupId: " ).append( getGroupId() );
212            buffer.append( "\nArtifactId: " ).append( getArtifactId() );
213            buffer.append( "\nMetadata Type: " ).append( getClass().getName() );
214    
215            return buffer.toString();
216        }
217    
218        public int getNature()
219        {
220            return RELEASE;
221        }
222    
223        public ArtifactRepositoryPolicy getPolicy( ArtifactRepository repository )
224        {
225            int nature = getNature();
226            if ( ( nature & RepositoryMetadata.RELEASE_OR_SNAPSHOT ) == RepositoryMetadata.RELEASE_OR_SNAPSHOT )
227            {
228                ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy( repository.getReleases() );
229                policy.merge( repository.getSnapshots() );
230                return policy;
231            }
232            else if ( ( nature & RepositoryMetadata.SNAPSHOT ) != 0 )
233            {
234                return repository.getSnapshots();
235            }
236            else
237            {
238                return repository.getReleases();
239            }
240        }
241    
242    }