Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java (revision 768998)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java (working copy)
@@ -20,6 +20,7 @@
import org.apache.jackrabbit.core.cluster.NamespaceEventListener;
import org.apache.jackrabbit.core.fs.FileSystem;
import org.apache.jackrabbit.core.fs.FileSystemResource;
+import org.apache.jackrabbit.core.util.DefaultNamespaceUtil;
import org.apache.jackrabbit.core.util.StringIndex;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.util.XMLChar;
@@ -56,7 +57,8 @@
static {
// reserved prefixes
reservedPrefixes.add(Name.NS_XML_PREFIX);
- reservedPrefixes.add(Name.NS_XMLNS_PREFIX);
+ reservedPrefixes.add(Name.NS_XMLNS_PREFIX);
+ reservedPrefixes.add(Name.NS_DEFAULT_CONV_VALUE);
// predefined (e.g. built-in) prefixes
reservedPrefixes.add(Name.NS_REP_PREFIX);
reservedPrefixes.add(Name.NS_JCR_PREFIX);
@@ -66,6 +68,7 @@
// reserved namespace URI's
reservedURIs.add(Name.NS_XML_URI);
reservedURIs.add(Name.NS_XMLNS_URI);
+ reservedURIs.add(Name.NS_DEFAULT_CONV_VALUE);
// predefined (e.g. built-in) namespace URI's
reservedURIs.add(Name.NS_REP_URI);
reservedURIs.add(Name.NS_JCR_URI);
@@ -128,7 +131,9 @@
* @param uri the namespace uri
* @param idx the index or null.
*/
- private void map(String prefix, String uri, Integer idx) {
+ private void map(String prefix, String uri, Integer idx) {
+ prefix = DefaultNamespaceUtil.convertToDefaultIfRequired(prefix);
+ uri = DefaultNamespaceUtil.convertToDefaultIfRequired(uri);
prefixToURI.put(prefix, uri);
uriToPrefix.put(uri, prefix);
if (!uriToIndex.containsKey(uri)) {
@@ -207,6 +212,9 @@
map(prefix, uri);
}
}
+
+ addDefaultNamespaceIfNotFound();
+
} finally {
in.close();
}
@@ -220,6 +228,18 @@
}
}
+ /**
+ * Verify that the default (empty) namespace exists. If it does
+ * not, add it. This can happen if the existing namespace
+ * property file has been created with the empty prefix and
+ * not the 'converted' value.
+ */
+ private void addDefaultNamespaceIfNotFound() {
+ if (!prefixToURI.containsKey(Name.NS_EMPTY_PREFIX)) {
+ map(Name.NS_EMPTY_PREFIX, Name.NS_DEFAULT_URI);
+ }
+ }
+
private void store() throws RepositoryException {
FileSystemResource propFile =
new FileSystemResource(nsRegStore, NS_REG_RESOURCE);
@@ -233,7 +253,7 @@
while (iter.hasNext()) {
String prefix = (String) iter.next();
String uri = (String) prefixToURI.get(prefix);
- props.setProperty(prefix, uri);
+ setProperty(props, prefix, uri);
}
try {
@@ -260,7 +280,7 @@
while (iter.hasNext()) {
String uri = (String) iter.next();
String index = uriToIndex.get(uri).toString();
- props.setProperty(uri, index);
+ setProperty(props, uri, index);
}
try {
@@ -277,6 +297,23 @@
}
/**
+ * Adds a specific key/value pair into the properties object. If the key/value
+ * pair represents the default namespace, the values will be converted into a
+ * different representation before storing in the properties. The method
+ * {@link DefaultNamespaceUtil#convertToDefaultIfRequired(String)} should be called when reading
+ * information from a property object to properly 'undo' this conversion.
+ *
+ * @param props Property object to store the key/value pair
+ * @param key Key that will be used when setting the property
+ * @param value Value of the property that is being set
+ */
+ private void setProperty(Properties props, String key, String value) {
+ key = DefaultNamespaceUtil.convertToValueIfDefault(key);
+ value = DefaultNamespaceUtil.convertToValueIfDefault(value);
+ props.setProperty(key, value);
+ }
+
+ /**
* Set an event channel to inform about changes.
*
* @param eventChannel event channel
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/DefaultNamespaceUtil.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/DefaultNamespaceUtil.java (revision 0)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/util/DefaultNamespaceUtil.java (revision 0)
@@ -0,0 +1,66 @@
+/*
+ * 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.core.util;
+
+
+import org.apache.jackrabbit.spi.Name;
+
+/**
+ * Simple utility class that converts the default namespace/uri into a value
+ * that can be used when storing information into property files. Added to
+ * resolve issues on IBM JDK 1.6 (see JIRA issue JCR-888).
+ */
+public class DefaultNamespaceUtil {
+
+ /**
+ * Converts the value into a non-empty string representation if the value
+ * provided is {@link Name#NS_DEFAULT_URI} or {@link Name#NS_EMPTY_PREFIX}.
+ *
+ * @param value URI or prefix to convert if default.
+ * @return If the value is default, a non-empty string representation that
+ * should be used when storing into property files. If not, the value
+ * will be returned.
+ */
+ public static String convertToValueIfDefault(String value) {
+ if (Name.NS_DEFAULT_URI.equals(value) ||
+ Name.NS_EMPTY_PREFIX.equals(value)) {
+ return Name.NS_DEFAULT_CONV_VALUE;
+ }
+
+ return value;
+ }
+
+ /**
+ * Converts the value back into the empty string representing
+ * {@link Name#NS_DEFAULT_URI} or {@link Name#NS_EMPTY_PREFIX} if the
+ * value is equal to the converted string returned from the
+ * {@link #convertToValueIfDefault(String)} method. If the value is not
+ * equal, it will be returned without modification.
+ *
+ * @param value Value to check if it is the converted default namespace
+ * value.
+ * @return The default uri/empty prefix if the value provided was converted
+ * by this class previously.
+ */
+ public static String convertToDefaultIfRequired(String value) {
+ if (Name.NS_DEFAULT_CONV_VALUE.equals(value)) {
+ return Name.NS_DEFAULT_URI;
+ }
+
+ return value;
+ }
+}
Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/DefaultNamespaceUtilTest.java
===================================================================
--- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/DefaultNamespaceUtilTest.java (revision 0)
+++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/DefaultNamespaceUtilTest.java (revision 0)
@@ -0,0 +1,105 @@
+/*
+ * 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.core.util;
+
+import org.apache.jackrabbit.spi.Name;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test class to verify that the DefaultNamespaceUtil class properly
+ * converts the default URI/Namespace value "" into a constant and vice-versa
+ */
+public class DefaultNamespaceUtilTest extends TestCase {
+
+ /**
+ * Test that a non-default value sent to the utility class will not be
+ * modified.
+ */
+ public void testResolveNonDefaultToValue() {
+ String value = "testValue";
+
+ String actualValue = DefaultNamespaceUtil.convertToValueIfDefault(value);
+
+ assertEquals("Value should not be changed if it is not the default" +
+ " URI/Namepace", value, actualValue);
+ }
+
+ /**
+ * Test that the default URI will be converted into a different
+ * value.
+ */
+ public void testResolveDefaultUriToValue() {
+ String value = Name.NS_DEFAULT_URI;
+ String actualValue = DefaultNamespaceUtil.convertToValueIfDefault(value);
+
+ assertEquals("Default URI should be changed",
+ Name.NS_DEFAULT_CONV_VALUE, actualValue);
+ }
+
+ /**
+ * Test that the default prefix will be converted into a different
+ * value.
+ */
+ public void testResolveDefaultPrefixToValue() {
+ String value = Name.NS_EMPTY_PREFIX;
+ String actualValue = DefaultNamespaceUtil.convertToValueIfDefault(value);
+
+ assertEquals("Default value should be changed",
+ Name.NS_DEFAULT_CONV_VALUE, actualValue);
+ }
+
+ /**
+ * Test that a value that wasn't converted from the default namespace/uri
+ * isn't changed when restoring from a property.
+ */
+ public void testResolveNonDefaultFromValue() {
+ String value = "testValue";
+
+ String actualValue = DefaultNamespaceUtil.convertToDefaultIfRequired(value);
+
+ assertEquals("A non-default value should not be modified", value, actualValue);
+ }
+
+ /**
+ * Test that the default URI value is provided when converting from the
+ * modified value.
+ */
+ public void testResolveDefaultUriFromValue() {
+ String value = Name.NS_DEFAULT_CONV_VALUE;
+ String expValue = Name.NS_DEFAULT_URI;
+
+ String actualValue = DefaultNamespaceUtil.convertToDefaultIfRequired(value);
+
+ assertEquals("The value should be converted back into the default URI",
+ expValue, actualValue);
+ }
+
+ /**
+ * Test that the empty prefix value is provided when converting from the
+ * modified value.
+ */
+ public void testResolveDefaultPrefixFromValue() {
+ String value = Name.NS_DEFAULT_CONV_VALUE;
+ String expValue = Name.NS_EMPTY_PREFIX;
+
+ String actualValue = DefaultNamespaceUtil.convertToDefaultIfRequired(value);
+
+ assertEquals("The value should be converted back into the default URI",
+ expValue, actualValue);
+ }
+}
Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/TestAll.java
===================================================================
--- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/TestAll.java (revision 768998)
+++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/util/TestAll.java (working copy)
@@ -33,6 +33,7 @@
public static Test suite() {
TestSuite suite = new TestSuite("Utility tests");
suite.addTestSuite(RepositoryLockTest.class);
+ suite.addTestSuite(DefaultNamespaceUtilTest.class);
return suite;
}
}
Index: jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/Name.java
===================================================================
--- jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/Name.java (revision 768998)
+++ jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/Name.java (working copy)
@@ -36,8 +36,10 @@
// default namespace (empty uri)
public static final String NS_EMPTY_PREFIX = "";
- public static final String NS_DEFAULT_URI = "";
-
+ public static final String NS_DEFAULT_URI = "";
+ // converted string denoting the default uri/prefix (JCR-888)
+ public static final String NS_DEFAULT_CONV_VALUE = "jcrDefaultNamespace";
+
// reserved namespace for repository internal node types
public static final String NS_REP_PREFIX = "rep";
public static final String NS_REP_URI = "internal";
@@ -68,6 +70,7 @@
* Empty array of Name
*/
public static final Name[] EMPTY_ARRAY = new Name[0];
+
/**
* Returns the local part of this Name object.