1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.officeimporter.internal.server

File DefaultOfficeServer.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart2.png
81% of files have more coverage

Code metrics

14
53
8
1
235
133
19
0.36
6.62
8
2.38

Classes

Class Line # Actions
DefaultOfficeServer 50 53 0% 19 61
0.1866666718.7%
 

Contributing tests

This file is covered by 58 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.officeimporter.internal.server;
21   
22    import java.io.File;
23    import java.io.InputStream;
24   
25    import javax.inject.Inject;
26    import javax.inject.Singleton;
27   
28    import org.artofsolving.jodconverter.OfficeDocumentConverter;
29    import org.artofsolving.jodconverter.document.JsonDocumentFormatRegistry;
30    import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
31    import org.artofsolving.jodconverter.office.ExternalOfficeManagerConfiguration;
32    import org.artofsolving.jodconverter.office.OfficeManager;
33    import org.slf4j.Logger;
34    import org.xwiki.component.annotation.Component;
35    import org.xwiki.environment.Environment;
36    import org.xwiki.officeimporter.converter.OfficeConverter;
37    import org.xwiki.officeimporter.internal.converter.DefaultOfficeConverter;
38    import org.xwiki.officeimporter.server.OfficeServer;
39    import org.xwiki.officeimporter.server.OfficeServerConfiguration;
40    import org.xwiki.officeimporter.server.OfficeServerException;
41   
42    /**
43    * Default {@link OfficeServer} implementation.
44    *
45    * @version $Id: 6e3da402bac998a7461627febb3c2a2c8d3b836b $
46    * @since 5.0M2
47    */
48    @Component
49    @Singleton
 
50    public class DefaultOfficeServer implements OfficeServer
51    {
52    /**
53    * The path to the file that can be used to configure the office document conversion.
54    */
55    private static final String DOCUMENT_FORMATS_PATH = "/document-formats.js";
56   
57    /**
58    * The office server configuration.
59    */
60    @Inject
61    private OfficeServerConfiguration config;
62   
63    /**
64    * Used to query global temporary working directory.
65    */
66    @Inject
67    private Environment environment;
68   
69    /**
70    * The logger to log.
71    */
72    @Inject
73    private Logger logger;
74   
75    /**
76    * Internal {@link OfficeManager} used to control / connect the office server.
77    */
78    private OfficeManager jodManager;
79   
80    /**
81    * Internal {@link OfficeDocumentConverter} used to convert office documents.
82    */
83    private OfficeDocumentConverter jodConverter;
84   
85    /**
86    * Current office server process state.
87    */
88    private ServerState state;
89   
90    /**
91    * Used for carrying out document conversion tasks.
92    */
93    private OfficeConverter converter;
94   
95    /**
96    * Default constructor.
97    */
 
98  185 toggle public DefaultOfficeServer()
99    {
100  185 setState(ServerState.NOT_CONNECTED);
101    }
102   
103    /**
104    * Initialize JodConverter.
105    *
106    * @throws OfficeServerException when failed to initialize
107    */
 
108  0 toggle public void initialize() throws OfficeServerException
109    {
110  0 if (this.config.getServerType() == OfficeServerConfiguration.SERVER_TYPE_INTERNAL) {
111  0 DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
112  0 configuration.setPortNumber(this.config.getServerPort());
113   
114  0 String homePath = this.config.getHomePath();
115  0 if (homePath != null) {
116  0 configuration.setOfficeHome(homePath);
117    }
118   
119  0 String profilePath = this.config.getProfilePath();
120  0 if (profilePath != null) {
121  0 configuration.setTemplateProfileDir(new File(profilePath));
122    }
123   
124  0 configuration.setMaxTasksPerProcess(this.config.getMaxTasksPerProcess());
125  0 configuration.setTaskExecutionTimeout(this.config.getTaskExecutionTimeout());
126   
127  0 try {
128  0 this.jodManager = configuration.buildOfficeManager();
129    } catch (Exception e) {
130    // Protect against exceptions raised by JodManager. For example if it cannot autodetect the office home,
131    // it'll throw an java.lang.IllegalStateException exception...
132    // We wrap this in an OfficeServerException in order to display some nicer message to the user.
133  0 throw new OfficeServerException("Failed to start Office server. Reason: " + e.getMessage(), e);
134    }
135  0 } else if (this.config.getServerType() == OfficeServerConfiguration.SERVER_TYPE_EXTERNAL_LOCAL) {
136  0 ExternalOfficeManagerConfiguration externalProcessOfficeManager = new ExternalOfficeManagerConfiguration();
137  0 externalProcessOfficeManager.setPortNumber(this.config.getServerPort());
138  0 externalProcessOfficeManager.setConnectOnStart(true);
139  0 this.jodManager = externalProcessOfficeManager.buildOfficeManager();
140    } else {
141  0 setState(ServerState.CONF_ERROR);
142  0 throw new OfficeServerException("Invalid office server configuration.");
143    }
144   
145  0 this.jodConverter = null;
146    // Try to use the JSON document format registry to configure the office document conversion.
147  0 InputStream input = getClass().getResourceAsStream(DOCUMENT_FORMATS_PATH);
148  0 if (input != null) {
149  0 try {
150  0 this.jodConverter = new OfficeDocumentConverter(this.jodManager, new JsonDocumentFormatRegistry(input));
151    } catch (Exception e) {
152  0 this.logger.warn("Failed to parse {} . The default document format registry will be used instead.",
153    DOCUMENT_FORMATS_PATH, e);
154    }
155    } else {
156  0 this.logger.debug("{} is missing. The default document format registry will be used instead.",
157    DOCUMENT_FORMATS_PATH);
158    }
159  0 if (this.jodConverter == null) {
160    // Use the default document format registry.
161  0 this.jodConverter = new OfficeDocumentConverter(this.jodManager);
162    }
163   
164  0 File workDir = this.environment.getTemporaryDirectory();
165  0 this.converter = new DefaultOfficeConverter(this.jodConverter, workDir);
166    }
167   
 
168  437 toggle @Override
169    public ServerState getState()
170    {
171  437 return this.state;
172    }
173   
 
174  0 toggle @Override
175    public void start() throws OfficeServerException
176    {
177    // If the office server is running then stop it in order to restart the connection.
178  0 stop();
179   
180  0 initialize();
181  0 try {
182  0 this.jodManager.start();
183  0 setState(ServerState.CONNECTED);
184  0 this.logger.info("Open Office instance started.");
185    } catch (Exception e) {
186  0 setState(ServerState.ERROR);
187  0 throw new OfficeServerException("Error while connecting / starting the office server.", e);
188    }
189    }
190   
 
191  32 toggle @Override
192    public void stop() throws OfficeServerException
193    {
194    // We should try stopping the office server even if the status is not connected but we should not raise an
195    // error if there is a failure to stop.
196  32 boolean connected = checkState(ServerState.CONNECTED);
197  32 try {
198  32 this.jodManager.stop();
199  0 setState(ServerState.NOT_CONNECTED);
200  0 this.logger.info("Open Office instance stopped.");
201    } catch (Exception e) {
202  32 if (connected) {
203  0 setState(ServerState.ERROR);
204  0 throw new OfficeServerException("Error while disconnecting / shutting down the office server.", e);
205    }
206    }
207    }
208   
 
209  0 toggle @Override
210    public OfficeConverter getConverter()
211    {
212  0 return this.converter;
213    }
214   
215    /**
216    * Utility method for setting the current office manager state.
217    *
218    * @param newState new state.
219    */
 
220  185 toggle private void setState(ServerState newState)
221    {
222  185 this.state = newState;
223    }
224   
225    /**
226    * Utility method for checking the office manager state.
227    *
228    * @param expectedState expected state.
229    * @return true if office manger is in given state, false otherwise.
230    */
 
231  32 toggle private boolean checkState(ServerState expectedState)
232    {
233  32 return (this.state == expectedState);
234    }
235    }