View Javadoc
1   package org.apache.maven.plugin;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.concurrent.ConcurrentHashMap;
27  
28  import org.apache.maven.project.ExtensionDescriptor;
29  import org.apache.maven.project.MavenProject;
30  import org.codehaus.plexus.classworlds.realm.ClassRealm;
31  import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
32  import org.codehaus.plexus.component.annotations.Component;
33  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
34  import org.eclipse.aether.artifact.Artifact;
35  
36  /**
37   * Default extension realm cache implementation. Assumes cached data does not change.
38   */
39  @Component( role = ExtensionRealmCache.class )
40  public class DefaultExtensionRealmCache
41      implements ExtensionRealmCache, Disposable
42  {
43  
44      protected static class CacheKey
45          implements Key
46      {
47  
48          private final List<File> files;
49  
50          private final List<Long> timestamps;
51  
52          private final List<Long> sizes;
53  
54          private final List<String> ids;
55  
56          private final int hashCode;
57  
58          public CacheKey( List<? extends Artifact> extensionArtifacts )
59          {
60              this.files = new ArrayList<File>( extensionArtifacts.size() );
61              this.timestamps = new ArrayList<Long>( extensionArtifacts.size() );
62              this.sizes = new ArrayList<Long>( extensionArtifacts.size() );
63              this.ids = new ArrayList<String>( extensionArtifacts.size() );
64  
65              for ( Artifact artifact : extensionArtifacts )
66              {
67                  File file = artifact.getFile();
68                  files.add( file );
69                  timestamps.add( ( file != null ) ? Long.valueOf( file.lastModified() ) : Long.valueOf( 0 ) );
70                  sizes.add( ( file != null ) ? Long.valueOf( file.length() ) : Long.valueOf( 0 ) );
71                  ids.add( artifact.getVersion() );
72              }
73  
74              this.hashCode =
75                  31 * files.hashCode() + 31 * ids.hashCode() + 31 * timestamps.hashCode() + 31 * sizes.hashCode();
76          }
77  
78          @Override
79          public int hashCode()
80          {
81              return hashCode;
82          }
83  
84          @Override
85          public boolean equals( Object o )
86          {
87              if ( o == this )
88              {
89                  return true;
90              }
91  
92              if ( !( o instanceof CacheKey ) )
93              {
94                  return false;
95              }
96  
97              CacheKey other = (CacheKey) o;
98  
99              return ids.equals( other.ids ) && files.equals( other.files ) && timestamps.equals( other.timestamps )
100                 && sizes.equals( other.sizes );
101         }
102 
103         @Override
104         public String toString()
105         {
106             return files.toString();
107         }
108     }
109 
110     protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<Key, CacheRecord>();
111 
112     @Override
113     public Key createKey( List<? extends Artifact> extensionArtifacts )
114     {
115         return new CacheKey( extensionArtifacts );
116     }
117 
118     public CacheRecord get( Key key )
119     {
120         return cache.get( key );
121     }
122 
123     public CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor )
124     {
125         if ( extensionRealm == null )
126         {
127             throw new NullPointerException();
128         }
129 
130         if ( cache.containsKey( key ) )
131         {
132             throw new IllegalStateException( "Duplicate extension realm for extension " + key );
133         }
134 
135         CacheRecord record = new CacheRecord( extensionRealm, extensionDescriptor );
136 
137         cache.put( key, record );
138 
139         return record;
140     }
141 
142     public void flush()
143     {
144         for ( CacheRecord record : cache.values() )
145         {
146             ClassRealm realm = record.realm;
147             try
148             {
149                 realm.getWorld().disposeRealm( realm.getId() );
150             }
151             catch ( NoSuchRealmException e )
152             {
153                 // ignore
154             }
155         }
156         cache.clear();
157     }
158 
159     public void register( MavenProject project, Key key, CacheRecord record )
160     {
161         // default cache does not track extension usage
162     }
163 
164     public void dispose()
165     {
166         flush();
167     }
168 
169 }