OCM-58 make OCM jackrabbit independent. Note that I did remove some methods from the NodeTypeManager interface, but the NodeTypeManagerImpl didn't implement many of them any way. Jackrabbit dependency is now only used as scope test
git-svn-id: https://svn.apache.org/repos/asf/jackrabbit/commons/ocm/trunk@1354509 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/jackrabbit/ocm/mapper/model/PropertyDefDescriptor.java b/src/main/java/org/apache/jackrabbit/ocm/mapper/model/PropertyDefDescriptor.java
index a0977f4..f7cb8ca 100755
--- a/src/main/java/org/apache/jackrabbit/ocm/mapper/model/PropertyDefDescriptor.java
+++ b/src/main/java/org/apache/jackrabbit/ocm/mapper/model/PropertyDefDescriptor.java
@@ -29,6 +29,8 @@
*/
String getJcrName();
+ String getFieldName();
+
/**
* @return Returns the property type name.
*/
diff --git a/src/main/java/org/apache/jackrabbit/ocm/nodemanagement/NodeTypeManager.java b/src/main/java/org/apache/jackrabbit/ocm/nodemanagement/NodeTypeManager.java
index 582da86..0e11145 100644
--- a/src/main/java/org/apache/jackrabbit/ocm/nodemanagement/NodeTypeManager.java
+++ b/src/main/java/org/apache/jackrabbit/ocm/nodemanagement/NodeTypeManager.java
@@ -80,109 +80,15 @@
void createNodeTypes(Session session, ClassDescriptor[] classDescriptors)
throws NodeTypeCreationException;
- /** This method creates JCR node types based on jcr-mapping xml
- * files.
- *
- * @param session Repository session
- * @param mappingXmlFiles InputStreams to jcr-mapping xml files
- * @throws NodeTypeCreationException NodeTypeCreationException
- */
- void createNodeTypesFromMappingFiles(Session session,
- InputStream[] mappingXmlFiles)
- throws NodeTypeCreationException;
-
/** This method creates a single JCR node type identified by its ClassDescriptor
* read from the jcr mapping file.
*
* @param session Repository session
* @param classDescriptor ClassDescriptor object created by jcr-mapping
- * @param jcrNodeType Name of the class that needs to be created identified
- * by its jcrNodeType name
* @throws NodeTypeCreationException NodeTypeCreationException
*/
void createSingleNodeType(Session session, ClassDescriptor classDescriptor)
throws NodeTypeCreationException;
- /** This method creates a single JCR node type identified by its jcrNodeType
- * name defined in a jcr-mapping xml file.
- *
- * @param session Repository session
- * @param mappingXmlFile InputStream to a jcr-mapping xml file
- * @param jcrNodeType Name of the class that needs to be created identified
- * by its jcrNodeType name
- * @throws NodeTypeCreationException NodeTypeCreationException
- */
- void createSingleNodeTypeFromMappingFile(Session session,
- InputStream mappingXmlFile, String jcrNodeType)
- throws NodeTypeCreationException;
- /** This method creates a JCR node type from a given Java Bean class by using
- * reflection. It creates required JCR property definitions from primitive
- * Java class properties using the same property name. Non-primitive class
- * properties are skipped.
- *
- * @param session Repository session
- * @param clazz Java class
- * @param jcrNodeType Name of JCR node type (including namespace)
- * @param reflectSuperClasses If true, all base classes are also reflected
- * @throws NodeTypeCreationException NodeTypeCreationException
- */
- void createNodeTypeFromClass(Session session, Class clazz,
- String jcrNodeType, boolean reflectSuperClasses)
- throws NodeTypeCreationException;
-
- /** This method creates JCR node types from a JCR vendor specific
- * configuration file.
- *
- * @param session Repository session
- * @param jcrRepositoryXmlConfigurationFile InputStream to file
- * @throws OperationNotSupportedException OperationNotSupportedException
- * @throws NodeTypeCreationException NodeTypeCreationException
- */
- void createNodeTypesFromConfiguration(Session session,
- InputStream jcrRepositoryConfigurationFile)
- throws OperationNotSupportedException, NodeTypeCreationException;
-
- /** This method removes all JCR node types that are defined in one to many
- * jcr-mapping XML files.
- *
- * @param session Repository session
- * @param mappingXmlFiles InputStreams to jcr-mapping xml file
- * @throws NodeTypeRemovalException NodeTypeRemovalException
- */
- void removeNodeTypesFromMappingFile(Session session, InputStream[] mappingXmlFiles)
- throws NodeTypeRemovalException;
-
- /**
- * This method removes JCR node types from a JCR vendor specific configuration file
- * @param session Repository session
- * @param jcrRepositoryConfigurationFile the file that contains the node type definition
- * @throws NodeTypeRemovalException
- */
- void removeNodeTypesFromConfiguration(Session session, InputStream jcrRepositoryConfigurationFile)
- throws NodeTypeRemovalException;
-
- /** This method removes a single JCR node type identified by its jcrNodeType
- * name.
- *
- * @param session Repository session
- * @param jcrNodeType
- * @throws NodeTypeRemovalException NodeTypeRemovalException
- */
- void removeSingleNodeType(Session session, String jcrNodeType)
- throws NodeTypeRemovalException;
-
- /** Returns the names of all node types in the repository identified by a
- * given namespace.
- *
- * @param namespace Name of nodetypes to return
- * @return list of matching JCR node types
- */
- List getPrimaryNodeTypeNames(Session session, String namespace);
-
- /** Returns a list of all JCR node types.
- *
- * @return list of all JCR node types
- */
- List getAllPrimaryNodeTypeNames(Session session);
}
diff --git a/src/main/java/org/apache/jackrabbit/ocm/nodemanagement/impl/NodeTypeManagerImpl.java b/src/main/java/org/apache/jackrabbit/ocm/nodemanagement/impl/NodeTypeManagerImpl.java
new file mode 100644
index 0000000..88bd051
--- /dev/null
+++ b/src/main/java/org/apache/jackrabbit/ocm/nodemanagement/impl/NodeTypeManagerImpl.java
@@ -0,0 +1,312 @@
+package org.apache.jackrabbit.ocm.nodemanagement.impl;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.nodetype.NodeDefinitionTemplate;
+import javax.jcr.nodetype.NodeTypeTemplate;
+import javax.jcr.nodetype.PropertyDefinitionTemplate;
+import javax.jcr.version.OnParentVersionAction;
+
+import org.apache.jackrabbit.ocm.mapper.model.BeanDescriptor;
+import org.apache.jackrabbit.ocm.mapper.model.ChildNodeDefDescriptor;
+import org.apache.jackrabbit.ocm.mapper.model.ClassDescriptor;
+import org.apache.jackrabbit.ocm.mapper.model.CollectionDescriptor;
+import org.apache.jackrabbit.ocm.mapper.model.FieldDescriptor;
+import org.apache.jackrabbit.ocm.mapper.model.MappingDescriptor;
+import org.apache.jackrabbit.ocm.mapper.model.PropertyDefDescriptor;
+import org.apache.jackrabbit.ocm.nodemanagement.NodeTypeManager;
+import org.apache.jackrabbit.ocm.nodemanagement.exception.NamespaceCreationException;
+import org.apache.jackrabbit.ocm.nodemanagement.exception.NodeTypeCreationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NodeTypeManagerImpl implements NodeTypeManager {
+
+ private static Logger log = LoggerFactory.getLogger(NodeTypeManagerImpl.class);
+ @Override
+ public void createNamespace(final Session session, final String namespace, final String namespaceUri) throws NamespaceCreationException {
+ if (session != null)
+ {
+ try
+ {
+ session.getWorkspace().getNamespaceRegistry().registerNamespace(namespace, namespaceUri);
+ log.info("Namespace created: " +
+ "{" + namespaceUri + "}" + namespace);
+ }
+ catch (Exception e)
+ {
+ throw new NamespaceCreationException(e);
+ }
+ }
+ }
+
+ @Override
+ public void createNodeTypes(final Session session, final MappingDescriptor mappingDescriptor) throws NodeTypeCreationException {
+ if (mappingDescriptor != null && mappingDescriptor.getClassDescriptorsByClassName().size() > 0)
+ {
+ final Collection classDescriptorObjects = mappingDescriptor.getClassDescriptorsByClassName().values();
+ final ClassDescriptor[] classDescriptors = (ClassDescriptor[])classDescriptorObjects.toArray(new ClassDescriptor[classDescriptorObjects.size()]);
+ createNodeTypes(session, classDescriptors);
+ }
+ else
+ {
+ throw new NodeTypeCreationException("The MappingDescriptor can't be null or empty.");
+ }
+ }
+
+ @Override
+ public void createNodeTypes(final Session session, final ClassDescriptor[] classDescriptors) throws NodeTypeCreationException {
+ if (classDescriptors != null && classDescriptors.length > 0)
+ {
+ log.info("Trying to create " + classDescriptors.length +
+ " JCR node types.");
+ for (int i = 0; i < classDescriptors.length; i++)
+ {
+ createSingleNodeType(session, classDescriptors[i]);
+ }
+ }
+ else
+ {
+ throw new NodeTypeCreationException("The ClassDescriptor can't be null or empty.");
+ }
+ }
+
+ @Override
+ public void createSingleNodeType(final Session session, final ClassDescriptor classDescriptor) throws NodeTypeCreationException {
+ try {
+ if (classDescriptor.getJcrType() != null &&
+ (classDescriptor.getJcrType().startsWith("nt:")
+ || classDescriptor.getJcrType().startsWith("mix:"))) {
+ throw new NodeTypeCreationException("Namespace nt and mix are reserved namespaces. Please specify your own.");
+ }
+
+ if (checkSuperTypes(session.getWorkspace().getNodeTypeManager(),
+ classDescriptor.getJcrSuperTypes())) {
+
+ javax.jcr.nodetype.NodeTypeManager ntm = session.getWorkspace().getNodeTypeManager();
+ final NodeTypeTemplate ntt = ntm.createNodeTypeTemplate();
+
+ if (classDescriptor.getJcrType() == null) {
+ ntt.setName(classDescriptor.getClassName());
+ } else {
+ ntt.setName(classDescriptor.getJcrType());
+ }
+ ntt.setAbstract(classDescriptor.isAbstract());
+ if (classDescriptor.getJcrSuperTypes() != null && classDescriptor.getJcrSuperTypes().length() > 0) {
+ String[] superTypesArray = classDescriptor.getJcrSuperTypes().split(",");
+ //TODO combine the mixins here as well as supertypes
+ // Add classDescriptor.getJcrMixinTypes() to superTypesArray
+ for (String s : classDescriptor.getJcrMixinTypes()) {
+ System.out.println(s);
+ }
+ ntt.setDeclaredSuperTypeNames(superTypesArray);
+ }
+ // should we also support mixins to be created?
+ ntt.setMixin(false);
+ ntt.setQueryable(true);
+ ntt.setOrderableChildNodes(true);
+
+ final List nodeDefinitionTemplates = ntt.getNodeDefinitionTemplates();
+ final List propertyDefinitionTemplates = ntt.getPropertyDefinitionTemplates();
+
+ if (classDescriptor.getFieldDescriptors() != null) {
+ Iterator fieldIterator = classDescriptor.getFieldDescriptors().iterator();
+ while (fieldIterator.hasNext()) {
+ FieldDescriptor field = (FieldDescriptor) fieldIterator.next();
+ if (!field.isPath()) {
+ final PropertyDefinitionTemplate pdt = getPropertyDefinition(ntm, session.getValueFactory(), field);
+ // add the just created pdt to the nodetypetemplate
+ propertyDefinitionTemplates.add(pdt);
+ }
+ }
+
+ if (classDescriptor.getBeanDescriptors() != null) {
+ Iterator beanIterator = classDescriptor.getBeanDescriptors().iterator();
+ while (beanIterator.hasNext()) {
+ BeanDescriptor field = (BeanDescriptor) beanIterator.next();
+ if (this.isPropertyType(field.getJcrType())) {
+ final PropertyDefinitionTemplate pdt = getPropertyDefinition(ntm, session.getValueFactory(), field);
+ // add the just created pdt to the nodetypetemplate
+ propertyDefinitionTemplates.add(pdt);
+ } else {
+ final NodeDefinitionTemplate ndt = getNodeDefinition(ntm, session.getValueFactory(), field);
+ // add the just created pdt to the nodetypetemplate
+ nodeDefinitionTemplates.add(ndt);
+ }
+ }
+ }
+
+ if (classDescriptor.getCollectionDescriptors() != null) {
+ Iterator collectionIterator = classDescriptor.getCollectionDescriptors().iterator();
+ while (collectionIterator.hasNext()) {
+ CollectionDescriptor field = (CollectionDescriptor) collectionIterator.next();
+ if (this.isPropertyType(field.getJcrType())) {
+ final PropertyDefinitionTemplate pdt = getPropertyDefinition(ntm, session.getValueFactory(), field);
+ // add the just created pdt to the nodetypetemplate
+ propertyDefinitionTemplates.add(pdt);
+ } else {
+ final NodeDefinitionTemplate ndt = getNodeDefinition(ntm, session.getValueFactory(), field);
+ // add the just created pdt to the nodetypetemplate
+ nodeDefinitionTemplates.add(ndt);
+ }
+ }
+ }
+ ntm.registerNodeType(ntt, false);
+ log.info("Registered JCR node type '" + ntt.getName() +
+ "' for class '" + classDescriptor.getClassName() + "'");
+ }
+ } else {
+ throw new NodeTypeCreationException("JCR supertypes could not be resolved.");
+ }
+ } catch (Exception e) {
+ log.error("Could not create node types from class descriptor.", e);
+ throw new NodeTypeCreationException(e);
+ }
+ }
+
+ private NodeDefinitionTemplate getNodeDefinition(final javax.jcr.nodetype.NodeTypeManager ntm,
+ final ValueFactory valueFactory,
+ final ChildNodeDefDescriptor field) throws RepositoryException {
+
+
+ final NodeDefinitionTemplate ndt = ntm.createNodeDefinitionTemplate();
+ if (field.getJcrName() != null) {
+ ndt.setName(field.getJcrName());
+ } else {
+ ndt.setName("*");
+ }
+
+ int onParentVersion = OnParentVersionAction.IGNORE;
+
+ if (field.getJcrOnParentVersion() != null
+ && field.getJcrOnParentVersion().length() > 0) {
+ onParentVersion = OnParentVersionAction.valueFromName(field.getJcrOnParentVersion());
+ }
+ ndt.setOnParentVersion(onParentVersion);
+ ndt.setSameNameSiblings(field.isJcrSameNameSiblings());
+
+ ndt.setAutoCreated(field.isJcrAutoCreated());
+ ndt.setDefaultPrimaryTypeName(field.getDefaultPrimaryType());
+ ndt.setMandatory(field.isJcrMandatory());
+ ndt.setProtected(field.isJcrProtected());
+ ndt.setRequiredPrimaryTypeNames(getJcrSuperTypes(field.getJcrType()));
+
+ return ndt;
+ }
+
+ private PropertyDefinitionTemplate getPropertyDefinition(final javax.jcr.nodetype.NodeTypeManager ntm,
+ final ValueFactory valueFactory,
+ final PropertyDefDescriptor field) throws RepositoryException {
+ final PropertyDefinitionTemplate pdt = ntm.createPropertyDefinitionTemplate();
+ if (field.getJcrName() != null) {
+ pdt.setName(field.getJcrName());
+ } else {
+ pdt.setName(field.getFieldName());
+ }
+
+ if (field.getJcrType() != null) {
+ try {
+ pdt.setRequiredType(PropertyType.valueFromName(field.getJcrType()));
+ } catch (IllegalArgumentException e) {
+ log.warn("Invalid property type '{}' for '{}'. Set default to String type", field.getJcrType(), field.getJcrName());
+ pdt.setRequiredType(PropertyType.STRING);
+ }
+ } else {
+ log.info("No property type set for {}. Setting 'String' type.", field.getJcrName());
+ pdt.setRequiredType(PropertyType.STRING);
+
+ }
+ int onParentVersion = OnParentVersionAction.IGNORE;
+ if (field.getJcrOnParentVersion() != null &&
+ field.getJcrOnParentVersion().length() > 0) {
+ onParentVersion = OnParentVersionAction.valueFromName(field.getJcrOnParentVersion());
+ }
+ pdt.setOnParentVersion(onParentVersion);
+
+ pdt.setAutoCreated(field.isJcrAutoCreated());
+ pdt.setAvailableQueryOperators(new String[0]);
+
+ pdt.setFullTextSearchable(true);
+ pdt.setMandatory(field.isJcrMandatory());
+ pdt.setMultiple(field.isJcrMultiple());
+ pdt.setOnParentVersion(onParentVersion);
+ pdt.setProtected(field.isJcrProtected());
+ pdt.setQueryOrderable(true);
+
+ if (field instanceof FieldDescriptor) {
+ FieldDescriptor f = (FieldDescriptor) field;
+ if (f.getJcrDefaultValue() != null) {
+ if (pdt.getRequiredType() == PropertyType.STRING) {
+ Value[] vals = {valueFactory.createValue(f.getJcrDefaultValue())};
+ pdt.setDefaultValues(vals);
+ } else {
+ log.warn("Can only set default value for String properties. Skip for field '{}'", field.getJcrName());
+ }
+ }
+ pdt.setValueConstraints(f.getJcrValueConstraints());
+ }
+
+ return pdt;
+ }
+
+ /** Checks if all JCR super types for a given node type exist.
+ *
+ * @param ntMgr NodeTypeManager
+ * @param superTypes Comma separated String with JCR node types
+ * @return returns <code>false</code> if one of the supertypes does not exist, otherwise returns <code>true</code>
+ */
+ private boolean checkSuperTypes(javax.jcr.nodetype.NodeTypeManager ntMgr,
+ String superTypes)
+ {
+ boolean exists = true;
+
+ if (superTypes != null && superTypes.length() > 0)
+ {
+ String[] superTypesArray = superTypes.split(",");
+ log.debug("JCR super types found: " + superTypesArray.length);
+ for (int i = 0; i < superTypesArray.length; i++)
+ {
+ try
+ {
+ ntMgr.getNodeType(superTypesArray[i]);
+ }
+ catch (Exception e)
+ {
+ log.error("JCR super type '" + superTypesArray[i] + "' does not exist!");
+ exists = false;
+ break;
+ }
+ }
+ }
+
+ return exists;
+ }
+
+ public String[] getJcrSuperTypes(String superTypes)
+ {
+ return superTypes.split(",");
+ }
+
+ private boolean isPropertyType(String type)
+ {
+ return (type.equals(PropertyType.TYPENAME_BINARY) ||
+ type.equals(PropertyType.TYPENAME_BOOLEAN) ||
+ type.equals(PropertyType.TYPENAME_DATE) ||
+ type.equals(PropertyType.TYPENAME_DOUBLE) ||
+ type.equals(PropertyType.TYPENAME_LONG) ||
+ type.equals(PropertyType.TYPENAME_NAME) ||
+ type.equals(PropertyType.TYPENAME_PATH) ||
+ type.equals(PropertyType.TYPENAME_REFERENCE) ||
+ type.equals(PropertyType.TYPENAME_WEAKREFERENCE) ||
+ type.equals(PropertyType.TYPENAME_DECIMAL) ||
+ type.equals(PropertyType.TYPENAME_URI) ||
+ type.equals(PropertyType.TYPENAME_STRING));
+ }
+}