JPA persistence.xml files may use jar-file entries relative to the unit root (as per the JPA spec)
Issue: SPR-9797
This commit is contained in:
@@ -173,12 +173,11 @@ class PersistenceUnitReader {
|
||||
|
||||
Element persistence = document.getDocumentElement();
|
||||
String version = persistence.getAttribute(PERSISTENCE_VERSION);
|
||||
URL unitRootURL = determinePersistenceUnitRootUrl(resource);
|
||||
URL rootUrl = determinePersistenceUnitRootUrl(resource);
|
||||
|
||||
List<Element> units = DomUtils.getChildElementsByTagName(persistence, PERSISTENCE_UNIT);
|
||||
for (Element unit : units) {
|
||||
SpringPersistenceUnitInfo info = parsePersistenceUnitInfo(unit, version);
|
||||
info.setPersistenceUnitRootUrl(unitRootURL);
|
||||
infos.add(info);
|
||||
infos.add(parsePersistenceUnitInfo(unit, version, rootUrl));
|
||||
}
|
||||
|
||||
return infos;
|
||||
@@ -193,46 +192,52 @@ class PersistenceUnitReader {
|
||||
*/
|
||||
protected URL determinePersistenceUnitRootUrl(Resource resource) throws IOException {
|
||||
URL originalURL = resource.getURL();
|
||||
String urlToString = originalURL.toExternalForm();
|
||||
|
||||
// If we get an archive, simply return the jar URL (section 6.2 from the JPA spec)
|
||||
if (ResourceUtils.isJarURL(originalURL)) {
|
||||
return ResourceUtils.extractJarFileURL(originalURL);
|
||||
}
|
||||
|
||||
else {
|
||||
// check META-INF folder
|
||||
if (!urlToString.contains(META_INF)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(resource.getFilename() +
|
||||
" should be located inside META-INF directory; cannot determine persistence unit root URL for " +
|
||||
resource);
|
||||
}
|
||||
return null;
|
||||
// check META-INF folder
|
||||
String urlToString = originalURL.toExternalForm();
|
||||
if (!urlToString.contains(META_INF)) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(resource.getFilename() +
|
||||
" should be located inside META-INF directory; cannot determine persistence unit root URL for " +
|
||||
resource);
|
||||
}
|
||||
if (urlToString.lastIndexOf(META_INF) == urlToString.lastIndexOf('/') - (1 + META_INF.length())) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(resource.getFilename() +
|
||||
" is not located in the root of META-INF directory; cannot determine persistence unit root URL for " +
|
||||
resource);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String persistenceUnitRoot = urlToString.substring(0, urlToString.lastIndexOf(META_INF));
|
||||
return new URL(persistenceUnitRoot);
|
||||
return null;
|
||||
}
|
||||
if (urlToString.lastIndexOf(META_INF) == urlToString.lastIndexOf('/') - (1 + META_INF.length())) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(resource.getFilename() +
|
||||
" is not located in the root of META-INF directory; cannot determine persistence unit root URL for " +
|
||||
resource);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String persistenceUnitRoot = urlToString.substring(0, urlToString.lastIndexOf(META_INF));
|
||||
if (persistenceUnitRoot.endsWith("/")) {
|
||||
persistenceUnitRoot = persistenceUnitRoot.substring(0, persistenceUnitRoot.length() - 1);
|
||||
}
|
||||
return new URL(persistenceUnitRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the unit info DOM element.
|
||||
*/
|
||||
protected SpringPersistenceUnitInfo parsePersistenceUnitInfo(Element persistenceUnit, String version) throws IOException {
|
||||
protected SpringPersistenceUnitInfo parsePersistenceUnitInfo(Element persistenceUnit, String version, URL rootUrl)
|
||||
throws IOException {
|
||||
|
||||
SpringPersistenceUnitInfo unitInfo = new SpringPersistenceUnitInfo();
|
||||
|
||||
// set JPA version (1.0 or 2.0)
|
||||
unitInfo.setPersistenceXMLSchemaVersion(version);
|
||||
|
||||
// set persistence unit root URL
|
||||
unitInfo.setPersistenceUnitRootUrl(rootUrl);
|
||||
|
||||
// set unit name
|
||||
unitInfo.setPersistenceUnitName(persistenceUnit.getAttribute(UNIT_NAME).trim());
|
||||
|
||||
@@ -277,10 +282,10 @@ class PersistenceUnitReader {
|
||||
unitInfo.setValidationModeName(validationMode);
|
||||
}
|
||||
|
||||
parseProperties(persistenceUnit, unitInfo);
|
||||
parseManagedClasses(persistenceUnit, unitInfo);
|
||||
parseMappingFiles(persistenceUnit, unitInfo);
|
||||
parseJarFiles(persistenceUnit, unitInfo);
|
||||
parseClass(persistenceUnit, unitInfo);
|
||||
parseProperty(persistenceUnit, unitInfo);
|
||||
|
||||
return unitInfo;
|
||||
}
|
||||
@@ -289,7 +294,7 @@ class PersistenceUnitReader {
|
||||
* Parse the <code>property</code> XML elements.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void parseProperty(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||
protected void parseProperties(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||
Element propRoot = DomUtils.getChildElementByTagName(persistenceUnit, PROPERTIES);
|
||||
if (propRoot == null) {
|
||||
return;
|
||||
@@ -306,7 +311,7 @@ class PersistenceUnitReader {
|
||||
* Parse the <code>class</code> XML elements.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void parseClass(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||
protected void parseManagedClasses(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) {
|
||||
List<Element> classes = DomUtils.getChildElementsByTagName(persistenceUnit, MANAGED_CLASS_NAME);
|
||||
for (Element element : classes) {
|
||||
String value = DomUtils.getTextValue(element).trim();
|
||||
@@ -315,23 +320,6 @@ class PersistenceUnitReader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the <code>jar-file</code> XML elements.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void parseJarFiles(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) throws IOException {
|
||||
List<Element> jars = DomUtils.getChildElementsByTagName(persistenceUnit, JAR_FILE_URL);
|
||||
for (Element element : jars) {
|
||||
String value = DomUtils.getTextValue(element).trim();
|
||||
if (StringUtils.hasText(value)) {
|
||||
Resource[] resources = this.resourcePatternResolver.getResources(value);
|
||||
for (Resource resource : resources) {
|
||||
unitInfo.addJarFileUrl(resource.getURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the <code>mapping-file</code> XML elements.
|
||||
*/
|
||||
@@ -346,4 +334,36 @@ class PersistenceUnitReader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the <code>jar-file</code> XML elements.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void parseJarFiles(Element persistenceUnit, SpringPersistenceUnitInfo unitInfo) throws IOException {
|
||||
List<Element> jars = DomUtils.getChildElementsByTagName(persistenceUnit, JAR_FILE_URL);
|
||||
for (Element element : jars) {
|
||||
String value = DomUtils.getTextValue(element).trim();
|
||||
if (StringUtils.hasText(value)) {
|
||||
Resource[] resources = this.resourcePatternResolver.getResources(value);
|
||||
boolean found = false;
|
||||
for (Resource resource : resources) {
|
||||
if (resource.exists()) {
|
||||
found = true;
|
||||
unitInfo.addJarFileUrl(resource.getURL());
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// relative to the persistence unit root, according to the JPA spec
|
||||
URL rootUrl = unitInfo.getPersistenceUnitRootUrl();
|
||||
if (rootUrl != null) {
|
||||
unitInfo.addJarFileUrl(new URL(rootUrl, value));
|
||||
}
|
||||
else {
|
||||
logger.warn("Cannot resolve jar-file entry [" + value + "] in persistence unit '" +
|
||||
unitInfo.getPersistenceUnitName() + "' without root URL");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user