Skip to content

Commit acea87b

Browse files
Allow combined modules with lower case namespaces (#2566)
* allow combined modules with lower case names * fix expected case of hello.xqm
1 parent c8883c8 commit acea87b

File tree

4 files changed

+34
-20
lines changed

4 files changed

+34
-20
lines changed

basex-core/src/main/java/org/basex/query/util/pkg/RepoManager.java

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,20 @@ public void delete(final String name) throws QueryException {
127127
repo.delete(pkg);
128128
}
129129

130-
if(pkg.type() == PkgType.COMBINED) {
131-
// delete associated JAR file
132-
final IOFile pkgFile = repo.path(pkgPath.replaceAll("\\.[^.]+$", IO.JARSUFFIX));
133-
if(!pkgFile.delete()) throw REPO_DELETE_X.get(info, pkgPath);
134-
}
135-
136130
// delete package directory or file
137131
final IOFile pkgFile = repo.path(pkgPath);
138132
if(!pkgFile.delete()) throw REPO_DELETE_X.get(info, pkgPath);
139133

140134
// delete directory with extracted jars
141-
final IOFile extDir = pkgFile.parent().resolve('.' + pkg.name().replaceAll("^.*\\.", ""));
135+
final String className = Strings.uriToClasspath(pkg.name().replaceAll("^.*\\.", ""));
136+
final IOFile extDir = pkgFile.parent().resolve('.' + className);
142137
if(!extDir.delete()) throw REPO_DELETE_X.get(info, extDir);
138+
139+
if(pkg.type() == PkgType.COMBINED) {
140+
// delete associated JAR file
141+
final IOFile jarFile = pkgFile.parent().resolve(className + IO.JARSUFFIX);
142+
if(!jarFile.delete()) throw REPO_DELETE_X.get(info, pkgPath);
143+
}
143144
deleted = true;
144145
}
145146
}
@@ -169,6 +170,14 @@ public ArrayList<Pkg> packages() {
169170
}
170171
}
171172
}
173+
// detect combined modules where names have different case
174+
for(final Pkg xqm : new ArrayList<>(map.values())) {
175+
if(xqm.type == PkgType.XQUERY) {
176+
final String jarName = Strings.uriToClasspath(xqm.name);
177+
final Pkg jar = map.get(jarName);
178+
if(jar != null && xqm.merge(jar).type == PkgType.COMBINED) map.remove(jarName);
179+
}
180+
}
172181
return new ArrayList<>(map.values());
173182
}
174183

@@ -208,7 +217,7 @@ private boolean installXQ(final byte[] content, final String path)
208217
try(QueryContext qc = new QueryContext(context)) {
209218
final byte[] uri = qc.parseLibrary(string(content), path).sc.module.uri();
210219
// copy file to rewritten URI file path
211-
return write(Strings.uri2path(string(uri)) + IO.XQMSUFFIX, content);
220+
return write(Strings.uri2path(string(uri)), IO.XQMSUFFIX, content);
212221
}
213222
}
214223

@@ -228,29 +237,33 @@ private boolean installJAR(final byte[] content, final String path)
228237
for(String s; (s = nli.readLine()) != null;) {
229238
// write file to rewritten file path
230239
final Matcher main = MAIN_CLASS.matcher(s);
231-
if(main.find()) return write(main.group(1).replace('.', '/') + IO.JARSUFFIX, content);
240+
if(main.find()) return write(main.group(1), IO.JARSUFFIX, content);
232241
}
233242
}
234243
throw REPO_PARSE_X_X.get(info, path, MANIFEST);
235244
}
236245

237246
/**
238247
* Writes a package to disk.
239-
* @param path file path
248+
* @param pkg package
249+
* @param suffix file suffix
240250
* @param content package content
241251
* @return {@code true} if existing package was replaced
242252
* @throws IOException I/O exception
243253
*/
244-
private boolean write(final String path, final byte[] content) throws IOException {
254+
private boolean write(final String pkg, final String suffix, final byte[] content)
255+
throws IOException {
245256
final IOFile repo = new IOFile(context.soptions.get(StaticOptions.REPOPATH));
246-
final IOFile target = new IOFile(repo, path);
257+
final boolean isJar = suffix.equals(IO.JARSUFFIX);
258+
final String pth = isJar ? Strings.uriToClasspath(pkg) : pkg;
259+
final IOFile target = new IOFile(repo, Strings.uri2path(pth) + suffix);
247260
final boolean exists = target.exists();
248261
if(!target.parent().md()) throw new BaseXException("Could not create %.", target);
249262
target.write(content);
250263

251264
// extract files from JAR package
252-
if(target.hasSuffix(IO.JARSUFFIX)) {
253-
final String pkgPath = path.replaceAll(IO.JARSUFFIX + '$', "");
265+
if(isJar) {
266+
final String pkgPath = Strings.uri2path(pkg);
254267
final String pkgName = target.name().replaceAll(IO.JARSUFFIX + '$', "");
255268
try(JarFile jarFile = new JarFile(target.file())) {
256269
for(final JarEntry entry : Collections.list(jarFile.entries())) {

basex-core/src/test/java/org/basex/query/expr/PackageAPITest.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,33 +289,34 @@ private static void copy(final Path source, final Path target) throws IOExceptio
289289
*/
290290
@Test public void installJar() {
291291
// ensure that all files are installed
292-
execute(new RepoInstall(REPO + "Hello.jar", null));
292+
execute(new RepoInstall(REPO + "hello.jar", null));
293293

294294
final IOFile jar = new IOFile(REPO, "org/basex/modules/Hello.jar");
295-
final IOFile xqm = new IOFile(REPO, "org/basex/modules/Hello.xqm");
295+
final IOFile xqm = new IOFile(REPO, "org/basex/modules/hello.xqm");
296296
assertTrue(jar.exists(), "File not found: " + jar);
297297
assertTrue(xqm.exists(), "File not found: " + xqm);
298298

299299
// run query
300-
String query = "import module namespace h='http://basex.org/modules/Hello';h:hello('Universe')";
300+
String query = "import module namespace h='http://basex.org/modules/hello';h:hello('Universe')";
301301
query(query, "Hello Universe");
302302

303303
// run query, ensure that wrong types will be rejected
304-
query = "import module namespace h='http://basex.org/modules/Hello';h:hello(123)";
304+
query = "import module namespace h='http://basex.org/modules/hello';h:hello(123)";
305305
try(QueryProcessor qp = new QueryProcessor(query, context)) {
306306
qp.value();
307307
} catch(final QueryException ex) {
308308
assertEquals(INVTYPE_X, ex.error());
309309
}
310310

311311
// ensure that all files were deleted
312-
execute(new RepoDelete("org.basex.modules.Hello", null));
312+
execute(new RepoDelete("org.basex.modules.hello", null));
313313
assertFalse(jar.exists(), "File was not deleted:" + jar);
314314
assertFalse(xqm.exists(), "File was not deleted:" + xqm);
315315

316316
// ensure that package can only be deleted once
317317
try {
318-
new RepoDelete("org.basex.modules.Hello", null).execute(context);
318+
new RepoDelete("org.basex.modules.hello", null).execute(context);
319+
fail("RepoDelete did not detect missing package.");
319320
} catch(final BaseXException ex) {
320321
assertTrue(ex.toString().contains(REPO_NOTFOUND_X.toString()));
321322
}
-1.47 KB
Binary file not shown.
1.51 KB
Binary file not shown.

0 commit comments

Comments
 (0)