Index: modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/Repository.java
new file mode 100644
===================================================================
--- /dev/null (revision 1812)
+++ modeshape-jcr-api/src/main/java/org/modeshape/jcr/api/Repository.java (working copy)
@@ -0,0 +1,464 @@
+package org.modeshape.jcr.api;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import javax.jcr.Value;
+
+/**
+ * Replicates JCR 2.0's Repository interface.
+ */
+public interface Repository extends javax.jcr.Repository {
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if repository content can be updated
+ * through the JCR API (as opposed to having read-only access).
+ *
+ * @since JCR 2.0
+ */
+ public static final String WRITE_SUPPORTED = "write.supported";
+
+ /**
+ * Key to a String
descriptor. Returns one of the following javax.jcr.Repository
constants
+ * indicating the stability of identifiers:
+ *
+ *
+ *
+ *
+ *
+ *
IDENTIFIER_STABILITY
. Indicates that identifiers may change
+ * between method calls.
+ *
+ * @since JCR 2.0
+ */
+ public static final String IDENTIFIER_STABILITY_METHOD_DURATION = "identifier.stability.method.duration";
+
+ /**
+ * One of four possible values for the descriptor IDENTIFIER_STABILITY
. Indicates that identifiers are guaranteed
+ * stable within a single save/refresh cycle.
+ *
+ * @since JCR 2.0
+ */
+ public static final String IDENTIFIER_STABILITY_SAVE_DURATION = "identifier.stability.save.duration";
+
+ /**
+ * One of four possible values for the descriptor IDENTIFIER_STABILITY
. Indicates that identifiers are guaranteed
+ * stable within a single session.
+ *
+ * @since JCR 2.0
+ */
+ public static final String IDENTIFIER_STABILITY_SESSION_DURATION = "identifier.stability.session.duration";
+
+ /**
+ * One of four possible values for the descriptor IDENTIFIER_STABILITY
. Indicates that identifiers are guaranteed
+ * to be stable forever.
+ *
+ * @since JCR 2.0
+ */
+ public static final String IDENTIFIER_STABILITY_INDEFINITE_DURATION = "identifier.stability.indefinite.duration";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if XML export is supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_XML_EXPORT_SUPPORTED = "option.xml.export.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if XML import is supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_XML_IMPORT_SUPPORTED = "option.xml.import.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if unfiled content is supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_UNFILED_CONTENT_SUPPORTED = "option.unfiled.content.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if full versioning is supported.
+ */
+ public static final String OPTION_VERSIONING_SUPPORTED = "option.versioning.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if simple versioning is supported.
+ */
+ public static final String OPTION_SIMPLE_VERSIONING_SUPPORTED = "option.simple.versioning.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if activities are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_ACTIVITIES_SUPPORTED = "option.activities.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if configurations and baselines are
+ * supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_BASELINES_SUPPORTED = "option.baselines.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if access control is supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_ACCESS_CONTROL_SUPPORTED = "option.access.control.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if journaled observation is supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_JOURNALED_OBSERVATION_SUPPORTED = "option.journaled.observation.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if retention and hold are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_RETENTION_SUPPORTED = "option.retention.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if lifecycles are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_LIFECYCLE_SUPPORTED = "option.lifecycle.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if workspace management is supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_WORKSPACE_MANAGEMENT_SUPPORTED = "option.workspace.management.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if the primary node type of an existing
+ * node can be updated.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_UPDATE_PRIMARY_NODE_TYPE_SUPPORTED = "option.update.primary.node.type.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if the mixin node types of an existing node
+ * can be added and removed.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_UPDATE_MIXIN_NODE_TYPES_SUPPORTED = "option.update.mixin.node.types.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if the creation of shareable nodes is
+ * supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_SHAREABLE_NODES_SUPPORTED = "option.shareable.nodes.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if node type management is supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_NODE_TYPE_MANAGEMENT_SUPPORTED = "option.node.type.management.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if node and property with same name is
+ * supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED = "option.node.and.property.with.same.name.supported";
+
+ /**
+ * Key to String
descriptor. Returns one of the following javax.jcr.Repository
constants indicating
+ * the level of support for node type inheritance:
+ * NODE_TYPE_MANAGEMENT_INHERITANCE
. Indicates that registration
+ * of primary node types is limited to those which have only nt:base as supertype. Registration of mixin node types is limited
+ * to those without any supertypes.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_INHERITANCE_MINIMAL = "node.type.management.inheritance.minimal";
+
+ /**
+ * One of three possible values for the descriptor NODE_TYPE_MANAGEMENT_INHERITANCE
. Indicates that registration
+ * of primary node types is limited to those with exactly one supertype. Registration of mixin node types is limited to those
+ * with at most one supertype.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_INHERITANCE_SINGLE = "node.type.management.inheritance.single";
+
+ /**
+ * One of three possible values for the descriptor NODE_TYPE_MANAGEMENT_INHERITANCE
. Indicates that primary node
+ * types can be registered with one or more supertypes. Mixin node types can be registered with zero or more supertypes.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_INHERITANCE_MULTIPLE = "node.type.management.inheritance.multiple";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if override of inherited property or child
+ * node definitions is supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_OVERRIDES_SUPPORTED = "node.type.management.overrides.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if primary items are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_PRIMARY_ITEM_NAME_SUPPORTED = "node.type.management.primary.item.name.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if preservation of child node ordering is
+ * supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_ORDERABLE_CHILD_NODES_SUPPORTED = "node.type.management.orderable.child.nodes.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if residual property and child node
+ * definitions are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_RESIDUAL_DEFINITIONS_SUPPORTED = "node.type.management.residual.definitions.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if autocreated properties and child nodes
+ * are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_AUTOCREATED_DEFINITIONS_SUPPORTED = "node.type.management.autocreated.definitions.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if same-name sibling child nodes are
+ * supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_SAME_NAME_SIBLINGS_SUPPORTED = "node.type.management.same.name.siblings.supported";
+
+ /**
+ * Key to a long[]
descriptor. Returns an array holding the javax.jcr.PropertyType
constants for the
+ * property types (including UNDEFINED
, if supported) that a registered node type can specify, or a zero-length
+ * array if registered node types cannot specify property definitions.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_PROPERTY_TYPES = "node.type.management.property.types";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if multivalue properties are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_MULTIVALUED_PROPERTIES_SUPPORTED = "node.type.management.multivalued.properties.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if registration of a node types with more
+ * than one BINARY
property is permitted.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_MULTIPLE_BINARY_PROPERTIES_SUPPORTED = "node.type.management.multiple.binary.properties.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true if and only value-constraints are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_VALUE_CONSTRAINTS_SUPPORTED = "node.type.management.value.constraints.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true if and only the update of node types is supported for node types
+ * currently in use as the type of an existing node in the repository.
+ *
+ * @since JCR 2.0
+ */
+ public static final String NODE_TYPE_MANAGEMENT_UPDATE_IN_USE_SUPORTED = "node.type.management.update.in.use.suported";
+
+ /**
+ * Key to a String[]
descriptor. Returns an array holding the constants representing the supported query
+ * languages, or a zero-length if query is not supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String QUERY_LANGUAGES = "query.languages";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if stored queries are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String QUERY_STORED_QUERIES_SUPPORTED = "query.stored.queries.supported";
+
+ /**
+ * Key to a boolean
descriptor. Returns true
if and only if full-text search is supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String QUERY_FULL_TEXT_SEARCH_SUPPORTED = "query.full.text.search.supported";
+
+ /**
+ * Key to String
descriptor. Returns one of the following javax.jcr.Repository
constants indicating
+ * the level of support for joins in queries:
+ * QUERY_JOINS
+ *
. Indicates that joins are not supported. Queries are limited to a
+ * single selector.
+ *
+ * @since JCR 2.0
+ */
+ public static final String QUERY_JOINS_NONE = "query.joins.none";
+
+ /**
+ * One of three possible values for the descriptor QUERY_JOINS
+ *
. Indicates that inner joins are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String QUERY_JOINS_INNER = "query.joins.inner";
+
+ /**
+ * One of three possible values for the descriptor QUERY_JOINS
+ *
. Indicates that inner and outer joins are supported.
+ *
+ * @since JCR 2.0
+ */
+ public static final String QUERY_JOINS_INNER_OUTER = "query.joins.inner.outer";
+
+ /**
+ * Returns a string array holding all descriptor keys available for this implementation, both the standard descriptors defined
+ * by the string constants in this interface and any implementation-specific descriptors. Used in conjunction with
+ * {@link #getDescriptorValue(String key)} and {@link #getDescriptorValues(String key)} to query information about this
+ * repository implementation.
+ *
+ * @return a string array holding all descriptor keys.
+ */
+ public String[] getDescriptorKeys();
+
+ /**
+ * Returns true
if key
is a standard descriptor defined by the string constants in this interface
+ * and false
if it is either a valid implementation-specific key or not a valid key.
+ *
+ * @param key a descriptor key.
+ * @return whether key
is a standard descriptor.
+ * @since JCR 2.0
+ */
+ public boolean isStandardDescriptor( String key );
+
+ /**
+ * Returns true
if key
is a valid single-value descriptor; otherwise returns false
.
+ *
+ * @param key a descriptor key.
+ * @return whether the specified desdfriptor is multi-valued.
+ * @since JCR 2.0
+ */
+ public boolean isSingleValueDescriptor( String key );
+
+ /**
+ * The value of a single-value descriptor is found by passing the key for that descriptor to this method. If key
+ * is the key of a multi-value descriptor or not a valid key this method returns null
.
+ *
+ * @param key a descriptor key.
+ * @return The value of the indicated descriptor
+ * @since JCR 2.0
+ */
+ public Value getDescriptorValue( String key );
+
+ /**
+ * The value array of a multi-value descriptor is found by passing the key for that descriptor to this method. If
+ * key
is the key of a single-value descriptor then this method returns that value as an array of size one. If
+ * key
is not a valid key this method returns null
.
+ *
+ * @param key a descriptor key.
+ * @return the value array for the indicated descriptor
+ * @since JCR 2.0
+ */
+ public Value[] getDescriptorValues( String key );
+
+ /**
+ * A collection of "standard" descriptors, as defined in the JSR-283 specification.
+ */
+ public static final Setkey
is null
.
- * @see javax.jcr.Repository#getDescriptor(java.lang.String)
+ * @see Repository#getDescriptor(java.lang.String)
*/
public String getDescriptor( String key ) {
+ if (!isSingleValueDescriptor(key)) return null;
+
+ JcrValue value = (JcrValue)descriptors.get(key);
+ try {
+ return value.getString();
+ } catch (RepositoryException re) {
+ throw new IllegalStateException(re);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalArgumentException if {@code key} is null or empty
+ * @see Repository#getDescriptorValue(String)
+ */
+ public JcrValue getDescriptorValue( String key ) {
+ if (!isSingleValueDescriptor(key)) return null;
+ return (JcrValue)descriptors.get(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalArgumentException if {@code key} is null or empty
+ * @see Repository#getDescriptorValues(String)
+ */
+ public JcrValue[] getDescriptorValues( String key ) {
+ Object value = descriptors.get(key);
+ if (value instanceof JcrValue[]) {
+ return (JcrValue[])value;
+ }
+ if (value instanceof JcrValue) {
+ return new JcrValue[] {(JcrValue)value};
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalArgumentException if {@code key} is null or empty
+ * @see Repository#isSingleValueDescriptor(String)
+ */
+ public boolean isSingleValueDescriptor( String key ) {
CheckArg.isNotEmpty(key, "key");
- return descriptors.get(key);
+ return descriptors.get(key) instanceof JcrValue;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws IllegalArgumentException if {@code key} is null or empty
+ * @see Repository#isStandardDescriptor(String)
+ */
+ public boolean isStandardDescriptor( String key ) {
+ return STANDARD_DESCRIPTORS.contains(key);
}
/**
@@ -1157,7 +1180,7 @@ public class JcrRepository implements Repository {
}
}
- protected static Properties getBundleProperties() throws RepositoryException {
+ protected static Properties getBundleProperties() {
if (bundleProperties == null) {
// This is idempotent, so we don't need to lock ...
InputStream stream = null;
@@ -1168,7 +1191,7 @@ public class JcrRepository implements Repository {
props.load(stream);
bundleProperties = new UnmodifiableProperties(props);
} catch (IOException e) {
- throw new RepositoryException(JcrI18n.failedToReadPropertiesFromManifest.text(e.getLocalizedMessage()), e);
+ throw new IllegalStateException(JcrI18n.failedToReadPropertiesFromManifest.text(e.getLocalizedMessage()), e);
} finally {
if (stream != null) {
try {
@@ -1184,14 +1207,121 @@ public class JcrRepository implements Repository {
}
protected static String getBundleProperty( String propertyName,
- boolean required ) throws RepositoryException {
+ boolean required ) {
String value = getBundleProperties().getProperty(propertyName);
if (value == null && required) {
- throw new RepositoryException(JcrI18n.failedToReadPropertyFromManifest.text(propertyName));
+ throw new IllegalStateException(JcrI18n.failedToReadPropertyFromManifest.text(propertyName));
}
return value;
}
+ /**
+ * Combines the given custom descriptors with the default repository descriptors.
+ *
+ * @param factories the value factories to use to create the descriptor values
+ * @param customDescriptors the custom descriptors; may be null
+ * @return the custom descriptors (if any) combined with the default repository descriptors; never null or empty
+ */
+ private static Map