All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.modeshape.jcr.PropertyDefinitionId Maven / Gradle / Ivy

There is a newer version: 5.4.1.Final
Show newest version
/*
 * ModeShape (http://www.modeshape.org)
 * See the COPYRIGHT.txt file distributed with this work for information
 * regarding copyright ownership.  Some portions may be licensed
 * to Red Hat, Inc. under one or more contributor license agreements.
 * See the AUTHORS.txt file in the distribution for a full listing of 
 * individual contributors.
 *
 * Unless otherwise indicated, all code in ModeShape is licensed
 * to you under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 * 
 * ModeShape is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.modeshape.jcr;

import java.util.HashMap;
import javax.jcr.PropertyType;
import org.modeshape.common.annotation.Immutable;
import org.modeshape.jcr.value.Name;
import org.modeshape.jcr.value.NameFactory;
import org.modeshape.jcr.value.ValueFormatException;

/**
 * An immutable identifier for a property definition. Although instances cannot be serialized, the property definitions are often
 * stored within the graph as {@link #getString() string values} on a property. These string values can later be
 * {@link #fromString(String, NameFactory) parsed} to reconstruct the identifier. Note that this string representation does not
 * use namespace prefixes, so they are long-lasting and durable.
 * 

* What distinguishes one property definition from another is not well documented in the JSR-170 specification. The closest this * version of the spec gets is Section 6.7.15, but that merely says that more than one property definition can have the same name. * The JSR-283 specification does clarify this more: Section 3.7.2.1.3 says : *

*

* "A node type may have two or more property definitions with identical name attributes (the value returned by * ItemDefinition.getName) as long as the definitions are otherwise distinguishable by either the required type attribute (the * value returned by PropertyDefinition.getRequiredType) or the multiple attribute (the value returned by * PropertyDefinition.isMultiple)." *

*

* This class is {@link Immutable} and designed to be used as a key in a {@link HashMap}. *

*/ @Immutable final class PropertyDefinitionId { /** * The string-form of the name that can be used to represent a residual property definition. */ public static final String ANY_NAME = JcrNodeType.RESIDUAL_ITEM_NAME; private final Name nodeTypeName; private final Name propertyDefinitionName; private final int propertyType; private final boolean allowsMultiple; /** * A cached string representation, which is used for {@link #equals(Object)} and {@link #hashCode()} among other things. */ private final String stringRepresentation; /** * Create a new identifier for a property definition. * * @param nodeTypeName the name of the node type; may not be null * @param propertyDefinitionName the name of the property definition, which may be a {@link #ANY_NAME residual property}; may * not be null * @param propertyType the required property type for the definition; must be a valid {@link PropertyType} value * @param allowsMultiple true if the property definition should allow multiple values, or false if it is a single-value * property definition */ public PropertyDefinitionId( Name nodeTypeName, Name propertyDefinitionName, int propertyType, boolean allowsMultiple ) { this.nodeTypeName = nodeTypeName; this.propertyDefinitionName = propertyDefinitionName; this.propertyType = propertyType; this.allowsMultiple = allowsMultiple; this.stringRepresentation = this.nodeTypeName.getString() + '/' + this.propertyDefinitionName.getString() + '/' + org.modeshape.jcr.api.PropertyType.nameFromValue(propertyType) + '/' + (allowsMultiple ? '*' : '1'); } /** * Get the name of the node type on which the property definition is defined * * @return the node type's name; may not be null */ public Name getNodeTypeName() { return nodeTypeName; } /** * Get the name of the property definition. * * @return the property definition's name; never null */ public Name getPropertyDefinitionName() { return propertyDefinitionName; } /** * Get the required property type * * @return the property type; always a valid {@link PropertyType} value */ public int getPropertyType() { return propertyType; } /** * Return whether the property definition allows multiple values. * * @return true if the property definition allows multiple values, or false if it is a single-value property definition */ public boolean allowsMultiple() { return allowsMultiple; } /** * Determine whether this property definition allows properties with any name. * * @return true if this node definition allows properties with any name, or false if this definition requires a particular * property name */ public boolean allowsAnyChildName() { return propertyDefinitionName.getLocalName().equals(ANY_NAME) && propertyDefinitionName.getNamespaceUri().length() == 0; } /** * Get the string form of this identifier. This form can be persisted, since it does not rely upon namespace prefixes. * * @return the string form */ public String getString() { return this.stringRepresentation; } /** * Parse the supplied string for of an identifer, and return the object form for that identifier. * * @param definition the {@link #getString() string form of the identifier}; may not be null * @param factory the factory that should be used to create Name objects; may not be null * @return the object form of the identifier; never null * @throws ValueFormatException if the definition is not the valid format */ public static PropertyDefinitionId fromString( String definition, NameFactory factory ) { String[] parts = definition.split("/"); String nodeTypeNameString = parts[0]; String propertyDefinitionNameString = parts[1]; Name nodeTypeName = factory.create(nodeTypeNameString); Name propertyDefinitionName = factory.create(propertyDefinitionNameString); int propertyType = org.modeshape.jcr.api.PropertyType.valueFromName(parts[2]); boolean allowsMultiple = parts[3].charAt(0) == '*'; return new PropertyDefinitionId(nodeTypeName, propertyDefinitionName, propertyType, allowsMultiple); } public PropertyDefinitionId asSingleValued() { return new PropertyDefinitionId(nodeTypeName, propertyDefinitionName, propertyType, false); } public PropertyDefinitionId asMultiValued() { return new PropertyDefinitionId(nodeTypeName, propertyDefinitionName, propertyType, true); } @Override public int hashCode() { return this.stringRepresentation.hashCode(); } @Override public boolean equals( Object obj ) { if (obj == this) return true; if (obj instanceof PropertyDefinitionId) { PropertyDefinitionId that = (PropertyDefinitionId)obj; return this.stringRepresentation.equals(that.stringRepresentation); } return false; } @Override public String toString() { return this.stringRepresentation; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy