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 org.apache.maven.index.reader.Record.Type;
23  
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import static org.apache.maven.index.reader.Utils.FIELD_SEPARATOR;
28  import static org.apache.maven.index.reader.Utils.INFO;
29  import static org.apache.maven.index.reader.Utils.UINFO;
30  import static org.apache.maven.index.reader.Utils.nvl;
31  
32  /**
33   * Maven 2 Index record transformer, that transforms {@link Record}s into "native" Maven Indexer records.
34   *
35   * @since 5.1.2
36   */
37  public class RecordCompactor
38  {
39      /**
40       * Compacts {@link Record} into low level MI record with all the encoded fields as physically present in MI binary
41       * chunk.
42       */
43      public Map<String, String> apply( final Record record )
44      {
45          if ( Type.DESCRIPTOR == record.getType() )
46          {
47              return compactDescriptor( record );
48          }
49          else if ( Type.ALL_GROUPS == record.getType() )
50          {
51              return compactAllGroups( record );
52          }
53          else if ( Type.ROOT_GROUPS == record.getType() )
54          {
55              return compactRootGroups( record );
56          }
57          else if ( Type.ARTIFACT_REMOVE == record.getType() )
58          {
59              return compactDeletedArtifact( record );
60          }
61          else if ( Type.ARTIFACT_ADD == record.getType() )
62          {
63              return compactAddedArtifact( record );
64          }
65          else
66          {
67              throw new IllegalArgumentException( "Unknown record: " + record );
68          }
69      }
70  
71      private static Map<String, String> compactDescriptor( final Record record )
72      {
73          final Map<String, String> result = new HashMap<String, String>();
74          result.put( "DESCRIPTOR", "NexusIndex" );
75          result.put( "IDXINFO", "1.0|" + record.get( Record.REPOSITORY_ID ) );
76          return result;
77      }
78  
79      private static Map<String, String> compactAllGroups( final Record record )
80      {
81          final Map<String, String> result = new HashMap<String, String>();
82          result.put( "allGroups", "allGroups" );
83          putIfNotNullAsStringArray( record.get( Record.ALL_GROUPS ), result, "allGroupsList" );
84          return result;
85      }
86  
87      private static Map<String, String> compactRootGroups( final Record record )
88      {
89          final Map<String, String> result = new HashMap<String, String>();
90          result.put( "rootGroups", "allGroups" );
91          putIfNotNullAsStringArray( record.get( Record.ROOT_GROUPS ), result, "rootGroupsList" );
92          return result;
93      }
94  
95      private static Map<String, String> compactDeletedArtifact( final Record record )
96      {
97          final Map<String, String> result = new HashMap<String, String>();
98          putIfNotNullTS( record.get( Record.REC_MODIFIED ), result, "m" );
99          result.put( "del", compactUinfo( record ) );
100         return result;
101     }
102 
103     /**
104      * Expands the "encoded" Maven Indexer record by splitting the synthetic fields and applying expanded field naming.
105      */
106     private static Map<String, String> compactAddedArtifact( final Record record )
107     {
108         final Map<String, String> result = new HashMap<String, String>();
109 
110         // Minimal
111         result.put( UINFO, compactUinfo( record ) );
112 
113         StringBuilder info = new StringBuilder();
114         info.append( nvl( record.get( Record.PACKAGING ) ) );
115         info.append( FIELD_SEPARATOR );
116         info.append( record.get( Record.FILE_MODIFIED ) );
117         info.append( FIELD_SEPARATOR );
118         info.append( record.get( Record.FILE_SIZE ) );
119         info.append( FIELD_SEPARATOR );
120         info.append( record.get( Record.HAS_SOURCES ) ? "1" : "0" );
121         info.append( FIELD_SEPARATOR );
122         info.append( record.get( Record.HAS_JAVADOC ) ? "1" : "0" );
123         info.append( FIELD_SEPARATOR );
124         info.append( record.get( Record.HAS_SIGNATURE ) ? "1" : "0" );
125         info.append( FIELD_SEPARATOR );
126         info.append( nvl( record.get( Record.FILE_EXTENSION ) ) );
127         result.put( INFO, info.toString() );
128 
129         putIfNotNullTS( record.get( Record.REC_MODIFIED ), result, "m" );
130         putIfNotNull( record.get( Record.NAME ), result, "n" );
131         putIfNotNull( record.get( Record.DESCRIPTION ), result, "d" );
132         putIfNotNull( record.get( Record.SHA1 ), result, "1" );
133 
134         // Jar file contents (optional)
135         putIfNotNullAsStringArray( record.get( Record.CLASSNAMES ), result, "classnames" );
136 
137         // Maven Plugin (optional)
138         putIfNotNull( record.get( Record.PLUGIN_PREFIX ), result, "px" );
139         putIfNotNullAsStringArray( record.get( Record.PLUGIN_GOALS ), result, "gx" );
140 
141         // OSGi (optional)
142         putIfNotNull( record.get( Record.OSGI_BUNDLE_SYMBOLIC_NAME ), result, "Bundle-SymbolicName" );
143         putIfNotNull( record.get( Record.OSGI_BUNDLE_VERSION ), result, "Bundle-Version" );
144         putIfNotNull( record.get( Record.OSGI_EXPORT_PACKAGE ), result, "Export-Package" );
145         putIfNotNull( record.get( Record.OSGI_EXPORT_SERVICE ), result, "Export-Service" );
146         putIfNotNull( record.get( Record.OSGI_BUNDLE_DESCRIPTION ), result, "Bundle-Description" );
147         putIfNotNull( record.get( Record.OSGI_BUNDLE_NAME ), result, "Bundle-Name" );
148         putIfNotNull( record.get( Record.OSGI_BUNDLE_LICENSE ), result, "Bundle-License" );
149         putIfNotNull( record.get( Record.OSGI_EXPORT_DOCURL ), result, "Bundle-DocURL" );
150         putIfNotNull( record.get( Record.OSGI_IMPORT_PACKAGE ), result, "Import-Package" );
151         putIfNotNull( record.get( Record.OSGI_REQUIRE_BUNDLE ), result, "Require-Bundle" );
152         putIfNotNull( record.get( Record.OSGI_PROVIDE_CAPABILITY ), result, "Provide-Capability" );
153         putIfNotNull( record.get( Record.OSGI_REQUIRE_CAPABILITY ), result, "Require-Capability" );
154         putIfNotNull( record.get( Record.OSGI_FRAGMENT_HOST ), result, "Fragment-Host" );
155         putIfNotNull( record.get( Record.OSGI_BREE ), result, "Bundle-RequiredExecutionEnvironment" );
156         putIfNotNull( record.get( Record.SHA_256 ), result, "sha256" );
157 
158         return result;
159     }
160 
161     /**
162      * Creates UINFO synthetic field.
163      */
164     private static String compactUinfo( final Record record )
165     {
166         final String classifier = record.get( Record.CLASSIFIER );
167         StringBuilder sb = new StringBuilder();
168         sb.append( record.get( Record.GROUP_ID ) ).append( FIELD_SEPARATOR ).append(
169             record.get( Record.ARTIFACT_ID ) ).append( FIELD_SEPARATOR ).append( record.get( Record.VERSION ) ).append(
170             FIELD_SEPARATOR ).append( nvl( classifier ) );
171         if ( classifier != null )
172         {
173             sb.append( FIELD_SEPARATOR ).append( record.get( Record.FILE_EXTENSION ) );
174         }
175         return sb.toString();
176     }
177 
178     /**
179      * Helper to put a value from source map into target map, if not null.
180      */
181     private static void putIfNotNull( final String source, final Map<String, String> target, final String targetName )
182     {
183         if ( source != null )
184         {
185             target.put( targetName, source );
186         }
187     }
188 
189     /**
190      * Helper to put a {@link Long} value from source map into target map, if not null.
191      */
192     private static void putIfNotNullTS( final Long source, final Map<String, String> target, final String targetName )
193     {
194         if ( source != null )
195         {
196             target.put( targetName, String.valueOf( source ) );
197         }
198     }
199 
200     /**
201      * Helper to put a array value from source map into target map joined with {@link Utils#FIELD_SEPARATOR}, if not
202      * null.
203      */
204     private static void putIfNotNullAsStringArray( final String[] source, final Map<String, String> target,
205                                                    final String targetName )
206     {
207         if ( source != null && source.length > 0 )
208         {
209             StringBuilder sb = new StringBuilder();
210             sb.append( source[0] );
211             for ( int i = 1; i < source.length; i++ )
212             {
213                 sb.append( FIELD_SEPARATOR ).append( source[i] );
214             }
215             target.put( targetName, sb.toString() );
216         }
217     }
218 }