Merge branch '6.2.x'
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,6 +40,7 @@ import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableSet;
|
||||
@@ -642,13 +643,15 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
}
|
||||
}
|
||||
if (currentPrefix != null) {
|
||||
// A prefix match found, potentially to be turned into a common parent cache entry.
|
||||
if (commonPrefix == null || !commonUnique || currentPrefix.length() > commonPrefix.length()) {
|
||||
commonPrefix = currentPrefix;
|
||||
existingPath = path;
|
||||
}
|
||||
else if (currentPrefix.equals(commonPrefix)) {
|
||||
commonUnique = false;
|
||||
if (checkPathWithinPackage(path.substring(currentPrefix.length()))) {
|
||||
// A prefix match found, potentially to be turned into a common parent cache entry.
|
||||
if (commonPrefix == null || !commonUnique || currentPrefix.length() > commonPrefix.length()) {
|
||||
commonPrefix = currentPrefix;
|
||||
existingPath = path;
|
||||
}
|
||||
else if (currentPrefix.equals(commonPrefix)) {
|
||||
commonUnique = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (actualRootPath == null || path.length() > actualRootPath.length()) {
|
||||
@@ -801,7 +804,7 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
if (separatorIndex == -1) {
|
||||
separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR);
|
||||
}
|
||||
if (separatorIndex != -1) {
|
||||
if (separatorIndex >= 0) {
|
||||
jarFileUrl = urlFile.substring(0, separatorIndex);
|
||||
rootEntryPath = urlFile.substring(separatorIndex + 2); // both separators are 2 chars
|
||||
NavigableSet<String> entriesCache = this.jarEntriesCache.get(jarFileUrl);
|
||||
@@ -828,11 +831,17 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
|
||||
if (con instanceof JarURLConnection jarCon) {
|
||||
// Should usually be the case for traditional JAR files.
|
||||
jarFile = jarCon.getJarFile();
|
||||
jarFileUrl = jarCon.getJarFileURL().toExternalForm();
|
||||
JarEntry jarEntry = jarCon.getJarEntry();
|
||||
rootEntryPath = (jarEntry != null ? jarEntry.getName() : "");
|
||||
closeJarFile = !jarCon.getUseCaches();
|
||||
try {
|
||||
jarFile = jarCon.getJarFile();
|
||||
jarFileUrl = jarCon.getJarFileURL().toExternalForm();
|
||||
JarEntry jarEntry = jarCon.getJarEntry();
|
||||
rootEntryPath = (jarEntry != null ? jarEntry.getName() : "");
|
||||
closeJarFile = !jarCon.getUseCaches();
|
||||
}
|
||||
catch (FileNotFoundException ex) {
|
||||
// Happens in case of cached root directory without specific subdirectory present.
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No JarURLConnection -> need to resort to URL file parsing.
|
||||
@@ -869,7 +878,13 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
}
|
||||
Set<Resource> result = new LinkedHashSet<>(64);
|
||||
NavigableSet<String> entriesCache = new TreeSet<>();
|
||||
for (String entryPath : jarFile.stream().map(JarEntry::getName).sorted().toList()) {
|
||||
Iterator<String> entryIterator = jarFile.stream().map(JarEntry::getName).sorted().iterator();
|
||||
while (entryIterator.hasNext()) {
|
||||
String entryPath = entryIterator.next();
|
||||
int entrySeparatorIndex = entryPath.indexOf(ResourceUtils.JAR_URL_SEPARATOR);
|
||||
if (entrySeparatorIndex >= 0) {
|
||||
entryPath = entryPath.substring(entrySeparatorIndex + ResourceUtils.JAR_URL_SEPARATOR.length());
|
||||
}
|
||||
entriesCache.add(entryPath);
|
||||
if (entryPath.startsWith(rootEntryPath)) {
|
||||
String relativePath = entryPath.substring(rootEntryPath.length());
|
||||
@@ -1099,6 +1114,10 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
|
||||
return (path.startsWith("/") ? path.substring(1) : path);
|
||||
}
|
||||
|
||||
private static boolean checkPathWithinPackage(String path) {
|
||||
return (path.contains("/") && !path.contains(ResourceUtils.JAR_URL_SEPARATOR));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,8 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@@ -66,6 +68,9 @@ public abstract class AbstractJdbcCall {
|
||||
/** List of RefCursor/ResultSet RowMapper objects. */
|
||||
private final Map<String, RowMapper<?>> declaredRowMappers = new LinkedHashMap<>();
|
||||
|
||||
/** Lock for the compilation step. */
|
||||
private final Lock compilationLock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Has this operation been compiled? Compilation means at least checking
|
||||
* that a DataSource or JdbcTemplate has been provided.
|
||||
@@ -278,24 +283,30 @@ public abstract class AbstractJdbcCall {
|
||||
* @throws org.springframework.dao.InvalidDataAccessApiUsageException if the object hasn't
|
||||
* been correctly initialized, for example if no DataSource has been provided
|
||||
*/
|
||||
public final synchronized void compile() throws InvalidDataAccessApiUsageException {
|
||||
if (!isCompiled()) {
|
||||
if (getProcedureName() == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Procedure or Function name is required");
|
||||
}
|
||||
try {
|
||||
this.jdbcTemplate.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new InvalidDataAccessApiUsageException(ex.getMessage());
|
||||
}
|
||||
compileInternal();
|
||||
this.compiled = true;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("SqlCall for " + (isFunction() ? "function" : "procedure") +
|
||||
" [" + getProcedureName() + "] compiled");
|
||||
public final void compile() throws InvalidDataAccessApiUsageException {
|
||||
this.compilationLock.lock();
|
||||
try {
|
||||
if (!isCompiled()) {
|
||||
if (getProcedureName() == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Procedure or Function name is required");
|
||||
}
|
||||
try {
|
||||
this.jdbcTemplate.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new InvalidDataAccessApiUsageException(ex.getMessage());
|
||||
}
|
||||
compileInternal();
|
||||
this.compiled = true;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("SqlCall for " + (isFunction() ? "function" : "procedure") +
|
||||
" [" + getProcedureName() + "] compiled");
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
this.compilationLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
* Copyright 2002-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -181,6 +181,13 @@ public abstract class JdbcTransactionObjectSupport implements SavepointManager,
|
||||
catch (SQLFeatureNotSupportedException ex) {
|
||||
// typically on Oracle - ignore
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
// ignore Microsoft SQLServerException: This operation is not supported.
|
||||
String msg = ex.getMessage();
|
||||
if (msg == null || !msg.contains("not supported")) {
|
||||
throw new TransactionSystemException("Could not explicitly release JDBC savepoint", ex);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new TransactionSystemException("Could not explicitly release JDBC savepoint", ex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user