You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by tr...@apache.org on 2013/11/14 02:56:42 UTC
svn commit: r1541782 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/api/
oak-core/src/main/java/org/apache/jackrabbit/oak/core/
oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/
oak-jcr/src/test/java/org/apac...
Author: tripod
Date: Thu Nov 14 01:56:41 2013
New Revision: 1541782
URL: http://svn.apache.org/r1541782
Log:
OAK-1126 Same node and property name support
- added org.apache.jackrabbit.oak.api.Descriptors and expose them already on the ContentRepository
- simply set the SNNP descriptor based on the NodeStore implementation
- adding simple SNNP tests
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Descriptors.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DescriptorsImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/JcrDescriptorsImpl.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/SameNamePropertyNodeTest.java
Removed:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/Descriptors.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentRepository.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/RepositoryImpl.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentRepository.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentRepository.java?rev=1541782&r1=1541781&r2=1541782&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentRepository.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentRepository.java Thu Nov 14 01:56:41 2013
@@ -83,4 +83,12 @@ public interface ContentRepository {
ContentSession login(@Nullable Credentials credentials, @Nullable String workspaceName)
throws LoginException, NoSuchWorkspaceException;
+ /**
+ * Returns the repository descriptors which contain all or a subset of the descriptors defined in
+ * {@link javax.jcr.Repository}.
+ *
+ * @return the repository descriptors
+ */
+ @Nonnull
+ Descriptors getDescriptors();
}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Descriptors.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Descriptors.java?rev=1541782&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Descriptors.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/Descriptors.java Thu Nov 14 01:56:41 2013
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.jackrabbit.oak.api;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.jcr.Value;
+
+/**
+ * Repository descriptors interface that is used to support providing the repository descriptors of
+ * {@link javax.jcr.Repository}
+ */
+public interface Descriptors {
+
+ /**
+ * 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 #getValue(String key)} and
+ * {@link #getValues(String key)} to query information about this
+ * repository implementation.
+ *
+ * @return a string array holding all descriptor keys.
+ */
+ @Nonnull
+ String[] getKeys();
+
+ /**
+ * Returns {@code true} if {@code key} is a standard descriptor
+ * defined by the string constants in this interface and {@code false}
+ * if it is either a valid implementation-specific key or not a valid key.
+ *
+ * @param key a descriptor key.
+ * @return whether <code>key</code> is a standard descriptor.
+ */
+ boolean isStandardDescriptor(@Nonnull String key);
+
+ /**
+ * Returns {@code true} if {@code key} is a valid single-value
+ * descriptor; otherwise returns {@code false}
+ *
+ * @param key a descriptor key.
+ * @return whether the specified descriptor is multi-valued.
+ * @since JCR 2.0
+ */
+ boolean isSingleValueDescriptor(@Nonnull String key);
+
+ /**
+ * The value of a single-value descriptor is found by passing the key for
+ * that descriptor to this method. If {@code key} is the key of a
+ * multi-value descriptor or not a valid key this method returns
+ * {@code null}.
+ *
+ * @param key a descriptor key.
+ * @return The value of the indicated descriptor
+ */
+ @CheckForNull
+ Value getValue(@Nonnull String key);
+
+ /**
+ * The value array of a multi-value descriptor is found by passing the key
+ * for that descriptor to this method. If {@code key} is the key of a
+ * single-value descriptor then this method returns that value as an array
+ * of size one. If {@code key} is not a valid key this method returns
+ * {@code null}.
+ *
+ * @param key a descriptor key.
+ * @return the value array for the indicated descriptor
+ */
+ @CheckForNull
+ Value[] getValues(@Nonnull String key);
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java?rev=1541782&r1=1541781&r2=1541782&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java Thu Nov 14 01:56:41 2013
@@ -16,16 +16,25 @@
*/
package org.apache.jackrabbit.oak.core;
-import static com.google.common.base.Preconditions.checkNotNull;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.jcr.Credentials;
import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.PropertyType;
+import javax.jcr.Repository;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
import javax.security.auth.login.LoginException;
+import org.apache.jackrabbit.commons.SimpleValueFactory;
import org.apache.jackrabbit.oak.api.ContentRepository;
import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.Descriptors;
+import org.apache.jackrabbit.oak.kernel.KernelNodeStore;
import org.apache.jackrabbit.oak.spi.commit.CommitHook;
import org.apache.jackrabbit.oak.spi.query.CompositeQueryIndexProvider;
import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
@@ -35,6 +44,59 @@ import org.apache.jackrabbit.oak.spi.sec
import org.apache.jackrabbit.oak.spi.security.authentication.LoginContextProvider;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.jcr.Repository.IDENTIFIER_STABILITY;
+import static javax.jcr.Repository.LEVEL_1_SUPPORTED;
+import static javax.jcr.Repository.LEVEL_2_SUPPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_AUTOCREATED_DEFINITIONS_SUPPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_INHERITANCE;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_INHERITANCE_SINGLE;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_MULTIPLE_BINARY_PROPERTIES_SUPPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_MULTIVALUED_PROPERTIES_SUPPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_ORDERABLE_CHILD_NODES_SUPPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_OVERRIDES_SUPPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_PRIMARY_ITEM_NAME_SUPPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_PROPERTY_TYPES;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_RESIDUAL_DEFINITIONS_SUPPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_SAME_NAME_SIBLINGS_SUPPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_UPDATE_IN_USE_SUPORTED;
+import static javax.jcr.Repository.NODE_TYPE_MANAGEMENT_VALUE_CONSTRAINTS_SUPPORTED;
+import static javax.jcr.Repository.OPTION_ACCESS_CONTROL_SUPPORTED;
+import static javax.jcr.Repository.OPTION_ACTIVITIES_SUPPORTED;
+import static javax.jcr.Repository.OPTION_BASELINES_SUPPORTED;
+import static javax.jcr.Repository.OPTION_JOURNALED_OBSERVATION_SUPPORTED;
+import static javax.jcr.Repository.OPTION_LIFECYCLE_SUPPORTED;
+import static javax.jcr.Repository.OPTION_LOCKING_SUPPORTED;
+import static javax.jcr.Repository.OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED;
+import static javax.jcr.Repository.OPTION_NODE_TYPE_MANAGEMENT_SUPPORTED;
+import static javax.jcr.Repository.OPTION_OBSERVATION_SUPPORTED;
+import static javax.jcr.Repository.OPTION_QUERY_SQL_SUPPORTED;
+import static javax.jcr.Repository.OPTION_RETENTION_SUPPORTED;
+import static javax.jcr.Repository.OPTION_SHAREABLE_NODES_SUPPORTED;
+import static javax.jcr.Repository.OPTION_SIMPLE_VERSIONING_SUPPORTED;
+import static javax.jcr.Repository.OPTION_TRANSACTIONS_SUPPORTED;
+import static javax.jcr.Repository.OPTION_UNFILED_CONTENT_SUPPORTED;
+import static javax.jcr.Repository.OPTION_UPDATE_MIXIN_NODE_TYPES_SUPPORTED;
+import static javax.jcr.Repository.OPTION_UPDATE_PRIMARY_NODE_TYPE_SUPPORTED;
+import static javax.jcr.Repository.OPTION_VERSIONING_SUPPORTED;
+import static javax.jcr.Repository.OPTION_WORKSPACE_MANAGEMENT_SUPPORTED;
+import static javax.jcr.Repository.OPTION_XML_EXPORT_SUPPORTED;
+import static javax.jcr.Repository.OPTION_XML_IMPORT_SUPPORTED;
+import static javax.jcr.Repository.QUERY_FULL_TEXT_SEARCH_SUPPORTED;
+import static javax.jcr.Repository.QUERY_JOINS;
+import static javax.jcr.Repository.QUERY_JOINS_NONE;
+import static javax.jcr.Repository.QUERY_LANGUAGES;
+import static javax.jcr.Repository.QUERY_STORED_QUERIES_SUPPORTED;
+import static javax.jcr.Repository.QUERY_XPATH_DOC_ORDER;
+import static javax.jcr.Repository.QUERY_XPATH_POS_INDEX;
+import static javax.jcr.Repository.REP_NAME_DESC;
+import static javax.jcr.Repository.REP_VENDOR_DESC;
+import static javax.jcr.Repository.REP_VENDOR_URL_DESC;
+import static javax.jcr.Repository.REP_VERSION_DESC;
+import static javax.jcr.Repository.SPEC_NAME_DESC;
+import static javax.jcr.Repository.SPEC_VERSION_DESC;
+import static javax.jcr.Repository.WRITE_SUPPORTED;
+
/**
* {@code MicroKernel}-based implementation of
* the {@link ContentRepository} interface.
@@ -47,6 +109,8 @@ public class ContentRepositoryImpl imple
private final SecurityProvider securityProvider;
private final QueryIndexProvider indexProvider;
+ private DescriptorsImpl descriptors;
+
/**
* Creates an content repository instance based on the given, already
* initialized components.
@@ -94,4 +158,222 @@ public class ContentRepositoryImpl imple
return nodeStore;
}
+ @Nonnull
+ @Override
+ public Descriptors getDescriptors() {
+ if (descriptors == null) {
+ descriptors = createDescriptors();
+ }
+ return descriptors;
+ }
+
+ @SuppressWarnings("deprecation")
+ @Nonnull
+ protected DescriptorsImpl createDescriptors() {
+ final ValueFactory valueFactory = new SimpleValueFactory();
+ final Value trueValue = valueFactory.createValue(true);
+ final Value falseValue = valueFactory.createValue(false);
+ DescriptorsImpl d = new DescriptorsImpl();
+ d.put(new DescriptorsImpl.Descriptor(
+ IDENTIFIER_STABILITY,
+ valueFactory.createValue(Repository.IDENTIFIER_STABILITY_METHOD_DURATION), true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ LEVEL_1_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ LEVEL_2_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_NODE_TYPE_MANAGEMENT_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_AUTOCREATED_DEFINITIONS_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_INHERITANCE,
+ valueFactory.createValue(NODE_TYPE_MANAGEMENT_INHERITANCE_SINGLE), true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_MULTIPLE_BINARY_PROPERTIES_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_MULTIVALUED_PROPERTIES_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_ORDERABLE_CHILD_NODES_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_OVERRIDES_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_PRIMARY_ITEM_NAME_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_PROPERTY_TYPES,
+ new Value[] {
+ valueFactory.createValue(PropertyType.TYPENAME_STRING),
+ valueFactory.createValue(PropertyType.TYPENAME_BINARY),
+ valueFactory.createValue(PropertyType.TYPENAME_LONG),
+ valueFactory.createValue(PropertyType.TYPENAME_LONG),
+ valueFactory.createValue(PropertyType.TYPENAME_DOUBLE),
+ valueFactory.createValue(PropertyType.TYPENAME_DECIMAL),
+ valueFactory.createValue(PropertyType.TYPENAME_DATE),
+ valueFactory.createValue(PropertyType.TYPENAME_BOOLEAN),
+ valueFactory.createValue(PropertyType.TYPENAME_NAME),
+ valueFactory.createValue(PropertyType.TYPENAME_PATH),
+ valueFactory.createValue(PropertyType.TYPENAME_REFERENCE),
+ valueFactory.createValue(PropertyType.TYPENAME_WEAKREFERENCE),
+ valueFactory.createValue(PropertyType.TYPENAME_URI),
+ valueFactory.createValue(PropertyType.TYPENAME_UNDEFINED)
+ }, false, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_RESIDUAL_DEFINITIONS_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_SAME_NAME_SIBLINGS_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_VALUE_CONSTRAINTS_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ NODE_TYPE_MANAGEMENT_UPDATE_IN_USE_SUPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_ACCESS_CONTROL_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_JOURNALED_OBSERVATION_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_LIFECYCLE_SUPPORTED,
+ falseValue, true, true));
+ // locking support added via JCR layer
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_LOCKING_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_OBSERVATION_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED,
+ supportsSameNameNodeAndProperties() ? trueValue : falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_QUERY_SQL_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_RETENTION_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_SHAREABLE_NODES_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_SIMPLE_VERSIONING_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_TRANSACTIONS_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_UNFILED_CONTENT_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_UPDATE_MIXIN_NODE_TYPES_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_UPDATE_PRIMARY_NODE_TYPE_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_VERSIONING_SUPPORTED,
+ trueValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_WORKSPACE_MANAGEMENT_SUPPORTED,
+ trueValue, true, true));
+ // xml export support added via JCR layer
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_XML_EXPORT_SUPPORTED,
+ falseValue, true, true));
+ // xml import support added via JCR layer
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_XML_IMPORT_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_ACTIVITIES_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ OPTION_BASELINES_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ QUERY_FULL_TEXT_SEARCH_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ QUERY_JOINS,
+ valueFactory.createValue(QUERY_JOINS_NONE), true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ QUERY_LANGUAGES,
+ new Value[0], false, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ QUERY_STORED_QUERIES_SUPPORTED,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ QUERY_XPATH_DOC_ORDER,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ QUERY_XPATH_POS_INDEX,
+ falseValue, true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ REP_NAME_DESC,
+ valueFactory.createValue("Apache Jackrabbit Oak"), true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ REP_VERSION_DESC,
+ valueFactory.createValue(getVersion()), true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ REP_VENDOR_DESC,
+ valueFactory.createValue("The Apache Software Foundation"), true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ REP_VENDOR_URL_DESC,
+ valueFactory.createValue("http://www.apache.org/"), true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ SPEC_NAME_DESC,
+ valueFactory.createValue("Content Repository for Java Technology API"), true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ SPEC_VERSION_DESC,
+ valueFactory.createValue("2.0"), true, true));
+ d.put(new DescriptorsImpl.Descriptor(
+ WRITE_SUPPORTED,
+ trueValue, true, true));
+
+ return d;
+ }
+
+ /**
+ * Checks if this repository supports same name node and properties. currently this is tied to the underlying
+ * node store implementation class.
+ *
+ * @return {@code true} if this repository supports SNNP.
+ */
+ private boolean supportsSameNameNodeAndProperties() {
+ return !(nodeStore instanceof KernelNodeStore);
+ }
+
+ /**
+ * Returns the version of this repository implementation.
+ * @return the version
+ */
+ @Nonnull
+ private static String getVersion() {
+ InputStream stream = ContentRepositoryImpl.class.getResourceAsStream(
+ "/META-INF/maven/org.apache.jackrabbit/oak-core/pom.properties");
+ if (stream != null) {
+ try {
+ try {
+ Properties properties = new Properties();
+ properties.load(stream);
+ return properties.getProperty("version");
+ } finally {
+ stream.close();
+ }
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ return "SNAPSHOT";
+ }
}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DescriptorsImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DescriptorsImpl.java?rev=1541782&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DescriptorsImpl.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/DescriptorsImpl.java Thu Nov 14 01:56:41 2013
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.jackrabbit.oak.core;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.jcr.Value;
+
+import org.apache.jackrabbit.oak.api.Descriptors;
+
+/**
+ * Default implementation of the {@link Descriptors} interface. Supports overlying of given default descriptors.
+ */
+public class DescriptorsImpl implements org.apache.jackrabbit.oak.api.Descriptors {
+
+ private final Descriptors base;
+
+ private final Map<String, Descriptor> descriptors = new ConcurrentHashMap<String, Descriptor>();
+
+ /**
+ * Constructs an empty descriptors set.
+ */
+ public DescriptorsImpl() {
+ base = null;
+ }
+
+ /**
+ * Constructs a descriptors set that uses the given {@code base} descriptors as base.
+ * @param base the base descriptors or {@code null}
+ */
+ public DescriptorsImpl(@Nullable Descriptors base) {
+ this.base = base;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Note: If this descriptors are based on default descriptors, the returns string array is a merge of this and the
+ * base's keys.
+ */
+ @Nonnull
+ @Override
+ public String[] getKeys() {
+ Set<String> keys = new HashSet<String>(descriptors.keySet());
+ if (base != null) {
+ Collections.addAll(keys, base.getKeys());
+ }
+ return keys.toArray(new String[keys.size()]);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Note: If the descriptor with {@code key} does not exist in this set, the call is delegated to the base descriptors.
+ */
+ @Override
+ public boolean isStandardDescriptor(@Nonnull String key) {
+ return descriptors.containsKey(key) && descriptors.get(key).standard
+ || base != null && base.isStandardDescriptor(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Note: If the descriptor with {@code key} does not exist in this set, the call is delegated to the base descriptors.
+ */
+ @Override
+ public boolean isSingleValueDescriptor(@Nonnull String key) {
+ return descriptors.containsKey(key) && descriptors.get(key).singleValued
+ || base != null && base.isSingleValueDescriptor(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Note: If the descriptor with {@code key} does not exist in this set, the call is delegated to the base descriptors.
+ */
+ @CheckForNull
+ @Override
+ public Value getValue(@Nonnull String key) {
+ Descriptor d = descriptors.get(key);
+ if (d == null) {
+ return base == null ? null : base.getValue(key);
+ }
+ return !d.singleValued ? null : d.values[0];
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Note: If the descriptor with {@code key} does not exist in this set, the call is delegated to the base descriptors.
+ */
+ @CheckForNull
+ @Override
+ public Value[] getValues(@Nonnull String key) {
+ Descriptor d = descriptors.get(key);
+ if (d == null) {
+ return base == null ? null : base.getValues(key);
+ }
+ return d.values;
+ }
+
+ /**
+ * Adds a new descriptor to this set of descriptors which overlay the ones from the base set.
+ * @param descriptor the descriptor to add.
+ */
+ public void put(@Nonnull Descriptor descriptor) {
+ descriptors.put(descriptor.name, descriptor);
+ }
+
+ /**
+ * Internal Descriptor class
+ */
+ public static final class Descriptor {
+ final String name;
+ final Value[] values;
+ final boolean singleValued;
+ final boolean standard;
+
+ public Descriptor(String name, Value[] values, boolean singleValued, boolean standard) {
+ this.name = name;
+ this.values = values;
+ this.singleValued = singleValued;
+ this.standard = standard;
+ }
+
+ public Descriptor(String name, Value value, boolean singleValued, boolean standard) {
+ this(name, new Value[]{ value }, singleValued, standard);
+ }
+ }
+
+}
Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/JcrDescriptorsImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/JcrDescriptorsImpl.java?rev=1541782&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/JcrDescriptorsImpl.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/JcrDescriptorsImpl.java Thu Nov 14 01:56:41 2013
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.jackrabbit.oak.jcr.repository;
+
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+
+import org.apache.jackrabbit.oak.api.Descriptors;
+import org.apache.jackrabbit.oak.core.DescriptorsImpl;
+
+import static javax.jcr.Repository.OPTION_LOCKING_SUPPORTED;
+import static javax.jcr.Repository.OPTION_XML_EXPORT_SUPPORTED;
+import static javax.jcr.Repository.OPTION_XML_IMPORT_SUPPORTED;
+
+/**
+ * The {@code JcrDescriptorsImpl} extend the {@link DescriptorsImpl} by automatically marking some of the JCR
+ * features as supported.
+ */
+public class JcrDescriptorsImpl extends DescriptorsImpl {
+
+ public JcrDescriptorsImpl(Descriptors base, ValueFactory valueFactory) {
+ super(base);
+
+ // add the descriptors of the features that are provided by the JCR layer
+ final Value trueValue = valueFactory.createValue(true);
+ final Value falseValue = valueFactory.createValue(false);
+ put(new DescriptorsImpl.Descriptor(
+ OPTION_LOCKING_SUPPORTED,
+ trueValue, true, true));
+ put(new DescriptorsImpl.Descriptor(
+ OPTION_XML_EXPORT_SUPPORTED,
+ trueValue, true, true));
+ put(new DescriptorsImpl.Descriptor(
+ OPTION_XML_IMPORT_SUPPORTED,
+ trueValue, true, true));
+ }
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/RepositoryImpl.java?rev=1541782&r1=1541781&r2=1541782&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/RepositoryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/repository/RepositoryImpl.java Thu Nov 14 01:56:41 2013
@@ -37,6 +37,8 @@ import org.apache.jackrabbit.api.securit
import org.apache.jackrabbit.commons.SimpleValueFactory;
import org.apache.jackrabbit.oak.api.ContentRepository;
import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.Descriptors;
+import org.apache.jackrabbit.oak.core.DescriptorsImpl;
import org.apache.jackrabbit.oak.jcr.session.RefreshStrategy;
import org.apache.jackrabbit.oak.jcr.session.RefreshStrategy.LogOnce;
import org.apache.jackrabbit.oak.jcr.session.RefreshStrategy.Once;
@@ -67,7 +69,7 @@ public class RepositoryImpl implements J
*/
public static final String REFRESH_INTERVAL = "oak.refresh-interval";
- private final Descriptors descriptors;
+ private final DescriptorsImpl descriptors;
private final ContentRepository contentRepository;
protected final Whiteboard whiteboard;
private final SecurityProvider securityProvider;
@@ -239,8 +241,8 @@ public class RepositoryImpl implements J
* by the subclasses to add more values to the descriptor
* @return repository descriptor
*/
- protected Descriptors determineDescriptors() {
- return new Descriptors(new SimpleValueFactory());
+ protected DescriptorsImpl determineDescriptors() {
+ return new JcrDescriptorsImpl(contentRepository.getDescriptors(), new SimpleValueFactory());
}
/**
Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/SameNamePropertyNodeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/SameNamePropertyNodeTest.java?rev=1541782&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/SameNamePropertyNodeTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/SameNamePropertyNodeTest.java Thu Nov 14 01:56:41 2013
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.jackrabbit.oak.jcr;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.apache.jackrabbit.test.NotExecutableException;
+import org.junit.Test;
+
+public class SameNamePropertyNodeTest extends AbstractJCRTest {
+
+ private String sameName = "sameName";
+ private Node n;
+ private Property p;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ if (!getHelper().getRepository().getDescriptorValue(Repository.OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED).getBoolean()) {
+ throw new NotExecutableException("node and property with same name is not supported");
+ }
+
+ n = testRootNode.addNode(sameName);
+ p = testRootNode.setProperty(sameName, "value");
+ superuser.save();
+ }
+
+ @Test
+ public void testIsSame() throws Exception {
+ assertFalse(n.isSame(p));
+ assertFalse(p.isSame(n));
+ }
+
+ @Test
+ public void testNodeExists() throws Exception {
+ assertTrue(superuser.nodeExists(n.getPath()));
+ }
+
+ @Test
+ public void testSessionGetNode() throws Exception {
+ Node nn = superuser.getNode(n.getPath());
+ assertTrue(n.isSame(nn));
+ }
+
+ @Test
+ public void testHasNode() throws Exception {
+ assertTrue(testRootNode.hasNode(sameName));
+ }
+
+ @Test
+ public void testGetNode() throws Exception {
+ assertTrue(n.isSame(testRootNode.getNode(sameName)));
+ assertFalse(n.isSame(p));
+ }
+
+ @Test
+ public void testPropertyExists() throws Exception {
+ assertTrue(superuser.propertyExists(p.getPath()));
+ }
+
+ @Test
+ public void testSessionGetProperty() throws Exception {
+ Property pp = superuser.getProperty(p.getPath());
+ assertTrue(p.isSame(pp));
+ }
+
+ @Test
+ public void testHasProperty() throws Exception {
+ assertTrue(testRootNode.hasProperty(sameName));
+ }
+
+ @Test
+ public void testGetProperty() throws Exception {
+ assertTrue(p.isSame(testRootNode.getProperty(sameName)));
+ assertFalse(p.isSame(n));
+ }
+
+ @Test
+ public void testItemExists() throws Exception {
+ assertTrue(superuser.itemExists(n.getPath()));
+ }
+
+ @Test
+ public void testGetItem() throws Exception {
+ Item item = superuser.getItem(n.getPath());
+ if (item.isNode()) {
+ assertTrue(n.isSame(item));
+ } else {
+ assertTrue(p.isSame(item));
+ }
+ }
+
+ /**
+ * Tests if a microkernel fixture sets the SNNP repository descriptor to false.
+ */
+ @Test
+ public void testMicroKernelSupport() throws Exception {
+ NodeStore nodeStore = NodeStoreFixture.MK_IMPL.createNodeStore();
+ JackrabbitRepository repository = (JackrabbitRepository) new Jcr(nodeStore).createRepository();
+ try {
+ assertFalse(repository.getDescriptorValue(Repository.OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED).getBoolean());
+ } finally {
+ repository.shutdown();
+ }
+ }
+
+ /**
+ * Tests if a nodestore fixture sets the SNNP repository descriptor to true.
+ */
+ @Test
+ public void testNodeStoreSupport() throws Exception {
+ NodeStore nodeStore = NodeStoreFixture.SEGMENT_MK.createNodeStore();
+ JackrabbitRepository repository = (JackrabbitRepository) new Jcr(nodeStore).createRepository();
+ try {
+ assertTrue(repository.getDescriptorValue(Repository.OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED).getBoolean());
+ } finally {
+ repository.shutdown();
+ }
+
+ }
+}
\ No newline at end of file