1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.officeimporter.internal.server

File DefaultOfficeServer.java

 

Coverage histogram

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

Code metrics

14
53
8
1
240
138
19
0.36
6.62
8
2.38

Classes

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

Contributing tests

This file is covered by 70 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.jodconverter.LocalConverter;
29    import org.jodconverter.document.JsonDocumentFormatRegistry;
30    import org.jodconverter.filter.text.LinkedImagesEmbedderFilter;
31    import org.jodconverter.office.LocalOfficeManager;
32    import org.jodconverter.office.ExternalOfficeManagerBuilder;
33    import org.jodconverter.office.OfficeManager;
34    import org.slf4j.Logger;
35    import org.xwiki.component.annotation.Component;
36    import org.xwiki.environment.Environment;
37    import org.xwiki.officeimporter.converter.OfficeConverter;
38    import org.xwiki.officeimporter.internal.converter.DefaultOfficeConverter;
39    import org.xwiki.officeimporter.server.OfficeServer;
40    import org.xwiki.officeimporter.server.OfficeServerConfiguration;
41    import org.xwiki.officeimporter.server.OfficeServerException;
42   
43    /**
44    * Default {@link OfficeServer} implementation.
45    *
46    * @version $Id: 18dbf6bda50f8b5326be2e4ae9b778ae4d6497c4 $
47    * @since 5.0M2
48    */
49    @Component
50    @Singleton
 
51    public class DefaultOfficeServer implements OfficeServer
52    {
53    /**
54    * The path to the file that can be used to configure the office document conversion.
55    */
56    private static final String DOCUMENT_FORMATS_PATH = "/document-formats.js";
57   
58    /**
59    * The office server configuration.
60    */
61    @Inject
62    private OfficeServerConfiguration config;
63   
64    /**
65    * Used to query global temporary working directory.
66    */
67    @Inject
68    private Environment environment;
69   
70    /**
71    * The logger to log.
72    */
73    @Inject
74    private Logger logger;
75   
76    /**
77    * Internal {@link OfficeManager} used to control / connect the office server.
78    */
79    private OfficeManager jodManager;
80   
81    /**
82    * Internal {@link LocalConverter} used to convert office documents.
83    */
84    private LocalConverter jodConverter;
85   
86    /**
87    * Current office server process state.
88    */
89    private ServerState state;
90   
91    /**
92    * Used for carrying out document conversion tasks.
93    */
94    private OfficeConverter converter;
95   
96    /**
97    * Default constructor.
98    */
 
99  217 toggle public DefaultOfficeServer()
100    {
101  217 setState(ServerState.NOT_CONNECTED);
102    }
103   
104    /**
105    * Initialize JodConverter.
106    *
107    * @throws OfficeServerException when failed to initialize
108    */
 
109  0 toggle public void initialize() throws OfficeServerException
110    {
111  0 if (this.config.getServerType() == OfficeServerConfiguration.SERVER_TYPE_INTERNAL) {
112  0 LocalOfficeManager.Builder configuration = LocalOfficeManager.builder();
113  0 configuration.portNumbers(this.config.getServerPort());
114   
115  0 String homePath = this.config.getHomePath();
116  0 if (homePath != null) {
117  0 configuration.officeHome(homePath);
118    }
119   
120  0 String profilePath = this.config.getProfilePath();
121  0 if (profilePath != null) {
122  0 configuration.templateProfileDir(new File(profilePath));
123    }
124   
125  0 configuration.maxTasksPerProcess(this.config.getMaxTasksPerProcess());
126  0 configuration.taskExecutionTimeout(this.config.getTaskExecutionTimeout());
127   
128  0 try {
129  0 this.jodManager = configuration.build();
130    } catch (Exception e) {
131    // Protect against exceptions raised by JodManager. For example if it cannot autodetect the office home,
132    // it'll throw an java.lang.IllegalStateException exception...
133    // We wrap this in an OfficeServerException in order to display some nicer message to the user.
134  0 throw new OfficeServerException("Failed to start Office server. Reason: " + e.getMessage(), e);
135    }
136  0 } else if (this.config.getServerType() == OfficeServerConfiguration.SERVER_TYPE_EXTERNAL_LOCAL) {
137  0 ExternalOfficeManagerBuilder externalProcessOfficeManager = new ExternalOfficeManagerBuilder();
138  0 externalProcessOfficeManager.setPortNumber(this.config.getServerPort());
139  0 externalProcessOfficeManager.setConnectOnStart(true);
140  0 this.jodManager = externalProcessOfficeManager.build();
141    } else {
142  0 setState(ServerState.CONF_ERROR);
143  0 throw new OfficeServerException("Invalid office server configuration.");
144    }
145   
146  0 this.jodConverter = null;
147    // Try to use the JSON document format registry to configure the office document conversion.
148  0 InputStream input = getClass().getResourceAsStream(DOCUMENT_FORMATS_PATH);
149  0 if (input != null) {
150  0 try {
151  0 this.jodConverter = LocalConverter.builder().officeManager(this.jodManager)
152    .formatRegistry(JsonDocumentFormatRegistry.create(input))
153    .filterChain(new LinkedImagesEmbedderFilter())
154    .build();
155    } catch (Exception e) {
156  0 this.logger.warn("Failed to parse {} . The default document format registry will be used instead.",
157    DOCUMENT_FORMATS_PATH, e);
158    }
159    } else {
160  0 this.logger.debug("{} is missing. The default document format registry will be used instead.",
161    DOCUMENT_FORMATS_PATH);
162    }
163  0 if (this.jodConverter == null) {
164    // Use the default document format registry.
165  0 this.jodConverter = LocalConverter.builder().officeManager(this.jodManager)
166    .filterChain(new LinkedImagesEmbedderFilter()).build();
167    }
168   
169  0 File workDir = this.environment.getTemporaryDirectory();
170  0 this.converter = new DefaultOfficeConverter(this.jodConverter, workDir);
171    }
172   
 
173  7720 toggle @Override
174    public ServerState getState()
175    {
176  7720 return this.state;
177    }
178   
 
179  0 toggle @Override
180    public void start() throws OfficeServerException
181    {
182    // If the office server is running then stop it in order to restart the connection.
183  0 stop();
184   
185  0 initialize();
186  0 try {
187  0 this.jodManager.start();
188  0 setState(ServerState.CONNECTED);
189  0 this.logger.info("Open Office instance started.");
190    } catch (Exception e) {
191  0 setState(ServerState.ERROR);
192  0 throw new OfficeServerException("Error while connecting / starting the office server.", e);
193    }
194    }
195   
 
196  38 toggle @Override
197    public void stop() throws OfficeServerException
198    {
199    // We should try stopping the office server even if the status is not connected but we should not raise an
200    // error if there is a failure to stop.
201  38 boolean connected = checkState(ServerState.CONNECTED);
202  38 try {
203  38 this.jodManager.stop();
204  0 setState(ServerState.NOT_CONNECTED);
205  0 this.logger.info("Open Office instance stopped.");
206    } catch (Exception e) {
207  38 if (connected) {
208  0 setState(ServerState.ERROR);
209  0 throw new OfficeServerException("Error while disconnecting / shutting down the office server.", e);
210    }
211    }
212    }
213   
 
214  0 toggle @Override
215    public OfficeConverter getConverter()
216    {
217  0 return this.converter;
218    }
219   
220    /**
221    * Utility method for setting the current office manager state.
222    *
223    * @param newState new state.
224    */
 
225  217 toggle private void setState(ServerState newState)
226    {
227  217 this.state = newState;
228    }
229   
230    /**
231    * Utility method for checking the office manager state.
232    *
233    * @param expectedState expected state.
234    * @return true if office manger is in given state, false otherwise.
235    */
 
236  38 toggle private boolean checkState(ServerState expectedState)
237    {
238  38 return (this.state == expectedState);
239    }
240    }