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;
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;
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 try ( FileInputStream fos = new FileInputStream( file ) )
198 {
199 properties.load( fos );
200 }
201
202 return properties;
203 }
204
205 void writeIndexData( IndexPackingRequest request, List<Integer> docIndexes, File targetArchive )
206 throws IOException
207 {
208 if ( targetArchive.exists() )
209 {
210 targetArchive.delete();
211 }
212
213 try ( OutputStream os = new FileOutputStream( targetArchive ) )
214 {
215 IndexDataWriter dw = new IndexDataWriter( os );
216 dw.write( request.getContext(), request.getIndexReader(), docIndexes );
217
218 os.flush();
219 }
220 }
221
222 void writeIndexProperties( IndexPackingRequest request, Properties info )
223 throws IOException
224 {
225 File propertyFile =
226 new File( request.getContext().getIndexDirectoryFile(), IndexingContext.INDEX_PACKER_PROPERTIES_FILE );
227 File targetPropertyFile = new File( request.getTargetDir(), IndexingContext.INDEX_REMOTE_PROPERTIES_FILE );
228
229 info.setProperty( IndexingContext.INDEX_ID, request.getContext().getId() );
230
231 try ( OutputStream os = new FileOutputStream( propertyFile ) )
232 {
233 info.store( os, null );
234 }
235
236 try ( OutputStream os = new FileOutputStream( targetPropertyFile ) )
237 {
238 info.store( os, null );
239 }
240
241 if ( request.isCreateChecksumFiles() )
242 {
243 FileUtils.fileWrite( new File( targetPropertyFile.getParentFile(),
244 targetPropertyFile.getName() + ".sha1" ).getAbsolutePath(),
245 DigesterUtils.getSha1Digest( targetPropertyFile ) );
246
247 FileUtils.fileWrite(
248 new File( targetPropertyFile.getParentFile(), targetPropertyFile.getName() + ".md5" ).getAbsolutePath(),
249 DigesterUtils.getMd5Digest( targetPropertyFile ) );
250 }
251 }
252
253 private String format( Date d )
254 {
255 SimpleDateFormat df = new SimpleDateFormat( IndexingContext.INDEX_TIME_FORMAT );
256 df.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
257 return df.format( d );
258 }
259 }