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