View Javadoc
1   package org.apache.maven.index.reader;
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.util.Map;
23  
24  /**
25   * Maven 2 Index record.
26   *
27   * @since 5.1.2
28   */
29  public final class Record
30  {
31      /**
32       * Entry key is field key with some metadata.
33       *
34       * @param <T> The type of the value belonging to this key instance.
35       */
36      public static final class EntryKey<T>
37      {
38          private final String name;
39  
40          private final Class<T> proto;
41  
42          public EntryKey( final String name, final Class<T> proto )
43          {
44              if ( name == null )
45              {
46                  throw new NullPointerException( "name is null" );
47              }
48              if ( proto == null )
49              {
50                  throw new NullPointerException( "proto is null" );
51              }
52              this.name = name;
53              this.proto = proto;
54          }
55  
56          public T coerce( final Object object )
57          {
58              return (T) proto.cast( object );
59          }
60  
61          @Override
62          public boolean equals( final Object o )
63          {
64              if ( this == o )
65              {
66                  return true;
67              }
68              if ( !( o instanceof EntryKey ) )
69              {
70                  return false;
71              }
72              EntryKey entryKey = (EntryKey) o;
73              return name.equals( entryKey.name );
74          }
75  
76          @Override
77          public int hashCode()
78          {
79              return name.hashCode();
80          }
81  
82          @Override
83          public String toString()
84          {
85              return "Key{" + "name='" + name + '\'' + ", type=" + proto.getSimpleName() + '}';
86          }
87      }
88  
89      /**
90       * Key of repository ID entry, that contains {@link String}.
91       */
92      public static final EntryKey<String> REPOSITORY_ID = new EntryKey<String>( "repositoryId", String.class );
93  
94      /**
95       * Key of all groups list entry, that contains {@link java.util.List<String>}.
96       */
97      public static final EntryKey<String[]> ALL_GROUPS = new EntryKey<String[]>( "allGroups", String[].class );
98  
99      /**
100      * Key of root groups list entry, that contains {@link java.util.List<String>}.
101      */
102     public static final EntryKey<String[]> ROOT_GROUPS = new EntryKey<String[]>( "rootGroups", String[].class );
103 
104     /**
105      * Key of index record modification (added to index or removed from index) timestamp entry, that contains {@link
106      * Long}.
107      */
108     public static final EntryKey<Long> REC_MODIFIED = new EntryKey<Long>( "recordModified", Long.class );
109 
110     /**
111      * Key of artifact groupId entry, that contains {@link String}.
112      */
113     public static final EntryKey<String> GROUP_ID = new EntryKey<String>( "groupId", String.class );
114 
115     /**
116      * Key of artifact artifactId entry, that contains {@link String}.
117      */
118     public static final EntryKey<String> ARTIFACT_ID = new EntryKey<String>( "artifactId", String.class );
119 
120     /**
121      * Key of artifact version entry, that contains {@link String}.
122      */
123     public static final EntryKey<String> VERSION = new EntryKey<String>( "version", String.class );
124 
125     /**
126      * Key of artifact classifier entry, that contains {@link String}.
127      */
128     public static final EntryKey<String> CLASSIFIER = new EntryKey<String>( "classifier", String.class );
129 
130     /**
131      * Key of artifact packaging entry, that contains {@link String}.
132      */
133     public static final EntryKey<String> PACKAGING = new EntryKey<String>( "packaging", String.class );
134 
135     /**
136      * Key of artifact file extension, that contains {@link String}.
137      */
138     public static final EntryKey<String> FILE_EXTENSION = new EntryKey<String>( "fileExtension", String.class );
139 
140     /**
141      * Key of artifact file last modified timestamp, that contains {@link Long}.
142      */
143     public static final EntryKey<Long> FILE_MODIFIED = new EntryKey<Long>( "fileModified", Long.class );
144 
145     /**
146      * Key of artifact file size in bytes, that contains {@link Long}.
147      */
148     public static final EntryKey<Long> FILE_SIZE = new EntryKey<Long>( "fileSize", Long.class );
149 
150     /**
151      * Key of artifact Sources presence flag, that contains {@link Boolean}.
152      */
153     public static final EntryKey<Boolean> HAS_SOURCES = new EntryKey<Boolean>( "hasSources", Boolean.class );
154 
155     /**
156      * Key of artifact Javadoc presence flag, that contains {@link Boolean}.
157      */
158     public static final EntryKey<Boolean> HAS_JAVADOC = new EntryKey<Boolean>( "hasJavadoc", Boolean.class );
159 
160     /**
161      * Key of artifact signature presence flag, that contains {@link Boolean}.
162      */
163     public static final EntryKey<Boolean> HAS_SIGNATURE = new EntryKey<Boolean>( "hasSignature", Boolean.class );
164 
165     /**
166      * Key of artifact name (as set in POM), that contains {@link String}.
167      */
168     public static final EntryKey<String> NAME = new EntryKey<String>( "name", String.class );
169 
170     /**
171      * Key of artifact description (as set in POM), that contains {@link String}.
172      */
173     public static final EntryKey<String> DESCRIPTION = new EntryKey<String>( "description", String.class );
174 
175     /**
176      * Key of artifact SHA1 digest, that contains {@link String}.
177      */
178     public static final EntryKey<String> SHA1 = new EntryKey<String>( "sha1", String.class );
179 
180     /**
181      * Key of artifact contained class names, that contains {@link java.util.List<String>}. Extracted by {@code
182      * JarFileContentsIndexCreator}.
183      */
184     public static final EntryKey<String[]> CLASSNAMES = new EntryKey<String[]>( "classNames", String[].class );
185 
186     /**
187      * Key of plugin artifact prefix, that contains {@link String}. Extracted by {@code
188      * MavenPluginArtifactInfoIndexCreator}.
189      */
190     public static final EntryKey<String> PLUGIN_PREFIX = new EntryKey<String>( "pluginPrefix", String.class );
191 
192     /**
193      * Key of plugin artifact goals, that contains {@link java.util.List<String>}. Extracted by {@code
194      * MavenPluginArtifactInfoIndexCreator}.
195      */
196     public static final EntryKey<String[]> PLUGIN_GOALS = new EntryKey<String[]>( "pluginGoals", String[].class );
197 
198     /**
199      * Key of OSGi "Bundle-SymbolicName" manifest entry, that contains {@link String}. Extracted by {@code
200      * OsgiArtifactIndexCreator}.
201      */
202     public static final EntryKey<String> OSGI_BUNDLE_SYMBOLIC_NAME =
203         new EntryKey<String>( "Bundle-SymbolicName", String.class );
204 
205     /**
206      * Key of OSGi "Bundle-Version" manifest entry, that contains {@link String}. Extracted by {@code
207      * OsgiArtifactIndexCreator}.
208      */
209     public static final EntryKey<String> OSGI_BUNDLE_VERSION = new EntryKey<String>( "Bundle-Version", String.class );
210 
211     /**
212      * Key of OSGi "Export-Package" manifest entry, that contains {@link String}. Extracted by {@code
213      * OsgiArtifactIndexCreator}.
214      */
215     public static final EntryKey<String> OSGI_EXPORT_PACKAGE = new EntryKey<String>( "Export-Package", String.class );
216 
217     /**
218      * Key of OSGi "Export-Service" manifest entry, that contains {@link String}. Extracted by {@code
219      * OsgiArtifactIndexCreator}.
220      */
221     public static final EntryKey<String> OSGI_EXPORT_SERVICE = new EntryKey<String>( "Export-Service", String.class );
222 
223     /**
224      * Key of OSGi "Bundle-Description" manifest entry, that contains {@link String}. Extracted by {@code
225      * OsgiArtifactIndexCreator}.
226      */
227     public static final EntryKey<String> OSGI_BUNDLE_DESCRIPTION =
228         new EntryKey<String>( "Bundle-Description", String.class );
229 
230     /**
231      * Key of OSGi "Bundle-Name" manifest entry, that contains {@link String}. Extracted by {@code
232      * OsgiArtifactIndexCreator}.
233      */
234     public static final EntryKey<String> OSGI_BUNDLE_NAME = new EntryKey<String>( "Bundle-Name", String.class );
235 
236     /**
237      * Key of OSGi "Bundle-License" manifest entry, that contains {@link String}. Extracted by {@code
238      * OsgiArtifactIndexCreator}.
239      */
240     public static final EntryKey<String> OSGI_BUNDLE_LICENSE = new EntryKey<String>( "Bundle-License", String.class );
241 
242     /**
243      * Key of OSGi "Bundle-DocURL" manifest entry, that contains {@link String}. Extracted by {@code
244      * OsgiArtifactIndexCreator}.
245      */
246     public static final EntryKey<String> OSGI_EXPORT_DOCURL = new EntryKey<String>( "Bundle-DocURL", String.class );
247 
248     /**
249      * Key of OSGi "Import-Package" manifest entry, that contains {@link String}. Extracted by {@code
250      * OsgiArtifactIndexCreator}.
251      */
252     public static final EntryKey<String> OSGI_IMPORT_PACKAGE = new EntryKey<String>( "Import-Package", String.class );
253 
254     /**
255      * Key of OSGi "Require-Bundle" manifest entry, that contains {@link String}. Extracted by {@code
256      * OsgiArtifactIndexCreator}.
257      */
258     public static final EntryKey<String> OSGI_REQUIRE_BUNDLE = new EntryKey<String>( "Require-Bundle", String.class );
259 
260     /**
261      * Key of OSGi "Provide-Capability" manifest entry, that contains {@link String}. Extracted by {@code
262      * OsgiArtifactIndexCreator}.
263      */
264     public static final EntryKey<String> OSGI_PROVIDE_CAPABILITY =
265         new EntryKey<String>( "Provide-Capability", String.class );
266 
267     /**
268      * Key of OSGi "Require-Capability" manifest entry, that contains {@link String}. Extracted by {@code
269      * OsgiArtifactIndexCreator}.
270      */
271     public static final EntryKey<String> OSGI_REQUIRE_CAPABILITY =
272         new EntryKey<String>( "Require-Capability", String.class );
273 
274     /**
275      * Key of OSGi "Fragment-Host" manifest entry, that contains {@link String}. Extracted by {@code
276      * OsgiArtifactIndexCreator}.
277      */
278     public static final EntryKey<String> OSGI_FRAGMENT_HOST = new EntryKey<String>( "Fragment-Host", String.class );
279 
280     /**
281      * Key of deprecated OSGi "Bundle-RequiredExecutionEnvironment" manifest entry, that contains {@link String}.
282      * Extracted by {@code OsgiArtifactIndexCreator}.
283      */
284     public static final EntryKey<String> OSGI_BREE =
285         new EntryKey<String>( "Bundle-RequiredExecutionEnvironment", String.class );
286 
287     /**
288      * Key for SHA-256 checksum  needed for OSGI content capability that contains {@link String}. Extracted by {@code
289      * OsgiArtifactIndexCreator}.
290      */
291     public static final EntryKey<String> SHA_256 = new EntryKey<String>( "sha256", String.class );
292 
293 
294     /**
295      * Types of returned records returned from index.
296      */
297     public enum Type
298     {
299         /**
300          * Descriptor record. Can be safely ignored.
301          * Contains following entries:
302          * <ul>
303          * <li>{@link #REPOSITORY_ID}</li>
304          * </ul>
305          */
306         DESCRIPTOR,
307 
308         /**
309          * Artifact ADD record. Records of this type should be added to your indexing system.
310          * Contains following entries:
311          * <ul>
312          * <li>{@link #REC_MODIFIED} (when record was added/modified on index)</li>
313          * <li>{@link #GROUP_ID}</li>
314          * <li>{@link #ARTIFACT_ID}</li>
315          * <li>{@link #VERSION}</li>
316          * <li>{@link #CLASSIFIER} (optional)</li>
317          * <li>{@link #FILE_EXTENSION}</li>
318          * <li>{@link #FILE_MODIFIED}</li>
319          * <li>{@link #FILE_SIZE}</li>
320          * <li>{@link #PACKAGING}</li>
321          * <li>{@link #HAS_SOURCES}</li>
322          * <li>{@link #HAS_JAVADOC}</li>
323          * <li>{@link #HAS_SIGNATURE}</li>
324          * <li>{@link #NAME}</li>
325          * <li>{@link #DESCRIPTION}</li>
326          * <li>{@link #SHA1}</li>
327          * <li>{@link #CLASSNAMES} (optional)</li>
328          * <li>{@link #PLUGIN_PREFIX} (optional, for maven-plugins only)</li>
329          * <li>{@link #PLUGIN_GOALS} (optional, for maven-plugins only)</li>
330          * </ul>
331          */
332         ARTIFACT_ADD,
333 
334         /**
335          * Artifact REMOVE record. In case of incremental updates, signals that this artifact was removed. Records of
336          * this type should be removed from your indexing system.
337          * Contains following entries:
338          * <ul>
339          * <li>{@link #REC_MODIFIED} (when record was deleted from index)</li>
340          * <li>{@link #GROUP_ID}</li>
341          * <li>{@link #ARTIFACT_ID}</li>
342          * <li>{@link #VERSION}</li>
343          * <li>{@link #CLASSIFIER} (optional)</li>
344          * <li>{@link #FILE_EXTENSION} (if {@link #CLASSIFIER} present)</li>
345          * <li>{@link #PACKAGING} (optional)</li>
346          * </ul>
347          */
348         ARTIFACT_REMOVE,
349 
350         /**
351          * Special record, containing all the Maven "groupId"s that are enlisted on the index. Can be safely ignored.
352          * Contains following entries:
353          * <ul>
354          * <li>{@link #ALL_GROUPS}</li>
355          * </ul>
356          */
357         ALL_GROUPS,
358 
359         /**
360          * Special record, containing all the root groups of Maven "groupId"s that are enlisted on the index. Can be
361          * safely ignored.
362          * Contains following entries:
363          * <ul>
364          * <li>{@link #ROOT_GROUPS}</li>
365          * </ul>
366          */
367         ROOT_GROUPS
368     }
369 
370     private final Type type;
371 
372     private final Map<EntryKey, Object> expanded;
373 
374     public Record( final Type type, final Map<EntryKey, Object> expanded )
375     {
376         this.type = type;
377         this.expanded = expanded;
378     }
379 
380     /**
381      * Returns the {@link Type} of this record. Usually users would be interested in {@link Type#ARTIFACT_ADD} and
382      * {@link Type#ARTIFACT_REMOVE} types only to maintain their own index. Still, indexer offers extra records too,
383      * see {@link Type} for all existing types.
384      */
385     public Type getType()
386     {
387         return type;
388     }
389 
390     /**
391      * Returns the expanded (processed and expanded synthetic fields) record as {@link Map} ready for consumption.
392      */
393     public Map<EntryKey, Object> getExpanded()
394     {
395         return expanded;
396     }
397 
398     /**
399      * Returns {@code true} if this record contains given {@link EntryKey}.
400      */
401     boolean containsKey( final EntryKey<?> entryKey )
402     {
403         return expanded.containsKey( entryKey );
404     }
405 
406     /**
407      * Type safe handy method to get value from expanded map.
408      */
409     public <T> T get( final EntryKey<T> entryKey )
410     {
411         return entryKey.coerce( expanded.get( entryKey ) );
412     }
413 
414     /**
415      * Type safe handy method to put value to expanded map. Accepts {@code null} values, that removes the mapping.
416      */
417     public <T> T put( final EntryKey<T> entryKey, final T value )
418     {
419         if ( value == null )
420         {
421             return entryKey.coerce( expanded.remove( entryKey ) );
422         }
423         else
424         {
425             if ( !entryKey.proto.isAssignableFrom( value.getClass() ) )
426             {
427                 throw new IllegalArgumentException( "Key " + entryKey + " does not accepts value " + value );
428             }
429             return entryKey.coerce( expanded.put( entryKey, value ) );
430         }
431     }
432 
433     @Override
434     public String toString()
435     {
436         return "Record{" + "type=" + type + ", expanded=" + expanded + '}';
437     }
438 }