path.
* @throws RepositoryException if an error occurs
*/
+ @Deprecated
ItemId resolvePath(Path path) throws RepositoryException;
/**
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java
index dbd40a4c8c1..322e9d699c7 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemManager.java
@@ -467,6 +467,7 @@ private boolean canRead(ItemData parent, ItemId childId) throws RepositoryExcept
* @param path path to the item to be checked
* @return true if the specified item exists
*/
+ @Deprecated
public boolean itemExists(Path path) {
try {
sanityCheck();
@@ -544,6 +545,7 @@ NodeImpl getRootNode() throws RepositoryException {
* @throws AccessDeniedException
* @throws RepositoryException
*/
+ @Deprecated
public ItemImpl getItem(Path path) throws PathNotFoundException,
AccessDeniedException, RepositoryException {
ItemId id = hierMgr.resolvePath(path);
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
index 3519d9211d6..7f59ef4bb56 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
@@ -565,6 +565,7 @@ protected synchronized NodeImpl createChildNode(Name name,
* @throws RepositoryException
* @deprecated use #renameChildNode(NodeId, Name, boolean)
*/
+ @Deprecated
protected void renameChildNode(Name oldName, int index, NodeId id,
Name newName)
throws RepositoryException {
@@ -3072,6 +3073,7 @@ public boolean isLocked() throws RepositoryException {
* @throws RepositoryException if some other error occurs
* @deprecated
*/
+ @Deprecated
protected void checkLock() throws LockException, RepositoryException {
if (isNew()) {
// a new node needs no check
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
index ce105bb7656..95e94d8f7e4 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
@@ -22,8 +22,6 @@
import java.io.OutputStream;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
-import java.security.AccessControlContext;
-import java.security.AccessController;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -80,6 +78,7 @@
import org.apache.jackrabbit.core.gc.GarbageCollector;
import org.apache.jackrabbit.core.id.NodeId;
import org.apache.jackrabbit.core.id.NodeIdFactory;
+import org.apache.jackrabbit.core.jdkcompat.Java23Subject;
import org.apache.jackrabbit.core.lock.LockManager;
import org.apache.jackrabbit.core.lock.LockManagerImpl;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
@@ -1025,8 +1024,7 @@ private Session extendAuthentication(String workspaceName)
Subject subject = null;
try {
- AccessControlContext acc = AccessController.getContext();
- subject = Subject.getSubject(acc);
+ subject = Java23Subject.getSubject();
} catch (SecurityException e) {
log.warn("Can't check for preauthentication. Reason: {}", e.getMessage());
}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java
index 05cd8fc4099..f98a9e2092c 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SearchManager.java
@@ -431,7 +431,7 @@ public NodeState next() {
protected AbstractQueryImpl createQueryInstance() throws RepositoryException {
try {
String queryImplClassName = handler.getQueryClass();
- Object obj = Class.forName(queryImplClassName).newInstance();
+ Object obj = Class.forName(queryImplClassName).getDeclaredConstructor().newInstance();
if (obj instanceof AbstractQueryImpl) {
return (AbstractQueryImpl) obj;
} else {
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
index 7a6dfd59a74..d413a245c81 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
@@ -738,6 +738,43 @@ public Node getNodeOrNull(String absPath) throws RepositoryException {
}
}
+ private static boolean isValidNamespaceName(String namespace) {
+ // the empty namespace and "internal" are valid as well, otherwise it always contains a colon (as it is a URI)
+ // compare with RFC 3986, Section 3 (https://datatracker.ietf.org/doc/html/rfc3986#section-3)
+ return namespace.isEmpty() || namespace.equals(Name.NS_REP_URI) || namespace.contains(":");
+ }
+
+ @Override
+ public String getExpandedName(Item item) throws RepositoryException {
+ String name = item.getName();
+ int pos = name.indexOf(":");
+ if (pos > 0) {
+ String prefix = name.substring(0, pos);
+ String uri = getNamespaceURI(prefix);
+ if (!isValidNamespaceName(uri)) {
+ throw new NamespaceException("Cannot determine expanded name for '" + name +
+ "' as registered namespace name '" + uri + "' is invalid");
+ }
+ return "{" + uri + "}" + name.substring(pos + 1);
+ }
+ else {
+ return "{}" + name;
+ }
+ }
+
+ @Override
+ public String getExpandedPath(Item item) throws RepositoryException {
+ StringBuilder result = new StringBuilder();
+ String name;
+ do {
+ result.insert(0, "/" + getExpandedName(item));
+ item = item.getParent();
+ name = item.getName();
+ // walk up to the root
+ } while (!name.isEmpty());
+ return result.toString();
+ }
+
//--------------------------------------------------------------< Session >
/**
* {@inheritDoc}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java
index e29c3cf7f96..94dd49ca128 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java
@@ -166,6 +166,7 @@ public boolean isDeep() {
* @return user id
* @deprecated User {@link #getOwner()} instead.
*/
+ @Deprecated
public String getUserId() {
return lockOwner;
}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java
index 7801c01dacd..d0c78d61793 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java
@@ -933,6 +933,7 @@ public FileSystem getFileSystem() throws RepositoryException {
* @return repository name
* @deprecated Use {@link SecurityConfig#getAppName()} instead.
*/
+ @Deprecated
public String getAppName() {
return sec.getAppName();
}
@@ -943,6 +944,7 @@ public String getAppName() {
* @return access manager configuration
* @deprecated Use {@link SecurityConfig#getAccessManagerConfig()} instead.
*/
+ @Deprecated
public AccessManagerConfig getAccessManagerConfig() {
return sec.getAccessManagerConfig();
}
@@ -954,6 +956,7 @@ public AccessManagerConfig getAccessManagerConfig() {
* JAAS mechanism should be used.
* @deprecated Use {@link SecurityConfig#getLoginModuleConfig()} instead.
*/
+ @Deprecated
public LoginModuleConfig getLoginModuleConfig() {
return sec.getLoginModuleConfig();
}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/SimpleBeanFactory.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/SimpleBeanFactory.java
index d81230003f1..56dd2daa1bc 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/SimpleBeanFactory.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/config/SimpleBeanFactory.java
@@ -17,6 +17,8 @@
package org.apache.jackrabbit.core.config;
+import java.lang.reflect.InvocationTargetException;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,12 +41,12 @@ public Object newInstance(Class> klass, BeanConfig config) throws Configuratio
}
// Instantiate the object using the default constructor
- return objectClass.newInstance();
+ return objectClass.getDeclaredConstructor().newInstance();
} catch (ClassNotFoundException e) {
throw new ConfigurationException(
"Configured bean implementation class " + cname
+ " was not found.", e);
- } catch (InstantiationException e) {
+ } catch (InstantiationException|IllegalArgumentException|InvocationTargetException|NoSuchMethodException|SecurityException e) {
throw new ConfigurationException(
"Configured bean implementation class " + cname
+ " can not be instantiated.", e);
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/fs/db/JNDIDatabaseFileSystem.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/fs/db/JNDIDatabaseFileSystem.java
index 7d21a066fe5..93eb6698c0d 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/fs/db/JNDIDatabaseFileSystem.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/fs/db/JNDIDatabaseFileSystem.java
@@ -35,6 +35,7 @@
* for the entire lifetime of the file system instance. The configured data
* source should be prepared for this.
*/
+@Deprecated
public class JNDIDatabaseFileSystem extends DatabaseFileSystem {
/**
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jdkcompat/Java23Subject.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jdkcompat/Java23Subject.java
new file mode 100644
index 00000000000..95ea967ee8d
--- /dev/null
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jdkcompat/Java23Subject.java
@@ -0,0 +1,58 @@
+/*
+ * 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.jdkcompat;
+
+import javax.security.auth.Subject;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.concurrent.Callable;
+
+/**
+ * This class contains methods replacing the deprecated
+ * {@link Subject#getSubject(AccessControlContext)}
+ * and associated methods, which changed their behavior
+ * with Java 23 (@see https://inside.java/2024/07/08/quality-heads-up).
+ *
+ * Subset borrowed from org.apache.jackrabbit.oak.commons.jdkcompat
+ * (see JCR-5121 and OAK-11199).
+ */
+public class Java23Subject {
+
+ static Method current;
+
+ static {
+ try {
+ current = Subject.class.getMethod("current");
+ } catch (NoSuchMethodException ignored) {}
+ }
+
+ public static Subject getSubject() {
+ Subject result;
+ if (current != null) {
+ try {
+ result = (Subject) current.invoke(null);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ throw new SecurityException(e);
+ }
+ } else {
+ result = Subject.getSubject(AccessController.getContext());
+ }
+ return result;
+ }
+}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/RegistryHelper.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/RegistryHelper.java
index 5a8e406ce17..6784a70e2a1 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/RegistryHelper.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/RegistryHelper.java
@@ -25,6 +25,8 @@
import org.apache.jackrabbit.api.JackrabbitRepository;
+import static org.apache.jackrabbit.commons.JndiRepositoryFactory.JNDI_ENABLED;
+
/**
* JNDI helper functionality. This class contains static utility
* methods for binding and unbinding Jackrabbit repositories to and
@@ -59,24 +61,28 @@ public static void registerRepository(Context ctx, String name,
String repHomeDir,
boolean overwrite)
throws NamingException, RepositoryException {
- Reference reference = new Reference(
- Repository.class.getName(),
- BindableRepositoryFactory.class.getName(),
- null); // no classpath defined
- reference.add(new StringRefAddr(
- BindableRepository.CONFIGFILEPATH_ADDRTYPE, configFilePath));
- reference.add(new StringRefAddr(
- BindableRepository.REPHOMEDIR_ADDRTYPE, repHomeDir));
+ if (JNDI_ENABLED) {
+ Reference reference = new Reference(
+ Repository.class.getName(),
+ BindableRepositoryFactory.class.getName(),
+ null); // no classpath defined
+ reference.add(new StringRefAddr(
+ BindableRepository.CONFIGFILEPATH_ADDRTYPE, configFilePath));
+ reference.add(new StringRefAddr(
+ BindableRepository.REPHOMEDIR_ADDRTYPE, repHomeDir));
- // always create instance by using BindableRepositoryFactory
- // which maintains an instance cache;
- // see http://issues.apache.org/jira/browse/JCR-411 for details
- Object obj = new BindableRepositoryFactory().getObjectInstance(
- reference, null, null, null);
- if (overwrite) {
- ctx.rebind(name, obj);
+ // always create instance by using BindableRepositoryFactory
+ // which maintains an instance cache;
+ // see http://issues.apache.org/jira/browse/JCR-411 for details
+ Object obj = new BindableRepositoryFactory().getObjectInstance(
+ reference, null, null, null);
+ if (overwrite) {
+ ctx.rebind(name, obj);
+ } else {
+ ctx.bind(name, obj);
+ }
} else {
- ctx.bind(name, obj);
+ throw new RepositoryException("JNDI is not enabled");
}
}
@@ -91,8 +97,10 @@ public static void registerRepository(Context ctx, String name,
*/
public static void unregisterRepository(Context ctx, String name)
throws NamingException {
- ((JackrabbitRepository) ctx.lookup(name)).shutdown();
- ctx.unbind(name);
+ if (JNDI_ENABLED) {
+ ((JackrabbitRepository) ctx.lookup(name)).shutdown();
+ ctx.unbind(name);
+ }
}
}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseJournal.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseJournal.java
index 786c92c1e60..2a0b71d7496 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseJournal.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseJournal.java
@@ -651,6 +651,7 @@ public String getDatabaseType() {
*
* @return the database type
*/
+ @Deprecated
public String getSchema() {
return databaseType;
}
@@ -706,6 +707,7 @@ public void setDatabaseType(String databaseType) {
*
* @param databaseType the database type
*/
+ @Deprecated
public void setSchema(String databaseType) {
this.databaseType = databaseType;
}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/JNDIDatabaseJournal.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/JNDIDatabaseJournal.java
index fa4a0d24743..48b149fae60 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/JNDIDatabaseJournal.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/JNDIDatabaseJournal.java
@@ -38,6 +38,7 @@
* for the entire lifetime of the journal instance. The configured data
* source should be prepared for this.
*/
+@Deprecated
public class JNDIDatabaseJournal extends DatabaseJournal {
/**
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/BundleDbPersistenceManager.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/BundleDbPersistenceManager.java
index 8d5a6cd0de8..86fdc7304aa 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/BundleDbPersistenceManager.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/BundleDbPersistenceManager.java
@@ -296,6 +296,7 @@ public void setSchemaObjectPrefix(String schemaObjectPrefix) {
*
* @return the database type name.
*/
+ @Deprecated
public String getSchema() {
return databaseType;
}
@@ -317,6 +318,7 @@ public String getDatabaseType() {
*
* @param databaseType database type name
*/
+ @Deprecated
public void setSchema(String databaseType) {
this.databaseType = databaseType;
}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/AbstractQueryHandler.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/AbstractQueryHandler.java
index 40502b033e9..7fc6088e8b1 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/AbstractQueryHandler.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/AbstractQueryHandler.java
@@ -183,6 +183,7 @@ public String getQueryClass() {
*
* @param idleTime the query handler idle time.
*/
+ @Deprecated
public void setIdleTime(String idleTime) {
log.warn("Parameter 'idleTime' is not supported anymore. "
+ "Please use 'maxIdleTime' in the repository configuration.");
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java
index efc3c253abb..47d76cb40bf 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java
@@ -665,6 +665,7 @@ protected void addURIValue(Document doc, String fieldName, URI internalValue) {
* @deprecated Use {@link #addStringValue(Document, String, String, boolean)
* addStringValue(Document, String, Object, boolean)} instead.
*/
+ @Deprecated
protected void addStringValue(Document doc, String fieldName, String internalValue) {
addStringValue(doc, fieldName, internalValue, true, true, DEFAULT_BOOST, true);
}
@@ -702,6 +703,7 @@ protected void addStringValue(Document doc, String fieldName,
* @param boost the boost value for this string field.
* @deprecated use {@link #addStringValue(Document, String, String, boolean, boolean, float, boolean)} instead.
*/
+ @Deprecated
protected void addStringValue(Document doc, String fieldName,
String internalValue, boolean tokenized,
boolean includeInNodeIndex, float boost) {
@@ -791,6 +793,7 @@ protected void addNameValue(Document doc, String fieldName, Name internalValue)
* @return a lucene field.
* @deprecated use {@link #createFulltextField(String, boolean, boolean, boolean)} instead.
*/
+ @Deprecated
protected Field createFulltextField(String value) {
return createFulltextField(value, supportHighlighting, supportHighlighting);
}
@@ -804,6 +807,7 @@ protected Field createFulltextField(String value) {
* @return a lucene field.
* @deprecated use {@link #createFulltextField(String, boolean, boolean, boolean)} instead.
*/
+ @Deprecated
protected Field createFulltextField(String value,
boolean store,
boolean withOffsets) {
@@ -855,6 +859,7 @@ protected Field createFulltextField(String value,
* @return a lucene field.
* @deprecated use {@link #createFulltextField(InternalValue, Metadata, boolean)} instead.
*/
+ @Deprecated
protected Fieldable createFulltextField(
InternalValue value, Metadata metadata) {
return createFulltextField(value, metadata, true);
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
index 6baef1fdbe7..ecb2ec0ad0d 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
@@ -92,7 +92,6 @@
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
-import org.apache.lucene.index.Payload;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.search.IndexSearcher;
@@ -177,6 +176,7 @@ public class SearchIndex extends AbstractQueryHandler {
* @deprecated this value is not used anymore. Instead the default value
* is calculated as follows: 2 * Runtime.getRuntime().availableProcessors().
*/
+ @Deprecated
public static final int DEFAULT_EXTRACTOR_POOL_SIZE = 0;
/**
@@ -932,7 +932,7 @@ public ExcerptProvider createExcerptProvider(Query query)
throws IOException {
ExcerptProvider ep;
try {
- ep = (ExcerptProvider) excerptProviderClass.newInstance();
+ ep = (ExcerptProvider) excerptProviderClass.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw Util.createIOException(e);
}
@@ -1306,7 +1306,7 @@ protected SynonymProvider createSynonymProvider() {
SynonymProvider sp = null;
if (synonymProviderClass != null) {
try {
- sp = (SynonymProvider) synonymProviderClass.newInstance();
+ sp = (SynonymProvider) synonymProviderClass.getDeclaredConstructor().newInstance();
sp.initialize(createSynonymProviderConfigResource());
} catch (Exception e) {
log.warn("Exception initializing synonym provider: "
@@ -1330,7 +1330,7 @@ protected DirectoryManager createDirectoryManager()
throw new IOException(directoryManagerClass +
" is not a DirectoryManager implementation");
}
- DirectoryManager df = (DirectoryManager) clazz.newInstance();
+ DirectoryManager df = (DirectoryManager) clazz.getDeclaredConstructor().newInstance();
df.init(this);
return df;
} catch (IOException e) {
@@ -1355,7 +1355,7 @@ protected RedoLogFactory createRedoLogFactory() throws IOException {
throw new IOException(redoLogFactoryClass +
" is not a RedoLogFactory implementation");
}
- return (RedoLogFactory) clazz.newInstance();
+ return (RedoLogFactory) clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
IOException ex = new IOException();
ex.initCause(e);
@@ -1419,7 +1419,7 @@ protected SpellChecker createSpellChecker() {
SpellChecker spCheck = null;
if (spellCheckerClass != null) {
try {
- spCheck = (SpellChecker) spellCheckerClass.newInstance();
+ spCheck = (SpellChecker) spellCheckerClass.getDeclaredConstructor().newInstance();
spCheck.init(this);
} catch (Exception e) {
log.warn("Exception initializing spell checker: "
@@ -2101,6 +2101,7 @@ public int getMaxExtractLength() {
* @param filterClasses comma separated list of class names
* @deprecated
*/
+ @Deprecated
public void setTextFilterClasses(String filterClasses) {
log.warn("The textFilterClasses configuration parameter has"
+ " been deprecated, and the configured value will"
@@ -2114,6 +2115,7 @@ public void setTextFilterClasses(String filterClasses) {
* @return class names of the text filters in use.
* @deprecated
*/
+ @Deprecated
public String getTextFilterClasses() {
return "deprectated";
}
@@ -2419,7 +2421,7 @@ public String getSynonymProviderConfigPath() {
public void setSimilarityClass(String className) {
try {
Class> similarityClass = Class.forName(className);
- similarity = (Similarity) similarityClass.newInstance();
+ similarity = (Similarity) similarityClass.getDeclaredConstructor().newInstance();
} catch (Exception e) {
log.warn("Invalid Similarity class: " + className, e);
}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java
index 3343bafe4d0..cc3f5cb6c1a 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java
@@ -36,18 +36,21 @@ public interface AccessManager {
* READ permission constant
* @deprecated
*/
+ @Deprecated
int READ = 1;
/**
* WRITE permission constant
* @deprecated
*/
+ @Deprecated
int WRITE = 2;
/**
* REMOVE permission constant
* @deprecated
*/
+ @Deprecated
int REMOVE = 4;
/**
@@ -102,6 +105,7 @@ void init(AMContext context, AccessControlProvider acProvider,
* @throws RepositoryException it an error occurs
* @deprecated
*/
+ @Deprecated
void checkPermission(ItemId id, int permissions)
throws AccessDeniedException, ItemNotFoundException, RepositoryException;
@@ -145,6 +149,7 @@ void checkPermission(ItemId id, int permissions)
* @throws RepositoryException if another error occurs
* @deprecated
*/
+ @Deprecated
boolean isGranted(ItemId id, int permissions)
throws ItemNotFoundException, RepositoryException;
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java
index d2b5237d491..767c3da6b20 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java
@@ -77,6 +77,7 @@ public abstract class AbstractLoginModule implements LoginModule {
* deprecated and will no longer be supported in a subsequent release.
* See also JCR-3293
*/
+ @Deprecated
private static final String PRE_AUTHENTICATED_ATTRIBUTE_OPTION = "trust_credentials_attribute";
private String principalProviderClassName;
@@ -95,6 +96,7 @@ public abstract class AbstractLoginModule implements LoginModule {
* has been deprecated and will no longer be available in a subsequent release.
* See also JCR-3293
*/
+ @Deprecated
private String preAuthAttributeName;
@@ -759,6 +761,7 @@ public void setPrincipalProvider(String principalProvider) {
* has been deprecated and will no longer be available in a subsequent release.
* See also JCR-3293
*/
+ @Deprecated
protected final String getPreAuthAttributeName() {
return preAuthAttributeName;
}
@@ -783,6 +786,7 @@ protected final String getPreAuthAttributeName() {
* has been deprecated and will no longer be available in a subsequent release.
* See also JCR-3293
*/
+ @Deprecated
protected boolean isPreAuthenticated(final Credentials creds) {
final String preAuthAttrName = getPreAuthAttributeName();
boolean isPreAuth = preAuthAttrName != null
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java
index c4370edb0db..8d5bd048361 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java
@@ -51,6 +51,7 @@ public class CryptedSimpleCredentials implements Credentials {
* @throws UnsupportedEncodingException
* @deprecated
*/
+ @Deprecated
public CryptedSimpleCredentials(SimpleCredentials credentials)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
userId = credentials.getUserID();
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/token/TokenBasedAuthentication.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/token/TokenBasedAuthentication.java
index d578d217727..60409e1d928 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/token/TokenBasedAuthentication.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/token/TokenBasedAuthentication.java
@@ -58,6 +58,7 @@ public class TokenBasedAuthentication implements Authentication {
* behavior of the {@code TokenBasedAuthentication}. Note that as of OAK 1.0
* this flag will no be supported.
*/
+ @Deprecated
public static final String PARAM_COMPAT = "TokenCompatMode";
private final TokenInfo tokenInfo;
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java
index fcb6d3d5ce0..939c5bed560 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractCompiledPermissions.java
@@ -159,6 +159,7 @@ public static class Result {
/**
* @deprecated
*/
+ @Deprecated
public Result(int allows, int denies, int allowPrivileges, int denyPrivileges) {
this(allows, denies, PrivilegeBits.getInstance(allowPrivileges), PrivilegeBits.getInstance(denyPrivileges));
}
@@ -178,6 +179,7 @@ public boolean grants(int permissions) {
/**
* @deprecated jackrabbit 2.3 (throws UnsupportedOperationException, use getPrivilegeBits instead)
*/
+ @Deprecated
public int getPrivileges() {
throw new UnsupportedOperationException("use #getPrivilegeBits instead.");
}
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java
index 57b9e92dd2d..cad868392bb 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java
@@ -62,6 +62,7 @@ public interface CompiledPermissions {
* @throws RepositoryException if an error occurs
* @deprecated Use {@link #getPrivilegeSet(Path)} instead.
*/
+ @Deprecated
int getPrivileges(Path absPath) throws RepositoryException;
/**
diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
index 0114df4fe5c..8aa0d71273d 100644
--- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
+++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
@@ -183,6 +183,7 @@ public PrivilegeRegistry(NamespaceRegistry namespaceRegistry, FileSystem fs)
* @deprecated Use {@link org.apache.jackrabbit.api.security.authorization.PrivilegeManager} instead.
* @see org.apache.jackrabbit.api.JackrabbitWorkspace#getPrivilegeManager()
*/
+ @Deprecated
public PrivilegeRegistry(NameResolver resolver) {
cacheDefinitions(createBuiltInPrivilegeDefinitions());
@@ -225,6 +226,7 @@ public void setEventChannel(PrivilegeEventChannel eventChannel) {
* @return all registered privileges.
* @deprecated Use {@link org.apache.jackrabbit.api.security.authorization.PrivilegeManager#getRegisteredPrivileges()} instead.
*/
+ @Deprecated
public Privilege[] getRegisteredPrivileges() {
try {
return new PrivilegeManagerImpl(this, resolver).getRegisteredPrivileges();
@@ -243,6 +245,7 @@ public Privilege[] getRegisteredPrivileges() {
* @throws RepositoryException If another error occurs.
* @deprecated Use {@link org.apache.jackrabbit.api.security.authorization.PrivilegeManager#getPrivilege(String)} instead.
*/
+ @Deprecated
public Privilege getPrivilege(String privilegeName) throws AccessControlException, RepositoryException {
return new PrivilegeManagerImpl(this, resolver).getPrivilege(privilegeName);
}
@@ -258,6 +261,7 @@ public Privilege getPrivilege(String privilegeName) throws AccessControlExceptio
* @see #getBits(Privilege[])
* @deprecated Use {@link PrivilegeManagerImpl#getPrivileges(PrivilegeBits)} instead.
*/
+ @Deprecated
public Privilege[] getPrivileges(int bits) {
SetTokenBasedLoginTest...
*/
@@ -230,120 +235,69 @@ public void testLogin() throws RepositoryException {
* Tests concurrent login on the Repository including token creation.
* Test copied and slightly adjusted from org.apache.jackrabbit.core.ConcurrentLoginTest
*/
- public void testConcurrentLogin() throws RepositoryException, NotExecutableException {
- final Exception[] exception = new Exception[1];
- List
+ * Please note that those prefixes can by redefined by an application using the * {@link Session#setNamespacePrefix(String, String)} method. As a result, the * constants may not refer to the respective items. + *
+ * On the other hand, the constants in {@link javax.jcr.nodetype.NodeType},
+ * {@link javax.jcr.Node}, {@link javax.jcr.Property} and {@link javax.jcr.Workspace}
+ * are more complete (covering JCR 2.0
+ * as well) and also define names using expanded form, which is immune to session local
+ * remappings, so it is recommended to use those constants instead whenever possible.
*/
public interface JcrConstants {
/**
- * jcr:autoCreated
+ * Use {@link javax.jcr.Property#JCR_AUTOCREATED} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_AUTOCREATED = "jcr:autoCreated";
/**
- * jcr:baseVersion
+ * Use {@link javax.jcr.Property#JCR_BASE_VERSION} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_BASEVERSION = "jcr:baseVersion";
- /**
- * jcr:child
- */
+
public static final String JCR_CHILD = "jcr:child";
/**
- * jcr:childNodeDefinition
+ * Use {@link javax.jcr.Node#JCR_CHILD_NODE_DEFINITION} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_CHILDNODEDEFINITION = "jcr:childNodeDefinition";
/**
- * jcr:content
+ * Use {@link javax.jcr.Node#JCR_CONTENT} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_CONTENT = "jcr:content";
/**
- * jcr:created
+ * Use {@link javax.jcr.Property#JCR_CREATED} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_CREATED = "jcr:created";
/**
- * jcr:data
+ * Use {@link javax.jcr.Property#JCR_DATA} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_DATA = "jcr:data";
/**
- * jcr:defaultPrimaryType
+ * Use {@link javax.jcr.Property#JCR_DEFAULT_PRIMARY_TYPE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_DEFAULTPRIMARYTYPE = "jcr:defaultPrimaryType";
/**
- * jcr:defaultValues
+ * Use {@link javax.jcr.Property#JCR_DEFAULT_VALUES} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_DEFAULTVALUES = "jcr:defaultValues";
/**
- * jcr:encoding
+ * Use {@link javax.jcr.Property#JCR_ENCODING} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_ENCODING = "jcr:encoding";
/**
- * jcr:frozenMixinTypes
+ * Use {@link javax.jcr.Property#JCR_FROZEN_MIXIN_TYPES} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_FROZENMIXINTYPES = "jcr:frozenMixinTypes";
/**
- * jcr:frozenNode
+ * Use {@link javax.jcr.Node#JCR_FROZEN_NODE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_FROZENNODE = "jcr:frozenNode";
/**
- * jcr:frozenPrimaryType
+ * Use {@link javax.jcr.Property#JCR_FROZEN_PRIMARY_TYPE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_FROZENPRIMARYTYPE = "jcr:frozenPrimaryType";
/**
- * jcr:frozenUuid
+ * Use {@link javax.jcr.Property#JCR_FROZEN_UUID} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_FROZENUUID = "jcr:frozenUuid";
/**
- * jcr:hasOrderableChildNodes
+ * Use {@link javax.jcr.Property#JCR_HAS_ORDERABLE_CHILD_NODES} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_HASORDERABLECHILDNODES = "jcr:hasOrderableChildNodes";
/**
- * jcr:isCheckedOut
+ * Use {@link javax.jcr.Property#JCR_IS_CHECKED_OUT} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_ISCHECKEDOUT = "jcr:isCheckedOut";
/**
- * jcr:isMixin
+ * Use {@link javax.jcr.Property#JCR_IS_MIXIN} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_ISMIXIN = "jcr:isMixin";
/**
- * jcr:language
+ * Use {@link javax.jcr.Property#JCR_LANGUAGE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_LANGUAGE = "jcr:language";
/**
- * jcr:lastModified
+ * Use {@link javax.jcr.Property#JCR_LAST_MODIFIED} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_LASTMODIFIED = "jcr:lastModified";
/**
- * jcr:lockIsDeep
+ * Use {@link javax.jcr.Property#JCR_LOCK_IS_DEEP} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_LOCKISDEEP = "jcr:lockIsDeep";
/**
- * jcr:lockOwner
+ * Use {@link javax.jcr.Property#JCR_LOCK_OWNER} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_LOCKOWNER = "jcr:lockOwner";
/**
- * jcr:mandatory
+ * Use {@link javax.jcr.Property#JCR_MANDATORY} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_MANDATORY = "jcr:mandatory";
/**
- * jcr:mergeFailed
+ * Use {@link javax.jcr.Property#JCR_MERGE_FAILED} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_MERGEFAILED = "jcr:mergeFailed";
/**
- * jcr:mimeType
+ * Use {@link javax.jcr.Property#JCR_MIMETYPE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_MIMETYPE = "jcr:mimeType";
/**
- * jcr:mixinTypes
+ * Use {@link javax.jcr.Property#JCR_MIXIN_TYPES} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_MIXINTYPES = "jcr:mixinTypes";
/**
- * jcr:multiple
+ * Use {@link javax.jcr.Property#JCR_MULTIPLE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_MULTIPLE = "jcr:multiple";
/**
- * jcr:name
+ * Use {@link javax.jcr.Property#JCR_NAME} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_NAME = "jcr:name";
/**
- * jcr:nodeTypeName
+ * Use {@link javax.jcr.Property#JCR_NODE_TYPE_NAME} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_NODETYPENAME = "jcr:nodeTypeName";
/**
- * jcr:onParentVersion
+ * Use {@link javax.jcr.Property#JCR_ON_PARENT_VERSION} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_ONPARENTVERSION = "jcr:onParentVersion";
/**
- * jcr:predecessors
+ * Use {@link javax.jcr.Property#JCR_PREDECESSORS} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_PREDECESSORS = "jcr:predecessors";
/**
- * jcr:primaryItemName
+ * Use {@link javax.jcr.Property#JCR_PRIMARY_ITEM_NAME} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_PRIMARYITEMNAME = "jcr:primaryItemName";
/**
- * jcr:primaryType
+ * Use {@link javax.jcr.Property#JCR_PRIMARY_TYPE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_PRIMARYTYPE = "jcr:primaryType";
/**
- * jcr:propertyDefinition
+ * Use {@link javax.jcr.Node#JCR_PROPERTY_DEFINITION} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_PROPERTYDEFINITION = "jcr:propertyDefinition";
/**
- * jcr:protected
+ * Use {@link javax.jcr.Property#JCR_PROTECTED} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_PROTECTED = "jcr:protected";
/**
- * jcr:requiredPrimaryTypes
+ * Use {@link javax.jcr.Property#JCR_REQUIRED_PRIMARY_TYPES} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_REQUIREDPRIMARYTYPES = "jcr:requiredPrimaryTypes";
/**
- * jcr:requiredType
+ * Use {@link javax.jcr.Property#JCR_REQUIRED_TYPE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_REQUIREDTYPE = "jcr:requiredType";
/**
- * jcr:rootVersion
+ * Use {@link javax.jcr.Node#JCR_ROOT_VERSION} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_ROOTVERSION = "jcr:rootVersion";
/**
* jcr:sameNameSiblings
+ * Use {@link javax.jcr.Property#JCR_SAME_NAME_SIBLINGS} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_SAMENAMESIBLINGS = "jcr:sameNameSiblings";
/**
- * jcr:statement
+ * Use {@link javax.jcr.Property#JCR_STATEMENT} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_STATEMENT = "jcr:statement";
/**
- * jcr:successors
+ * Use {@link javax.jcr.Property#JCR_SUCCESSORS} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_SUCCESSORS = "jcr:successors";
/**
- * jcr:supertypes
+ * Use {@link javax.jcr.Property#JCR_SUPERTYPES} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_SUPERTYPES = "jcr:supertypes";
/**
- * jcr:system
+ * Use {@link javax.jcr.Workspace#NAME_SYSTEM_NODE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_SYSTEM = "jcr:system";
/**
- * jcr:uuid
+ * Use {@link javax.jcr.Property#JCR_TITLE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
+ */
+ public static final String JCR_TITLE = "jcr:title";
+ /**
+ * Use {@link javax.jcr.Property#JCR_UUID} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_UUID = "jcr:uuid";
/**
- * jcr:valueConstraints
+ * Use {@link javax.jcr.Property#JCR_VALUE_CONSTRAINTS} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_VALUECONSTRAINTS = "jcr:valueConstraints";
/**
- * jcr:versionHistory
+ * Use {@link javax.jcr.Property#JCR_VERSION_HISTORY} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_VERSIONHISTORY = "jcr:versionHistory";
/**
- * jcr:versionLabels
+ * Use {@link javax.jcr.Node#JCR_VERSION_LABELS} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_VERSIONLABELS = "jcr:versionLabels";
/**
- * jcr:versionStorage
+ * Use {@link javax.jcr.Workspace#NAME_VERSION_STORAGE_NODE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_VERSIONSTORAGE = "jcr:versionStorage";
/**
- * jcr:versionableUuid
+ * Use {@link javax.jcr.Property#JCR_VERSIONABLE_UUID} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String JCR_VERSIONABLEUUID = "jcr:versionableUuid";
@@ -229,75 +240,103 @@ public interface JcrConstants {
public static final String JCR_SCORE = "jcr:score";
/**
- * mix:lockable
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_CREATED} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
+ */
+ public static final String MIX_CREATED = "mix:created";
+ /**
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_LANGUAGE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
+ */
+ public static final String MIX_LANGUAGE = "mix:language";
+ /**
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_LAST_MODIFIED} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
+ */
+ public static final String MIX_LAST_MODIFIED = "mix:lastModified";
+ /**
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_LIFECYCLE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
+ */
+ public static final String MIX_LIFECYCLE = "mix:lifecycle";
+ /**
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_LOCKABLE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String MIX_LOCKABLE = "mix:lockable";
/**
- * mix:referenceable
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_MIMETYPE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
+ */
+ public static final String MIX_MIMETYPE = "mix:mimetype";
+ /**
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_REFERENCEABLE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String MIX_REFERENCEABLE = "mix:referenceable";
/**
- * mix:versionable
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_SIMPLE_VERSIONABLE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
+ */
+ public static final String MIX_SIMPLE_VERSIONABLE = "mix:simpleVersionable";
+ /**
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_VERSIONABLE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String MIX_VERSIONABLE = "mix:versionable";
/**
- * mix:shareable
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_SHAREABLE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String MIX_SHAREABLE = "mix:shareable";
/**
- * nt:base
+ * Use {@link javax.jcr.nodetype.NodeType#MIX_TITLE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
+ */
+ public static final String MIX_TITLE = "mix:title";
+ /**
+ * Use {@link javax.jcr.nodetype.NodeType#NT_BASE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_BASE = "nt:base";
/**
- * nt:childNodeDefinition
+ * Use {@link javax.jcr.nodetype.NodeType#NT_CHILD_NODE_DEFINITION} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_CHILDNODEDEFINITION = "nt:childNodeDefinition";
/**
- * nt:file
+ * Use {@link javax.jcr.nodetype.NodeType#NT_FILE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_FILE = "nt:file";
/**
- * nt:folder
+ * Use {@link javax.jcr.nodetype.NodeType#NT_FOLDER} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_FOLDER = "nt:folder";
/**
- * nt:frozenNode
+ * Use {@link javax.jcr.nodetype.NodeType#NT_FROZEN_NODE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_FROZENNODE = "nt:frozenNode";
/**
- * nt:hierarchyNode
+ * Use {@link javax.jcr.nodetype.NodeType#NT_HIERARCHY_NODE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_HIERARCHYNODE = "nt:hierarchyNode";
/**
- * nt:linkedFile
+ * Use {@link javax.jcr.nodetype.NodeType#NT_LINKED_FILE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_LINKEDFILE = "nt:linkedFile";
/**
- * nt:nodeType
+ * Use {@link javax.jcr.nodetype.NodeType#NT_NODE_TYPE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_NODETYPE = "nt:nodeType";
/**
- * nt:propertyDefinition
+ * Use {@link javax.jcr.nodetype.NodeType#NT_PROPERTY_DEFINITION} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_PROPERTYDEFINITION = "nt:propertyDefinition";
/**
- * nt:query
+ * Use {@link javax.jcr.nodetype.NodeType#NT_QUERY} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_QUERY = "nt:query";
/**
- * nt:resource
+ * Use {@link javax.jcr.nodetype.NodeType#NT_RESOURCE} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_RESOURCE = "nt:resource";
/**
- * nt:unstructured
+ * Use {@link javax.jcr.nodetype.NodeType#NT_UNSTRUCTURED} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_UNSTRUCTURED = "nt:unstructured";
/**
- * nt:version
+ * Use {@link javax.jcr.nodetype.NodeType#NT_VERSION} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_VERSION = "nt:version";
/**
- * nt:versionHistory
+ * Use {@link javax.jcr.nodetype.NodeType#NT_VERSION_HISTORY} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_VERSIONHISTORY = "nt:versionHistory";
/**
@@ -305,7 +344,7 @@ public interface JcrConstants {
*/
public static final String NT_VERSIONLABELS = "nt:versionLabels";
/**
- * nt:versionedChild
+ * Use {@link javax.jcr.nodetype.NodeType#NT_VERSIONED_CHILD} whenever expanded JCR names are supported (e.g. in JCR API method parameters).
*/
public static final String NT_VERSIONEDCHILD = "nt:versionedChild";
}
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JndiRepositoryFactory.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JndiRepositoryFactory.java
index 92274df6f3f..83eca3032f7 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JndiRepositoryFactory.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JndiRepositoryFactory.java
@@ -56,6 +56,11 @@
@SuppressWarnings({ "rawtypes", "unchecked" })
public class JndiRepositoryFactory implements RepositoryFactory {
+ /**
+ * Disabled by default, see JCR-5135
+ */
+ public static final boolean JNDI_ENABLED = Boolean.getBoolean("jackrabbit.jndi.enabled");
+
/**
* The JNDI name parameter name.
*/
@@ -64,29 +69,32 @@ public class JndiRepositoryFactory implements RepositoryFactory {
public Repository getRepository(Map parameters)
throws RepositoryException {
- if (parameters == null) {
- return null; // no default JNDI repository
- } else {
- Hashtable environment = new Hashtable(parameters);
- if (environment.containsKey(JNDI_NAME)) {
- String name = environment.remove(JNDI_NAME).toString();
- return getRepository(name, environment);
- } else if (environment.containsKey(JcrUtils.REPOSITORY_URI)) {
- Object parameter = environment.remove(JcrUtils.REPOSITORY_URI);
- try {
- URI uri = new URI(parameter.toString().trim());
- if ("jndi".equalsIgnoreCase(uri.getScheme())) {
- return getRepository(uri, environment);
- } else {
- return null; // not a jndi: URI
+ if (JNDI_ENABLED) {
+ if (parameters == null) {
+ return null; // no default JNDI repository
+ } else {
+ Hashtable environment = new Hashtable(parameters);
+ if (environment.containsKey(JNDI_NAME)) {
+ String name = environment.remove(JNDI_NAME).toString();
+ return getRepository(name, environment);
+ } else if (environment.containsKey(JcrUtils.REPOSITORY_URI)) {
+ Object parameter = environment.remove(JcrUtils.REPOSITORY_URI);
+ try {
+ URI uri = new URI(parameter.toString().trim());
+ if ("jndi".equalsIgnoreCase(uri.getScheme())) {
+ return getRepository(uri, environment);
+ } else {
+ return null; // not a jndi: URI
+ }
+ } catch (URISyntaxException e) {
+ return null; // not a valid URI
}
- } catch (URISyntaxException e) {
- return null; // not a valid URI
+ } else {
+ return null; // unknown parameters
}
- } else {
- return null; // unknown parameters
}
}
+ return null;
}
private Repository getRepository(URI uri, Hashtable environment)
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java
index a5581185c5c..457463d9012 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java
@@ -16,8 +16,15 @@
*/
package org.apache.jackrabbit.commons;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
+import java.util.UUID;
+import java.util.function.UnaryOperator;
import javax.jcr.NamespaceException;
import javax.jcr.NamespaceRegistry;
@@ -53,6 +60,11 @@ public class NamespaceHelper {
*/
private final Session session;
+ /**
+ * Current namespace registry.
+ */
+ private NamespaceRegistry namespaceRegistry;
+
/**
* Creates a namespace helper for the given session.
*
@@ -60,6 +72,19 @@ public class NamespaceHelper {
*/
public NamespaceHelper(Session session) {
this.session = session;
+ // will be set on lazily
+ this.namespaceRegistry = null;
+ }
+
+ /**
+ Get the namespace registry; needs to be done on-demand because the constructor
+ does not allow RepositoryException
+ */
+ private NamespaceRegistry getNamespaceRegistry() throws RepositoryException {
+ if (namespaceRegistry == null) {
+ namespaceRegistry = session.getWorkspace().getNamespaceRegistry();
+ }
+ return namespaceRegistry;
}
/**
@@ -72,22 +97,22 @@ public NamespaceHelper(Session session) {
* @throws RepositoryException if the namespaces could not be retrieved
*/
public Map
+ * This class is deprecated and will be removed in future releases.
*
* @since 1.4
+ * @deprecated use {@link ProxyRepository} instead
*/
+@Deprecated(forRemoval = true)
public class JNDIRepository extends ProxyRepository {
/**
@@ -38,5 +42,4 @@ public class JNDIRepository extends ProxyRepository {
public JNDIRepository(Context context, String name) {
super(new JNDIRepositoryFactory(context, name));
}
-
}
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/repository/JNDIRepositoryFactory.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/repository/JNDIRepositoryFactory.java
index 15646532644..c211c44444f 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/repository/JNDIRepositoryFactory.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/repository/JNDIRepositoryFactory.java
@@ -21,11 +21,17 @@
import javax.naming.Context;
import javax.naming.NamingException;
+import static org.apache.jackrabbit.commons.JndiRepositoryFactory.JNDI_ENABLED;
+
/**
* Factory that looks up a repository from JNDI.
+ *
+ * This class is deprecated and will be removed in future releases.
*
* @since 1.4
+ * @deprecated use {@link org.apache.jackrabbit.commons.JndiRepositoryFactory} instead
*/
+@Deprecated(forRemoval = true)
public class JNDIRepositoryFactory implements RepositoryFactory {
/**
@@ -56,25 +62,28 @@ public JNDIRepositoryFactory(Context context, String name) {
* @throws RepositoryException if the repository can not be found
*/
public Repository getRepository() throws RepositoryException {
- try {
- Object repository = context.lookup(name);
- if (repository instanceof Repository) {
- return (Repository) repository;
- } else if (repository == null) {
- throw new RepositoryException(
- "Repository not found: The JNDI entry "
- + name + " is null");
- } else {
+ if (JNDI_ENABLED) {
+ try {
+ Object repository = context.lookup(name);
+ if (repository instanceof Repository) {
+ return (Repository) repository;
+ } else if (repository == null) {
+ throw new RepositoryException(
+ "Repository not found: The JNDI entry "
+ + name + " is null");
+ } else {
+ throw new RepositoryException(
+ "Invalid repository: The JNDI entry "
+ + name + " is an instance of "
+ + repository.getClass().getName());
+ }
+ } catch (NamingException e) {
throw new RepositoryException(
- "Invalid repository: The JNDI entry "
- + name + " is an instance of "
- + repository.getClass().getName());
+ "Repository not found: The JNDI entry " + name
+ + " could not be looked up", e);
}
- } catch (NamingException e) {
- throw new RepositoryException(
- "Repository not found: The JNDI entry " + name
- + " could not be looked up", e);
}
+ return null;
}
}
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/XMLFactories.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/XMLFactories.java
new file mode 100755
index 00000000000..925e379562f
--- /dev/null
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/XMLFactories.java
@@ -0,0 +1,77 @@
+/*
+ * 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.commons.xml;
+
+import org.xml.sax.EntityResolver;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.IOException;
+
+/**
+ * Factory for "safe" instances of XML parsers (wrt XXE etc.).
+ */
+public class XMLFactories {
+
+ private XMLFactories() {
+ }
+
+ /**
+ * @return a "safe" {@link DocumentBuilderFactory}
+ */
+ public static DocumentBuilderFactory safeDocumentBuilderFactory() {
+ // see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
+
+ javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
+
+ factory.setIgnoringComments(false);
+ factory.setIgnoringElementContentWhitespace(true);
+ factory.setXIncludeAware(false);
+
+ // Prevent XXE attacks by disabling external entity processing
+ factory.setExpandEntityReferences(false);
+
+ String feature = null;
+
+ try {
+ feature = XMLConstants.FEATURE_SECURE_PROCESSING;
+ factory.setFeature(feature, true);
+ feature = "http://apache.org/xml/features/disallow-doctype-decl";
+ factory.setFeature(feature, true);
+ feature = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
+ factory.setFeature(feature, false);
+ feature = "http://xml.org/sax/features/external-general-entities";
+ factory.setFeature(feature, false);
+ feature = "http://xml.org/sax/features/external-parameter-entities";
+ factory.setFeature(feature, false);
+ } catch (Exception ex) {
+ // abort if secure processing is not supported
+ throw new IllegalStateException("Secure processing feature '" + feature + "' not supported by the DocumentBuilderFactory: " + factory.getClass().getName(), ex);
+ }
+ return factory;
+ }
+
+ /**
+ * @return an {@link EntityResolver} which will always cause a parse exception.
+ */
+ public static EntityResolver nonResolvingEntityResolver() {
+ return (publicId, systemId) -> {
+ throw new IOException("This parser does not support resolution of external entities (publicId: " + publicId
+ + ", systemId: " + systemId + ")");
+ };
+ }
+}
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/package-info.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/package-info.java
index 28b80f00b30..ff032b7bc45 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/package-info.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/package-info.java
@@ -14,5 +14,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@org.osgi.annotation.versioning.Version("2.2")
+@org.osgi.annotation.versioning.Version("2.3")
package org.apache.jackrabbit.commons.xml;
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/package-info.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/package-info.java
index 26f32fe40f9..3dae34a6ab9 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/package-info.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/package-info.java
@@ -14,5 +14,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@org.osgi.annotation.versioning.Version("2.2")
+@org.osgi.annotation.versioning.Version("2.3")
package org.apache.jackrabbit;
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Base64.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Base64.java
index f6708899252..ae2925f5719 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Base64.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Base64.java
@@ -27,9 +27,17 @@
import java.io.Writer;
import java.io.BufferedWriter;
import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
/**
*
+ * NOTE: the decoder accepts invalid input (such as non-trailing padding characters)
+ * and just returns broken output (see JCR-5227).
+ *
+ * See RFC 4648, Section 4.
+ *
+ * See {@link java.util.Base64} for a better JDK alternative.
*/
public class Base64 {
@@ -46,9 +54,7 @@ public class Base64 {
static {
// initialize decoding table
- for (int i = 0; i < DECODETABLE.length; i++) {
- DECODETABLE[i] = 0x7f;
- }
+ Arrays.fill(DECODETABLE, (byte) 0x7f);
// build decoding table
for (int i = 0; i < BASE64CHARS.length; i++) {
DECODETABLE[BASE64CHARS[i]] = (byte) i;
@@ -65,11 +71,10 @@ private Base64() {
}
/**
- * Base64-decodes or -encodes (see {@link #decodeOrEncode(String)}
+ * Base64-decodes or -encodes (see {@link #decodeOrEncode(String)})
* all the given arguments and prints the results on separate lines
* in standard output.
*
- * @since Apache Jackrabbit 2.3
* @param args command line arguments to be decoded or encoded
*/
public static void main(String[] args) {
@@ -80,10 +85,9 @@ public static void main(String[] args) {
/**
* Base64-decodes or -encodes the given string, depending on whether
- * or not it contains a "{base64}" prefix. If the string gets encoded,
+ * it contains a "{base64}" prefix. If the string gets encoded,
* the "{base64}" prefix is added to it.
*
- * @since Apache Jackrabbit 2.3
* @param data string to be decoded or encoded
* @return decoded or encoded string
*/
@@ -101,7 +105,6 @@ public static String decodeOrEncode(String data) {
* If the given string is
+ * Note that just using this method does not necessarily return a string which is a
+ * valid local name.
+ * You still have to take care of invalid XML characters.
*
* @param name the name to escape
* @return the escaped name
@@ -567,6 +574,31 @@ public static String unescapeIllegalJcrChars(String name) {
return buffer.toString();
}
+ /**
+ * Checks if the given name is a valid JCR local name.
+ *
+ * Note that the return value of {@link #escapeIllegalJcrChars(String)} is not necessarily a valid local name.
+ * You still have to take care of invalid XML characters.
+ *
+ * @param localName the string value to check
+ * @return
- * Overridable methods are provided to change the storage node and to change how
- * nodes are added to and removed. Hopefully, all you need for unusual subclasses
- * is here.
- *
- * If this constructor is used by a serializable subclass then the init()
- * method must be called.
- */
- protected CopyOfAbstractLinkedList() {
- }
-
- /**
- * Constructs a list copying data from the specified collection.
- *
- * @param coll the collection to copy
- */
- protected CopyOfAbstractLinkedList(final Collection extends E> coll) {
- init();
- addAll(coll);
- }
-
- /**
- * The equivalent of a default constructor, broken out so it can be called
- * by any constructor and by {@code readObject}.
- * Subclasses which override this method should make sure they call super,
- * so the list is initialized properly.
- */
- protected void init() {
- header = createHeaderNode();
- }
-
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public boolean isEmpty() {
- return size() == 0;
- }
-
- @Override
- public E get(final int index) {
- final Node
- * This implementation iterates over the elements of this list, checking each element in
- * turn to see if it's contained in {@code coll}. If it's contained, it's removed
- * from this list. As a consequence, it is advised to use a collection type for
- * {@code coll} that provides a fast (e.g. O(1)) implementation of
- * {@link Collection#contains(Object)}.
- */
- @Override
- public boolean removeAll(final Collection> coll) {
- boolean modified = false;
- final Iterator
- * This implementation iterates over the elements of this list, checking each element in
- * turn to see if it's contained in {@code coll}. If it's not contained, it's removed
- * from this list. As a consequence, it is advised to use a collection type for
- * {@code coll} that provides a fast (e.g. O(1)) implementation of
- * {@link Collection#contains(Object)}.
- */
- @Override
- public boolean retainAll(final Collection> coll) {
- boolean modified = false;
- final Iterator
- * This implementation uses {@link #createNode(Object)} and
- * {@link #addNode(CopyOfAbstractLinkedList.Node,CopyOfAbstractLinkedList.Node)}.
- *
- * @param node node to insert before
- * @param value value of the newly added node
- * @throws NullPointerException if {@code node} is null
- */
- protected void addNodeBefore(final Node
- * This implementation uses {@link #createNode(Object)} and
- * {@link #addNode(CopyOfAbstractLinkedList.Node,CopyOfAbstractLinkedList.Node)}.
- *
- * @param node node to insert after
- * @param value value of the newly added node
- * @throws NullPointerException if {@code node} is null
- */
- protected void addNodeAfter(final Node
- * The first serializable subclass must call this method from
- * {@code writeObject}.
- *
- * @param outputStream the stream to write the object to
- * @throws IOException if anything goes wrong
- */
- protected void doWriteObject(final ObjectOutputStream outputStream) throws IOException {
- // Write the size so we know how many nodes to read back
- outputStream.writeInt(size());
- for (final E e : this) {
- outputStream.writeObject(e);
- }
- }
-
- /**
- * Deserializes the data held in this object to the stream specified.
- *
- * The first serializable subclass must call this method from
- * {@code readObject}.
- *
- * @param inputStream the stream to read the object from
- * @throws IOException if any error occurs while reading from the stream
- * @throws ClassNotFoundException if a class read from the stream can not be loaded
- */
- @SuppressWarnings("unchecked")
- protected void doReadObject(final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
- init();
- final int size = inputStream.readInt();
- for (int i = 0; i < size; i++) {
- add((E) inputStream.readObject());
- }
- }
-
- /**
- * A node within the linked list.
- *
- * From Commons Collections 3.1, all access to the {@code value} property
- * is via the methods on this class.
- */
- protected static class Nodenull if the namespace does not exist.
+ * session, or {@code null} if the namespace does not exist.
*
* @see Session#getNamespacePrefix(String)
* @param uri namespace URI
- * @return namespace prefix, or null
- * @throws RepositoryException if the namespace could not be retrieved
+ * @return namespace prefix, or {@code null}
+ * @throws RepositoryException if the namespace prefix could not be retrieved
*/
public String getPrefix(String uri) throws RepositoryException {
try {
@@ -99,11 +124,11 @@ public String getPrefix(String uri) throws RepositoryException {
/**
* Returns the namespace URI mapped to the given prefix in the current
- * session, or null if the namespace does not exist.
+ * session, or {@code null} if the namespace does not exist.
*
* @see Session#getNamespaceURI(String)
* @param prefix namespace prefix
- * @return namespace prefix, or null
+ * @return namespace prefix, or {@code null}
* @throws RepositoryException if the namespace could not be retrieved
*/
public String getURI(String prefix) throws RepositoryException {
@@ -126,7 +151,7 @@ public String getURI(String prefix) throws RepositoryException {
*/
public String getJcrName(String uri, String name)
throws NamespaceException, RepositoryException {
- if (uri != null && uri.length() > 0) {
+ if (uri != null && !uri.isEmpty()) {
return session.getNamespacePrefix(uri) + ":" + name;
} else {
return name;
@@ -144,6 +169,11 @@ public String getJcrName(String uri, String name)
*
* node.getProperty(helper.getName("jcr:data"));
*
+ * Note that it is simpler to just use the expanded name wherever supported:
+ *
+ * node.getProperty("http://www.jcp.org/jcr/1.0}data");
+ *
+ * Also note the predefined constants in {@link org.apache.jackrabbit.JcrConstants}.
*
* @param name prefixed name using the standard JCR prefixes
* @return prefixed name using the current session namespace mappings
@@ -178,7 +208,7 @@ public String getJcrName(String name)
/**
* Safely registers the given namespace. If the namespace already exists,
* then the prefix mapped to the namespace in the current session is
- * returned. Otherwise the namespace is registered to the namespace
+ * returned. Otherwise, the namespace is registered to the namespace
* registry. If the given prefix is already registered for some other
* namespace or otherwise invalid, then another prefix is automatically
* generated. After the namespace has been registered, the prefix mapped
@@ -192,32 +222,36 @@ public String getJcrName(String name)
*/
public String registerNamespace(String prefix, String uri)
throws RepositoryException {
- NamespaceRegistry registry =
- session.getWorkspace().getNamespaceRegistry();
+ NamespaceRegistry registry = getNamespaceRegistry();
try {
// Check if the namespace is registered
registry.getPrefix(uri);
} catch (NamespaceException e1) {
- // Replace troublesome prefix hints
- if (prefix == null || prefix.length() == 0
+ // Throw away Troublesome prefix hints
+ if (prefix == null || prefix.isEmpty()
|| prefix.toLowerCase().startsWith("xml")
|| !XMLChar.isValidNCName(prefix)) {
- prefix = "ns"; // ns, ns2, ns3, ns4, ...
+ prefix = null;
}
- // Loop until an unused prefix is found
- try {
- String base = prefix;
- for (int i = 2; true; i++) {
- registry.getURI(prefix);
- prefix = base + i;
- }
- } catch (NamespaceException e2) {
- // Exit the loop
- }
+ if (prefix == null) {
+ prefix = suggestPrefix(uri, pref -> {
+ // prefix checker
+ try {
+ return registry.getURI(pref);
+ } catch (RepositoryException e) {
+ return null;
+ }
+ });
+ }
// Register the namespace
- registry.registerNamespace(prefix, uri);
+ try {
+ registry.registerNamespace(prefix, uri);
+ } catch (NamespaceException ex) {
+ // likely prefix is already in use; retry with null prefix
+ return registerNamespace(null, uri);
+ }
}
return session.getNamespacePrefix(uri);
@@ -231,10 +265,118 @@ public String registerNamespace(String prefix, String uri)
* @throws RepositoryException if the namespaces could not be registered
*/
public void registerNamespaces(MapJSONHandler interface receives notifications from the
* JsonParser.
+ * @deprecated use JSON Processing API instead.
*/
+@Deprecated(since="2.24.0")
public interface JsonHandler {
/**
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/json/JsonParser.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/json/JsonParser.java
index 529d48690b6..2433e83e493 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/json/JsonParser.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/json/JsonParser.java
@@ -29,7 +29,9 @@
* JsonParser parses and validates the JSON object passed upon
* {@link #parse(String)} or {@link #parse(InputStream, String)} and notifies
* the specified JsonHandler
+ * @deprecated use JSON Processing API instead.
*/
+@Deprecated(since="2.24.0")
public class JsonParser {
private static final String NULL = "null";
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/package-info.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/package-info.java
index 42b3b486607..7eb2a8d1414 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/package-info.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/package-info.java
@@ -14,5 +14,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@org.osgi.annotation.versioning.Version("2.4.0")
+@org.osgi.annotation.versioning.Version("2.5.0")
package org.apache.jackrabbit.commons;
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/repository/JNDIRepository.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/repository/JNDIRepository.java
index c8eff32952b..ffd94138f6c 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/repository/JNDIRepository.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/repository/JNDIRepository.java
@@ -24,9 +24,13 @@
* does not need to exist when this class is instantiated. The JNDI entry
* can also be replaced with another repository during the lifetime of an
* instance of this class.
+ * Base64 provides Base64 encoding/decoding of strings and streams.
+ * null, then null
* is returned.
*
- * @since Apache Jackrabbit 2.3
* @param data string to be decoded, can be null
* @return the given string, possibly decoded
*/
@@ -233,7 +236,6 @@ public static void encode(byte[] data, int off, int len, Writer writer)
/**
* Returns the base64 representation of UTF-8 encoded string.
*
- * @since Apache Jackrabbit 2.3
* @param data the string to be encoded
* @return base64-encoding of the string
*/
@@ -254,7 +256,6 @@ public static String encode(String data) {
* The given string is returned as-is if it doesn't contain a valid
* base64 encoding.
*
- * @since Apache Jackrabbit 2.3
* @param data the base64-encoded data to be decoded
* @return decoded string
*/
@@ -262,7 +263,7 @@ public static String decode(String data) {
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
decode(data, buffer);
- return new String(buffer.toByteArray(), StandardCharsets.UTF_8);
+ return buffer.toString(StandardCharsets.UTF_8);
} catch (IllegalArgumentException e) {
return data;
} catch (IOException e) { // should never happen
@@ -325,6 +326,20 @@ public static void decode(char[] chars, OutputStream out)
decode(chars, 0, chars.length, out);
}
+ // utility methods to decode into 1st, 2nd and 3rd position of output
+
+ private static byte decodeFirst(int b0, int b1) {
+ return (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+ }
+
+ private static byte decodeSecond(int b1, int b2) {
+ return (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
+ }
+
+ private static byte decodeThird(int b2, int b3) {
+ return (byte) (b2 << 6 & 0xc0 | b3 & 0x3f);
+ }
+
/**
* Decode base64 encoded data.
*
@@ -358,16 +373,16 @@ public static void decode(char[] chars, int off, int len, OutputStream out)
int b2 = DECODETABLE[chunk[2]];
int b3 = DECODETABLE[chunk[3]];
if (chunk[3] == BASE64PAD && chunk[2] == BASE64PAD) {
- dec[0] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
+ dec[0] = decodeFirst(b0, b1);
out.write(dec, 0, 1);
} else if (chunk[3] == BASE64PAD) {
- dec[0] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
- dec[1] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
+ dec[0] = decodeFirst(b0, b1);
+ dec[1] = decodeSecond(b1, b2);
out.write(dec, 0, 2);
} else {
- dec[0] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3);
- dec[1] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf);
- dec[2] = (byte) (b2 << 6 & 0xc0 | b3 & 0x3f);
+ dec[0] = decodeFirst(b0, b1);
+ dec[1] = decodeSecond(b1, b2);
+ dec[2] = decodeThird(b2, b3);
out.write(dec, 0, 3);
}
posChunk = 0;
@@ -376,5 +391,31 @@ public static void decode(char[] chars, int off, int len, OutputStream out)
throw new IllegalArgumentException("specified data is not base64 encoded");
}
}
+
+ // if there is an incomplete chunk...
+ if (posChunk != 0) {
+ boolean lastCharWasPad = chunk[posChunk - 1] == BASE64PAD;
+ if (lastCharWasPad) {
+ throw new IllegalArgumentException("specified data is not base64 encoded (input ends with unexpected pad character");
+ }
+
+ // handle missing padding gracefully, inspired by
+ // https://datatracker.ietf.org/doc/html/rfc7515#appendix-C
+
+ if (posChunk == 1) {
+ throw new IllegalArgumentException("specified data is not base64 encoded (extra non-pad character");
+ }
+
+ if (posChunk == 2) {
+ // no padding, input length == 2; add two pad characters
+ chunk[2] = BASE64PAD;
+ chunk[3] = BASE64PAD;
+ } else {
+ // no padding, input length == 3: add one pad character
+ chunk[3] = BASE64PAD;
+ }
+
+ decode(chunk, out);
+ }
}
}
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Text.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Text.java
index 0b860bc904f..b6afc77c1da 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Text.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/Text.java
@@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Properties;
+import java.util.Set;
/**
* This Class provides some text related utilities
@@ -41,6 +42,8 @@ private Text() {
*/
public static final char[] hexTable = "0123456789abcdef".toCharArray();
+ private static final Settrue if the name is valid, false otherwise.
+ * @see JCR 2.0 Spec, §3.2.2 Local Names
+ * @see #escapeIllegalJcrChars(String)
+ * @since 2.6.0 (Apache Jackrabbit 2.24.0)
+ */
+ public static boolean isValidJcrLocalName(String localName) {
+ if (localName == null || localName.isEmpty()) {
+ return false;
+ }
+ // self or parent are invalid
+ if (localName.equals(".") || localName.equals("..")) {
+ return false;
+ }
+ return localName.chars().noneMatch(c ->
+ INVALID_JCR_LOCAL_NAME_CHARS.contains((char) c) || !XMLChar.isValid(c)
+ );
+ }
+
/**
* Returns the name part of the path. If the given path is already a name
* (i.e. contains no slashes) it is returned.
diff --git a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/package-info.java b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/package-info.java
index ebb06936161..ccfc068b292 100644
--- a/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/package-info.java
+++ b/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/util/package-info.java
@@ -14,5 +14,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@org.osgi.annotation.versioning.Version("2.5.0")
+@org.osgi.annotation.versioning.Version("2.6.0")
package org.apache.jackrabbit.util;
diff --git a/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/JcrUtilsTest.java b/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/JcrUtilsTest.java
index a6a867112be..e44224ee333 100644
--- a/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/JcrUtilsTest.java
+++ b/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/JcrUtilsTest.java
@@ -51,20 +51,52 @@ public void testGetRepository() throws Exception {
"java.naming.factory.initial",
"org.osjava.sj.memory.MemoryContextFactory");
parameters.put("org.osjava.sj.jndi.shared", "true");
- assertTrue(repository == JcrUtils.getRepository(parameters));
+
+ // JDNI ist disabled by default
+ if (JndiRepositoryFactory.JNDI_ENABLED) {
+ assertTrue(repository == JcrUtils.getRepository(parameters));
+ } else {
+ try {
+ JcrUtils.getRepository(parameters);
+ fail("Repository lookup should fail and throw an exception");
+ } catch (RepositoryException expected) {}
+ }
// Test lookup with URI query parameters
- assertTrue(repository == JcrUtils.getRepository(
- "jndi://x"
- + "?org.apache.jackrabbit.repository.jndi.name=repository"
- + "&org.osjava.sj.jndi.shared=true"
- + "&java.naming.factory.initial"
- + "=org.osjava.sj.memory.MemoryContextFactory"));
+ // JDNI ist disabled by default
+ if (JndiRepositoryFactory.JNDI_ENABLED) {
+ assertTrue(repository == JcrUtils.getRepository(
+ "jndi://x"
+ + "?org.apache.jackrabbit.repository.jndi.name=repository"
+ + "&org.osjava.sj.jndi.shared=true"
+ + "&java.naming.factory.initial"
+ + "=org.osjava.sj.memory.MemoryContextFactory"));
+ } else {
+ try {
+ JcrUtils.getRepository(
+ "jndi://x"
+ + "?org.apache.jackrabbit.repository.jndi.name=repository"
+ + "&org.osjava.sj.jndi.shared=true"
+ + "&java.naming.factory.initial"
+ + "=org.osjava.sj.memory.MemoryContextFactory");
+ fail("Repository lookup should fail and throw an exception");
+ } catch (RepositoryException expected) {}
+ }
// Test lookup with the custom JNDI URI format (JCR-2771)
- assertTrue(repository == JcrUtils.getRepository(
- "jndi://org.osjava.sj.memory.MemoryContextFactory/repository"
- + "?org.osjava.sj.jndi.shared=true"));
+ // JDNI ist disabled by default
+ if (JndiRepositoryFactory.JNDI_ENABLED) {
+ assertTrue(repository == JcrUtils.getRepository(
+ "jndi://org.osjava.sj.memory.MemoryContextFactory/repository"
+ + "?org.osjava.sj.jndi.shared=true"));
+ } else {
+ try {
+ JcrUtils.getRepository(
+ "jndi://org.osjava.sj.memory.MemoryContextFactory/repository"
+ + "?org.osjava.sj.jndi.shared=true");
+ fail("Repository lookup should fail and throw an exception");
+ } catch (RepositoryException expected) {}
+ }
try {
JcrUtils.getRepository(
diff --git a/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/NamespaceHelperTest.java b/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/NamespaceHelperTest.java
new file mode 100644
index 00000000000..7db200b622a
--- /dev/null
+++ b/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/NamespaceHelperTest.java
@@ -0,0 +1,362 @@
+/*
+ * 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.commons;
+
+import junit.framework.TestCase;
+import org.mockito.Mockito;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Workspace;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+public class NamespaceHelperTest extends TestCase {
+
+ private Session session;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ session = Mockito.mock(Session.class);
+ }
+
+ public void testGetNamespaces() throws RepositoryException {
+ NamespaceHelper nsHelper = new NamespaceHelper(session);
+
+ when(session.getNamespacePrefixes()).thenReturn(new String[0]);
+ MapLengthsProperty extends {@link org.apache.jackrabbit.webdav.property.DavProperty} providing
+ * {@code LengthsProperty} extends {@link org.apache.jackrabbit.webdav.property.DavProperty} providing
* utilities to handle the multiple lengths of the property item represented
* by this resource.
*/
@@ -32,7 +32,7 @@ public class LengthsProperty extends AbstractDavPropertyLengthsProperty from the given long array.
+ * Create a new {@code LengthsProperty} from the given long array.
*
* @param lengths as retrieved from the JCR property
*/
@@ -42,10 +42,10 @@ public LengthsProperty(long[] lengths) {
}
/**
- * Returns an array of {@link long}s representing the value of this
+ * Returns an array of {@code long}s representing the value of this
* property.
*
- * @return an array of {@link long}s
+ * @return an array of {@code long}s
*/
public long[] getValue() {
return value;
diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java
index 1292b129ce3..defe7a522bb 100644
--- a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java
+++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/simple/ResourceConfig.java
@@ -351,7 +351,7 @@ private static Object buildClassFromConfig(Element parent) {
String className = DomUtil.getAttribute(classElem, "name", null);
if (className != null) {
Class> c = Class.forName(className);
- instance = c.newInstance();
+ instance = c.getDeclaredConstructor().newInstance();
} else {
log.error("Invalid configuration: missing 'class' element");
}
diff --git a/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/util/RequestDataTest.java b/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/util/RequestDataTest.java
new file mode 100755
index 00000000000..36d59c55a3c
--- /dev/null
+++ b/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/util/RequestDataTest.java
@@ -0,0 +1,249 @@
+/*
+ * 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.server.util;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.collections4.IteratorUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.*;
+
+import javax.servlet.ServletInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RequestDataTest {
+
+ @Rule
+ public TemporaryFolder tempFolder = new TemporaryFolder();
+
+ @Mock
+ private HttpServletRequest mockRequest;
+
+ /**
+ * Helper to wrap raw multipart text bytes cleanly into a mock ServletInputStream.
+ */
+ private ServletInputStream createServletInputStream(final byte[] payload) {
+ final ByteArrayInputStream bais = new ByteArrayInputStream(payload);
+ return new ServletInputStream() {
+ @Override
+ public int read() {
+ return bais.read();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return bais.available() == 0;
+ }
+
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
+ public void setReadListener(javax.servlet.ReadListener readListener) {
+ throw new UnsupportedOperationException("Non-blocking I/O not implemented in mock");
+ }
+ };
+ }
+
+ /**
+ * Verifies standard parsing works smoothly using the clean temp directory assignment.
+ */
+ @Test
+ public void getParameterWithStandardRequest() throws Exception {
+ File testTmpDir = tempFolder.newFolder("jackrabbit_standard_tmp");
+
+ // ONLY stub what is actually called by RequestData for a standard request
+ // when(mockRequest.getParameter("param1")).thenReturn("value1");
+ when(mockRequest.getParameterValues("param1")).thenReturn(new String[]{"value1"});
+
+ RequestData requestData = new RequestData(mockRequest, testTmpDir);
+
+ try {
+ String[] values = requestData.getParameterValues("param1");
+ assertNotNull("Parameter array should not be null", values);
+ assertEquals("Value mismatch", "value1", values[0]);
+ } finally {
+ requestData.dispose();
+ }
+ }
+
+ /**
+ * Test multipart POST requests consisting of multiple body parameters.
+ */
+ @Test
+ public void testMultipartPostWithMultipleParts() throws Exception {
+ File testTmpDir = tempFolder.newFolder("jackrabbit_multi_parts");
+
+ String boundary = "----MockBoundary123";
+ String body = "--" + boundary + "\r\n" +
+ "Content-Disposition: form-data; name=\"textField\"\r\n\r\n" +
+ "textValue\r\n" +
+ "--" + boundary + "\r\n" +
+ "Content-Disposition: form-data; name=\"fileField\"; filename=\"test.txt\"\r\n" +
+ "Content-Type: text/plain\r\n\r\n" +
+ "Hello World Item Data\r\n" +
+ "--" + boundary + "--\r\n";
+ byte[] payloadBytes = body.getBytes(StandardCharsets.UTF_8);
+
+ // For multipart requests, these methods are genuinely called by Jackrabbit's parser
+ when(mockRequest.getMethod()).thenReturn("POST");
+ when(mockRequest.getContentType()).thenReturn("multipart/form-data; boundary=" + boundary);
+ lenient().when(mockRequest.getCharacterEncoding()).thenReturn("UTF-8");
+ when(mockRequest.getInputStream()).thenReturn(createServletInputStream(payloadBytes));
+
+ RequestData requestData = new RequestData(mockRequest, testTmpDir);
+ try {
+ assertEquals("textValue", requestData.getParameter("textField"));
+ assertNotNull("Multipart file field must map", requestData.getParameter("fileField"));
+ assertEquals(Set.of("fileField", "textField"), IteratorUtils.toSet(requestData.getParameterNames()));
+ assertEquals(List.of("text/plain"), Arrays.asList(requestData.getParameterTypes("fileField")));
+ assertNull(requestData.getParameterTypes("textField")[0]);
+ assertEquals(1, requestData.getParameterTypes("textField").length);
+
+ InputStream[] streams = requestData.getFileParameters("fileField");
+ assertEquals(1, streams.length);
+ assertEquals("Hello World Item Data", new String(streams[0].readAllBytes(), StandardCharsets.UTF_8));
+
+ assertNull("Multipart file field must map", requestData.getParameter("x"));
+ assertNull(requestData.getFileParameters("x"));
+ assertNull(requestData.getParameterTypes("x"));
+ assertNull(requestData.getParameterValues("x"));
+ } finally {
+ requestData.dispose();
+ }
+ }
+
+ /**
+ * Test data parsing performance against inflated MIME/Header padding sizes.
+ */
+ // @Test
+ public void testMultipartPostWithLargeHeaders() throws Exception {
+ File testTmpDir = tempFolder.newFolder("jackrabbit_large_headers");
+ String boundary = "----MockBoundaryLargeHeaders";
+
+ String body = "--" + boundary + "\r\n" +
+ "Content-Disposition: form-data; name=\"payloadField\"\r\n" +
+ "X-Long-Header: " + "X-Header-Padding-Data-String-".repeat(1000) + "\r\n\r\n" +
+ "ShortBodyContent\r\n" +
+ "--" + boundary + "--\r\n";
+ byte[] payloadBytes = body.getBytes(StandardCharsets.UTF_8);
+
+ when(mockRequest.getMethod()).thenReturn("POST");
+ when(mockRequest.getContentType()).thenReturn("multipart/form-data; boundary=" + boundary);
+ lenient().when(mockRequest.getCharacterEncoding()).thenReturn("UTF-8");
+ when(mockRequest.getInputStream()).thenReturn(createServletInputStream(payloadBytes));
+
+ RequestData requestData = new RequestData(mockRequest, testTmpDir);
+ try {
+ assertEquals("ShortBodyContent", requestData.getParameter("payloadField"));
+ } finally {
+ requestData.dispose();
+ }
+ }
+
+ private void buildRequestWithFilenameOfVaryingLength(int length) throws IOException {
+ String boundary = "----MockBoundaryLongFilename";
+
+ String longFilename = "0123456789".repeat(length / 10) + ".tmp";
+
+ String body = "--" + boundary + "\r\n" +
+ "Content-Disposition: form-data; name=\"fileUpload\"; filename=\"" + longFilename + "\"\r\n" +
+ "Content-Type: application/octet-stream\r\n\r\n" +
+ "FileContentStreamData\r\n" +
+ "--" + boundary + "--\r\n";
+ byte[] payloadBytes = body.getBytes(StandardCharsets.UTF_8);
+
+ when(mockRequest.getMethod()).thenReturn("POST");
+ when(mockRequest.getContentType()).thenReturn("multipart/form-data; boundary=" + boundary);
+ lenient().when(mockRequest.getCharacterEncoding()).thenReturn("UTF-8");
+ when(mockRequest.getInputStream()).thenReturn(createServletInputStream(payloadBytes));
+ }
+
+ // test default limits in commons-fileuploads
+
+ @Test
+ public void testMultipartPostWithShorterFilename() throws Exception {
+ buildRequestWithFilenameOfVaryingLength(400);
+ File testTmpDir = tempFolder.newFolder("jackrabbit_long_filename");
+ RequestData requestData = new RequestData(mockRequest, testTmpDir);
+ try {
+ assertTrue(
+ requestData.getParameter("fileUpload").length() > 350);
+ } finally {
+ requestData.dispose();
+ }
+ }
+
+ @Test(expected = IOException.class)
+ public void testMultipartPostWithExtremelyLongFilename() throws Exception {
+ // header bytes ~= filename length + ~107; at 5000 chars this far exceeds the 4096 default
+ buildRequestWithFilenameOfVaryingLength(5000);
+ File testTmpDir = tempFolder.newFolder("jackrabbit_long_filename");
+ new RequestData(mockRequest, testTmpDir); // must throw IOException
+ }
+
+ @Test
+ public void testMultipartPostWithLongFilenameUnderNewDefault() throws Exception {
+ buildRequestWithFilenameOfVaryingLength(3800); // above 512, below 4096
+ File testTmpDir = tempFolder.newFolder("jackrabbit_medium_filename");
+ RequestData requestData = new RequestData(mockRequest, testTmpDir);
+ try {
+ assertTrue(requestData.getParameter("fileUpload").length() > 3800);
+ } finally {
+ requestData.dispose();
+ }
+ }
+
+ @Test
+ public void testMultipartPostWithExtremelyLongFilenameWithHigherConfig() throws Exception {
+ try {
+ System.setProperty("jackrabbit-server-PartHeaderSizeMax", "8192");
+ buildRequestWithFilenameOfVaryingLength(7500);
+ File testTmpDir = tempFolder.newFolder("jackrabbit_long_filename");
+ RequestData requestData = new RequestData(mockRequest, testTmpDir);
+ try {
+ assertTrue(
+ requestData.getParameter("fileUpload").length() > 7500);
+ } finally {
+ requestData.dispose();
+ }
+ } finally {
+ System.clearProperty("jackrabbit-server-PartHeaderSizeMax");
+ }
+ }
+}
\ No newline at end of file
diff --git a/jackrabbit-jcr-servlet/pom.xml b/jackrabbit-jcr-servlet/pom.xml
index b02b2476ee5..d8e46174998 100644
--- a/jackrabbit-jcr-servlet/pom.xml
+++ b/jackrabbit-jcr-servlet/pom.xml
@@ -22,7 +22,7 @@
TreeComparator compares two trees. This allows re-use for
diff --git a/jackrabbit-jcr2dav/pom.xml b/jackrabbit-jcr2dav/pom.xml
index 74fa2a3c30d..195d3a9bd33 100644
--- a/jackrabbit-jcr2dav/pom.xml
+++ b/jackrabbit-jcr2dav/pom.xml
@@ -26,7 +26,7 @@
LinkNode.
- * @see CopyOfAbstractLinkedList#createHeaderNode()
+ * @see AbstractLinkedListJava21#createHeaderNode()
*/
@Override
protected Node createHeaderNode() {
diff --git a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeType.java b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeType.java
index 210c11ee103..5c551656ebe 100644
--- a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeType.java
+++ b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/nodetype/EffectiveNodeType.java
@@ -106,6 +106,7 @@ public void checkAddNodeConstraints(Name name, QNodeTypeDefinition nodeTypeDefin
* @deprecated Use {@link #hasRemoveNodeConstraint(Name)} and
* {@link #hasRemovePropertyConstraint(Name)} respectively.
*/
+ @Deprecated
public void checkRemoveItemConstraints(Name name) throws ConstraintViolationException;
/**
diff --git a/test/performance/jackrabbit11/src/test/java/org/apache/jackrabbit/performance/PerformanceTest.java b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/package-info.java
similarity index 76%
rename from test/performance/jackrabbit11/src/test/java/org/apache/jackrabbit/performance/PerformanceTest.java
rename to jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/package-info.java
index 11a7ccebb50..fe15ce17a21 100644
--- a/test/performance/jackrabbit11/src/test/java/org/apache/jackrabbit/performance/PerformanceTest.java
+++ b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/package-info.java
@@ -14,15 +14,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.jackrabbit.performance;
-
-import org.testng.annotations.Test;
-
-public class PerformanceTest extends AbstractPerformanceTest {
-
- @Test
- public void testPerformance() throws Exception {
- testPerformance("1.1");
- }
-
-}
+@org.osgi.annotation.versioning.Version("2.22.4")
+package org.apache.jackrabbit.jcr2spi;
\ No newline at end of file
diff --git a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/security/authorization/AccessControlProviderStub.java b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/security/authorization/AccessControlProviderStub.java
index 23ace3a6c02..fcb2c2b8cd8 100644
--- a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/security/authorization/AccessControlProviderStub.java
+++ b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/security/authorization/AccessControlProviderStub.java
@@ -69,7 +69,7 @@ public static AccessControlProvider newInstance(RepositoryConfig config) throws
try {
Class> acProviderClass = Class.forName(className);
if (AccessControlProvider.class.isAssignableFrom(acProviderClass)) {
- AccessControlProvider acProvider = (AccessControlProvider) acProviderClass.newInstance();
+ AccessControlProvider acProvider = (AccessControlProvider) acProviderClass.getDeclaredConstructor().newInstance();
acProvider.init(config);
return acProvider;
} else {
diff --git a/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/BinaryTest.java b/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/BinaryTest.java
index a01d8209baa..11651c78470 100644
--- a/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/BinaryTest.java
+++ b/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/BinaryTest.java
@@ -16,19 +16,18 @@
*/
package org.apache.jackrabbit.jcr2spi;
-import java.util.Random;
-
import static org.junit.Assert.assertArrayEquals;
import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Random;
+import javax.jcr.Binary;
import javax.jcr.Node;
-import javax.jcr.Session;
import javax.jcr.Property;
-import javax.jcr.Binary;
+import javax.jcr.Session;
import javax.jcr.ValueFormatException;
-import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.jcr2spi.state.PropertyState;
import org.apache.jackrabbit.spi.QValue;
import org.apache.jackrabbit.test.AbstractJCRTest;
@@ -186,7 +185,9 @@ public void testStreamIntegrity() throws Exception {
// check the binaries are indeed the same (JCR-4154)
byte[] result = new byte[bytes.length];
- IOUtils.readFully(p.getBinary().getStream(), result);
+ try (InputStream in = p.getBinary().getStream()) {
+ result = in.readAllBytes();
+ }
assertArrayEquals(bytes, result);
} finally {
s.logout();
diff --git a/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/CopyMoveToJsonTest.java b/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/CopyMoveToJsonTest.java
index 9b7e6c26b4d..2ac41fee50c 100755
--- a/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/CopyMoveToJsonTest.java
+++ b/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/CopyMoveToJsonTest.java
@@ -17,14 +17,15 @@
package org.apache.jackrabbit.jcr2spi;
import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.test.AbstractJCRTest;
@@ -39,7 +40,9 @@ public void testCreateJson() throws Exception {
try {
Property p = s.getNode(testRoot).getNode("test.json").getNode(JcrConstants.JCR_CONTENT)
.getProperty(JcrConstants.JCR_DATA);
- assertEquals(jsondata, IOUtils.toString(p.getBinary().getStream(), "UTF-8"));
+ try (InputStream in = p.getBinary().getStream()) {
+ assertEquals(jsondata, new String(in.readAllBytes(), StandardCharsets.UTF_8));
+ }
} finally {
s.logout();
}
@@ -53,7 +56,9 @@ public void testCopyJson() throws Exception {
try {
Property p = s.getNode(testRoot).getNode("target.json").getNode(JcrConstants.JCR_CONTENT)
.getProperty(JcrConstants.JCR_DATA);
- assertEquals(jsondata, IOUtils.toString(p.getBinary().getStream(), "UTF-8"));
+ try (InputStream in = p.getBinary().getStream()) {
+ assertEquals(jsondata, new String(in.readAllBytes(), StandardCharsets.UTF_8));
+ }
} finally {
s.logout();
}
@@ -67,7 +72,9 @@ public void testMoveJson() throws Exception {
try {
Property p = s.getNode(testRoot).getNode("target.json").getNode(JcrConstants.JCR_CONTENT)
.getProperty(JcrConstants.JCR_DATA);
- assertEquals(jsondata, IOUtils.toString(p.getBinary().getStream(), "UTF-8"));
+ try (InputStream in = p.getBinary().getStream()) {
+ assertEquals(jsondata, new String(in.readAllBytes(), StandardCharsets.UTF_8));
+ }
} finally {
s.logout();
}
diff --git a/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/security/authorization/jackrabbit/acl/AccessControlListImplTest.java b/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/security/authorization/jackrabbit/acl/AccessControlListImplTest.java
index 9c6a9789d71..f0fe19ed5ee 100644
--- a/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/security/authorization/jackrabbit/acl/AccessControlListImplTest.java
+++ b/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/security/authorization/jackrabbit/acl/AccessControlListImplTest.java
@@ -28,7 +28,6 @@
import javax.jcr.security.AccessControlList;
import javax.jcr.security.Privilege;
-import junit.framework.Assert;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.QValueFactory;
@@ -36,6 +35,7 @@
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
import org.apache.jackrabbit.test.api.security.AbstractAccessControlTest;
+import org.junit.Assert;
/**
* Tests the functionality of the JCR AccessControlList API implementation. The
@@ -97,15 +97,14 @@ public void testAddingDifferentEntries() throws Exception {
// four different entries
Assert.assertEquals(4, acl.size());
-
+
// UnknownPrincipal entries
AccessControlEntry[] pentries = getEntries(acl, unknownPrincipal);
Assert.assertEquals(2, pentries.length);
-
+
// secondPrincipal entries
AccessControlEntry[] sentries = getEntries(acl, knownPrincipal);
Assert.assertEquals(2, sentries.length);
-
}
public void testMultipleEntryEffect() throws Exception {
diff --git a/jackrabbit-parent/pom.xml b/jackrabbit-parent/pom.xml
index cc7617c4777..9c888e264e3 100644
--- a/jackrabbit-parent/pom.xml
+++ b/jackrabbit-parent/pom.xml
@@ -27,14 +27,14 @@
DocumentBuilderFactory.
*/
- private static DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = createFactory();
-
- private static DocumentBuilderFactory createFactory() {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- factory.setIgnoringComments(false);
- factory.setIgnoringElementContentWhitespace(true);
- return factory;
- }
+ private static DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = XMLFactories.safeDocumentBuilderFactory();
/**
* Constant for TransformerFactory
@@ -279,6 +272,8 @@ private PrivilegeDefinition parseDefinition(Node n, Mapfalse.
* @deprecated use {@link #addOrderSpec(Path , boolean)} instead.
*/
+ @Deprecated
public void addOrderSpec(Name property, boolean ascending) {
addOrderSpec(createPath(property), ascending);
}
@@ -232,6 +233,7 @@ public static final class OrderSpec {
* ascending, otherwise descending.
* @deprecated use {@link OrderSpec#OrderSpec(Path, boolean)} instead.
*/
+ @Deprecated
public OrderSpec(Name property, boolean ascending) {
this(createPath(property), ascending);
}
@@ -254,6 +256,7 @@ public OrderSpec(Path property, boolean ascending) {
* @return the name of the property.
* @deprecated use {@link #getPropertyPath()} instead.
*/
+ @Deprecated
public Name getProperty() {
return property.getName();
}
diff --git a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/TextsearchQueryNode.java b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/TextsearchQueryNode.java
index 15d1686e64f..3c2fe14ce82 100644
--- a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/TextsearchQueryNode.java
+++ b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/TextsearchQueryNode.java
@@ -98,6 +98,7 @@ public String getQuery() {
* @return property name or null.
* @deprecated Use {@link #getRelativePath()} instead.
*/
+ @Deprecated
public Name getPropertyName() {
return relPath == null ? null : relPath.getName();
}
@@ -108,6 +109,7 @@ public Name getPropertyName() {
* @param property the name of the property.
* @deprecated Use {@link #setRelativePath(Path)} instead.
*/
+ @Deprecated
public void setPropertyName(Name property) {
PathBuilder builder = new PathBuilder();
builder.addLast(property);
diff --git a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/SimpleCharStream.java b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/SimpleCharStream.java
index 2e085993bd7..9df5d742496 100644
--- a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/SimpleCharStream.java
+++ b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/SimpleCharStream.java
@@ -218,7 +218,7 @@ public char readChar() throws java.io.IOException
* @deprecated
* @see #getEndColumn
*/
-
+ @Deprecated
public int getColumn() {
return bufcolumn[bufpos];
}
@@ -227,7 +227,7 @@ public int getColumn() {
* @deprecated
* @see #getEndLine
*/
-
+ @Deprecated
public int getLine() {
return bufline[bufpos];
}
diff --git a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql2/Parser.java b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql2/Parser.java
index d8603db6197..22500e701f8 100644
--- a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql2/Parser.java
+++ b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql2/Parser.java
@@ -25,6 +25,7 @@
* @deprecated use {@link org.apache.jackrabbit.commons.query.sql2.Parser}
* instead.
*/
+@Deprecated
public class Parser extends org.apache.jackrabbit.commons.query.sql2.Parser {
diff --git a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/SimpleCharStream.java b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/SimpleCharStream.java
index 1547afa8cb8..1d7f294d0e0 100644
--- a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/SimpleCharStream.java
+++ b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/xpath/SimpleCharStream.java
@@ -202,7 +202,7 @@ public char readChar() throws java.io.IOException
* @deprecated
* @see #getEndColumn
*/
-
+ @Deprecated
public int getColumn() {
return bufcolumn[bufpos];
}
@@ -211,7 +211,7 @@ public int getColumn() {
* @deprecated
* @see #getEndLine
*/
-
+ @Deprecated
public int getLine() {
return bufline[bufpos];
}
diff --git a/jackrabbit-spi/pom.xml b/jackrabbit-spi/pom.xml
index ad9f80c260b..1128361ca28 100644
--- a/jackrabbit-spi/pom.xml
+++ b/jackrabbit-spi/pom.xml
@@ -26,7 +26,7 @@
@@ -191,7 +190,11 @@ protected void doSetFileSystemOptionsPropertiesInString() throws Exception {
File [] identities = configBuilder.getIdentities(fso);
Assert.assertNotNull(identities);
Assert.assertEquals(1, identities.length);
- Assert.assertEquals("/home/tester/.ssh/id_rsa", FilenameUtils.separatorsToUnix(identities[0].getPath()));
+ String expectedPath = identities[0].getPath();
+ if (FilenameUtils.getPrefixLength(expectedPath) != 0) {
+ expectedPath = expectedPath.substring(FilenameUtils.getPrefixLength(expectedPath) - 1);
+ }
+ Assert.assertEquals("/home/tester/.ssh/id_rsa", FilenameUtils.separatorsToUnix(expectedPath));
Assert.assertEquals(Integer.valueOf(30000), configBuilder.getTimeout(fso));
dataStore.close();
diff --git a/jackrabbit-webapp/pom.xml b/jackrabbit-webapp/pom.xml
index 7c3a23184c0..528ff63baef 100644
--- a/jackrabbit-webapp/pom.xml
+++ b/jackrabbit-webapp/pom.xml
@@ -26,7 +26,7 @@
Expanded Name.
*
*/
+ @Deprecated
public static String getQualifiedName(String localName, Namespace namespace) {
return getExpandedName(localName, namespace);
}
diff --git a/pom.xml b/pom.xml
index cebd0a85f3b..00b7d8ab163 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@