1 package org.apache.maven.index.packer;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.OutputStream;
27 import java.text.SimpleDateFormat;
28 import java.util.Date;
29 import java.util.List;
30 import java.util.Properties;
31 import java.util.TimeZone;
32
33 import javax.inject.Inject;
34 import javax.inject.Named;
35 import javax.inject.Singleton;
36
37 import org.apache.maven.index.context.IndexingContext;
38 import org.apache.maven.index.incremental.IncrementalHandler;
39 import org.apache.maven.index.updater.IndexDataWriter;
40 import org.codehaus.plexus.util.FileUtils;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45
46
47
48
49
50 @Singleton
51 @Named
52 public class DefaultIndexPacker
53 implements IndexPacker
54 {
55
56 private final Logger logger = LoggerFactory.getLogger( getClass() );
57
58 protected Logger getLogger()
59 {
60 return logger;
61 }
62
63 private final IncrementalHandler incrementalHandler;
64
65
66 @Inject
67 public DefaultIndexPacker( IncrementalHandler incrementalHandler )
68 {
69 this.incrementalHandler = incrementalHandler;
70 }
71
72 public void packIndex( IndexPackingRequest request )
73 throws IOException, IllegalArgumentException
74 {
75 if ( request.getTargetDir() == null )
76 {
77 throw new IllegalArgumentException( "The target dir is null" );
78 }
79
80 if ( request.getTargetDir().exists() )
81 {
82 if ( !request.getTargetDir().isDirectory() )
83 {
84 throw new IllegalArgumentException(
85 String.format( "Specified target path %s is not a directory",
86 request.getTargetDir().getAbsolutePath() ) );
87 }
88 if ( !request.getTargetDir().canWrite() )
89 {
90 throw new IllegalArgumentException( String.format( "Specified target path %s is not writtable",
91 request.getTargetDir().getAbsolutePath() ) );
92 }
93 }
94 else
95 {
96 if ( !request.getTargetDir().mkdirs() )
97 {
98 throw new IllegalArgumentException( "Can't create " + request.getTargetDir().getAbsolutePath() );
99 }
100 }
101
102
103 File v1File = new File( request.getTargetDir(), IndexingContext.INDEX_FILE_PREFIX + ".gz" );
104
105 Properties info = null;
106
107 try
108 {
109
110
111 info = readIndexProperties( request );
112
113 if ( request.isCreateIncrementalChunks() )
114 {
115 List<Integer> chunk = incrementalHandler.getIncrementalUpdates( request, info );
116
117 if ( chunk == null )
118 {
119 getLogger().debug( "Problem with Chunks, forcing regeneration of whole index" );
120 incrementalHandler.initializeProperties( info );
121 }
122 else if ( chunk.isEmpty() )
123 {
124 getLogger().debug( "No incremental changes, not writing new incremental chunk" );
125 }
126 else
127 {
128 File file = new File( request.getTargetDir(),
129 IndexingContext.INDEX_FILE_PREFIX + "." + info.getProperty(
130 IndexingContext.INDEX_CHUNK_COUNTER ) + ".gz" );
131
132 writeIndexData( request, chunk, file );
133
134 if ( request.isCreateChecksumFiles() )
135 {
136 FileUtils.fileWrite(
137 new File( file.getParentFile(), file.getName() + ".sha1" ).getAbsolutePath(),
138 DigesterUtils.getSha1Digest( file ) );
139
140 FileUtils.fileWrite(
141 new File( file.getParentFile(), file.getName() + ".md5" ).getAbsolutePath(),
142 DigesterUtils.getMd5Digest( file ) );
143 }
144 }
145 }
146 }
147 catch ( IOException e )
148 {
149 getLogger().info( "Unable to read properties file, will force index regeneration" );
150 info = new Properties();
151 incrementalHandler.initializeProperties( info );
152 }
153
154 Date timestamp = request.getContext().getTimestamp();
155
156 if ( timestamp == null )
157 {
158 timestamp = new Date( 0 );
159 }
160
161 if ( request.getFormats().contains( IndexPackingRequest.IndexFormat.FORMAT_V1 ) )
162 {
163 info.setProperty( IndexingContext.INDEX_TIMESTAMP, format( timestamp ) );
164
165 writeIndexData( request, null, v1File );
166
167 if ( request.isCreateChecksumFiles() )
168 {
169 FileUtils.fileWrite( new File( v1File.getParentFile(), v1File.getName() + ".sha1" ).getAbsolutePath(),
170 DigesterUtils.getSha1Digest( v1File ) );
171
172 FileUtils.fileWrite( new File( v1File.getParentFile(), v1File.getName() + ".md5" ).getAbsolutePath(),
173 DigesterUtils.getMd5Digest( v1File ) );
174 }
175 }
176
177 writeIndexProperties( request, info );
178 }
179
180 private Properties readIndexProperties( IndexPackingRequest request )
181 throws IOException
182 {
183 File file = null;
184
185 if ( request.isUseTargetProperties() || request.getContext().getIndexDirectoryFile() == null )
186 {
187 file = new File( request.getTargetDir(), IndexingContext.INDEX_REMOTE_PROPERTIES_FILE );
188 }
189 else
190 {
191 file =
192 new File( request.getContext().getIndexDirectoryFile(), IndexingContext.INDEX_PACKER_PROPERTIES_FILE );
193 }
194
195 Properties properties = new Properties();
196
197 FileInputStream fos = null;
198
199 try
200 {
201 fos = new FileInputStream( file );
202 properties.load( fos );
203 }
204 finally
205 {
206 if ( fos != null )
207 {
208 fos.close();
209 }
210 }
211
212 return properties;
213 }
214
215 void writeIndexData( IndexPackingRequest request, List<Integer> docIndexes, File targetArchive )
216 throws IOException
217 {
218 if ( targetArchive.exists() )
219 {
220 targetArchive.delete();
221 }
222
223 try ( OutputStream os = new FileOutputStream( targetArchive ) )
224 {
225 IndexDataWriter dw = new IndexDataWriter( os );
226 dw.write( request.getContext(), request.getIndexReader(), docIndexes );
227
228 os.flush();
229 }
230 }
231
232 void writeIndexProperties( IndexPackingRequest request, Properties info )
233 throws IOException
234 {
235 File propertyFile =
236 new File( request.getContext().getIndexDirectoryFile(), IndexingContext.INDEX_PACKER_PROPERTIES_FILE );
237 File targetPropertyFile = new File( request.getTargetDir(), IndexingContext.INDEX_REMOTE_PROPERTIES_FILE );
238
239 info.setProperty( IndexingContext.INDEX_ID, request.getContext().getId() );
240
241 try ( OutputStream os = new FileOutputStream( propertyFile ) )
242 {
243 info.store( os, null );
244 }
245
246 try ( OutputStream os = new FileOutputStream( targetPropertyFile ) )
247 {
248 info.store( os, null );
249 }
250
251 if ( request.isCreateChecksumFiles() )
252 {
253 FileUtils.fileWrite( new File( targetPropertyFile.getParentFile(),
254 targetPropertyFile.getName() + ".sha1" ).getAbsolutePath(),
255 DigesterUtils.getSha1Digest( targetPropertyFile ) );
256
257 FileUtils.fileWrite(
258 new File( targetPropertyFile.getParentFile(), targetPropertyFile.getName() + ".md5" ).getAbsolutePath(),
259 DigesterUtils.getMd5Digest( targetPropertyFile ) );
260 }
261 }
262
263 private String format( Date d )
264 {
265 SimpleDateFormat df = new SimpleDateFormat( IndexingContext.INDEX_TIME_FORMAT );
266 df.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
267 return df.format( d );
268 }
269 }