001/* 002 * (C) Copyright 2006-2016 Nuxeo SA (http://nuxeo.com/) and others. 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 */ 019package org.nuxeo.common; 020 021import java.io.File; 022import java.net.URL; 023import java.util.Properties; 024 025import org.apache.commons.lang.StringUtils; 026import org.apache.commons.lang.builder.ToStringBuilder; 027import org.apache.commons.logging.Log; 028import org.apache.commons.logging.LogFactory; 029 030/** 031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 032 */ 033public class Environment { 034 035 private static Log logger = LogFactory.getLog(Environment.class); 036 037 /** 038 * Constants that identifies possible hosts for the framework. 039 */ 040 public static final String JBOSS_HOST = "JBoss"; 041 042 // Jetty or GF3 embedded 043 public static final String NXSERVER_HOST = "NXServer"; 044 045 public static final String TOMCAT_HOST = "Tomcat"; 046 047 public static final String NUXEO_HOME_DIR = "nuxeo.home.dir"; 048 049 /** 050 * @since 5.6 051 */ 052 public static final String NUXEO_HOME = "nuxeo.home"; 053 054 /** 055 * @since 5.4.2 056 */ 057 public static final String NUXEO_RUNTIME_HOME = "nuxeo.runtime.home"; 058 059 public static final String NUXEO_DATA_DIR = "nuxeo.data.dir"; 060 061 /** 062 * @since 5.9.4 063 */ 064 public static final String DEFAULT_DATA_DIR = "data"; 065 066 public static final String NUXEO_LOG_DIR = "nuxeo.log.dir"; 067 068 /** 069 * @since 5.9.4 070 */ 071 public static final String DEFAULT_LOG_DIR = "log"; 072 073 public static final String NUXEO_PID_DIR = "nuxeo.pid.dir"; 074 075 public static final String NUXEO_TMP_DIR = "nuxeo.tmp.dir"; 076 077 /** 078 * @since 5.9.4 079 */ 080 public static final String DEFAULT_TMP_DIR = "tmp"; 081 082 public static final String NUXEO_CONFIG_DIR = "nuxeo.config.dir"; 083 084 /** 085 * @since 5.9.4 086 */ 087 public static final String DEFAULT_CONFIG_DIR = "config"; 088 089 public static final String NUXEO_WEB_DIR = "nuxeo.web.dir"; 090 091 /** 092 * @since 5.9.4 093 */ 094 public static final String DEFAULT_WEB_DIR = "web"; 095 096 /** 097 * @since 5.9.4 098 */ 099 public static final String NUXEO_MP_DIR = "nuxeo.mp.dir"; 100 101 /** 102 * @since 5.9.4 103 */ 104 public static final String DEFAULT_MP_DIR = "packages"; 105 106 /** 107 * @since 5.6 108 */ 109 public static final String NUXEO_CONTEXT_PATH = "org.nuxeo.ecm.contextPath"; 110 111 /** 112 * The application layout (optional): directory containing nuxeo runtime osgi bundles. 113 */ 114 public static final String BUNDLES_DIR = "nuxeo.osgi.app.bundles"; 115 116 public static final String BUNDLES = "nuxeo.osgi.bundles"; 117 118 private static volatile Environment DEFAULT; 119 120 protected final File home; 121 122 protected File data; 123 124 protected File log; 125 126 protected File config; 127 128 protected File web; 129 130 protected File temp; 131 132 protected final Properties properties; 133 134 protected String[] args; 135 136 protected boolean isAppServer; 137 138 protected String hostAppName; 139 140 protected String hostAppVersion; 141 142 protected Iterable<URL> configProvider; 143 144 // Handy parameter to distinguish from (Runtime)home 145 private File serverHome = null; 146 147 // Handy parameter to distinguish from (Server)home 148 private File runtimeHome = null; 149 150 public static final String SERVER_STATUS_KEY = "server.status.key"; 151 152 public static final String DISTRIBUTION_NAME = "org.nuxeo.distribution.name"; 153 154 public static final String DISTRIBUTION_VERSION = "org.nuxeo.distribution.version"; 155 156 /** 157 * @since 7.10 158 */ 159 public static final String DISTRIBUTION_SERVER = "org.nuxeo.distribution.server"; 160 161 /** 162 * @since 7.10 163 */ 164 public static final String DISTRIBUTION_DATE = "org.nuxeo.distribution.date"; 165 166 /** 167 * @since 7.10 168 */ 169 public static final String DISTRIBUTION_PACKAGE = "org.nuxeo.distribution.package"; 170 171 /** 172 * @since 7.10 173 */ 174 public static final String PRODUCT_NAME = "org.nuxeo.ecm.product.name"; 175 176 /** 177 * @since 7.10 178 */ 179 public static final String PRODUCT_VERSION = "org.nuxeo.ecm.product.version"; 180 181 // proxy 182 /** 183 * @since 6.0 184 */ 185 public static final String NUXEO_HTTP_PROXY_HOST = "nuxeo.http.proxy.host"; 186 187 /** 188 * @since 6.0 189 */ 190 public static final String NUXEO_HTTP_PROXY_PORT = "nuxeo.http.proxy.port"; 191 192 /** 193 * @since 6.0 194 */ 195 public static final String NUXEO_HTTP_PROXY_LOGIN = "nuxeo.http.proxy.login"; 196 197 /** 198 * @since 6.0 199 */ 200 public static final String NUXEO_HTTP_PROXY_PASSWORD = "nuxeo.http.proxy.password"; 201 202 /** 203 * @since 7.4 204 */ 205 public static final String CRYPT_ALGO = "server.crypt.algorithm"; 206 207 /** 208 * @since 7.4 209 */ 210 public static final String CRYPT_KEY = "server.crypt.secretkey"; 211 212 /** 213 * @since 7.4 214 */ 215 public static final String CRYPT_KEYALIAS = "server.crypt.keyalias"; 216 217 /** 218 * @since 7.4 219 */ 220 public static final String CRYPT_KEYSTORE_PATH = "server.crypt.keystore.path"; 221 222 /** 223 * @since 7.4 224 */ 225 public static final String CRYPT_KEYSTORE_PASS = "server.crypt.keystore.pass"; 226 227 /** 228 * @since 7.4 229 */ 230 public static final String JAVA_DEFAULT_KEYSTORE = "javax.net.ssl.keyStore"; 231 232 /** 233 * @since 7.4 234 */ 235 public static final String JAVA_DEFAULT_KEYSTORE_PASS = "javax.net.ssl.keyStorePassword"; 236 237 /** 238 * Call to that constructor should be followed by a call to {@link #init()}. Depending on the available System 239 * properties, you may want to also call {@link #loadProperties(Properties)} or {@link #setServerHome(File)} methods 240 * before {@link #init()}; here is the recommended order: 241 * 242 * <pre> 243 * Environment env = new Environment(home); 244 * Environment.setDefault(env); 245 * env.loadProperties(properties); 246 * env.setServerHome(home); 247 * env.init(); 248 * </pre> 249 * 250 * @param home Root path used for most defaults. It is recommended to make it match the server home rather than the 251 * runtime home. 252 * @see #init() 253 */ 254 public Environment(File home) { 255 this(home, null); 256 } 257 258 /** 259 * Call to that constructor should be followed by a call to {@link #init()}. Depending on the available System 260 * properties, you may want to also call {@link #setServerHome(File)} method before {@link #init()}; here is the 261 * recommended order: 262 * 263 * <pre> 264 * Environment env = new Environment(home, properties); 265 * Environment.setDefault(env); 266 * env.setServerHome(home); 267 * env.init(); 268 * </pre> 269 * 270 * @param home Root path used for most defaults. It is recommended to make it match the server home rather than the 271 * runtime home. 272 * @param properties Source properties for initialization. It is used as an {@code Hashtable}: ie only the custom 273 * values are read, the properties default values are ignored if any. 274 * @see #init() 275 */ 276 public Environment(File home, Properties properties) { 277 this.home = home.getAbsoluteFile(); 278 this.properties = new Properties(); 279 if (properties != null) { 280 loadProperties(properties); 281 } 282 } 283 284 public static synchronized void setDefault(Environment env) { 285 DEFAULT = env; 286 } 287 288 public static Environment getDefault() { 289 if (DEFAULT == null) { 290 tryInitEnvironment(); 291 } 292 return DEFAULT; 293 } 294 295 private static synchronized void tryInitEnvironment() { 296 String homeDir = System.getProperty(NUXEO_HOME); 297 if (homeDir != null) { 298 File home = new File(homeDir); 299 if (home.isDirectory()) { 300 DEFAULT = new Environment(home); 301 DEFAULT.init(); 302 } 303 } 304 } 305 306 public File getHome() { 307 return home; 308 } 309 310 public boolean isApplicationServer() { 311 return isAppServer; 312 } 313 314 public void setIsApplicationServer(boolean isAppServer) { 315 this.isAppServer = isAppServer; 316 } 317 318 public String getHostApplicationName() { 319 return hostAppName; 320 } 321 322 public String getHostApplicationVersion() { 323 return hostAppVersion; 324 } 325 326 public void setHostApplicationName(String name) { 327 hostAppName = name; 328 } 329 330 public void setHostApplicationVersion(String version) { 331 hostAppVersion = version; 332 } 333 334 public File getTemp() { 335 if (temp == null) { 336 setTemp(properties.getProperty(NUXEO_TMP_DIR, DEFAULT_TMP_DIR)); 337 } 338 return temp; 339 } 340 341 /** 342 * Resolve the path against {@link Environment#serverHome} if not absolute. 343 * 344 * @since 8.1 345 */ 346 public void setTemp(String temp) { 347 setTemp(getServerHome().toPath().resolve(temp).toFile()); 348 } 349 350 public void setTemp(File temp) { 351 this.temp = temp.getAbsoluteFile(); 352 setProperty(NUXEO_TMP_DIR, temp.getAbsolutePath()); 353 temp.mkdirs(); 354 } 355 356 public File getConfig() { 357 if (config == null) { 358 setConfig(properties.getProperty(NUXEO_CONFIG_DIR, DEFAULT_CONFIG_DIR)); 359 } 360 return config; 361 } 362 363 /** 364 * Resolve the path against {@link Environment#runtimeHome} if not absolute. 365 * 366 * @since 8.1 367 */ 368 public void setConfig(String config) { 369 File configFile = getRuntimeHome().toPath().resolve(config).toFile(); 370 setConfig(configFile); 371 } 372 373 public void setConfig(File config) { 374 this.config = config.getAbsoluteFile(); 375 setProperty(NUXEO_CONFIG_DIR, config.getAbsolutePath()); 376 config.mkdirs(); 377 } 378 379 public File getLog() { 380 if (log == null) { 381 setLog(properties.getProperty(NUXEO_LOG_DIR, DEFAULT_LOG_DIR)); 382 } 383 return log; 384 } 385 386 /** 387 * Resolve the path against {@link Environment#serverHome} if not absolute. 388 * 389 * @since 8.1 390 */ 391 public void setLog(String log) { 392 setLog(getServerHome().toPath().resolve(log).toFile()); 393 } 394 395 public void setLog(File log) { 396 this.log = log.getAbsoluteFile(); 397 setProperty(NUXEO_LOG_DIR, log.getAbsolutePath()); 398 log.mkdirs(); 399 } 400 401 public File getData() { 402 if (data == null) { 403 setData(properties.getProperty(NUXEO_DATA_DIR, DEFAULT_DATA_DIR)); 404 } 405 return data; 406 } 407 408 /** 409 * Resolve the path against {@link Environment#runtimeHome} if not absolute. 410 * 411 * @since 8.1 412 */ 413 public void setData(String data) { 414 setData(getRuntimeHome().toPath().resolve(data).toFile()); 415 } 416 417 public void setData(File data) { 418 this.data = data.getAbsoluteFile(); 419 setProperty(NUXEO_DATA_DIR, data.getAbsolutePath()); 420 data.mkdirs(); 421 } 422 423 public File getWeb() { 424 if (web == null) { 425 setWeb(properties.getProperty(NUXEO_WEB_DIR, DEFAULT_WEB_DIR)); 426 } 427 return web; 428 } 429 430 /** 431 * Resolve the path against {@link Environment#runtimeHome} if not absolute. 432 * 433 * @since 8.1 434 */ 435 public void setWeb(String web) { 436 setWeb(getRuntimeHome().toPath().resolve(web).toFile()); 437 } 438 439 public void setWeb(File web) { 440 this.web = web; 441 setProperty(NUXEO_WEB_DIR, web.getAbsolutePath()); 442 } 443 444 /** 445 * @since 5.4.2 446 */ 447 public File getRuntimeHome() { 448 initRuntimeHome(); 449 return runtimeHome; 450 } 451 452 /** 453 * @since 5.4.2 454 */ 455 public void setRuntimeHome(File runtimeHome) { 456 this.runtimeHome = runtimeHome.getAbsoluteFile(); 457 setProperty(NUXEO_RUNTIME_HOME, runtimeHome.getAbsolutePath()); 458 } 459 460 public String[] getCommandLineArguments() { 461 return args; 462 } 463 464 public void setCommandLineArguments(String[] args) { 465 this.args = args; 466 } 467 468 public String getProperty(String key) { 469 return properties.getProperty(key); 470 } 471 472 public String getProperty(String key, String defaultValue) { 473 String val = properties.getProperty(key); 474 return val == null ? defaultValue : val; 475 } 476 477 /** 478 * If setting a path property, consider using {@link #setPath(String, String)} 479 */ 480 public void setProperty(String key, String value) { 481 properties.setProperty(key, value); 482 } 483 484 public Properties getProperties() { 485 return properties; 486 } 487 488 public void loadProperties(Properties props) { 489 properties.putAll(props); 490 } 491 492 public boolean isJBoss() { 493 return JBOSS_HOST.equals(hostAppName); 494 } 495 496 public boolean isJetty() { 497 return NXSERVER_HOST.equals(hostAppName); 498 } 499 500 public boolean isTomcat() { 501 return TOMCAT_HOST.equals(hostAppName); 502 } 503 504 /** 505 * Initialization with System properties to avoid issues due to home set with runtime home instead of server home. 506 * If {@link #NUXEO_HOME} System property is not set, or if you want to set a custom server home, then you should 507 * call {@link #setServerHome(File)} before. 508 * 509 * @since 5.4.1 510 */ 511 public void init() { 512 initServerHome(); 513 initRuntimeHome(); 514 515 String dataDir = System.getProperty(NUXEO_DATA_DIR); 516 if (StringUtils.isNotEmpty(dataDir)) { 517 setData(new File(dataDir)); 518 } 519 520 String configDir = System.getProperty(NUXEO_CONFIG_DIR); 521 if (StringUtils.isNotEmpty(configDir)) { 522 setConfig(new File(configDir)); 523 } 524 525 String logDir = System.getProperty(NUXEO_LOG_DIR); 526 if (StringUtils.isNotEmpty(logDir)) { 527 setLog(new File(logDir)); 528 } 529 530 String tmpDir = System.getProperty(NUXEO_TMP_DIR); 531 if (StringUtils.isNotEmpty(tmpDir)) { 532 setTemp(new File(tmpDir)); 533 } 534 535 String mpDir = System.getProperty(NUXEO_MP_DIR); 536 setPath(NUXEO_MP_DIR, StringUtils.isNotEmpty(mpDir) ? mpDir : DEFAULT_MP_DIR, getServerHome()); 537 } 538 539 private void initRuntimeHome() { 540 if (runtimeHome != null) { 541 return; 542 } 543 String runtimeDir = System.getProperty(NUXEO_RUNTIME_HOME); 544 if (runtimeDir != null && !runtimeDir.isEmpty()) { 545 setRuntimeHome(new File(runtimeDir)); 546 } else { 547 setRuntimeHome(home); 548 } 549 } 550 551 /** 552 * This method always returns the server home (or {@link #getHome()} if {@link #NUXEO_HOME_DIR} is not set). 553 * 554 * @since 5.4.2 555 * @return Server home 556 */ 557 public File getServerHome() { 558 initServerHome(); 559 return serverHome; 560 } 561 562 /** 563 * @since 5.4.2 564 */ 565 public void setServerHome(File serverHome) { 566 this.serverHome = serverHome.getAbsoluteFile(); 567 setProperty(NUXEO_HOME_DIR, serverHome.getAbsolutePath()); 568 } 569 570 private void initServerHome() { 571 if (serverHome != null) { 572 return; 573 } 574 String homeDir = System.getProperty(NUXEO_HOME, System.getProperty(NUXEO_HOME_DIR)); 575 if (homeDir != null && !homeDir.isEmpty()) { 576 setServerHome(new File(homeDir)); 577 } else { 578 logger.warn(String.format("Could not set the server home from %s or %s system properties, will use %s", 579 NUXEO_HOME, NUXEO_HOME_DIR, home)); 580 setServerHome(home); 581 } 582 logger.debug(this); 583 } 584 585 public void setConfigurationProvider(Iterable<URL> configProvider) { 586 this.configProvider = configProvider; 587 } 588 589 public Iterable<URL> getConfigurationProvider() { 590 return configProvider; 591 } 592 593 @Override 594 public String toString() { 595 return ToStringBuilder.reflectionToString(this); 596 } 597 598 /** 599 * Add a file path as a property 600 * 601 * @param key Property key 602 * @param value Property value: an absolute or relative file 603 * @param baseDir The directory against which the file will be resolved if not absolute 604 * @since 8.1 605 * @see #setProperty(String, String) 606 * @see #setPath(String, String, File) 607 * @see #setPath(String, File) 608 */ 609 public void setPath(String key, File value, File baseDir) { 610 setProperty(key, baseDir.toPath().resolve(value.toPath()).toFile().getAbsolutePath()); 611 } 612 613 /** 614 * Add a file path as a property 615 * 616 * @param key Property key 617 * @param value Property value: an absolute or relative file path 618 * @param baseDir The directory against which the file will be resolved if not absolute 619 * @since 8.1 620 * @see #setProperty(String, String) 621 * @see #setPath(String, File, File) 622 * @see #setPath(String, File) 623 */ 624 public void setPath(String key, String value, File baseDir) { 625 setProperty(key, baseDir.toPath().resolve(value).toFile().getAbsolutePath()); 626 } 627 628 /** 629 * Add a file path as a property 630 * 631 * @param key Property key 632 * @param value Property value: an absolute or relative file; if relative, it will be resolved against {@link #home} 633 * @since 8.1 634 * @see #setProperty(String, String) 635 * @see #setPath(String, File, File) 636 */ 637 public void setPath(String key, File value) { 638 setPath(key, value, home); 639 } 640 641 /** 642 * Add a file path as a property 643 * 644 * @param key Property key 645 * @param value Property value: an absolute or relative file path; if relative, it will be resolved against 646 * {@link #home} 647 * @since 8.1 648 * @see #setProperty(String, String) 649 * @see #setPath(String, String, File) 650 */ 651 public void setPath(String key, String value) { 652 setPath(key, value, home); 653 } 654 655 /** 656 * @return the file which path is associated with the given key. The file is guaranteed to be absolute if it has 657 * been set with {@link #setPath(String, File)} 658 * @since 8.1 659 */ 660 public File getPath(String key) { 661 return getPath(key, null); 662 } 663 664 /** 665 * @param key the property key 666 * @param defaultValue the default path, absolute or relative to server home 667 * @return the file which path is associated with the given key. The file is guaranteed to be absolute if it has 668 * been set with {@link #setPath(String, File)} 669 * @since 8.1 670 */ 671 public File getPath(String key, String defaultValue) { 672 String path = properties.getProperty(key); 673 if (path != null) { 674 return new File(path); 675 } else if (defaultValue != null) { 676 return getServerHome().toPath().resolve(defaultValue).toFile(); 677 } 678 return null; 679 } 680}