Index: src/test/java/org/apache/jackrabbit/core/config/testCustomNodeTypes.xml
===================================================================
--- src/test/java/org/apache/jackrabbit/core/config/testCustomNodeTypes.xml (revision 0)
+++ src/test/java/org/apache/jackrabbit/core/config/testCustomNodeTypes.xml (revision 0)
@@ -0,0 +1,18 @@
+
+
+true if this node type registry contains custom
+ * node type definitions; false otherwise.
+ */
+ public synchronized boolean hasCustomNodeTypesDefined()
+ throws RepositoryException {
+ boolean customNodeTypesDefined = false;
+
+ try {
+ customNodeTypesDefined = customNodeTypesResource.exists();
+ } catch (FileSystemException fse) {
+ String error =
+ "internal error: failed to access custom node type definitions stored in "
+ + customNodeTypesResource.getPath();
+ log.debug(error);
+ throw new RepositoryException(error, fse);
+ }
+
+ return customNodeTypesDefined;
+ }
/**
* @param id
Index: src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java (revision 379317)
+++ src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDefStore.java (working copy)
@@ -16,8 +16,8 @@
*/
package org.apache.jackrabbit.core.nodetype;
-import org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader;
-import org.apache.jackrabbit.core.nodetype.xml.NodeTypeWriter;
+import org.apache.jackrabbit.core.nodetype.xml.XmlNodeTypeReader;
+import org.apache.jackrabbit.core.nodetype.xml.XmlNodeTypeWriter;
import org.apache.jackrabbit.name.QName;
import javax.jcr.NamespaceRegistry;
@@ -52,7 +52,7 @@
public void load(InputStream in)
throws IOException, InvalidNodeTypeDefException,
RepositoryException {
- NodeTypeDef[] types = NodeTypeReader.read(in);
+ NodeTypeDef[] types = XmlNodeTypeReader.read(in);
for (int i = 0; i < types.length; i++) {
add(types[i]);
}
@@ -68,7 +68,7 @@
throws IOException, RepositoryException {
NodeTypeDef[] types = (NodeTypeDef[])
ntDefs.values().toArray(new NodeTypeDef[ntDefs.size()]);
- NodeTypeWriter.write(out, types, registry);
+ XmlNodeTypeWriter.write(out, types, registry);
}
/**
Index: src/main/java/org/apache/jackrabbit/core/config/config.dtd
===================================================================
--- src/main/java/org/apache/jackrabbit/core/config/config.dtd (revision 379317)
+++ src/main/java/org/apache/jackrabbit/core/config/config.dtd (working copy)
@@ -154,3 +154,13 @@
+
+
+
+
Index: src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java (revision 379317)
+++ src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java (working copy)
@@ -218,6 +218,11 @@
private final SearchConfig sc;
/**
+ * Optional custom node type configuration.
+ */
+ private final CustomNodeTypeConfig cntc;
+
+ /**
* Creates a repository configuration object.
*
* @param template workspace configuration template
@@ -232,6 +237,7 @@
* @param defaultWorkspace name of the default workspace
* @param vc versioning configuration
* @param sc search configuration for system search manager.
+ * @param cntc custom node type configuration
* @param parser the ConfigurationParser that servers as config factory
*/
public RepositoryConfig(String home, String name,
@@ -239,7 +245,7 @@
String workspaceDirectory, String workspaceConfigDirectory,
String defaultWorkspace, int workspaceMaxIdleTime,
Element template, VersioningConfig vc, SearchConfig sc,
- ConfigurationParser parser) {
+ CustomNodeTypeConfig cntc, ConfigurationParser parser) {
this.workspaces = new HashMap();
this.home = home;
this.name = name;
@@ -253,6 +259,7 @@
this.template = template;
this.vc = vc;
this.sc = sc;
+ this.cntc = cntc;
this.parser = parser;
}
@@ -269,6 +276,9 @@
if (sc != null) {
sc.init();
}
+ if (cntc != null) {
+ cntc.init();
+ }
// Get the physical workspace root directory (create it if not found)
File directory = new File(workspaceDirectory);
@@ -657,4 +667,15 @@
public SearchConfig getSearchConfig() {
return sc;
}
+
+ /**
+ * Returns the repository custom node type definition configuration.
+ * Returns null if no custom node type definition file
+ * has been configured.
+ *
+ * @return search index configuration, or null
+ */
+ public CustomNodeTypeConfig getCustomNodeTypeConfig() {
+ return cntc;
+ }
}
Index: src/main/java/org/apache/jackrabbit/core/config/CustomNodeTypeConfig.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/config/CustomNodeTypeConfig.java (revision 0)
+++ src/main/java/org/apache/jackrabbit/core/config/CustomNodeTypeConfig.java (revision 0)
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.config;
+
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.NamespaceException;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
+import org.apache.jackrabbit.core.nodetype.NodeTypeReader;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * Custom node type configuration. This bean configuration class is used
+ * to create the custom node types in the repository.
+ */
+public class CustomNodeTypeConfig extends BeanConfig {
+
+ /**
+ * The name of the custom node type definition file's path property.
+ */
+ private static final String PATH_PROPERTY = "path";
+
+ /**
+ * The node type reader implmentation used to process the custom node
+ * type definition file.
+ */
+ private NodeTypeReader ntr;
+
+ /**
+ * Creates a custom node type configuration object.
+ *
+ * @param readerClassName The name of the class used to process the
+ * custom node type definition file.
+ * @param custom node type configuration properties
+ */
+ public CustomNodeTypeConfig(
+ String readerClassName, Properties properties ) {
+ super( readerClassName, properties );
+ }
+
+ /**
+ * Creates the custom node type configuration object.
+ *
+ * @throws ConfigurationException if the requested type cannot
+ * be instantiated.
+ */
+ public void init() throws ConfigurationException {
+ Class nodeTypeReaderClass = null;
+
+ try {
+ nodeTypeReaderClass = Class.forName( getClassName() );
+ } catch (ClassNotFoundException e) {
+ throw new ConfigurationException( "Could not find "
+ + getClassName() + ".", e );
+ }
+
+ if (!NodeTypeReader.class.isAssignableFrom( nodeTypeReaderClass )) {
+ throw new ConfigurationException(
+ getClassName() + " does not implement the "
+ + "org.apache.jackrabbit.core.nodetype.NodeTypeReader "
+ + "interface." );
+ }
+
+ try {
+ ntr = (NodeTypeReader) nodeTypeReaderClass.newInstance();
+ } catch (Exception e) {
+ throw new ConfigurationException(
+ "Could not instantiate" + getClassName() + ".", e );
+ }
+ }
+
+ /**
+ * Returns an array of NodeTypeDef objects found in the
+ * custom node type definition file.
+ *
+ * @return an array of NodeTypeDef objects
+ * @throws ConfigurationException if an error occurs while processing
+ * the custom node type definition file
+ */
+ public NodeTypeDef[] getCustomNodeTypes(NamespaceRegistry nsReg)
+ throws ConfigurationException {
+ String nodeTypeDefFileLocation = getParameters().getProperty(PATH_PROPERTY);
+
+ if (nodeTypeDefFileLocation == null) {
+ throw new ConfigurationException(
+ "The '" + PATH_PROPERTY + "' property was not found.");
+ }
+
+ InputStream in = null;
+ NodeTypeDef[] nodeTypeDefinitions = null;
+
+ try {
+ in = getClass().getClassLoader().getResourceAsStream(nodeTypeDefFileLocation);
+ nodeTypeDefinitions = ntr.readNodeTypes(in);
+ Properties namespaces = ntr.getNamespaces();
+
+ Enumeration nsEnum = namespaces.propertyNames();
+ while (nsEnum.hasMoreElements()) {
+ String prefix = (String) nsEnum.nextElement();
+ try {
+ nsReg.getURI(prefix);
+ } catch (NamespaceException e) {
+ nsReg.registerNamespace(prefix, namespaces.getProperty(prefix));
+ }
+ }
+ } catch (IOException e) {
+ throw new ConfigurationException(
+ "An error occured while reading from " + nodeTypeDefFileLocation + ".", e);
+ } catch (InvalidNodeTypeDefException e) {
+ throw new ConfigurationException(
+ "An invalid node type was found in " + nodeTypeDefFileLocation + ".", e);
+ } catch (RepositoryException e) {
+ throw new ConfigurationException(
+ "A RepositoryException occurred while processing "
+ + nodeTypeDefFileLocation + ".", e);
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ return nodeTypeDefinitions;
+ }
+}
Index: src/main/java/org/apache/jackrabbit/core/config/ConfigurationParser.java
===================================================================
--- src/main/java/org/apache/jackrabbit/core/config/ConfigurationParser.java (revision 379317)
+++ src/main/java/org/apache/jackrabbit/core/config/ConfigurationParser.java (working copy)
@@ -78,6 +78,10 @@
/** Name of the versioning configuration element. */
public static final String VERSIONING_ELEMENT = "Versioning";
+
+ /** Name of the custom node type definitions configuration element. */
+ public static final String CUSTOM_NODE_TYPE_DEFINITIONS_ELEMENT =
+ "CustomNodeTypeDefinitions";
/** Name of the file system configuration element. */
public static final String FILE_SYSTEM_ELEMENT = "FileSystem";
@@ -111,6 +115,10 @@
/** Name of the bean implementation class configuration attribute. */
public static final String CLASS_ATTRIBUTE = "class";
+ /** Name of the custom node type definition reader implementation
+ class configuration attribute. */
+ public static final String READER_CLASS_ATTRIBUTE = "readerClass";
+
/** Name of the bean parameter name configuration attribute. */
public static final String NAME_ATTRIBUTE = "name";
@@ -121,6 +129,11 @@
public static final String DEFAULT_QUERY_HANDLER =
"org.apache.jackrabbit.core.query.lucene.SearchIndex";
+ /** Name of the default custom node definition reader
+ implementation class. */
+ public static final String DEFAULT_CUSTOM_NODE_TYPE_READER =
+ "org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader";
+
/**
* The configuration parser variables. These name-value pairs
* are used to substitute ${...} variable references
@@ -243,10 +256,13 @@
// Optional search configuration
SearchConfig sc = parseSearchConfig(root);
+
+ // Optional custom node type configuration
+ CustomNodeTypeConfig cntc = parseCustomNodeTypeConfig(root);
return new RepositoryConfig(home, appName, amc, lmc, fsc,
workspaceDirectory, workspaceConfigDirectory, defaultWorkspace,
- maxIdleTime, template, vc, sc, this);
+ maxIdleTime, template, vc, sc, cntc, this);
}
/**
@@ -378,6 +394,52 @@
}
/**
+ * Parses custom node type configuration. Custom node type configuration
+ * uses the following format:
+ *
+ * <CustomNodeTypeDefinitions class="..."> + * <param name="..." value="..."> + * ... + * </CustomNodeTypeDefinitions> + *+ * + * The
CustomNodeTypeDefinitions elements is a
+ * {@link #parseBeanConfig(Element,String) bean configuration} element.
+ * If the custom node type reader implementation class is not given, then
+ * a default implementation is used.
+ *
+ * The custom node type configuration is an optional feature of repository
+ * configuration. If the custom node type configuration element is not
+ * found, then this method returns null.
+ *
+ *
+ * @param parent parent of the CustomNodeTypeDefinitions element
+ * @return custom node type definitions configuration, or null
+ * @throws ConfigurationException if the configuration is broken
+ */
+ protected CustomNodeTypeConfig parseCustomNodeTypeConfig(Element parent)
+ throws ConfigurationException {
+ NodeList children = parent.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE
+ && CUSTOM_NODE_TYPE_DEFINITIONS_ELEMENT.equals(child.getNodeName())) {
+ Element element = (Element) child;
+
+ // Custom node type reader implementation class
+ String readerClassName = getAttribute(
+ element, READER_CLASS_ATTRIBUTE, DEFAULT_CUSTOM_NODE_TYPE_READER);
+
+ // Search parameters
+ Properties parameters = parseParameters(element);
+
+ return new CustomNodeTypeConfig(readerClassName, parameters);
+ }
+ }
+ return null;
+ }
+
+ /**
* Parses versioning configuration. Versioning configuration uses the
* following format:
*