Skip to content

Commit ffce45b

Browse files
authored
Merge pull request #2362 from adamretter/module-classpath-relative-4.x.x
(4.x.x) Improve classpath modules resolution
2 parents 3fbdcd7 + 8bf5b8a commit ffce45b

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 */
@@ -163,6 +158,26 @@ private static String firstPathSegment(final String path) {
163158
.getRawCollectionPath();
164159
}
165160

161+
private static Source getSource_fromClasspath(final String contextPath, final String location) throws IOException {
162+
if (location.startsWith(ClassLoaderSource.PROTOCOL)) {
163+
return new ClassLoaderSource(location);
164+
}
165+
166+
final Path rootPath = Paths.get(contextPath.substring(ClassLoaderSource.PROTOCOL.length()));
167+
168+
// 1) try resolving location as child
169+
final Path childLocation = rootPath.resolve(location);
170+
try {
171+
return new ClassLoaderSource(ClassLoaderSource.PROTOCOL + childLocation.toString().replace('\\', '/'));
172+
} catch (final IOException e) {
173+
// no-op, we will try again below
174+
}
175+
176+
// 2) try resolving location as sibling
177+
final Path siblingLocation = rootPath.resolveSibling(location);
178+
return new ClassLoaderSource(ClassLoaderSource.PROTOCOL + siblingLocation.toString().replace('\\', '/'));
179+
}
180+
166181
/**
167182
* Get the resource source from the database.
168183
*

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

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

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

0 commit comments

Comments
 (0)