1 package org.apache.maven.index.reader;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.index.reader.WritableResourceHandler.WritableResource;
23
24 import java.io.Closeable;
25 import java.io.IOException;
26 import java.text.ParseException;
27 import java.util.Date;
28 import java.util.Iterator;
29 import java.util.Map;
30 import java.util.Properties;
31 import java.util.UUID;
32
33 import static org.apache.maven.index.reader.Utils.loadProperties;
34 import static org.apache.maven.index.reader.Utils.storeProperties;
35
36
37
38
39
40
41
42
43
44 public class IndexWriter
45 implements Closeable
46 {
47 private static final int INDEX_V1 = 1;
48
49 private final WritableResourceHandler local;
50
51 private final Properties localIndexProperties;
52
53 private final boolean incremental;
54
55 private final String nextChunkCounter;
56
57 private final String nextChunkName;
58
59 public IndexWriter( final WritableResourceHandler local, final String indexId, final boolean incrementalSupported )
60 throws IOException
61 {
62 if ( local == null )
63 {
64 throw new NullPointerException( "local resource handler null" );
65 }
66 if ( indexId == null )
67 {
68 throw new NullPointerException( "indexId null" );
69 }
70 this.local = local;
71 Properties indexProperties = loadProperties( local.locate( Utils.INDEX_FILE_PREFIX + ".properties" ) );
72 if ( incrementalSupported && indexProperties != null )
73 {
74 this.localIndexProperties = indexProperties;
75
76 String localIndexId = localIndexProperties.getProperty( "nexus.index.id" );
77 if ( localIndexId == null || !localIndexId.equals( indexId ) )
78 {
79 throw new IllegalArgumentException(
80 "index already exists and indexId mismatch or unreadable: " + localIndexId + ", " + indexId );
81 }
82 this.incremental = true;
83 this.nextChunkCounter = calculateNextChunkCounter();
84 this.nextChunkName = Utils.INDEX_FILE_PREFIX + "." + nextChunkCounter + ".gz";
85 }
86 else
87 {
88
89 this.localIndexProperties = new Properties();
90 this.localIndexProperties.setProperty( "nexus.index.id", indexId );
91 this.localIndexProperties.setProperty( "nexus.index.chain-id", UUID.randomUUID().toString() );
92 this.incremental = false;
93 this.nextChunkCounter = null;
94 this.nextChunkName = Utils.INDEX_FILE_PREFIX + ".gz";
95 }
96 }
97
98
99
100
101 public String getIndexId()
102 {
103 return localIndexProperties.getProperty( "nexus.index.id" );
104 }
105
106
107
108
109
110
111 public Date getPublishedTimestamp()
112 {
113 try
114 {
115 String timestamp = localIndexProperties.getProperty( "nexus.index.timestamp" );
116 if ( timestamp != null )
117 {
118 return Utils.INDEX_DATE_FORMAT.parse( timestamp );
119 }
120 return null;
121 }
122 catch ( ParseException e )
123 {
124 throw new RuntimeException( "Corrupt date", e );
125 }
126 }
127
128
129
130
131 public boolean isIncremental()
132 {
133 return incremental;
134 }
135
136
137
138
139
140 public String getChainId()
141 {
142 return localIndexProperties.getProperty( "nexus.index.chain-id" );
143 }
144
145
146
147
148 public String getNextChunkName()
149 {
150 return nextChunkName;
151 }
152
153
154
155
156 public int writeChunk( final Iterator<Map<String, String>> iterator )
157 throws IOException
158 {
159 int written;
160
161 try ( WritableResource writableResource = local.locate( nextChunkName ) )
162 {
163 final ChunkWriter chunkWriter =
164 new ChunkWriter( nextChunkName, writableResource.write(), INDEX_V1, new Date() );
165 try
166 {
167 written = chunkWriter.writeChunk( iterator );
168 }
169 finally
170 {
171 chunkWriter.close();
172 }
173 if ( incremental )
174 {
175
176 }
177 return written;
178 }
179 }
180
181
182
183
184
185
186
187 public void close()
188 throws IOException
189 {
190 try
191 {
192 if ( incremental )
193 {
194 localIndexProperties.setProperty( "nexus.index.last-incremental", nextChunkCounter );
195 }
196 localIndexProperties.setProperty( "nexus.index.timestamp", Utils.INDEX_DATE_FORMAT.format( new Date() ) );
197 storeProperties( local.locate( Utils.INDEX_FILE_PREFIX + ".properties" ), localIndexProperties );
198 }
199 finally
200 {
201 local.close();
202 }
203 }
204
205
206
207
208 private String calculateNextChunkCounter()
209 {
210 String lastChunkCounter = localIndexProperties.getProperty( "nexus.index.last-incremental" );
211 if ( lastChunkCounter != null )
212 {
213 return String.valueOf( Integer.parseInt( lastChunkCounter ) + 1 );
214 }
215 else
216 {
217 return "1";
218 }
219 }
220 }