1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.schemaextractor.impl;
21
22
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.io.FileWriter;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.InvalidObjectException;
30 import java.net.URL;
31 import java.util.Enumeration;
32 import java.util.Map;
33 import java.util.Map.Entry;
34 import java.util.Stack;
35 import java.util.UUID;
36 import java.util.regex.Pattern;
37
38 import org.apache.directory.api.i18n.I18n;
39 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
40 import org.apache.directory.api.ldap.model.exception.LdapException;
41 import org.apache.directory.api.ldap.model.ldif.LdapLdifException;
42 import org.apache.directory.api.ldap.model.ldif.LdifEntry;
43 import org.apache.directory.api.ldap.model.ldif.LdifReader;
44 import org.apache.directory.api.ldap.schemaextractor.SchemaLdifExtractor;
45 import org.apache.directory.api.ldap.schemaextractor.UniqueResourceException;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49
50
51
52
53
54
55 public class DefaultSchemaLdifExtractor implements SchemaLdifExtractor
56 {
57
58 private static final String BASE_PATH = "";
59
60
61 private static final String SCHEMA_SUBDIR = "schema";
62
63
64 private static final Logger LOG = LoggerFactory.getLogger( DefaultSchemaLdifExtractor.class );
65
66
67
68
69
70 private static final Pattern EXTRACT_PATTERN = Pattern.compile( ".*schema" + "[/\\Q\\\\E]" + "ou=schema.*\\.ldif" );
71
72
73 private boolean extracted;
74
75
76 private File outputDirectory;
77
78
79
80
81
82
83
84
85 public DefaultSchemaLdifExtractor( File outputDirectory )
86 {
87 LOG.debug( "BASE_PATH set to {}, outputDirectory set to {}", BASE_PATH, outputDirectory );
88 this.outputDirectory = outputDirectory;
89 File schemaDirectory = new File( outputDirectory, SCHEMA_SUBDIR );
90
91 if ( !outputDirectory.exists() )
92 {
93 LOG.debug( "Creating output directory: {}", outputDirectory );
94 if ( !outputDirectory.mkdir() )
95 {
96 LOG.error( "Failed to create outputDirectory: {}", outputDirectory );
97 }
98 }
99 else
100 {
101 LOG.debug( "Output directory exists: no need to create." );
102 }
103
104 if ( !schemaDirectory.exists() )
105 {
106 LOG.info( "Schema directory '{}' does NOT exist: extracted state set to false.", schemaDirectory );
107 extracted = false;
108 }
109 else
110 {
111 LOG.info( "Schema directory '{}' does exist: extracted state set to true.", schemaDirectory );
112 extracted = true;
113 }
114 }
115
116
117
118
119
120
121
122 public boolean isExtracted()
123 {
124 return extracted;
125 }
126
127
128
129
130
131
132
133
134 public void extractOrCopy( boolean overwrite ) throws IOException
135 {
136 if ( !outputDirectory.exists() && !outputDirectory.mkdirs() )
137 {
138 throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, outputDirectory
139 .getAbsolutePath() ) );
140 }
141
142 File schemaDirectory = new File( outputDirectory, SCHEMA_SUBDIR );
143
144 if ( !schemaDirectory.exists() )
145 {
146 if ( !schemaDirectory.mkdirs() )
147 {
148 throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, schemaDirectory
149 .getAbsolutePath() ) );
150 }
151 }
152 else if ( !overwrite )
153 {
154 throw new IOException( I18n.err( I18n.ERR_08001, schemaDirectory.getAbsolutePath() ) );
155 }
156
157 Map<String, Boolean> list = ResourceMap.getResources( EXTRACT_PATTERN );
158
159 for ( Entry<String, Boolean> entry : list.entrySet() )
160 {
161 if ( entry.getValue() )
162 {
163 extractFromClassLoader( entry.getKey() );
164 }
165 else
166 {
167 File resource = new File( entry.getKey() );
168 copyFile( resource, getDestinationFile( resource ) );
169 }
170 }
171 }
172
173
174
175
176
177
178
179
180
181 public void extractOrCopy() throws IOException
182 {
183 extractOrCopy( false );
184 }
185
186
187
188
189
190
191
192
193
194
195 private void copyFile( File source, File destination ) throws IOException
196 {
197 LOG.debug( "copyFile(): source = {}, destination = {}", source, destination );
198
199 if ( !destination.getParentFile().exists() && !destination.getParentFile().mkdirs() )
200 {
201 throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, destination.getParentFile()
202 .getAbsolutePath() ) );
203 }
204
205 if ( !source.getParentFile().exists() )
206 {
207 throw new FileNotFoundException( I18n.err( I18n.ERR_08002, source.getAbsolutePath() ) );
208 }
209
210 FileWriter out = new FileWriter( destination );
211
212 LdifReader ldifReader = null;
213
214 try
215 {
216 ldifReader = new LdifReader( source );
217 boolean first = true;
218 LdifEntry ldifEntry = null;
219
220 while ( ldifReader.hasNext() )
221 {
222 if ( first )
223 {
224 ldifEntry = ldifReader.next();
225
226 if ( ldifEntry.get( SchemaConstants.ENTRY_UUID_AT ) == null )
227 {
228
229 UUID entryUuid = UUID.randomUUID();
230 ldifEntry.addAttribute( SchemaConstants.ENTRY_UUID_AT, entryUuid.toString() );
231 }
232
233 first = false;
234 }
235 else
236 {
237
238 String msg = I18n.err( I18n.ERR_08003, source );
239 LOG.error( msg );
240 throw new InvalidObjectException( msg );
241 }
242 }
243
244
245 String ldifString = "version: 1\n" + ldifEntry.toString();
246
247 out.write( ldifString );
248 out.flush();
249 }
250 catch ( LdapLdifException ne )
251 {
252 String msg = I18n.err( I18n.ERR_08004, source, ne.getLocalizedMessage() );
253 LOG.error( msg );
254 throw new InvalidObjectException( msg );
255 }
256 catch ( LdapException ne )
257 {
258 String msg = I18n.err( I18n.ERR_08004, source, ne.getLocalizedMessage() );
259 LOG.error( msg );
260 throw new InvalidObjectException( msg );
261 }
262 finally
263 {
264 ldifReader.close();
265 out.close();
266 }
267 }
268
269
270
271
272
273
274
275
276
277 private File assembleDestinationFile( Stack<String> fileComponentStack )
278 {
279 File destinationFile = outputDirectory.getAbsoluteFile();
280
281 while ( !fileComponentStack.isEmpty() )
282 {
283 destinationFile = new File( destinationFile, fileComponentStack.pop() );
284 }
285
286 return destinationFile;
287 }
288
289
290
291
292
293
294
295
296 private File getDestinationFile( File resource )
297 {
298 File parent = resource.getParentFile();
299 Stack<String> fileComponentStack = new Stack<String>();
300 fileComponentStack.push( resource.getName() );
301
302 while ( parent != null )
303 {
304 if ( parent.getName().equals( "schema" ) )
305 {
306
307
308
309 fileComponentStack.push( "schema" );
310
311 return assembleDestinationFile( fileComponentStack );
312 }
313
314 fileComponentStack.push( parent.getName() );
315
316 if ( parent.equals( parent.getParentFile() ) || parent.getParentFile() == null )
317 {
318 throw new IllegalStateException( I18n.err( I18n.ERR_08005 ) );
319 }
320
321 parent = parent.getParentFile();
322 }
323
324 throw new IllegalStateException( I18n.err( I18n.ERR_08006 ) );
325 }
326
327
328
329
330
331
332
333
334
335
336
337
338 public static InputStream getUniqueResourceAsStream( String resourceName, String resourceDescription )
339 throws IOException
340 {
341 resourceName = BASE_PATH + resourceName;
342 URL result = getUniqueResource( resourceName, resourceDescription );
343 return result.openStream();
344 }
345
346
347
348
349
350
351
352
353
354
355 public static URL getUniqueResource( String resourceName, String resourceDescription ) throws IOException
356 {
357 Enumeration<URL> resources = DefaultSchemaLdifExtractor.class.getClassLoader().getResources( resourceName );
358 if ( !resources.hasMoreElements() )
359 {
360 throw new UniqueResourceException( resourceName, resourceDescription );
361 }
362 URL result = resources.nextElement();
363 if ( resources.hasMoreElements() )
364 {
365 throw new UniqueResourceException( resourceName, result, resources, resourceDescription );
366 }
367 return result;
368 }
369
370
371
372
373
374
375
376
377 private void extractFromClassLoader( String resource ) throws IOException
378 {
379 byte[] buf = new byte[512];
380 InputStream in = DefaultSchemaLdifExtractor.getUniqueResourceAsStream( resource,
381 "LDIF file in schema repository" );
382
383 try
384 {
385 File destination = new File( outputDirectory, resource );
386
387
388
389
390 if ( destination.exists() )
391 {
392 return;
393 }
394
395 if ( !destination.getParentFile().exists() && !destination.getParentFile().mkdirs() )
396 {
397 throw new IOException( I18n.err( I18n.ERR_09001_DIRECTORY_CREATION_FAILED, destination
398 .getParentFile().getAbsolutePath() ) );
399 }
400
401 FileOutputStream out = new FileOutputStream( destination );
402 try
403 {
404 while ( in.available() > 0 )
405 {
406 int readCount = in.read( buf );
407 out.write( buf, 0, readCount );
408 }
409 out.flush();
410 }
411 finally
412 {
413 out.close();
414 }
415 }
416 finally
417 {
418 in.close();
419 }
420 }
421 }