diff --git a/pom.xml b/pom.xml
index 3028c75..3472bdc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,327 +1,318 @@
-
-
- 4.0.0
-
- org.ghost4j
- ghost4j
- jar
- 1.0.5
-
- Ghost4J
- Java wrapper for Ghostscript API. Official ${project.name} build of the
- ${project.version} release
-
- http://www.ghost4j.org
-
-
-
- ossrh
- https://oss.sonatype.org/content/repositories/snapshots
-
-
- ossrh
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
-
-
-
-
-
- GNU LESSER GENERAL PUBLIC LICENSE
- http://www.gnu.org/licenses/lgpl-3.0-standalone.html
-
-
-
-
- scm:git:https://github.com/zippy1978/ghost4j.git
- scm:git:https://github.com/zippy1978/ghost4j.git
- http://www.github.com/zippy1978/ghost4j
- HEAD
-
-
-
- GitHub
- https://github.com/zippy1978/ghost4j/issues
-
-
-
- UTF-8
-
-
-
-
- Gilles Grousset
- gi.grousset@gmail.com
- http://zippy1978.tumblr.com
-
-
-
-
-
- Dave Smith
- dave.smith@candata.com
- CANdata Systems
- http://www.candata.com
-
-
- Michael Sliwak
- msliwak@googlemail.com
-
-
- squallssck
- http://techfee.com
- squallssck@gmail.com
-
-
- BusyBusinessCat
- https://github.com/BusyBusinessCat
-
-
- O.J. Sousa Rodrigues
- osoriojaques@gmail.com
-
- developer
- contributor
-
- +1
-
-
-
-
-
- junit
- junit
- 4.11
- test
-
-
- net.java.dev.jna
- jna
- 4.1.0
-
-
- org.slf4j
- slf4j-api
- 1.7.32
-
-
- commons-beanutils
- commons-beanutils
- 1.9.4
-
-
- org.apache.xmlgraphics
- xmlgraphics-commons
- 2.3
-
-
- com.lowagie
- itext
- 2.1.7
-
-
- bcmail-jdk14
- bouncycastle
-
-
- bcmail-jdk14
- org.bouncycastle
-
-
- bcprov-jdk14
- bouncycastle
-
-
- bcprov-jdk14
- org.bouncycastle
-
-
- bctsp-jdk14
- org.bouncycastle
-
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-project-info-reports-plugin
- 2.4
-
-
-
- dependencies
- project-team
- license
- scm
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.10.3
-
- maven
- -Xdoclint:none
-
-
-
-
-
-
-
-
-
- org.apache.maven.wagon
- wagon-ssh
- 2.2
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.0
-
-
- 1.7
-
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 2.1.2
-
-
- verify
-
- jar-no-fork
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.8.1
-
- maven
- -Xdoclint:none
-
-
-
- verify
-
- jar
-
-
-
-
-
-
- maven-assembly-plugin
-
-
- src/main/assembly/dist.xml
-
-
-
-
-
- com.github.github
- site-maven-plugin
- 0.12
-
- Official ${project.name} build
- github.com
- ${project.artifactId}
- zippy1978
-
-
-
-
- site
-
- site
-
-
-
-
-
- org.apache.maven.plugins
- maven-site-plugin
- 3.0
-
-
- com.anasoft.os
- m2st-doxia-macros
- 2.0
-
-
- org.apache.maven.doxia
- doxia-module-markdown
- 1.7
-
-
-
- UTF-8
- UTF-8
-
-
- org.apache.maven.plugins
- maven-project-info-reports-plugin
- 2.5
-
-
-
- dependencies
- project-team
- issue-tracking
- license
- scm
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.7
-
-
- org.apache.maven.plugins
- maven-surefire-report-plugin
- 2.6
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-gpg-plugin
- 1.6
-
-
- sign-artifacts
- verify
-
- sign
-
-
-
-
-
-
-
-
-
-
+
+
+ 4.0.0
+
+ org.ghost4j
+ org.ghost4j
+ jar
+ 1.0.5
+
+ Ghost4J
+ Java wrapper for Ghostscript API. Official ${project.name} build of the ${project.version} release
+ http://www.ghost4j.org
+
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+ ossrh
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
+
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ http://www.gnu.org/licenses/lgpl-3.0-standalone.html
+
+
+
+
+ scm:git:https://github.com/zippy1978/ghost4j.git
+ scm:git:https://github.com/zippy1978/ghost4j.git
+ http://www.github.com/zippy1978/ghost4j
+ HEAD
+
+
+
+ GitHub
+ https://github.com/zippy1978/ghost4j/issues
+
+
+
+ UTF-8
+
+
+
+
+ Gilles Grousset
+ gi.grousset@gmail.com
+ http://zippy1978.tumblr.com
+
+
+
+
+
+ Dave Smith
+ dave.smith@candata.com
+ CANdata Systems
+ http://www.candata.com
+
+
+ Michael Sliwak
+ msliwak@googlemail.com
+
+
+ squallssck
+ http://techfee.com
+ squallssck@gmail.com
+
+
+ BusyBusinessCat
+ https://github.com/BusyBusinessCat
+
+
+ O.J. Sousa Rodrigues
+ osoriojaques@gmail.com
+
+ developer
+ contributor
+
+ +1
+
+
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ org.slf4j
+ slf4j-jdk14
+ 2.0.6
+ test
+
+
+ net.java.dev.jna
+ jna
+ 5.13.0
+
+
+ org.slf4j
+ slf4j-api
+ 2.0.6
+
+
+ commons-beanutils
+ commons-beanutils
+ 1.9.4
+
+
+ org.apache.xmlgraphics
+ xmlgraphics-commons
+ 2.8
+
+
+ com.lowagie
+ itext
+ 2.1.7
+
+
+ bcmail-jdk14
+ bouncycastle
+
+
+ bcmail-jdk14
+ org.bouncycastle
+
+
+ bcprov-jdk14
+ bouncycastle
+
+
+ bcprov-jdk14
+ org.bouncycastle
+
+
+ bctsp-jdk14
+ org.bouncycastle
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+ 2.4
+
+
+
+ dependencies
+ project-team
+ license
+ scm
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.3
+
+ maven
+ -Xdoclint:none
+
+
+
+
+
+
+
+
+ org.apache.maven.wagon
+ wagon-ssh
+ 2.2
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.0
+
+
+ 17
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.1.2
+
+
+ verify
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.8.1
+
+ maven
+ -Xdoclint:none
+
+
+
+ verify
+
+ jar
+
+
+
+
+
+ maven-assembly-plugin
+
+
+ src/main/assembly/dist.xml
+
+
+
+
+ com.github.github
+ site-maven-plugin
+ 0.12
+
+ Official ${project.name} build
+ github.com
+ ${project.artifactId}
+ zippy1978
+
+
+
+ site
+
+ site
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 3.0
+
+
+ com.anasoft.os
+ m2st-doxia-macros
+ 2.0
+
+
+ org.apache.maven.doxia
+ doxia-module-markdown
+ 1.7
+
+
+
+ UTF-8
+ UTF-8
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+ 2.5
+
+
+
+ dependencies
+ project-team
+ issue-tracking
+ license
+ scm
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.7
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+ 2.6
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/ghost4j/AbstractComponent.java b/src/main/java/org/ghost4j/AbstractComponent.java
index ae5dd44..a304949 100644
--- a/src/main/java/org/ghost4j/AbstractComponent.java
+++ b/src/main/java/org/ghost4j/AbstractComponent.java
@@ -25,139 +25,138 @@
*/
public abstract class AbstractComponent implements Component {
- /**
- * Holds available device names of the Ghostscript interperter.
- */
- private static final List AVAILABLE_DEVICE_NAMES = new ArrayList();
-
- /**
- * Classes of Document supported by the converter.
- */
- protected Class>[] supportedDocumentClasses;
-
- /**
- * Assert a given document instance is supported by the converter
- *
- * @param document
- * @throws DocumentException
- * When document is not supported
- */
- protected void assertDocumentSupported(Document document)
- throws DocumentException {
-
- if (supportedDocumentClasses != null) {
-
- for (Class> clazz : supportedDocumentClasses) {
- if (clazz.getName().equals(document.getClass().getName())) {
- // supported
- return;
+ /**
+ * Holds available device names of the Ghostscript interperter.
+ */
+ private static final List AVAILABLE_DEVICE_NAMES = new ArrayList();
+
+ /**
+ * Classes of Document supported by the converter.
+ */
+ protected Class>[] supportedDocumentClasses;
+
+ /**
+ * Assert a given document instance is supported by the converter
+ *
+ * @param document
+ * @throws DocumentException
+ * When document is not supported
+ */
+ protected void assertDocumentSupported(Document document)
+ throws DocumentException {
+
+ if (supportedDocumentClasses != null) {
+
+ for (Class> clazz : supportedDocumentClasses) {
+ if (clazz.getName().equals(document.getClass().getName())) {
+ // supported
+ return;
+ }
+ }
+
+ // document not supported
+ throw new DocumentException("Documents of class "
+ + document.getClass().getName()
+ + " are not supported by the component");
}
- }
-
- // document not supported
- throw new DocumentException("Documents of class "
- + document.getClass().getName()
- + " are not supported by the component");
- }
- }
-
- public void copySettings(Map settings)
- throws IllegalAccessException, InvocationTargetException {
-
- if (settings.get("maxProcessCount") != null) {
- settings.remove("maxProcessCount");
}
- BeanUtils.populate(this, settings);
+ public void copySettings(Map settings)
+ throws IllegalAccessException, InvocationTargetException {
- }
-
- @SuppressWarnings("unchecked")
- public Map extractSettings() throws IllegalAccessException,
- InvocationTargetException, NoSuchMethodException {
+ if (settings.get("maxProcessCount") != null) {
+ settings.remove("maxProcessCount");
+ }
- Map result = PropertyUtils.describe(this);
+ BeanUtils.populate(this, settings);
- if (result.get("maxProcessCount") != null) {
- result.remove("maxProcessCount");
}
- return result;
- }
-
- /**
- * Checks if a given device is supported by the current Ghostscript version.
- *
- * @param deviceName
- * Device name
- * @return true/false
- * @throws GhostscriptException
- */
- protected synchronized boolean isDeviceSupported(String deviceName)
- throws GhostscriptException {
-
- // if no device names know yet : query the interpreter
- if (AVAILABLE_DEVICE_NAMES.size() == 0) {
+ public Map extractSettings() throws IllegalAccessException,
+ InvocationTargetException, NoSuchMethodException {
- // get Ghostscript instance
- Ghostscript gs = Ghostscript.getInstance();
+ Map result = PropertyUtils.describe(this);
- // retrieve available devices
- try {
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- String[] gsArgs = { "-dQUIET", "-dNOPAUSE", "-dBATCH",
- "-dNODISPLAY" };
-
- synchronized (gs) {
- gs.setStdOut(baos);
- gs.initialize(gsArgs);
- gs.runString("devicenames ==");
- gs.exit();
+ if (result.get("maxProcessCount") != null) {
+ result.remove("maxProcessCount");
}
- // result string
- String result = new String(baos.toByteArray());
- String[] lines = result.split("\n");
- int i = 0;
- while (!lines[i].startsWith("[")) {
- i++;
- }
- String[] deviceNames = lines[i].substring(1,
- lines[i].length() - 2).split("/");
- for (String string : deviceNames) {
- AVAILABLE_DEVICE_NAMES.add(string.trim());
+ return result;
+ }
+
+ /**
+ * Checks if a given device is supported by the current Ghostscript version.
+ *
+ * @param deviceName
+ * Device name
+ * @return true/false
+ * @throws GhostscriptException
+ */
+ protected synchronized boolean isDeviceSupported(String deviceName)
+ throws GhostscriptException {
+
+ // if no device names know yet : query the interpreter
+ if (AVAILABLE_DEVICE_NAMES.size() == 0) {
+
+ // get Ghostscript instance
+ Ghostscript gs = Ghostscript.getInstance();
+
+ // retrieve available devices
+ try {
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ String[] gsArgs = { "-dQUIET", "-dNOPAUSE", "-dBATCH",
+ "-dNODISPLAY" };
+
+ synchronized (gs) {
+ gs.setStdOut(baos);
+ gs.initialize(gsArgs);
+ gs.runString("devicenames ==");
+ gs.exit();
+ }
+
+ // result string
+ String result = new String(baos.toByteArray());
+ String[] lines = result.split("\n");
+ int i = 0;
+ while (!lines[i].startsWith("[")) {
+ i++;
+ }
+ String[] deviceNames = lines[i].substring(1,
+ lines[i].length() - 2).split("/");
+ for (String string : deviceNames) {
+ AVAILABLE_DEVICE_NAMES.add(string.trim());
+ }
+
+ } catch (GhostscriptException e) {
+ throw e;
+ } finally {
+ Ghostscript.deleteInstance();
+ }
}
- } catch (GhostscriptException e) {
- throw e;
- } finally {
- Ghostscript.deleteInstance();
- }
+ return AVAILABLE_DEVICE_NAMES.contains(deviceName);
}
- return AVAILABLE_DEVICE_NAMES.contains(deviceName);
- }
-
- /**
- * Asserts a given device is supported by the current Ghostscript version.
- *
- * @param deviceName
- * Device name
- * @throws GhostscriptException
- * Thrown is device is not supported, or call to the interpreter
- * fails
- */
- protected void assertDeviceSupported(String deviceName)
- throws GhostscriptException {
-
- if (!this.isDeviceSupported(deviceName)) {
- throw new GhostscriptException(
- "device "
- + deviceName
- + " is not supported by the current Ghostscript interpreter.");
+ /**
+ * Asserts a given device is supported by the current Ghostscript version.
+ *
+ * @param deviceName
+ * Device name
+ * @throws GhostscriptException
+ * Thrown is device is not supported, or call to the interpreter
+ * fails
+ */
+ protected void assertDeviceSupported(String deviceName)
+ throws GhostscriptException {
+
+ if (!this.isDeviceSupported(deviceName)) {
+ throw new GhostscriptException(
+ "device "
+ + deviceName
+ + " is not supported by the current Ghostscript interpreter.");
+ }
}
- }
}
diff --git a/src/main/java/org/ghost4j/AbstractRemoteComponent.java b/src/main/java/org/ghost4j/AbstractRemoteComponent.java
index df4c56e..2198027 100644
--- a/src/main/java/org/ghost4j/AbstractRemoteComponent.java
+++ b/src/main/java/org/ghost4j/AbstractRemoteComponent.java
@@ -25,125 +25,125 @@
*/
public abstract class AbstractRemoteComponent extends AbstractComponent {
- /**
- * Logger used to log messages.
- */
- private Logger logger = LoggerFactory.getLogger(AbstractRemoteComponent.class.getName());
-
- /**
- * Maximum number of parallel processes allowed for the converter.
- */
- protected int maxProcessCount = 0;
- /**
- * Number of parallel processes running.
- */
- protected int processCount = 0;
-
- /**
- * Wait for a process to get free.
- */
- public void waitForFreeProcess() {
-
- while (processCount >= maxProcessCount) {
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- // nothing
- }
+ /**
+ * Logger used to log messages.
+ */
+ private Logger logger = LoggerFactory.getLogger(AbstractRemoteComponent.class.getName());
+
+ /**
+ * Maximum number of parallel processes allowed for the converter.
+ */
+ protected int maxProcessCount = 0;
+ /**
+ * Number of parallel processes running.
+ */
+ protected int processCount = 0;
+
+ /**
+ * Wait for a process to get free.
+ */
+ public void waitForFreeProcess() {
+
+ while (processCount >= maxProcessCount) {
+ try {
+ Thread.sleep(1000);
+ } catch (Exception e) {
+ // nothing
+ }
+ }
}
- }
-
- /**
- * Checks if the current class has a proper 'main' method declared.
- *
- * @return true id 'main' method was found
- */
- public boolean isStandAloneModeSupported() {
-
- try {
- this.getClass().getMethod("main", String[].class);
- return true;
- } catch (Exception ex) {
- return false;
+
+ /**
+ * Checks if the current class has a proper 'main' method declared.
+ *
+ * @return true id 'main' method was found
+ */
+ public boolean isStandAloneModeSupported() {
+
+ try {
+ this.getClass().getMethod("main", String[].class);
+ return true;
+ } catch (Exception ex) {
+ return false;
+ }
+ }
+
+ /**
+ * Start a remote component server on a Javafork object.
+ *
+ * @param fork
+ * JavaFork used to run the server
+ * @return Port number used by the server
+ * @throws IOException
+ */
+ protected synchronized int startRemoteServer(JavaFork fork)
+ throws IOException {
+
+ // get free TCP port to run Cajo server on
+ int cajoPort = NetworkUtil.findAvailablePort("127.0.0.1", 5000, 6000);
+ if (cajoPort == 0) {
+ throw new IOException("No port available to start remote component");
+ }
+ logger.debug(Thread.currentThread() + " uses " + cajoPort
+ + " as server port");
+
+ // add extra environment variables to JVM
+ Map environment = new HashMap();
+ // Cajo port
+ environment.put("cajo.port", String.valueOf(cajoPort));
+ fork.setEnvironment(environment);
+
+ // start new JVM with current converter
+ fork.start();
+
+ // wait for the remote JVM to start
+ NetworkUtil.waitUntilPortListening("127.0.0.1", cajoPort, 10000);
+
+ return cajoPort;
+ }
+
+ /**
+ * Get a client proxy of a remote component
+ *
+ * @param serverPort
+ * Server port
+ * @param clazz
+ * Interface of the proxy
+ * @return The proxy object
+ * @throws Exception
+ */
+ protected synchronized Object getRemoteComponent(int serverPort,
+ Class> clazz) throws Exception {
+
+ return Remote.getItem("//127.0.0.1:" + serverPort + "/"
+ + clazz.getCanonicalName());
+
}
- }
-
- /**
- * Start a remote component server on a Javafork object.
- *
- * @param fork
- * JavaFork used to run the server
- * @return Port number used by the server
- * @throws IOException
- */
- protected synchronized int startRemoteServer(JavaFork fork)
- throws IOException {
-
- // get free TCP port to run Cajo server on
- int cajoPort = NetworkUtil.findAvailablePort("127.0.0.1", 5000, 6000);
- if (cajoPort == 0) {
- throw new IOException("No port available to start remote component");
+
+ /**
+ * Create and return a new JavaFork for remote processing.
+ *
+ * @return A JavaFork
+ */
+ protected JavaFork buildJavaFork() {
+
+ JavaFork fork = new JavaFork();
+ fork.setRedirectStreams(true);
+ fork.setWaitBeforeExiting(false);
+ fork.setStartClass(this.getClass());
+
+ return fork;
+ }
+
+ public int getMaxProcessCount() {
+ return maxProcessCount;
+ }
+
+ public void setMaxProcessCount(int maxProcessCount) {
+ this.maxProcessCount = maxProcessCount;
+ }
+
+ public int getProcessCount() {
+ return processCount;
}
- logger.debug(Thread.currentThread() + " uses " + cajoPort
- + " as server port");
-
- // add extra environment variables to JVM
- Map environment = new HashMap();
- // Cajo port
- environment.put("cajo.port", String.valueOf(cajoPort));
- fork.setEnvironment(environment);
-
- // start new JVM with current converter
- fork.start();
-
- // wait for the remote JVM to start
- NetworkUtil.waitUntilPortListening("127.0.0.1", cajoPort, 10000);
-
- return cajoPort;
- }
-
- /**
- * Get a client proxy of a remote component
- *
- * @param serverPort
- * Server port
- * @param clazz
- * Interface of the proxy
- * @return The proxy object
- * @throws Exception
- */
- protected synchronized Object getRemoteComponent(int serverPort,
- Class> clazz) throws Exception {
-
- return Remote.getItem("//127.0.0.1:" + serverPort + "/"
- + clazz.getCanonicalName());
-
- }
-
- /**
- * Create and return a new JavaFork for remote processing.
- *
- * @return A JavaFork
- */
- protected JavaFork buildJavaFork() {
-
- JavaFork fork = new JavaFork();
- fork.setRedirectStreams(true);
- fork.setWaitBeforeExiting(false);
- fork.setStartClass(this.getClass());
-
- return fork;
- }
-
- public int getMaxProcessCount() {
- return maxProcessCount;
- }
-
- public void setMaxProcessCount(int maxProcessCount) {
- this.maxProcessCount = maxProcessCount;
- }
-
- public int getProcessCount() {
- return processCount;
- }
}
diff --git a/src/main/java/org/ghost4j/Component.java b/src/main/java/org/ghost4j/Component.java
index c541cc3..23a30d7 100644
--- a/src/main/java/org/ghost4j/Component.java
+++ b/src/main/java/org/ghost4j/Component.java
@@ -17,26 +17,26 @@
*/
public interface Component {
- /**
- * Copy settings (object properties except for property 'maxProcessCount')
- * to the current component
- *
- * @param settings
- * @throws InvocationTargetException
- * @throws IllegalAccessException
- */
- public void copySettings(Map settings)
- throws IllegalAccessException, InvocationTargetException;
+ /**
+ * Copy settings (object properties except for property 'maxProcessCount')
+ * to the current component
+ *
+ * @param settings
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ */
+ public void copySettings(Map settings)
+ throws IllegalAccessException, InvocationTargetException;
- /**
- * Extract settings (object properties except for property
- * 'maxProcessCount') of the current component
- *
- * @return a Map of settings
- * @throws NoSuchMethodException
- * @throws InvocationTargetException
- * @throws IllegalAccessException
- */
- public Map extractSettings() throws IllegalAccessException,
- InvocationTargetException, NoSuchMethodException;
+ /**
+ * Extract settings (object properties except for property
+ * 'maxProcessCount') of the current component
+ *
+ * @return a Map of settings
+ * @throws NoSuchMethodException
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ */
+ public Map extractSettings() throws IllegalAccessException,
+ InvocationTargetException, NoSuchMethodException;
}
diff --git a/src/main/java/org/ghost4j/Ghostscript.java b/src/main/java/org/ghost4j/Ghostscript.java
index de43342..cbcf202 100644
--- a/src/main/java/org/ghost4j/Ghostscript.java
+++ b/src/main/java/org/ghost4j/Ghostscript.java
@@ -9,14 +9,17 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
import org.ghost4j.display.DisplayCallback;
import org.ghost4j.display.DisplayData;
+import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
/**
@@ -26,639 +29,664 @@
*/
public class Ghostscript {
- /**
- * Name of the system property used to set the encoding to use for stdin.
- */
- public static final String PROPERTY_NAME_ENCODING = "ghost4j.encoding";
- /**
- * Holds Ghostscript interpreter native instance (C pointer).
- */
- private static GhostscriptLibrary.gs_main_instance.ByReference nativeInstanceByRef;
- /**
- * Holds singleton instance.
- */
- private static Ghostscript instance;
- /**
- * Standard input stream.
- */
- private static InputStream stdIn;
- /**
- * Standard output stream.
- */
- private static OutputStream stdOut;
- /**
- * Error output stream.
- */
- private static OutputStream stdErr;
- /**
- * Display callback used to handle display.
- */
- private static DisplayCallback displayCallback;
- /**
- * Stores display data when working with display callback.
- */
- private static DisplayData displayData;
- /**
- * Holds the native display callback.
- */
- private static GhostscriptLibrary.display_callback_s nativeDisplayCallback;
-
- /**
- * Singleton access method.
- *
- * @return The singleton instance.
- */
- public static synchronized Ghostscript getInstance() {
-
- if (instance == null) {
-
- // new instance
- instance = new Ghostscript();
+ /**
+ * Name of the system property used to set the encoding to use for stdin.
+ */
+ public static final String PROPERTY_NAME_ENCODING = "ghost4j.encoding";
+ /**
+ * Logger name.
+ */
+ private static final String LOGGER_NAME = Ghostscript.class.getName();
+ /**
+ * Holds Ghostscript interpreter native instance (C pointer).
+ */
+ private static GhostscriptLibrary.gs_main_instance.ByReference nativeInstanceByRef;
+ /**
+ * Holds singleton instance.
+ */
+ private static Ghostscript instance;
+ /**
+ * Standard input stream.
+ */
+ private static InputStream stdIn;
+ /**
+ * Standard output stream.
+ */
+ private static OutputStream stdOut;
+ /**
+ * Error output stream.
+ */
+ private static OutputStream stdErr;
+ /**
+ * Display callback used to handle display.
+ */
+ private static DisplayCallback displayCallback;
+ /**
+ * Stores display data when working with display callback.
+ */
+ private static DisplayData displayData;
+ /**
+ * Holds the native display callback.
+ */
+ private static GhostscriptLibrary.display_callback_s nativeDisplayCallback;
+
+ /**
+ * Singleton access method.
+ *
+ * @return The singleton instance.
+ */
+ public static synchronized Ghostscript getInstance() {
+
+ if (instance == null) {
+
+ // new instance
+ instance = new Ghostscript();
- }
+ }
- return instance;
- }
-
- /**
- * Gets the display callback set on the Ghostscript interpreter (may be null
- * if not set).
- *
- * @return The DisplayCallback or null
- */
- public synchronized DisplayCallback getDisplayCallback() {
- return displayCallback;
- }
-
- /**
- * Sets a display callback for the Ghostscript interpreter.
- *
- * @param displayCallback
- * DisplayCallback object
- */
- public synchronized void setDisplayCallback(DisplayCallback displayCallback) {
- this.displayCallback = displayCallback;
- }
-
- /**
- * Gets the error output stream of the Ghostscript interpreter (may be null
- * if not set).
- *
- * @return The OutputStream or null
- */
- public synchronized OutputStream getStdErr() {
- return stdErr;
- }
-
- /**
- * Sets the error output stream of the Ghostscript interpreter.
- *
- * @param stdErr
- * OutputStream object
- */
- public synchronized void setStdErr(OutputStream stdErr) {
- this.stdErr = stdErr;
- }
-
- /**
- * Gets the standard output stream of the Ghostscript interpreter (may be
- * null if not set).
- *
- * @return The OutputStream or null
- */
- public synchronized OutputStream getStdOut() {
- return stdOut;
- }
-
- /**
- * Sets the standard output stream of the Ghostscript interpreter.
- *
- * @param stdOut
- * OutputStream object
- */
- public synchronized void setStdOut(OutputStream stdOut) {
- this.stdOut = stdOut;
- }
-
- /**
- * Gets the standard input stream of the Ghostscript interpreter (may be
- * null if not set).
- *
- * @return The InputStream or null
- */
- public synchronized InputStream getStdIn() {
- return stdIn;
- }
-
- /**
- * Sets the standard input stream of the Ghostscript interpreter.
- *
- * @param stdIn
- * InputStream object
- */
- public synchronized void setStdIn(InputStream stdIn) {
- this.stdIn = stdIn;
- }
-
- /**
- * Private constructor.
- */
- private Ghostscript() {
- }
-
- /**
- * Singleton factory method for getting a Ghostscript,interpreter instance.
- * Only called from class itself.
- *
- * @return Ghostscript instance.
- * @throws org.ghost4j.GhostscriptException
- */
- private synchronized GhostscriptLibrary.gs_main_instance.ByReference getNativeInstanceByRef()
- throws GhostscriptException {
-
- if (nativeInstanceByRef == null) {
-
- // prepare instance
- nativeInstanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
- // create instance
- int result = GhostscriptLibrary.instance.gsapi_new_instance(
- nativeInstanceByRef.getPointer(), null);
-
- // test result
- if (result != 0) {
- // failure
- nativeInstanceByRef = null;
- throw new GhostscriptException(
- "Cannot get Ghostscript interpreter instance. Error code is "
- + result);
- }
+ return instance;
}
- return nativeInstanceByRef;
- }
+ /**
+ * Gets the display callback set on the Ghostscript interpreter (may be null
+ * if not set).
+ *
+ * @return The DisplayCallback or null
+ */
+ public synchronized DisplayCallback getDisplayCallback() {
+ return displayCallback;
+ }
- private synchronized DisplayData getDisplayData() {
+ /**
+ * Sets a display callback for the Ghostscript interpreter.
+ *
+ * @param displayCallback
+ * DisplayCallback object
+ */
+ public synchronized void setDisplayCallback(DisplayCallback displayCallback) {
+ this.displayCallback = displayCallback;
+ }
- if (displayData == null) {
- displayData = new DisplayData();
+ /**
+ * Gets the error output stream of the Ghostscript interpreter (may be null
+ * if not set).
+ *
+ * @return The OutputStream or null
+ */
+ public synchronized OutputStream getStdErr() {
+ return stdErr;
}
- return displayData;
- }
-
- /**
- * Gets Ghostscript revision data.
- *
- * @return Revision data.
- */
- public static GhostscriptRevision getRevision() {
-
- // prepare revision structure and call revision function
- GhostscriptLibrary.gsapi_revision_s revision = new GhostscriptLibrary.gsapi_revision_s();
- GhostscriptLibrary.instance.gsapi_revision(revision, revision.size());
-
- GhostscriptRevision result = new GhostscriptRevision();
- result.setProduct(revision.product);
- result.setCopyright(revision.copyright);
- result.setNumber(new Float(revision.revision.floatValue() / 100)
- .toString());
- // parse revision date
- try {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
- result.setRevisionDate(sdf.parse(revision.revisiondate.toString()));
- } catch (ParseException e) {
- result.setRevisionDate(null);
+ /**
+ * Sets the error output stream of the Ghostscript interpreter.
+ *
+ * @param stdErr
+ * OutputStream object
+ */
+ public synchronized void setStdErr(OutputStream stdErr) {
+ this.stdErr = stdErr;
}
- return result;
-
- }
-
- /**
- * Initializes Ghostscript interpreter.
- *
- * @param args
- * Interpreter parameters. Use the same as Ghostscript command
- * line arguments.
- * @throws org.ghost4j.GhostscriptException
- */
- public void initialize(String[] args) throws GhostscriptException {
-
- int result = 0;
-
- // stdin callback
- GhostscriptLibrary.stdin_fn stdinCallback = null;
- if (getStdIn() != null) {
- stdinCallback = new GhostscriptLibrary.stdin_fn() {
-
- public int callback(Pointer caller_handle, Pointer buf, int len) {
-
- // retrieve encoding, if no ghost4j encoding defined = use
- // JVM default
- String encoding = System.getProperty(
- PROPERTY_NAME_ENCODING,
- System.getProperty("file.encoding"));
-
- try {
- byte[] buffer = new byte[1000];
- int read = getStdIn().read(buffer);
- if (read != -1) {
- buf.setString(0, new String(buffer, 0, read,
- encoding));
- buffer = null;
- return read;
- }
- } catch (Exception e) {
- // an error occurs: do nothing
- }
+ /**
+ * Gets the standard output stream of the Ghostscript interpreter (may be
+ * null if not set).
+ *
+ * @return The OutputStream or null
+ */
+ public synchronized OutputStream getStdOut() {
+ return stdOut;
+ }
- return 0;
- }
- };
+ /**
+ * Sets the standard output stream of the Ghostscript interpreter.
+ *
+ * @param stdOut
+ * OutputStream object
+ */
+ public synchronized void setStdOut(OutputStream stdOut) {
+ this.stdOut = stdOut;
}
- // stdout callback, if no stdout explicitly defined, use a
- // GhostscriptLoggerOutputStream to log messages
- GhostscriptLibrary.stdout_fn stdoutCallback = null;
- if (getStdOut() == null) {
- setStdOut(new GhostscriptLoggerOutputStream(Level.INFO));
+ /**
+ * Gets the standard input stream of the Ghostscript interpreter (may be
+ * null if not set).
+ *
+ * @return The InputStream or null
+ */
+ public synchronized InputStream getStdIn() {
+ return stdIn;
}
- stdoutCallback = new GhostscriptLibrary.stdout_fn() {
+ /**
+ * Sets the standard input stream of the Ghostscript interpreter.
+ *
+ * @param stdIn
+ * InputStream object
+ */
+ public synchronized void setStdIn(InputStream stdIn) {
+ this.stdIn = stdIn;
+ }
- public int callback(Pointer caller_handle, String str, int len) {
+ /**
+ * Private constructor.
+ */
+ private Ghostscript() {
+ }
- try {
- getStdOut().write(str.getBytes(), 0, len);
- } catch (IOException ex) {
- // do nothing
+ /**
+ * Singleton factory method for getting a Ghostscript,interpreter instance.
+ * Only called from class itself.
+ *
+ * @return Ghostscript instance.
+ * @throws org.ghost4j.GhostscriptException
+ */
+ private synchronized GhostscriptLibrary.gs_main_instance.ByReference getNativeInstanceByRef()
+ throws GhostscriptException {
+
+ if (nativeInstanceByRef == null) {
+
+ // prepare instance
+ nativeInstanceByRef = new GhostscriptLibrary.gs_main_instance.ByReference();
+ // create instance
+ int result = GhostscriptLibrary.instance.gsapi_new_instance(
+ nativeInstanceByRef.getPointer(), null);
+
+ // test result
+ if (result != 0) {
+ // failure
+ nativeInstanceByRef = null;
+ throw new GhostscriptException(
+ "Cannot get Ghostscript interpreter instance. Error code is "
+ + result);
+ }
}
- return len;
- }
- };
-
- // stderr callback, if no stdout explicitly defined, use a
- // GhostscriptLoggerOutputStream to log messages
- GhostscriptLibrary.stderr_fn stderrCallback = null;
- if (getStdErr() == null) {
- setStdErr(new GhostscriptLoggerOutputStream(Level.ERROR));
+ return nativeInstanceByRef;
}
- stderrCallback = new GhostscriptLibrary.stderr_fn() {
+ private synchronized DisplayData getDisplayData() {
- public int callback(Pointer caller_handle, String str, int len) {
+ if (displayData == null) {
+ displayData = new DisplayData();
+ }
+ return displayData;
+ }
+
+ /**
+ * Gets Ghostscript revision data.
+ *
+ * @return Revision data.
+ */
+ public static GhostscriptRevision getRevision() {
+
+ // prepare revision structure and call revision function
+ GhostscriptLibrary.gsapi_revision_s revision = new GhostscriptLibrary.gsapi_revision_s();
+ GhostscriptLibrary.instance.gsapi_revision(revision, revision.size());
+
+ GhostscriptRevision result = new GhostscriptRevision();
+ result.setProduct(revision.product);
+ result.setCopyright(revision.copyright);
+
+ /* This does not do the right thing. Ghostscript 9.55.0 returns a
+ * revision number of 9550 but this results in 95.5. Perhaps it would
+ * be better to simply return 9550?
+ */
+ //result.setNumber(Float.valueOf(revision.revision.floatValue() / 100));
+ result.setNumber(revision.revision.longValue());
+ // parse revision date
try {
- getStdErr().write(str.getBytes(), 0, len);
- } catch (IOException ex) {
- // do nothing
+ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
+ result.setRevisionDate(LocalDate.parse(
+ revision.revisiondate.toString(), dtf));
+ } catch (DateTimeParseException e) {
+ result.setRevisionDate(null);
}
- return len;
- }
- };
+ return result;
- // io setting
- result = GhostscriptLibrary.instance.gsapi_set_stdio(
- getNativeInstanceByRef().getValue(), stdinCallback,
- stdoutCallback, stderrCallback);
-
- // test result
- if (result != 0) {
- throw new GhostscriptException(
- "Cannot set IO on Ghostscript interpreter. Error code is "
- + result);
}
- // display callback setting
- if (getDisplayCallback() != null) {
- result = GhostscriptLibrary.instance.gsapi_set_display_callback(
- getNativeInstanceByRef().getValue(),
- buildNativeDisplayCallback(getDisplayCallback()));
-
- // test result
- if (result != 0) {
- throw new GhostscriptException(
- "Cannot set display callback on Ghostscript interpreter. Error code is "
- + result);
- }
- }
+ /**
+ * Initializes Ghostscript interpreter.
+ *
+ * @param args
+ * Interpreter parameters. Use the same as Ghostscript command
+ * line arguments.
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void initialize(String[] args) throws GhostscriptException {
+
+ int result = 0;
+
+ // stdin callback
+ GhostscriptLibrary.stdin_fn stdinCallback = null;
+ if (getStdIn() != null) {
+ stdinCallback = new GhostscriptLibrary.stdin_fn() {
+
+ public int callback(Pointer caller_handle, Pointer buf, int len) {
+
+ // retrieve encoding, if no ghost4j encoding defined = use
+ // JVM default
+ String encoding = System.getProperty(
+ PROPERTY_NAME_ENCODING,
+ System.getProperty("file.encoding"));
+
+ try {
+ byte[] buffer = new byte[1000];
+ int read = getStdIn().read(buffer);
+ if (read != -1) {
+ buf.setString(0, new String(buffer, 0, read,
+ encoding));
+ buffer = null;
+ return read;
+ }
+ } catch (Exception e) {
+ // an error occurs: do nothing
+ }
+
+ return 0;
+ }
+ };
+ }
- // init
- result = GhostscriptLibrary.instance.gsapi_set_arg_encoding(getNativeInstanceByRef().getValue(), GhostscriptLibrary.GS_ARG_ENCODING_UTF8);
- if (args != null) {
- result = GhostscriptLibrary.instance.gsapi_init_with_args(
- getNativeInstanceByRef().getValue(), args.length, args);
- } else {
- result = GhostscriptLibrary.instance.gsapi_init_with_args(
- getNativeInstanceByRef().getValue(), 0, null);
- }
+ // stdout callback, if no stdout explicitly defined, use a
+ // GhostscriptLoggerOutputStream to log messages
+ GhostscriptLibrary.stdout_fn stdoutCallback = null;
+ if (getStdOut() == null) {
+ setStdOut(new GhostscriptLoggerOutputStream(Level.INFO));
+ }
- // interpreter exited: this is not an error
- if (result == -101) {
- exit();
- result = 0;
- }
+ stdoutCallback = new GhostscriptLibrary.stdout_fn() {
- // test result
- if (result != 0) {
- throw new GhostscriptException(
- "Cannot initialize Ghostscript interpreter. Error code is "
- + result);
- }
- }
-
- /**
- * Builds a native display callback from a DisplayCallback object.
- *
- * @param displayCallback
- * DisplayCallback to use.
- * @return The created native display callback.
- */
- private synchronized GhostscriptLibrary.display_callback_s buildNativeDisplayCallback(
- DisplayCallback displayCallback) throws GhostscriptException {
-
- nativeDisplayCallback = new GhostscriptLibrary.display_callback_s();
-
- // determine display callback version from Ghostscript version
- float version = Float.parseFloat(getRevision().getNumber());
- // some versions report version 8.15 as 815.05
- if (version < 8.50 || version > 100) {
- nativeDisplayCallback.version_major = 1;
- } else {
- nativeDisplayCallback.version_major = 2;
- }
- nativeDisplayCallback.version_minor = 0;
+ public int callback(Pointer caller_handle, String str, int len) {
- nativeDisplayCallback.display_open = new GhostscriptLibrary.display_callback_s.display_open() {
+ try {
+ getStdOut().write(str.getBytes(), 0, len);
+ } catch (IOException ex) {
+ // do nothing
+ }
- public int callback(Pointer handle, Pointer device) {
+ return len;
+ }
+ };
- // call to java callback
- try {
- getDisplayCallback().displayOpen();
- } catch (GhostscriptException e) {
- return 1;
+ // stderr callback, if no stdout explicitly defined, use a
+ // GhostscriptLoggerOutputStream to log messages
+ GhostscriptLibrary.stderr_fn stderrCallback = null;
+ if (getStdErr() == null) {
+ setStdErr(new GhostscriptLoggerOutputStream(Level.ERROR));
}
- return 0;
- }
- };
- nativeDisplayCallback.display_preclose = new GhostscriptLibrary.display_callback_s.display_preclose() {
+ stderrCallback = new GhostscriptLibrary.stderr_fn() {
- public int callback(Pointer handle, Pointer device) {
+ public int callback(Pointer caller_handle, String str, int len) {
- // call to java callback
- try {
- getDisplayCallback().displayPreClose();
- } catch (GhostscriptException e) {
- return 1;
+ try {
+ getStdErr().write(str.getBytes(), 0, len);
+ } catch (IOException ex) {
+ // do nothing
+ }
+
+ return len;
+ }
+ };
+
+ // io setting
+ result = GhostscriptLibrary.instance.gsapi_set_stdio(
+ getNativeInstanceByRef().getValue(), stdinCallback,
+ stdoutCallback, stderrCallback);
+
+ // test result
+ if (result != 0) {
+ throw new GhostscriptException(
+ "Cannot set IO on Ghostscript interpreter. Error code is "
+ + result);
}
- return 0;
- }
- };
- nativeDisplayCallback.display_close = new GhostscriptLibrary.display_callback_s.display_close() {
+ // display callback setting
+ if (getDisplayCallback() != null) {
+ result = GhostscriptLibrary.instance.gsapi_set_display_callback(
+ getNativeInstanceByRef().getValue(),
+ buildNativeDisplayCallback(getDisplayCallback()));
+
+ // test result
+ if (result != 0) {
+ throw new GhostscriptException(
+ "Cannot set display callback on Ghostscript interpreter. Error code is "
+ + result);
+ }
+ }
- public int callback(Pointer handle, Pointer device) {
+ // init
+ Logger logger = LoggerFactory.getLogger(LOGGER_NAME);
+ GhostscriptRevision rev = Ghostscript.getRevision();
+ logger.info(rev.getProduct() + " " + rev.getNumber() + " (" +
+ rev.getRevisionDateFormatted() + ")");
+ logger.info(rev.getCopyright());
+
+ /* Ghostscript versions older than 9.08 (at least) do not have the
+ * gsapi_set_arg_encoding() function call. On those older versions
+ * there is no requirement to call it. So if we detect a version
+ * older than 9.08 skip the call.
+ */
+ if (rev.getNumber() > Long.valueOf("9070")) {
+ result = GhostscriptLibrary.instance.gsapi_set_arg_encoding(getNativeInstanceByRef().getValue(), GhostscriptLibrary.GS_ARG_ENCODING_UTF8);
+ }
- // call to java callback
- try {
- getDisplayCallback().displayClose();
- } catch (GhostscriptException e) {
- return 1;
+ if (args != null) {
+ result = GhostscriptLibrary.instance.gsapi_init_with_args(
+ getNativeInstanceByRef().getValue(), args.length, args);
+ } else {
+ result = GhostscriptLibrary.instance.gsapi_init_with_args(
+ getNativeInstanceByRef().getValue(), 0, null);
}
- return 0;
- }
- };
- nativeDisplayCallback.display_presize = new GhostscriptLibrary.display_callback_s.display_presize() {
+ // interpreter exited: this is not an error
+ if (result == -101) {
+ exit();
+ result = 0;
+ }
- public int callback(Pointer handle, Pointer device, int width,
- int height, int raster, int format) {
+ // test result
+ if (result != 0) {
+ throw new GhostscriptException(
+ "Cannot initialize Ghostscript interpreter. Error code is "
+ + result);
+ }
+ }
- // call to java callback
- try {
- getDisplayCallback().displayPreSize(width, height, raster,
- format);
- } catch (GhostscriptException e) {
- return 1;
+ /**
+ * Builds a native display callback from a DisplayCallback object.
+ *
+ * @param displayCallback
+ * DisplayCallback to use.
+ * @return The created native display callback.
+ */
+ private synchronized GhostscriptLibrary.display_callback_s buildNativeDisplayCallback(
+ DisplayCallback displayCallback) throws GhostscriptException {
+
+ nativeDisplayCallback = new GhostscriptLibrary.display_callback_s();
+
+ // determine display callback version from Ghostscript version
+ //float version = getRevision().getNumber();
+ float version = Float.valueOf(getRevision().getNumber() / 100);
+ // some versions report version 8.15 as 815.05
+ if (version < 8.50 || version > 100) {
+ nativeDisplayCallback.version_major = 1;
+ } else {
+ nativeDisplayCallback.version_major = 2;
}
+ nativeDisplayCallback.version_minor = 0;
- return 0;
- }
- };
- nativeDisplayCallback.display_size = new GhostscriptLibrary.display_callback_s.display_size() {
+ nativeDisplayCallback.display_open = new GhostscriptLibrary.display_callback_s.display_open() {
- public int callback(Pointer handle, Pointer device, int width,
- int height, int raster, int format, Pointer pimage) {
+ public int callback(Pointer handle, Pointer device) {
- // prepare current page data
- getDisplayData().setWidth(width);
- getDisplayData().setHeight(height);
- getDisplayData().setRaster(raster);
- getDisplayData().setFormat(format);
- getDisplayData().setPimage(pimage);
+ // call to java callback
+ try {
+ getDisplayCallback().displayOpen();
+ } catch (GhostscriptException e) {
+ return 1;
+ }
- // call to java callback
- try {
- getDisplayCallback().displaySize(width, height, raster,
- format);
- } catch (GhostscriptException e) {
- return 1;
- }
+ return 0;
+ }
+ };
+ nativeDisplayCallback.display_preclose = new GhostscriptLibrary.display_callback_s.display_preclose() {
- return 0;
- }
- };
- nativeDisplayCallback.display_sync = new GhostscriptLibrary.display_callback_s.display_sync() {
+ public int callback(Pointer handle, Pointer device) {
- public int callback(Pointer handle, Pointer device) {
+ // call to java callback
+ try {
+ getDisplayCallback().displayPreClose();
+ } catch (GhostscriptException e) {
+ return 1;
+ }
- // call to java callback
- try {
- getDisplayCallback().displaySync();
- } catch (GhostscriptException e) {
- return 1;
- }
+ return 0;
+ }
+ };
+ nativeDisplayCallback.display_close = new GhostscriptLibrary.display_callback_s.display_close() {
- return 0;
- }
- };
- nativeDisplayCallback.display_page = new GhostscriptLibrary.display_callback_s.display_page() {
+ public int callback(Pointer handle, Pointer device) {
- public int callback(Pointer handle, Pointer device, int copies,
- int flush) {
+ // call to java callback
+ try {
+ getDisplayCallback().displayClose();
+ } catch (GhostscriptException e) {
+ return 1;
+ }
- byte[] data = getDisplayData().getPimage().getByteArray(
- 0,
- getDisplayData().getRaster()
- * getDisplayData().getHeight());
+ return 0;
+ }
+ };
+ nativeDisplayCallback.display_presize = new GhostscriptLibrary.display_callback_s.display_presize() {
- // call to java callback
- try {
- getDisplayCallback().displayPage(
- getDisplayData().getWidth(),
- getDisplayData().getHeight(),
- getDisplayData().getRaster(),
- getDisplayData().getFormat(), copies, flush, data);
- } catch (GhostscriptException e) {
- return 1;
- }
+ public int callback(Pointer handle, Pointer device, int width,
+ int height, int raster, int format) {
- return 0;
- }
- };
- nativeDisplayCallback.display_update = new GhostscriptLibrary.display_callback_s.display_update() {
+ // call to java callback
+ try {
+ getDisplayCallback().displayPreSize(width, height, raster,
+ format);
+ } catch (GhostscriptException e) {
+ return 1;
+ }
+
+ return 0;
+ }
+ };
+ nativeDisplayCallback.display_size = new GhostscriptLibrary.display_callback_s.display_size() {
+
+ public int callback(Pointer handle, Pointer device, int width,
+ int height, int raster, int format, Pointer pimage) {
+
+ // prepare current page data
+ getDisplayData().setWidth(width);
+ getDisplayData().setHeight(height);
+ getDisplayData().setRaster(raster);
+ getDisplayData().setFormat(format);
+ getDisplayData().setPimage(pimage);
+
+ // call to java callback
+ try {
+ getDisplayCallback().displaySize(width, height, raster,
+ format);
+ } catch (GhostscriptException e) {
+ return 1;
+ }
+
+ return 0;
+ }
+ };
+ nativeDisplayCallback.display_sync = new GhostscriptLibrary.display_callback_s.display_sync() {
- public int callback(Pointer handle, Pointer device, int x, int y,
- int w, int h) {
+ public int callback(Pointer handle, Pointer device) {
- // call to java callback
- try {
- getDisplayCallback().displayUpdate(x, y, w, h);
- } catch (GhostscriptException e) {
- return 1;
- }
+ // call to java callback
+ try {
+ getDisplayCallback().displaySync();
+ } catch (GhostscriptException e) {
+ return 1;
+ }
- return 0;
- }
- };
-
- nativeDisplayCallback.display_memalloc = null;
- nativeDisplayCallback.display_memfree = null;
-
- switch (nativeDisplayCallback.version_major) {
- case 1:
- nativeDisplayCallback.size = nativeDisplayCallback.size()
- - Pointer.SIZE;
- break;
- default:
- nativeDisplayCallback.size = nativeDisplayCallback.size();
- break;
- }
+ return 0;
+ }
+ };
+ nativeDisplayCallback.display_page = new GhostscriptLibrary.display_callback_s.display_page() {
+
+ public int callback(Pointer handle, Pointer device, int copies,
+ int flush) {
+
+ byte[] data = getDisplayData().getPimage().getByteArray(
+ 0,
+ getDisplayData().getRaster()
+ * getDisplayData().getHeight());
+
+ // call to java callback
+ try {
+ getDisplayCallback().displayPage(
+ getDisplayData().getWidth(),
+ getDisplayData().getHeight(),
+ getDisplayData().getRaster(),
+ getDisplayData().getFormat(), copies, flush, data);
+ } catch (GhostscriptException e) {
+ return 1;
+ }
+
+ return 0;
+ }
+ };
+ nativeDisplayCallback.display_update = new GhostscriptLibrary.display_callback_s.display_update() {
- nativeDisplayCallback.display_separation = null;
+ public int callback(Pointer handle, Pointer device, int x, int y,
+ int w, int h) {
- return nativeDisplayCallback;
- }
+ // call to java callback
+ try {
+ getDisplayCallback().displayUpdate(x, y, w, h);
+ } catch (GhostscriptException e) {
+ return 1;
+ }
- /**
- * Exits Ghostscript interpreter. Must be called after initialize.
- *
- * @throws org.ghost4j.GhostscriptException
- */
- public void exit() throws GhostscriptException {
+ return 0;
+ }
+ };
+
+ nativeDisplayCallback.display_memalloc = null;
+ nativeDisplayCallback.display_memfree = null;
+
+ switch (nativeDisplayCallback.version_major) {
+ case 1:
+ nativeDisplayCallback.size = nativeDisplayCallback.size()
+ - Native.POINTER_SIZE;
+ break;
+ default:
+ nativeDisplayCallback.size = nativeDisplayCallback.size();
+ break;
+ }
- if (nativeInstanceByRef != null) {
- int result = GhostscriptLibrary.instance
- .gsapi_exit(getNativeInstanceByRef().getValue());
+ nativeDisplayCallback.display_separation = null;
- if (result != 0) {
- throw new GhostscriptException(
- "Cannot exit Ghostscript interpreter. Error code is "
- + result);
- }
- }
- }
-
- /**
- * Sends command string to Ghostscript interpreter. Must be called after
- * initialize method.
- *
- * @param string
- * Command string
- * @throws org.ghost4j.GhostscriptException
- */
- public void runString(String string) throws GhostscriptException {
-
- IntByReference exitCode = new IntByReference();
-
- GhostscriptLibrary.instance.gsapi_run_string_begin(
- getNativeInstanceByRef().getValue(), 0, exitCode);
-
- // test exit code
- if (exitCode.getValue() != 0) {
- throw new GhostscriptException(
- "Cannot run command on Ghostscript interpreter. gsapi_run_string_begin failed with error code "
- + exitCode.getValue());
+ return nativeDisplayCallback;
}
- // split string on carriage return
- String[] slices = string.split("\n");
-
- for (int i = 0; i < slices.length; i++) {
- String slice = slices[i] + "\n";
- GhostscriptLibrary.instance.gsapi_run_string_continue(
- getNativeInstanceByRef().getValue(), slice, slice.length(),
- 0, exitCode);
-
- // test exit code
- if (exitCode.getValue() != 0) {
- throw new GhostscriptException(
- "Cannot run command on Ghostscript interpreter. gsapi_run_string_continue failed with error code "
- + exitCode.getValue());
- }
+ /**
+ * Exits Ghostscript interpreter. Must be called after initialize.
+ *
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void exit() throws GhostscriptException {
+
+ if (nativeInstanceByRef != null) {
+ int result = GhostscriptLibrary.instance
+ .gsapi_exit(getNativeInstanceByRef().getValue());
+
+ if (result != 0) {
+ throw new GhostscriptException(
+ "Cannot exit Ghostscript interpreter. Error code is "
+ + result);
+ }
+ }
}
- GhostscriptLibrary.instance.gsapi_run_string_end(
- getNativeInstanceByRef().getValue(), 0, exitCode);
+ /**
+ * Sends command string to Ghostscript interpreter. Must be called after
+ * initialize method.
+ *
+ * @param string
+ * Command string
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void runString(String string) throws GhostscriptException {
+
+ IntByReference exitCode = new IntByReference();
+
+ GhostscriptLibrary.instance.gsapi_run_string_begin(
+ getNativeInstanceByRef().getValue(), 0, exitCode);
+
+ // test exit code
+ if (exitCode.getValue() != 0) {
+ throw new GhostscriptException(
+ "Cannot run command on Ghostscript interpreter. gsapi_run_string_begin failed with error code "
+ + exitCode.getValue());
+ }
- // test exit code
- if (exitCode.getValue() != 0) {
- throw new GhostscriptException(
- "Cannot run command on Ghostscript interpreter. gsapi_run_string_end failed with error code "
- + exitCode.getValue());
- }
+ // split string on carriage return
+ String[] slices = string.split("\n");
- }
+ for (int i = 0; i < slices.length; i++) {
+ String slice = slices[i] + "\n";
+ GhostscriptLibrary.instance.gsapi_run_string_continue(
+ getNativeInstanceByRef().getValue(), slice, slice.length(),
+ 0, exitCode);
- /**
- * Sends file Ghostscript interpreter. Must be called after initialize
- * method.
- *
- * @param fileName
- * File name
- * @throws org.ghost4j.GhostscriptException
- */
- public void runFile(String fileName) throws GhostscriptException {
+ // test exit code
+ if (exitCode.getValue() != 0) {
+ throw new GhostscriptException(
+ "Cannot run command on Ghostscript interpreter. gsapi_run_string_continue failed with error code "
+ + exitCode.getValue());
+ }
+ }
- IntByReference exitCode = new IntByReference();
+ GhostscriptLibrary.instance.gsapi_run_string_end(
+ getNativeInstanceByRef().getValue(), 0, exitCode);
- GhostscriptLibrary.instance.gsapi_run_file(getNativeInstanceByRef()
- .getValue(), fileName, 0, exitCode);
+ // test exit code
+ if (exitCode.getValue() != 0) {
+ throw new GhostscriptException(
+ "Cannot run command on Ghostscript interpreter. gsapi_run_string_end failed with error code "
+ + exitCode.getValue());
+ }
- // test exit code
- if (exitCode.getValue() != 0) {
- throw new GhostscriptException(
- "Cannot run file on Ghostscript interpreter. Error code "
- + exitCode.getValue());
}
- }
-
- /**
- * Deletes the singleton instance of the Ghostscript object. This ensures
- * that the native Ghostscrit interpreter instance is deleted. This method
- * must be called if Ghostscript is not used anymore or maybe reinitialized.
- *
- * @throws org.ghost4j.GhostscriptException
- */
- public static synchronized void deleteInstance()
- throws GhostscriptException {
-
- // clear instance
- if (instance != null) {
- // unreference singleton instance
- instance = null;
+ /**
+ * Sends file Ghostscript interpreter. Must be called after initialize
+ * method.
+ *
+ * @param fileName
+ * File name
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void runFile(String fileName) throws GhostscriptException {
+
+ IntByReference exitCode = new IntByReference();
+
+ GhostscriptLibrary.instance.gsapi_run_file(getNativeInstanceByRef()
+ .getValue(), fileName, 0, exitCode);
+
+ // test exit code
+ if (exitCode.getValue() != 0) {
+ throw new GhostscriptException(
+ "Cannot run file on Ghostscript interpreter. Error code "
+ + exitCode.getValue());
+ }
+
}
- // delete native interpeter instance
- if (nativeInstanceByRef != null) {
- GhostscriptLibrary.instance
- .gsapi_delete_instance(nativeInstanceByRef.getValue());
- nativeInstanceByRef = null;
+ /**
+ * Deletes the singleton instance of the Ghostscript object. This ensures
+ * that the native Ghostscrit interpreter instance is deleted. This method
+ * must be called if Ghostscript is not used anymore or maybe reinitialized.
+ *
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public static synchronized void deleteInstance()
+ throws GhostscriptException {
+
+ // clear instance
+ if (instance != null) {
+ // unreference singleton instance
+ instance = null;
+ }
+
+ // delete native interpeter instance
+ if (nativeInstanceByRef != null) {
+ GhostscriptLibrary.instance
+ .gsapi_delete_instance(nativeInstanceByRef.getValue());
+ nativeInstanceByRef = null;
+ }
}
- }
}
diff --git a/src/main/java/org/ghost4j/GhostscriptException.java b/src/main/java/org/ghost4j/GhostscriptException.java
index c4895ac..17fbdbf 100644
--- a/src/main/java/org/ghost4j/GhostscriptException.java
+++ b/src/main/java/org/ghost4j/GhostscriptException.java
@@ -13,25 +13,24 @@
*/
public class GhostscriptException extends Exception {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = -3901110749568935981L;
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = -3901110749568935981L;
- public GhostscriptException() {
- super();
- }
+ public GhostscriptException() {
+ super();
+ }
- public GhostscriptException(String message) {
- super(message);
- }
+ public GhostscriptException(String message) {
+ super(message);
+ }
- public GhostscriptException(Throwable cause) {
- super(cause);
- }
+ public GhostscriptException(Throwable cause) {
+ super(cause);
+ }
- public GhostscriptException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
\ No newline at end of file
+ public GhostscriptException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/org/ghost4j/GhostscriptLibrary.java b/src/main/java/org/ghost4j/GhostscriptLibrary.java
index 8b1d461..4c50f59 100644
--- a/src/main/java/org/ghost4j/GhostscriptLibrary.java
+++ b/src/main/java/org/ghost4j/GhostscriptLibrary.java
@@ -15,7 +15,6 @@
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
-import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
import java.util.Arrays;
import java.util.List;
@@ -29,455 +28,455 @@
* @author Gilles Grousset (gi.grousset@gmail.com)
*/
public interface GhostscriptLibrary extends Library {
-
- final int GS_ARG_ENCODING_UTF8 = 1;
-
- /**
- * Static instance of the library itself.
- */
- public static GhostscriptLibrary instance = GhostscriptLibraryLoader
- .loadLibrary();
-
- /**
- * Structure in charge of holding Ghostscript revision data.
- */
- public class gsapi_revision_s extends Structure {
-
- /**
- * Product name.
- */
- public String product;
- /**
- * Copyright.
- */
- public String copyright;
- /**
- * Revision number.
- */
- public NativeLong revision;
- /**
- * Revision date.
- */
- public NativeLong revisiondate;
-
- protected List> getFieldOrder() {
- return Arrays.asList("product", "copyright", "revision", "revisiondate");
- }
- }
-
- /**
- * Structure defining display callback functions.
- */
- public class display_callback_s extends Structure {
-
- /**
- * Callback called when new device has been opened. This is the first
- * event from this device.
- */
- public static interface display_open extends Callback {
-
- public int callback(Pointer handle, Pointer device);
- }
-
- /**
- * Callback called when device is about to be closed. Device will not be
- * closed until this function returns.
- */
- public static interface display_preclose extends Callback {
-
- public int callback(Pointer handle, Pointer device);
- }
-
- /**
- * Callback called when device has been closed. This is the last event
- * from this device.
- */
- public static interface display_close extends Callback {
-
- public int callback(Pointer handle, Pointer device);
- }
-
- /**
- * Callback called when device is about to be resized. Resize will only
- * occur if this function returns 0. raster is byte count of a row.
- */
- public static interface display_presize extends Callback {
-
- public int callback(Pointer handle, Pointer device, int width,
- int height, int raster, int format);
- }
-
- /**
- * Callback called when device has been resized. New pointer to raster
- * is returned in pimage.
- */
- public static interface display_size extends Callback {
-
- public int callback(Pointer handle, Pointer device, int width,
- int height, int raster, int format, Pointer pimage);
- }
-
- /**
- * Callback called on page flush.
- */
- public static interface display_sync extends Callback {
-
- public int callback(Pointer handle, Pointer device);
- }
-
- /**
- * Callback called on show page. If you want to pause on showpage, then
- * don't return immediately.
- */
- public static interface display_page extends Callback {
-
- public int callback(Pointer handle, Pointer device, int copies,
- int flush);
- }
-
- /**
- * Callback called to notify the caller whenever a portion of the raster
- * is updated. This can be used for cooperative multitasking or for
- * progressive update of the display.
- */
- public static interface display_update extends Callback {
-
- public int callback(Pointer handle, Pointer device, int x, int y,
- int w, int h);
- }
-
- /**
- * Callback called to allocate memory for bitmap This is provided in
- * case you need to create memory in a special way, e.g. shared. This
- * will only be called to allocate the image buffer. The first row will
- * be placed at the address returned by display_memalloc.
- */
- public static interface display_memalloc extends Callback {
-
- public void callback(Pointer handle, Pointer device, NativeLong size);
- }
-
- /**
- * Callback called to free memory for bitmap.
- */
- public static interface display_memfree extends Callback {
-
- public int callback(Pointer handle, Pointer device, Pointer mem);
- }
-
- public static interface display_separation extends Callback {
-
- public int callback(Pointer handle, Pointer device, int component,
- String component_name, short c, short m, short y, short k);
- }
-
- /**
- * Size of this structure. Used for checking if we have been handed a
- * valid structure.
- */
- public int size;
- /**
- * Major version of this structure. The major version number will change
- * if this structure changes.
- */
- public int version_major;
- /**
- * Minor version of this structure. The minor version number will change
- * if new features are added without changes to this structure. For
- * example, a new color format.
- */
- public int version_minor;
- /**
- * Holds a display_open callback.
- */
- public display_open display_open;
- /**
- * Holds a display_preclose callback.
- */
- public display_preclose display_preclose;
- /**
- * Holds a display_close callback.
- */
- public display_close display_close;
- /**
- * Holds a display_presize callback.
- */
- public display_presize display_presize;
- /**
- * Holds a display_size callback.
- */
- public display_size display_size;
- /**
- * Holds a display_sync callback.
- */
- public display_sync display_sync;
- /**
- * Holds a display_page callback.
- */
- public display_page display_page;
- /**
- * Holds a display_update callback. Set this to null if not required.
- */
- public display_update display_update;
- /**
- * Holds a display_memalloc callback. Set this to null if not required.
- */
- public display_memalloc display_memalloc;
- /**
- * Holds a display_memfree callback. Set this to null if not required.
- */
- public display_memfree display_memfree;
- /**
- * Holds a display_separation callback. Set this to null if not
- * required. Ghostscript must only use this callback if version_major >=
- * 2.
- */
- public display_separation display_separation;
-
- protected List> getFieldOrder() {
- return Arrays.asList("size", "version_major", "version_minor", "display_open", "display_preclose", "display_close", "display_presize", "display_size", "display_sync", "display_page", "display_update", "display_memalloc", "display_memfree", "display_separation");
- }
- }
-
- /**
- * Pointer holding a native Ghostscript instance.
- */
- public class gs_main_instance extends PointerType {
-
- @Override
- public Object fromNative(Object arg0, FromNativeContext arg1) {
- return super.fromNative(arg0, arg1);
- }
-
- public static class ByReference extends PointerByReference {
-
- @Override
- public Object fromNative(Object arg0, FromNativeContext arg1) {
- return super.fromNative(arg0, arg1);
- }
- }
- }
-
- /**
- * Callback called to provide a custom input to Ghostscript. buf is a
- * pointer to a char array. len is the length of the char array.
- */
- public interface stdin_fn extends StdCallCallback {
-
- public int callback(Pointer caller_handle, Pointer buf, int len);
- }
-
- /**
- * Callback called to provide a custom output to Ghostscript. Important: The
- * output is not the resulting file, but the output of the Postscript
- * interpreter. str holds output characters. len is the length for str.
- */
- public interface stdout_fn extends StdCallCallback {
-
- public int callback(Pointer caller_handle, String str, int len);
- }
-
- /**
- * Callback called to provide a custom error output to Ghostscript. str
- * holds output characters. len is the length for str.
- */
- public interface stderr_fn extends StdCallCallback {
-
- public int callback(Pointer caller_handle, String str, int len);
- }
-
- /**
- * This function returns the revision numbers and strings of the Ghostscript
- * interpreter library. You should call it before any other interpreter
- * library functions to make sure that the correct version of the
- * Ghostscript interpreter has been loaded.
- *
- * @param pr Pointer to the gsapi_revision_s that will hold return values.
- * @param len pr Length
- * @see gsapi_revision_s
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_revision(Structure pr, int len);
-
- /**
- * Create a new instance of Ghostscript. This instance is passed to most
- * other gsapi functions. The caller_handle will be provided to callback
- * functions. At this stage, Ghostscript supports only one instance.
- *
- * @param pinstance Pointer to gs_main_instance that will hold the
- * Ghostscript instance.
- * @param caller_handle Caller handler pointer (may be null).
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_new_instance(Pointer pinstance, Pointer caller_handle);
-
- /**
- * Destroy an instance of Ghostscript. Before you call this, Ghostscript
- * must have finished. If Ghostscript has been initialised, you must call
- * gsapi_exit before gsapi_delete_instance.
- *
- * @param instance Pointer to the Ghostscript instance.
- */
- public void gsapi_delete_instance(Pointer instance);
-
- /**
- * Exit the interpreter. This must be called on shutdown if
- * gsapi_init_with_args() has been called, and just before
- * gsapi_delete_instance().
- *
- * @param instance Pointer to the Ghostscript instance.
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_exit(Pointer instance);
-
- /**
- * Set the encoding used for the interpretation of all subsequent args
- * supplied via the gsapi interface on this instance. By default we expect
- * args to be in encoding 0 (the 'local' encoding for this OS). On Windows
- * this means "the currently selected codepage". On Linux this typically
- * means utf8. This means that omitting to call this function will leave
- * Ghostscript running exactly as it always has. Please note that use of the
- * 'local' encoding is now deprecated and should be avoided in new code.
- * This must be called after gsapi_new_instance() and before
- * gsapi_init_with_args().
- *
- * @param instance
- * @param encoding
- * @return
- */
- public int gsapi_set_arg_encoding(Pointer instance, int encoding);
-
- /**
- * Initialise the interpreter. This calls gs_main_init_with_args() in
- * imainarg.c. The arguments are the same as the "C" main function: argv[0]
- * is ignored and the user supplied arguments are argv[1] to argv[argc-1].
- *
- * @param instance Pointer to the Ghostscript instance.
- * @param argc Argument count
- * @param argv Argument array
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_init_with_args(Pointer instance, int argc, String[] argv);
-
- /**
- * Send instruction to the Ghostscript interpreter. The address passed in
- * pexit_code will be used to return the exit code for the interpreter in
- * case of a quit or fatal error.
- *
- * @param instance Pointer to the Ghostscript instance.
- * @param str Instructions. Max length for the string is 65535.
- * @param user_errors If set to 0 errors are returned the normal way (to the
- * interpreter output), if a negative value is used errors are returns
- * directly by the function.
- * @param pexit_code Pointer to the exit return code
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_run_string(Pointer instance, String str, int user_errors,
- IntByReference pexit_code);
-
- /**
- * Send instruction to the Ghostscript interpreter. The address passed in
- * pexit_code will be used to return the exit code for the interpreter in
- * case of a quit or fatal error.
- *
- * @param instance Pointer to the Ghostscript instance.
- * @param str Instructions. Max length for the string is 65535.
- * @param length str length.
- * @param user_errors If set to 0 errors are returned the normal way (to the
- * interpreter output), if a negative value is used errors are returns
- * directly by the function.
- * @param pexit_code Pointer to the exit return code
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_run_string_with_length(Pointer instance, String str,
- int length, int user_errors, IntByReference pexit_code);
-
- /**
- * Open an instruction block to the Ghostscript interpreter. The address
- * passed in pexit_code will be used to return the exit code for the
- * interpreter in case of a quit or fatal error.
- *
- * @param instance Pointer to the Ghostscript instance.
- * @param user_errors If set to 0 errors are returned the normal way (to the
- * interpreter output), if a negative value is used errors are returns
- * directly by the function.
- * @param pexit_code Pointer to the exit return code
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_run_string_begin(Pointer instance, int user_errors,
- IntByReference pexit_code);
-
- /**
- * Send instruction to the Ghostscript interpreter. Must be used after
- * gsapi_run_string_begin is called. The address passed in pexit_code will
- * be used to return the exit code for the interpreter in case of a quit or
- * fatal error.
- *
- * @param instance Pointer to the Ghostscript instance.
- * @param str Instructions. Max length for the string is 65535.
- * @param length str length.
- * @param user_errors If set to 0 errors are returned the normal way (to the
- * interpreter output), if a negative value is used errors are returns
- * directly by the function.
- * @param pexit_code Pointer to the exit return code
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_run_string_continue(Pointer instance, String str,
- int length, int user_errors, IntByReference pexit_code);
-
- /**
- * Close an instruction block to the Ghostscript interpreter. The address
- * passed in pexit_code will be used to return the exit code for the
- * interpreter in case of a quit or fatal error.
- *
- * @param instance Pointer to the Ghostscript instance.
- * @param user_errors If set to 0 errors are returned the normal way (to the
- * interpreter output), if a negative value is used errors are returns
- * directly by the function.
- * @param pexit_code Pointer to the exit return code
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_run_string_end(Pointer instance, int user_errors,
- IntByReference pexit_code);
-
- /**
- * Send instructions from a file to the Ghostscript interpreter.
- *
- * @param instance Pointer to the Ghostscript instance.
- * @param file_name File name.
- * @param user_errors If set to 0 errors are returned the normal way (to the
- * interpreter output), if a negative value is used errors are returns
- * directly by the function.
- * @param pexit_code
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_run_file(Pointer instance, String file_name,
- int user_errors, IntByReference pexit_code);
-
- /**
- * Set the callback functions for stdio. The stdin callback function should
- * return the number of characters read, 0 for EOF, or -1 for error. The
- * stdout and stderr callback functions should return the number of
- * characters written.
- *
- * @param instance Pointer to the Ghostscript instance.
- * @param stdin_fn Stdin callback function.
- * @param stdout_fn Stdout callback function.
- * @param stderr_fn Stderr callback function.
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_set_stdio(Pointer instance, stdin_fn stdin_fn,
- stdout_fn stdout_fn, stderr_fn stderr_fn);
-
- /**
- * Set the callback structure for the display device. If the display device
- * is used, this must be called after gsapi_new_instance() and before
- * gsapi_init_with_args(). See gdevdsp.h for more details.
- *
- * @param instance Pointer to the Ghostscript instance.
- * @param callback display_callback_s Structure holding display callback
- * functions.
- * @return 0 if everything is OK, < 0 otherwise
- */
- public int gsapi_set_display_callback(Pointer instance, Structure callback);
+
+ final int GS_ARG_ENCODING_UTF8 = 1;
+
+ /**
+ * Static instance of the library itself.
+ */
+ public static GhostscriptLibrary instance = GhostscriptLibraryLoader
+ .loadLibrary();
+
+ /**
+ * Structure in charge of holding Ghostscript revision data.
+ */
+ public class gsapi_revision_s extends Structure {
+
+ /**
+ * Product name.
+ */
+ public String product;
+ /**
+ * Copyright.
+ */
+ public String copyright;
+ /**
+ * Revision number.
+ */
+ public NativeLong revision;
+ /**
+ * Revision date.
+ */
+ public NativeLong revisiondate;
+
+ protected List getFieldOrder() {
+ return Arrays.asList("product", "copyright", "revision", "revisiondate");
+ }
+ }
+
+ /**
+ * Structure defining display callback functions.
+ */
+ public class display_callback_s extends Structure {
+
+ /**
+ * Callback called when new device has been opened. This is the first
+ * event from this device.
+ */
+ public static interface display_open extends Callback {
+
+ public int callback(Pointer handle, Pointer device);
+ }
+
+ /**
+ * Callback called when device is about to be closed. Device will not be
+ * closed until this function returns.
+ */
+ public static interface display_preclose extends Callback {
+
+ public int callback(Pointer handle, Pointer device);
+ }
+
+ /**
+ * Callback called when device has been closed. This is the last event
+ * from this device.
+ */
+ public static interface display_close extends Callback {
+
+ public int callback(Pointer handle, Pointer device);
+ }
+
+ /**
+ * Callback called when device is about to be resized. Resize will only
+ * occur if this function returns 0. raster is byte count of a row.
+ */
+ public static interface display_presize extends Callback {
+
+ public int callback(Pointer handle, Pointer device, int width,
+ int height, int raster, int format);
+ }
+
+ /**
+ * Callback called when device has been resized. New pointer to raster
+ * is returned in pimage.
+ */
+ public static interface display_size extends Callback {
+
+ public int callback(Pointer handle, Pointer device, int width,
+ int height, int raster, int format, Pointer pimage);
+ }
+
+ /**
+ * Callback called on page flush.
+ */
+ public static interface display_sync extends Callback {
+
+ public int callback(Pointer handle, Pointer device);
+ }
+
+ /**
+ * Callback called on show page. If you want to pause on showpage, then
+ * don't return immediately.
+ */
+ public static interface display_page extends Callback {
+
+ public int callback(Pointer handle, Pointer device, int copies,
+ int flush);
+ }
+
+ /**
+ * Callback called to notify the caller whenever a portion of the raster
+ * is updated. This can be used for cooperative multitasking or for
+ * progressive update of the display.
+ */
+ public static interface display_update extends Callback {
+
+ public int callback(Pointer handle, Pointer device, int x, int y,
+ int w, int h);
+ }
+
+ /**
+ * Callback called to allocate memory for bitmap This is provided in
+ * case you need to create memory in a special way, e.g. shared. This
+ * will only be called to allocate the image buffer. The first row will
+ * be placed at the address returned by display_memalloc.
+ */
+ public static interface display_memalloc extends Callback {
+
+ public void callback(Pointer handle, Pointer device, NativeLong size);
+ }
+
+ /**
+ * Callback called to free memory for bitmap.
+ */
+ public static interface display_memfree extends Callback {
+
+ public int callback(Pointer handle, Pointer device, Pointer mem);
+ }
+
+ public static interface display_separation extends Callback {
+
+ public int callback(Pointer handle, Pointer device, int component,
+ String component_name, short c, short m, short y, short k);
+ }
+
+ /**
+ * Size of this structure. Used for checking if we have been handed a
+ * valid structure.
+ */
+ public int size;
+ /**
+ * Major version of this structure. The major version number will change
+ * if this structure changes.
+ */
+ public int version_major;
+ /**
+ * Minor version of this structure. The minor version number will change
+ * if new features are added without changes to this structure. For
+ * example, a new color format.
+ */
+ public int version_minor;
+ /**
+ * Holds a display_open callback.
+ */
+ public display_open display_open;
+ /**
+ * Holds a display_preclose callback.
+ */
+ public display_preclose display_preclose;
+ /**
+ * Holds a display_close callback.
+ */
+ public display_close display_close;
+ /**
+ * Holds a display_presize callback.
+ */
+ public display_presize display_presize;
+ /**
+ * Holds a display_size callback.
+ */
+ public display_size display_size;
+ /**
+ * Holds a display_sync callback.
+ */
+ public display_sync display_sync;
+ /**
+ * Holds a display_page callback.
+ */
+ public display_page display_page;
+ /**
+ * Holds a display_update callback. Set this to null if not required.
+ */
+ public display_update display_update;
+ /**
+ * Holds a display_memalloc callback. Set this to null if not required.
+ */
+ public display_memalloc display_memalloc;
+ /**
+ * Holds a display_memfree callback. Set this to null if not required.
+ */
+ public display_memfree display_memfree;
+ /**
+ * Holds a display_separation callback. Set this to null if not
+ * required. Ghostscript must only use this callback if version_major >=
+ * 2.
+ */
+ public display_separation display_separation;
+
+ protected List getFieldOrder() {
+ return Arrays.asList("size", "version_major", "version_minor", "display_open", "display_preclose", "display_close", "display_presize", "display_size", "display_sync", "display_page", "display_update", "display_memalloc", "display_memfree", "display_separation");
+ }
+ }
+
+ /**
+ * Pointer holding a native Ghostscript instance.
+ */
+ public class gs_main_instance extends PointerType {
+
+ @Override
+ public Object fromNative(Object arg0, FromNativeContext arg1) {
+ return super.fromNative(arg0, arg1);
+ }
+
+ public static class ByReference extends PointerByReference {
+
+ @Override
+ public Object fromNative(Object arg0, FromNativeContext arg1) {
+ return super.fromNative(arg0, arg1);
+ }
+ }
+ }
+
+ /**
+ * Callback called to provide a custom input to Ghostscript. buf is a
+ * pointer to a char array. len is the length of the char array.
+ */
+ public interface stdin_fn extends Callback {
+
+ public int callback(Pointer caller_handle, Pointer buf, int len);
+ }
+
+ /**
+ * Callback called to provide a custom output to Ghostscript. Important: The
+ * output is not the resulting file, but the output of the Postscript
+ * interpreter. str holds output characters. len is the length for str.
+ */
+ public interface stdout_fn extends Callback {
+
+ public int callback(Pointer caller_handle, String str, int len);
+ }
+
+ /**
+ * Callback called to provide a custom error output to Ghostscript. str
+ * holds output characters. len is the length for str.
+ */
+ public interface stderr_fn extends Callback {
+
+ public int callback(Pointer caller_handle, String str, int len);
+ }
+
+ /**
+ * This function returns the revision numbers and strings of the Ghostscript
+ * interpreter library. You should call it before any other interpreter
+ * library functions to make sure that the correct version of the
+ * Ghostscript interpreter has been loaded.
+ *
+ * @param pr Pointer to the gsapi_revision_s that will hold return values.
+ * @param len pr Length
+ * @see gsapi_revision_s
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_revision(Structure pr, int len);
+
+ /**
+ * Create a new instance of Ghostscript. This instance is passed to most
+ * other gsapi functions. The caller_handle will be provided to callback
+ * functions. At this stage, Ghostscript supports only one instance.
+ *
+ * @param pinstance Pointer to gs_main_instance that will hold the
+ * Ghostscript instance.
+ * @param caller_handle Caller handler pointer (may be null).
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_new_instance(Pointer pinstance, Pointer caller_handle);
+
+ /**
+ * Destroy an instance of Ghostscript. Before you call this, Ghostscript
+ * must have finished. If Ghostscript has been initialised, you must call
+ * gsapi_exit before gsapi_delete_instance.
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ */
+ public void gsapi_delete_instance(Pointer instance);
+
+ /**
+ * Exit the interpreter. This must be called on shutdown if
+ * gsapi_init_with_args() has been called, and just before
+ * gsapi_delete_instance().
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_exit(Pointer instance);
+
+ /**
+ * Set the encoding used for the interpretation of all subsequent args
+ * supplied via the gsapi interface on this instance. By default we expect
+ * args to be in encoding 0 (the 'local' encoding for this OS). On Windows
+ * this means "the currently selected codepage". On Linux this typically
+ * means utf8. This means that omitting to call this function will leave
+ * Ghostscript running exactly as it always has. Please note that use of the
+ * 'local' encoding is now deprecated and should be avoided in new code.
+ * This must be called after gsapi_new_instance() and before
+ * gsapi_init_with_args().
+ *
+ * @param instance
+ * @param encoding
+ * @return
+ */
+ public int gsapi_set_arg_encoding(Pointer instance, int encoding);
+
+ /**
+ * Initialise the interpreter. This calls gs_main_init_with_args() in
+ * imainarg.c. The arguments are the same as the "C" main function: argv[0]
+ * is ignored and the user supplied arguments are argv[1] to argv[argc-1].
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @param argc Argument count
+ * @param argv Argument array
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_init_with_args(Pointer instance, int argc, String[] argv);
+
+ /**
+ * Send instruction to the Ghostscript interpreter. The address passed in
+ * pexit_code will be used to return the exit code for the interpreter in
+ * case of a quit or fatal error.
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @param str Instructions. Max length for the string is 65535.
+ * @param user_errors If set to 0 errors are returned the normal way (to the
+ * interpreter output), if a negative value is used errors are returns
+ * directly by the function.
+ * @param pexit_code Pointer to the exit return code
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_run_string(Pointer instance, String str, int user_errors,
+ IntByReference pexit_code);
+
+ /**
+ * Send instruction to the Ghostscript interpreter. The address passed in
+ * pexit_code will be used to return the exit code for the interpreter in
+ * case of a quit or fatal error.
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @param str Instructions. Max length for the string is 65535.
+ * @param length str length.
+ * @param user_errors If set to 0 errors are returned the normal way (to the
+ * interpreter output), if a negative value is used errors are returns
+ * directly by the function.
+ * @param pexit_code Pointer to the exit return code
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_run_string_with_length(Pointer instance, String str,
+ int length, int user_errors, IntByReference pexit_code);
+
+ /**
+ * Open an instruction block to the Ghostscript interpreter. The address
+ * passed in pexit_code will be used to return the exit code for the
+ * interpreter in case of a quit or fatal error.
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @param user_errors If set to 0 errors are returned the normal way (to the
+ * interpreter output), if a negative value is used errors are returns
+ * directly by the function.
+ * @param pexit_code Pointer to the exit return code
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_run_string_begin(Pointer instance, int user_errors,
+ IntByReference pexit_code);
+
+ /**
+ * Send instruction to the Ghostscript interpreter. Must be used after
+ * gsapi_run_string_begin is called. The address passed in pexit_code will
+ * be used to return the exit code for the interpreter in case of a quit or
+ * fatal error.
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @param str Instructions. Max length for the string is 65535.
+ * @param length str length.
+ * @param user_errors If set to 0 errors are returned the normal way (to the
+ * interpreter output), if a negative value is used errors are returns
+ * directly by the function.
+ * @param pexit_code Pointer to the exit return code
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_run_string_continue(Pointer instance, String str,
+ int length, int user_errors, IntByReference pexit_code);
+
+ /**
+ * Close an instruction block to the Ghostscript interpreter. The address
+ * passed in pexit_code will be used to return the exit code for the
+ * interpreter in case of a quit or fatal error.
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @param user_errors If set to 0 errors are returned the normal way (to the
+ * interpreter output), if a negative value is used errors are returns
+ * directly by the function.
+ * @param pexit_code Pointer to the exit return code
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_run_string_end(Pointer instance, int user_errors,
+ IntByReference pexit_code);
+
+ /**
+ * Send instructions from a file to the Ghostscript interpreter.
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @param file_name File name.
+ * @param user_errors If set to 0 errors are returned the normal way (to the
+ * interpreter output), if a negative value is used errors are returns
+ * directly by the function.
+ * @param pexit_code
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_run_file(Pointer instance, String file_name,
+ int user_errors, IntByReference pexit_code);
+
+ /**
+ * Set the callback functions for stdio. The stdin callback function should
+ * return the number of characters read, 0 for EOF, or -1 for error. The
+ * stdout and stderr callback functions should return the number of
+ * characters written.
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @param stdin_fn Stdin callback function.
+ * @param stdout_fn Stdout callback function.
+ * @param stderr_fn Stderr callback function.
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_set_stdio(Pointer instance, stdin_fn stdin_fn,
+ stdout_fn stdout_fn, stderr_fn stderr_fn);
+
+ /**
+ * Set the callback structure for the display device. If the display device
+ * is used, this must be called after gsapi_new_instance() and before
+ * gsapi_init_with_args(). See gdevdsp.h for more details.
+ *
+ * @param instance Pointer to the Ghostscript instance.
+ * @param callback display_callback_s Structure holding display callback
+ * functions.
+ * @return 0 if everything is OK, < 0 otherwise
+ */
+ public int gsapi_set_display_callback(Pointer instance, Structure callback);
}
diff --git a/src/main/java/org/ghost4j/GhostscriptLibraryLoader.java b/src/main/java/org/ghost4j/GhostscriptLibraryLoader.java
index 19d3673..428beb9 100644
--- a/src/main/java/org/ghost4j/GhostscriptLibraryLoader.java
+++ b/src/main/java/org/ghost4j/GhostscriptLibraryLoader.java
@@ -16,27 +16,27 @@
*/
public class GhostscriptLibraryLoader {
- /**
- * Load native library according to host OS.
- *
- * @return The loaded library.
- */
- protected static GhostscriptLibrary loadLibrary() {
+ /**
+ * Load native library according to host OS.
+ *
+ * @return The loaded library.
+ */
+ protected static GhostscriptLibrary loadLibrary() {
- // library name
- String libName = "gs";
+ // library name
+ String libName = "gs";
- // on Windows: library has a different name according to the
- // architecture
- if (Platform.isWindows()) {
- // architecture
- String arch = System.getProperty("sun.arch.data.model");
+ // on Windows: library has a different name according to the
+ // architecture
+ if (Platform.isWindows()) {
+ // architecture
+ String arch = System.getProperty("sun.arch.data.model");
- libName = "gsdll" + arch;
+ libName = "gsdll" + arch;
- }
+ }
- return (GhostscriptLibrary) Native.loadLibrary(libName,
- GhostscriptLibrary.class);
- }
+ return (GhostscriptLibrary) Native.load(libName,
+ GhostscriptLibrary.class);
+ }
}
diff --git a/src/main/java/org/ghost4j/GhostscriptLoggerOutputStream.java b/src/main/java/org/ghost4j/GhostscriptLoggerOutputStream.java
index ca84b9d..a1abc0c 100644
--- a/src/main/java/org/ghost4j/GhostscriptLoggerOutputStream.java
+++ b/src/main/java/org/ghost4j/GhostscriptLoggerOutputStream.java
@@ -21,62 +21,62 @@
*/
public class GhostscriptLoggerOutputStream extends OutputStream {
- /**
- * Logger name.
- */
- private static final String LOGGER_NAME = Ghostscript.class.getName();
+ /**
+ * Logger name.
+ */
+ private static final String LOGGER_NAME = Ghostscript.class.getName();
- /**
- * Line termination for a log message.
- */
- private static final int LINE_END = (int) '\n';
+ /**
+ * Line termination for a log message.
+ */
+ private static final int LINE_END = (int) '\n';
- /**
- * ByteArrayOutputStream used to store outputed messages being written.
- */
- private ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ /**
+ * ByteArrayOutputStream used to store outputed messages being written.
+ */
+ private ByteArrayOutputStream baos = new ByteArrayOutputStream();
- /**
- * Logger used to log messages.
- */
- private Logger logger;
+ /**
+ * Logger used to log messages.
+ */
+ private final Logger logger;
- /**
- * Log level used when outputing messages to the logger.
- */
- private Level level;
+ /**
+ * Log level used when outputing messages to the logger.
+ */
+ private final Level level;
- /**
- * Constructor.
- *
- * @param level
- * Defines the log level of outputed messages.
- */
- public GhostscriptLoggerOutputStream(Level level) {
- logger = LoggerFactory.getLogger(LOGGER_NAME);
- baos = new ByteArrayOutputStream();
- this.level = level;
- }
+ /**
+ * Constructor.
+ *
+ * @param level
+ * Defines the log level of outputed messages.
+ */
+ public GhostscriptLoggerOutputStream(final Level level) {
+ logger = LoggerFactory.getLogger(LOGGER_NAME);
+ baos = new ByteArrayOutputStream();
+ this.level = level;
+ }
- /**
- * Write method that stores data to write in the ByteArrayOutputStream and
- * sends messages to the logger when a line ends.
- *
- * @param b
- * Byte to write
- * @throws IOException
- */
- public void write(int b) throws IOException {
+ /**
+ * Write method that stores data to write in the ByteArrayOutputStream and
+ * sends messages to the logger when a line ends.
+ *
+ * @param b
+ * Byte to write
+ * @throws IOException
+ */
+ public void write(int b) throws IOException {
- if (b == LINE_END) {
- if (level == Level.INFO) {
- logger.info(baos.toString());
- } else if (level == Level.ERROR) {
- logger.error(baos.toString());
- }
- baos.reset();
- } else {
- baos.write(b);
+ if (b == LINE_END) {
+ if (level == Level.INFO) {
+ logger.info(baos.toString());
+ } else if (level == Level.ERROR) {
+ logger.error(baos.toString());
+ }
+ baos.reset();
+ } else {
+ baos.write(b);
+ }
}
- }
}
diff --git a/src/main/java/org/ghost4j/GhostscriptRevision.java b/src/main/java/org/ghost4j/GhostscriptRevision.java
index 84d10b2..dd6f0de 100644
--- a/src/main/java/org/ghost4j/GhostscriptRevision.java
+++ b/src/main/java/org/ghost4j/GhostscriptRevision.java
@@ -6,7 +6,8 @@
*/
package org.ghost4j;
-import java.util.Date;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
/**
* Class used to carry Ghostscript revision data.
@@ -15,52 +16,60 @@
*/
public class GhostscriptRevision {
- /**
- * Product name.
- */
- private String product;
- /**
- * Copyright.
- */
- private String copyright;
- /**
- * Revision number.
- */
- private String number;
- /**
- * Revision date.
- */
- private Date revisionDate;
+ /**
+ * Product name.
+ */
+ private String product;
+ /**
+ * Copyright.
+ */
+ private String copyright;
+ /**
+ * Revision number.
+ */
+ private long number;
+ /**
+ * Revision date.
+ */
+ private LocalDate revisionDate;
- public String getProduct() {
- return product;
- }
+ public String getProduct() {
+ return product;
+ }
- public void setProduct(String product) {
- this.product = product;
- }
+ public void setProduct(final String product) {
+ this.product = product;
+ }
- public String getCopyright() {
- return copyright;
- }
+ public String getCopyright() {
+ return copyright;
+ }
- public void setCopyright(String copyright) {
- this.copyright = copyright;
- }
+ public void setCopyright(final String copyright) {
+ this.copyright = copyright;
+ }
- public Date getRevisionDate() {
- return revisionDate;
- }
+ public LocalDate getRevisionDate() {
+ return revisionDate;
+ }
- public void setRevisionDate(Date revisionDate) {
- this.revisionDate = revisionDate;
- }
+ public String getRevisionDateFormatted() {
+ if (revisionDate != null) {
+ return revisionDate.format(DateTimeFormatter.ISO_DATE);
+ } else {
+ return "unavailable";
+ }
+ }
- public String getNumber() {
- return number;
- }
+ public void setRevisionDate(final LocalDate revisionDate) {
+ this.revisionDate = revisionDate;
+ }
- public void setNumber(String number) {
- this.number = number;
- }
+ public long getNumber() {
+ return number;
+ }
+
+ public void setNumber(final long number) {
+ this.number = number;
+ }
}
diff --git a/src/main/java/org/ghost4j/converter/AbstractConverter.java b/src/main/java/org/ghost4j/converter/AbstractConverter.java
index 57fa51e..fc06e14 100644
--- a/src/main/java/org/ghost4j/converter/AbstractConverter.java
+++ b/src/main/java/org/ghost4j/converter/AbstractConverter.java
@@ -20,16 +20,16 @@
* @author Gilles Grousset (gi.grousset@gmail.com)
*/
public abstract class AbstractConverter extends AbstractComponent implements
- Converter {
+Converter {
- public void convert(Document document, OutputStream outputStream)
- throws IOException, ConverterException, DocumentException {
+ public void convert(Document document, OutputStream outputStream)
+ throws IOException, ConverterException, DocumentException {
- // perform actual processing
- run(document, outputStream);
+ // perform actual processing
+ run(document, outputStream);
- }
+ }
- protected abstract void run(Document document, OutputStream outputStream)
- throws IOException, ConverterException, DocumentException;
+ protected abstract void run(Document document, OutputStream outputStream)
+ throws IOException, ConverterException, DocumentException;
}
diff --git a/src/main/java/org/ghost4j/converter/AbstractRemoteConverter.java b/src/main/java/org/ghost4j/converter/AbstractRemoteConverter.java
index 68a6871..41ee119 100644
--- a/src/main/java/org/ghost4j/converter/AbstractRemoteConverter.java
+++ b/src/main/java/org/ghost4j/converter/AbstractRemoteConverter.java
@@ -25,117 +25,117 @@
* @author Gilles Grousset (gi.grousset@gmail.com)
*/
public abstract class AbstractRemoteConverter extends AbstractRemoteComponent
- implements RemoteConverter {
-
- protected abstract void run(Document document, OutputStream outputStream)
- throws IOException, ConverterException, DocumentException;
-
- /**
- * Starts a remote converter server.
- *
- * @param remoteConverter
- * @throws ConverterException
- */
- protected static void startRemoteConverter(RemoteConverter remoteConverter)
- throws ConverterException {
-
- try {
-
- // get port
- if (System.getenv("cajo.port") == null) {
- throw new ConverterException(
- "No Cajo port defined for remote converter");
- }
- int cajoPort = Integer.parseInt(System.getenv("cajo.port"));
-
- // export converter
- RemoteConverter converterCopy = remoteConverter.getClass()
- .newInstance();
- converterCopy.setMaxProcessCount(0);
-
- Remote.config(null, cajoPort, null, 0);
- ItemServer.bind(converterCopy,
- RemoteConverter.class.getCanonicalName());
-
- } catch (Exception e) {
- throw new ConverterException(e);
+implements RemoteConverter {
+
+ protected abstract void run(Document document, OutputStream outputStream)
+ throws IOException, ConverterException, DocumentException;
+
+ /**
+ * Starts a remote converter server.
+ *
+ * @param remoteConverter
+ * @throws ConverterException
+ */
+ protected static void startRemoteConverter(RemoteConverter remoteConverter)
+ throws ConverterException {
+
+ try {
+
+ // get port
+ if (System.getenv("cajo.port") == null) {
+ throw new ConverterException(
+ "No Cajo port defined for remote converter");
+ }
+ int cajoPort = Integer.parseInt(System.getenv("cajo.port"));
+
+ // export converter
+ RemoteConverter converterCopy = remoteConverter.getClass()
+ .getDeclaredConstructor().newInstance();
+ converterCopy.setMaxProcessCount(0);
+
+ Remote.config(null, cajoPort, null, 0);
+ ItemServer.bind(converterCopy,
+ RemoteConverter.class.getCanonicalName());
+
+ } catch (Exception e) {
+ throw new ConverterException(e);
+ }
+
}
- }
+ public byte[] remoteConvert(Document document) throws IOException,
+ ConverterException, DocumentException {
- public byte[] remoteConvert(Document document) throws IOException,
- ConverterException, DocumentException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ run(document, baos);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- run(document, baos);
+ byte[] result = baos.toByteArray();
+ baos.close();
- byte[] result = baos.toByteArray();
- baos.close();
+ return result;
- return result;
+ }
- }
+ public void convert(Document document, OutputStream outputStream)
+ throws IOException, ConverterException, DocumentException {
- public void convert(Document document, OutputStream outputStream)
- throws IOException, ConverterException, DocumentException {
+ if (maxProcessCount == 0) {
- if (maxProcessCount == 0) {
+ // perform actual processing
+ run(document, outputStream);
- // perform actual processing
- run(document, outputStream);
+ } else {
- } else {
+ // handle parallel processes
- // handle parallel processes
+ // wait for a process to get free
+ this.waitForFreeProcess();
+ processCount++;
- // wait for a process to get free
- this.waitForFreeProcess();
- processCount++;
+ // check if current class supports stand alone mode
+ if (!this.isStandAloneModeSupported()) {
+ throw new ConverterException(
+ "Standalone mode is not supported by this converter: no 'main' method found");
+ }
- // check if current class supports stand alone mode
- if (!this.isStandAloneModeSupported()) {
- throw new ConverterException(
- "Standalone mode is not supported by this converter: no 'main' method found");
- }
+ // prepare new JVM
+ JavaFork fork = this.buildJavaFork();
- // prepare new JVM
- JavaFork fork = this.buildJavaFork();
+ // set JVM Xmx parameter according to the document size
+ int documentMbSize = (document.getSize() / 1024 / 1024) + 1;
+ int xmxValue = 64 + documentMbSize;
+ fork.setXmx(xmxValue + "m");
- // set JVM Xmx parameter according to the document size
- int documentMbSize = (document.getSize() / 1024 / 1024) + 1;
- int xmxValue = 64 + documentMbSize;
- fork.setXmx(xmxValue + "m");
+ int cajoPort = 0;
- int cajoPort = 0;
+ try {
- try {
+ // start remove server
+ cajoPort = this.startRemoteServer(fork);
- // start remove server
- cajoPort = this.startRemoteServer(fork);
+ // get remote component
+ Object remote = this.getRemoteComponent(cajoPort,
+ RemoteConverter.class);
- // get remote component
- Object remote = this.getRemoteComponent(cajoPort,
- RemoteConverter.class);
+ // copy converter settings to remote converter
+ Remote.invoke(remote, "copySettings", this.extractSettings());
- // copy converter settings to remote converter
- Remote.invoke(remote, "copySettings", this.extractSettings());
+ // perform remote conversion
+ byte[] result = (byte[]) Remote.invoke(remote, "remoteConvert",
+ document);
- // perform remote conversion
- byte[] result = (byte[]) Remote.invoke(remote, "remoteConvert",
- document);
+ // write result to output stream
+ outputStream.write(result);
- // write result to output stream
- outputStream.write(result);
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ConverterException(e);
+ } finally {
+ processCount--;
+ fork.stop();
+ }
+ }
- } catch (IOException e) {
- throw e;
- } catch (Exception e) {
- throw new ConverterException(e);
- } finally {
- processCount--;
- fork.stop();
- }
}
-
- }
}
diff --git a/src/main/java/org/ghost4j/converter/Converter.java b/src/main/java/org/ghost4j/converter/Converter.java
index f8378ec..37dd5d4 100644
--- a/src/main/java/org/ghost4j/converter/Converter.java
+++ b/src/main/java/org/ghost4j/converter/Converter.java
@@ -21,19 +21,19 @@
*/
public interface Converter extends Component {
- /**
- * Converts a given document and output results in provided output stream.
- *
- * @param document
- * Document to convert. Document type may or may no be supported
- * (support left to the convert final implementation).
- * @param outputStream
- * Output stream where converted document is written.
- * @throws IOException
- * @throws ConverterException
- * @throws DocumentException
- */
- public void convert(Document document, OutputStream outputStream)
- throws IOException, ConverterException, DocumentException;
+ /**
+ * Converts a given document and output results in provided output stream.
+ *
+ * @param document
+ * Document to convert. Document type may or may no be supported
+ * (support left to the convert final implementation).
+ * @param outputStream
+ * Output stream where converted document is written.
+ * @throws IOException
+ * @throws ConverterException
+ * @throws DocumentException
+ */
+ public void convert(Document document, OutputStream outputStream)
+ throws IOException, ConverterException, DocumentException;
}
diff --git a/src/main/java/org/ghost4j/converter/ConverterException.java b/src/main/java/org/ghost4j/converter/ConverterException.java
index e50a535..98c4a63 100644
--- a/src/main/java/org/ghost4j/converter/ConverterException.java
+++ b/src/main/java/org/ghost4j/converter/ConverterException.java
@@ -15,24 +15,24 @@
*/
public class ConverterException extends Exception {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = -4246261539550729104L;
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = -4246261539550729104L;
- public ConverterException() {
- super();
- }
+ public ConverterException() {
+ super();
+ }
- public ConverterException(String message) {
- super(message);
- }
+ public ConverterException(String message) {
+ super(message);
+ }
- public ConverterException(Throwable cause) {
- super(cause);
- }
+ public ConverterException(Throwable cause) {
+ super(cause);
+ }
- public ConverterException(String message, Throwable cause) {
- super(message, cause);
- }
+ public ConverterException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/src/main/java/org/ghost4j/converter/PDFConverter.java b/src/main/java/org/ghost4j/converter/PDFConverter.java
index 29ed9cb..94cdb7a 100644
--- a/src/main/java/org/ghost4j/converter/PDFConverter.java
+++ b/src/main/java/org/ghost4j/converter/PDFConverter.java
@@ -13,7 +13,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-
import org.apache.commons.io.IOUtils;
import org.ghost4j.Ghostscript;
import org.ghost4j.GhostscriptException;
@@ -22,6 +21,8 @@
import org.ghost4j.document.PSDocument;
import org.ghost4j.document.PaperSize;
import org.ghost4j.util.DiskStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* PDF converter.
@@ -30,297 +31,308 @@
*/
public class PDFConverter extends AbstractRemoteConverter {
- public static final int OPTION_AUTOROTATEPAGES_NONE = 0;
- public static final int OPTION_AUTOROTATEPAGES_ALL = 1;
- public static final int OPTION_AUTOROTATEPAGES_PAGEBYPAGE = 2;
- public static final int OPTION_AUTOROTATEPAGES_OFF = 3;
-
- public static final int OPTION_PROCESSCOLORMODEL_RGB = 0;
- public static final int OPTION_PROCESSCOLORMODEL_GRAY = 1;
- public static final int OPTION_PROCESSCOLORMODEL_CMYK = 2;
-
- public static final int OPTION_PDFSETTINGS_DEFAULT = 0;
- public static final int OPTION_PDFSETTINGS_SCREEN = 1;
- public static final int OPTION_PDFSETTINGS_EBOOK = 2;
- public static final int OPTION_PDFSETTINGS_PRINTER = 3;
- public static final int OPTION_PDFSETTINGS_PREPRESS = 4;
-
- /**
- * Define auto rotate pages behaviour. Can be OPTION_AUTOROTATEPAGES_NONE,
- * OPTION_AUTOROTATEPAGES_ALL, OPTION_AUTOROTATEPAGES_PAGEBYPAGE or
- * OPTION_AUTOROTATEPAGES_OFF (default).
- */
- private int autoRotatePages = OPTION_AUTOROTATEPAGES_OFF;
-
- /**
- * Define process color model. Can be OPTION_PROCESSCOLORMODEL_RGB,
- * OPTION_PROCESSCOLORMODEL_GRAY or OPTION_PROCESSCOLORMODEL_CMYK.
- */
- private int processColorModel;
-
- /**
- * Define PDF settings to use. Can be OPTION_PDFSETTINGS_DEFAULT,
- * OPTION_PDFSETTINGS_SCREEN, OPTION_PDFSETTINGS_EBOOK,
- * OPTION_PDFSETTINGS_PRINTER or OPTION_PDFSETTINGS_PREPRESS.
- */
- private int PDFSettings;
-
- /**
- * Define PDF version compatibility level (default is "1.4").
- */
- private String compatibilityLevel = "1.4";
-
- /**
- * Enable PDFX generation (default is false).
- */
- private boolean PDFX = false;
-
- /**
- * Define standard paper size for the generated PDF file. This parameter is
- * ignored if a paper size is provided in the input file. Default value is
- * "letter".
- */
- private PaperSize paperSize = PaperSize.LETTER;
-
- public PDFConverter() {
-
- // set supported classes
- supportedDocumentClasses = new Class[1];
- supportedDocumentClasses[0] = PSDocument.class;
- }
-
- /**
- * Main method used to start the converter in standalone 'slave mode'.
- *
- * @param args
- * @throws ConverterException
- */
- public static void main(String args[]) throws ConverterException {
-
- startRemoteConverter(new PDFConverter());
- }
-
- /**
- * Run method called to perform the actual process of the converter.
- *
- * @param document
- * @param outputStream
- * @throws IOException
- * @throws ConverterException
- * @throws DocumentException
- */
- @Override
- public void run(Document document, OutputStream outputStream)
- throws IOException, ConverterException, DocumentException {
-
- // if no output = nothing to do
- if (outputStream == null) {
- return;
+ public static final int OPTION_AUTOROTATEPAGES_NONE = 0;
+ public static final int OPTION_AUTOROTATEPAGES_ALL = 1;
+ public static final int OPTION_AUTOROTATEPAGES_PAGEBYPAGE = 2;
+ public static final int OPTION_AUTOROTATEPAGES_OFF = 3;
+
+ public static final int OPTION_PROCESSCOLORMODEL_RGB = 0;
+ public static final int OPTION_PROCESSCOLORMODEL_GRAY = 1;
+ public static final int OPTION_PROCESSCOLORMODEL_CMYK = 2;
+
+ public static final int OPTION_PDFSETTINGS_DEFAULT = 0;
+ public static final int OPTION_PDFSETTINGS_SCREEN = 1;
+ public static final int OPTION_PDFSETTINGS_EBOOK = 2;
+ public static final int OPTION_PDFSETTINGS_PRINTER = 3;
+ public static final int OPTION_PDFSETTINGS_PREPRESS = 4;
+
+ /**
+ * Logger name.
+ */
+ private static final String LOGGER_NAME = Ghostscript.class.getName();
+
+ /**
+ * Define auto rotate pages behaviour. Can be OPTION_AUTOROTATEPAGES_NONE,
+ * OPTION_AUTOROTATEPAGES_ALL, OPTION_AUTOROTATEPAGES_PAGEBYPAGE or
+ * OPTION_AUTOROTATEPAGES_OFF (default).
+ */
+ private int autoRotatePages = OPTION_AUTOROTATEPAGES_OFF;
+
+ /**
+ * Define process color model. Can be OPTION_PROCESSCOLORMODEL_RGB,
+ * OPTION_PROCESSCOLORMODEL_GRAY or OPTION_PROCESSCOLORMODEL_CMYK.
+ */
+ private int processColorModel;
+
+ /**
+ * Define PDF settings to use. Can be OPTION_PDFSETTINGS_DEFAULT,
+ * OPTION_PDFSETTINGS_SCREEN, OPTION_PDFSETTINGS_EBOOK,
+ * OPTION_PDFSETTINGS_PRINTER or OPTION_PDFSETTINGS_PREPRESS.
+ */
+ private int PDFSettings;
+
+ /**
+ * Define PDF version compatibility level (default is "1.4").
+ */
+ private String compatibilityLevel = "1.4";
+
+ /**
+ * Enable PDFX generation (default is false).
+ */
+ private boolean PDFX = false;
+
+ /**
+ * Define standard paper size for the generated PDF file. This parameter is
+ * ignored if a paper size is provided in the input file. Default value is
+ * "letter".
+ */
+ private PaperSize paperSize = PaperSize.LETTER;
+
+ public PDFConverter() {
+
+ // set supported classes
+ supportedDocumentClasses = new Class[1];
+ supportedDocumentClasses[0] = PSDocument.class;
}
- // assert document is supported
- this.assertDocumentSupported(document);
+ /**
+ * Main method used to start the converter in standalone 'slave mode'.
+ *
+ * @param args
+ * @throws ConverterException
+ */
+ public static void main(String args[]) throws ConverterException {
- // get Ghostscript instance
- Ghostscript gs = Ghostscript.getInstance();
+ startRemoteConverter(new PDFConverter());
+ }
- // generate a unique diskstore key
- DiskStore diskStore = DiskStore.getInstance();
- String diskStoreKey = diskStore.generateUniqueKey();
+ /**
+ * Run method called to perform the actual process of the converter.
+ *
+ * @param document
+ * @param outputStream
+ * @throws IOException
+ * @throws ConverterException
+ * @throws DocumentException
+ */
+ @Override
+ public void run(Document document, OutputStream outputStream)
+ throws IOException, ConverterException, DocumentException {
+
+ // if no output = nothing to do
+ if (outputStream == null) {
+ return;
+ }
+
+ // assert document is supported
+ this.assertDocumentSupported(document);
+
+ // get Ghostscript instance
+ Ghostscript gs = Ghostscript.getInstance();
+
+ // generate a unique diskstore key
+ DiskStore diskStore = DiskStore.getInstance();
+ String diskStoreKey = diskStore.generateUniqueKey();
+
+ // prepare Ghostscript interpreter parameters
+ int argCount = 15;
+ if (autoRotatePages != OPTION_AUTOROTATEPAGES_OFF) {
+ argCount++;
+ }
+ String[] gsArgs = new String[argCount];
+
+ gsArgs[0] = "-ps2pdf"; // the first argument in the arg array is ignored
+ gsArgs[1] = "-dNOPAUSE";
+ gsArgs[2] = "-dBATCH";
+ gsArgs[3] = "-dSAFER";
+
+ int paramPosition = 3;
+
+ // autorotatepages
+ switch (autoRotatePages) {
+ case OPTION_AUTOROTATEPAGES_NONE:
+ paramPosition++;
+ gsArgs[paramPosition] = "-dAutoRotatePages=/None";
+ break;
+ case OPTION_AUTOROTATEPAGES_ALL:
+ paramPosition++;
+ gsArgs[paramPosition] = "-dAutoRotatePages=/All";
+ break;
+ case OPTION_AUTOROTATEPAGES_PAGEBYPAGE:
+ paramPosition++;
+ gsArgs[paramPosition] = "-dAutoRotatePages=/PageByPage";
+ break;
+ default:
+ // nothing
+ break;
+
+ }
+
+ // processcolormodel
+ paramPosition++;
+ switch (processColorModel) {
+ case OPTION_PROCESSCOLORMODEL_CMYK:
+ gsArgs[paramPosition] = "-dProcessColorModel=/DeviceCMYK";
+ break;
+ case OPTION_PROCESSCOLORMODEL_GRAY:
+ gsArgs[paramPosition] = "-dProcessColorModel=/DeviceGray";
+ break;
+ default:
+ gsArgs[paramPosition] = "-dProcessColorModel=/DeviceRGB";
+ }
+
+ // pdf settings
+ paramPosition++;
+ switch (PDFSettings) {
+ case OPTION_PDFSETTINGS_EBOOK:
+ gsArgs[paramPosition] = "-dPDFSETTINGS=/ebook";
+ break;
+ case OPTION_PDFSETTINGS_SCREEN:
+ gsArgs[paramPosition] = "-dPDFSETTINGS=/screen";
+ break;
+ case OPTION_PDFSETTINGS_PRINTER:
+ gsArgs[paramPosition] = "-dPDFSETTINGS=/printer";
+ break;
+ case OPTION_PDFSETTINGS_PREPRESS:
+ gsArgs[paramPosition] = "-dPDFSETTINGS=/prepress";
+ break;
+ default:
+ gsArgs[paramPosition] = "-dPDFSETTINGS=/default";
+ }
+
+ // compatibilitylevel
+ paramPosition++;
+ gsArgs[paramPosition] = "-dCompatibilityLevel=" + compatibilityLevel;
+
+ // PDFX
+ paramPosition++;
+ gsArgs[paramPosition] = "-dPDFX=" + PDFX;
+
+ // papersize
+ paramPosition++;
+ gsArgs[paramPosition] = "-dDEVICEWIDTHPOINTS=" + paperSize.getWidth();
+ paramPosition++;
+ gsArgs[paramPosition] = "-dDEVICEHEIGHTPOINTS=" + paperSize.getHeight();
+
+ paramPosition++;
+ gsArgs[paramPosition] = "-sDEVICE=pdfwrite";
+ // output to file, as stdout redirect does not work properly
+ paramPosition++;
+ gsArgs[paramPosition] = "-sOutputFile="
+ + diskStore.addFile(diskStoreKey).getAbsolutePath();
+ paramPosition++;
+ gsArgs[paramPosition] = "-q";
+ paramPosition++;
+ gsArgs[paramPosition] = "-f";
+ paramPosition++;
+ gsArgs[paramPosition] = "-";
+
+ InputStream is = new ByteArrayInputStream(document.getContent());
+
+ try {
+
+ // execute and exit interpreter
+ synchronized (gs) {
+ Logger logger = LoggerFactory.getLogger(LOGGER_NAME);
+ logger.debug("Arguments to gs:");
+
+ for (String arg : gsArgs) {
+ logger.debug(arg);
+ }
+
+ gs.setStdIn(is);
+ gs.initialize(gsArgs);
+ }
+
+ // write obtained file to output stream
+ File outputFile = diskStore.getFile(diskStoreKey);
+ if (outputFile == null) {
+ throw new ConverterException("Cannot retrieve file with key "
+ + diskStoreKey + " from disk store");
+ }
+
+ FileInputStream fis = new FileInputStream(outputFile);
+ byte[] content = new byte[(int) outputFile.length()];
+ fis.read(content);
+ fis.close();
+
+ outputStream.write(content);
+
+ } catch (GhostscriptException e) {
+
+ throw new ConverterException(e);
+
+ } finally {
+
+ IOUtils.closeQuietly(is);
+
+ // delete Ghostscript instance
+ try {
+ Ghostscript.deleteInstance();
+ } catch (GhostscriptException e) {
+ throw new ConverterException(e);
+ }
+
+ // remove temporary file
+ diskStore.removeFile(diskStoreKey);
+ }
- // prepare Ghostscript interpreter parameters
- int argCount = 15;
- if (autoRotatePages != OPTION_AUTOROTATEPAGES_OFF) {
- argCount++;
}
- String[] gsArgs = new String[argCount];
-
- gsArgs[0] = "-ps2pdf";
- gsArgs[1] = "-dNOPAUSE";
- gsArgs[2] = "-dBATCH";
- gsArgs[3] = "-dSAFER";
-
- int paramPosition = 3;
-
- // autorotatepages
- switch (autoRotatePages) {
- case OPTION_AUTOROTATEPAGES_NONE:
- paramPosition++;
- gsArgs[paramPosition] = "-dAutoRotatePages=/None";
- break;
- case OPTION_AUTOROTATEPAGES_ALL:
- paramPosition++;
- gsArgs[paramPosition] = "-dAutoRotatePages=/All";
- break;
- case OPTION_AUTOROTATEPAGES_PAGEBYPAGE:
- paramPosition++;
- gsArgs[paramPosition] = "-dAutoRotatePages=/PageByPage";
- break;
- default:
- // nothing
- break;
+ public int getAutoRotatePages() {
+ return autoRotatePages;
}
- // processcolormodel
- paramPosition++;
- switch (processColorModel) {
- case OPTION_PROCESSCOLORMODEL_CMYK:
- gsArgs[paramPosition] = "-dProcessColorModel=/DeviceCMYK";
- break;
- case OPTION_PROCESSCOLORMODEL_GRAY:
- gsArgs[paramPosition] = "-dProcessColorModel=/DeviceGray";
- break;
- default:
- gsArgs[paramPosition] = "-dProcessColorModel=/DeviceRGB";
+ public void setAutoRotatePages(int autoRotatePages) {
+ this.autoRotatePages = autoRotatePages;
}
- // pdf settings
- paramPosition++;
- switch (PDFSettings) {
- case OPTION_PDFSETTINGS_EBOOK:
- gsArgs[paramPosition] = "-dPDFSETTINGS=/ebook";
- break;
- case OPTION_PDFSETTINGS_SCREEN:
- gsArgs[paramPosition] = "-dPDFSETTINGS=/screen";
- break;
- case OPTION_PDFSETTINGS_PRINTER:
- gsArgs[paramPosition] = "-dPDFSETTINGS=/printer";
- break;
- case OPTION_PDFSETTINGS_PREPRESS:
- gsArgs[paramPosition] = "-dPDFSETTINGS=/prepress";
- break;
- default:
- gsArgs[paramPosition] = "-dPDFSETTINGS=/default";
+ public int getProcessColorModel() {
+ return processColorModel;
}
- // compatibilitylevel
- paramPosition++;
- gsArgs[paramPosition] = "-dCompatibilityLevel=" + compatibilityLevel;
-
- // PDFX
- paramPosition++;
- gsArgs[paramPosition] = "-dPDFX=" + PDFX;
-
- // papersize
- paramPosition++;
- gsArgs[paramPosition] = "-dDEVICEWIDTHPOINTS=" + paperSize.getWidth();
- paramPosition++;
- gsArgs[paramPosition] = "-dDEVICEHEIGHTPOINTS=" + paperSize.getHeight();
-
- paramPosition++;
- gsArgs[paramPosition] = "-sDEVICE=pdfwrite";
- // output to file, as stdout redirect does not work properly
- paramPosition++;
- gsArgs[paramPosition] = "-sOutputFile="
- + diskStore.addFile(diskStoreKey).getAbsolutePath();
- paramPosition++;
- gsArgs[paramPosition] = "-q";
- paramPosition++;
- gsArgs[paramPosition] = "-f";
- paramPosition++;
- gsArgs[paramPosition] = "-";
-
- InputStream is = new ByteArrayInputStream(document.getContent());
-
- try {
-
- // execute and exit interpreter
- synchronized (gs) {
- gs.setStdIn(is);
- gs.initialize(gsArgs);
-
- }
-
- // write obtained file to output stream
- File outputFile = diskStore.getFile(diskStoreKey);
- if (outputFile == null) {
- throw new ConverterException("Cannot retrieve file with key "
- + diskStoreKey + " from disk store");
- }
-
- FileInputStream fis = new FileInputStream(outputFile);
- byte[] content = new byte[(int) outputFile.length()];
- fis.read(content);
- fis.close();
-
- outputStream.write(content);
-
- } catch (GhostscriptException e) {
-
- throw new ConverterException(e);
-
- } finally {
-
- IOUtils.closeQuietly(is);
-
- // delete Ghostscript instance
- try {
- Ghostscript.deleteInstance();
- } catch (GhostscriptException e) {
- throw new ConverterException(e);
- }
-
- // remove temporary file
- diskStore.removeFile(diskStoreKey);
+ public void setProcessColorModel(int processColorModel) {
+ this.processColorModel = processColorModel;
}
- }
-
- public int getAutoRotatePages() {
- return autoRotatePages;
- }
-
- public void setAutoRotatePages(int autoRotatePages) {
- this.autoRotatePages = autoRotatePages;
- }
-
- public int getProcessColorModel() {
- return processColorModel;
- }
-
- public void setProcessColorModel(int processColorModel) {
- this.processColorModel = processColorModel;
- }
-
- public String getCompatibilityLevel() {
- return compatibilityLevel;
- }
+ public String getCompatibilityLevel() {
+ return compatibilityLevel;
+ }
- public void setCompatibilityLevel(String compatibilityLevel) {
- this.compatibilityLevel = compatibilityLevel;
- }
+ public void setCompatibilityLevel(String compatibilityLevel) {
+ this.compatibilityLevel = compatibilityLevel;
+ }
- public int getPDFSettings() {
- return PDFSettings;
- }
+ public int getPDFSettings() {
+ return PDFSettings;
+ }
- public void setPDFSettings(int PDFSettings) {
- this.PDFSettings = PDFSettings;
- }
+ public void setPDFSettings(int PDFSettings) {
+ this.PDFSettings = PDFSettings;
+ }
- public boolean isPDFX() {
- return PDFX;
- }
+ public boolean isPDFX() {
+ return PDFX;
+ }
- public void setPDFX(boolean PDFX) {
- this.PDFX = PDFX;
- }
+ public void setPDFX(boolean PDFX) {
+ this.PDFX = PDFX;
+ }
- public PaperSize getPaperSize() {
- return paperSize;
- }
+ public PaperSize getPaperSize() {
+ return paperSize;
+ }
- public void setPaperSize(PaperSize paperSize) {
- this.paperSize = paperSize;
- }
+ public void setPaperSize(PaperSize paperSize) {
+ this.paperSize = paperSize;
+ }
- public void setPaperSize(String paperSizeName) {
+ public void setPaperSize(String paperSizeName) {
- PaperSize found = PaperSize.getStandardPaperSize(paperSizeName);
- if (found != null) {
- this.setPaperSize(found);
+ PaperSize found = PaperSize.getStandardPaperSize(paperSizeName);
+ if (found != null) {
+ this.setPaperSize(found);
+ }
}
- }
}
diff --git a/src/main/java/org/ghost4j/converter/PSConverter.java b/src/main/java/org/ghost4j/converter/PSConverter.java
index 4c7e930..511ae85 100644
--- a/src/main/java/org/ghost4j/converter/PSConverter.java
+++ b/src/main/java/org/ghost4j/converter/PSConverter.java
@@ -27,177 +27,177 @@
*/
public class PSConverter extends AbstractRemoteConverter {
- public static final int OPTION_DEVICE_AUTO = 0;
- public static final int OPTION_DEVICE_PSWRITE = 1;
- public static final int OPTION_DEVICE_PS2WRITE = 2;
-
- /**
- * Ghostscript device to use to perform conversion.
- */
- private int device = 0;
-
- /**
- * PostScript language level: 1, 2 or 3.
- */
- private int languageLevel = 3;
-
- /**
- * Define standard paper size for the generated PDF file. This parameter is
- * ignored if a paper size is provided in the input file. Default value is
- * "letter".
- */
- private PaperSize paperSize = PaperSize.LETTER;
-
- public PSConverter() {
-
- // set supported classes
- supportedDocumentClasses = new Class[2];
- supportedDocumentClasses[0] = PSDocument.class;
- supportedDocumentClasses[1] = PDFDocument.class;
- }
-
- /**
- * Main method used to start the converter in standalone 'slave mode'.
- *
- * @param args
- * @throws ConverterException
- */
- public static void main(String args[]) throws ConverterException {
-
- startRemoteConverter(new PSConverter());
- }
-
- @Override
- public void run(Document document, OutputStream outputStream)
- throws IOException, ConverterException, DocumentException {
-
- // if no output = nothing to do
- if (outputStream == null) {
- return;
+ public static final int OPTION_DEVICE_AUTO = 0;
+ public static final int OPTION_DEVICE_PSWRITE = 1;
+ public static final int OPTION_DEVICE_PS2WRITE = 2;
+
+ /**
+ * Ghostscript device to use to perform conversion.
+ */
+ private int device = 0;
+
+ /**
+ * PostScript language level: 1, 2 or 3.
+ */
+ private int languageLevel = 3;
+
+ /**
+ * Define standard paper size for the generated PDF file. This parameter is
+ * ignored if a paper size is provided in the input file. Default value is
+ * "letter".
+ */
+ private PaperSize paperSize = PaperSize.LETTER;
+
+ public PSConverter() {
+
+ // set supported classes
+ supportedDocumentClasses = new Class[2];
+ supportedDocumentClasses[0] = PSDocument.class;
+ supportedDocumentClasses[1] = PDFDocument.class;
}
- // assert document is supported
- this.assertDocumentSupported(document);
-
- // determine device to use
- String deviceName = "";
- try {
- switch (device) {
- case OPTION_DEVICE_PSWRITE:
- deviceName = "pswrite";
- break;
- case OPTION_DEVICE_PS2WRITE:
- deviceName = "ps2write";
- break;
- case OPTION_DEVICE_AUTO:
- // automatic : use ps2write is available otherwise pswrite
- if (this.isDeviceSupported("ps2write")) {
- deviceName = "ps2write";
- } else {
- deviceName = "pswrite";
- }
- break;
- default:
- deviceName = "pswrite";
- break;
- }
- } catch (GhostscriptException e) {
- throw new ConverterException(e);
+ /**
+ * Main method used to start the converter in standalone 'slave mode'.
+ *
+ * @param args
+ * @throws ConverterException
+ */
+ public static void main(String args[]) throws ConverterException {
+
+ startRemoteConverter(new PSConverter());
}
- // get Ghostscript instance
- Ghostscript gs = Ghostscript.getInstance();
-
- // generate a unique diskstore key for output file
- DiskStore diskStore = DiskStore.getInstance();
- String outputDiskStoreKey = diskStore.generateUniqueKey();
- // generate a unique diskstore key for input file
- String inputDiskStoreKey = diskStore.generateUniqueKey();
- // write document to input file
- document.write(diskStore.addFile(inputDiskStoreKey));
-
- // prepare Ghostscript interpreter parameters
- String[] gsArgs = {
- // dummy value to prevent interpreter from blocking
- "-psconv",
- "-dNOPAUSE",
- "-dBATCH",
- "-dSAFER",
- "-dLanguageLevel=" + languageLevel,
- "-dDEVICEWIDTHPOINTS=" + paperSize.getWidth(),
- "-dDEVICEHEIGHTPOINTS=" + paperSize.getHeight(),
- "-sDEVICE=" + deviceName,
- // output to file, as stdout redirect does not work properly
- "-sOutputFile="
- + diskStore.addFile(outputDiskStoreKey)
+ @Override
+ public void run(Document document, OutputStream outputStream)
+ throws IOException, ConverterException, DocumentException {
+
+ // if no output = nothing to do
+ if (outputStream == null) {
+ return;
+ }
+
+ // assert document is supported
+ this.assertDocumentSupported(document);
+
+ // determine device to use
+ String deviceName = "";
+ try {
+ switch (device) {
+ case OPTION_DEVICE_PSWRITE:
+ deviceName = "pswrite";
+ break;
+ case OPTION_DEVICE_PS2WRITE:
+ deviceName = "ps2write";
+ break;
+ case OPTION_DEVICE_AUTO:
+ // automatic : use ps2write is available otherwise pswrite
+ if (this.isDeviceSupported("ps2write")) {
+ deviceName = "ps2write";
+ } else {
+ deviceName = "pswrite";
+ }
+ break;
+ default:
+ deviceName = "pswrite";
+ break;
+ }
+ } catch (GhostscriptException e) {
+ throw new ConverterException(e);
+ }
+
+ // get Ghostscript instance
+ Ghostscript gs = Ghostscript.getInstance();
+
+ // generate a unique diskstore key for output file
+ DiskStore diskStore = DiskStore.getInstance();
+ String outputDiskStoreKey = diskStore.generateUniqueKey();
+ // generate a unique diskstore key for input file
+ String inputDiskStoreKey = diskStore.generateUniqueKey();
+ // write document to input file
+ document.write(diskStore.addFile(inputDiskStoreKey));
+
+ // prepare Ghostscript interpreter parameters
+ String[] gsArgs = {
+ // dummy value to prevent interpreter from blocking
+ "-psconv",
+ "-dNOPAUSE",
+ "-dBATCH",
+ "-dSAFER",
+ "-dLanguageLevel=" + languageLevel,
+ "-dDEVICEWIDTHPOINTS=" + paperSize.getWidth(),
+ "-dDEVICEHEIGHTPOINTS=" + paperSize.getHeight(),
+ "-sDEVICE=" + deviceName,
+ // output to file, as stdout redirect does not work properly
+ "-sOutputFile="
+ + diskStore.addFile(outputDiskStoreKey)
.getAbsolutePath(), "-q", "-f",
- // read from a file as stdin redirect does not work properly
- // with PDF file as input
- diskStore.getFile(inputDiskStoreKey).getAbsolutePath() };
+ // read from a file as stdin redirect does not work properly
+ // with PDF file as input
+ diskStore.getFile(inputDiskStoreKey).getAbsolutePath() };
- try {
+ try {
- // execute and exit interpreter
- synchronized (gs) {
- gs.initialize(gsArgs);
- gs.exit();
- }
+ // execute and exit interpreter
+ synchronized (gs) {
+ gs.initialize(gsArgs);
+ gs.exit();
+ }
- // write obtained file to output stream
- File outputFile = diskStore.getFile(outputDiskStoreKey);
- if (outputFile == null) {
- throw new ConverterException("Cannot retrieve file with key "
- + outputDiskStoreKey + " from disk store");
- }
+ // write obtained file to output stream
+ File outputFile = diskStore.getFile(outputDiskStoreKey);
+ if (outputFile == null) {
+ throw new ConverterException("Cannot retrieve file with key "
+ + outputDiskStoreKey + " from disk store");
+ }
- FileInputStream fis = new FileInputStream(outputFile);
- byte[] content = new byte[(int) outputFile.length()];
- fis.read(content);
- fis.close();
+ FileInputStream fis = new FileInputStream(outputFile);
+ byte[] content = new byte[(int) outputFile.length()];
+ fis.read(content);
+ fis.close();
- outputStream.write(content);
+ outputStream.write(content);
- } catch (GhostscriptException e) {
+ } catch (GhostscriptException e) {
- throw new ConverterException(e);
+ throw new ConverterException(e);
- } finally {
+ } finally {
- // delete Ghostscript instance
- try {
- Ghostscript.deleteInstance();
- } catch (GhostscriptException e) {
- throw new ConverterException(e);
- }
+ // delete Ghostscript instance
+ try {
+ Ghostscript.deleteInstance();
+ } catch (GhostscriptException e) {
+ throw new ConverterException(e);
+ }
- // remove temporary files
- diskStore.removeFile(outputDiskStoreKey);
- diskStore.removeFile(inputDiskStoreKey);
- }
+ // remove temporary files
+ diskStore.removeFile(outputDiskStoreKey);
+ diskStore.removeFile(inputDiskStoreKey);
+ }
- }
+ }
- public int getLanguageLevel() {
- return languageLevel;
- }
+ public int getLanguageLevel() {
+ return languageLevel;
+ }
- public void setLanguageLevel(int languageLevel) {
- this.languageLevel = languageLevel;
- }
+ public void setLanguageLevel(int languageLevel) {
+ this.languageLevel = languageLevel;
+ }
- public PaperSize getPaperSize() {
- return paperSize;
- }
+ public PaperSize getPaperSize() {
+ return paperSize;
+ }
- public void setPaperSize(PaperSize paperSize) {
- this.paperSize = paperSize;
- }
+ public void setPaperSize(PaperSize paperSize) {
+ this.paperSize = paperSize;
+ }
- public int getDevice() {
- return device;
- }
+ public int getDevice() {
+ return device;
+ }
- public void setDevice(int device) {
- this.device = device;
- }
+ public void setDevice(int device) {
+ this.device = device;
+ }
}
diff --git a/src/main/java/org/ghost4j/converter/RemoteConverter.java b/src/main/java/org/ghost4j/converter/RemoteConverter.java
index a5fd206..7656f3f 100644
--- a/src/main/java/org/ghost4j/converter/RemoteConverter.java
+++ b/src/main/java/org/ghost4j/converter/RemoteConverter.java
@@ -14,11 +14,11 @@
*/
public interface RemoteConverter extends Converter {
- /**
- * Sets max parallel conversion processes allowed for the converter
- *
- * @param maxProcessCount
- */
- public void setMaxProcessCount(int maxProcessCount);
+ /**
+ * Sets max parallel conversion processes allowed for the converter
+ *
+ * @param maxProcessCount
+ */
+ public void setMaxProcessCount(int maxProcessCount);
}
diff --git a/src/main/java/org/ghost4j/display/DisplayCallback.java b/src/main/java/org/ghost4j/display/DisplayCallback.java
index eb0f5bb..4cf59e2 100644
--- a/src/main/java/org/ghost4j/display/DisplayCallback.java
+++ b/src/main/java/org/ghost4j/display/DisplayCallback.java
@@ -24,106 +24,106 @@
*/
public interface DisplayCallback {
- /**
- * Method called when new device has been opened. This is the first event
- * from this device.
- *
- * @throws org.ghost4j.GhostscriptException
- */
- public void displayOpen() throws GhostscriptException;
+ /**
+ * Method called when new device has been opened. This is the first event
+ * from this device.
+ *
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void displayOpen() throws GhostscriptException;
- /**
- * Method called when device is about to be closed. Device will not be
- * closed until this function returns.
- *
- * @throws org.ghost4j.GhostscriptException
- */
- public void displayPreClose() throws GhostscriptException;
+ /**
+ * Method called when device is about to be closed. Device will not be
+ * closed until this function returns.
+ *
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void displayPreClose() throws GhostscriptException;
- /**
- * Method called when device has been closed. This is the last event from
- * this device.
- *
- * @throws org.ghost4j.GhostscriptException
- */
- public void displayClose() throws GhostscriptException;
+ /**
+ * Method called when device has been closed. This is the last event from
+ * this device.
+ *
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void displayClose() throws GhostscriptException;
- /**
- * Method called when device is about to be resized.
- *
- * @param width
- * Width
- * @param height
- * Height
- * @param raster
- * Raster
- * @param format
- * Format
- * @throws org.ghost4j.GhostscriptException
- */
- public void displayPreSize(int width, int height, int raster, int format)
- throws GhostscriptException;
+ /**
+ * Method called when device is about to be resized.
+ *
+ * @param width
+ * Width
+ * @param height
+ * Height
+ * @param raster
+ * Raster
+ * @param format
+ * Format
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void displayPreSize(int width, int height, int raster, int format)
+ throws GhostscriptException;
- /**
- * Method called when device has been resized.
- *
- * @param width
- * Width
- * @param height
- * Height
- * @param raster
- * Raster
- * @param format
- * Format
- * @throws org.ghost4j.GhostscriptException
- */
- public void displaySize(int width, int height, int raster, int format)
- throws GhostscriptException;
+ /**
+ * Method called when device has been resized.
+ *
+ * @param width
+ * Width
+ * @param height
+ * Height
+ * @param raster
+ * Raster
+ * @param format
+ * Format
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void displaySize(int width, int height, int raster, int format)
+ throws GhostscriptException;
- /**
- * Method called on page flush.
- *
- * @throws org.ghost4j.GhostscriptException
- */
- public void displaySync() throws GhostscriptException;
+ /**
+ * Method called on page flush.
+ *
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void displaySync() throws GhostscriptException;
- /**
- * Method called on show page.
- *
- * @param width
- * Width
- * @param height
- * Height
- * @param raster
- * Raster
- * @param format
- * Format
- * @param copies
- * Copies
- * @param flush
- * Flush
- * @param imageData
- * Byte array representing image data. Data layout and order is
- * controlled by the -dDisplayFormat argument.
- * @throws org.ghost4j.GhostscriptException
- */
- public void displayPage(int width, int height, int raster, int format,
- int copies, int flush, byte[] imageData)
- throws GhostscriptException;
+ /**
+ * Method called on show page.
+ *
+ * @param width
+ * Width
+ * @param height
+ * Height
+ * @param raster
+ * Raster
+ * @param format
+ * Format
+ * @param copies
+ * Copies
+ * @param flush
+ * Flush
+ * @param imageData
+ * Byte array representing image data. Data layout and order is
+ * controlled by the -dDisplayFormat argument.
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void displayPage(int width, int height, int raster, int format,
+ int copies, int flush, byte[] imageData)
+ throws GhostscriptException;
- /**
- * Method called to notify whenever a portion of the raster is updated.
- *
- * @param x
- * X coordinate
- * @param y
- * Y coordinate
- * @param width
- * Width
- * @param height
- * Height
- * @throws org.ghost4j.GhostscriptException
- */
- public void displayUpdate(int x, int y, int width, int height)
- throws GhostscriptException;
+ /**
+ * Method called to notify whenever a portion of the raster is updated.
+ *
+ * @param x
+ * X coordinate
+ * @param y
+ * Y coordinate
+ * @param width
+ * Width
+ * @param height
+ * Height
+ * @throws org.ghost4j.GhostscriptException
+ */
+ public void displayUpdate(int x, int y, int width, int height)
+ throws GhostscriptException;
}
diff --git a/src/main/java/org/ghost4j/display/DisplayData.java b/src/main/java/org/ghost4j/display/DisplayData.java
index 69a6922..0e4d056 100644
--- a/src/main/java/org/ghost4j/display/DisplayData.java
+++ b/src/main/java/org/ghost4j/display/DisplayData.java
@@ -15,49 +15,49 @@
*/
public class DisplayData {
- private int width;
- private int height;
- private int raster;
- private int format;
- private Pointer pimage;
-
- public int getWidth() {
- return width;
- }
-
- public void setWidth(int width) {
- this.width = width;
- }
-
- public int getHeight() {
- return height;
- }
-
- public void setHeight(int height) {
- this.height = height;
- }
-
- public int getRaster() {
- return raster;
- }
-
- public void setRaster(int raster) {
- this.raster = raster;
- }
-
- public int getFormat() {
- return format;
- }
-
- public void setFormat(int format) {
- this.format = format;
- }
-
- public Pointer getPimage() {
- return pimage;
- }
-
- public void setPimage(Pointer pimage) {
- this.pimage = pimage;
- }
+ private int width;
+ private int height;
+ private int raster;
+ private int format;
+ private Pointer pimage;
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public int getRaster() {
+ return raster;
+ }
+
+ public void setRaster(int raster) {
+ this.raster = raster;
+ }
+
+ public int getFormat() {
+ return format;
+ }
+
+ public void setFormat(int format) {
+ this.format = format;
+ }
+
+ public Pointer getPimage() {
+ return pimage;
+ }
+
+ public void setPimage(Pointer pimage) {
+ this.pimage = pimage;
+ }
}
diff --git a/src/main/java/org/ghost4j/display/ImageWriterDisplayCallback.java b/src/main/java/org/ghost4j/display/ImageWriterDisplayCallback.java
index 9b3a6f4..30840b3 100644
--- a/src/main/java/org/ghost4j/display/ImageWriterDisplayCallback.java
+++ b/src/main/java/org/ghost4j/display/ImageWriterDisplayCallback.java
@@ -21,67 +21,67 @@
*/
public class ImageWriterDisplayCallback implements DisplayCallback {
- /**
- * Holds document images.
- */
- private List images;
+ /**
+ * Holds document images.
+ */
+ private List images;
- /**
- * Constructor.
- */
- public ImageWriterDisplayCallback() {
- images = new ArrayList();
- }
+ /**
+ * Constructor.
+ */
+ public ImageWriterDisplayCallback() {
+ images = new ArrayList();
+ }
- public void displayOpen() throws GhostscriptException {
+ public void displayOpen() throws GhostscriptException {
- }
+ }
- public void displayPreClose() throws GhostscriptException {
+ public void displayPreClose() throws GhostscriptException {
- }
+ }
- public void displayClose() throws GhostscriptException {
+ public void displayClose() throws GhostscriptException {
- }
+ }
- public void displayPreSize(int width, int height, int raster, int format)
- throws GhostscriptException {
+ public void displayPreSize(int width, int height, int raster, int format)
+ throws GhostscriptException {
- }
+ }
- public void displaySize(int width, int height, int raster, int format)
- throws GhostscriptException {
+ public void displaySize(int width, int height, int raster, int format)
+ throws GhostscriptException {
- }
+ }
- public void displaySync() throws GhostscriptException {
+ public void displaySync() throws GhostscriptException {
- }
+ }
- public void displayPage(int width, int height, int raster, int format,
- int copies, int flush, byte[] imageData)
- throws GhostscriptException {
+ public void displayPage(int width, int height, int raster, int format,
+ int copies, int flush, byte[] imageData)
+ throws GhostscriptException {
- // create new raster
- PageRaster pageRaster = new PageRaster();
- pageRaster.setWidth(width);
- pageRaster.setHeight(height);
- pageRaster.setRaster(raster);
- pageRaster.setFormat(format);
- pageRaster.setData(imageData);
+ // create new raster
+ PageRaster pageRaster = new PageRaster();
+ pageRaster.setWidth(width);
+ pageRaster.setHeight(height);
+ pageRaster.setRaster(raster);
+ pageRaster.setFormat(format);
+ pageRaster.setData(imageData);
- // convert to image and add to list
- images.add(ImageUtil.converterPageRasterToImage(pageRaster));
+ // convert to image and add to list
+ images.add(ImageUtil.converterPageRasterToImage(pageRaster));
- }
+ }
- public void displayUpdate(int x, int y, int width, int height)
- throws GhostscriptException {
+ public void displayUpdate(int x, int y, int width, int height)
+ throws GhostscriptException {
- }
+ }
- public List getImages() {
- return images;
- }
+ public List getImages() {
+ return images;
+ }
}
diff --git a/src/main/java/org/ghost4j/display/PageRaster.java b/src/main/java/org/ghost4j/display/PageRaster.java
index a685007..2d35980 100644
--- a/src/main/java/org/ghost4j/display/PageRaster.java
+++ b/src/main/java/org/ghost4j/display/PageRaster.java
@@ -16,53 +16,53 @@
*/
public class PageRaster implements Serializable {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = -977080307761838114L;
- private int width;
- private int height;
- private int raster;
- private int format;
- private byte[] data;
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = -977080307761838114L;
+ private int width;
+ private int height;
+ private int raster;
+ private int format;
+ private byte[] data;
- public int getWidth() {
- return width;
- }
+ public int getWidth() {
+ return width;
+ }
- public void setWidth(int width) {
- this.width = width;
- }
+ public void setWidth(int width) {
+ this.width = width;
+ }
- public int getHeight() {
- return height;
- }
+ public int getHeight() {
+ return height;
+ }
- public void setHeight(int height) {
- this.height = height;
- }
+ public void setHeight(int height) {
+ this.height = height;
+ }
- public int getRaster() {
- return raster;
- }
+ public int getRaster() {
+ return raster;
+ }
- public void setRaster(int raster) {
- this.raster = raster;
- }
+ public void setRaster(int raster) {
+ this.raster = raster;
+ }
- public int getFormat() {
- return format;
- }
+ public int getFormat() {
+ return format;
+ }
- public void setFormat(int format) {
- this.format = format;
- }
+ public void setFormat(int format) {
+ this.format = format;
+ }
- public byte[] getData() {
- return data;
- }
+ public byte[] getData() {
+ return data;
+ }
- public void setData(byte[] data) {
- this.data = data;
- }
+ public void setData(byte[] data) {
+ this.data = data;
+ }
}
diff --git a/src/main/java/org/ghost4j/display/PageRasterDisplayCallback.java b/src/main/java/org/ghost4j/display/PageRasterDisplayCallback.java
index 82ae44b..c12ed8f 100644
--- a/src/main/java/org/ghost4j/display/PageRasterDisplayCallback.java
+++ b/src/main/java/org/ghost4j/display/PageRasterDisplayCallback.java
@@ -19,65 +19,65 @@
*/
public class PageRasterDisplayCallback implements DisplayCallback {
- private List rasters;
+ private List rasters;
- /**
- * Constructor
- */
- public PageRasterDisplayCallback() {
+ /**
+ * Constructor
+ */
+ public PageRasterDisplayCallback() {
- rasters = new ArrayList();
- }
+ rasters = new ArrayList();
+ }
- public void displayClose() throws GhostscriptException {
+ public void displayClose() throws GhostscriptException {
- }
+ }
- public void displayOpen() throws GhostscriptException {
+ public void displayOpen() throws GhostscriptException {
- }
+ }
- public void displayPage(int width, int height, int raster, int format,
- int copies, int flush, byte[] imageData)
- throws GhostscriptException {
+ public void displayPage(int width, int height, int raster, int format,
+ int copies, int flush, byte[] imageData)
+ throws GhostscriptException {
- // prepare new raster
- PageRaster pageRaster = new PageRaster();
- pageRaster.setWidth(width);
- pageRaster.setHeight(height);
- pageRaster.setRaster(raster);
- pageRaster.setFormat(format);
- pageRaster.setData(imageData);
+ // prepare new raster
+ PageRaster pageRaster = new PageRaster();
+ pageRaster.setWidth(width);
+ pageRaster.setHeight(height);
+ pageRaster.setRaster(raster);
+ pageRaster.setFormat(format);
+ pageRaster.setData(imageData);
- // add it to the result list
- rasters.add(pageRaster);
+ // add it to the result list
+ rasters.add(pageRaster);
- }
+ }
- public void displayPreClose() throws GhostscriptException {
+ public void displayPreClose() throws GhostscriptException {
- }
+ }
- public void displayPreSize(int width, int height, int raster, int format)
- throws GhostscriptException {
+ public void displayPreSize(int width, int height, int raster, int format)
+ throws GhostscriptException {
- }
+ }
- public void displaySize(int width, int height, int raster, int format)
- throws GhostscriptException {
+ public void displaySize(int width, int height, int raster, int format)
+ throws GhostscriptException {
- }
+ }
- public void displaySync() throws GhostscriptException {
+ public void displaySync() throws GhostscriptException {
- }
+ }
- public void displayUpdate(int x, int y, int width, int height)
- throws GhostscriptException {
- }
+ public void displayUpdate(int x, int y, int width, int height)
+ throws GhostscriptException {
+ }
- public List getRasters() {
- return rasters;
- }
+ public List getRasters() {
+ return rasters;
+ }
}
diff --git a/src/main/java/org/ghost4j/document/AbstractDocument.java b/src/main/java/org/ghost4j/document/AbstractDocument.java
index d82a1e9..b300922 100644
--- a/src/main/java/org/ghost4j/document/AbstractDocument.java
+++ b/src/main/java/org/ghost4j/document/AbstractDocument.java
@@ -29,124 +29,128 @@
*/
public abstract class AbstractDocument implements Document, Serializable {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = -7160779330993730486L;
-
- /**
- * Buffer size used while reading (loading) document content.
- */
- public static final int READ_BUFFER_SIZE = 1024;
-
- /**
- * Content of the document.
- */
- protected byte[] content;
-
- public void load(File file) throws FileNotFoundException, IOException {
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = -7160779330993730486L;
+
+ /**
+ * Buffer size used while reading (loading) document content.
+ */
+ public static final int READ_BUFFER_SIZE = 1024;
+
+ /**
+ * Content of the document.
+ */
+ protected byte[] content;
+
+ public int load(File file) throws FileNotFoundException, IOException {
+
+ FileInputStream fis = new FileInputStream(file);
+ int totalread = load(fis);
+ IOUtils.closeQuietly(fis);
+ return totalread;
+ }
- FileInputStream fis = new FileInputStream(file);
- load(fis);
- IOUtils.closeQuietly(fis);
- }
+ public int load(InputStream inputStream) throws IOException {
- public void load(InputStream inputStream) throws IOException {
+ int totalread = 0;
+ byte[] buffer = new byte[READ_BUFFER_SIZE];
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buffer = new byte[READ_BUFFER_SIZE];
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int readCount = 0;
+ while ((readCount = inputStream.read(buffer)) > 0) {
+ baos.write(buffer, 0, readCount);
+ totalread+=readCount;
+ }
+ content = baos.toByteArray();
- int readCount = 0;
- while ((readCount = inputStream.read(buffer)) > 0) {
- baos.write(buffer, 0, readCount);
+ IOUtils.closeQuietly(baos);
+ return totalread;
}
- content = baos.toByteArray();
- IOUtils.closeQuietly(baos);
- }
+ public void write(File file) throws IOException {
- public void write(File file) throws IOException {
+ FileOutputStream fos = new FileOutputStream(file);
+ write(fos);
+ IOUtils.closeQuietly(fos);
- FileOutputStream fos = new FileOutputStream(file);
- write(fos);
- IOUtils.closeQuietly(fos);
+ }
- }
+ public void write(OutputStream outputStream) throws IOException {
- public void write(OutputStream outputStream) throws IOException {
+ outputStream.write(content);
- outputStream.write(content);
+ }
- }
+ public int getSize() {
- public int getSize() {
+ if (content == null) {
+ return 0;
+ } else {
+ return content.length;
+ }
+ }
- if (content == null) {
- return 0;
- } else {
- return content.length;
+ public byte[] getContent() {
+ return content;
}
- }
-
- public byte[] getContent() {
- return content;
- }
-
- /**
- * Assert the given page index is valid for the current document.
- *
- * @param index
- * Index to check
- * @throws DocumentException
- * Thrown if index is not valid
- */
- protected void assertValidPageIndex(int index) throws DocumentException {
-
- if (content == null || index > this.getPageCount()) {
- throw new DocumentException("Invalid page index: " + index);
+
+ /**
+ * Assert the given page index is valid for the current document.
+ *
+ * @param index
+ * Index to check
+ * @throws DocumentException
+ * Thrown if index is not valid
+ */
+ protected void assertValidPageIndex(int index) throws DocumentException {
+
+ if (content == null || index > this.getPageCount()) {
+ throw new DocumentException("Invalid page index: " + index);
+ }
}
- }
-
- /**
- * Assert the given page range is valid for the current document.
- *
- * @param begin
- * Range begin index
- * @param end
- * Range end index
- * @throws DocumentException
- */
- protected void assertValidPageRange(int begin, int end)
- throws DocumentException {
-
- this.assertValidPageIndex(begin);
- this.assertValidPageIndex(end);
-
- if (begin > end) {
- throw new DocumentException("Invalid page range: " + begin + " - "
- + end);
+
+ /**
+ * Assert the given page range is valid for the current document.
+ *
+ * @param begin
+ * Range begin index
+ * @param end
+ * Range end index
+ * @throws DocumentException
+ */
+ protected void assertValidPageRange(int begin, int end)
+ throws DocumentException {
+
+ this.assertValidPageIndex(begin);
+ this.assertValidPageIndex(end);
+
+ if (begin > end) {
+ throw new DocumentException("Invalid page range: " + begin + " - "
+ + end);
+ }
}
- }
- public void append(Document document) throws DocumentException {
+ public void append(Document document) throws DocumentException {
- if (document == null || !this.getType().equals(document.getType())) {
- throw new DocumentException(
- "Cannot append document of different types");
+ if (document == null || !this.getType().equals(document.getType())) {
+ throw new DocumentException(
+ "Cannot append document of different types");
+ }
}
- }
- public List explode() throws DocumentException {
+ public List explode() throws DocumentException {
- List result = new ArrayList();
+ List result = new ArrayList();
- int pageCount = this.getPageCount();
+ int pageCount = this.getPageCount();
- for (int i = 0; i < pageCount; i++) {
- result.add(this.extract(i + 1, i + 1));
- }
+ for (int i = 0; i < pageCount; i++) {
+ result.add(this.extract(i + 1, i + 1));
+ }
- return result;
- }
+ return result;
+ }
}
diff --git a/src/main/java/org/ghost4j/document/Document.java b/src/main/java/org/ghost4j/document/Document.java
index 9bd3a83..8f24293 100644
--- a/src/main/java/org/ghost4j/document/Document.java
+++ b/src/main/java/org/ghost4j/document/Document.java
@@ -21,98 +21,98 @@
*/
public interface Document {
- public static final String TYPE_POSTSCRIPT = "PostScript";
- public static final String TYPE_PDF = "PDF";
+ public static final String TYPE_POSTSCRIPT = "PostScript";
+ public static final String TYPE_PDF = "PDF";
- /**
- * Load document from a File.
- *
- * @param file
- * File.
- * @throws FileNotFoundException
- * @throws IOException
- */
- public void load(File file) throws FileNotFoundException, IOException;
+ /**
+ * Load document from a File.
+ *
+ * @param file
+ * File.
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ public int load(File file) throws FileNotFoundException, IOException;
- /**
- * Load document from an InputStream.
- *
- * @param inputStream
- * @throws IOException
- */
- public void load(InputStream inputStream) throws IOException;
+ /**
+ * Load document from an InputStream.
+ *
+ * @param inputStream
+ * @throws IOException
+ */
+ public int load(InputStream inputStream) throws IOException;
- /**
- * Write document to a File.
- *
- * @param file
- * File.
- * @throws IOException
- */
- public void write(File file) throws IOException;
+ /**
+ * Write document to a File.
+ *
+ * @param file
+ * File.
+ * @throws IOException
+ */
+ public void write(File file) throws IOException;
- /**
- * Write document to an OutputStream
- *
- * @param outputStream
- * @throws IOException
- */
- public void write(OutputStream outputStream) throws IOException;
+ /**
+ * Write document to an OutputStream
+ *
+ * @param outputStream
+ * @throws IOException
+ */
+ public void write(OutputStream outputStream) throws IOException;
- /**
- * Return document page count
- *
- * @return Number of pages.
- */
- public int getPageCount() throws DocumentException;
+ /**
+ * Return document page count
+ *
+ * @return Number of pages.
+ */
+ public int getPageCount() throws DocumentException;
- /**
- * Return the type of the document.
- *
- * @return A String representing the document type name.
- */
- public String getType();
+ /**
+ * Return the type of the document.
+ *
+ * @return A String representing the document type name.
+ */
+ public String getType();
- /**
- * Return document size
- *
- * @return Document size in bytes.
- */
- public int getSize();
+ /**
+ * Return document size
+ *
+ * @return Document size in bytes.
+ */
+ public int getSize();
- /**
- * Return document content as a byte array
- *
- * @return Byte array
- */
- public byte[] getContent();
+ /**
+ * Return document content as a byte array
+ *
+ * @return Byte array
+ */
+ public byte[] getContent();
- /**
- * Return a new document containing pages of a given range. Note : begin and
- * end indicies start at 1
- *
- * @param begin
- * Index of the first page to extract
- * @param end
- * Index of the last page to extract
- * @return A new document.
- */
- public Document extract(int begin, int end) throws DocumentException;
+ /**
+ * Return a new document containing pages of a given range. Note : begin and
+ * end indicies start at 1
+ *
+ * @param begin
+ * Index of the first page to extract
+ * @param end
+ * Index of the last page to extract
+ * @return A new document.
+ */
+ public Document extract(int begin, int end) throws DocumentException;
- /**
- * Append pages of another document to the current document.
- *
- * @param document
- * Document ot append
- * @throws DocumentException
- */
- public void append(Document document) throws DocumentException;
+ /**
+ * Append pages of another document to the current document.
+ *
+ * @param document
+ * Document ot append
+ * @throws DocumentException
+ */
+ public void append(Document document) throws DocumentException;
- /**
- * Separate each pages to a new document.
- *
- * @return A list of Document.
- * @throws DocumentException
- */
- public List explode() throws DocumentException;
+ /**
+ * Separate each pages to a new document.
+ *
+ * @return A list of Document.
+ * @throws DocumentException
+ */
+ public List explode() throws DocumentException;
}
diff --git a/src/main/java/org/ghost4j/document/DocumentException.java b/src/main/java/org/ghost4j/document/DocumentException.java
index f09d7fe..7134cdb 100644
--- a/src/main/java/org/ghost4j/document/DocumentException.java
+++ b/src/main/java/org/ghost4j/document/DocumentException.java
@@ -15,25 +15,25 @@
*/
public class DocumentException extends Exception {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 3773482793220746656L;
-
- public DocumentException() {
- super();
- }
-
- public DocumentException(String message) {
- super(message);
- }
-
- public DocumentException(Throwable cause) {
- super(cause);
- }
-
- public DocumentException(String message, Throwable cause) {
- super(message, cause);
- }
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 3773482793220746656L;
+
+ public DocumentException() {
+ super();
+ }
+
+ public DocumentException(String message) {
+ super(message);
+ }
+
+ public DocumentException(Throwable cause) {
+ super(cause);
+ }
+
+ public DocumentException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/src/main/java/org/ghost4j/document/PDFDocument.java b/src/main/java/org/ghost4j/document/PDFDocument.java
index 113bb20..bc53aa2 100644
--- a/src/main/java/org/ghost4j/document/PDFDocument.java
+++ b/src/main/java/org/ghost4j/document/PDFDocument.java
@@ -26,160 +26,162 @@
*/
public class PDFDocument extends AbstractDocument {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 6331191005700202153L;
-
- @Override
- public void load(InputStream inputStream) throws IOException {
- super.load(inputStream);
-
- // check that the file is a PDF
- ByteArrayInputStream bais = null;
- PdfReader reader = null;
-
- try {
-
- bais = new ByteArrayInputStream(content);
- reader = new PdfReader(bais);
-
- } catch (Exception e) {
- throw new IOException("PDF document is not valid");
- } finally {
- if (reader != null)
- reader.close();
- IOUtils.closeQuietly(bais);
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 6331191005700202153L;
+
+ @Override
+ public int load(InputStream inputStream) throws IOException {
+ int totalread = super.load(inputStream);
+
+ // check that the file is a PDF
+ ByteArrayInputStream bais = null;
+ PdfReader reader = null;
+
+ try {
+
+ bais = new ByteArrayInputStream(content);
+ reader = new PdfReader(bais);
+
+ } catch (Exception e) {
+ throw new IOException("PDF document is not valid");
+ } finally {
+ if (reader != null)
+ reader.close();
+ IOUtils.closeQuietly(bais);
+ }
+
+ return totalread;
}
- }
- public int getPageCount() throws DocumentException {
+ public int getPageCount() throws DocumentException {
- int pageCount = 0;
+ int pageCount = 0;
- if (content == null) {
- return pageCount;
- }
+ if (content == null) {
+ return pageCount;
+ }
- ByteArrayInputStream bais = null;
- PdfReader reader = null;
+ ByteArrayInputStream bais = null;
+ PdfReader reader = null;
- try {
+ try {
- bais = new ByteArrayInputStream(content);
- reader = new PdfReader(bais);
- pageCount = reader.getNumberOfPages();
+ bais = new ByteArrayInputStream(content);
+ reader = new PdfReader(bais);
+ pageCount = reader.getNumberOfPages();
- } catch (Exception e) {
- throw new DocumentException(e);
- } finally {
- if (reader != null)
- reader.close();
- IOUtils.closeQuietly(bais);
- }
+ } catch (Exception e) {
+ throw new DocumentException(e);
+ } finally {
+ if (reader != null)
+ reader.close();
+ IOUtils.closeQuietly(bais);
+ }
- return pageCount;
+ return pageCount;
- }
+ }
- public Document extract(int begin, int end) throws DocumentException {
+ public Document extract(int begin, int end) throws DocumentException {
- this.assertValidPageRange(begin, end);
+ this.assertValidPageRange(begin, end);
- PDFDocument result = new PDFDocument();
+ PDFDocument result = new PDFDocument();
- ByteArrayInputStream bais = null;
- ByteArrayOutputStream baos = null;
+ ByteArrayInputStream bais = null;
+ ByteArrayOutputStream baos = null;
- if (content != null) {
+ if (content != null) {
- com.lowagie.text.Document document = new com.lowagie.text.Document();
+ com.lowagie.text.Document document = new com.lowagie.text.Document();
- try {
+ try {
- bais = new ByteArrayInputStream(content);
- baos = new ByteArrayOutputStream();
+ bais = new ByteArrayInputStream(content);
+ baos = new ByteArrayOutputStream();
- PdfReader inputPDF = new PdfReader(bais);
+ PdfReader inputPDF = new PdfReader(bais);
- // create a writer for the outputstream
- PdfWriter writer = PdfWriter.getInstance(document, baos);
+ // create a writer for the outputstream
+ PdfWriter writer = PdfWriter.getInstance(document, baos);
- document.open();
- PdfContentByte cb = writer.getDirectContent();
+ document.open();
+ PdfContentByte cb = writer.getDirectContent();
- PdfImportedPage page;
+ PdfImportedPage page;
- while (begin <= end) {
- document.newPage();
- page = writer.getImportedPage(inputPDF, begin);
- cb.addTemplate(page, 0, 0);
- begin++;
- }
+ while (begin <= end) {
+ document.newPage();
+ page = writer.getImportedPage(inputPDF, begin);
+ cb.addTemplate(page, 0, 0);
+ begin++;
+ }
+
+ document.close();
- document.close();
+ result.load(new ByteArrayInputStream(baos.toByteArray()));
- result.load(new ByteArrayInputStream(baos.toByteArray()));
+ } catch (Exception e) {
+ throw new DocumentException(e);
+ } finally {
+ if (document.isOpen())
+ document.close();
+ IOUtils.closeQuietly(bais);
+ IOUtils.closeQuietly(baos);
+ }
- } catch (Exception e) {
- throw new DocumentException(e);
- } finally {
- if (document.isOpen())
- document.close();
- IOUtils.closeQuietly(bais);
- IOUtils.closeQuietly(baos);
- }
+ }
+ return result;
}
- return result;
- }
+ @Override
+ public void append(Document document) throws DocumentException {
- @Override
- public void append(Document document) throws DocumentException {
+ super.append(document);
- super.append(document);
+ ByteArrayOutputStream baos = null;
+ com.lowagie.text.Document mergedDocument = new com.lowagie.text.Document();
- ByteArrayOutputStream baos = null;
- com.lowagie.text.Document mergedDocument = new com.lowagie.text.Document();
+ try {
- try {
+ baos = new ByteArrayOutputStream();
+ PdfCopy copy = new PdfCopy(mergedDocument, baos);
- baos = new ByteArrayOutputStream();
- PdfCopy copy = new PdfCopy(mergedDocument, baos);
+ mergedDocument.open();
- mergedDocument.open();
+ // copy current document
+ PdfReader reader = new PdfReader(content);
+ int pageCount = reader.getNumberOfPages();
+ for (int i = 0; i < pageCount;) {
+ copy.addPage(copy.getImportedPage(reader, ++i));
+ }
- // copy current document
- PdfReader reader = new PdfReader(content);
- int pageCount = reader.getNumberOfPages();
- for (int i = 0; i < pageCount;) {
- copy.addPage(copy.getImportedPage(reader, ++i));
- }
+ // copy new document
+ reader = new PdfReader(document.getContent());
+ pageCount = reader.getNumberOfPages();
+ for (int i = 0; i < pageCount;) {
+ copy.addPage(copy.getImportedPage(reader, ++i));
+ }
- // copy new document
- reader = new PdfReader(document.getContent());
- pageCount = reader.getNumberOfPages();
- for (int i = 0; i < pageCount;) {
- copy.addPage(copy.getImportedPage(reader, ++i));
- }
+ mergedDocument.close();
- mergedDocument.close();
+ // replace content with new content
+ content = baos.toByteArray();
- // replace content with new content
- content = baos.toByteArray();
+ } catch (Exception e) {
+ throw new DocumentException(e);
+ } finally {
+ if (mergedDocument.isOpen())
+ mergedDocument.close();
+ IOUtils.closeQuietly(baos);
+ }
- } catch (Exception e) {
- throw new DocumentException(e);
- } finally {
- if (mergedDocument.isOpen())
- mergedDocument.close();
- IOUtils.closeQuietly(baos);
}
- }
-
- public String getType() {
- return TYPE_PDF;
- }
+ public String getType() {
+ return TYPE_PDF;
+ }
}
diff --git a/src/main/java/org/ghost4j/document/PSDocument.java b/src/main/java/org/ghost4j/document/PSDocument.java
index bc30b7c..a13b57d 100644
--- a/src/main/java/org/ghost4j/document/PSDocument.java
+++ b/src/main/java/org/ghost4j/document/PSDocument.java
@@ -36,229 +36,231 @@
*/
public class PSDocument extends AbstractDocument {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 7225098893496658222L;
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 7225098893496658222L;
- @Override
- public void load(InputStream inputStream) throws IOException {
+ @Override
+ public int load(InputStream inputStream) throws IOException {
- super.load(inputStream);
+ int totalread = super.load(inputStream);
- // check that the file is a PostScript
- ByteArrayInputStream bais = null;
- try {
+ // check that the file is a PostScript
+ ByteArrayInputStream bais = null;
+ try {
- bais = new ByteArrayInputStream(content);
+ bais = new ByteArrayInputStream(content);
- DSCParser parser = new DSCParser(bais);
- if (parser.nextDSCComment(DSCConstants.END_COMMENTS) == null) {
- throw new IOException("PostScript document is not valid");
- }
+ DSCParser parser = new DSCParser(bais);
+ if (parser.nextDSCComment(DSCConstants.END_COMMENTS) == null) {
+ throw new IOException("PostScript document is not valid");
+ }
- } catch (DSCException e) {
- throw new IOException(e.getMessage());
- } finally {
- IOUtils.closeQuietly(bais);
+ } catch (DSCException e) {
+ throw new IOException(e.getMessage());
+ } finally {
+ IOUtils.closeQuietly(bais);
+ }
+
+ return totalread;
}
- }
- public int getPageCount() throws DocumentException {
+ public int getPageCount() throws DocumentException {
- int pageCount = 0;
+ int pageCount = 0;
- if (content == null) {
- return pageCount;
- }
+ if (content == null) {
+ return pageCount;
+ }
+
+ ByteArrayInputStream bais = null;
- ByteArrayInputStream bais = null;
+ try {
- try {
+ // read pages from the %%Pages DSC comment
- // read pages from the %%Pages DSC comment
+ bais = new ByteArrayInputStream(content);
- bais = new ByteArrayInputStream(content);
+ DSCParser parser = new DSCParser(bais);
+ Object tP = parser.nextDSCComment(DSCConstants.PAGES);
+ while (tP instanceof DSCAtend)
+ tP = parser.nextDSCComment(DSCConstants.PAGES);
+ DSCCommentPages pages = (DSCCommentPages) tP;
+ pageCount = pages.getPageCount();
- DSCParser parser = new DSCParser(bais);
- Object tP = parser.nextDSCComment(DSCConstants.PAGES);
- while (tP instanceof DSCAtend)
- tP = parser.nextDSCComment(DSCConstants.PAGES);
- DSCCommentPages pages = (DSCCommentPages) tP;
- pageCount = pages.getPageCount();
+ } catch (Exception e) {
+ throw new DocumentException(e);
+ } finally {
+ IOUtils.closeQuietly(bais);
+ }
- } catch (Exception e) {
- throw new DocumentException(e);
- } finally {
- IOUtils.closeQuietly(bais);
+ return pageCount;
}
- return pageCount;
- }
+ public Document extract(int begin, int end) throws DocumentException {
- public Document extract(int begin, int end) throws DocumentException {
+ this.assertValidPageRange(begin, end);
- this.assertValidPageRange(begin, end);
+ PSDocument result = new PSDocument();
- PSDocument result = new PSDocument();
+ ByteArrayInputStream bais = null;
+ ByteArrayOutputStream baos = null;
- ByteArrayInputStream bais = null;
- ByteArrayOutputStream baos = null;
+ if (content != null) {
- if (content != null) {
+ try {
- try {
+ bais = new ByteArrayInputStream(content);
+ baos = new ByteArrayOutputStream();
- bais = new ByteArrayInputStream(content);
- baos = new ByteArrayOutputStream();
+ PageExtractor.extractPages(bais, baos, begin, end);
- PageExtractor.extractPages(bais, baos, begin, end);
+ result.load(new ByteArrayInputStream(baos.toByteArray()));
- result.load(new ByteArrayInputStream(baos.toByteArray()));
+ } catch (Exception e) {
+ throw new DocumentException(e);
+ } finally {
+ IOUtils.closeQuietly(bais);
+ IOUtils.closeQuietly(baos);
+ }
- } catch (Exception e) {
- throw new DocumentException(e);
- } finally {
- IOUtils.closeQuietly(bais);
- IOUtils.closeQuietly(baos);
- }
+ }
+ return result;
}
- return result;
- }
-
- /**
- * This methods appends pages the DSC way (only by relying on the
- * structure). It does not work with documents generated by different
- * softwares / spools. It is intended to be used only for rearranging pages
- * of the same document. If you need to append a different document,
- * consider using the SafeAppenderModifier instead.
- *
- * @see SafeAppenderModifier
- */
- @Override
- public void append(Document document) throws DocumentException {
-
- super.append(document);
-
- ByteArrayInputStream baisCurrent = null;
- ByteArrayInputStream baisNew = null;
- ByteArrayOutputStream baos = null;
-
- int currentPageCount = this.getPageCount();
- int totalPageCount = currentPageCount + document.getPageCount();
-
- try {
- baisCurrent = new ByteArrayInputStream(content);
- baos = new ByteArrayOutputStream();
-
- DSCParser currentParser = new DSCParser(baisCurrent);
- PSGenerator gen = new PSGenerator(baos);
- currentParser.addListener(new DefaultNestedDocumentHandler(gen));
-
- // skip DSC header
- DSCHeaderComment header = DSCTools
- .checkAndSkipDSC30Header(currentParser);
- header.generate(gen);
- // set number of pages
- DSCCommentPages pages = new DSCCommentPages(totalPageCount);
- pages.generate(gen);
-
- currentParser.setFilter(new DSCFilter() {
- public boolean accept(DSCEvent event) {
- if (event.isDSCComment()) {
-
- // filter %%Pages which we add manually above
- return !event.asDSCComment().getName()
- .equals(DSCConstants.PAGES);
- } else {
- return true;
- }
- }
- });
-
- // skip the prolog and to the first page
- DSCComment pageOrTrailer = currentParser.nextDSCComment(
- DSCConstants.PAGE, gen);
- if (pageOrTrailer == null) {
- throw new DSCException("Page expected, but none found");
- }
-
- // remove filter
- currentParser.setFilter(null);
-
- // process individual pages
- while (true) {
- DSCCommentPage page = (DSCCommentPage) pageOrTrailer;
- page.setPagePosition(page.getPagePosition());
- page.generate(gen);
- pageOrTrailer = DSCTools.nextPageOrTrailer(currentParser, gen);
- if (pageOrTrailer == null) {
- throw new DSCException(
- "File is not DSC-compliant: Unexpected end of file");
- } else if (!DSCConstants.PAGE.equals(pageOrTrailer.getName())) {
- break;
- }
- }
-
- // append pages of the new document now
- baisNew = new ByteArrayInputStream(document.getContent());
- DSCParser newParser = new DSCParser(baisNew);
- header = DSCTools.checkAndSkipDSC30Header(newParser);
- pageOrTrailer = newParser.nextDSCComment(DSCConstants.PAGE);
- if (pageOrTrailer == null) {
- throw new DSCException("Page expected, but none found");
- }
- int i = 1;
- while (true) {
- DSCCommentPage page = (DSCCommentPage) pageOrTrailer;
- page.setPageName(String.valueOf(currentPageCount + i));
- page.setPagePosition(currentPageCount + i);
- page.generate(gen);
- pageOrTrailer = DSCTools.nextPageOrTrailer(newParser, gen);
- if (pageOrTrailer == null) {
- throw new DSCException(
- "File is not DSC-compliant: Unexpected end of file");
- } else if (!DSCConstants.PAGE.equals(pageOrTrailer.getName())) {
- pageOrTrailer.generate(gen);
- break;
+ /**
+ * This methods appends pages the DSC way (only by relying on the
+ * structure). It does not work with documents generated by different
+ * softwares / spools. It is intended to be used only for rearranging pages
+ * of the same document. If you need to append a different document,
+ * consider using the SafeAppenderModifier instead.
+ *
+ * @see SafeAppenderModifier
+ */
+ @Override
+ public void append(Document document) throws DocumentException {
+
+ super.append(document);
+
+ ByteArrayInputStream baisCurrent = null;
+ ByteArrayInputStream baisNew = null;
+ ByteArrayOutputStream baos = null;
+
+ int currentPageCount = this.getPageCount();
+ int totalPageCount = currentPageCount + document.getPageCount();
+
+ try {
+ baisCurrent = new ByteArrayInputStream(content);
+ baos = new ByteArrayOutputStream();
+
+ DSCParser currentParser = new DSCParser(baisCurrent);
+ PSGenerator gen = new PSGenerator(baos);
+ currentParser.addListener(new DefaultNestedDocumentHandler(gen));
+
+ // skip DSC header
+ DSCHeaderComment header = DSCTools
+ .checkAndSkipDSC30Header(currentParser);
+ header.generate(gen);
+ // set number of pages
+ DSCCommentPages pages = new DSCCommentPages(totalPageCount);
+ pages.generate(gen);
+
+ currentParser.setFilter(new DSCFilter() {
+ public boolean accept(DSCEvent event) {
+ if (event.isDSCComment()) {
+
+ // filter %%Pages which we add manually above
+ return !event.asDSCComment().getName()
+ .equals(DSCConstants.PAGES);
+ } else {
+ return true;
+ }
+ }
+ });
+
+ // skip the prolog and to the first page
+ DSCComment pageOrTrailer = currentParser.nextDSCComment(
+ DSCConstants.PAGE, gen);
+ if (pageOrTrailer == null) {
+ throw new DSCException("Page expected, but none found");
+ }
+
+ // remove filter
+ currentParser.setFilter(null);
+
+ // process individual pages
+ while (true) {
+ DSCCommentPage page = (DSCCommentPage) pageOrTrailer;
+ page.setPagePosition(page.getPagePosition());
+ page.generate(gen);
+ pageOrTrailer = DSCTools.nextPageOrTrailer(currentParser, gen);
+ if (pageOrTrailer == null) {
+ throw new DSCException(
+ "File is not DSC-compliant: Unexpected end of file");
+ } else if (!DSCConstants.PAGE.equals(pageOrTrailer.getName())) {
+ break;
+ }
+ }
+
+ // append pages of the new document now
+ baisNew = new ByteArrayInputStream(document.getContent());
+ DSCParser newParser = new DSCParser(baisNew);
+ header = DSCTools.checkAndSkipDSC30Header(newParser);
+ pageOrTrailer = newParser.nextDSCComment(DSCConstants.PAGE);
+ if (pageOrTrailer == null) {
+ throw new DSCException("Page expected, but none found");
+ }
+ int i = 1;
+ while (true) {
+ DSCCommentPage page = (DSCCommentPage) pageOrTrailer;
+ page.setPageName(String.valueOf(currentPageCount + i));
+ page.setPagePosition(currentPageCount + i);
+ page.generate(gen);
+ pageOrTrailer = DSCTools.nextPageOrTrailer(newParser, gen);
+ if (pageOrTrailer == null) {
+ throw new DSCException(
+ "File is not DSC-compliant: Unexpected end of file");
+ } else if (!DSCConstants.PAGE.equals(pageOrTrailer.getName())) {
+ pageOrTrailer.generate(gen);
+ break;
+ }
+ i++;
+ }
+
+ // write the rest (end)
+ currentParser.setFilter(new DSCFilter() {
+ public boolean accept(DSCEvent event) {
+ if (event.isDSCComment()) {
+
+ // filter %%Pages (in case of attend)
+ return !event.asDSCComment().getName()
+ .equals(DSCConstants.PAGES);
+ } else {
+ return true;
+ }
+ }
+ });
+ while (currentParser.hasNext()) {
+ DSCEvent event = currentParser.nextEvent();
+ event.generate(gen);
+ }
+
+ // update current document content
+ content = baos.toByteArray();
+
+ } catch (Exception e) {
+ throw new DocumentException(e);
+ } finally {
+ IOUtils.closeQuietly(baisCurrent);
+ IOUtils.closeQuietly(baisNew);
+ IOUtils.closeQuietly(baos);
}
- i++;
- }
-
- // write the rest (end)
- currentParser.setFilter(new DSCFilter() {
- public boolean accept(DSCEvent event) {
- if (event.isDSCComment()) {
-
- // filter %%Pages (in case of attend)
- return !event.asDSCComment().getName()
- .equals(DSCConstants.PAGES);
- } else {
- return true;
- }
- }
- });
- while (currentParser.hasNext()) {
- DSCEvent event = currentParser.nextEvent();
- event.generate(gen);
- }
-
- // update current document content
- content = baos.toByteArray();
-
- } catch (Exception e) {
- throw new DocumentException(e);
- } finally {
- IOUtils.closeQuietly(baisCurrent);
- IOUtils.closeQuietly(baisNew);
- IOUtils.closeQuietly(baos);
}
- }
- public String getType() {
- return TYPE_POSTSCRIPT;
- }
+ public String getType() {
+ return TYPE_POSTSCRIPT;
+ }
}
diff --git a/src/main/java/org/ghost4j/document/PaperSize.java b/src/main/java/org/ghost4j/document/PaperSize.java
index 0c2cebf..b64a43b 100644
--- a/src/main/java/org/ghost4j/document/PaperSize.java
+++ b/src/main/java/org/ghost4j/document/PaperSize.java
@@ -19,149 +19,149 @@
*/
public class PaperSize implements Serializable {
- /**
- * Serial UID.
- */
- private static final long serialVersionUID = -1614204334526018509L;
-
- /**
- * Standard paper sizes index map. Allows faster paer size lookup by name.
- */
- private static final Map index = new HashMap();
-
- public static final PaperSize LEDGER = new PaperSize("ledger", 1224, 792);
- public static final PaperSize LEGAL = new PaperSize("legal", 612, 1008);
- public static final PaperSize LETTER = new PaperSize("letter", 612, 792);
- public static final PaperSize ARCHE = new PaperSize("archE", 2592, 3456);
- public static final PaperSize ARCHD = new PaperSize("archD", 1728, 2592);
- public static final PaperSize ARCHC = new PaperSize("archC", 1296, 1728);
- public static final PaperSize ARCHB = new PaperSize("archB", 864, 1296);
- public static final PaperSize ARCHA = new PaperSize("archA", 648, 864);
- public static final PaperSize A0 = new PaperSize("a0", 2384, 3370);
- public static final PaperSize A1 = new PaperSize("a1", 1684, 2384);
- public static final PaperSize A2 = new PaperSize("a2", 1191, 1684);
- public static final PaperSize A3 = new PaperSize("a3", 842, 1191);
- public static final PaperSize A4 = new PaperSize("a4", 595, 842);
- public static final PaperSize A5 = new PaperSize("a5", 420, 595);
- public static final PaperSize A6 = new PaperSize("a6", 297, 420);
- public static final PaperSize A7 = new PaperSize("a7", 210, 297);
- public static final PaperSize A8 = new PaperSize("a8", 148, 210);
- public static final PaperSize A9 = new PaperSize("a9", 105, 148);
- public static final PaperSize A10 = new PaperSize("a10", 73, 105);
-
- /**
- * Paper width in points.
- */
- private final int width;
-
- /**
- * Paper height in points.
- */
- private final int height;
-
- /**
- * Paper name (if standard paper size)
- */
- private String name;
-
- /**
- * Constructor accepting dimensions.
- *
- * @param width
- * Width
- * @param height
- * Height
- */
- public PaperSize(int width, int height) {
- this.width = width;
- this.height = height;
- }
-
- /**
- * Constructor accepting dimensions and name.
- *
- * @param name
- * Name. If provided, considered as a standard size (will be
- * accessible with the getStandardPaperSize later on).
- * @param width
- * Width
- * @param height
- * Height
- */
- public PaperSize(String name, int width, int height) {
- this.width = width;
- this.height = height;
- this.name = name;
-
- // if name: add to the index of standard sizes
- if (this.name != null) {
- synchronized (index) {
- index.put(this.name.toLowerCase(), this);
- }
+ /**
+ * Serial UID.
+ */
+ private static final long serialVersionUID = -1614204334526018509L;
+
+ /**
+ * Standard paper sizes index map. Allows faster paer size lookup by name.
+ */
+ private static final Map index = new HashMap();
+
+ public static final PaperSize LEDGER = new PaperSize("ledger", 1224, 792);
+ public static final PaperSize LEGAL = new PaperSize("legal", 612, 1008);
+ public static final PaperSize LETTER = new PaperSize("letter", 612, 792);
+ public static final PaperSize ARCHE = new PaperSize("archE", 2592, 3456);
+ public static final PaperSize ARCHD = new PaperSize("archD", 1728, 2592);
+ public static final PaperSize ARCHC = new PaperSize("archC", 1296, 1728);
+ public static final PaperSize ARCHB = new PaperSize("archB", 864, 1296);
+ public static final PaperSize ARCHA = new PaperSize("archA", 648, 864);
+ public static final PaperSize A0 = new PaperSize("a0", 2384, 3370);
+ public static final PaperSize A1 = new PaperSize("a1", 1684, 2384);
+ public static final PaperSize A2 = new PaperSize("a2", 1191, 1684);
+ public static final PaperSize A3 = new PaperSize("a3", 842, 1191);
+ public static final PaperSize A4 = new PaperSize("a4", 595, 842);
+ public static final PaperSize A5 = new PaperSize("a5", 420, 595);
+ public static final PaperSize A6 = new PaperSize("a6", 297, 420);
+ public static final PaperSize A7 = new PaperSize("a7", 210, 297);
+ public static final PaperSize A8 = new PaperSize("a8", 148, 210);
+ public static final PaperSize A9 = new PaperSize("a9", 105, 148);
+ public static final PaperSize A10 = new PaperSize("a10", 73, 105);
+
+ /**
+ * Paper width in points.
+ */
+ private final int width;
+
+ /**
+ * Paper height in points.
+ */
+ private final int height;
+
+ /**
+ * Paper name (if standard paper size)
+ */
+ private String name;
+
+ /**
+ * Constructor accepting dimensions.
+ *
+ * @param width
+ * Width
+ * @param height
+ * Height
+ */
+ public PaperSize(int width, int height) {
+ this.width = width;
+ this.height = height;
}
- }
-
- /**
- * Returns a scaled PaperSize according to a scale factor.
- *
- * @param factor
- * Scale factor
- * @return Scaled PaperSize
- */
- public PaperSize scale(float factor) {
-
- return new PaperSize((int) (width * factor), (int) (height * factor));
-
- }
-
- /**
- * Returns a portrait orientation of the PaperSize.
- *
- * @return A PaperSize.
- */
- public PaperSize portrait() {
- if (width > height) {
- return new PaperSize(height, width);
- } else {
- return new PaperSize(width, height);
+
+ /**
+ * Constructor accepting dimensions and name.
+ *
+ * @param name
+ * Name. If provided, considered as a standard size (will be
+ * accessible with the getStandardPaperSize later on).
+ * @param width
+ * Width
+ * @param height
+ * Height
+ */
+ public PaperSize(String name, int width, int height) {
+ this.width = width;
+ this.height = height;
+ this.name = name;
+
+ // if name: add to the index of standard sizes
+ if (this.name != null) {
+ synchronized (index) {
+ index.put(this.name.toLowerCase(), this);
+ }
+ }
+ }
+
+ /**
+ * Returns a scaled PaperSize according to a scale factor.
+ *
+ * @param factor
+ * Scale factor
+ * @return Scaled PaperSize
+ */
+ public PaperSize scale(float factor) {
+
+ return new PaperSize((int) (width * factor), (int) (height * factor));
+
+ }
+
+ /**
+ * Returns a portrait orientation of the PaperSize.
+ *
+ * @return A PaperSize.
+ */
+ public PaperSize portrait() {
+ if (width > height) {
+ return new PaperSize(height, width);
+ } else {
+ return new PaperSize(width, height);
+ }
+ }
+
+ /**
+ * Returns a landscape orientation of the PaperSize.
+ *
+ * @return A PaperSize.
+ */
+ public PaperSize landscape() {
+ if (width < height) {
+ return new PaperSize(height, width);
+ } else {
+ return new PaperSize(width, height);
+ }
}
- }
-
- /**
- * Returns a landscape orientation of the PaperSize.
- *
- * @return A PaperSize.
- */
- public PaperSize landscape() {
- if (width < height) {
- return new PaperSize(height, width);
- } else {
- return new PaperSize(width, height);
+
+ /**
+ * Looks for a standard paper size with a given name.
+ *
+ * @param name
+ * Paper size name (not case sensitive).
+ * @return PaperSize found or null
+ */
+ public static synchronized PaperSize getStandardPaperSize(String name) {
+
+ return index.get(name.toLowerCase());
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public String getName() {
+ return name;
}
- }
-
- /**
- * Looks for a standard paper size with a given name.
- *
- * @param name
- * Paper size name (not case sensitive).
- * @return PaperSize found or null
- */
- public static synchronized PaperSize getStandardPaperSize(String name) {
-
- return index.get(name.toLowerCase());
- }
-
- public int getWidth() {
- return width;
- }
-
- public int getHeight() {
- return height;
- }
-
- public String getName() {
- return name;
- }
}
diff --git a/src/main/java/org/ghost4j/modifier/AbstractModifier.java b/src/main/java/org/ghost4j/modifier/AbstractModifier.java
index f12aed5..4888e6a 100644
--- a/src/main/java/org/ghost4j/modifier/AbstractModifier.java
+++ b/src/main/java/org/ghost4j/modifier/AbstractModifier.java
@@ -22,16 +22,16 @@
* @author Gilles Grousset (gi.grousset@gmail.com)
*/
public abstract class AbstractModifier extends AbstractComponent implements
- Modifier {
+Modifier {
- public Document modify(Document source, Map parameters)
- throws ModifierException, DocumentException, IOException {
+ public Document modify(Document source, Map parameters)
+ throws ModifierException, DocumentException, IOException {
- // perform actual processing
- return run(source, parameters);
- }
+ // perform actual processing
+ return run(source, parameters);
+ }
- protected abstract Document run(Document source,
- Map parameters) throws ModifierException,
- DocumentException;
+ protected abstract Document run(Document source,
+ Map parameters) throws ModifierException,
+ DocumentException;
}
diff --git a/src/main/java/org/ghost4j/modifier/AbstractRemoteModifier.java b/src/main/java/org/ghost4j/modifier/AbstractRemoteModifier.java
index 488275a..974fd06 100644
--- a/src/main/java/org/ghost4j/modifier/AbstractRemoteModifier.java
+++ b/src/main/java/org/ghost4j/modifier/AbstractRemoteModifier.java
@@ -26,112 +26,112 @@
* @author Gilles Grousset (gi.grousset@gmail.com)
*/
public abstract class AbstractRemoteModifier extends AbstractRemoteComponent
- implements RemoteModifier {
-
- protected abstract Document run(Document source,
- Map parameters) throws ModifierException,
- DocumentException, IOException;
-
- /**
- * Starts a remote modifier server.
- *
- * @param remoteModifier
- * @throws ModifierException
- */
- protected static void startRemoteModifier(RemoteModifier remoteModifier)
- throws ModifierException {
-
- try {
-
- // get port
- if (System.getenv("cajo.port") == null) {
- throw new ModifierException(
- "No Cajo port defined for remote converter");
- }
- int cajoPort = Integer.parseInt(System.getenv("cajo.port"));
-
- // export modifier
- RemoteModifier modifierCopy = remoteModifier.getClass()
- .newInstance();
- remoteModifier.setMaxProcessCount(0);
-
- Remote.config(null, cajoPort, null, 0);
- ItemServer.bind(modifierCopy,
- RemoteModifier.class.getCanonicalName());
-
- } catch (Exception e) {
- throw new ModifierException(e);
+implements RemoteModifier {
+
+ protected abstract Document run(Document source,
+ Map parameters) throws ModifierException,
+ DocumentException, IOException;
+
+ /**
+ * Starts a remote modifier server.
+ *
+ * @param remoteModifier
+ * @throws ModifierException
+ */
+ protected static void startRemoteModifier(RemoteModifier remoteModifier)
+ throws ModifierException {
+
+ try {
+
+ // get port
+ if (System.getenv("cajo.port") == null) {
+ throw new ModifierException(
+ "No Cajo port defined for remote converter");
+ }
+ int cajoPort = Integer.parseInt(System.getenv("cajo.port"));
+
+ // export modifier
+ RemoteModifier modifierCopy = remoteModifier.getClass()
+ .getDeclaredConstructor().newInstance();
+ remoteModifier.setMaxProcessCount(0);
+
+ Remote.config(null, cajoPort, null, 0);
+ ItemServer.bind(modifierCopy,
+ RemoteModifier.class.getCanonicalName());
+
+ } catch (Exception e) {
+ throw new ModifierException(e);
+ }
+
}
- }
+ public Document remoteModify(Document source,
+ Map parameters) throws ModifierException,
+ DocumentException, IOException {
- public Document remoteModify(Document source,
- Map parameters) throws ModifierException,
- DocumentException, IOException {
+ return run(source, parameters);
- return run(source, parameters);
+ }
- }
+ public Document modify(Document source, Map parameters)
+ throws ModifierException, DocumentException, IOException {
- public Document modify(Document source, Map parameters)
- throws ModifierException, DocumentException, IOException {
+ if (maxProcessCount == 0) {
- if (maxProcessCount == 0) {
+ // perform actual processing
+ return run(source, parameters);
- // perform actual processing
- return run(source, parameters);
+ } else {
- } else {
+ // handle parallel processes
- // handle parallel processes
+ // wait for a process to get free
+ this.waitForFreeProcess();
+ processCount++;
- // wait for a process to get free
- this.waitForFreeProcess();
- processCount++;
+ // check if current class supports stand alone mode
+ if (!this.isStandAloneModeSupported()) {
+ throw new ModifierException(
+ "Standalone mode is not supported by this modifier: no 'main' method found");
+ }
- // check if current class supports stand alone mode
- if (!this.isStandAloneModeSupported()) {
- throw new ModifierException(
- "Standalone mode is not supported by this modifier: no 'main' method found");
- }
+ // prepare new JVM
+ JavaFork fork = this.buildJavaFork();
- // prepare new JVM
- JavaFork fork = this.buildJavaFork();
+ // set JVM Xmx parameter according to the document size
+ int documentMbSize = ((source.getSize() / 1024 / 1024) + 1) * 2;
+ int xmxValue = 64 + documentMbSize;
+ fork.setXmx(xmxValue + "m");
- // set JVM Xmx parameter according to the document size
- int documentMbSize = ((source.getSize() / 1024 / 1024) + 1) * 2;
- int xmxValue = 64 + documentMbSize;
- fork.setXmx(xmxValue + "m");
+ int cajoPort = 0;
- int cajoPort = 0;
+ try {
- try {
+ // start remove server
+ cajoPort = this.startRemoteServer(fork);
- // start remove server
- cajoPort = this.startRemoteServer(fork);
+ // get remote component
+ Object remote = this.getRemoteComponent(cajoPort,
+ RemoteModifier.class);
- // get remote component
- Object remote = this.getRemoteComponent(cajoPort,
- RemoteModifier.class);
+ // copy modifier settings to remote converter
+ Remote.invoke(remote, "copySettings", this.extractSettings());
- // copy modifier settings to remote converter
- Remote.invoke(remote, "copySettings", this.extractSettings());
+ // perform remote conversion
+ Object[] args = { source, parameters };
+ Document result = (Document) Remote.invoke(remote,
+ "remoteModify", args);
- // perform remote conversion
- Object[] args = { source, parameters };
- Document result = (Document) Remote.invoke(remote,
- "remoteModify", args);
+ // return result
+ return result;
- // return result
- return result;
+ } catch (Exception e) {
+ throw new ModifierException(e);
+ } finally {
+ processCount--;
+ fork.stop();
+ }
+ }
- } catch (Exception e) {
- throw new ModifierException(e);
- } finally {
- processCount--;
- fork.stop();
- }
}
-
- }
}
diff --git a/src/main/java/org/ghost4j/modifier/Modifier.java b/src/main/java/org/ghost4j/modifier/Modifier.java
index 2c47554..848d9f9 100644
--- a/src/main/java/org/ghost4j/modifier/Modifier.java
+++ b/src/main/java/org/ghost4j/modifier/Modifier.java
@@ -21,16 +21,16 @@
*/
public interface Modifier {
- /**
- * Modify a document with optional parameters
- *
- * @param source
- * Document to modify
- * @param parameters
- * Modifier parameters
- * @return Modifier version of the document
- * @throws ModifierException
- */
- public Document modify(Document source, Map parameters)
- throws ModifierException, DocumentException, IOException;
+ /**
+ * Modify a document with optional parameters
+ *
+ * @param source
+ * Document to modify
+ * @param parameters
+ * Modifier parameters
+ * @return Modifier version of the document
+ * @throws ModifierException
+ */
+ public Document modify(Document source, Map parameters)
+ throws ModifierException, DocumentException, IOException;
}
diff --git a/src/main/java/org/ghost4j/modifier/ModifierException.java b/src/main/java/org/ghost4j/modifier/ModifierException.java
index cedee95..55fcf55 100644
--- a/src/main/java/org/ghost4j/modifier/ModifierException.java
+++ b/src/main/java/org/ghost4j/modifier/ModifierException.java
@@ -15,24 +15,24 @@
*/
public class ModifierException extends Exception {
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 2810773454523525125L;
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 2810773454523525125L;
- public ModifierException() {
- super();
- }
+ public ModifierException() {
+ super();
+ }
- public ModifierException(String message) {
- super(message);
- }
+ public ModifierException(String message) {
+ super(message);
+ }
- public ModifierException(Throwable cause) {
- super(cause);
- }
+ public ModifierException(Throwable cause) {
+ super(cause);
+ }
- public ModifierException(String message, Throwable cause) {
- super(message, cause);
- }
+ public ModifierException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/src/main/java/org/ghost4j/modifier/RemoteModifier.java b/src/main/java/org/ghost4j/modifier/RemoteModifier.java
index b9ff913..6f2414a 100644
--- a/src/main/java/org/ghost4j/modifier/RemoteModifier.java
+++ b/src/main/java/org/ghost4j/modifier/RemoteModifier.java
@@ -13,11 +13,11 @@
*/
public interface RemoteModifier extends Modifier {
- /**
- * Sets max parallel rendering processes allowed for the modifier
- *
- * @param maxProcessCount
- */
- public void setMaxProcessCount(int maxProcessCount);
+ /**
+ * Sets max parallel rendering processes allowed for the modifier
+ *
+ * @param maxProcessCount
+ */
+ public void setMaxProcessCount(int maxProcessCount);
}
diff --git a/src/main/java/org/ghost4j/modifier/SafeAppenderModifier.java b/src/main/java/org/ghost4j/modifier/SafeAppenderModifier.java
index 46e07ff..1f9cce0 100644
--- a/src/main/java/org/ghost4j/modifier/SafeAppenderModifier.java
+++ b/src/main/java/org/ghost4j/modifier/SafeAppenderModifier.java
@@ -31,117 +31,117 @@
*/
public class SafeAppenderModifier extends AbstractRemoteModifier {
- public static final String PARAMETER_APPEND_DOCUMENT = "APPEND_DOCUMENT";
-
- public SafeAppenderModifier() {
-
- // set supported classes
- supportedDocumentClasses = new Class[] { PSDocument.class,
- PDFDocument.class };
- }
-
- /**
- * Main method used to start the modifier in standalone 'slave mode'.
- *
- * @param args
- * @throws ModifierException
- */
- public static void main(String args[]) throws ModifierException {
- startRemoteModifier(new SafeAppenderModifier());
- }
-
- @Override
- protected Document run(Document source, Map parameters)
- throws ModifierException, DocumentException, IOException {
-
- // check that document to append is provided as parameter
- Document append = (Document) parameters.get(PARAMETER_APPEND_DOCUMENT);
- if (append == null) {
- throw new ModifierException(
- "No document to append found in parameters map");
- }
+ public static final String PARAMETER_APPEND_DOCUMENT = "APPEND_DOCUMENT";
- // get Ghostscript instance
- Ghostscript gs = Ghostscript.getInstance();
-
- // generate a unique diskstore key for source and append documents, and
- // for output file
- DiskStore diskStore = DiskStore.getInstance();
- String sourceDiskStoreKey = diskStore.generateUniqueKey();
- String appendDiskStoreKey = diskStore.generateUniqueKey();
- String outputDiskStoreKey = diskStore.generateUniqueKey();
-
- // write source and append to files
- source.write(diskStore.addFile(sourceDiskStoreKey));
- append.write(diskStore.addFile(appendDiskStoreKey));
-
- // guess output device from source document type
- String deviceName = "pswrite";
- try {
- if (source.getType().equals(Document.TYPE_PDF)) {
- deviceName = "pdfwrite";
- } else {
- // for Postscript : use ps2write if available
- if (this.isDeviceSupported("ps2write")) {
- deviceName = "ps2write";
- } else {
- deviceName = "pswrite";
- }
- }
- } catch (GhostscriptException e) {
- throw new ModifierException(e);
+ public SafeAppenderModifier() {
+
+ // set supported classes
+ supportedDocumentClasses = new Class[] { PSDocument.class,
+ PDFDocument.class };
}
- // prepare args
- String[] gsArgs = {
- "-psconv",
- "-dNOPAUSE",
- "-dSAFER",
- "-dBATCH",
- "-sDEVICE=" + deviceName,
- "-sOutputFile="
- + diskStore.addFile(outputDiskStoreKey)
- .getAbsolutePath(), "-q", "-f",
- diskStore.getFile(sourceDiskStoreKey).getAbsolutePath(),
- diskStore.getFile(appendDiskStoreKey).getAbsolutePath() };
-
- Document result = null;
-
- try {
-
- // execute and exit interpreter
- synchronized (gs) {
- gs.initialize(gsArgs);
- gs.exit();
- }
-
- // load obtained document (same type as source document)
- if (source.getType().equals(Document.TYPE_PDF)) {
- result = new PDFDocument();
- } else if (source.getType().equals(Document.TYPE_POSTSCRIPT)) {
- result = new PSDocument();
- }
- result.load(diskStore.getFile(outputDiskStoreKey));
-
- } catch (GhostscriptException e) {
-
- throw new ModifierException(e);
-
- } finally {
-
- // delete Ghostscript instance
- try {
- Ghostscript.deleteInstance();
- } catch (GhostscriptException e) {
- throw new ModifierException(e);
- }
-
- // remove temporary files
- diskStore.removeFile(outputDiskStoreKey);
- diskStore.removeFile(sourceDiskStoreKey);
- diskStore.removeFile(appendDiskStoreKey);
+ /**
+ * Main method used to start the modifier in standalone 'slave mode'.
+ *
+ * @param args
+ * @throws ModifierException
+ */
+ public static void main(String args[]) throws ModifierException {
+ startRemoteModifier(new SafeAppenderModifier());
}
- return result;
- }
+ @Override
+ protected Document run(Document source, Map parameters)
+ throws ModifierException, DocumentException, IOException {
+
+ // check that document to append is provided as parameter
+ Document append = (Document) parameters.get(PARAMETER_APPEND_DOCUMENT);
+ if (append == null) {
+ throw new ModifierException(
+ "No document to append found in parameters map");
+ }
+
+ // get Ghostscript instance
+ Ghostscript gs = Ghostscript.getInstance();
+
+ // generate a unique diskstore key for source and append documents, and
+ // for output file
+ DiskStore diskStore = DiskStore.getInstance();
+ String sourceDiskStoreKey = diskStore.generateUniqueKey();
+ String appendDiskStoreKey = diskStore.generateUniqueKey();
+ String outputDiskStoreKey = diskStore.generateUniqueKey();
+
+ // write source and append to files
+ source.write(diskStore.addFile(sourceDiskStoreKey));
+ append.write(diskStore.addFile(appendDiskStoreKey));
+
+ // guess output device from source document type
+ String deviceName = "pswrite";
+ try {
+ if (source.getType().equals(Document.TYPE_PDF)) {
+ deviceName = "pdfwrite";
+ } else {
+ // for Postscript : use ps2write if available
+ if (this.isDeviceSupported("ps2write")) {
+ deviceName = "ps2write";
+ } else {
+ deviceName = "pswrite";
+ }
+ }
+ } catch (GhostscriptException e) {
+ throw new ModifierException(e);
+ }
+
+ // prepare args
+ String[] gsArgs = {
+ "-psconv",
+ "-dNOPAUSE",
+ "-dSAFER",
+ "-dBATCH",
+ "-sDEVICE=" + deviceName,
+ "-sOutputFile="
+ + diskStore.addFile(outputDiskStoreKey)
+ .getAbsolutePath(), "-q", "-f",
+ diskStore.getFile(sourceDiskStoreKey).getAbsolutePath(),
+ diskStore.getFile(appendDiskStoreKey).getAbsolutePath() };
+
+ Document result = null;
+
+ try {
+
+ // execute and exit interpreter
+ synchronized (gs) {
+ gs.initialize(gsArgs);
+ gs.exit();
+ }
+
+ // load obtained document (same type as source document)
+ if (source.getType().equals(Document.TYPE_PDF)) {
+ result = new PDFDocument();
+ } else if (source.getType().equals(Document.TYPE_POSTSCRIPT)) {
+ result = new PSDocument();
+ }
+ result.load(diskStore.getFile(outputDiskStoreKey));
+
+ } catch (GhostscriptException e) {
+
+ throw new ModifierException(e);
+
+ } finally {
+
+ // delete Ghostscript instance
+ try {
+ Ghostscript.deleteInstance();
+ } catch (GhostscriptException e) {
+ throw new ModifierException(e);
+ }
+
+ // remove temporary files
+ diskStore.removeFile(outputDiskStoreKey);
+ diskStore.removeFile(sourceDiskStoreKey);
+ diskStore.removeFile(appendDiskStoreKey);
+ }
+
+ return result;
+ }
}
diff --git a/src/main/java/org/ghost4j/util/DiskStore.java b/src/main/java/org/ghost4j/util/DiskStore.java
index 4a0f9af..e75e4bd 100644
--- a/src/main/java/org/ghost4j/util/DiskStore.java
+++ b/src/main/java/org/ghost4j/util/DiskStore.java
@@ -22,142 +22,142 @@
*/
public class DiskStore {
- public static final String ROOT_PATH = System.getProperty("java.io.tmpdir")
- + File.separator + "ghost4j";
-
- /**
- * Shared instance.
- */
- private static DiskStore instance;
-
- /**
- * Map used to store references to temprorary files.
- */
- private final Map map;
-
- /**
- * Access to the shared instance.
- *
- * @return The shared DiskStore instance.
- */
- public static synchronized DiskStore getInstance() {
-
- if (instance == null) {
- instance = new DiskStore();
+ public static final String ROOT_PATH = System.getProperty("java.io.tmpdir")
+ + File.separator + "ghost4j";
+
+ /**
+ * Shared instance.
+ */
+ private static DiskStore instance;
+
+ /**
+ * Map used to store references to temprorary files.
+ */
+ private final Map map;
+
+ /**
+ * Access to the shared instance.
+ *
+ * @return The shared DiskStore instance.
+ */
+ public static synchronized DiskStore getInstance() {
+
+ if (instance == null) {
+ instance = new DiskStore();
+ }
+
+ return instance;
+
}
- return instance;
+ /**
+ * Private constructor.
+ */
+ private DiskStore() {
- }
+ map = new HashMap();
- /**
- * Private constructor.
- */
- private DiskStore() {
+ // register a shutdown hook to ensure temporary files are deleted at
+ // shutdown
+ Runtime.getRuntime().addShutdownHook(new Thread() {
- map = new HashMap();
+ @Override
+ public void run() {
+ super.run();
- // register a shutdown hook to ensure temporary files are deleted at
- // shutdown
- Runtime.getRuntime().addShutdownHook(new Thread() {
+ DiskStore diskStore = DiskStore.getInstance();
- @Override
- public void run() {
- super.run();
+ // remove all files when store is destroyed
+ try {
+ for (String key : map.keySet()) {
+ diskStore.removeFile(key);
+ }
- DiskStore diskStore = DiskStore.getInstance();
+ // remove root dir
+ new File(ROOT_PATH).delete();
- // remove all files when store is destroyed
- try {
- for (String key : map.keySet()) {
- diskStore.removeFile(key);
- }
+ } catch (Exception e) {
+ // fail silently...
+ }
+ }
+ });
- // remove root dir
- new File(ROOT_PATH).delete();
+ }
- } catch (Exception e) {
- // fail silently...
+ /**
+ * Generates a unique diskstore key. Use the JVM PID and UUID.
+ *
+ * @return A unique key as string
+ */
+ public synchronized String generateUniqueKey() {
+
+ UUID id = UUID.randomUUID();
+ String pid = ManagementFactory.getRuntimeMXBean().getName();
+ if (pid.contains("@")) {
+ pid = pid.split("@")[0];
}
- }
- });
-
- }
-
- /**
- * Generates a unique diskstore key. Use the JVM PID and UUID.
- *
- * @return A unique key as string
- */
- public synchronized String generateUniqueKey() {
-
- UUID id = UUID.randomUUID();
- String pid = ManagementFactory.getRuntimeMXBean().getName();
- if (pid.contains("@")) {
- pid = pid.split("@")[0];
+ return id + "@" + pid;
}
- return id + "@" + pid;
- }
-
- /**
- * Retrieve a File from a store key. If key is unknown, null is returned.
- *
- * @param key
- * Unique file resource identifier.
- * @return File or null (if not found).
- */
- public synchronized File getFile(String key) {
-
- return map.get(key);
-
- }
-
- /**
- * Remove a file from the store. This also deleted the temporary file from
- * the file system.
- *
- * @param key
- * Unique file resource identifier.
- * @throws IOException
- * In case the file cannot be deleted.
- */
- public synchronized void removeFile(String key) throws IOException {
-
- File file = this.getFile(key);
-
- if (file != null && file.exists()) {
-
- // delete file
- if (!file.delete()) {
- throw new IOException("Temporary file "
- + file.getAbsolutePath() + " cannot be deleted");
- }
-
- // remove from map
- map.remove(key);
+
+ /**
+ * Retrieve a File from a store key. If key is unknown, null is returned.
+ *
+ * @param key
+ * Unique file resource identifier.
+ * @return File or null (if not found).
+ */
+ public synchronized File getFile(String key) {
+
+ return map.get(key);
+
}
- }
- /**
- * Add a file to the store.
- *
- * @param key
- * File unique identifier.
- * @return The generated (empty) file.
- */
- public synchronized File addFile(String key) {
+ /**
+ * Remove a file from the store. This also deleted the temporary file from
+ * the file system.
+ *
+ * @param key
+ * Unique file resource identifier.
+ * @throws IOException
+ * In case the file cannot be deleted.
+ */
+ public synchronized void removeFile(String key) throws IOException {
+
+ File file = this.getFile(key);
+
+ if (file != null && file.exists()) {
+
+ // delete file
+ if (!file.delete()) {
+ throw new IOException("Temporary file "
+ + file.getAbsolutePath() + " cannot be deleted");
+ }
+
+ // remove from map
+ map.remove(key);
+ }
+ }
- // prepare file
- File file = new File(ROOT_PATH, key);
+ /**
+ * Add a file to the store.
+ *
+ * @param key
+ * File unique identifier.
+ * @return The generated (empty) file.
+ */
+ public synchronized File addFile(String key) {
- // ensure store root is created
- file.getParentFile().mkdirs();
+ // prepare file
+ File file = new File(ROOT_PATH, key);
- // add to map
- map.put(key, file);
+ // ensure store root is created
+ file.getParentFile().mkdirs();
- return file;
+ // add to map
+ map.put(key, file);
- }
+ return file;
+
+ }
}
diff --git a/src/main/java/org/ghost4j/util/ImageUtil.java b/src/main/java/org/ghost4j/util/ImageUtil.java
index 80d8dd4..9edfaae 100644
--- a/src/main/java/org/ghost4j/util/ImageUtil.java
+++ b/src/main/java/org/ghost4j/util/ImageUtil.java
@@ -28,48 +28,48 @@
*/
public class ImageUtil {
- /**
- * Converts a list of PageRaster objects to a list of Image objects
- *
- * @param rasters
- * Page rasters to convert
- * @return A list of images
- */
- public static List convertPageRastersToImages(
- List rasters) {
+ /**
+ * Converts a list of PageRaster objects to a list of Image objects
+ *
+ * @param rasters
+ * Page rasters to convert
+ * @return A list of images
+ */
+ public static List convertPageRastersToImages(
+ List rasters) {
- List result = new ArrayList();
+ List result = new ArrayList();
- for (PageRaster raster : rasters) {
- result.add(converterPageRasterToImage(raster));
- }
+ for (PageRaster raster : rasters) {
+ result.add(converterPageRasterToImage(raster));
+ }
- return result;
- }
+ return result;
+ }
- /**
- * Converts a PageRaster object to an Image object. Raster data is supposed
- * to hold RGB image data
- *
- * @param raster
- * Page raster to convert
- * @return An image
- */
- public static Image converterPageRasterToImage(PageRaster raster) {
+ /**
+ * Converts a PageRaster object to an Image object. Raster data is supposed
+ * to hold RGB image data
+ *
+ * @param raster
+ * Page raster to convert
+ * @return An image
+ */
+ public static Image converterPageRasterToImage(PageRaster raster) {
- // create raster
- DataBufferByte dbb = new DataBufferByte(raster.getData(),
- raster.getData().length);
- WritableRaster wr = Raster.createInterleavedRaster(dbb,
- raster.getWidth(), raster.getHeight(), raster.getRaster(), 3,
- new int[] { 0, 1, 2 }, null);
+ // create raster
+ DataBufferByte dbb = new DataBufferByte(raster.getData(),
+ raster.getData().length);
+ WritableRaster wr = Raster.createInterleavedRaster(dbb,
+ raster.getWidth(), raster.getHeight(), raster.getRaster(), 3,
+ new int[] { 0, 1, 2 }, null);
- // create color space
- ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
- ColorModel cm = new ComponentColorModel(cs, false, false,
- Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+ // create color space
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ ColorModel cm = new ComponentColorModel(cs, false, false,
+ Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
- // create image and return it
- return new BufferedImage(cm, wr, false, null);
- }
+ // create image and return it
+ return new BufferedImage(cm, wr, false, null);
+ }
}
diff --git a/src/main/java/org/ghost4j/util/JavaFork.java b/src/main/java/org/ghost4j/util/JavaFork.java
index 5b940e2..6a700c8 100644
--- a/src/main/java/org/ghost4j/util/JavaFork.java
+++ b/src/main/java/org/ghost4j/util/JavaFork.java
@@ -25,289 +25,289 @@
*/
public class JavaFork implements Runnable {
- private static final String JAVA_COMMAND;
- private static final String PATH_SEPARATOR = System
- .getProperty("path.separator");
+ private static final String JAVA_COMMAND;
+ private static final String PATH_SEPARATOR = System
+ .getProperty("path.separator");
private static final String FILE_SEPARATOR = File.separator;
- static {
- if (System.getProperty("os.name").toLowerCase().contains("windows")) {
- JAVA_COMMAND = "javaw";
- } else {
- JAVA_COMMAND = "java";
- }
- }
-
- /**
- * Start class of the JVM.
- */
- private Class> startClass;
- /**
- * Process object of the JVM. Is null if the JVM is not running.
- */
- private Process process;
- /**
- * If set to TRUE, output and error streams are redirected to the main JVM
- * output stream
- */
- private boolean redirectStreams;
- /**
- * If set to TRUE, main JVM will wait for this JVM to stop before exiting.
- */
- private boolean waitBeforeExiting = false;
-
- /**
- * Additional environment variables.
- */
- private Map environment;
-
- /**
- * Xmx parameter. Default value is set to 128M.
- */
- private String xmx = "128m";
-
- /**
- * Xms parameter. Default value is set to 64M.
- */
- private String xms = "64m";
-
- public void start(Class> startClass) {
-
- this.setStartClass(startClass);
- this.start();
-
- }
-
- public void start() {
-
- // start thread
- final Thread thread = new Thread(this);
- thread.setDaemon(false);
- thread.start();
-
- // register shutdown hook to wait for thread when JVM exists
- if (waitBeforeExiting) {
- Runtime.getRuntime().addShutdownHook(new Thread() {
-
- @Override
- public void run() {
- try {
- thread.join();
- } catch (InterruptedException e) {
- // nothing
- }
+ static {
+ if (System.getProperty("os.name").toLowerCase().contains("windows")) {
+ JAVA_COMMAND = "javaw";
+ } else {
+ JAVA_COMMAND = "java";
}
-
- });
}
- }
+ /**
+ * Start class of the JVM.
+ */
+ private Class> startClass;
+ /**
+ * Process object of the JVM. Is null if the JVM is not running.
+ */
+ private Process process;
+ /**
+ * If set to TRUE, output and error streams are redirected to the main JVM
+ * output stream
+ */
+ private boolean redirectStreams;
+ /**
+ * If set to TRUE, main JVM will wait for this JVM to stop before exiting.
+ */
+ private boolean waitBeforeExiting = false;
+
+ /**
+ * Additional environment variables.
+ */
+ private Map environment;
+
+ /**
+ * Xmx parameter. Default value is set to 128M.
+ */
+ private String xmx = "128m";
+
+ /**
+ * Xms parameter. Default value is set to 64M.
+ */
+ private String xms = "64m";
+
+ public void start(Class> startClass) {
+
+ this.setStartClass(startClass);
+ this.start();
- public void stop() {
-
- if (process != null) {
- process.destroy();
}
- }
- public void run() {
+ public void start() {
- // check if process is not already running
- if (process != null) {
- throw new RuntimeException("Fork is already running");
- }
+ // start thread
+ final Thread thread = new Thread(this);
+ thread.setDaemon(false);
+ thread.start();
- // check if start class is set
- if (startClass == null) {
- throw new RuntimeException("No start class defined");
- }
+ // register shutdown hook to wait for thread when JVM exists
+ if (waitBeforeExiting) {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
- // retrieve classpath
- String classPath = this.getCurrentClasspath();
+ @Override
+ public void run() {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ // nothing
+ }
+ }
+
+ });
+ }
- // build child process
- String ghost4JEncoding = System.getProperty("ghost4j.encoding");
- String fileEncoding = "-Dfile.encoding=";
- if (ghost4JEncoding != null) {
- fileEncoding += ghost4JEncoding;
- } else {
- fileEncoding += System.getProperty("file.encoding");
- }
- ProcessBuilder processBuilder = new ProcessBuilder(JAVA_COMMAND,
- fileEncoding, "-Xms" + xms, "-Xmx" + xmx, "-cp", classPath,
- startClass.getName());
- if (System.getProperty("jna.library.path") != null) {
- String jnaLibraryPath = "-Djna.library.path="
- + System.getProperty("jna.library.path");
- processBuilder = new ProcessBuilder(JAVA_COMMAND, fileEncoding,
- jnaLibraryPath, "-Xms" + xms, "-Xmx" + xmx, "-cp",
- classPath, startClass.getName());
- }
- processBuilder.directory(new File(System.getProperty("user.dir")));
- processBuilder.environment().putAll(System.getenv());
- if (getEnvironment() != null) {
- processBuilder.environment().putAll(getEnvironment());
}
- // start
- try {
- process = processBuilder.start();
+ public void stop() {
- // redirect output stream to main process output stream
- if (redirectStreams) {
- // error stream
- processBuilder.redirectErrorStream(true);
- // standard stream
- StreamGobbler outputStreamGobbler = new StreamGobbler(
- process.getInputStream(), System.out);
- outputStreamGobbler.start();
- }
+ if (process != null) {
+ process.destroy();
+ }
+ }
- process.waitFor();
+ public void run() {
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ // check if process is not already running
+ if (process != null) {
+ throw new RuntimeException("Fork is already running");
+ }
- }
+ // check if start class is set
+ if (startClass == null) {
+ throw new RuntimeException("No start class defined");
+ }
- private String getCurrentClasspath() {
- StringBuilder cpBuilder = new StringBuilder();
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
- if(classLoader instanceof URLClassLoader) {
- URL[] urls = ((URLClassLoader) classLoader).getURLs();
-
- for (int i = 0; i < urls.length; i++) {
- // need to do some conversion to get the paths right
- // otherwise paths get broken on windows
- String s = urls[i].toExternalForm();
+ // retrieve classpath
+ String classPath = this.getCurrentClasspath();
- try {
- s = URLDecoder.decode(s, "UTF-8");
- urls[i] = new URL(s);
- s = new File(urls[i].getFile()).getAbsolutePath();
- cpBuilder.append(s);
- if (i < urls.length - 1)
- cpBuilder.append(PATH_SEPARATOR);
- } catch (UnsupportedEncodingException e) {
- // should never happen as we pass supported encoding UTF-8
- } catch (MalformedURLException e) {
- // should also never happen at this point, but who knows ;-)
- }
+ // build child process
+ String ghost4JEncoding = System.getProperty("ghost4j.encoding");
+ String fileEncoding = "-Dfile.encoding=";
+ if (ghost4JEncoding != null) {
+ fileEncoding += ghost4JEncoding;
+ } else {
+ fileEncoding += System.getProperty("file.encoding");
+ }
+ ProcessBuilder processBuilder = new ProcessBuilder(JAVA_COMMAND,
+ fileEncoding, "-Xms" + xms, "-Xmx" + xmx, "-cp", classPath,
+ startClass.getName());
+ if (System.getProperty("jna.library.path") != null) {
+ String jnaLibraryPath = "-Djna.library.path="
+ + System.getProperty("jna.library.path");
+ processBuilder = new ProcessBuilder(JAVA_COMMAND, fileEncoding,
+ jnaLibraryPath, "-Xms" + xms, "-Xmx" + xmx, "-cp",
+ classPath, startClass.getName());
+ }
+ processBuilder.directory(new File(System.getProperty("user.dir")));
+ processBuilder.environment().putAll(System.getenv());
+ if (getEnvironment() != null) {
+ processBuilder.environment().putAll(getEnvironment());
}
- } else if (classLoader.getClass().getName().equals("org.jboss.modules.ModuleClassLoader")) {
- // This branch is for JBoss 7 & JBoss EAP 6 support. Not sure about Wildfly
+
+ // start
try {
- Enumeration urls2 = classLoader.getResources("/");
-
- while (urls2.hasMoreElements()) {
- URL path = urls2.nextElement();
- String s = path.toExternalForm();
- if(s.startsWith("vfs:")) {
- if(s.contains(".jar")) {
- URLConnection conn = new URL(URLDecoder.decode(s, "UTF-8")).openConnection();
- Object vf = conn.getContent();
- // Use reflection to call getPhysicalFile() method org.jboss.vfs.VirtualFile
- // This eliminates the dependency on JBoss specific jar files
- Method getPhysicalFile = vf.getClass().getDeclaredMethod("getPhysicalFile");
- getPhysicalFile.setAccessible(true);
- File physicalFile = (File)getPhysicalFile.invoke(vf);
- String jarVFSPath = physicalFile.getAbsolutePath();
-
- int idxJarExt = jarVFSPath.lastIndexOf(".jar");
- int idxSlashAfterJar = jarVFSPath.indexOf(FILE_SEPARATOR, idxJarExt);
- int idxSlashBeforeJar = jarVFSPath.substring(0,idxJarExt).lastIndexOf(FILE_SEPARATOR);
-
- String jarFileName2 = jarVFSPath.substring(idxSlashBeforeJar + 1, idxJarExt + 4);
- String jarFolder = jarVFSPath.substring(0, idxSlashAfterJar);
- String jarFullPath = jarFolder + FILE_SEPARATOR + jarFileName2;
-
- cpBuilder.append(jarFullPath);
- if (urls2.hasMoreElements()) {
- cpBuilder.append(PATH_SEPARATOR);
- }
- } else if(s.contains("classes")) {
- URLConnection conn = new URL(URLDecoder.decode(s, "UTF-8")).openConnection();
- Object vf = conn.getContent();
- // Use reflection to call getPhysicalFile() method org.jboss.vfs.VirtualFile
- // This eliminates the dependency on JBoss specific jar files
- Method getPhysicalFile = vf.getClass().getDeclaredMethod("getPhysicalFile");
- getPhysicalFile.setAccessible(true);
- File physicalFile = (File)getPhysicalFile.invoke(vf);
- String jarVFSPath = physicalFile.getAbsolutePath();
- cpBuilder.append(jarVFSPath);
- if (urls2.hasMoreElements()) {
- cpBuilder.append(PATH_SEPARATOR);
- }
- }
- }
+ process = processBuilder.start();
+
+ // redirect output stream to main process output stream
+ if (redirectStreams) {
+ // error stream
+ processBuilder.redirectErrorStream(true);
+ // standard stream
+ StreamGobbler outputStreamGobbler = new StreamGobbler(
+ process.getInputStream(), System.out);
+ outputStreamGobbler.start();
}
+
+ process.waitFor();
+
} catch (Exception e) {
throw new RuntimeException(e);
}
- } else {
- throw new RuntimeException("Found unknown ClassLoader type, cannot scan classes: " + classLoader.getClass().getName());
- }
-
- String cp = cpBuilder.toString();
-
- if (cp.isEmpty() || cp.contains("surefirebooter")) {
- // if called from Maven: use the java.class.path property as
- // classpath
- return System.getProperty("java.class.path");
- } else {
- return cp;
+
}
- }
+ private String getCurrentClasspath() {
+ StringBuilder cpBuilder = new StringBuilder();
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+ if(classLoader instanceof URLClassLoader) {
+ URL[] urls = ((URLClassLoader) classLoader).getURLs();
+
+ for (int i = 0; i < urls.length; i++) {
+ // need to do some conversion to get the paths right
+ // otherwise paths get broken on windows
+ String s = urls[i].toExternalForm();
+
+ try {
+ s = URLDecoder.decode(s, "UTF-8");
+ urls[i] = new URL(s);
+ s = new File(urls[i].getFile()).getAbsolutePath();
+ cpBuilder.append(s);
+ if (i < urls.length - 1)
+ cpBuilder.append(PATH_SEPARATOR);
+ } catch (UnsupportedEncodingException e) {
+ // should never happen as we pass supported encoding UTF-8
+ } catch (MalformedURLException e) {
+ // should also never happen at this point, but who knows ;-)
+ }
+ }
+ } else if (classLoader.getClass().getName().equals("org.jboss.modules.ModuleClassLoader")) {
+ // This branch is for JBoss 7 & JBoss EAP 6 support. Not sure about Wildfly
+ try {
+ Enumeration urls2 = classLoader.getResources("/");
+
+ while (urls2.hasMoreElements()) {
+ URL path = urls2.nextElement();
+ String s = path.toExternalForm();
+ if(s.startsWith("vfs:")) {
+ if(s.contains(".jar")) {
+ URLConnection conn = new URL(URLDecoder.decode(s, "UTF-8")).openConnection();
+ Object vf = conn.getContent();
+ // Use reflection to call getPhysicalFile() method org.jboss.vfs.VirtualFile
+ // This eliminates the dependency on JBoss specific jar files
+ Method getPhysicalFile = vf.getClass().getDeclaredMethod("getPhysicalFile");
+ getPhysicalFile.setAccessible(true);
+ File physicalFile = (File)getPhysicalFile.invoke(vf);
+ String jarVFSPath = physicalFile.getAbsolutePath();
+
+ int idxJarExt = jarVFSPath.lastIndexOf(".jar");
+ int idxSlashAfterJar = jarVFSPath.indexOf(FILE_SEPARATOR, idxJarExt);
+ int idxSlashBeforeJar = jarVFSPath.substring(0,idxJarExt).lastIndexOf(FILE_SEPARATOR);
+
+ String jarFileName2 = jarVFSPath.substring(idxSlashBeforeJar + 1, idxJarExt + 4);
+ String jarFolder = jarVFSPath.substring(0, idxSlashAfterJar);
+ String jarFullPath = jarFolder + FILE_SEPARATOR + jarFileName2;
+
+ cpBuilder.append(jarFullPath);
+ if (urls2.hasMoreElements()) {
+ cpBuilder.append(PATH_SEPARATOR);
+ }
+ } else if(s.contains("classes")) {
+ URLConnection conn = new URL(URLDecoder.decode(s, "UTF-8")).openConnection();
+ Object vf = conn.getContent();
+ // Use reflection to call getPhysicalFile() method org.jboss.vfs.VirtualFile
+ // This eliminates the dependency on JBoss specific jar files
+ Method getPhysicalFile = vf.getClass().getDeclaredMethod("getPhysicalFile");
+ getPhysicalFile.setAccessible(true);
+ File physicalFile = (File)getPhysicalFile.invoke(vf);
+ String jarVFSPath = physicalFile.getAbsolutePath();
+ cpBuilder.append(jarVFSPath);
+ if (urls2.hasMoreElements()) {
+ cpBuilder.append(PATH_SEPARATOR);
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ throw new RuntimeException("Found unknown ClassLoader type, cannot scan classes: " + classLoader.getClass().getName());
+ }
- public Class> getStartClass() {
- return startClass;
- }
+ String cp = cpBuilder.toString();
- public void setStartClass(Class> startClass) {
- this.startClass = startClass;
- }
+ if (cp.isEmpty() || cp.contains("surefirebooter")) {
+ // if called from Maven: use the java.class.path property as
+ // classpath
+ return System.getProperty("java.class.path");
+ } else {
+ return cp;
+ }
- public boolean getRedirectStreams() {
- return redirectStreams;
- }
+ }
- public void setRedirectStreams(boolean redirectStreams) {
- this.redirectStreams = redirectStreams;
- }
+ public Class> getStartClass() {
+ return startClass;
+ }
- public boolean getWaitBeforeExiting() {
- return waitBeforeExiting;
- }
+ public void setStartClass(Class> startClass) {
+ this.startClass = startClass;
+ }
- public void setWaitBeforeExiting(boolean waitBeforeExiting) {
- this.waitBeforeExiting = waitBeforeExiting;
- }
+ public boolean getRedirectStreams() {
+ return redirectStreams;
+ }
- public Map getEnvironment() {
- return environment;
- }
+ public void setRedirectStreams(boolean redirectStreams) {
+ this.redirectStreams = redirectStreams;
+ }
+
+ public boolean getWaitBeforeExiting() {
+ return waitBeforeExiting;
+ }
+
+ public void setWaitBeforeExiting(boolean waitBeforeExiting) {
+ this.waitBeforeExiting = waitBeforeExiting;
+ }
+
+ public Map getEnvironment() {
+ return environment;
+ }
- public void setEnvironment(Map environment) {
- this.environment = environment;
- }
+ public void setEnvironment(Map environment) {
+ this.environment = environment;
+ }
- public String getXmx() {
- return xmx;
- }
+ public String getXmx() {
+ return xmx;
+ }
- public void setXmx(String xmx) {
- this.xmx = xmx;
- }
+ public void setXmx(String xmx) {
+ this.xmx = xmx;
+ }
- public String getXms() {
- return xms;
- }
+ public String getXms() {
+ return xms;
+ }
- public void setXms(String xms) {
- this.xms = xms;
- }
+ public void setXms(String xms) {
+ this.xms = xms;
+ }
}
diff --git a/src/main/java/org/ghost4j/util/NetworkUtil.java b/src/main/java/org/ghost4j/util/NetworkUtil.java
index 5518684..1df7263 100644
--- a/src/main/java/org/ghost4j/util/NetworkUtil.java
+++ b/src/main/java/org/ghost4j/util/NetworkUtil.java
@@ -17,76 +17,76 @@
*/
public class NetworkUtil {
- /**
- * Finds an available port within a port range on a host
- *
- * @param hostname
- * Host name
- * @param startPort
- * Port number starting the range
- * @param endPort
- * Port number ending the range
- * @return An available port number, or 0 if none is available.
- */
- public static synchronized int findAvailablePort(String hostname,
- int startPort, int endPort) {
+ /**
+ * Finds an available port within a port range on a host
+ *
+ * @param hostname
+ * Host name
+ * @param startPort
+ * Port number starting the range
+ * @param endPort
+ * Port number ending the range
+ * @return An available port number, or 0 if none is available.
+ */
+ public static synchronized int findAvailablePort(String hostname,
+ int startPort, int endPort) {
- for (int port = startPort; port < (endPort + 1); port++) {
+ for (int port = startPort; port < (endPort + 1); port++) {
- try {
- Socket socket = new Socket(InetAddress.getByName(hostname),
- port);
- // port not available
- socket.close();
- } catch (IOException e) {
- // port available
- return port;
- }
+ try {
+ Socket socket = new Socket(InetAddress.getByName(hostname),
+ port);
+ // port not available
+ socket.close();
+ } catch (IOException e) {
+ // port available
+ return port;
+ }
+ }
+
+ return 0;
}
- return 0;
- }
+ /**
+ * Waits until a port is listening on a given host. An exception is thrown
+ * if the timeout is excedeed.
+ *
+ * @param hostname
+ * Host name
+ * @param port
+ * Port number
+ * @param timeout
+ * Timeout in seconds
+ * @throws IOException
+ * If a connection error occurs or if the timeout is exceeded
+ */
+ public static void waitUntilPortListening(String hostname, int port,
+ int timeout) throws IOException {
- /**
- * Waits until a port is listening on a given host. An exception is thrown
- * if the timeout is excedeed.
- *
- * @param hostname
- * Host name
- * @param port
- * Port number
- * @param timeout
- * Timeout in seconds
- * @throws IOException
- * If a connection error occurs or if the timeout is exceeded
- */
- public static void waitUntilPortListening(String hostname, int port,
- int timeout) throws IOException {
+ int i = 0;
+ while (i < timeout) {
- int i = 0;
- while (i < timeout) {
+ // try to get connection
+ try {
+ Socket socket = new Socket(InetAddress.getByName(hostname),
+ port);
+ // connection OK: exit
+ socket.close();
+ return;
+ } catch (IOException e) {
+ // nothing
+ }
- // try to get connection
- try {
- Socket socket = new Socket(InetAddress.getByName(hostname),
- port);
- // connection OK: exit
- socket.close();
- return;
- } catch (IOException e) {
- // nothing
- }
+ i++;
- i++;
+ // wait for 1 second
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // nothing
+ }
+ }
- // wait for 1 second
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // nothing
- }
+ throw new IOException("Timeout waiting for port " + port + " to listen");
}
-
- throw new IOException("Timeout waiting for port " + port + " to listen");
- }
}
diff --git a/src/main/java/org/ghost4j/util/StreamGobbler.java b/src/main/java/org/ghost4j/util/StreamGobbler.java
index 0173b59..435fc9b 100644
--- a/src/main/java/org/ghost4j/util/StreamGobbler.java
+++ b/src/main/java/org/ghost4j/util/StreamGobbler.java
@@ -21,51 +21,51 @@
*/
public class StreamGobbler extends Thread {
- /**
- * Input stream to read.
- */
- InputStream inputStream;
- /**
- * Output stream to write.
- */
- OutputStream outputStream;
+ /**
+ * Input stream to read.
+ */
+ InputStream inputStream;
+ /**
+ * Output stream to write.
+ */
+ OutputStream outputStream;
- public StreamGobbler(InputStream inputStream, OutputStream outputStream) {
+ public StreamGobbler(InputStream inputStream, OutputStream outputStream) {
- this.inputStream = inputStream;
- this.outputStream = outputStream;
- }
+ this.inputStream = inputStream;
+ this.outputStream = outputStream;
+ }
- @Override
- public void run() {
+ @Override
+ public void run() {
- try {
+ try {
- PrintWriter printWriter = null;
- if (outputStream != null) {
- printWriter = new PrintWriter(outputStream);
- }
+ PrintWriter printWriter = null;
+ if (outputStream != null) {
+ printWriter = new PrintWriter(outputStream);
+ }
- InputStreamReader inputStreamReader = new InputStreamReader(
- inputStream);
- BufferedReader bufferedReader = new BufferedReader(
- inputStreamReader);
- String line = null;
- while ((line = bufferedReader.readLine()) != null) {
- if (printWriter != null) {
- printWriter.println(line);
- }
- }
+ InputStreamReader inputStreamReader = new InputStreamReader(
+ inputStream);
+ BufferedReader bufferedReader = new BufferedReader(
+ inputStreamReader);
+ String line = null;
+ while ((line = bufferedReader.readLine()) != null) {
+ if (printWriter != null) {
+ printWriter.println(line);
+ }
+ }
- if (printWriter != null) {
- printWriter.flush();
- }
+ if (printWriter != null) {
+ printWriter.flush();
+ }
- } catch (IOException e) {
+ } catch (IOException e) {
- // nothing
+ // nothing
- }
+ }
- }
+ }
}