/*
* 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 static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
import java.util.List;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeDefinitionTemplate;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeDefinition;
import javax.jcr.nodetype.NodeTypeTemplate;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.nodetype.PropertyDefinitionTemplate;
import org.modeshape.jcr.api.query.qom.QueryObjectModelConstants;
/**
* Helper class to compare various manifestions of node type definitions. Ideally, this should be converted to a Hamcrest matcher
* at some point.
*/
public class NodeTypeAssertion {
@SuppressWarnings( "unchecked" )
public static void compareTemplateToNodeType( NodeTypeTemplate template,
NodeType nodeType ) {
compareNodeTypeDefinitions(template, nodeType);
PropertyDefinition[] propertyDefs = nodeType.getDeclaredPropertyDefinitions();
List<PropertyDefinitionTemplate> propertyTemplates = template.getPropertyDefinitionTemplates();
comparePropertyDefinitions(propertyDefs, propertyTemplates);
NodeDefinition[] childNodeDefs = nodeType.getDeclaredChildNodeDefinitions();
List<NodeDefinitionTemplate> childNodeTemplates = template.getNodeDefinitionTemplates();
compareChildNodeDefinitions(childNodeDefs, childNodeTemplates);
}
private static void compareNodeTypeDefinitions( NodeTypeDefinition template,
NodeTypeDefinition nodeType ) {
assertThat(nodeType, is(notNullValue()));
assertThat(nodeType.getName(), is(template.getName()));
assertThat(nodeType.getDeclaredSupertypeNames().length, is(template.getDeclaredSupertypeNames().length));
for (int i = 0; i < template.getDeclaredSupertypeNames().length; i++) {
assertThat(template.getDeclaredSupertypeNames()[i], is(nodeType.getDeclaredSupertypeNames()[i]));
}
assertThat(template.isMixin(), is(nodeType.isMixin()));
assertThat(template.hasOrderableChildNodes(), is(nodeType.hasOrderableChildNodes()));
assertThat(template.isQueryable(), is(nodeType.isQueryable()));
assertThat(template.isAbstract(), is(nodeType.isAbstract()));
}
private static void comparePropertyDefinitions( PropertyDefinition[] propertyDefs,
List<PropertyDefinitionTemplate> propertyTemplates ) {
assertThat(propertyDefs.length, is(propertyTemplates.size()));
for (PropertyDefinitionTemplate pt : propertyTemplates) {
JcrPropertyDefinitionTemplate propertyTemplate = (JcrPropertyDefinitionTemplate)pt;
PropertyDefinition matchingDefinition = null;
for (int i = 0; i < propertyDefs.length; i++) {
PropertyDefinition pd = propertyDefs[i];
String ptName = propertyTemplate.getName() == null ? JcrNodeType.RESIDUAL_ITEM_NAME : propertyTemplate.getName();
if (pd.getName().equals(ptName) && pd.getRequiredType() == propertyTemplate.getRequiredType()
&& pd.isMultiple() == propertyTemplate.isMultiple()) {
matchingDefinition = pd;
break;
}
}
comparePropertyTemplateToPropertyDefinition(propertyTemplate, (JcrPropertyDefinition)matchingDefinition);
}
}
private static void compareChildNodeDefinitions( NodeDefinition[] childNodeDefs,
List<NodeDefinitionTemplate> childNodeTemplates ) {
assertThat(childNodeDefs.length, is(childNodeTemplates.size()));
for (NodeDefinitionTemplate nt : childNodeTemplates) {
JcrNodeDefinitionTemplate childNodeTemplate = (JcrNodeDefinitionTemplate)nt;
NodeDefinition matchingDefinition = null;
for (int i = 0; i < childNodeDefs.length; i++) {
NodeDefinition nd = childNodeDefs[i];
String ntName = childNodeTemplate.getName() == null ? JcrNodeType.RESIDUAL_ITEM_NAME : childNodeTemplate.getName();
if (nd.getName().equals(ntName) && nd.allowsSameNameSiblings() == childNodeTemplate.allowsSameNameSiblings()) {
boolean onlyBaseTypeRequired = nd.getRequiredPrimaryTypes().length == 0
|| (nd.getRequiredPrimaryTypes().length == 1 && nd.getRequiredPrimaryTypes()[0].getName().equals("nt:base"));
boolean onlyHasBase = childNodeTemplate.getRequiredPrimaryTypeNames().length == 0
|| (childNodeTemplate.getRequiredPrimaryTypeNames().length == 1 && childNodeTemplate.getRequiredPrimaryTypeNames()[0].equals("nt:base"));
if (onlyBaseTypeRequired && onlyHasBase) {
// We have a match
matchingDefinition = nd;
break;
}
if (nd.getRequiredPrimaryTypes().length != childNodeTemplate.getRequiredPrimaryTypeNames().length) continue;
boolean matchesOnRequiredTypes = true;
for (int j = 0; j < nd.getRequiredPrimaryTypes().length; j++) {
String ndName = nd.getRequiredPrimaryTypes()[j].getName();
String tempName = childNodeTemplate.getRequiredPrimaryTypeNames()[j];
if (!ndName.equals(tempName)) {
matchesOnRequiredTypes = false;
break;
}
}
if (matchesOnRequiredTypes) {
matchingDefinition = nd;
break;
}
}
}
if (matchingDefinition == null) {
System.out.println(childNodeTemplate);
}
compareNodeTemplateToNodeDefinition(childNodeTemplate, (JcrNodeDefinition)matchingDefinition);
}
}
private static void comparePropertyTemplateToPropertyDefinition( JcrPropertyDefinitionTemplate template,
JcrPropertyDefinition definition ) {
assertThat(definition, is(notNullValue()));
assertThat(definition.getDeclaringNodeType(), is(notNullValue()));
// Had to match on name to even get to the definition
// assertThat(template.getName(), is(definition.getName()));
assertThat(emptyIfNull(template.getValueConstraints()), is(definition.getValueConstraints()));
assertThat(template.getOnParentVersion(), is(definition.getOnParentVersion()));
assertThat(template.getRequiredType(), is(definition.getRequiredType()));
assertThat(template.isAutoCreated(), is(definition.isAutoCreated()));
assertThat(template.isMandatory(), is(definition.isMandatory()));
assertThat(template.isMultiple(), is(definition.isMultiple()));
assertThat(template.isProtected(), is(definition.isProtected()));
assertThat(template.isFullTextSearchable(), is(definition.isFullTextSearchable()));
assertThat(template.isQueryOrderable(), is(definition.isQueryOrderable()));
String[] tempOps = template.getAvailableQueryOperators();
if (tempOps == null) {
tempOps = new String[] {QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO,
QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN,
QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN_OR_EQUAL_TO,
QueryObjectModelConstants.JCR_OPERATOR_LESS_THAN, QueryObjectModelConstants.JCR_OPERATOR_LESS_THAN_OR_EQUAL_TO,
QueryObjectModelConstants.JCR_OPERATOR_LIKE, QueryObjectModelConstants.JCR_OPERATOR_NOT_EQUAL_TO};
}
assertThat(tempOps, is(definition.getAvailableQueryOperators()));
}
private static void compareNodeTemplateToNodeDefinition( JcrNodeDefinitionTemplate template,
JcrNodeDefinition definition ) {
assertThat(definition, is(notNullValue()));
assertThat(definition.getDeclaringNodeType(), is(notNullValue()));
// Had to match on name to even get to the definition
// assertThat(template.getName(), is(definition.getName()));
assertThat(template.getOnParentVersion(), is(definition.getOnParentVersion()));
assertThat(template.isAutoCreated(), is(definition.isAutoCreated()));
assertThat(template.isMandatory(), is(definition.isMandatory()));
assertThat(template.isProtected(), is(definition.isProtected()));
assertThat(template.getDefaultPrimaryTypeName(), is(definition.getDefaultPrimaryTypeName()));
assertThat(template.allowsSameNameSiblings(), is(definition.allowsSameNameSiblings()));
// assertThat(template.getRequiredPrimaryTypeNames(), is(definition.getRequiredPrimaryTypeNames()));
}
private static String[] emptyIfNull( String[] incoming ) {
if (incoming != null) return incoming;
return new String[0];
}
}