去掉Apollo配置中心依赖
|
@ -0,0 +1,160 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.yudianbank</groupId>
|
||||
<artifactId>jodconverter-core</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- required for org.hyperic:sigar -->
|
||||
<id>jboss-public-repository-group</id>
|
||||
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>juh</artifactId>
|
||||
<version>3.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>ridl</artifactId>
|
||||
<version>3.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>unoil</artifactId>
|
||||
<version>3.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- for the command line tool -->
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.1</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hyperic</groupId>
|
||||
<artifactId>sigar</artifactId>
|
||||
<version>1.6.5.132</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20090211</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>6.0.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- 要将源码放上去,需要加入这个插件 -->
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<attach>true</attach>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.7.2</version>
|
||||
<configuration>
|
||||
<!-- don't run tests in parallel -->
|
||||
<perCoreThreadCount>false</perCoreThreadCount>
|
||||
<threadCount>1</threadCount>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>org.artofsolving.jodconverter.cli.Convert</mainClass>
|
||||
<addClasspath>true</addClasspath>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2-beta-5</version>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/dist.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
<!-- distribute目录 -->
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>repo</id>
|
||||
<name>User Project Releases</name>
|
||||
<url>http://192.168.1.204:8081/nexus/content/repositories/releases</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>repo</id>
|
||||
<name>User Project SNAPSHOTS</name>
|
||||
<url>http://192.168.1.204:8081/nexus/content/repositories/snapshots</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
</project>
|
|
@ -0,0 +1,37 @@
|
|||
<assembly>
|
||||
<id>dist</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>lib</outputDirectory>
|
||||
<excludes>
|
||||
<exclude>org.hyperic:sigar</exclude>
|
||||
</excludes>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<includes>
|
||||
<include>LICENSE.txt</include>
|
||||
<include>README.txt</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>target</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>${project.artifactId}-${project.version}-javadoc.jar</include>
|
||||
<include>${project.artifactId}-${project.version}-sources.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>src/main/resources</directory>
|
||||
<outputDirectory>/conf</outputDirectory>
|
||||
<includes>
|
||||
<include>document-formats.js</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
|
@ -0,0 +1,125 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter;
|
||||
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.SERVICE_DESKTOP;
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.cast;
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.toUnoProperties;
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.toUrl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import org.artofsolving.jodconverter.office.OfficeContext;
|
||||
import org.artofsolving.jodconverter.office.OfficeException;
|
||||
import org.artofsolving.jodconverter.office.OfficeTask;
|
||||
|
||||
import com.sun.star.frame.XComponentLoader;
|
||||
import com.sun.star.frame.XStorable;
|
||||
import com.sun.star.io.IOException;
|
||||
import com.sun.star.lang.IllegalArgumentException;
|
||||
import com.sun.star.lang.XComponent;
|
||||
import com.sun.star.task.ErrorCodeIOException;
|
||||
import com.sun.star.util.CloseVetoException;
|
||||
import com.sun.star.util.XCloseable;
|
||||
|
||||
public abstract class AbstractConversionTask implements OfficeTask {
|
||||
|
||||
private final File inputFile;
|
||||
private final File outputFile;
|
||||
|
||||
public AbstractConversionTask(File inputFile, File outputFile) {
|
||||
this.inputFile = inputFile;
|
||||
this.outputFile = outputFile;
|
||||
}
|
||||
|
||||
protected abstract Map<String,?> getLoadProperties(File inputFile);
|
||||
|
||||
protected abstract Map<String,?> getStoreProperties(File outputFile, XComponent document);
|
||||
|
||||
public void execute(OfficeContext context) throws OfficeException {
|
||||
XComponent document = null;
|
||||
try {
|
||||
document = loadDocument(context, inputFile);
|
||||
modifyDocument(document);
|
||||
storeDocument(document, outputFile);
|
||||
} catch (OfficeException officeException) {
|
||||
throw officeException;
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException("conversion failed", exception);
|
||||
} finally {
|
||||
if (document != null) {
|
||||
XCloseable closeable = cast(XCloseable.class, document);
|
||||
if (closeable != null) {
|
||||
try {
|
||||
closeable.close(true);
|
||||
} catch (CloseVetoException closeVetoException) {
|
||||
// whoever raised the veto should close the document
|
||||
}
|
||||
} else {
|
||||
document.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private XComponent loadDocument(OfficeContext context, File inputFile) throws OfficeException {
|
||||
if (!inputFile.exists()) {
|
||||
throw new OfficeException("input document not found");
|
||||
}
|
||||
XComponentLoader loader = cast(XComponentLoader.class, context.getService(SERVICE_DESKTOP));
|
||||
Map<String,?> loadProperties = getLoadProperties(inputFile);
|
||||
XComponent document = null;
|
||||
try {
|
||||
document = loader.loadComponentFromURL(toUrl(inputFile), "_blank", 0, toUnoProperties(loadProperties));
|
||||
} catch (IllegalArgumentException illegalArgumentException) {
|
||||
throw new OfficeException("could not load document: " + inputFile.getName(), illegalArgumentException);
|
||||
} catch (ErrorCodeIOException errorCodeIOException) {
|
||||
throw new OfficeException("could not load document: " + inputFile.getName() + "; errorCode: " + errorCodeIOException.ErrCode, errorCodeIOException);
|
||||
} catch (IOException ioException) {
|
||||
throw new OfficeException("could not load document: " + inputFile.getName(), ioException);
|
||||
}
|
||||
if (document == null) {
|
||||
throw new OfficeException("could not load document: " + inputFile.getName());
|
||||
}
|
||||
return document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to modify the document after it has been loaded and before it gets
|
||||
* saved in the new format.
|
||||
* <p>
|
||||
* Does nothing by default.
|
||||
*
|
||||
* @param document
|
||||
* @throws OfficeException
|
||||
*/
|
||||
protected void modifyDocument(XComponent document) throws OfficeException {
|
||||
// noop
|
||||
}
|
||||
|
||||
private void storeDocument(XComponent document, File outputFile) throws OfficeException {
|
||||
Map<String,?> storeProperties = getStoreProperties(outputFile, document);
|
||||
if (storeProperties == null) {
|
||||
throw new OfficeException("unsupported conversion");
|
||||
}
|
||||
try {
|
||||
cast(XStorable.class, document).storeToURL(toUrl(outputFile), toUnoProperties(storeProperties));
|
||||
} catch (ErrorCodeIOException errorCodeIOException) {
|
||||
throw new OfficeException("could not store document: " + outputFile.getName() + "; errorCode: " + errorCodeIOException.ErrCode, errorCodeIOException);
|
||||
} catch (IOException ioException) {
|
||||
throw new OfficeException("could not store document: " + outputFile.getName(), ioException);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.artofsolving.jodconverter.document.DefaultDocumentFormatRegistry;
|
||||
import org.artofsolving.jodconverter.document.DocumentFormat;
|
||||
import org.artofsolving.jodconverter.document.DocumentFormatRegistry;
|
||||
import org.artofsolving.jodconverter.office.OfficeException;
|
||||
import org.artofsolving.jodconverter.office.OfficeManager;
|
||||
|
||||
import com.sun.star.document.UpdateDocMode;
|
||||
|
||||
public class OfficeDocumentConverter {
|
||||
|
||||
private final OfficeManager officeManager;
|
||||
private final DocumentFormatRegistry formatRegistry;
|
||||
|
||||
private Map<String,?> defaultLoadProperties = createDefaultLoadProperties();
|
||||
|
||||
public OfficeDocumentConverter(OfficeManager officeManager) {
|
||||
this(officeManager, new DefaultDocumentFormatRegistry());
|
||||
}
|
||||
|
||||
public OfficeDocumentConverter(OfficeManager officeManager, DocumentFormatRegistry formatRegistry) {
|
||||
this.officeManager = officeManager;
|
||||
this.formatRegistry = formatRegistry;
|
||||
}
|
||||
|
||||
private Map<String,Object> createDefaultLoadProperties() {
|
||||
Map<String,Object> loadProperties = new HashMap<String,Object>();
|
||||
loadProperties.put("Hidden", true);
|
||||
loadProperties.put("ReadOnly", true);
|
||||
loadProperties.put("UpdateDocMode", UpdateDocMode.QUIET_UPDATE);
|
||||
return loadProperties;
|
||||
}
|
||||
|
||||
public void setDefaultLoadProperties(Map<String, ?> defaultLoadProperties) {
|
||||
this.defaultLoadProperties = defaultLoadProperties;
|
||||
}
|
||||
|
||||
public DocumentFormatRegistry getFormatRegistry() {
|
||||
return formatRegistry;
|
||||
}
|
||||
|
||||
public void convert(File inputFile, File outputFile) throws OfficeException {
|
||||
String outputExtension = FilenameUtils.getExtension(outputFile.getName());
|
||||
DocumentFormat outputFormat = formatRegistry.getFormatByExtension(outputExtension);
|
||||
convert(inputFile, outputFile, outputFormat);
|
||||
}
|
||||
|
||||
public void convert(File inputFile, File outputFile, DocumentFormat outputFormat) throws OfficeException {
|
||||
String inputExtension = FilenameUtils.getExtension(inputFile.getName());
|
||||
DocumentFormat inputFormat = formatRegistry.getFormatByExtension(inputExtension);
|
||||
StandardConversionTask conversionTask = new StandardConversionTask(inputFile, outputFile, outputFormat);
|
||||
conversionTask.setDefaultLoadProperties(defaultLoadProperties);
|
||||
conversionTask.setInputFormat(inputFormat);
|
||||
officeManager.execute(conversionTask);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter;
|
||||
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.*;
|
||||
|
||||
import org.artofsolving.jodconverter.document.DocumentFamily;
|
||||
import org.artofsolving.jodconverter.office.OfficeException;
|
||||
|
||||
|
||||
import com.sun.star.lang.XComponent;
|
||||
import com.sun.star.lang.XServiceInfo;
|
||||
|
||||
class OfficeDocumentUtils {
|
||||
|
||||
private OfficeDocumentUtils() {
|
||||
throw new AssertionError("utility class must not be instantiated");
|
||||
}
|
||||
|
||||
public static DocumentFamily getDocumentFamily(XComponent document) throws OfficeException {
|
||||
XServiceInfo serviceInfo = cast(XServiceInfo.class, document);
|
||||
if (serviceInfo.supportsService("com.sun.star.text.GenericTextDocument")) {
|
||||
// NOTE: a GenericTextDocument is either a TextDocument, a WebDocument, or a GlobalDocument
|
||||
// but this further distinction doesn't seem to matter for conversions
|
||||
return DocumentFamily.TEXT;
|
||||
} else if (serviceInfo.supportsService("com.sun.star.sheet.SpreadsheetDocument")) {
|
||||
return DocumentFamily.SPREADSHEET;
|
||||
} else if (serviceInfo.supportsService("com.sun.star.presentation.PresentationDocument")) {
|
||||
return DocumentFamily.PRESENTATION;
|
||||
} else if (serviceInfo.supportsService("com.sun.star.drawing.DrawingDocument")) {
|
||||
return DocumentFamily.DRAWING;
|
||||
} else {
|
||||
throw new OfficeException("document of unknown family: " + serviceInfo.getImplementationName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter;
|
||||
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.cast;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.artofsolving.jodconverter.document.DocumentFamily;
|
||||
import org.artofsolving.jodconverter.document.DocumentFormat;
|
||||
import org.artofsolving.jodconverter.office.OfficeException;
|
||||
|
||||
import com.sun.star.lang.XComponent;
|
||||
import com.sun.star.util.XRefreshable;
|
||||
|
||||
public class StandardConversionTask extends AbstractConversionTask {
|
||||
|
||||
private final DocumentFormat outputFormat;
|
||||
|
||||
private Map<String,?> defaultLoadProperties;
|
||||
private DocumentFormat inputFormat;
|
||||
|
||||
public StandardConversionTask(File inputFile, File outputFile, DocumentFormat outputFormat) {
|
||||
super(inputFile, outputFile);
|
||||
this.outputFormat = outputFormat;
|
||||
}
|
||||
|
||||
public void setDefaultLoadProperties(Map<String, ?> defaultLoadProperties) {
|
||||
this.defaultLoadProperties = defaultLoadProperties;
|
||||
}
|
||||
|
||||
public void setInputFormat(DocumentFormat inputFormat) {
|
||||
this.inputFormat = inputFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void modifyDocument(XComponent document) throws OfficeException {
|
||||
XRefreshable refreshable = cast(XRefreshable.class, document);
|
||||
if (refreshable != null) {
|
||||
refreshable.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String,?> getLoadProperties(File inputFile) {
|
||||
Map<String,Object> loadProperties = new HashMap<String,Object>();
|
||||
if (defaultLoadProperties != null) {
|
||||
loadProperties.putAll(defaultLoadProperties);
|
||||
}
|
||||
if (inputFormat != null && inputFormat.getLoadProperties() != null) {
|
||||
loadProperties.putAll(inputFormat.getLoadProperties());
|
||||
}
|
||||
return loadProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String,?> getStoreProperties(File outputFile, XComponent document) {
|
||||
DocumentFamily family = OfficeDocumentUtils.getDocumentFamily(document);
|
||||
return outputFormat.getStoreProperties(family);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.cli;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.cli.PosixParser;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||
import org.artofsolving.jodconverter.document.DefaultDocumentFormatRegistry;
|
||||
import org.artofsolving.jodconverter.document.DocumentFormatRegistry;
|
||||
import org.artofsolving.jodconverter.document.JsonDocumentFormatRegistry;
|
||||
import org.artofsolving.jodconverter.office.OfficeManager;
|
||||
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
|
||||
import org.json.JSONException;
|
||||
|
||||
/**
|
||||
* Command line interface executable.
|
||||
*/
|
||||
public class Convert {
|
||||
|
||||
public static final int STATUS_OK = 0;
|
||||
public static final int STATUS_MISSING_INPUT_FILE = 1;
|
||||
public static final int STATUS_INVALID_ARGUMENTS = 255;
|
||||
|
||||
private static final Option OPTION_OUTPUT_FORMAT = new Option("o", "output-format", true, "output format (e.g. pdf)");
|
||||
private static final Option OPTION_PORT = new Option("p", "port", true, "office socket port (optional; defaults to 2002)");
|
||||
private static final Option OPTION_REGISTRY = new Option("r", "registry", true, "document formats registry configuration file (optional)");
|
||||
private static final Option OPTION_TIMEOUT = new Option("t", "timeout", true, "maximum conversion time in seconds (optional; defaults to 120)");
|
||||
private static final Option OPTION_USER_PROFILE = new Option("u", "user-profile", true, "use settings from the given user installation dir (optional)");
|
||||
private static final Options OPTIONS = initOptions();
|
||||
|
||||
private static final int DEFAULT_OFFICE_PORT = 2002;
|
||||
|
||||
private static Options initOptions() {
|
||||
Options options = new Options();
|
||||
options.addOption(OPTION_OUTPUT_FORMAT);
|
||||
options.addOption(OPTION_PORT);
|
||||
options.addOption(OPTION_REGISTRY);
|
||||
options.addOption(OPTION_TIMEOUT);
|
||||
options.addOption(OPTION_USER_PROFILE);
|
||||
return options;
|
||||
}
|
||||
|
||||
public static void main(String[] arguments) throws ParseException, JSONException, IOException {
|
||||
CommandLineParser commandLineParser = new PosixParser();
|
||||
CommandLine commandLine = commandLineParser.parse(OPTIONS, arguments);
|
||||
|
||||
String outputFormat = null;
|
||||
if (commandLine.hasOption(OPTION_OUTPUT_FORMAT.getOpt())) {
|
||||
outputFormat = commandLine.getOptionValue(OPTION_OUTPUT_FORMAT.getOpt());
|
||||
}
|
||||
|
||||
int port = DEFAULT_OFFICE_PORT;
|
||||
if (commandLine.hasOption(OPTION_PORT.getOpt())) {
|
||||
port = Integer.parseInt(commandLine.getOptionValue(OPTION_PORT.getOpt()));
|
||||
}
|
||||
|
||||
String[] fileNames = commandLine.getArgs();
|
||||
if ((outputFormat == null && fileNames.length != 2) || fileNames.length < 1) {
|
||||
String syntax = "java -jar jodconverter-core.jar [options] input-file output-file\n"
|
||||
+ "or [options] -o output-format input-file [input-file...]";
|
||||
HelpFormatter helpFormatter = new HelpFormatter();
|
||||
helpFormatter.printHelp(syntax, OPTIONS);
|
||||
System.exit(STATUS_INVALID_ARGUMENTS);
|
||||
}
|
||||
|
||||
DocumentFormatRegistry registry;
|
||||
if (commandLine.hasOption(OPTION_REGISTRY.getOpt())) {
|
||||
File registryFile = new File(commandLine.getOptionValue(OPTION_REGISTRY.getOpt()));
|
||||
registry = new JsonDocumentFormatRegistry(FileUtils.readFileToString(registryFile));
|
||||
} else {
|
||||
registry = new DefaultDocumentFormatRegistry();
|
||||
}
|
||||
|
||||
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
|
||||
configuration.setPortNumber(port);
|
||||
if (commandLine.hasOption(OPTION_TIMEOUT.getOpt())) {
|
||||
int timeout = Integer.parseInt(commandLine.getOptionValue(OPTION_TIMEOUT.getOpt()));
|
||||
configuration.setTaskExecutionTimeout(timeout * 1000);
|
||||
}
|
||||
if (commandLine.hasOption(OPTION_USER_PROFILE.getOpt())) {
|
||||
String templateProfileDir = commandLine.getOptionValue(OPTION_USER_PROFILE.getOpt());
|
||||
configuration.setTemplateProfileDir(new File(templateProfileDir));
|
||||
}
|
||||
|
||||
OfficeManager officeManager = configuration.buildOfficeManager();
|
||||
officeManager.start();
|
||||
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, registry);
|
||||
try {
|
||||
if (outputFormat == null) {
|
||||
File inputFile = new File(fileNames[0]);
|
||||
File outputFile = new File(fileNames[1]);
|
||||
converter.convert(inputFile, outputFile);
|
||||
} else {
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
File inputFile = new File(fileNames[i]);
|
||||
String outputName = FilenameUtils.getBaseName(fileNames[i]) + "." + outputFormat;
|
||||
File outputFile = new File(FilenameUtils.getFullPath(fileNames[i]) + outputName);
|
||||
converter.convert(inputFile, outputFile);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
officeManager.stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.document;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class DefaultDocumentFormatRegistry extends SimpleDocumentFormatRegistry {
|
||||
|
||||
public DefaultDocumentFormatRegistry() {
|
||||
DocumentFormat pdf = new DocumentFormat("Portable Document Format", "pdf", "application/pdf");
|
||||
pdf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer_pdf_Export"));
|
||||
pdf.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc_pdf_Export"));
|
||||
pdf.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_pdf_Export"));
|
||||
pdf.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_pdf_Export"));
|
||||
addFormat(pdf);
|
||||
|
||||
DocumentFormat swf = new DocumentFormat("Macromedia Flash", "swf", "application/x-shockwave-flash");
|
||||
swf.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_flash_Export"));
|
||||
swf.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_flash_Export"));
|
||||
addFormat(swf);
|
||||
|
||||
// disabled because it's not always available
|
||||
//DocumentFormat xhtml = new DocumentFormat("XHTML", "xhtml", "application/xhtml+xml");
|
||||
//xhtml.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "XHTML Writer File"));
|
||||
//xhtml.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "XHTML Calc File"));
|
||||
//xhtml.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "XHTML Impress File"));
|
||||
//addFormat(xhtml);
|
||||
|
||||
DocumentFormat html = new DocumentFormat("HTML", "html", "text/html");
|
||||
// HTML is treated as Text when supplied as input, but as an output it is also
|
||||
// available for exporting Spreadsheet and Presentation formats
|
||||
html.setInputFamily(DocumentFamily.TEXT);
|
||||
html.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "HTML (StarWriter)"));
|
||||
html.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "HTML (StarCalc)"));
|
||||
html.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_html_Export"));
|
||||
addFormat(html);
|
||||
|
||||
DocumentFormat odt = new DocumentFormat("OpenDocument Text", "odt", "application/vnd.oasis.opendocument.text");
|
||||
odt.setInputFamily(DocumentFamily.TEXT);
|
||||
odt.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer8"));
|
||||
addFormat(odt);
|
||||
|
||||
DocumentFormat sxw = new DocumentFormat("OpenOffice.org 1.0 Text Document", "sxw", "application/vnd.sun.xml.writer");
|
||||
sxw.setInputFamily(DocumentFamily.TEXT);
|
||||
sxw.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "StarOffice XML (Writer)"));
|
||||
addFormat(sxw);
|
||||
|
||||
DocumentFormat doc = new DocumentFormat("Microsoft Word", "doc", "application/msword");
|
||||
doc.setInputFamily(DocumentFamily.TEXT);
|
||||
doc.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "MS Word 97"));
|
||||
addFormat(doc);
|
||||
|
||||
DocumentFormat docx = new DocumentFormat("Microsoft Word 2007 XML", "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
||||
docx.setInputFamily(DocumentFamily.TEXT);
|
||||
addFormat(docx);
|
||||
|
||||
DocumentFormat rtf = new DocumentFormat("Rich Text Format", "rtf", "text/rtf");
|
||||
rtf.setInputFamily(DocumentFamily.TEXT);
|
||||
rtf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "Rich Text Format"));
|
||||
addFormat(rtf);
|
||||
|
||||
DocumentFormat wpd = new DocumentFormat("WordPerfect", "wpd", "application/wordperfect");
|
||||
wpd.setInputFamily(DocumentFamily.TEXT);
|
||||
addFormat(wpd);
|
||||
|
||||
DocumentFormat txt = new DocumentFormat("Plain Text", "txt", "text/plain");
|
||||
txt.setInputFamily(DocumentFamily.TEXT);
|
||||
Map<String,Object> txtLoadAndStoreProperties = new LinkedHashMap<String,Object>();
|
||||
txtLoadAndStoreProperties.put("FilterName", "Text (encoded)");
|
||||
txtLoadAndStoreProperties.put("FilterOptions", "utf8");
|
||||
txt.setLoadProperties(txtLoadAndStoreProperties);
|
||||
txt.setStoreProperties(DocumentFamily.TEXT, txtLoadAndStoreProperties);
|
||||
addFormat(txt);
|
||||
|
||||
DocumentFormat wikitext = new DocumentFormat("MediaWiki wikitext", "wiki", "text/x-wiki");
|
||||
wikitext.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "MediaWiki"));
|
||||
//addFormat(wikitext);
|
||||
|
||||
DocumentFormat ods = new DocumentFormat("OpenDocument Spreadsheet", "ods", "application/vnd.oasis.opendocument.spreadsheet");
|
||||
ods.setInputFamily(DocumentFamily.SPREADSHEET);
|
||||
ods.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc8"));
|
||||
addFormat(ods);
|
||||
|
||||
DocumentFormat sxc = new DocumentFormat("OpenOffice.org 1.0 Spreadsheet", "sxc", "application/vnd.sun.xml.calc");
|
||||
sxc.setInputFamily(DocumentFamily.SPREADSHEET);
|
||||
sxc.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "StarOffice XML (Calc)"));
|
||||
addFormat(sxc);
|
||||
|
||||
DocumentFormat xls = new DocumentFormat("Microsoft Excel", "xls", "application/vnd.ms-excel");
|
||||
xls.setInputFamily(DocumentFamily.SPREADSHEET);
|
||||
xls.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "MS Excel 97"));
|
||||
addFormat(xls);
|
||||
|
||||
DocumentFormat xlsx = new DocumentFormat("Microsoft Excel 2007 XML", "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
xlsx.setInputFamily(DocumentFamily.SPREADSHEET);
|
||||
addFormat(xlsx);
|
||||
|
||||
DocumentFormat csv = new DocumentFormat("Comma Separated Values", "csv", "text/csv");
|
||||
csv.setInputFamily(DocumentFamily.SPREADSHEET);
|
||||
Map<String,Object> csvLoadAndStoreProperties = new LinkedHashMap<String,Object>();
|
||||
csvLoadAndStoreProperties.put("FilterName", "Text - txt - csv (StarCalc)");
|
||||
csvLoadAndStoreProperties.put("FilterOptions", "44,34,0"); // Field Separator: ','; Text Delimiter: '"'
|
||||
csv.setLoadProperties(csvLoadAndStoreProperties);
|
||||
csv.setStoreProperties(DocumentFamily.SPREADSHEET, csvLoadAndStoreProperties);
|
||||
addFormat(csv);
|
||||
|
||||
DocumentFormat tsv = new DocumentFormat("Tab Separated Values", "tsv", "text/tab-separated-values");
|
||||
tsv.setInputFamily(DocumentFamily.SPREADSHEET);
|
||||
Map<String,Object> tsvLoadAndStoreProperties = new LinkedHashMap<String,Object>();
|
||||
tsvLoadAndStoreProperties.put("FilterName", "Text - txt - csv (StarCalc)");
|
||||
tsvLoadAndStoreProperties.put("FilterOptions", "9,34,0"); // Field Separator: '\t'; Text Delimiter: '"'
|
||||
tsv.setLoadProperties(tsvLoadAndStoreProperties);
|
||||
tsv.setStoreProperties(DocumentFamily.SPREADSHEET, tsvLoadAndStoreProperties);
|
||||
addFormat(tsv);
|
||||
|
||||
DocumentFormat odp = new DocumentFormat("OpenDocument Presentation", "odp", "application/vnd.oasis.opendocument.presentation");
|
||||
odp.setInputFamily(DocumentFamily.PRESENTATION);
|
||||
odp.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress8"));
|
||||
addFormat(odp);
|
||||
|
||||
DocumentFormat sxi = new DocumentFormat("OpenOffice.org 1.0 Presentation", "sxi", "application/vnd.sun.xml.impress");
|
||||
sxi.setInputFamily(DocumentFamily.PRESENTATION);
|
||||
sxi.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "StarOffice XML (Impress)"));
|
||||
addFormat(sxi);
|
||||
|
||||
DocumentFormat ppt = new DocumentFormat("Microsoft PowerPoint", "ppt", "application/vnd.ms-powerpoint");
|
||||
ppt.setInputFamily(DocumentFamily.PRESENTATION);
|
||||
ppt.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "MS PowerPoint 97"));
|
||||
addFormat(ppt);
|
||||
|
||||
DocumentFormat pptx = new DocumentFormat("Microsoft PowerPoint 2007 XML", "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
|
||||
pptx.setInputFamily(DocumentFamily.PRESENTATION);
|
||||
addFormat(pptx);
|
||||
|
||||
DocumentFormat odg = new DocumentFormat("OpenDocument Drawing", "odg", "application/vnd.oasis.opendocument.graphics");
|
||||
odg.setInputFamily(DocumentFamily.DRAWING);
|
||||
odg.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw8"));
|
||||
addFormat(odg);
|
||||
|
||||
DocumentFormat svg = new DocumentFormat("Scalable Vector Graphics", "svg", "image/svg+xml");
|
||||
svg.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_svg_Export"));
|
||||
addFormat(svg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.document;
|
||||
|
||||
public enum DocumentFamily {
|
||||
|
||||
TEXT, SPREADSHEET, PRESENTATION, DRAWING
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.document;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class DocumentFormat {
|
||||
|
||||
private String name;
|
||||
private String extension;
|
||||
private String mediaType;
|
||||
private DocumentFamily inputFamily;
|
||||
private Map<String,?> loadProperties;
|
||||
private Map<DocumentFamily,Map<String,?>> storePropertiesByFamily;
|
||||
|
||||
public DocumentFormat() {
|
||||
// default
|
||||
}
|
||||
|
||||
public DocumentFormat(String name, String extension, String mediaType) {
|
||||
this.name = name;
|
||||
this.extension = extension;
|
||||
this.mediaType = mediaType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getExtension() {
|
||||
return extension;
|
||||
}
|
||||
|
||||
public void setExtension(String extension) {
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
public String getMediaType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
public void setMediaType(String mediaType) {
|
||||
this.mediaType = mediaType;
|
||||
}
|
||||
|
||||
public DocumentFamily getInputFamily() {
|
||||
return inputFamily;
|
||||
}
|
||||
|
||||
public void setInputFamily(DocumentFamily documentFamily) {
|
||||
this.inputFamily = documentFamily;
|
||||
}
|
||||
|
||||
public Map<String, ?> getLoadProperties() {
|
||||
return loadProperties;
|
||||
}
|
||||
|
||||
public void setLoadProperties(Map<String,?> loadProperties) {
|
||||
this.loadProperties = loadProperties;
|
||||
}
|
||||
|
||||
public Map<DocumentFamily, Map<String, ?>> getStorePropertiesByFamily() {
|
||||
return storePropertiesByFamily;
|
||||
}
|
||||
|
||||
public void setStorePropertiesByFamily(Map<DocumentFamily, Map<String,?>> storePropertiesByFamily) {
|
||||
this.storePropertiesByFamily = storePropertiesByFamily;
|
||||
}
|
||||
|
||||
public void setStoreProperties(DocumentFamily family, Map<String,?> storeProperties) {
|
||||
if (storePropertiesByFamily == null) {
|
||||
storePropertiesByFamily = new HashMap<DocumentFamily,Map<String,?>>();
|
||||
}
|
||||
storePropertiesByFamily.put(family, storeProperties);
|
||||
}
|
||||
|
||||
public Map<String,?> getStoreProperties(DocumentFamily family) {
|
||||
if (storePropertiesByFamily == null) {
|
||||
return null;
|
||||
}
|
||||
return storePropertiesByFamily.get(family);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.document;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface DocumentFormatRegistry {
|
||||
|
||||
public DocumentFormat getFormatByExtension(String extension);
|
||||
|
||||
public DocumentFormat getFormatByMediaType(String mediaType);
|
||||
|
||||
public Set<DocumentFormat> getOutputFormats(DocumentFamily family);
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.document;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class JsonDocumentFormatRegistry extends SimpleDocumentFormatRegistry {
|
||||
|
||||
public JsonDocumentFormatRegistry(InputStream input) throws JSONException, IOException {
|
||||
readJsonArray(IOUtils.toString(input));
|
||||
}
|
||||
|
||||
public JsonDocumentFormatRegistry(String source) throws JSONException {
|
||||
readJsonArray(source);
|
||||
}
|
||||
|
||||
private void readJsonArray(String source) throws JSONException {
|
||||
JSONArray array = new JSONArray(source);
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONObject jsonFormat = array.getJSONObject(i);
|
||||
DocumentFormat format = new DocumentFormat();
|
||||
format.setName(jsonFormat.getString("name"));
|
||||
format.setExtension(jsonFormat.getString("extension"));
|
||||
format.setMediaType(jsonFormat.getString("mediaType"));
|
||||
if (jsonFormat.has("inputFamily")) {
|
||||
format.setInputFamily(DocumentFamily.valueOf(jsonFormat.getString("inputFamily")));
|
||||
}
|
||||
if (jsonFormat.has("loadProperties")) {
|
||||
format.setLoadProperties(toJavaMap(jsonFormat.getJSONObject("loadProperties")));
|
||||
}
|
||||
if (jsonFormat.has("storePropertiesByFamily")) {
|
||||
JSONObject jsonStorePropertiesByFamily = jsonFormat.getJSONObject("storePropertiesByFamily");
|
||||
for (String key : JSONObject.getNames(jsonStorePropertiesByFamily)) {
|
||||
Map<String,?> storeProperties = toJavaMap(jsonStorePropertiesByFamily.getJSONObject(key));
|
||||
format.setStoreProperties(DocumentFamily.valueOf(key), storeProperties);
|
||||
}
|
||||
}
|
||||
addFormat(format);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String,?> toJavaMap(JSONObject jsonMap) throws JSONException {
|
||||
Map<String,Object> map = new HashMap<String,Object>();
|
||||
for (String key : JSONObject.getNames(jsonMap)) {
|
||||
Object value = jsonMap.get(key);
|
||||
if (value instanceof JSONObject) {
|
||||
map.put(key, toJavaMap((JSONObject) value));
|
||||
} else {
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.document;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SimpleDocumentFormatRegistry implements DocumentFormatRegistry {
|
||||
|
||||
private List<DocumentFormat> documentFormats = new ArrayList<DocumentFormat>();
|
||||
|
||||
public void addFormat(DocumentFormat documentFormat) {
|
||||
documentFormats.add(documentFormat);
|
||||
}
|
||||
|
||||
public DocumentFormat getFormatByExtension(String extension) {
|
||||
if (extension == null) {
|
||||
return null;
|
||||
}
|
||||
String lowerExtension = extension.toLowerCase();
|
||||
//TODO keep a documentByExtension map instead
|
||||
for (DocumentFormat format : documentFormats) {
|
||||
if (format.getExtension().equals(lowerExtension)) {
|
||||
return format;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public DocumentFormat getFormatByMediaType(String mediaType) {
|
||||
if (mediaType == null) {
|
||||
return null;
|
||||
}
|
||||
//TODO keep a documentByMediaType map instead
|
||||
for (DocumentFormat format : documentFormats) {
|
||||
if (format.getMediaType().equals(mediaType)) {
|
||||
return format;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<DocumentFormat> getOutputFormats(DocumentFamily family) {
|
||||
Set<DocumentFormat> formats = new HashSet<DocumentFormat>();
|
||||
for (DocumentFormat format : documentFormats) {
|
||||
if (format.getStoreProperties(family) != null) {
|
||||
formats.add(format);
|
||||
}
|
||||
}
|
||||
return formats;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.artofsolving.jodconverter.process.ProcessManager;
|
||||
import org.artofsolving.jodconverter.process.PureJavaProcessManager;
|
||||
import org.artofsolving.jodconverter.process.LinuxProcessManager;
|
||||
import org.artofsolving.jodconverter.process.SigarProcessManager;
|
||||
import org.artofsolving.jodconverter.util.PlatformUtils;
|
||||
|
||||
public class DefaultOfficeManagerConfiguration {
|
||||
|
||||
public static final long DEFAULT_RETRY_TIMEOUT = 120000L;
|
||||
|
||||
private File officeHome = OfficeUtils.getDefaultOfficeHome();
|
||||
private OfficeConnectionProtocol connectionProtocol = OfficeConnectionProtocol.SOCKET;
|
||||
private int[] portNumbers = new int[] { 2002 };
|
||||
private String[] pipeNames = new String[] { "office" };
|
||||
private String[] runAsArgs = null;
|
||||
private File templateProfileDir = null;
|
||||
private File workDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
private long taskQueueTimeout = 30000L; // 30 seconds
|
||||
private long taskExecutionTimeout = 120000L; // 2 minutes
|
||||
private int maxTasksPerProcess = 200;
|
||||
private long retryTimeout = DEFAULT_RETRY_TIMEOUT;
|
||||
|
||||
private ProcessManager processManager = null; // lazily initialised
|
||||
|
||||
public DefaultOfficeManagerConfiguration setOfficeHome(String officeHome) throws NullPointerException, IllegalArgumentException {
|
||||
checkArgumentNotNull("officeHome", officeHome);
|
||||
return setOfficeHome(new File(officeHome));
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setOfficeHome(File officeHome) throws NullPointerException, IllegalArgumentException {
|
||||
checkArgumentNotNull("officeHome", officeHome);
|
||||
checkArgument("officeHome", officeHome.isDirectory(), "must exist and be a directory");
|
||||
this.officeHome = officeHome;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setConnectionProtocol(OfficeConnectionProtocol connectionProtocol) throws NullPointerException {
|
||||
checkArgumentNotNull("connectionProtocol", connectionProtocol);
|
||||
this.connectionProtocol = connectionProtocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setPortNumber(int portNumber) {
|
||||
this.portNumbers = new int[] { portNumber };
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setPortNumbers(int... portNumbers) throws NullPointerException, IllegalArgumentException {
|
||||
checkArgumentNotNull("portNumbers", portNumbers);
|
||||
checkArgument("portNumbers", portNumbers.length > 0, "must not be empty");
|
||||
this.portNumbers = portNumbers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setPipeName(String pipeName) throws NullPointerException {
|
||||
checkArgumentNotNull("pipeName", pipeName);
|
||||
this.pipeNames = new String[] { pipeName };
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setPipeNames(String... pipeNames) throws NullPointerException, IllegalArgumentException {
|
||||
checkArgumentNotNull("pipeNames", pipeNames);
|
||||
checkArgument("pipeNames", pipeNames.length > 0, "must not be empty");
|
||||
this.pipeNames = pipeNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setRunAsArgs(String... runAsArgs) {
|
||||
this.runAsArgs = runAsArgs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setTemplateProfileDir(File templateProfileDir) throws IllegalArgumentException {
|
||||
if (templateProfileDir != null) {
|
||||
checkArgument("templateProfileDir", templateProfileDir.isDirectory(), "must exist and be a directory");
|
||||
}
|
||||
this.templateProfileDir = templateProfileDir;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory where temporary office profiles will be created.
|
||||
* <p>
|
||||
* Defaults to the system temporary directory as specified by the <code>java.io.tmpdir</code> system property.
|
||||
*
|
||||
* @param workDir
|
||||
* @return
|
||||
*/
|
||||
public DefaultOfficeManagerConfiguration setWorkDir(File workDir) {
|
||||
checkArgumentNotNull("workDir", workDir);
|
||||
this.workDir = workDir;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setTaskQueueTimeout(long taskQueueTimeout) {
|
||||
this.taskQueueTimeout = taskQueueTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setTaskExecutionTimeout(long taskExecutionTimeout) {
|
||||
this.taskExecutionTimeout = taskExecutionTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultOfficeManagerConfiguration setMaxTasksPerProcess(int maxTasksPerProcess) {
|
||||
this.maxTasksPerProcess = maxTasksPerProcess;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a specific {@link ProcessManager} implementation
|
||||
* <p>
|
||||
* The default is to use {@link SigarProcessManager} if sigar.jar is
|
||||
* available in the classpath, otherwise {@link LinuxProcessManager}
|
||||
* on Linux and {@link PureJavaProcessManager} on other platforms.
|
||||
*
|
||||
* @param processManager
|
||||
* @return
|
||||
* @throws NullPointerException
|
||||
*/
|
||||
public DefaultOfficeManagerConfiguration setProcessManager(ProcessManager processManager) throws NullPointerException {
|
||||
checkArgumentNotNull("processManager", processManager);
|
||||
this.processManager = processManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry timeout set in milliseconds. Used for retrying office process calls.
|
||||
* If not set, it defaults to 2 minutes
|
||||
*
|
||||
* @param retryTimeout in milliseconds
|
||||
* @return
|
||||
*/
|
||||
public DefaultOfficeManagerConfiguration setRetryTimeout(long retryTimeout) {
|
||||
this.retryTimeout = retryTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OfficeManager buildOfficeManager() throws IllegalStateException {
|
||||
if (officeHome == null) {
|
||||
throw new IllegalStateException("officeHome not set and could not be auto-detected");
|
||||
} else if (!officeHome.isDirectory()) {
|
||||
throw new IllegalStateException("officeHome doesn't exist or is not a directory: " + officeHome);
|
||||
} else if (!OfficeUtils.getOfficeExecutable(officeHome).isFile()) {
|
||||
throw new IllegalStateException("invalid officeHome: it doesn't contain soffice.bin: " + officeHome);
|
||||
}
|
||||
if (templateProfileDir != null && !isValidProfileDir(templateProfileDir)) {
|
||||
throw new IllegalStateException("templateProfileDir doesn't appear to contain a user profile: " + templateProfileDir);
|
||||
}
|
||||
if (!workDir.isDirectory()) {
|
||||
throw new IllegalStateException("workDir doesn't exist or is not a directory: " + workDir);
|
||||
}
|
||||
|
||||
if (processManager == null) {
|
||||
processManager = findBestProcessManager();
|
||||
}
|
||||
|
||||
int numInstances = connectionProtocol == OfficeConnectionProtocol.PIPE ? pipeNames.length : portNumbers.length;
|
||||
UnoUrl[] unoUrls = new UnoUrl[numInstances];
|
||||
for (int i = 0; i < numInstances; i++) {
|
||||
unoUrls[i] = (connectionProtocol == OfficeConnectionProtocol.PIPE) ? UnoUrl.pipe(pipeNames[i]) : UnoUrl.socket(portNumbers[i]);
|
||||
}
|
||||
return new ProcessPoolOfficeManager(officeHome, unoUrls, runAsArgs, templateProfileDir, workDir, retryTimeout, taskQueueTimeout, taskExecutionTimeout, maxTasksPerProcess, processManager);
|
||||
}
|
||||
|
||||
private ProcessManager findBestProcessManager() {
|
||||
if (isSigarAvailable()) {
|
||||
return new SigarProcessManager();
|
||||
} else if (PlatformUtils.isLinux()) {
|
||||
LinuxProcessManager processManager = new LinuxProcessManager();
|
||||
if (runAsArgs != null) {
|
||||
processManager.setRunAsArgs(runAsArgs);
|
||||
}
|
||||
return processManager;
|
||||
} else {
|
||||
// NOTE: UnixProcessManager can't be trusted to work on Solaris
|
||||
// because of the 80-char limit on ps output there
|
||||
return new PureJavaProcessManager();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSigarAvailable() {
|
||||
try {
|
||||
Class.forName("org.hyperic.sigar.Sigar", false, getClass().getClassLoader());
|
||||
return true;
|
||||
} catch (ClassNotFoundException classNotFoundException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkArgumentNotNull(String argName, Object argValue) throws NullPointerException {
|
||||
if (argValue == null) {
|
||||
throw new NullPointerException(argName + " must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkArgument(String argName, boolean condition, String message) throws IllegalArgumentException {
|
||||
if (!condition) {
|
||||
throw new IllegalArgumentException(argName + " " + message);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValidProfileDir(File profileDir) {
|
||||
return new File(profileDir, "user").isDirectory();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.net.ConnectException;
|
||||
|
||||
/**
|
||||
* {@link OfficeManager} implementation that connects to an external Office process.
|
||||
* <p>
|
||||
* The external Office process needs to be started manually, e.g. from the command line with
|
||||
*
|
||||
* <pre>
|
||||
* soffice -accept="socket,host=127.0.0.1,port=2002;urp;"
|
||||
* </pre>
|
||||
* <p>
|
||||
* Since this implementation does not manage the Office process, it does not support auto-restarting the process if it exits unexpectedly.
|
||||
* <p>
|
||||
* It will however auto-reconnect to the external process if the latter is manually restarted.
|
||||
* <p>
|
||||
* This {@link OfficeManager} implementation basically provides the same behaviour as JODConverter 2.x, including using <em>synchronized</em> blocks for serialising office
|
||||
* operations.
|
||||
*/
|
||||
class ExternalOfficeManager implements OfficeManager {
|
||||
|
||||
private final OfficeConnection connection;
|
||||
private final boolean connectOnStart;
|
||||
|
||||
/**
|
||||
* @param unoUrl
|
||||
* @param connectOnStart
|
||||
* should a connection be attempted on {@link #start()}? Default is <em>true</em>. If <em>false</em>, a connection will only be attempted the first time an
|
||||
* {@link OfficeTask} is executed.
|
||||
*/
|
||||
public ExternalOfficeManager(UnoUrl unoUrl, boolean connectOnStart) {
|
||||
connection = new OfficeConnection(unoUrl);
|
||||
this.connectOnStart = connectOnStart;
|
||||
}
|
||||
|
||||
public void start() throws OfficeException {
|
||||
if (connectOnStart) {
|
||||
synchronized (connection) {
|
||||
connect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
synchronized (connection) {
|
||||
if (connection.isConnected()) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void execute(OfficeTask task) throws OfficeException {
|
||||
synchronized (connection) {
|
||||
if (!connection.isConnected()) {
|
||||
connect();
|
||||
}
|
||||
task.execute(connection);
|
||||
}
|
||||
}
|
||||
|
||||
private void connect() {
|
||||
try {
|
||||
connection.connect();
|
||||
} catch (ConnectException connectException) {
|
||||
throw new OfficeException("could not connect to external office process", connectException);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return connection.isConnected();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
public class ExternalOfficeManagerConfiguration {
|
||||
|
||||
private OfficeConnectionProtocol connectionProtocol = OfficeConnectionProtocol.SOCKET;
|
||||
private int portNumber = 2002;
|
||||
private String pipeName = "office";
|
||||
private boolean connectOnStart = true;
|
||||
|
||||
public ExternalOfficeManagerConfiguration setConnectionProtocol(OfficeConnectionProtocol connectionProtocol) {
|
||||
this.connectionProtocol = connectionProtocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ExternalOfficeManagerConfiguration setPortNumber(int portNumber) {
|
||||
this.portNumber = portNumber;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ExternalOfficeManagerConfiguration setPipeName(String pipeName) {
|
||||
this.pipeName = pipeName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ExternalOfficeManagerConfiguration setConnectOnStart(boolean connectOnStart) {
|
||||
this.connectOnStart = connectOnStart;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OfficeManager buildOfficeManager() {
|
||||
UnoUrl unoUrl = connectionProtocol == OfficeConnectionProtocol.SOCKET ? UnoUrl.socket(portNumber) : UnoUrl.pipe(pipeName);
|
||||
return new ExternalOfficeManager(unoUrl, connectOnStart);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.net.ConnectException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sun.star.frame.XDesktop;
|
||||
import com.sun.star.lang.DisposedException;
|
||||
|
||||
class ManagedOfficeProcess {
|
||||
|
||||
private static final Integer EXIT_CODE_NEW_INSTALLATION = Integer.valueOf(81);
|
||||
|
||||
private final ManagedOfficeProcessSettings settings;
|
||||
|
||||
private final OfficeProcess process;
|
||||
private final OfficeConnection connection;
|
||||
|
||||
private ExecutorService executor = Executors.newSingleThreadExecutor(new NamedThreadFactory("OfficeProcessThread"));
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getName());
|
||||
|
||||
public ManagedOfficeProcess(ManagedOfficeProcessSettings settings) throws OfficeException {
|
||||
this.settings = settings;
|
||||
process = new OfficeProcess(settings.getOfficeHome(), settings.getUnoUrl(), settings.getRunAsArgs(), settings.getTemplateProfileDir(), settings.getWorkDir(), settings
|
||||
.getProcessManager());
|
||||
connection = new OfficeConnection(settings.getUnoUrl());
|
||||
}
|
||||
|
||||
public OfficeConnection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public void startAndWait() throws OfficeException {
|
||||
Future<?> future = executor.submit(new Runnable() {
|
||||
public void run() {
|
||||
doStartProcessAndConnect();
|
||||
}
|
||||
});
|
||||
try {
|
||||
future.get();
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException("failed to start and connect", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopAndWait() throws OfficeException {
|
||||
Future<?> future = executor.submit(new Runnable() {
|
||||
public void run() {
|
||||
doStopProcess();
|
||||
}
|
||||
});
|
||||
try {
|
||||
future.get();
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException("failed to start and connect", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void restartAndWait() {
|
||||
Future<?> future = executor.submit(new Runnable() {
|
||||
public void run() {
|
||||
doStopProcess();
|
||||
doStartProcessAndConnect();
|
||||
}
|
||||
});
|
||||
try {
|
||||
future.get();
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException("failed to restart", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void restartDueToTaskTimeout() {
|
||||
executor.execute(new Runnable() {
|
||||
public void run() {
|
||||
doTerminateProcess();
|
||||
// will cause unexpected disconnection and subsequent restart
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void restartDueToLostConnection() {
|
||||
executor.execute(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
doEnsureProcessExited();
|
||||
doStartProcessAndConnect();
|
||||
} catch (OfficeException officeException) {
|
||||
logger.log(Level.SEVERE, "could not restart process", officeException);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doStartProcessAndConnect() throws OfficeException {
|
||||
try {
|
||||
process.start();
|
||||
new Retryable() {
|
||||
protected void attempt() throws TemporaryException, Exception {
|
||||
try {
|
||||
connection.connect();
|
||||
} catch (ConnectException connectException) {
|
||||
Integer exitCode = process.getExitCode();
|
||||
if (exitCode == null) {
|
||||
// process is running; retry later
|
||||
throw new TemporaryException(connectException);
|
||||
} else if (exitCode.equals(EXIT_CODE_NEW_INSTALLATION)) {
|
||||
// restart and retry later
|
||||
// see http://code.google.com/p/jodconverter/issues/detail?id=84
|
||||
logger.log(Level.WARNING, "office process died with exit code 81; restarting it");
|
||||
process.start(true);
|
||||
throw new TemporaryException(connectException);
|
||||
} else {
|
||||
throw new OfficeException("office process died with exit code " + exitCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute(settings.getRetryInterval(), settings.getRetryTimeout());
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException("could not establish connection", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private void doStopProcess() {
|
||||
try {
|
||||
XDesktop desktop = OfficeUtils.cast(XDesktop.class, connection.getService(OfficeUtils.SERVICE_DESKTOP));
|
||||
desktop.terminate();
|
||||
} catch (DisposedException disposedException) {
|
||||
// expected
|
||||
} catch (Exception exception) {
|
||||
// in case we can't get hold of the desktop
|
||||
doTerminateProcess();
|
||||
}
|
||||
doEnsureProcessExited();
|
||||
}
|
||||
|
||||
private void doEnsureProcessExited() throws OfficeException {
|
||||
try {
|
||||
int exitCode = process.getExitCode(settings.getRetryInterval(), settings.getRetryTimeout());
|
||||
logger.info("process exited with code " + exitCode);
|
||||
} catch (RetryTimeoutException retryTimeoutException) {
|
||||
doTerminateProcess();
|
||||
}
|
||||
process.deleteProfileDir();
|
||||
}
|
||||
|
||||
private void doTerminateProcess() throws OfficeException {
|
||||
try {
|
||||
int exitCode = process.forciblyTerminate(settings.getRetryInterval(), settings.getRetryTimeout());
|
||||
logger.info("process forcibly terminated with code " + exitCode);
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException("could not terminate process", exception);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isConnected() {
|
||||
return connection.isConnected();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.artofsolving.jodconverter.process.ProcessManager;
|
||||
import org.artofsolving.jodconverter.process.PureJavaProcessManager;
|
||||
|
||||
class ManagedOfficeProcessSettings {
|
||||
|
||||
public static final long DEFAULT_RETRY_INTERVAL = 250L;
|
||||
|
||||
private final UnoUrl unoUrl;
|
||||
private File officeHome = OfficeUtils.getDefaultOfficeHome();
|
||||
private String[] runAsArgs;
|
||||
private File templateProfileDir;
|
||||
private File workDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
private ProcessManager processManager = new PureJavaProcessManager();
|
||||
private long retryTimeout = DefaultOfficeManagerConfiguration.DEFAULT_RETRY_TIMEOUT;
|
||||
private long retryInterval = DEFAULT_RETRY_INTERVAL;
|
||||
|
||||
public ManagedOfficeProcessSettings(UnoUrl unoUrl) {
|
||||
this.unoUrl = unoUrl;
|
||||
}
|
||||
|
||||
public UnoUrl getUnoUrl() {
|
||||
return unoUrl;
|
||||
}
|
||||
|
||||
public File getOfficeHome() {
|
||||
return officeHome;
|
||||
}
|
||||
|
||||
public void setOfficeHome(File officeHome) {
|
||||
this.officeHome = officeHome;
|
||||
}
|
||||
|
||||
public String[] getRunAsArgs() {
|
||||
return runAsArgs;
|
||||
}
|
||||
|
||||
public void setRunAsArgs(String[] runAsArgs) {
|
||||
this.runAsArgs = runAsArgs;
|
||||
}
|
||||
|
||||
public File getTemplateProfileDir() {
|
||||
return templateProfileDir;
|
||||
}
|
||||
|
||||
public void setTemplateProfileDir(File templateProfileDir) {
|
||||
this.templateProfileDir = templateProfileDir;
|
||||
}
|
||||
|
||||
public File getWorkDir() {
|
||||
return workDir;
|
||||
}
|
||||
|
||||
public void setWorkDir(File workDir) {
|
||||
this.workDir = workDir;
|
||||
}
|
||||
|
||||
public ProcessManager getProcessManager() {
|
||||
return processManager;
|
||||
}
|
||||
|
||||
public void setProcessManager(ProcessManager processManager) {
|
||||
this.processManager = processManager;
|
||||
}
|
||||
|
||||
public long getRetryTimeout() {
|
||||
return retryTimeout;
|
||||
}
|
||||
|
||||
public void setRetryTimeout(long retryTimeout) {
|
||||
this.retryTimeout = retryTimeout;
|
||||
}
|
||||
|
||||
public long getRetryInterval() {
|
||||
return retryInterval;
|
||||
}
|
||||
|
||||
public void setRetryInterval(long retryInterval) {
|
||||
this.retryInterval = retryInterval;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* A {@link ThreadFactory} that allows for custom thread names
|
||||
*/
|
||||
class NamedThreadFactory implements ThreadFactory {
|
||||
|
||||
private static final AtomicInteger threadIndex = new AtomicInteger(0);
|
||||
|
||||
private final String baseName;
|
||||
private final boolean daemon;
|
||||
|
||||
public NamedThreadFactory(String baseName) {
|
||||
this(baseName, true);
|
||||
}
|
||||
|
||||
public NamedThreadFactory(String baseName, boolean daemon) {
|
||||
this.baseName = baseName;
|
||||
this.daemon = daemon;
|
||||
}
|
||||
|
||||
public Thread newThread(Runnable runnable) {
|
||||
Thread thread = new Thread(runnable, baseName + "-" + threadIndex.getAndIncrement());
|
||||
thread.setDaemon(daemon);
|
||||
return thread;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.net.ConnectException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sun.star.beans.XPropertySet;
|
||||
import com.sun.star.bridge.XBridge;
|
||||
import com.sun.star.bridge.XBridgeFactory;
|
||||
import com.sun.star.comp.helper.Bootstrap;
|
||||
import com.sun.star.connection.NoConnectException;
|
||||
import com.sun.star.connection.XConnection;
|
||||
import com.sun.star.connection.XConnector;
|
||||
import com.sun.star.lang.EventObject;
|
||||
import com.sun.star.lang.XComponent;
|
||||
import com.sun.star.lang.XEventListener;
|
||||
import com.sun.star.lang.XMultiComponentFactory;
|
||||
import com.sun.star.uno.XComponentContext;
|
||||
|
||||
class OfficeConnection implements OfficeContext {
|
||||
|
||||
private static AtomicInteger bridgeIndex = new AtomicInteger();
|
||||
|
||||
private final UnoUrl unoUrl;
|
||||
|
||||
private XComponent bridgeComponent;
|
||||
private XMultiComponentFactory serviceManager;
|
||||
private XComponentContext componentContext;
|
||||
|
||||
private final List<OfficeConnectionEventListener> connectionEventListeners = new ArrayList<OfficeConnectionEventListener>();
|
||||
|
||||
private volatile boolean connected = false;
|
||||
|
||||
private XEventListener bridgeListener = new XEventListener() {
|
||||
public void disposing(EventObject event) {
|
||||
if (connected) {
|
||||
connected = false;
|
||||
logger.info(String.format("disconnected: '%s'", unoUrl));
|
||||
OfficeConnectionEvent connectionEvent = new OfficeConnectionEvent(OfficeConnection.this);
|
||||
for (OfficeConnectionEventListener listener : connectionEventListeners) {
|
||||
listener.disconnected(connectionEvent);
|
||||
}
|
||||
}
|
||||
// else we tried to connect to a server that doesn't speak URP
|
||||
}
|
||||
};
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getName());
|
||||
|
||||
public OfficeConnection(UnoUrl unoUrl) {
|
||||
this.unoUrl = unoUrl;
|
||||
}
|
||||
|
||||
public void addConnectionEventListener(OfficeConnectionEventListener connectionEventListener) {
|
||||
connectionEventListeners.add(connectionEventListener);
|
||||
}
|
||||
|
||||
public void connect() throws ConnectException {
|
||||
logger.fine(String.format("connecting with connectString '%s'", unoUrl));
|
||||
try {
|
||||
XComponentContext localContext = Bootstrap.createInitialComponentContext(null);
|
||||
XMultiComponentFactory localServiceManager = localContext.getServiceManager();
|
||||
XConnector connector = OfficeUtils.cast(XConnector.class, localServiceManager.createInstanceWithContext("com.sun.star.connection.Connector", localContext));
|
||||
XConnection connection = connector.connect(unoUrl.getConnectString());
|
||||
XBridgeFactory bridgeFactory = OfficeUtils.cast(XBridgeFactory.class, localServiceManager.createInstanceWithContext("com.sun.star.bridge.BridgeFactory", localContext));
|
||||
String bridgeName = "jodconverter_" + bridgeIndex.getAndIncrement();
|
||||
XBridge bridge = bridgeFactory.createBridge(bridgeName, "urp", connection, null);
|
||||
bridgeComponent = OfficeUtils.cast(XComponent.class, bridge);
|
||||
bridgeComponent.addEventListener(bridgeListener);
|
||||
serviceManager = OfficeUtils.cast(XMultiComponentFactory.class, bridge.getInstance("StarOffice.ServiceManager"));
|
||||
XPropertySet properties = OfficeUtils.cast(XPropertySet.class, serviceManager);
|
||||
componentContext = OfficeUtils.cast(XComponentContext.class, properties.getPropertyValue("DefaultContext"));
|
||||
connected = true;
|
||||
logger.info(String.format("connected: '%s'", unoUrl));
|
||||
OfficeConnectionEvent connectionEvent = new OfficeConnectionEvent(this);
|
||||
for (OfficeConnectionEventListener listener : connectionEventListeners) {
|
||||
listener.connected(connectionEvent);
|
||||
}
|
||||
} catch (NoConnectException connectException) {
|
||||
throw new ConnectException(String.format("connection failed: '%s'; %s", unoUrl, connectException.getMessage()));
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException("connection failed: "+ unoUrl, exception);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
public synchronized void disconnect() {
|
||||
logger.fine(String.format("disconnecting: '%s'", unoUrl));
|
||||
bridgeComponent.dispose();
|
||||
}
|
||||
|
||||
public Object getService(String serviceName) {
|
||||
try {
|
||||
return serviceManager.createInstanceWithContext(serviceName, componentContext);
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException(String.format("failed to obtain service '%s'", serviceName), exception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
class OfficeConnectionEvent extends EventObject {
|
||||
|
||||
private static final long serialVersionUID = 2060652797570876077L;
|
||||
|
||||
public OfficeConnectionEvent(OfficeConnection source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
interface OfficeConnectionEventListener extends EventListener {
|
||||
|
||||
void connected(OfficeConnectionEvent event);
|
||||
|
||||
void disconnected(OfficeConnectionEvent event);
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
public enum OfficeConnectionProtocol { PIPE, SOCKET }
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
public interface OfficeContext {
|
||||
|
||||
Object getService(String serviceName);
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
public class OfficeException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public OfficeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public OfficeException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
/**
|
||||
* An OfficeManager knows how to execute {@link OfficeTask}s.
|
||||
* <p>
|
||||
* An OfficeManager implementation will typically manage one or more
|
||||
* {@link OfficeConnection}s.
|
||||
*/
|
||||
public interface OfficeManager {
|
||||
|
||||
void execute(OfficeTask task) throws OfficeException;
|
||||
|
||||
void start() throws OfficeException;
|
||||
|
||||
void stop() throws OfficeException;
|
||||
|
||||
boolean isRunning();
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import static org.artofsolving.jodconverter.process.ProcessManager.PID_NOT_FOUND;
|
||||
import static org.artofsolving.jodconverter.process.ProcessManager.PID_UNKNOWN;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.artofsolving.jodconverter.process.ProcessManager;
|
||||
import org.artofsolving.jodconverter.process.ProcessQuery;
|
||||
import org.artofsolving.jodconverter.util.PlatformUtils;
|
||||
|
||||
class OfficeProcess {
|
||||
|
||||
private final File officeHome;
|
||||
private final UnoUrl unoUrl;
|
||||
private final String[] runAsArgs;
|
||||
private final File templateProfileDir;
|
||||
private final File instanceProfileDir;
|
||||
private final ProcessManager processManager;
|
||||
|
||||
private Process process;
|
||||
private long pid = PID_UNKNOWN;
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getName());
|
||||
|
||||
public OfficeProcess(File officeHome, UnoUrl unoUrl, String[] runAsArgs, File templateProfileDir, File workDir, ProcessManager processManager) {
|
||||
this.officeHome = officeHome;
|
||||
this.unoUrl = unoUrl;
|
||||
this.runAsArgs = runAsArgs;
|
||||
this.templateProfileDir = templateProfileDir;
|
||||
this.instanceProfileDir = getInstanceProfileDir(workDir, unoUrl);
|
||||
this.processManager = processManager;
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
start(false);
|
||||
}
|
||||
|
||||
public void start(boolean restart) throws IOException {
|
||||
ProcessQuery processQuery = new ProcessQuery("soffice.bin", unoUrl.getAcceptString());
|
||||
long existingPid = processManager.findPid(processQuery);
|
||||
if (!(existingPid == PID_NOT_FOUND || existingPid == PID_UNKNOWN)) {
|
||||
throw new IllegalStateException(String.format("a process with acceptString '%s' is already running; pid %d",
|
||||
unoUrl.getAcceptString(), existingPid));
|
||||
}
|
||||
if (!restart) {
|
||||
prepareInstanceProfileDir();
|
||||
}
|
||||
List<String> command = new ArrayList<String>();
|
||||
File executable = OfficeUtils.getOfficeExecutable(officeHome);
|
||||
if (runAsArgs != null) {
|
||||
command.addAll(Arrays.asList(runAsArgs));
|
||||
}
|
||||
command.add(executable.getAbsolutePath());
|
||||
command.add("-accept=" + unoUrl.getAcceptString() + ";urp;");
|
||||
command.add("-env:UserInstallation=" + OfficeUtils.toUrl(instanceProfileDir));
|
||||
command.add("-headless");
|
||||
command.add("-nocrashreport");
|
||||
command.add("-nodefault");
|
||||
command.add("-nofirststartwizard");
|
||||
command.add("-nolockcheck");
|
||||
command.add("-nologo");
|
||||
command.add("-norestore");
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||
if (PlatformUtils.isWindows()) {
|
||||
addBasisAndUrePaths(processBuilder);
|
||||
}
|
||||
logger.info(String.format("starting process with acceptString '%s' and profileDir '%s'", unoUrl, instanceProfileDir));
|
||||
process = processBuilder.start();
|
||||
pid = processManager.findPid(processQuery);
|
||||
if (pid == PID_NOT_FOUND) {
|
||||
throw new IllegalStateException(String.format("process with acceptString '%s' started but its pid could not be found",
|
||||
unoUrl.getAcceptString()));
|
||||
}
|
||||
logger.info("started process" + (pid != PID_UNKNOWN ? "; pid = " + pid : ""));
|
||||
}
|
||||
|
||||
private File getInstanceProfileDir(File workDir, UnoUrl unoUrl) {
|
||||
String dirName = ".jodconverter_" + unoUrl.getAcceptString().replace(',', '_').replace('=', '-');
|
||||
return new File(workDir, dirName);
|
||||
}
|
||||
|
||||
private void prepareInstanceProfileDir() throws OfficeException {
|
||||
if (instanceProfileDir.exists()) {
|
||||
logger.warning(String.format("profile dir '%s' already exists; deleting", instanceProfileDir));
|
||||
deleteProfileDir();
|
||||
}
|
||||
if (templateProfileDir != null) {
|
||||
try {
|
||||
FileUtils.copyDirectory(templateProfileDir, instanceProfileDir);
|
||||
} catch (IOException ioException) {
|
||||
throw new OfficeException("failed to create profileDir", ioException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteProfileDir() {
|
||||
if (instanceProfileDir != null) {
|
||||
try {
|
||||
FileUtils.deleteDirectory(instanceProfileDir);
|
||||
} catch (IOException ioException) {
|
||||
File oldProfileDir = new File(instanceProfileDir.getParentFile(), instanceProfileDir.getName() + ".old." + System.currentTimeMillis());
|
||||
if (instanceProfileDir.renameTo(oldProfileDir)) {
|
||||
logger.warning("could not delete profileDir: " + ioException.getMessage() + "; renamed it to " + oldProfileDir);
|
||||
} else {
|
||||
logger.severe("could not delete profileDir: " + ioException.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addBasisAndUrePaths(ProcessBuilder processBuilder) throws IOException {
|
||||
// see http://wiki.services.openoffice.org/wiki/ODF_Toolkit/Efforts/Three-Layer_OOo
|
||||
File basisLink = new File(officeHome, "basis-link");
|
||||
if (!basisLink.isFile()) {
|
||||
logger.fine("no %OFFICE_HOME%/basis-link found; assuming it's OOo 2.x and we don't need to append URE and Basic paths");
|
||||
return;
|
||||
}
|
||||
String basisLinkText = FileUtils.readFileToString(basisLink).trim();
|
||||
File basisHome = new File(officeHome, basisLinkText);
|
||||
File basisProgram = new File(basisHome, "program");
|
||||
File ureLink = new File(basisHome, "ure-link");
|
||||
String ureLinkText = FileUtils.readFileToString(ureLink).trim();
|
||||
File ureHome = new File(basisHome, ureLinkText);
|
||||
File ureBin = new File(ureHome, "bin");
|
||||
Map<String,String> environment = processBuilder.environment();
|
||||
// Windows environment variables are case insensitive but Java maps are not :-/
|
||||
// so let's make sure we modify the existing key
|
||||
String pathKey = "PATH";
|
||||
for (String key : environment.keySet()) {
|
||||
if ("PATH".equalsIgnoreCase(key)) {
|
||||
pathKey = key;
|
||||
}
|
||||
}
|
||||
String path = environment.get(pathKey) + ";" + ureBin.getAbsolutePath() + ";" + basisProgram.getAbsolutePath();
|
||||
logger.fine(String.format("setting %s to \"%s\"", pathKey, path));
|
||||
environment.put(pathKey, path);
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
if (process == null) {
|
||||
return false;
|
||||
}
|
||||
return getExitCode() == null;
|
||||
}
|
||||
|
||||
private class ExitCodeRetryable extends Retryable {
|
||||
|
||||
private int exitCode;
|
||||
|
||||
protected void attempt() throws TemporaryException, Exception {
|
||||
try {
|
||||
exitCode = process.exitValue();
|
||||
} catch (IllegalThreadStateException illegalThreadStateException) {
|
||||
throw new TemporaryException(illegalThreadStateException);
|
||||
}
|
||||
}
|
||||
|
||||
public int getExitCode() {
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Integer getExitCode() {
|
||||
try {
|
||||
return process.exitValue();
|
||||
} catch (IllegalThreadStateException exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getExitCode(long retryInterval, long retryTimeout) throws RetryTimeoutException {
|
||||
try {
|
||||
ExitCodeRetryable retryable = new ExitCodeRetryable();
|
||||
retryable.execute(retryInterval, retryTimeout);
|
||||
return retryable.getExitCode();
|
||||
} catch (RetryTimeoutException retryTimeoutException) {
|
||||
throw retryTimeoutException;
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException("could not get process exit code", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public int forciblyTerminate(long retryInterval, long retryTimeout) throws IOException, RetryTimeoutException {
|
||||
logger.info(String.format("trying to forcibly terminate process: '" + unoUrl + "'" + (pid != PID_UNKNOWN ? " (pid " + pid + ")" : "")));
|
||||
processManager.kill(process, pid);
|
||||
return getExitCode(retryInterval, retryTimeout);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
public interface OfficeTask {
|
||||
|
||||
void execute(OfficeContext context) throws OfficeException;
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import org.artofsolving.jodconverter.util.PlatformUtils;
|
||||
|
||||
import com.sun.star.beans.PropertyValue;
|
||||
import com.sun.star.uno.UnoRuntime;
|
||||
|
||||
public class OfficeUtils {
|
||||
|
||||
public static final String SERVICE_DESKTOP = "com.sun.star.frame.Desktop";
|
||||
|
||||
private OfficeUtils() {
|
||||
throw new AssertionError("utility class must not be instantiated");
|
||||
}
|
||||
|
||||
public static <T> T cast(Class<T> type, Object object) {
|
||||
return (T) UnoRuntime.queryInterface(type, object);
|
||||
}
|
||||
|
||||
public static PropertyValue property(String name, Object value) {
|
||||
PropertyValue propertyValue = new PropertyValue();
|
||||
propertyValue.Name = name;
|
||||
propertyValue.Value = value;
|
||||
return propertyValue;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static PropertyValue[] toUnoProperties(Map<String,?> properties) {
|
||||
PropertyValue[] propertyValues = new PropertyValue[properties.size()];
|
||||
int i = 0;
|
||||
for (Map.Entry<String,?> entry : properties.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Map) {
|
||||
Map<String,Object> subProperties = (Map<String,Object>) value;
|
||||
value = toUnoProperties(subProperties);
|
||||
}
|
||||
propertyValues[i++] = property((String) entry.getKey(), value);
|
||||
}
|
||||
return propertyValues;
|
||||
}
|
||||
|
||||
public static String toUrl(File file) {
|
||||
String path = file.toURI().getRawPath();
|
||||
String url = path.startsWith("//") ? "file:" + path : "file://" + path;
|
||||
return url.endsWith("/") ? url.substring(0, url.length() - 1) : url;
|
||||
}
|
||||
|
||||
public static File getDefaultOfficeHome() {
|
||||
if (System.getProperty("office.home") != null) {
|
||||
return new File(System.getProperty("office.home"));
|
||||
}
|
||||
if (PlatformUtils.isWindows()) {
|
||||
// %ProgramFiles(x86)% on 64-bit machines; %ProgramFiles% on 32-bit ones
|
||||
String programFiles = System.getenv("ProgramFiles(x86)");
|
||||
if (programFiles == null) {
|
||||
programFiles = System.getenv("ProgramFiles");
|
||||
}
|
||||
return findOfficeHome(
|
||||
programFiles + File.separator + "OpenOffice 4",
|
||||
programFiles + File.separator + "LibreOffice 4"
|
||||
);
|
||||
} else if (PlatformUtils.isMac()) {
|
||||
return findOfficeHome(
|
||||
"/Applications/OpenOffice.org.app/Contents",
|
||||
"/Applications/LibreOffice.app/Contents"
|
||||
);
|
||||
} else {
|
||||
// Linux or other *nix variants
|
||||
return findOfficeHome(
|
||||
"/opt/openoffice.org3",
|
||||
"/opt/libreoffice",
|
||||
"/usr/lib/openoffice",
|
||||
"/usr/lib/libreoffice"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static File findOfficeHome(String... knownPaths) {
|
||||
for (String path : knownPaths) {
|
||||
File home = new File(path);
|
||||
if (getOfficeExecutable(home).isFile()) {
|
||||
return home;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static File getOfficeExecutable(File officeHome) {
|
||||
if (PlatformUtils.isMac()) {
|
||||
return new File(officeHome, "MacOS/soffice.bin");
|
||||
} else {
|
||||
return new File(officeHome, "program/soffice.bin");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
//
|
||||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
class PooledOfficeManager implements OfficeManager {
|
||||
|
||||
private final PooledOfficeManagerSettings settings;
|
||||
private final ManagedOfficeProcess managedOfficeProcess;
|
||||
private final SuspendableThreadPoolExecutor taskExecutor;
|
||||
|
||||
private volatile boolean stopping = false;
|
||||
private int taskCount;
|
||||
private Future<?> currentTask;
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getName());
|
||||
|
||||
private OfficeConnectionEventListener connectionEventListener = new OfficeConnectionEventListener() {
|
||||
public void connected(OfficeConnectionEvent event) {
|
||||
taskCount = 0;
|
||||
taskExecutor.setAvailable(true);
|
||||
}
|
||||
public void disconnected(OfficeConnectionEvent event) {
|
||||
taskExecutor.setAvailable(false);
|
||||
if (stopping) {
|
||||
// expected
|
||||
stopping = false;
|
||||
} else {
|
||||
logger.warning("connection lost unexpectedly; attempting restart");
|
||||
if (currentTask != null) {
|
||||
currentTask.cancel(true);
|
||||
}
|
||||
managedOfficeProcess.restartDueToLostConnection();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public PooledOfficeManager(UnoUrl unoUrl) {
|
||||
this(new PooledOfficeManagerSettings(unoUrl));
|
||||
}
|
||||
|
||||
public PooledOfficeManager(PooledOfficeManagerSettings settings) {
|
||||
this.settings = settings;
|
||||
managedOfficeProcess = new ManagedOfficeProcess(settings);
|
||||
managedOfficeProcess.getConnection().addConnectionEventListener(connectionEventListener);
|
||||
taskExecutor = new SuspendableThreadPoolExecutor(new NamedThreadFactory("OfficeTaskThread"));
|
||||
}
|
||||
|
||||
public void execute(final OfficeTask task) throws OfficeException {
|
||||
Future<?> futureTask = taskExecutor.submit(new Runnable() {
|
||||
public void run() {
|
||||
if (settings.getMaxTasksPerProcess() > 0 && ++taskCount == settings.getMaxTasksPerProcess() + 1) {
|
||||
logger.info(String.format("reached limit of %d maxTasksPerProcess: restarting", settings.getMaxTasksPerProcess()));
|
||||
taskExecutor.setAvailable(false);
|
||||
stopping = true;
|
||||
managedOfficeProcess.restartAndWait();
|
||||
//FIXME taskCount will be 0 rather than 1 at this point
|
||||
}
|
||||
task.execute(managedOfficeProcess.getConnection());
|
||||
}
|
||||
});
|
||||
currentTask = futureTask;
|
||||
try {
|
||||
futureTask.get(settings.getTaskExecutionTimeout(), TimeUnit.MILLISECONDS);
|
||||
} catch (TimeoutException timeoutException) {
|
||||
managedOfficeProcess.restartDueToTaskTimeout();
|
||||
throw new OfficeException("task did not complete within timeout", timeoutException);
|
||||
} catch (ExecutionException executionException) {
|
||||
if (executionException.getCause() instanceof OfficeException) {
|
||||
throw (OfficeException) executionException.getCause();
|
||||
} else {
|
||||
throw new OfficeException("task failed", executionException.getCause());
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
throw new OfficeException("task failed", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void start() throws OfficeException {
|
||||
managedOfficeProcess.startAndWait();
|
||||
}
|
||||
|
||||
public void stop() throws OfficeException {
|
||||
taskExecutor.setAvailable(false);
|
||||
stopping = true;
|
||||
taskExecutor.shutdownNow();
|
||||
managedOfficeProcess.stopAndWait();
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return managedOfficeProcess.isConnected();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
class PooledOfficeManagerSettings extends ManagedOfficeProcessSettings {
|
||||
|
||||
public static final long DEFAULT_TASK_EXECUTION_TIMEOUT = 120000L;
|
||||
public static final int DEFAULT_MAX_TASKS_PER_PROCESS = 200;
|
||||
|
||||
private long taskExecutionTimeout = DEFAULT_TASK_EXECUTION_TIMEOUT;
|
||||
private int maxTasksPerProcess = DEFAULT_MAX_TASKS_PER_PROCESS;
|
||||
|
||||
public PooledOfficeManagerSettings(UnoUrl unoUrl) {
|
||||
super(unoUrl);
|
||||
}
|
||||
|
||||
public long getTaskExecutionTimeout() {
|
||||
return taskExecutionTimeout;
|
||||
}
|
||||
|
||||
public void setTaskExecutionTimeout(long taskExecutionTimeout) {
|
||||
this.taskExecutionTimeout = taskExecutionTimeout;
|
||||
}
|
||||
|
||||
public int getMaxTasksPerProcess() {
|
||||
return maxTasksPerProcess;
|
||||
}
|
||||
|
||||
public void setMaxTasksPerProcess(int maxTasksPerProcess) {
|
||||
this.maxTasksPerProcess = maxTasksPerProcess;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.artofsolving.jodconverter.process.ProcessManager;
|
||||
|
||||
class ProcessPoolOfficeManager implements OfficeManager {
|
||||
|
||||
private final BlockingQueue<PooledOfficeManager> pool;
|
||||
private final PooledOfficeManager[] pooledManagers;
|
||||
private final long taskQueueTimeout;
|
||||
|
||||
private volatile boolean running = false;
|
||||
|
||||
private final Logger logger = Logger.getLogger(ProcessPoolOfficeManager.class.getName());
|
||||
|
||||
public ProcessPoolOfficeManager(File officeHome, UnoUrl[] unoUrls, String[] runAsArgs, File templateProfileDir, File workDir,
|
||||
long retryTimeout, long taskQueueTimeout, long taskExecutionTimeout, int maxTasksPerProcess,
|
||||
ProcessManager processManager) {
|
||||
this.taskQueueTimeout = taskQueueTimeout;
|
||||
pool = new ArrayBlockingQueue<PooledOfficeManager>(unoUrls.length);
|
||||
pooledManagers = new PooledOfficeManager[unoUrls.length];
|
||||
for (int i = 0; i < unoUrls.length; i++) {
|
||||
PooledOfficeManagerSettings settings = new PooledOfficeManagerSettings(unoUrls[i]);
|
||||
settings.setRunAsArgs(runAsArgs);
|
||||
settings.setTemplateProfileDir(templateProfileDir);
|
||||
settings.setWorkDir(workDir);
|
||||
settings.setOfficeHome(officeHome);
|
||||
settings.setRetryTimeout(retryTimeout);
|
||||
settings.setTaskExecutionTimeout(taskExecutionTimeout);
|
||||
settings.setMaxTasksPerProcess(maxTasksPerProcess);
|
||||
settings.setProcessManager(processManager);
|
||||
pooledManagers[i] = new PooledOfficeManager(settings);
|
||||
}
|
||||
logger.info("ProcessManager implementation is " + processManager.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public synchronized void start() throws OfficeException {
|
||||
for (int i = 0; i < pooledManagers.length; i++) {
|
||||
pooledManagers[i].start();
|
||||
releaseManager(pooledManagers[i]);
|
||||
}
|
||||
running = true;
|
||||
}
|
||||
|
||||
public void execute(OfficeTask task) throws IllegalStateException, OfficeException {
|
||||
if (!running) {
|
||||
throw new IllegalStateException("this OfficeManager is currently stopped");
|
||||
}
|
||||
PooledOfficeManager manager = null;
|
||||
try {
|
||||
manager = acquireManager();
|
||||
if (manager == null) {
|
||||
throw new OfficeException("no office manager available");
|
||||
}
|
||||
manager.execute(task);
|
||||
} finally {
|
||||
if (manager != null) {
|
||||
releaseManager(manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void stop() throws OfficeException {
|
||||
running = false;
|
||||
logger.info("stopping");
|
||||
pool.clear();
|
||||
for (int i = 0; i < pooledManagers.length; i++) {
|
||||
pooledManagers[i].stop();
|
||||
}
|
||||
logger.info("stopped");
|
||||
}
|
||||
|
||||
private PooledOfficeManager acquireManager() {
|
||||
try {
|
||||
return pool.poll(taskQueueTimeout, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException interruptedException) {
|
||||
throw new OfficeException("interrupted", interruptedException);
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseManager(PooledOfficeManager manager) {
|
||||
try {
|
||||
pool.put(manager);
|
||||
} catch (InterruptedException interruptedException) {
|
||||
throw new OfficeException("interrupted", interruptedException);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
class RetryTimeoutException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -3704437769955257514L;
|
||||
|
||||
public RetryTimeoutException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
abstract class Retryable {
|
||||
|
||||
/**
|
||||
* @throws TemporaryException for an error condition that can be temporary - i.e. retrying later could be successful
|
||||
* @throws Exception for all other error conditions
|
||||
*/
|
||||
protected abstract void attempt() throws TemporaryException, Exception;
|
||||
|
||||
public void execute(long interval, long timeout) throws RetryTimeoutException, Exception {
|
||||
execute(0L, interval, timeout);
|
||||
}
|
||||
|
||||
public void execute(long delay, long interval, long timeout) throws RetryTimeoutException, Exception {
|
||||
long start = System.currentTimeMillis();
|
||||
if (delay > 0L) {
|
||||
sleep(delay);
|
||||
}
|
||||
while (true) {
|
||||
try {
|
||||
attempt();
|
||||
return;
|
||||
} catch (TemporaryException temporaryException) {
|
||||
if (System.currentTimeMillis() - start < timeout) {
|
||||
sleep(interval);
|
||||
// continue
|
||||
} else {
|
||||
throw new RetryTimeoutException(temporaryException.getCause());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sleep(long millis) {
|
||||
try {
|
||||
Thread.sleep(millis);
|
||||
} catch (InterruptedException interruptedException) {
|
||||
// continue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
class SuspendableThreadPoolExecutor extends ThreadPoolExecutor {
|
||||
|
||||
private boolean available = false;
|
||||
private ReentrantLock suspendLock = new ReentrantLock();
|
||||
private Condition availableCondition = suspendLock.newCondition();
|
||||
|
||||
public SuspendableThreadPoolExecutor(ThreadFactory threadFactory) {
|
||||
super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeExecute(Thread thread, Runnable task) {
|
||||
super.beforeExecute(thread, task);
|
||||
suspendLock.lock();
|
||||
try {
|
||||
while (!available) {
|
||||
availableCondition.await();
|
||||
}
|
||||
} catch (InterruptedException interruptedException) {
|
||||
thread.interrupt();
|
||||
} finally {
|
||||
suspendLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setAvailable(boolean available) {
|
||||
suspendLock.lock();
|
||||
try {
|
||||
this.available = available;
|
||||
if (available) {
|
||||
availableCondition.signalAll();
|
||||
}
|
||||
} finally {
|
||||
suspendLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Represents an error condition that can be temporary, i.e. that could go
|
||||
* away by simply retrying the same operation after an interval.
|
||||
*/
|
||||
class TemporaryException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 7237380113208327295L;
|
||||
|
||||
public TemporaryException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(new BigDecimal("7412611111110.99"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.office;
|
||||
|
||||
/**
|
||||
* Encapsulates the UNO Interprocess Connection type and parameters.
|
||||
* <p>
|
||||
* OpenOffice.org supports two connection types: TCP sockets and named pipes.
|
||||
* Named pipes are marginally faster and do not take up a TCP port, but they
|
||||
* require native libraries, which means setting <em>java.library.path</em>
|
||||
* when starting Java. E.g. on Linux
|
||||
* <pre>
|
||||
* java -Djava.library.path=/opt/openoffice.org/ure/lib ...
|
||||
* </pre>
|
||||
* <p>
|
||||
* See <a href="http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Opening_a_Connection">Opening a Connection</a>
|
||||
* in the OpenOffice.org Developer's Guide for more details.
|
||||
*/
|
||||
class UnoUrl {
|
||||
|
||||
private final String acceptString;
|
||||
private final String connectString;
|
||||
|
||||
private UnoUrl(String acceptString, String connectString) {
|
||||
this.acceptString = acceptString;
|
||||
this.connectString = connectString;
|
||||
}
|
||||
|
||||
public static UnoUrl socket(int port) {
|
||||
String socketString = "socket,host=127.0.0.1,port=" + port;
|
||||
return new UnoUrl(socketString, socketString + ",tcpNoDelay=1");
|
||||
}
|
||||
|
||||
public static UnoUrl pipe(String pipeName) {
|
||||
String pipeString = "pipe,name=" + pipeName;
|
||||
return new UnoUrl(pipeString, pipeString);
|
||||
}
|
||||
|
||||
public String getAcceptString() {
|
||||
return acceptString;
|
||||
}
|
||||
|
||||
public String getConnectString() {
|
||||
return connectString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return connectString;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.process;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
/**
|
||||
* {@link ProcessManager} implementation for Linux. Uses the <tt>ps</tt>
|
||||
* and <tt>kill</tt> commands.
|
||||
* <p>
|
||||
* Should Work on Solaris too, except that the command line string
|
||||
* returned by <tt>ps</tt> there is limited to 80 characters and this affects
|
||||
* {@link #findPid(String)}.
|
||||
*/
|
||||
public class LinuxProcessManager implements ProcessManager {
|
||||
|
||||
private static final Pattern PS_OUTPUT_LINE = Pattern.compile("^\\s*(\\d+)\\s+(.*)$");
|
||||
|
||||
private String[] runAsArgs;
|
||||
|
||||
public void setRunAsArgs(String... runAsArgs) {
|
||||
this.runAsArgs = runAsArgs;
|
||||
}
|
||||
|
||||
protected String[] psCommand() {
|
||||
return new String[] { "/bin/ps", "-e", "-o", "pid,args" };
|
||||
}
|
||||
|
||||
public long findPid(ProcessQuery query) throws IOException {
|
||||
String regex = Pattern.quote(query.getCommand()) + ".*" + Pattern.quote(query.getArgument());
|
||||
Pattern commandPattern = Pattern.compile(regex);
|
||||
for (String line : execute(psCommand())) {
|
||||
Matcher lineMatcher = PS_OUTPUT_LINE.matcher(line);
|
||||
if (lineMatcher.matches()) {
|
||||
String command = lineMatcher.group(2);
|
||||
Matcher commandMatcher = commandPattern.matcher(command);
|
||||
if (commandMatcher.find()) {
|
||||
return Long.parseLong(lineMatcher.group(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
return PID_NOT_FOUND;
|
||||
}
|
||||
|
||||
public void kill(Process process, long pid) throws IOException {
|
||||
if (pid <= 0) {
|
||||
throw new IllegalArgumentException("invalid pid: " + pid);
|
||||
}
|
||||
execute("/bin/kill", "-KILL", Long.toString(pid));
|
||||
}
|
||||
|
||||
private List<String> execute(String... args) throws IOException {
|
||||
String[] command;
|
||||
if (runAsArgs != null) {
|
||||
command = new String[runAsArgs.length + args.length];
|
||||
System.arraycopy(runAsArgs, 0, command, 0, runAsArgs.length);
|
||||
System.arraycopy(args, 0, command, runAsArgs.length, args.length);
|
||||
} else {
|
||||
command = args;
|
||||
}
|
||||
Process process = new ProcessBuilder(command).start();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> lines = IOUtils.readLines(process.getInputStream());
|
||||
return lines;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.process;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ProcessManager {
|
||||
|
||||
public static final long PID_NOT_FOUND = -2;
|
||||
public static final long PID_UNKNOWN = -1;
|
||||
|
||||
void kill(Process process, long pid) throws IOException;
|
||||
|
||||
/**
|
||||
* @param query
|
||||
* @return the pid if found, {@link #PID_NOT_FOUND} if not,
|
||||
* or {@link #PID_UNKNOWN} if this implementation is unable to find out
|
||||
* @throws IOException
|
||||
*/
|
||||
long findPid(ProcessQuery query) throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.process;
|
||||
|
||||
public class ProcessQuery {
|
||||
|
||||
private final String command;
|
||||
private final String argument;
|
||||
|
||||
public ProcessQuery(String command, String argument) {
|
||||
this.command = command;
|
||||
this.argument = argument;
|
||||
}
|
||||
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public String getArgument() {
|
||||
return argument;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.process;
|
||||
|
||||
public class PureJavaProcessManager implements ProcessManager {
|
||||
|
||||
public long findPid(ProcessQuery query) {
|
||||
return PID_UNKNOWN;
|
||||
}
|
||||
|
||||
public void kill(Process process, long pid) {
|
||||
process.destroy();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.process;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hyperic.sigar.Sigar;
|
||||
import org.hyperic.sigar.SigarException;
|
||||
import org.hyperic.sigar.ptql.ProcessFinder;
|
||||
|
||||
/**
|
||||
* {@link ProcessManager} implementation that uses the SIGAR library.
|
||||
* <p>
|
||||
* Requires the sigar.jar in the classpath and the appropriate system-specific
|
||||
* native library (e.g. <tt>libsigar-x86-linux.so</tt> on Linux x86) available
|
||||
* in the <em>java.library.path</em>.
|
||||
* <p>
|
||||
* See the <a href="http://support.hyperic.com/display/SIGAR">SIGAR site</a>
|
||||
* for documentation and downloads.
|
||||
*/
|
||||
public class SigarProcessManager implements ProcessManager {
|
||||
|
||||
public long findPid(ProcessQuery query) throws IOException {
|
||||
Sigar sigar = new Sigar();
|
||||
try {
|
||||
long[] pids = ProcessFinder.find(sigar, "State.Name.eq=" + query.getCommand());
|
||||
for (int i = 0; i < pids.length; i++) {
|
||||
String[] arguments = sigar.getProcArgs(pids[i]);
|
||||
if (arguments != null && argumentMatches(arguments, query.getArgument())) {
|
||||
return pids[i];
|
||||
}
|
||||
}
|
||||
return PID_NOT_FOUND;
|
||||
} catch (SigarException sigarException) {
|
||||
throw new IOException("findPid failed", sigarException);
|
||||
} finally {
|
||||
sigar.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void kill(Process process, long pid) throws IOException {
|
||||
Sigar sigar = new Sigar();
|
||||
try {
|
||||
sigar.kill(pid, Sigar.getSigNum("KILL"));
|
||||
} catch (SigarException sigarException) {
|
||||
throw new IOException("kill failed", sigarException);
|
||||
} finally {
|
||||
sigar.close();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean argumentMatches(String[] arguments, String expected) {
|
||||
for (String argument : arguments) {
|
||||
if (argument.contains(expected)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// JODConverter - Java OpenDocument Converter
|
||||
// Copyright 2004-2012 Mirko Nasato and contributors
|
||||
//
|
||||
// JODConverter is Open Source software, you can redistribute it and/or
|
||||
// modify it under either (at your option) of the following licenses
|
||||
//
|
||||
// 1. The GNU Lesser General Public License v3 (or later)
|
||||
// -> http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
// 2. The Apache License, Version 2.0
|
||||
// -> http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
//
|
||||
package org.artofsolving.jodconverter.util;
|
||||
|
||||
public class PlatformUtils {
|
||||
|
||||
private static final String OS_NAME = System.getProperty("os.name").toLowerCase();
|
||||
|
||||
private PlatformUtils() {
|
||||
throw new AssertionError("utility class must not be instantiated");
|
||||
}
|
||||
|
||||
public static boolean isLinux() {
|
||||
return OS_NAME.startsWith("linux");
|
||||
}
|
||||
|
||||
public static boolean isMac() {
|
||||
return OS_NAME.startsWith("mac");
|
||||
}
|
||||
|
||||
public static boolean isWindows() {
|
||||
return OS_NAME.startsWith("windows");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
[
|
||||
{
|
||||
"name": "Portable Document Format",
|
||||
"extension": "pdf",
|
||||
"mediaType": "application/pdf",
|
||||
"storePropertiesByFamily": {
|
||||
"DRAWING": {"FilterName": "draw_pdf_Export"},
|
||||
"SPREADSHEET": {"FilterName": "calc_pdf_Export"},
|
||||
"PRESENTATION": {"FilterName": "impress_pdf_Export"},
|
||||
"TEXT": {"FilterName": "writer_pdf_Export"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Macromedia Flash",
|
||||
"extension": "swf",
|
||||
"mediaType": "application/x-shockwave-flash",
|
||||
"storePropertiesByFamily": {
|
||||
"DRAWING": {"FilterName": "draw_flash_Export"},
|
||||
"PRESENTATION": {"FilterName": "impress_flash_Export"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTML",
|
||||
"extension": "html",
|
||||
"mediaType": "text/html",
|
||||
"inputFamily": "TEXT",
|
||||
"storePropertiesByFamily": {
|
||||
"SPREADSHEET": {"FilterName": "HTML (StarCalc)"},
|
||||
"PRESENTATION": {"FilterName": "impress_html_Export"},
|
||||
"TEXT": {"FilterName": "HTML (StarWriter)"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OpenDocument Text",
|
||||
"extension": "odt",
|
||||
"mediaType": "application/vnd.oasis.opendocument.text",
|
||||
"inputFamily": "TEXT",
|
||||
"storePropertiesByFamily": {"TEXT": {"FilterName": "writer8"}}
|
||||
},
|
||||
{
|
||||
"name": "OpenOffice.org 1.0 Text Document",
|
||||
"extension": "sxw",
|
||||
"mediaType": "application/vnd.sun.xml.writer",
|
||||
"inputFamily": "TEXT",
|
||||
"storePropertiesByFamily": {"TEXT": {"FilterName": "StarOffice XML (Writer)"}}
|
||||
},
|
||||
{
|
||||
"name": "Microsoft Word",
|
||||
"extension": "doc",
|
||||
"mediaType": "application/msword",
|
||||
"inputFamily": "TEXT",
|
||||
"storePropertiesByFamily": {"TEXT": {"FilterName": "MS Word 97"}}
|
||||
},
|
||||
{
|
||||
"name": "Microsoft Word 2007 XML",
|
||||
"extension": "docx",
|
||||
"mediaType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"inputFamily": "TEXT"
|
||||
},
|
||||
{
|
||||
"name": "Rich Text Format",
|
||||
"extension": "rtf",
|
||||
"mediaType": "text/rtf",
|
||||
"inputFamily": "TEXT",
|
||||
"storePropertiesByFamily": {"TEXT": {"FilterName": "Rich Text Format"}}
|
||||
},
|
||||
{
|
||||
"name": "WordPerfect",
|
||||
"extension": "wpd",
|
||||
"mediaType": "application/wordperfect",
|
||||
"inputFamily": "TEXT"
|
||||
},
|
||||
{
|
||||
"name": "Plain Text",
|
||||
"extension": "txt",
|
||||
"mediaType": "text/plain",
|
||||
"inputFamily": "TEXT",
|
||||
"loadProperties": {
|
||||
"FilterName": "Text (encoded)",
|
||||
"FilterOptions": "utf8"
|
||||
},
|
||||
"storePropertiesByFamily": {"TEXT": {
|
||||
"FilterName": "Text (encoded)",
|
||||
"FilterOptions": "utf8"
|
||||
}}
|
||||
},
|
||||
{
|
||||
"name": "MediaWiki wikitext",
|
||||
"extension": "wiki",
|
||||
"mediaType": "text/x-wiki",
|
||||
"storePropertiesByFamily": {"TEXT": {"FilterName": "MediaWiki"}}
|
||||
},
|
||||
{
|
||||
"name": "OpenDocument Spreadsheet",
|
||||
"extension": "ods",
|
||||
"mediaType": "application/vnd.oasis.opendocument.spreadsheet",
|
||||
"inputFamily": "SPREADSHEET",
|
||||
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "calc8"}}
|
||||
},
|
||||
{
|
||||
"name": "OpenOffice.org 1.0 Spreadsheet",
|
||||
"extension": "sxc",
|
||||
"mediaType": "application/vnd.sun.xml.calc",
|
||||
"inputFamily": "SPREADSHEET",
|
||||
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "StarOffice XML (Calc)"}}
|
||||
},
|
||||
{
|
||||
"name": "Microsoft Excel",
|
||||
"extension": "xls",
|
||||
"mediaType": "application/vnd.ms-excel",
|
||||
"inputFamily": "SPREADSHEET",
|
||||
"storePropertiesByFamily": {"SPREADSHEET": {"FilterName": "MS Excel 97"}}
|
||||
},
|
||||
{
|
||||
"name": "Microsoft Excel 2007 XML",
|
||||
"extension": "xlsx",
|
||||
"mediaType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"inputFamily": "SPREADSHEET"
|
||||
},
|
||||
{
|
||||
"name": "Comma Separated Values",
|
||||
"extension": "csv",
|
||||
"mediaType": "text/csv",
|
||||
"inputFamily": "SPREADSHEET",
|
||||
"loadProperties": {
|
||||
"FilterName": "Text - txt - csv (StarCalc)",
|
||||
"FilterOptions": "44,34,0"
|
||||
},
|
||||
"storePropertiesByFamily": {"SPREADSHEET": {
|
||||
"FilterName": "Text - txt - csv (StarCalc)",
|
||||
"FilterOptions": "44,34,0"
|
||||
}}
|
||||
},
|
||||
{
|
||||
"name": "Tab Separated Values",
|
||||
"extension": "tsv",
|
||||
"mediaType": "text/tab-separated-values",
|
||||
"inputFamily": "SPREADSHEET",
|
||||
"loadProperties": {
|
||||
"FilterName": "Text - txt - csv (StarCalc)",
|
||||
"FilterOptions": "9,34,0"
|
||||
},
|
||||
"storePropertiesByFamily": {"SPREADSHEET": {
|
||||
"FilterName": "Text - txt - csv (StarCalc)",
|
||||
"FilterOptions": "9,34,0"
|
||||
}}
|
||||
},
|
||||
{
|
||||
"name": "OpenDocument Presentation",
|
||||
"extension": "odp",
|
||||
"mediaType": "application/vnd.oasis.opendocument.presentation",
|
||||
"inputFamily": "PRESENTATION",
|
||||
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "impress8"}}
|
||||
},
|
||||
{
|
||||
"name": "OpenOffice.org 1.0 Presentation",
|
||||
"extension": "sxi",
|
||||
"mediaType": "application/vnd.sun.xml.impress",
|
||||
"inputFamily": "PRESENTATION",
|
||||
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "StarOffice XML (Impress)"}}
|
||||
},
|
||||
{
|
||||
"name": "Microsoft PowerPoint",
|
||||
"extension": "ppt",
|
||||
"mediaType": "application/vnd.ms-powerpoint",
|
||||
"inputFamily": "PRESENTATION",
|
||||
"storePropertiesByFamily": {"PRESENTATION": {"FilterName": "MS PowerPoint 97"}}
|
||||
},
|
||||
{
|
||||
"name": "Microsoft PowerPoint 2007 XML",
|
||||
"extension": "pptx",
|
||||
"mediaType": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"inputFamily": "PRESENTATION"
|
||||
},
|
||||
{
|
||||
"name": "OpenDocument Drawing",
|
||||
"extension": "odg",
|
||||
"mediaType": "application/vnd.oasis.opendocument.graphics",
|
||||
"inputFamily": "DRAWING",
|
||||
"storePropertiesByFamily": {"DRAWING": {"FilterName": "draw8"}}
|
||||
},
|
||||
{
|
||||
"name": "Scalable Vector Graphics",
|
||||
"extension": "svg",
|
||||
"mediaType": "image/svg+xml",
|
||||
"storePropertiesByFamily": {"DRAWING": {"FilterName": "draw_svg_Export"}}
|
||||
}
|
||||
]
|
|
@ -0,0 +1,171 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.8.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>jodconverter-web</artifactId>
|
||||
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<ufile.sdk.verison>1.0-SNAPSHOT</ufile.sdk.verison>
|
||||
<logging.path>${basedir}/target/classes/logs</logging.path>
|
||||
<appName>file-preview</appName>
|
||||
</properties>
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- required for org.hyperic:sigar -->
|
||||
<id>jboss-public-repository-group</id>
|
||||
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.logstash.logback</groupId>
|
||||
<artifactId>logstash-logback-encoder</artifactId>
|
||||
<version>4.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yudianbank</groupId>
|
||||
<artifactId>jodconverter</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<groupId>commons-io</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- REDISSON -->
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>3.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version>3.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>org.apache.poi.xwpf.converter.core</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>poi</artifactId>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>fr.opensagres.xdocreport.document</artifactId>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
<!-- 解压(apache) -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.9</version>
|
||||
</dependency>
|
||||
<!-- 解压(rar)-->
|
||||
<dependency>
|
||||
<groupId>com.github.junrar</groupId>
|
||||
<artifactId>junrar</artifactId>
|
||||
<version>0.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jchardet</groupId>
|
||||
<artifactId>jchardet</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>antlr</groupId>
|
||||
<artifactId>antlr</artifactId>
|
||||
<version>2.7.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>3.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>19.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>jodconverter-web/src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,19 +1,14 @@
|
|||
package com.yudianbank;
|
||||
|
||||
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
@ComponentScan(value = "com.yudianbank.*")
|
||||
//@EnableApolloConfig
|
||||
public class FilePreviewApplication {
|
||||
public static void main(String[] args) {
|
||||
Properties properties = System.getProperties();
|
|
@ -1,7 +1,6 @@
|
|||
package com.yudianbank.utils;
|
||||
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
|
@ -1,11 +1,8 @@
|
|||
package com.yudianbank.utils;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Component
|
||||
public class ShedulerClean {
|
||||
@Value("${file.dir}")
|
|
@ -1,7 +1,5 @@
|
|||
package com.yudianbank.web.controller;
|
||||
|
||||
import com.ctrip.framework.apollo.Config;
|
||||
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
|
||||
import com.yudianbank.param.ReturnResponse;
|
||||
import com.yudianbank.utils.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
Before Width: | Height: | Size: 601 B After Width: | Height: | Size: 601 B |
Before Width: | Height: | Size: 580 B After Width: | Height: | Size: 580 B |
Before Width: | Height: | Size: 570 B After Width: | Height: | Size: 570 B |
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 762 B |
Before Width: | Height: | Size: 399 B After Width: | Height: | Size: 399 B |
Before Width: | Height: | Size: 710 B After Width: | Height: | Size: 710 B |
Before Width: | Height: | Size: 432 B After Width: | Height: | Size: 432 B |
Before Width: | Height: | Size: 534 B After Width: | Height: | Size: 534 B |
Before Width: | Height: | Size: 529 B After Width: | Height: | Size: 529 B |
Before Width: | Height: | Size: 467 B After Width: | Height: | Size: 467 B |
Before Width: | Height: | Size: 45 B After Width: | Height: | Size: 45 B |
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 381 B |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
@ -12,7 +12,7 @@ website: http://code.google.com/p/jquerytree/
|
|||
.ztree {margin:0; padding:5px; color:#333}
|
||||
.ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap; outline:0}
|
||||
.ztree li ul{ margin:0; padding:0 0 0 18px}
|
||||
.ztree li ul.line{ background:url(./img/line_conn.gif) 0 0 repeat-y;}
|
||||
.ztree li ul.line{ background:url(img/line_conn.gif) 0 0 repeat-y;}
|
||||
|
||||
.ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:17px; color:#333; background-color: transparent;
|
||||
text-decoration:none; vertical-align:top; display: inline-block}
|
||||
|
@ -29,7 +29,7 @@ website: http://code.google.com/p/jquerytree/
|
|||
.ztree li span.button {line-height:0; margin:0; width:16px; height:16px; display: inline-block; vertical-align:middle;
|
||||
border:0 none; cursor: pointer;outline:none;
|
||||
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
|
||||
background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")}
|
||||
background-image:url("img/zTreeStandard.png"); *background-image:url("img/zTreeStandard.gif")}
|
||||
|
||||
.ztree li span.button.chk {width:13px; height:13px; margin:0 3px 0 0; cursor: auto}
|
||||
.ztree li span.button.chk.checkbox_false_full {background-position:0 0}
|
||||
|
@ -76,13 +76,13 @@ website: http://code.google.com/p/jquerytree/
|
|||
.ztree li span.button.edit {margin-right:2px; background-position:-110px -48px; vertical-align:top; *vertical-align:middle}
|
||||
.ztree li span.button.remove {margin-right:2px; background-position:-110px -64px; vertical-align:top; *vertical-align:middle}
|
||||
|
||||
.ztree li span.button.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}
|
||||
.ztree li span.button.ico_loading{margin-right:2px; background:url(img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle}
|
||||
|
||||
ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)}
|
||||
|
||||
span.tmpzTreeMove_arrow {width:16px; height:16px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute;
|
||||
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
|
||||
background-position:-110px -80px; background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")}
|
||||
background-position:-110px -80px; background-image:url("img/zTreeStandard.png"); *background-image:url("img/zTreeStandard.gif")}
|
||||
|
||||
ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)}
|
||||
.zTreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute}
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
173
pom.xml
|
@ -1,166 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.yudianbank</groupId>
|
||||
<artifactId>filepreview</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>file-online-preview</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.8.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<ufile.sdk.verison>1.0-SNAPSHOT</ufile.sdk.verison>
|
||||
<logging.path>${basedir}/target/classes/logs</logging.path>
|
||||
<appName>file-preview</appName>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.logstash.logback</groupId>
|
||||
<artifactId>logstash-logback-encoder</artifactId>
|
||||
<version>4.11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- REDISSON -->
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId> org.apache.poi</groupId>
|
||||
<artifactId> poi </artifactId>
|
||||
<version>3.12</version>
|
||||
</dependency>
|
||||
<dependency >
|
||||
<groupId> org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version > 3.12 </version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>org.apache.poi.xwpf.converter.core</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>poi</artifactId>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>fr.opensagres.xdocreport.document</artifactId>
|
||||
<version>1.0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
<!-- 解压(apache) -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.9</version>
|
||||
</dependency>
|
||||
<!-- 解压(rar)-->
|
||||
<dependency>
|
||||
<groupId>com.github.junrar</groupId>
|
||||
<artifactId>junrar</artifactId>
|
||||
<version>0.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jchardet</groupId>
|
||||
<artifactId>jchardet</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>antlr</groupId>
|
||||
<artifactId>antlr</artifactId>
|
||||
<version>2.7.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>3.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.artofsolving.jodconverter</groupId>
|
||||
<artifactId>jodconverter-core</artifactId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<groupId>commons-io</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.3.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.yudianbank</groupId>
|
||||
<artifactId>filepreview</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<modules>
|
||||
<module>jodconverter-core</module>
|
||||
<module>jodconverter-web</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>file-online-preview</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
</project>
|
||||
|
|