1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.jcr;
25
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.net.URL;
30 import java.util.Collections;
31 import java.util.EnumMap;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.Map;
35 import java.util.Set;
36 import net.jcip.annotations.NotThreadSafe;
37 import org.modeshape.cnd.CndImporter;
38 import org.modeshape.common.component.ClassLoaderFactory;
39 import org.modeshape.common.util.CheckArg;
40 import org.modeshape.graph.ExecutionContext;
41 import org.modeshape.graph.Graph;
42 import org.modeshape.graph.Location;
43 import org.modeshape.graph.Node;
44 import org.modeshape.graph.Subgraph;
45 import org.modeshape.graph.connector.RepositorySource;
46 import org.modeshape.graph.io.Destination;
47 import org.modeshape.graph.io.GraphBatchDestination;
48 import org.modeshape.graph.property.Name;
49 import org.modeshape.graph.property.Path;
50 import org.modeshape.graph.property.PathNotFoundException;
51 import org.modeshape.graph.property.Property;
52 import org.modeshape.graph.property.NamespaceRegistry.Namespace;
53 import org.modeshape.jcr.JcrRepository.Option;
54 import org.modeshape.repository.ModeShapeConfiguration;
55 import org.modeshape.repository.ModeShapeConfigurationException;
56 import org.xml.sax.SAXException;
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 @NotThreadSafe
75 public class JcrConfiguration extends ModeShapeConfiguration {
76
77
78
79
80
81
82 public interface RepositoryDefinition<ReturnType>
83 extends Returnable<ReturnType>, Removable<ReturnType>, SetDescription<RepositoryDefinition<ReturnType>> {
84
85
86
87
88
89
90
91
92 RepositoryDefinition<ReturnType> setSource( String sourceName );
93
94
95
96
97
98
99 String getSource();
100
101
102
103
104
105
106
107
108
109 RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
110 String value );
111
112
113
114
115
116
117
118
119
120 RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
121 boolean value );
122
123
124
125
126
127
128
129
130
131 RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
132 int value );
133
134
135
136
137
138
139
140
141
142 RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
143 long value );
144
145
146
147
148
149
150
151
152
153 RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
154 float value );
155
156
157
158
159
160
161
162
163
164 RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
165 double value );
166
167
168
169
170
171
172
173
174 String getOption( JcrRepository.Option option );
175
176
177
178
179
180
181
182
183
184
185
186
187 RepositoryDefinition<ReturnType> addNodeTypes( String pathToCndFile );
188
189
190
191
192
193
194
195
196
197 RepositoryDefinition<ReturnType> addNodeTypes( File cndFile );
198
199
200
201
202
203
204
205
206
207
208
209
210 RepositoryDefinition<ReturnType> addNodeTypes( URL urlOfCndFile );
211
212
213
214
215
216
217
218
219
220
221
222
223 RepositoryDefinition<ReturnType> addNodeTypes( InputStream cndContent );
224
225
226
227
228
229
230
231
232 RepositoryDefinition<ReturnType> registerNamespace( String prefix,
233 String uri );
234 }
235
236 private final Map<String, RepositoryDefinition<? extends JcrConfiguration>> repositoryDefinitions = new HashMap<String, RepositoryDefinition<? extends JcrConfiguration>>();
237
238
239
240
241 public JcrConfiguration() {
242 super();
243 }
244
245
246
247
248
249
250
251 public JcrConfiguration( ExecutionContext context ) {
252 super(context);
253 }
254
255
256
257
258
259
260
261
262 @Override
263 public JcrConfiguration loadFrom( String pathToFile ) throws IOException, SAXException {
264 super.loadFrom(pathToFile);
265 return this;
266 }
267
268
269
270
271
272
273 @Override
274 public JcrConfiguration loadFrom( String pathToConfigurationFile,
275 String path ) throws IOException, SAXException {
276 super.loadFrom(pathToConfigurationFile, path);
277 return this;
278 }
279
280
281
282
283
284
285 @Override
286 public JcrConfiguration loadFrom( File configurationFile ) throws IOException, SAXException {
287 super.loadFrom(configurationFile);
288 return this;
289 }
290
291
292
293
294
295
296 @Override
297 public JcrConfiguration loadFrom( File configurationFile,
298 String path ) throws IOException, SAXException {
299 super.loadFrom(configurationFile, path);
300 return this;
301 }
302
303
304
305
306
307
308 @Override
309 public JcrConfiguration loadFrom( URL urlToConfigurationFile ) throws IOException, SAXException {
310 super.loadFrom(urlToConfigurationFile);
311 return this;
312 }
313
314
315
316
317
318
319 @Override
320 public JcrConfiguration loadFrom( URL urlToConfigurationFile,
321 String path ) throws IOException, SAXException {
322 super.loadFrom(urlToConfigurationFile, path);
323 return this;
324 }
325
326
327
328
329
330
331 @Override
332 public JcrConfiguration loadFrom( InputStream configurationFileInputStream ) throws IOException, SAXException {
333 super.loadFrom(configurationFileInputStream);
334 return this;
335 }
336
337
338
339
340
341
342 @Override
343 public JcrConfiguration loadFrom( InputStream configurationFileInputStream,
344 String path ) throws IOException, SAXException {
345 super.loadFrom(configurationFileInputStream, path);
346 return this;
347 }
348
349
350
351
352
353
354 @Override
355 public JcrConfiguration loadFrom( RepositorySource source ) {
356 super.loadFrom(source);
357 return this;
358 }
359
360
361
362
363
364
365
366 @Override
367 public JcrConfiguration loadFrom( RepositorySource source,
368 String workspaceName ) {
369 super.loadFrom(source, workspaceName);
370 return this;
371 }
372
373
374
375
376
377
378
379 @Override
380 public JcrConfiguration loadFrom( RepositorySource source,
381 String workspaceName,
382 String pathInWorkspace ) {
383 super.loadFrom(source, workspaceName, pathInWorkspace);
384 return this;
385 }
386
387
388
389
390
391
392 @Override
393 public JcrConfiguration and() {
394 return this;
395 }
396
397
398
399
400
401
402 @Override
403 public JcrConfiguration withClassLoaderFactory( ClassLoaderFactory classLoaderFactory ) {
404 super.withClassLoaderFactory(classLoaderFactory);
405 return this;
406 }
407
408
409
410
411
412
413 @Override
414 public MimeTypeDetectorDefinition<JcrConfiguration> mimeTypeDetector( String name ) {
415 return mimeTypeDetectorDefinition(this, name);
416 }
417
418
419
420
421
422
423 @Override
424 public RepositorySourceDefinition<JcrConfiguration> repositorySource( String name ) {
425 return repositorySourceDefinition(this, name);
426 }
427
428
429
430
431
432
433 @Override
434 public SequencerDefinition<JcrConfiguration> sequencer( String name ) {
435 return sequencerDefinition(this, name);
436 }
437
438
439
440
441
442
443
444
445 public RepositoryDefinition<JcrConfiguration> repository( String name ) {
446 return repositoryDefinition(this, name);
447 }
448
449
450
451
452
453
454 public Set<RepositoryDefinition<JcrConfiguration>> repositories() {
455
456 Set<String> names = getNamesOfComponentsUnder(ModeShapeLexicon.REPOSITORIES);
457 names.addAll(this.repositoryDefinitions.keySet());
458 Set<RepositoryDefinition<JcrConfiguration>> results = new HashSet<RepositoryDefinition<JcrConfiguration>>();
459 for (String name : names) {
460 results.add(repository(name));
461 }
462 return Collections.unmodifiableSet(results);
463 }
464
465
466
467
468
469
470 @Override
471 public JcrConfiguration save() {
472 super.save();
473 this.repositoryDefinitions.clear();
474 return this;
475 }
476
477
478
479
480
481
482 @Override
483 public JcrEngine build() {
484 save();
485 return new JcrEngine(getExecutionContextForEngine(), getConfigurationDefinition());
486 }
487
488
489
490
491
492
493
494
495
496 @SuppressWarnings( "unchecked" )
497 protected <ReturnType extends JcrConfiguration> RepositoryDefinition<ReturnType> repositoryDefinition( ReturnType returnObject,
498 String name ) {
499 RepositoryDefinition<ReturnType> definition = (RepositoryDefinition<ReturnType>)repositoryDefinitions.get(name);
500 if (definition == null) {
501 definition = new RepositoryBuilder<ReturnType>(returnObject, changes(), path(), ModeShapeLexicon.REPOSITORIES,
502 name(name));
503 repositoryDefinitions.put(name, definition);
504 }
505 return definition;
506 }
507
508 protected class RepositoryBuilder<ReturnType> extends GraphReturnable<ReturnType, RepositoryDefinition<ReturnType>>
509 implements RepositoryDefinition<ReturnType> {
510 private final EnumMap<JcrRepository.Option, String> optionValues = new EnumMap<Option, String>(Option.class);
511
512 protected RepositoryBuilder( ReturnType returnObject,
513 Graph.Batch batch,
514 Path path,
515 Name... names ) {
516 super(returnObject, batch, path, names);
517
518 try {
519 Path optionsPath = context.getValueFactories().getPathFactory().create(path, ModeShapeLexicon.OPTIONS);
520 Subgraph options = batch.getGraph().getSubgraphOfDepth(2).at(optionsPath);
521 for (Location optionChild : options.getRoot().getChildren()) {
522 Node option = options.getNode(optionChild);
523 Property property = option.getProperty(ModeShapeLexicon.VALUE);
524 if (property != null && property.isEmpty()) {
525 try {
526 Option key = Option.findOption(optionChild.getPath()
527 .getLastSegment()
528 .getString(context.getNamespaceRegistry()));
529 String value = context.getValueFactories().getStringFactory().create(property.getFirstValue());
530 optionValues.put(key, value);
531 } catch (IllegalArgumentException e) {
532
533 }
534 }
535 }
536 } catch (PathNotFoundException e) {
537
538 }
539 }
540
541 @Override
542 protected RepositoryDefinition<ReturnType> thisType() {
543 return this;
544 }
545
546 public RepositoryDefinition<ReturnType> setSource( String sourceName ) {
547 setProperty(ModeShapeLexicon.SOURCE_NAME, sourceName);
548 return this;
549 }
550
551 public String getSource() {
552 Property property = getProperty(ModeShapeLexicon.SOURCE_NAME);
553 if (property != null && !property.isEmpty()) {
554 return context.getValueFactories().getStringFactory().create(property.getFirstValue());
555 }
556 return null;
557 }
558
559 public RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
560 String value ) {
561 CheckArg.isNotNull(option, "option");
562 CheckArg.isNotNull(value, "value");
563 createIfMissing(ModeShapeLexicon.OPTIONS, option.name()).with(ModeShapeLexicon.VALUE, value.trim()).and();
564 optionValues.put(option, value);
565 return this;
566 }
567
568 public RepositoryDefinition<ReturnType> setOption( Option option,
569 boolean value ) {
570 return setOption(option, Boolean.toString(value));
571 }
572
573 public RepositoryDefinition<ReturnType> setOption( Option option,
574 int value ) {
575 return setOption(option, Integer.toString(value));
576 }
577
578 public RepositoryDefinition<ReturnType> setOption( Option option,
579 long value ) {
580 return setOption(option, Long.toString(value));
581 }
582
583 public RepositoryDefinition<ReturnType> setOption( Option option,
584 float value ) {
585 return setOption(option, Float.toString(value));
586 }
587
588 public RepositoryDefinition<ReturnType> setOption( Option option,
589 double value ) {
590 return setOption(option, Double.toString(value));
591 }
592
593 public String getOption( Option option ) {
594 CheckArg.isNotNull(option, "option");
595 return optionValues.get(option);
596 }
597
598 public RepositoryDefinition<ReturnType> registerNamespace( String prefix,
599 String uri ) {
600 CheckArg.isNotEmpty(prefix, "prefix");
601 CheckArg.isNotEmpty(uri, "uri");
602 prefix = prefix.trim();
603 uri = uri.trim();
604 createIfMissing(ModeShapeLexicon.NAMESPACES, prefix).with(ModeShapeLexicon.URI, uri).and();
605 return this;
606 }
607
608 public RepositoryDefinition<ReturnType> addNodeTypes( String pathToCndFile ) {
609 CheckArg.isNotEmpty(pathToCndFile, "pathToCndFile");
610 return addNodeTypes(new File(pathToCndFile));
611 }
612
613 public RepositoryDefinition<ReturnType> addNodeTypes( File file ) {
614 CheckArg.isNotNull(file, "file");
615 if (file.exists() && file.canRead()) {
616 CndImporter importer = createCndImporter();
617 try {
618 Set<Namespace> namespacesBefore = batch.getGraph().getContext().getNamespaceRegistry().getNamespaces();
619 importer.importFrom(file, getProblems());
620
621
622 registerNewNamespaces(namespacesBefore);
623 } catch (IOException e) {
624 throw new ModeShapeConfigurationException(e);
625 }
626 return this;
627 }
628 throw new ModeShapeConfigurationException(JcrI18n.fileDoesNotExist.text(file.getPath()));
629 }
630
631 public RepositoryDefinition<ReturnType> addNodeTypes( URL url ) {
632 CheckArg.isNotNull(url, "url");
633
634 InputStream stream = null;
635 boolean foundError = false;
636 try {
637 Set<Namespace> namespacesBefore = batch.getGraph().getContext().getNamespaceRegistry().getNamespaces();
638 stream = url.openStream();
639 CndImporter importer = createCndImporter();
640 importer.importFrom(stream, getProblems(), url.toString());
641
642
643 registerNewNamespaces(namespacesBefore);
644 } catch (IOException e) {
645 foundError = true;
646 throw new ModeShapeConfigurationException(e);
647 } finally {
648 if (stream != null) {
649 try {
650 stream.close();
651 } catch (IOException e) {
652 if (!foundError) {
653 throw new ModeShapeConfigurationException(e);
654 }
655 }
656 }
657 }
658 return this;
659 }
660
661 public RepositoryDefinition<ReturnType> addNodeTypes( InputStream cndContent ) {
662 CndImporter importer = createCndImporter();
663 try {
664 Set<Namespace> namespacesBefore = batch.getGraph().getContext().getNamespaceRegistry().getNamespaces();
665 importer.importFrom(cndContent, getProblems(), "stream");
666
667
668 registerNewNamespaces(namespacesBefore);
669 } catch (IOException e) {
670 throw new ModeShapeConfigurationException(e);
671 }
672 return this;
673 }
674
675 protected void registerNewNamespaces( Set<Namespace> namespacesBefore ) {
676 Set<Namespace> namespacesAfter = batch.getGraph().getContext().getNamespaceRegistry().getNamespaces();
677 Set<Namespace> newNamespaces = new HashSet<Namespace>(namespacesAfter);
678 newNamespaces.removeAll(namespacesBefore);
679 for (Namespace namespace : newNamespaces) {
680 registerNamespace(namespace.getPrefix(), namespace.getNamespaceUri());
681 }
682 }
683
684 protected CndImporter createCndImporter() {
685
686 Path nodeTypesPath = subpath(JcrLexicon.NODE_TYPES);
687 createIfMissing(JcrLexicon.NODE_TYPES).and();
688
689
690 Destination destination = new GraphBatchDestination(batch, true);
691
692
693 return new CndImporter(destination, nodeTypesPath);
694 }
695 }
696
697 }