View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors.
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   * 
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.jcr;
25  
26  import java.io.IOException;
27  import java.io.InputStream;
28  import java.util.Arrays;
29  import net.jcip.annotations.Immutable;
30  import org.modeshape.cnd.CndImporter;
31  import org.modeshape.common.collection.ImmutableProblems;
32  import org.modeshape.common.collection.Problems;
33  import org.modeshape.common.collection.SimpleProblems;
34  import org.modeshape.graph.ExecutionContext;
35  import org.modeshape.graph.Graph;
36  import org.modeshape.graph.connector.inmemory.InMemoryRepositorySource;
37  import org.modeshape.graph.io.Destination;
38  import org.modeshape.graph.io.GraphBatchDestination;
39  import org.modeshape.graph.property.PathFactory;
40  
41  /**
42   * Class to parse one or more Compact Node Definition (CND) files containing custom node type definitions into a format that can
43   * be registered with the {@link JcrNodeTypeManager}.
44   * <p>
45   * The class contains methods for determining whether the CND files were parsed successfully and what errors occurred. Typically,
46   * the class will be used like this:
47   * 
48   * <pre>
49   * try {
50   *  String[] cndFilePaths = // The URIs for the resource files on the classpath
51   *  JcrNodeTypeSource nodeTypeSource = new CndNodeTypeSource(cndFilePaths);
52   *  
53   *  if (!nodeTypeSource.isValid()) {
54   *      Problems problems = nodeTypeSource.getProblems();
55   *      // Report problems
56   *  }
57   *  else {
58   *      jcrNodeTypeManager.registerNodeTypes(nodeTypeSource);
59   *  }
60   * }
61   * catch (IOException ioe) {
62   *  System.err.println(&quot;Could not find one of the CND files.&quot;);
63   *  ioe.printStackTrace();
64   * }
65   * 
66   * </pre>
67   * 
68   * </p>
69   */
70  @Immutable
71  public class CndNodeTypeSource implements JcrNodeTypeSource {
72  
73      private final Graph graph;
74      private final Problems problems;
75  
76      /**
77       * Creates a new {@link JcrNodeTypeSource} with based on the CND file with the given resource name.
78       * 
79       * @param resourceName the name of the resource; this resource must be on the classpath
80       * @throws IOException if an error loading or reading the resource occurs
81       */
82      public CndNodeTypeSource( String resourceName ) throws IOException {
83          this(new String[] {resourceName});
84      }
85  
86      /**
87       * Creates a new {@link JcrNodeTypeSource} based on the CND files at the given resource names.
88       * 
89       * @param resourceNames the name of the resources to load; these resources must be on the classpath
90       * @throws IOException if an error loading or reading the any of the resources occurs
91       */
92      public CndNodeTypeSource( String resourceNames[] ) throws IOException {
93  
94          Problems problems = new SimpleProblems();
95  
96          // Graph creation requires a context, but there are no security implications for this and namespace mappings are
97          // specified in the CND file itself
98          ExecutionContext context = new ExecutionContext();
99          PathFactory pathFactory = context.getValueFactories().getPathFactory();
100         InMemoryRepositorySource source = new InMemoryRepositorySource();
101         source.setName("CND Import Source");
102         this.graph = Graph.create(source, context);
103         for (String resourceName : Arrays.asList(resourceNames)) {
104             Graph.Batch batch = graph.batch();
105             Destination destination = new GraphBatchDestination(batch);
106             CndImporter importer = new CndImporter(destination, pathFactory.createRootPath());
107             InputStream is = getClass().getResourceAsStream(resourceName);
108 
109             // This submits the batch
110             importer.importFrom(is, problems, resourceName);
111         }
112         this.problems = new ImmutableProblems(problems);
113     }
114 
115     /**
116      * Returns true if no errors were encountered while parsing the CND file or files
117      * 
118      * @return true if no errors were encountered while parsing the CND file or files
119      */
120     public boolean isValid() {
121         return !problems.hasErrors();
122     }
123 
124     /**
125      * Returns the problems (if any) that were encountered parsing the CND files. Node type registration errors or warnings will
126      * NOT be added to this set of problems.
127      * 
128      * @return returns the problems (if any) that were encountered parsing the CND files.
129      */
130     public Problems getProblems() {
131         return problems;
132     }
133 
134     /**
135      * {@inheritDoc}
136      * 
137      * @see org.modeshape.jcr.JcrNodeTypeSource#getNodeTypes()
138      */
139     public final Graph getNodeTypes() {
140         return graph;
141     }
142 
143 }