001/*
002 * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu, jcarsique
018 */
019
020package org.nuxeo.common;
021
022import java.io.File;
023import java.net.URL;
024import java.util.Properties;
025
026import org.apache.commons.lang.StringUtils;
027import org.apache.commons.lang.builder.ToStringBuilder;
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030
031/**
032 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
033 */
034public class Environment {
035
036    private static Log logger = LogFactory.getLog(Environment.class);
037
038    /**
039     * Constants that identifies possible hosts for the framework.
040     */
041    public static final String JBOSS_HOST = "JBoss";
042
043    // Jetty or GF3 embedded
044    public static final String NXSERVER_HOST = "NXServer";
045
046    public static final String TOMCAT_HOST = "Tomcat";
047
048    public static final String NUXEO_HOME_DIR = "nuxeo.home.dir";
049
050    /**
051     * @since 5.6
052     */
053    public static final String NUXEO_HOME = "nuxeo.home";
054
055    /**
056     * @since 5.4.2
057     */
058    public static final String NUXEO_RUNTIME_HOME = "nuxeo.runtime.home";
059
060    public static final String NUXEO_DATA_DIR = "nuxeo.data.dir";
061
062    /**
063     * @since 5.9.4
064     */
065    public static final String DEFAULT_DATA_DIR = "data";
066
067    public static final String NUXEO_LOG_DIR = "nuxeo.log.dir";
068
069    /**
070     * @since 5.9.4
071     */
072    public static final String DEFAULT_LOG_DIR = "log";
073
074    public static final String NUXEO_PID_DIR = "nuxeo.pid.dir";
075
076    public static final String NUXEO_TMP_DIR = "nuxeo.tmp.dir";
077
078    /**
079     * @since 5.9.4
080     */
081    public static final String DEFAULT_TMP_DIR = "tmp";
082
083    public static final String NUXEO_CONFIG_DIR = "nuxeo.config.dir";
084
085    /**
086     * @since 5.9.4
087     */
088    public static final String DEFAULT_CONFIG_DIR = "config";
089
090    public static final String NUXEO_WEB_DIR = "nuxeo.web.dir";
091
092    /**
093     * @since 5.9.4
094     */
095    public static final String DEFAULT_WEB_DIR = "web";
096
097    /**
098     * @since 5.9.4
099     */
100    public static final String NUXEO_MP_DIR = "nuxeo.mp.dir";
101
102    /**
103     * @since 5.9.4
104     */
105    public static final String DEFAULT_MP_DIR = "packages";
106
107    /**
108     * @since 5.6
109     */
110    public static final String NUXEO_CONTEXT_PATH = "org.nuxeo.ecm.contextPath";
111
112    /**
113     * The home directory.
114     *
115     * @deprecated never defined; use {@link #NUXEO_HOME_DIR}
116     */
117    @Deprecated
118    public static final String HOME_DIR = "org.nuxeo.app.home";
119
120    /**
121     * The web root.
122     *
123     * @deprecated never defined; use {@link #NUXEO_WEB_DIR}
124     */
125    @Deprecated
126    public static final String WEB_DIR = "org.nuxeo.app.web";
127
128    /**
129     * The config directory.
130     *
131     * @deprecated never defined; use {@link #NUXEO_CONFIG_DIR}
132     */
133    @Deprecated
134    public static final String CONFIG_DIR = "org.nuxeo.app.config";
135
136    /**
137     * The data directory.
138     *
139     * @deprecated never defined; use {@link #NUXEO_DATA_DIR}
140     */
141    @Deprecated
142    public static final String DATA_DIR = "org.nuxeo.app.data";
143
144    /**
145     * The log directory.
146     *
147     * @deprecated never defined; use {@link #NUXEO_LOG_DIR}
148     */
149    @Deprecated
150    public static final String LOG_DIR = "org.nuxeo.app.log";
151
152    /**
153     * The application layout (optional): directory containing nuxeo runtime osgi bundles.
154     */
155    public static final String BUNDLES_DIR = "nuxeo.osgi.app.bundles";
156
157    public static final String BUNDLES = "nuxeo.osgi.bundles";
158
159    private static volatile Environment DEFAULT;
160
161    protected final File home;
162
163    protected File data;
164
165    protected File log;
166
167    protected File config;
168
169    protected File web;
170
171    protected File temp;
172
173    protected final Properties properties;
174
175    protected String[] args;
176
177    protected boolean isAppServer;
178
179    protected String hostAppName;
180
181    protected String hostAppVersion;
182
183    protected Iterable<URL> configProvider;
184
185    // Handy parameter to distinguish from (Runtime)home
186    private File serverHome = null;
187
188    // Handy parameter to distinguish from (Server)home
189    private File runtimeHome;
190
191    public static final String SERVER_STATUS_KEY = "server.status.key";
192
193    public static final String DISTRIBUTION_NAME = "org.nuxeo.distribution.name";
194
195    public static final String DISTRIBUTION_VERSION = "org.nuxeo.distribution.version";
196
197    // proxy
198    /**
199     * @since 6.0
200     */
201    public static final String NUXEO_HTTP_PROXY_HOST = "nuxeo.http.proxy.host";
202
203    /**
204     * @since 6.0
205     */
206    public static final String NUXEO_HTTP_PROXY_PORT = "nuxeo.http.proxy.port";
207
208    /**
209     * @since 6.0
210     */
211    public static final String NUXEO_HTTP_PROXY_LOGIN = "nuxeo.http.proxy.login";
212
213    /**
214     * @since 6.0
215     */
216    public static final String NUXEO_HTTP_PROXY_PASSWORD = "nuxeo.http.proxy.password";
217
218    /**
219     * @since 7.4
220     */
221    public static final String CRYPT_ALGO = "server.crypt.algorithm";
222
223    /**
224     * @since 7.4
225     */
226    public static final String CRYPT_KEY = "server.crypt.secretkey";
227
228    /**
229     * @since 7.4
230     */
231    public static final String CRYPT_KEYALIAS = "server.crypt.keyalias";
232
233    /**
234     * @since 7.4
235     */
236    public static final String CRYPT_KEYSTORE_PATH = "server.crypt.keystore.path";
237
238    /**
239     * @since 7.4
240     */
241    public static final String CRYPT_KEYSTORE_PASS = "server.crypt.keystore.pass";
242
243    /**
244     * @since 7.4
245     */
246    public static final String JAVA_DEFAULT_KEYSTORE = "javax.net.ssl.keyStore";
247
248    /**
249     * @since 7.4
250     */
251    public static final String JAVA_DEFAULT_KEYSTORE_PASS = "javax.net.ssl.keyStorePassword";
252
253    public Environment(File home) {
254        this(home, null);
255    }
256
257    public Environment(File home, Properties properties) {
258        this.home = home;
259        this.properties = new Properties();
260        if (properties != null) {
261            loadProperties(properties);
262        }
263        this.properties.put(HOME_DIR, this.home.getAbsolutePath());
264    }
265
266    public static synchronized void setDefault(Environment env) {
267        DEFAULT = env;
268    }
269
270    public static Environment getDefault() {
271        if (DEFAULT == null) {
272            tryInitEnvironment();
273        }
274        return DEFAULT;
275    }
276
277    private static synchronized void tryInitEnvironment() {
278        String homeDir = System.getProperty(NUXEO_HOME);
279        if (homeDir != null) {
280            File home = new File(homeDir);
281            if (home.isDirectory()) {
282                DEFAULT = new Environment(home);
283            }
284        }
285    }
286
287    public File getHome() {
288        return home;
289    }
290
291    public boolean isApplicationServer() {
292        return isAppServer;
293    }
294
295    public void setIsApplicationServer(boolean isAppServer) {
296        this.isAppServer = isAppServer;
297    }
298
299    public String getHostApplicationName() {
300        return hostAppName;
301    }
302
303    public String getHostApplicationVersion() {
304        return hostAppVersion;
305    }
306
307    public void setHostApplicationName(String name) {
308        hostAppName = name;
309    }
310
311    public void setHostApplicationVersion(String version) {
312        hostAppVersion = version;
313    }
314
315    public File getTemp() {
316        if (temp == null) {
317            temp = new File(home, DEFAULT_TMP_DIR);
318        }
319        return temp;
320    }
321
322    public void setTemp(File temp) {
323        this.temp = temp;
324        properties.put(NUXEO_TMP_DIR, temp.getAbsolutePath());
325    }
326
327    public File getConfig() {
328        if (config == null) {
329            config = new File(home, DEFAULT_CONFIG_DIR);
330        }
331        return config;
332    }
333
334    public void setConfig(File config) {
335        this.config = config;
336        properties.put(NUXEO_CONFIG_DIR, config.getAbsolutePath());
337    }
338
339    public File getLog() {
340        if (log == null) {
341            log = new File(home, DEFAULT_LOG_DIR);
342        }
343        return log;
344    }
345
346    public void setLog(File log) {
347        this.log = log;
348        properties.put(NUXEO_LOG_DIR, log.getAbsolutePath());
349    }
350
351    public File getData() {
352        if (data == null) {
353            data = new File(home, DEFAULT_DATA_DIR);
354        }
355        return data;
356    }
357
358    public void setData(File data) {
359        this.data = data;
360        properties.put(NUXEO_DATA_DIR, data.getAbsolutePath());
361    }
362
363    public File getWeb() {
364        if (web == null) {
365            web = new File(home, DEFAULT_WEB_DIR);
366        }
367        return web;
368    }
369
370    public void setWeb(File web) {
371        this.web = web;
372        properties.put(NUXEO_WEB_DIR, web.getAbsolutePath());
373    }
374
375    /**
376     * @since 5.4.2
377     */
378    public File getRuntimeHome() {
379        if (runtimeHome == null) {
380            initRuntimeHome();
381        }
382        return runtimeHome;
383    }
384
385    /**
386     * @since 5.4.2
387     */
388    public void setRuntimeHome(File runtimeHome) {
389        this.runtimeHome = runtimeHome;
390        properties.put(NUXEO_RUNTIME_HOME, runtimeHome.getAbsolutePath());
391    }
392
393    public String[] getCommandLineArguments() {
394        return args;
395    }
396
397    public void setCommandLineArguments(String[] args) {
398        this.args = args;
399    }
400
401    public String getProperty(String key) {
402        return properties.getProperty(key);
403    }
404
405    public String getProperty(String key, String defaultValue) {
406        String val = properties.getProperty(key);
407        return val == null ? defaultValue : val;
408    }
409
410    public void setProperty(String key, String value) {
411        properties.put(key, value);
412    }
413
414    public Properties getProperties() {
415        return properties;
416    }
417
418    public void loadProperties(Properties props) {
419        properties.putAll(props);
420    }
421
422    public boolean isJBoss() {
423        return JBOSS_HOST.equals(hostAppName);
424    }
425
426    public boolean isJetty() {
427        return NXSERVER_HOST.equals(hostAppName);
428    }
429
430    public boolean isTomcat() {
431        return TOMCAT_HOST.equals(hostAppName);
432    }
433
434    /**
435     * Initialization with System properties to avoid issues due to home set with runtime home instead of server home.
436     *
437     * @since 5.4.1
438     */
439    public void init() {
440        String dataDir = System.getProperty(NUXEO_DATA_DIR);
441        String configDir = System.getProperty(NUXEO_CONFIG_DIR);
442        String logDir = System.getProperty(NUXEO_LOG_DIR);
443        String tmpDir = System.getProperty(NUXEO_TMP_DIR);
444        String mpDir = System.getProperty(NUXEO_MP_DIR);
445
446        initServerHome();
447        initRuntimeHome();
448        if (StringUtils.isNotEmpty(dataDir)) {
449            setData(new File(dataDir));
450        }
451        if (StringUtils.isNotEmpty(configDir)) {
452            setConfig(new File(configDir));
453        }
454        if (StringUtils.isNotEmpty(logDir)) {
455            setLog(new File(logDir));
456        }
457        if (StringUtils.isNotEmpty(tmpDir)) {
458            setTemp(new File(tmpDir));
459        }
460        if (StringUtils.isNotEmpty(mpDir)) {
461            properties.put(NUXEO_MP_DIR, mpDir);
462        }
463    }
464
465    private void initRuntimeHome() {
466        String runtimeDir = System.getProperty(NUXEO_RUNTIME_HOME);
467        if (runtimeDir != null && !runtimeDir.isEmpty()) {
468            runtimeHome = new File(runtimeDir);
469        } else {
470            runtimeHome = home;
471        }
472    }
473
474    /**
475     * This method always returns the server home (or null if {@link #NUXEO_HOME_DIR} is not set), whereas
476     * {@link #getHome()} may return runtime home.
477     *
478     * @since 5.4.2
479     * @return Server home
480     */
481    public File getServerHome() {
482        if (serverHome == null) {
483            initServerHome();
484        }
485        return serverHome;
486    }
487
488    /**
489     * @since 5.4.2
490     */
491    public void setServerHome(File serverHome) {
492        this.serverHome = serverHome;
493        properties.put(NUXEO_HOME_DIR, serverHome.getAbsolutePath());
494    }
495
496    private void initServerHome() {
497        String homeDir = System.getProperty(NUXEO_HOME, System.getProperty(NUXEO_HOME_DIR));
498        if (homeDir != null && !homeDir.isEmpty()) {
499            serverHome = new File(homeDir);
500        } else {
501            logger.warn(String.format("Could not get %s neither %s system properties, will use %s", NUXEO_HOME,
502                    NUXEO_HOME_DIR, home));
503            serverHome = home;
504        }
505        logger.debug(this);
506    }
507
508    public void setConfigurationProvider(Iterable<URL> configProvider) {
509        this.configProvider = configProvider;
510    }
511
512    public Iterable<URL> getConfigurationProvider() {
513        return configProvider;
514    }
515
516    @Override
517    public String toString() {
518        return ToStringBuilder.reflectionToString(this);
519    }
520}