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 */ 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 = null; 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 /** 198 * @since 7.10 199 */ 200 public static final String DISTRIBUTION_SERVER = "org.nuxeo.distribution.server"; 201 202 /** 203 * @since 7.10 204 */ 205 public static final String DISTRIBUTION_DATE = "org.nuxeo.distribution.date"; 206 207 /** 208 * @since 7.10 209 */ 210 public static final String DISTRIBUTION_PACKAGE = "org.nuxeo.distribution.package"; 211 212 /** 213 * @since 7.10 214 */ 215 public static final String PRODUCT_NAME = "org.nuxeo.ecm.product.name"; 216 217 /** 218 * @since 7.10 219 */ 220 public static final String PRODUCT_VERSION = "org.nuxeo.ecm.product.version"; 221 222 // proxy 223 /** 224 * @since 6.0 225 */ 226 public static final String NUXEO_HTTP_PROXY_HOST = "nuxeo.http.proxy.host"; 227 228 /** 229 * @since 6.0 230 */ 231 public static final String NUXEO_HTTP_PROXY_PORT = "nuxeo.http.proxy.port"; 232 233 /** 234 * @since 6.0 235 */ 236 public static final String NUXEO_HTTP_PROXY_LOGIN = "nuxeo.http.proxy.login"; 237 238 /** 239 * @since 6.0 240 */ 241 public static final String NUXEO_HTTP_PROXY_PASSWORD = "nuxeo.http.proxy.password"; 242 243 /** 244 * @since 7.4 245 */ 246 public static final String CRYPT_ALGO = "server.crypt.algorithm"; 247 248 /** 249 * @since 7.4 250 */ 251 public static final String CRYPT_KEY = "server.crypt.secretkey"; 252 253 /** 254 * @since 7.4 255 */ 256 public static final String CRYPT_KEYALIAS = "server.crypt.keyalias"; 257 258 /** 259 * @since 7.4 260 */ 261 public static final String CRYPT_KEYSTORE_PATH = "server.crypt.keystore.path"; 262 263 /** 264 * @since 7.4 265 */ 266 public static final String CRYPT_KEYSTORE_PASS = "server.crypt.keystore.pass"; 267 268 /** 269 * @since 7.4 270 */ 271 public static final String JAVA_DEFAULT_KEYSTORE = "javax.net.ssl.keyStore"; 272 273 /** 274 * @since 7.4 275 */ 276 public static final String JAVA_DEFAULT_KEYSTORE_PASS = "javax.net.ssl.keyStorePassword"; 277 278 /** 279 * Call to that constructor should be followed by a call to {@link #init()}. Depending on the available System 280 * properties, you may want to also call {@link #loadProperties(Properties)} or {@link #setServerHome(File)} methods 281 * before {@link #init()}; here is the recommended order: 282 * 283 * <pre> 284 * Environment env = new Environment(home); 285 * Environment.setDefault(env); 286 * env.loadProperties(properties); 287 * env.setServerHome(home); 288 * env.init(); 289 * </pre> 290 * 291 * @param home Root path used for most defaults. It is recommended to make it match the server home rather than the 292 * runtime home. 293 * @see #init() 294 */ 295 public Environment(File home) { 296 this(home, null); 297 } 298 299 /** 300 * Call to that constructor should be followed by a call to {@link #init()}. Depending on the available System 301 * properties, you may want to also call {@link #setServerHome(File)} method before {@link #init()}; here is the 302 * recommended order: 303 * 304 * <pre> 305 * Environment env = new Environment(home, properties); 306 * Environment.setDefault(env); 307 * env.setServerHome(home); 308 * env.init(); 309 * </pre> 310 * 311 * @param home Root path used for most defaults. It is recommended to make it match the server home rather than the 312 * runtime home. 313 * @param properties Source properties for initialization. It is used as an {@code Hashtable}: ie only the custom 314 * values are read, the properties default values are ignored if any. 315 * @see #init() 316 */ 317 public Environment(File home, Properties properties) { 318 this.home = home.getAbsoluteFile(); 319 this.properties = new Properties(); 320 if (properties != null) { 321 loadProperties(properties); 322 } 323 this.properties.setProperty(HOME_DIR, this.home.getAbsolutePath()); 324 } 325 326 public static synchronized void setDefault(Environment env) { 327 DEFAULT = env; 328 } 329 330 public static Environment getDefault() { 331 if (DEFAULT == null) { 332 tryInitEnvironment(); 333 } 334 return DEFAULT; 335 } 336 337 private static synchronized void tryInitEnvironment() { 338 String homeDir = System.getProperty(NUXEO_HOME); 339 if (homeDir != null) { 340 File home = new File(homeDir); 341 if (home.isDirectory()) { 342 DEFAULT = new Environment(home); 343 DEFAULT.init(); 344 } 345 } 346 } 347 348 public File getHome() { 349 return home; 350 } 351 352 public boolean isApplicationServer() { 353 return isAppServer; 354 } 355 356 public void setIsApplicationServer(boolean isAppServer) { 357 this.isAppServer = isAppServer; 358 } 359 360 public String getHostApplicationName() { 361 return hostAppName; 362 } 363 364 public String getHostApplicationVersion() { 365 return hostAppVersion; 366 } 367 368 public void setHostApplicationName(String name) { 369 hostAppName = name; 370 } 371 372 public void setHostApplicationVersion(String version) { 373 hostAppVersion = version; 374 } 375 376 public File getTemp() { 377 if (temp == null) { 378 setTemp(properties.getProperty(NUXEO_TMP_DIR, DEFAULT_TMP_DIR)); 379 } 380 return temp; 381 } 382 383 /** 384 * Resolve the path against {@link Environment#serverHome} if not absolute. 385 * 386 * @param temp 387 * @since 8.1 388 */ 389 public void setTemp(String temp) { 390 setTemp(getServerHome().toPath().resolve(temp).toFile()); 391 } 392 393 public void setTemp(File temp) { 394 this.temp = temp.getAbsoluteFile(); 395 setProperty(NUXEO_TMP_DIR, temp.getAbsolutePath()); 396 temp.mkdirs(); 397 } 398 399 public File getConfig() { 400 if (config == null) { 401 setConfig(properties.getProperty(NUXEO_CONFIG_DIR, DEFAULT_CONFIG_DIR)); 402 } 403 return config; 404 } 405 406 /** 407 * Resolve the path against {@link Environment#runtimeHome} if not absolute. 408 * 409 * @param config 410 * @since 8.1 411 */ 412 public void setConfig(String config) { 413 File configFile = getRuntimeHome().toPath().resolve(config).toFile(); 414 setConfig(configFile); 415 } 416 417 public void setConfig(File config) { 418 this.config = config.getAbsoluteFile(); 419 setProperty(NUXEO_CONFIG_DIR, config.getAbsolutePath()); 420 config.mkdirs(); 421 } 422 423 public File getLog() { 424 if (log == null) { 425 setLog(properties.getProperty(NUXEO_LOG_DIR, DEFAULT_LOG_DIR)); 426 } 427 return log; 428 } 429 430 /** 431 * Resolve the path against {@link Environment#serverHome} if not absolute. 432 * 433 * @param log 434 * @since 8.1 435 */ 436 public void setLog(String log) { 437 setLog(getServerHome().toPath().resolve(log).toFile()); 438 } 439 440 public void setLog(File log) { 441 this.log = log.getAbsoluteFile(); 442 setProperty(NUXEO_LOG_DIR, log.getAbsolutePath()); 443 log.mkdirs(); 444 } 445 446 public File getData() { 447 if (data == null) { 448 setData(properties.getProperty(NUXEO_DATA_DIR, DEFAULT_DATA_DIR)); 449 } 450 return data; 451 } 452 453 /** 454 * Resolve the path against {@link Environment#runtimeHome} if not absolute. 455 * 456 * @param data 457 * @since 8.1 458 */ 459 public void setData(String data) { 460 setData(getRuntimeHome().toPath().resolve(data).toFile()); 461 } 462 463 public void setData(File data) { 464 this.data = data.getAbsoluteFile(); 465 setProperty(NUXEO_DATA_DIR, data.getAbsolutePath()); 466 data.mkdirs(); 467 } 468 469 public File getWeb() { 470 if (web == null) { 471 setWeb(properties.getProperty(NUXEO_WEB_DIR, DEFAULT_WEB_DIR)); 472 } 473 return web; 474 } 475 476 /** 477 * Resolve the path against {@link Environment#runtimeHome} if not absolute. 478 * 479 * @param web 480 * @since 8.1 481 */ 482 public void setWeb(String web) { 483 setWeb(getRuntimeHome().toPath().resolve(web).toFile()); 484 } 485 486 public void setWeb(File web) { 487 this.web = web; 488 setProperty(NUXEO_WEB_DIR, web.getAbsolutePath()); 489 } 490 491 /** 492 * @since 5.4.2 493 */ 494 public File getRuntimeHome() { 495 initRuntimeHome(); 496 return runtimeHome; 497 } 498 499 /** 500 * @since 5.4.2 501 */ 502 public void setRuntimeHome(File runtimeHome) { 503 this.runtimeHome = runtimeHome.getAbsoluteFile(); 504 setProperty(NUXEO_RUNTIME_HOME, runtimeHome.getAbsolutePath()); 505 } 506 507 public String[] getCommandLineArguments() { 508 return args; 509 } 510 511 public void setCommandLineArguments(String[] args) { 512 this.args = args; 513 } 514 515 public String getProperty(String key) { 516 return properties.getProperty(key); 517 } 518 519 public String getProperty(String key, String defaultValue) { 520 String val = properties.getProperty(key); 521 return val == null ? defaultValue : val; 522 } 523 524 /** 525 * If setting a path property, consider using {@link #setPath(String, String)} 526 */ 527 public void setProperty(String key, String value) { 528 properties.setProperty(key, value); 529 } 530 531 public Properties getProperties() { 532 return properties; 533 } 534 535 public void loadProperties(Properties props) { 536 properties.putAll(props); 537 } 538 539 public boolean isJBoss() { 540 return JBOSS_HOST.equals(hostAppName); 541 } 542 543 public boolean isJetty() { 544 return NXSERVER_HOST.equals(hostAppName); 545 } 546 547 public boolean isTomcat() { 548 return TOMCAT_HOST.equals(hostAppName); 549 } 550 551 /** 552 * Initialization with System properties to avoid issues due to home set with runtime home instead of server home. 553 * If {@link #NUXEO_HOME} System property is not set, or if you want to set a custom server home, then you should 554 * call {@link #setServerHome(File)} before. 555 * 556 * @since 5.4.1 557 */ 558 public void init() { 559 initServerHome(); 560 initRuntimeHome(); 561 562 String dataDir = System.getProperty(NUXEO_DATA_DIR); 563 if (StringUtils.isNotEmpty(dataDir)) { 564 setData(new File(dataDir)); 565 } 566 567 String configDir = System.getProperty(NUXEO_CONFIG_DIR); 568 if (StringUtils.isNotEmpty(configDir)) { 569 setConfig(new File(configDir)); 570 } 571 572 String logDir = System.getProperty(NUXEO_LOG_DIR); 573 if (StringUtils.isNotEmpty(logDir)) { 574 setLog(new File(logDir)); 575 } 576 577 String tmpDir = System.getProperty(NUXEO_TMP_DIR); 578 if (StringUtils.isNotEmpty(tmpDir)) { 579 setTemp(new File(tmpDir)); 580 } 581 582 String mpDir = System.getProperty(NUXEO_MP_DIR); 583 setPath(NUXEO_MP_DIR, StringUtils.isNotEmpty(mpDir) ? mpDir : DEFAULT_MP_DIR, getServerHome()); 584 } 585 586 private void initRuntimeHome() { 587 if (runtimeHome != null) { 588 return; 589 } 590 String runtimeDir = System.getProperty(NUXEO_RUNTIME_HOME); 591 if (runtimeDir != null && !runtimeDir.isEmpty()) { 592 setRuntimeHome(new File(runtimeDir)); 593 } else { 594 setRuntimeHome(home); 595 } 596 } 597 598 /** 599 * This method always returns the server home (or {@link #getHome()} if {@link #NUXEO_HOME_DIR} is not set). 600 * 601 * @since 5.4.2 602 * @return Server home 603 */ 604 public File getServerHome() { 605 initServerHome(); 606 return serverHome; 607 } 608 609 /** 610 * @since 5.4.2 611 */ 612 public void setServerHome(File serverHome) { 613 this.serverHome = serverHome.getAbsoluteFile(); 614 setProperty(NUXEO_HOME_DIR, serverHome.getAbsolutePath()); 615 } 616 617 private void initServerHome() { 618 if (serverHome != null) { 619 return; 620 } 621 String homeDir = System.getProperty(NUXEO_HOME, System.getProperty(NUXEO_HOME_DIR)); 622 if (homeDir != null && !homeDir.isEmpty()) { 623 setServerHome(new File(homeDir)); 624 } else { 625 logger.warn(String.format("Could not set the server home from %s or %s system properties, will use %s", 626 NUXEO_HOME, NUXEO_HOME_DIR, home)); 627 setServerHome(home); 628 } 629 logger.debug(this); 630 } 631 632 public void setConfigurationProvider(Iterable<URL> configProvider) { 633 this.configProvider = configProvider; 634 } 635 636 public Iterable<URL> getConfigurationProvider() { 637 return configProvider; 638 } 639 640 @Override 641 public String toString() { 642 return ToStringBuilder.reflectionToString(this); 643 } 644 645 /** 646 * Add a file path as a property 647 * 648 * @param key Property key 649 * @param value Property value: an absolute or relative file 650 * @param baseDir The directory against which the file will be resolved if not absolute 651 * @since 8.1 652 * @see #setProperty(String, String) 653 * @see #setPath(String, String, File) 654 * @see #setPath(String, File) 655 */ 656 public void setPath(String key, File value, File baseDir) { 657 setProperty(key, baseDir.toPath().resolve(value.toPath()).toFile().getAbsolutePath()); 658 } 659 660 /** 661 * Add a file path as a property 662 * 663 * @param key Property key 664 * @param value Property value: an absolute or relative file path 665 * @param baseDir The directory against which the file will be resolved if not absolute 666 * @since 8.1 667 * @see #setProperty(String, String) 668 * @see #setPath(String, File, File) 669 * @see #setPath(String, File) 670 */ 671 public void setPath(String key, String value, File baseDir) { 672 setProperty(key, baseDir.toPath().resolve(value).toFile().getAbsolutePath()); 673 } 674 675 /** 676 * Add a file path as a property 677 * 678 * @param key Property key 679 * @param value Property value: an absolute or relative file; if relative, it will be resolved against {@link #home} 680 * @since 8.1 681 * @see #setProperty(String, String) 682 * @see #setPath(String, File, File) 683 */ 684 public void setPath(String key, File value) { 685 setPath(key, value, home); 686 } 687 688 /** 689 * Add a file path as a property 690 * 691 * @param key Property key 692 * @param value Property value: an absolute or relative file path; if relative, it will be resolved against 693 * {@link #home} 694 * @since 8.1 695 * @see #setProperty(String, String) 696 * @see #setPath(String, String, File) 697 */ 698 public void setPath(String key, String value) { 699 setPath(key, value, home); 700 } 701 702 /** 703 * @param key 704 * @return the file which path is associated with the given key. The file is guaranteed to be absolute if it has 705 * been set with {@link #setPath(String, File)} 706 * @since 8.1 707 */ 708 public File getPath(String key) { 709 return getPath(key, null); 710 } 711 712 /** 713 * @param key the property key 714 * @param defaultValue the default path, absolute or relative to server home 715 * @return the file which path is associated with the given key. The file is guaranteed to be absolute if it has 716 * been set with {@link #setPath(String, File)} 717 * @since 8.1 718 */ 719 public File getPath(String key, String defaultValue) { 720 String path = properties.getProperty(key); 721 if (path != null) { 722 return new File(path); 723 } else if (defaultValue != null) { 724 return getServerHome().toPath().resolve(defaultValue).toFile(); 725 } 726 return null; 727 } 728}