/* * ModeShape (http://www.modeshape.org) * * 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.modeshape.jcr; import java.util.ArrayList; import java.util.List; import javax.jcr.nodetype.ConstraintViolationException; import javax.jcr.nodetype.NodeDefinition; import javax.jcr.nodetype.NodeDefinitionTemplate; import javax.jcr.nodetype.NodeTypeTemplate; import javax.jcr.nodetype.PropertyDefinition; import javax.jcr.nodetype.PropertyDefinitionTemplate; import org.modeshape.common.annotation.NotThreadSafe; import org.modeshape.common.util.CheckArg; import org.modeshape.jcr.value.Name; import org.modeshape.jcr.value.ValueFormatException; /** * ModeShape implementation of the JCR NodeTypeTemplate interface */ @NotThreadSafe public class JcrNodeTypeTemplate implements NodeTypeTemplate { private final ExecutionContext context; private final List<NodeDefinitionTemplate> nodeDefinitionTemplates = new ArrayList<NodeDefinitionTemplate>(); private final List<PropertyDefinitionTemplate> propertyDefinitionTemplates = new ArrayList<PropertyDefinitionTemplate>(); private final boolean createdFromExistingDefinition; private boolean isAbstract; private boolean queryable = true; private boolean mixin; private boolean orderableChildNodes; private Name[] declaredSupertypeNames; private Name name; private Name primaryItemName; JcrNodeTypeTemplate( ExecutionContext context ) { this(context, false); } JcrNodeTypeTemplate( ExecutionContext context, boolean createdFromExistingDefinition ) { assert context != null; this.context = context; this.createdFromExistingDefinition = createdFromExistingDefinition; } JcrNodeTypeTemplate( JcrNodeTypeTemplate original, ExecutionContext context ) { this.context = context; this.isAbstract = original.isAbstract; this.queryable = original.queryable; this.mixin = original.mixin; this.name = original.name; this.orderableChildNodes = original.orderableChildNodes; this.declaredSupertypeNames = original.declaredSupertypeNames; this.primaryItemName = original.primaryItemName; JcrItemDefinitionTemplate.registerMissingNamespaces(original.context, context, this.name); JcrItemDefinitionTemplate.registerMissingNamespaces(original.context, context, this.declaredSupertypeNames); JcrItemDefinitionTemplate.registerMissingNamespaces(original.context, context, this.primaryItemName); for (NodeDefinitionTemplate childDefn : original.nodeDefinitionTemplates) { this.nodeDefinitionTemplates.add(((JcrNodeDefinitionTemplate)childDefn).with(context)); } for (PropertyDefinitionTemplate propDefn : original.propertyDefinitionTemplates) { this.propertyDefinitionTemplates.add(((JcrPropertyDefinitionTemplate)propDefn).with(context)); } this.createdFromExistingDefinition = original.createdFromExistingDefinition; } JcrNodeTypeTemplate with( ExecutionContext context ) { return context == this.context ? this : new JcrNodeTypeTemplate(this, context); } ExecutionContext getExecutionContext() { return context; } private String string( Name name ) { if (name == null) return null; return name.getString(context.getNamespaceRegistry()); } Name[] declaredSupertypeNames() { return this.declaredSupertypeNames; } @Override public List<NodeDefinitionTemplate> getNodeDefinitionTemplates() { return nodeDefinitionTemplates; } @Override public List<PropertyDefinitionTemplate> getPropertyDefinitionTemplates() { return propertyDefinitionTemplates; } @Override public void setAbstract( boolean isAbstract ) { this.isAbstract = isAbstract; } @Override public void setDeclaredSuperTypeNames( String[] names ) throws ConstraintViolationException { if (names == null) { throw new ConstraintViolationException(JcrI18n.badNodeTypeName.text("names")); } Name[] supertypeNames = new Name[names.length]; for (int i = 0; i < names.length; i++) { CheckArg.isNotEmpty(names[i], "names[" + i + ""); try { supertypeNames[i] = context.getValueFactories().getNameFactory().create(names[i]); } catch (ValueFormatException vfe) { throw new ConstraintViolationException(vfe); } } this.declaredSupertypeNames = supertypeNames; } @Override public void setMixin( boolean mixin ) { this.mixin = mixin; } @Override public void setName( String name ) throws ConstraintViolationException { CheckArg.isNotEmpty(name, "name"); try { this.name = context.getValueFactories().getNameFactory().create(name); } catch (ValueFormatException vfe) { throw new ConstraintViolationException(vfe); } } @Override public void setOrderableChildNodes( boolean orderable ) { this.orderableChildNodes = orderable; } /** * {@inheritDoc} * <p> * Passing a null or blank name is equivalent to "unsetting" (or removing) the primary item name. * </p> * * @see javax.jcr.nodetype.NodeTypeDefinition#getPrimaryItemName() type.NodeTypeTemplate#setPrimaryItemName(java.lang.String) */ @Override public void setPrimaryItemName( String name ) throws ConstraintViolationException { if (name == null || name.trim().length() == 0) { this.primaryItemName = null; } else { try { this.primaryItemName = context.getValueFactories().getNameFactory().create(name); } catch (ValueFormatException vfe) { throw new ConstraintViolationException(vfe); } } } @Override public NodeDefinition[] getDeclaredChildNodeDefinitions() { if (!createdFromExistingDefinition && nodeDefinitionTemplates.isEmpty()) return null; return nodeDefinitionTemplates.toArray(new NodeDefinition[nodeDefinitionTemplates.size()]); } @Override public PropertyDefinition[] getDeclaredPropertyDefinitions() { if (!createdFromExistingDefinition && propertyDefinitionTemplates.isEmpty()) return null; return propertyDefinitionTemplates.toArray(new PropertyDefinition[propertyDefinitionTemplates.size()]); } @Override public String[] getDeclaredSupertypeNames() { if (declaredSupertypeNames == null) return new String[0]; String[] names = new String[declaredSupertypeNames.length]; for (int i = 0; i < declaredSupertypeNames.length; i++) { names[i] = declaredSupertypeNames[i].getString(context.getNamespaceRegistry()); } return names; } @Override public String getName() { return string(name); } @Override public String getPrimaryItemName() { return string(primaryItemName); } @Override public boolean hasOrderableChildNodes() { return orderableChildNodes; } @Override public boolean isAbstract() { return isAbstract; } @Override public boolean isMixin() { return mixin; } @Override public boolean isQueryable() { return queryable; } @Override public void setQueryable( boolean queryable ) { this.queryable = queryable; } @Override public String toString() { return getName(); } }