001    package org.apache.maven.plugin;
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.util.ArrayList;
024    import java.util.HashMap;
025    import java.util.List;
026    import java.util.Map;
027    
028    import org.apache.maven.project.ExtensionDescriptor;
029    import org.apache.maven.project.MavenProject;
030    import org.codehaus.plexus.classworlds.realm.ClassRealm;
031    import org.codehaus.plexus.component.annotations.Component;
032    import org.eclipse.aether.artifact.Artifact;
033    
034    /**
035     * Default extension realm cache implementation. Assumes cached data does not change.
036     */
037    @Component( role = ExtensionRealmCache.class )
038    public class DefaultExtensionRealmCache
039        implements ExtensionRealmCache
040    {
041    
042        private static class CacheKey
043        {
044    
045            private final List<File> files;
046    
047            private final List<Long> timestamps;
048    
049            private final List<Long> sizes;
050    
051            private final List<String> ids;
052    
053            private final int hashCode;
054    
055            public CacheKey( List<? extends Artifact> extensionArtifacts )
056            {
057                this.files = new ArrayList<File>( extensionArtifacts.size() );
058                this.timestamps = new ArrayList<Long>( extensionArtifacts.size() );
059                this.sizes = new ArrayList<Long>( extensionArtifacts.size() );
060                this.ids = new ArrayList<String>( extensionArtifacts.size() );
061    
062                for ( Artifact artifact : extensionArtifacts )
063                {
064                    File file = artifact.getFile();
065                    files.add( file );
066                    timestamps.add( ( file != null ) ? Long.valueOf( file.lastModified() ) : Long.valueOf( 0 ) );
067                    sizes.add( ( file != null ) ? Long.valueOf( file.length() ) : Long.valueOf( 0 ) );
068                    ids.add( artifact.getVersion() );
069                }
070    
071                this.hashCode =
072                    31 * files.hashCode() + 31 * ids.hashCode() + 31 * timestamps.hashCode() + 31 * sizes.hashCode();
073            }
074    
075            @Override
076            public int hashCode()
077            {
078                return hashCode;
079            }
080    
081            @Override
082            public boolean equals( Object o )
083            {
084                if ( o == this )
085                {
086                    return true;
087                }
088    
089                if ( !( o instanceof CacheKey ) )
090                {
091                    return false;
092                }
093    
094                CacheKey other = (CacheKey) o;
095    
096                return ids.equals( other.ids ) && files.equals( other.files ) && timestamps.equals( other.timestamps )
097                    && sizes.equals( other.sizes );
098            }
099    
100        }
101    
102        private final Map<CacheKey, CacheRecord> cache = new HashMap<CacheKey, CacheRecord>();
103    
104        public CacheRecord get( List<? extends Artifact> extensionArtifacts )
105        {
106            return cache.get( new CacheKey( extensionArtifacts ) );
107        }
108    
109        public CacheRecord put( List<? extends Artifact> extensionArtifacts, ClassRealm extensionRealm,
110                                ExtensionDescriptor extensionDescriptor )
111        {
112            if ( extensionRealm == null )
113            {
114                throw new NullPointerException();
115            }
116    
117            CacheKey key = new CacheKey( extensionArtifacts );
118    
119            if ( cache.containsKey( key ) )
120            {
121                throw new IllegalStateException( "Duplicate extension realm for extension " + extensionArtifacts );
122            }
123    
124            CacheRecord record = new CacheRecord( extensionRealm, extensionDescriptor );
125    
126            cache.put( key, record );
127    
128            return record;
129        }
130    
131        public void flush()
132        {
133            cache.clear();
134        }
135    
136        public void register( MavenProject project, CacheRecord record )
137        {
138            // default cache does not track extension usage
139        }
140    
141    }