Skip to content

Commit

Permalink
Create two versions: a "standalone" version and a normal version
Browse files Browse the repository at this point in the history
Only the "standalone" version includes the binaries and tables.
  • Loading branch information
bertfrees committed Jun 6, 2019
1 parent 2ecdcc5 commit 6066381
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 151 deletions.
45 changes: 33 additions & 12 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,23 +134,18 @@
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<!--
Add the binaries to the test classpath in order to make the tests work. Adding them to
the (standalone) JAR is done in the maven-bundle-plugin.
-->
<execution>
<id>add-resources</id>
<phase>generate-resources</phase>
<id>add-test-resources</id>
<phase>generate-test-resources</phase>
<goals>
<goal>add-resource</goal>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>target/dependency/share/liblouis/tables</directory>
<targetPath>org/liblouis/resource-files/tables</targetPath>
</resource>
<!--
For MacOS include only 64-bit version because JNA only looks in one path, namely
/darwin/liblouis.dylib. The alternative is to build a multi-architecture binary,
or to check the architecture in Louis.java and specify an exact path in the JAR.
-->
<resource>
<directory>target/dependency/lib/x86_64-MacOSX-gpp/shared</directory>
<includes>
Expand Down Expand Up @@ -194,6 +189,10 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<!-- part of integration-test -->
<exclude>org/liblouis/DefaultTablesTest.java</exclude>
</excludes>
<forkMode>pertest</forkMode>
<systemPropertyVariables>
<jna.nosys>true</jna.nosys>
Expand All @@ -212,6 +211,28 @@
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
<executions>
<execution>
<id>bundle-standalone</id>
<phase>package</phase>
<goals>
<goal>bundle</goal>
</goals>
<configuration>
<classifier>standalone</classifier>
<instructions>
<Include-Resource>
org/liblouis/resource-files/tables=target/dependency/share/liblouis/tables,
darwin/liblouis.dylib=target/dependency/lib/x86_64-MacOSX-gpp/shared/liblouis.dylib,
linux-x86/liblouis.so=target/dependency/lib/i386-Linux-gpp/shared/liblouis.so,
linux-x86-64/liblouis.so=target/dependency/lib/amd64-Linux-gpp/shared/liblouis.so,
win32-x86/liblouis.dll=target/dependency/bin/i686-w64-mingw32-gpp/liblouis.dll,
win32-x86-64/liblouis.dll=target/dependency/bin/x86_64-w64-mingw32-gpp/liblouis.dll
</Include-Resource>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
<!--
run the same tests but from another project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test-jar</groupId>
<artifactId>test-jar</artifactId>
<groupId>test-standalone-jar</groupId>
<artifactId>test-standalone-jar</artifactId>
<version>0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.liblouis</groupId>
<artifactId>liblouis-java</artifactId>
<version>${liblouis-java.version}</version>
<classifier>standalone</classifier>
</dependency>
<dependency>
<groupId>junit</groupId>
Expand Down
152 changes: 152 additions & 0 deletions src/main/java/org/liblouis/EmbeddedTableResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package org.liblouis;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.BasicFileAttributeView;
import static java.nio.file.Files.walkFileTree;
import java.nio.file.Files;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.NoSuchFileException;
import java.nio.file.SimpleFileVisitor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.liblouis.Louis.asFile;
import static org.liblouis.Louis.asURL;

/**
* Default table resolver implementation that looks for tables inside this JAR and falls back to the file system
*/
class EmbeddedTableResolver implements TableResolver {

private final Map<String,URL> tables;
private final Set<String> tablePaths;
private final Map<String,URL> aggregatorTables = new HashMap<String,URL>();

EmbeddedTableResolver(org.slf4j.Logger logger) {
tables = new HashMap<String,URL>();
for (String table : listResources("org/liblouis/resource-files/tables"))
tables.put(table, Louis.class.getResource("resource-files/tables/" + table));
tablePaths = Collections.unmodifiableSet(tables.keySet());
logger.debug("Using default tables");
logger.trace("Table files: " + tablePaths);
}

public URL resolve(String table, URL base) {
// if we are resolving an include rule from a generated aggregator table, resolve without base
if (aggregatorTables.containsValue(base))
base = null;
if (base == null || tables.containsValue(base)) {
if (tables.containsKey(table))
return tables.get(table);
}
// if it is a comma separated table list, create a single file that includes all the sub-tables
if (base == null && table.contains(",")) {
if (aggregatorTables.containsKey(table))
return aggregatorTables.get(table);
StringBuilder b = new StringBuilder();
for (String s : table.split(","))
b.append("include ").append(s.replaceAll("\\\\", "\\\\\\\\")).append('\n');
InputStream in = new ByteArrayInputStream(b.toString().getBytes(StandardCharsets.UTF_8));
try {
File f = File.createTempFile("liblouis-java-", ".tbl");
f.delete();
Files.copy(in, f.toPath());
f.deleteOnExit();
URL u = asURL(f);
aggregatorTables.put(table, u);
return u;
} catch (IOException e) {
throw new RuntimeException(e); // should not happen
}
}
// try file system
if (base != null && base.toString().startsWith("file:")) {
File f = base.toString().endsWith("/")
? new File(asFile(base), table)
: new File(asFile(base).getParentFile(), table);
if (f.exists())
return asURL(f);
} else if (base == null) {
File f = new File(table);
if (f.exists())
return asURL(f);
}
return null; // table cannot be resolved
}

public Set<String> list() {
return tablePaths;
}

private static Iterable<String> listResources(final String directory) {
File jarFile = asFile(Louis.class.getProtectionDomain().getCodeSource().getLocation());
if (!jarFile.exists())
throw new RuntimeException();
else if (jarFile.isDirectory()) {
File d = new File(jarFile, directory);
if (!d.exists())
throw new RuntimeException("directory does not exist");
else if (!d.isDirectory())
throw new RuntimeException("is not a directory");
else {
List<String> resources = new ArrayList<String>();
for (File f : d.listFiles())
resources.add(f.getName() + (f.isDirectory() ? "/" : ""));
return resources; }}
else {
FileSystem fs; {
try {
fs = FileSystems.newFileSystem(URI.create("jar:" + jarFile.toURI()),
Collections.<String,Object>emptyMap()); }
catch (IOException e) {
throw new RuntimeException(e); }}
try {
Path d = fs.getPath("/" + directory);
BasicFileAttributes a; {
try {
a = Files.getFileAttributeView(d, BasicFileAttributeView.class).readAttributes(); }
catch (NoSuchFileException e) {
throw new RuntimeException("directory does not exist"); }
catch (FileSystemNotFoundException e) {
throw new RuntimeException(e); }
catch (IOException e) {
throw new RuntimeException(e); }}
if (!a.isDirectory())
throw new RuntimeException("is not a directory");
final List<String> resources = new ArrayList<String>();
try {
walkFileTree(d, EnumSet.noneOf(FileVisitOption.class), 1, new SimpleFileVisitor<Path>() {
public FileVisitResult visitFile(Path f, BasicFileAttributes _) throws IOException {
resources.add(""+f.getFileName());
return FileVisitResult.CONTINUE; }}); }
catch (NoSuchFileException e) {
throw new RuntimeException(e); }
catch (IOException e) {
throw new RuntimeException(e); }
return resources; }
finally {
try {
fs.close(); }
catch (IOException e) {
throw new RuntimeException(e); }
}
}
}
}
Loading

0 comments on commit 6066381

Please sign in to comment.