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