Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set user directory for openoffice processes #125

Merged
merged 2 commits into from
Feb 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@

package com.haulmont.yarg.formatters.impl.doc.connector;

import com.google.common.collect.Lists;
import com.sun.star.comp.helper.BootstrapException;
import com.sun.star.lib.util.NativeLibraryLoader;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -38,7 +42,7 @@
* http:https://udk.openoffice.org/source/browse/udk/javaunohelper/com/sun/star/comp/helper/Bootstrap.java?view=markup
*/
public class OOServer {
protected static final Logger log = LoggerFactory.getLogger(JavaProcessManager.class);
protected static final Logger log = LoggerFactory.getLogger(OOServer.class);
/**
* The OOo server process.
*/
Expand All @@ -57,10 +61,12 @@ public class OOServer {
/**
* The options for starting the OOo server.
*/
private List oooOptions;
private List<String> oooOptions;

private ProcessManager processManager;

protected OfficeIntegration officeIntegration;

/**
* Constructs an OOo server which uses the folder of the OOo installation
* containing the soffice executable and a given list of options to start
Expand All @@ -69,13 +75,15 @@ public class OOServer {
* @param oooExecFolder The folder of the OOo installation containing the soffice executable
* @param oooOptions The list of options
*/
public OOServer(String oooExecFolder, List oooOptions, String host, int port, ProcessManager processManager) {
public OOServer(String oooExecFolder, List<String> oooOptions, String host, int port,
ProcessManager processManager, OfficeIntegration officeIntegration) {
this.oooProcess = null;
this.oooExecFolder = oooExecFolder;
this.host = host;
this.port = port;
this.oooOptions = oooOptions;
this.processManager = processManager;
this.officeIntegration = officeIntegration;
}

/**
Expand All @@ -91,7 +99,7 @@ public OOServer(String oooExecFolder, List oooOptions, String host, int port, Pr
* the pipe name "oooPipe" the accept option looks like this:
* - accept option : -accept=pipe,name=oooPipe;urp;
*/
public void start() throws BootstrapException, IOException {
public synchronized void start() throws BootstrapException, IOException {
// find office executable relative to this class's class loader
String sOffice = System.getProperty("os.name").startsWith("Windows") ? "soffice.exe" : "soffice";
//accept option !Note! we are using old version notation (- instead of --) to support old version of office
Expand All @@ -103,23 +111,30 @@ public void start() throws BootstrapException, IOException {
if (fOffice == null)
throw new BootstrapException("no office executable found!");

// create call with arguments
int arguments = (oooOptions != null) ? oooOptions.size() + 1 : 1;
arguments++;
String[] oooCommand = new String[arguments];
oooCommand[0] = fOffice.getPath();
List<String> argumentsList = Lists.newLinkedList();
argumentsList.add(fOffice.getPath());

for (int i = 0; i < oooOptions.size(); i++) {
oooCommand[i + 1] = (String) oooOptions.get(i);
}
if (CollectionUtils.isNotEmpty(oooOptions))
argumentsList.addAll(oooOptions);

oooCommand[arguments - 1] = oooAcceptOption;
String instanceProfilePath = getInstanceProfilePath();
if (StringUtils.isNotBlank(instanceProfilePath)) {
prepareInstanceProfileDir();
argumentsList.add("-env:UserInstallation=" + toUrl(new File(instanceProfilePath)));
}
argumentsList.add(oooAcceptOption);

// start office process
oooProcess = Runtime.getRuntime().exec(oooCommand);
oooProcess = Runtime.getRuntime().exec(argumentsList.toArray(new String[0]));

pipe(oooProcess.getInputStream(), "OUT");
pipe(oooProcess.getErrorStream(), "ERR");
}

pipe(oooProcess.getInputStream(), System.out, "CO> ");
pipe(oooProcess.getErrorStream(), System.err, "CE> ");
public String toUrl(File file) {
String path = file.toURI().getRawPath();
String url = path.startsWith("//") ? "file:" + path : "file:https://" + path;
return url.endsWith("/") ? url.substring(0, url.length() - 1) : url;
}

/**
Expand All @@ -128,17 +143,18 @@ public void start() throws BootstrapException, IOException {
* nothing.
* If there has been a previous start, kill destroys the process.
*/
public void kill() {
public synchronized void kill() {
if (oooProcess != null) {
log.info("OOServer is killing office instance with port " + port);
log.info("OOServer is killing office instance with port {}", port);
List<Long> pids = processManager.findPid(host, port);
processManager.kill(oooProcess, pids);
oooProcess = null;
deleteProfileDir();
}
}

private static void pipe(final InputStream in, final PrintStream out, final String prefix) {
new Thread("Pipe: " + prefix) {
protected void pipe(final InputStream in, final String prefix) {
new Thread(String.format("OOServer: %s", prefix)) {
@Override
public void run() {
BufferedReader r = new BufferedReader(new InputStreamReader(in));
Expand All @@ -148,10 +164,10 @@ public void run() {
if (s == null) {
break;
}
out.println(prefix + s);
log.debug("{}: {}", prefix, s);
}
} catch (IOException e) {
e.printStackTrace(System.err);
log.debug("OOServer error:", e);
}
}
}.start();
Expand All @@ -177,4 +193,40 @@ public static List<String> getDefaultOOoOptions() {

return options;
}

protected void prepareInstanceProfileDir() {
String instanceProfilePath = getInstanceProfilePath();
if (StringUtils.isNotBlank(instanceProfilePath)) {
File instanceProfileDir = new File(instanceProfilePath);
if (instanceProfileDir.exists()) {
log.debug(String.format("OpenOffice server profile dir '%s' already exists; deleting", instanceProfileDir));
deleteProfileDir();
}
}
}

protected void deleteProfileDir() {
String instanceProfilePath = getInstanceProfilePath();
if (StringUtils.isNotBlank(instanceProfilePath)) {
File instanceProfileDir = new File(instanceProfilePath);
try {
FileUtils.deleteDirectory(instanceProfileDir);
} catch (IOException ioException) {
File oldProfileDir = new File(instanceProfileDir.getParentFile(),
instanceProfileDir.getName() + ".old." + System.currentTimeMillis());
if (instanceProfileDir.renameTo(oldProfileDir)) {
log.warn("could not delete profileDir: " + ioException.getMessage() + "; renamed it to " + oldProfileDir);
} else {
log.error("could not delete profileDir: " + ioException.getMessage());
}
}
}
}

protected String getInstanceProfilePath() {
if (StringUtils.isBlank(officeIntegration.getTemporaryDirPath()))
return "";

return officeIntegration.getTemporaryDirPath() + String.format(".ooserver_%s_%s", host, port);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public class OfficeConnection {
public OfficeConnection(String openOfficePath, Integer port, ProcessManager processManager, OfficeIntegration officeIntegration) {
this.port = port;
this.officeIntegration = officeIntegration;
this.oooServer = new OOServer(openOfficePath, OOServer.getDefaultOOoOptions(), "localhost", port, processManager);
this.oooServer = new OOServer(openOfficePath, OOServer.getDefaultOOoOptions(),
"localhost", port, processManager, officeIntegration);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you should pass the temp directory name instead of OfficeIntegration?

this.bsc = new BootstrapSocketConnector(oooServer);
this.openOfficePath = openOfficePath;
}
Expand Down