Skip to content

Commit 99eeb9c

Browse files
authored
Merge pull request #2361 from adamretter/module-classpath-relative-5.0.0
(5.0.0) Improve classpath modules resolution
2 parents 02af2e5 + f0f99c6 commit 99eeb9c

File tree

2 files changed

+70
-8
lines changed

2 files changed

+70
-8
lines changed

src/org/exist/source/SourceFactory.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,9 @@ public class SourceFactory {
7777
Source source = null;
7878

7979
/* resource: */
80-
if (location.startsWith(ClassLoaderSource.PROTOCOL)) {
81-
source = new ClassLoaderSource(location);
82-
} else if (contextPath != null && contextPath.startsWith(ClassLoaderSource.PROTOCOL)) {
83-
// Pretend it is a file on the local system so we can resolve it easily with URL() class.
84-
final String conPathNoProtocol = contextPath.replace(ClassLoaderSource.PROTOCOL, "file://");
85-
String resolvedURL = new URL(new URL(conPathNoProtocol), location).toString();
86-
resolvedURL = resolvedURL.replaceFirst("file://", ClassLoaderSource.PROTOCOL);
87-
source = new ClassLoaderSource(resolvedURL);
80+
if (location.startsWith(ClassLoaderSource.PROTOCOL)
81+
|| (contextPath != null && contextPath.startsWith(ClassLoaderSource.PROTOCOL))) {
82+
source = getSource_fromClasspath(contextPath, location);
8883
}
8984

9085
/* xmldb */
@@ -154,6 +149,26 @@ private static String firstPathSegment(final String path) {
154149
.getRawCollectionPath();
155150
}
156151

152+
private static Source getSource_fromClasspath(final String contextPath, final String location) throws IOException {
153+
if (location.startsWith(ClassLoaderSource.PROTOCOL)) {
154+
return new ClassLoaderSource(location);
155+
}
156+
157+
final Path rootPath = Paths.get(contextPath.substring(ClassLoaderSource.PROTOCOL.length()));
158+
159+
// 1) try resolving location as child
160+
final Path childLocation = rootPath.resolve(location);
161+
try {
162+
return new ClassLoaderSource(ClassLoaderSource.PROTOCOL + childLocation.toString().replace('\\', '/'));
163+
} catch (final IOException e) {
164+
// no-op, we will try again below
165+
}
166+
167+
// 2) try resolving location as sibling
168+
final Path siblingLocation = rootPath.resolveSibling(location);
169+
return new ClassLoaderSource(ClassLoaderSource.PROTOCOL + siblingLocation.toString().replace('\\', '/'));
170+
}
171+
157172
/**
158173
* Get the resource source from the database.
159174
*

test/src/org/exist/source/SourceFactoryTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,53 @@ public void getSourceFromResource_contextAbsoluteFileUrl_locationRelativeUrl_bas
133133
assertEquals(getClass().getResource(location), relativeSource.getKey());
134134
}
135135

136+
@Test
137+
public void getSourceFromResource_contextFolderUrl_locationRelative() throws IOException, PermissionDeniedException {
138+
final String contextPath = "resource:org/exist/source";
139+
final String location = "library.xqm";
140+
141+
final Source source = SourceFactory.getSource(null, contextPath, location, false);
142+
143+
assertTrue(source instanceof ClassLoaderSource);
144+
assertEquals(getClass().getResource("library.xqm"), source.getKey());
145+
}
146+
147+
@Test
148+
public void getSourceFromResource_contextFolderUrl_locationAbsoluteUrl() throws IOException, PermissionDeniedException {
149+
final String contextPath = "resource:org/exist/source";
150+
final String location = "resource:org/exist/source/library.xqm";
151+
152+
final Source source = SourceFactory.getSource(null, contextPath, location, false);
153+
154+
assertTrue(source instanceof ClassLoaderSource);
155+
assertEquals(getClass().getResource("library.xqm"), source.getKey());
156+
}
157+
158+
@Test
159+
public void getSourceFromResource_contextFolderUrl_locationRelativeUrl() throws IOException, PermissionDeniedException {
160+
final String contextPath = "resource:org/exist/source";
161+
final String location = "library.xqm";
162+
163+
final Source source = SourceFactory.getSource(null, contextPath, location, false);
164+
165+
assertTrue(source instanceof ClassLoaderSource);
166+
assertEquals(getClass().getResource("library.xqm"), source.getKey());
167+
}
168+
169+
@Test
170+
public void getSourceFromResource_contextFolderUrl_locationRelativeUrl_basedOnSource() throws IOException, PermissionDeniedException {
171+
final String contextPath = "resource:org/exist/source";
172+
final String location = "library.xqm";
173+
174+
final Source mainSource = SourceFactory.getSource(null, "", contextPath, false);
175+
assertTrue(mainSource instanceof ClassLoaderSource);
176+
177+
final Source relativeSource = SourceFactory.getSource(null, ((ClassLoaderSource)mainSource).getSource(), location, false);
178+
179+
assertTrue(relativeSource instanceof ClassLoaderSource);
180+
assertEquals(getClass().getResource(location), relativeSource.getKey());
181+
}
182+
136183
@Test
137184
public void getSourceFromXmldb_noContext() throws IOException, PermissionDeniedException {
138185
final String contextPath = null;

0 commit comments

Comments
 (0)