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.commons.lang3.Validate;
29  import org.apache.maven.artifact.Artifact;
30  import org.apache.maven.project.ExtensionDescriptor;
31  import org.apache.maven.project.MavenProject;
32  import org.codehaus.plexus.classworlds.realm.ClassRealm;
33  import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
34  import org.codehaus.plexus.component.annotations.Component;
35  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
36  
37  /**
38   * Default extension realm cache implementation. Assumes cached data does not change.
39   */
40  @Component( role = ExtensionRealmCache.class )
41  public class DefaultExtensionRealmCache
42      implements ExtensionRealmCache, Disposable
43  {
44  
45      protected static class CacheKey
46          implements Key
47      {
48  
49          private final List<File> files;
50  
51          private final List<Long> timestamps;
52  
53          private final List<Long> sizes;
54  
55          private final List<String> ids;
56  
57          private final int hashCode;
58  
59          public CacheKey( List<Artifact> extensionArtifacts )
60          {
61              this.files = new ArrayList<>( extensionArtifacts.size() );
62              this.timestamps = new ArrayList<>( extensionArtifacts.size() );
63              this.sizes = new ArrayList<>( extensionArtifacts.size() );
64              this.ids = new ArrayList<>( extensionArtifacts.size() );
65  
66              for ( Artifact artifact : extensionArtifacts )
67              {
68                  File file = artifact.getFile();
69                  files.add( file );
70                  timestamps.add( ( file != null ) ? Long.valueOf( file.lastModified() ) : Long.valueOf( 0 ) );
71                  sizes.add( ( file != null ) ? Long.valueOf( file.length() ) : Long.valueOf( 0 ) );
72                  ids.add( artifact.getVersion() );
73              }
74  
75              this.hashCode =
76                  31 * files.hashCode() + 31 * ids.hashCode() + 31 * timestamps.hashCode() + 31 * sizes.hashCode();
77          }
78  
79          @Override
80          public int hashCode()
81          {
82              return hashCode;
83          }
84  
85          @Override
86          public boolean equals( Object o )
87          {
88              if ( o == this )
89              {
90                  return true;
91              }
92  
93              if ( !( o instanceof CacheKey ) )
94              {
95                  return false;
96              }
97  
98              CacheKey other = (CacheKey) o;
99  
100             return ids.equals( other.ids ) && files.equals( other.files ) && timestamps.equals( other.timestamps )
101                 && sizes.equals( other.sizes );
102         }
103 
104         @Override
105         public String toString()
106         {
107             return files.toString();
108         }
109     }
110 
111     protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<>();
112 
113     @Override
114     public Key createKey( List<Artifact> extensionArtifacts )
115     {
116         return new CacheKey( extensionArtifacts );
117     }
118 
119     public CacheRecord get( Key key )
120     {
121         return cache.get( key );
122     }
123 
124     public CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor,
125                             List<Artifact> artifacts )
126     {
127         Validate.notNull( extensionRealm, "extensionRealm cannot be null" );
128 
129         if ( cache.containsKey( key ) )
130         {
131             throw new IllegalStateException( "Duplicate extension realm for extension " + key );
132         }
133 
134         CacheRecord record = new CacheRecord( extensionRealm, extensionDescriptor, artifacts );
135 
136         cache.put( key, record );
137 
138         return record;
139     }
140 
141     public void flush()
142     {
143         for ( CacheRecord record : cache.values() )
144         {
145             ClassRealm realm = record.realm;
146             try
147             {
148                 realm.getWorld().disposeRealm( realm.getId() );
149             }
150             catch ( NoSuchRealmException e )
151             {
152                 // ignore
153             }
154         }
155         cache.clear();
156     }
157 
158     public void register( MavenProject project, Key key, CacheRecord record )
159     {
160         // default cache does not track extension usage
161     }
162 
163     public void dispose()
164     {
165         flush();
166     }
167 
168 }