001/* 002 * File : $Source$ 003 * Date : $Date$ 004 * Version: $Revision$ 005 * 006 * This library is part of OpenCms - 007 * the Open Source Content Management System 008 * 009 * Copyright (C) 2002 - 2009 Alkacon Software (http://www.alkacon.com) 010 * 011 * This library is free software; you can redistribute it and/or 012 * modify it under the terms of the GNU Lesser General Public 013 * License as published by the Free Software Foundation; either 014 * version 2.1 of the License, or (at your option) any later version. 015 * 016 * This library is distributed in the hope that it will be useful, 017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 * Lesser General Public License for more details. 020 * 021 * For further information about Alkacon Software, please see the 022 * company website: http://www.alkacon.com 023 * 024 * For further information about OpenCms, please see the 025 * project website: http://www.opencms.org 026 * 027 * You should have received a copy of the GNU Lesser General Public 028 * License along with this library; if not, write to the Free Software 029 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 030 */ 031 032package org.opencms.setup; 033 034import org.opencms.main.CmsLog; 035import org.opencms.setup.comptest.CmsSetupTestResult; 036import org.opencms.setup.comptest.CmsSetupTests; 037import org.opencms.util.CmsStringUtil; 038 039import java.io.File; 040import java.io.PrintStream; 041import java.util.Date; 042import java.util.List; 043import java.util.Map; 044 045import org.apache.commons.logging.Log; 046 047/** 048 * A bean to perform a OpenCms setup automatically.<p> 049 * 050 * @since 9.0 051 */ 052public class CmsAutoSetup { 053 054 /** The log object for this class. */ 055 private static final Log LOG = CmsLog.getLog(CmsAutoSetup.class); 056 057 /** A constant for the path, where the "setup.properties" files is placed on the local file system. */ 058 private static final String PARAM_CONFIG_PATH = "-path"; 059 060 /** Set this parameter to create DB and tables only. */ 061 private static final String PARAM_DB_ONLY = "-dbonly"; 062 063 /** Horizontal ruler - ASCII style. */ 064 private static final String HR = "-----------------------------------------------------------"; 065 066 /** The setup bean. */ 067 private CmsSetupBean m_bean; 068 069 /** The setup properties to use. */ 070 private CmsAutoSetupProperties m_props; 071 072 /** 073 * A bean for a automatically performed setup of OpenCms.<p> 074 * 075 * @param props the properties to use 076 */ 077 public CmsAutoSetup(CmsAutoSetupProperties props) { 078 079 m_props = props; 080 m_bean = new CmsSetupBean(); 081 m_bean.init(props.getSetupWebappPath(), props.getServeltMapping(), props.getSetupDefaultWebappName()); 082 } 083 084 /** 085 * Main program entry point when started via the command line.<p> 086 * 087 * @param args parameters passed to the application via the command line 088 */ 089 public static void main(String[] args) { 090 091 System.out.println(); 092 System.out.println(HR); 093 System.out.println("OpenCms setup started at: " + new Date(System.currentTimeMillis())); 094 System.out.println(HR); 095 System.out.println(); 096 097 String path = null; 098 099 boolean setupDBOnly = false; 100 if ((args.length > 0) && (args[0] != null)) { 101 for (int i = 0; i < args.length; i++) { 102 if (args[i] != null) { 103 if (PARAM_CONFIG_PATH.equals(args[i]) && (args.length > (i + 1))) { 104 path = args[i + 1]; 105 } else if (args[i].startsWith(PARAM_CONFIG_PATH)) { 106 path = args[i].substring(PARAM_CONFIG_PATH.length()).trim(); 107 } else if (PARAM_DB_ONLY.equals(args[i])) { 108 setupDBOnly = true; 109 } 110 } 111 } 112 } 113 if ((null != path) && (new File(path).exists())) { 114 System.out.println("Using config file: " + path + "\n"); 115 try { 116 CmsAutoSetupProperties props = new CmsAutoSetupProperties(path); 117 System.out.println("Webapp path : " + props.getSetupWebappPath()); 118 System.out.println("Ethernet address: " + props.getEthernetAddress()); 119 System.out.println("Server URL : " + props.getServerUrl()); 120 System.out.println("Server name : " + props.getServerName()); 121 System.out.println("Show progress : " + props.isShowProgress()); 122 System.out.println(); 123 for (Map.Entry<String, String[]> entry : props.toParameterMap().entrySet()) { 124 System.out.println(entry.getKey() + " = " + entry.getValue()[0]); 125 } 126 System.out.println(); 127 CmsAutoSetup setup = new CmsAutoSetup(props); 128 if (setupDBOnly) { 129 System.out.println("Creating DB and tables only."); 130 System.out.println( 131 "The opencms.properties file will not be written and no modules will be installed.\n\n"); 132 setup.initSetupBean(); 133 setup.setupDB(); 134 } else { 135 setup.run(); 136 } 137 } catch (Exception e) { 138 System.out.println("An error occurred during the setup process with the following error message:"); 139 System.out.println(e.getMessage()); 140 System.out.println("Please have a look into the opencms log file for detailed information."); 141 LOG.error(e.getMessage(), e); 142 System.exit(1); 143 } 144 } else { 145 System.out.println(""); 146 System.err.println( 147 "Config file not found, please specify a path where to find the setup properties to use."); 148 System.out.println("Usage example (Unix): setup.sh -path /path/to/setup.properties"); 149 System.out.println("Usage example (Win): setup.bat -path C:\\setup.properties"); 150 System.out.println(""); 151 System.out.println("Have a look at the package: org/opencms/setup/setup.properties.example"); 152 System.out.println("in order to find a sample configuration file."); 153 } 154 System.exit(0); 155 } 156 157 /** 158 * Initializes the setup bean with the auto setup properties.<p> 159 */ 160 public void initSetupBean() { 161 162 m_bean.setAutoMode(true); 163 m_bean.setDatabase(m_props.getDbProduct()); 164 m_bean.setDb(m_props.getDbName()); 165 m_bean.setDbCreateUser(m_props.getCreateUser()); 166 m_bean.setDbCreatePwd(m_props.getCreatePwd() == null ? "" : m_props.getCreatePwd()); 167 m_bean.setDbWorkUser(m_props.getWorkerUser()); 168 m_bean.setDbWorkPwd(m_props.getWorkerPwd() == null ? "" : m_props.getWorkerPwd()); 169 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_props.getConStrParams())) { 170 m_bean.setDbConStrParams(m_props.getConStrParams()); 171 } 172 m_bean.setDbCreateConStr(m_props.getConnectionUrl()); 173 m_bean.setDbWorkConStr(m_props.getConnectionUrl()); 174 m_bean.setDbParamaters(m_props.toParameterMap(), m_props.getDbProvider(), "/opencms/", null); 175 176 m_bean.setServerName(m_props.getServerName()); 177 m_bean.setWorkplaceSite(m_props.getServerUrl()); 178 m_bean.setEthernetAddress( 179 m_props.getEthernetAddress() == null ? CmsStringUtil.getEthernetAddress() : m_props.getEthernetAddress()); 180 181 // initialize the available modules 182 m_bean.getAvailableModules(); 183 List<String> componentsToInstall = m_props.getInstallComponents(); 184 String modules = m_bean.getComponentModules(componentsToInstall); 185 m_bean.setInstallModules(modules); 186 } 187 188 /** 189 * Performs the setup.<p> 190 * 191 * @throws Exception in case the setup fails 192 */ 193 public void run() throws Exception { 194 195 if (m_bean.getWizardEnabled()) { 196 197 long timeStarted = System.currentTimeMillis(); 198 199 CmsSetupTests setupTests = new CmsSetupTests(); 200 setupTests.runTests(m_bean, "No server info present, because this test is running in auto mode."); 201 if (setupTests.isRed()) { 202 for (CmsSetupTestResult result : setupTests.getTestResults()) { 203 if (result.isRed()) { 204 throw new Exception(result.getInfo()); 205 } 206 } 207 } 208 System.out.println("System requirements tested successfully."); 209 210 initSetupBean(); 211 212 setupDB(); 213 214 if (m_bean.prepareStep8()) { 215 System.out.println("Configuration files written successfully."); 216 m_bean.prepareStep8b(); 217 } 218 219 if (m_props.isShowProgress()) { 220 // show a simple progress indicator 221 // this is only needed in case you do an automated installation and watch the console 222 System.out.println("\nImporting modules:"); 223 // System.out will be redirected by the setup bean, so keep a reference for the progress indicator 224 PrintStream out = System.out; 225 int timecount = 0; 226 StringBuffer points = new StringBuffer(100); 227 while (m_bean.isImportRunning()) { 228 if ((++timecount % 10) == 0) { 229 points.append('.'); 230 out.println(points); 231 } 232 Thread.sleep(500); 233 } 234 System.out.println("\nModule import is finished!"); 235 } else { 236 // no progress indicator 237 System.out.println("Importing modules."); 238 while (m_bean.isImportRunning()) { 239 Thread.sleep(500); 240 } 241 } 242 System.out.println("Modules imported successfully."); 243 244 m_bean.prepareStep10(); 245 System.out.println(); 246 System.out.println(HR); 247 System.out.println( 248 "OpenCms setup finished successfully in " 249 + Math.round((System.currentTimeMillis() - timeStarted) / 1000) 250 + " seconds."); 251 System.out.println(HR); 252 } else { 253 throw new Exception("Error starting Alkacon OpenCms setup wizard."); 254 } 255 } 256 257 /** 258 * Creates DB and tables when necessary.<p> 259 * 260 * @throws Exception in case creating DB or tables fails 261 */ 262 public void setupDB() throws Exception { 263 264 if (m_bean.isInitialized()) { 265 System.out.println("Setup-Bean initialized successfully."); 266 CmsSetupDb db = new CmsSetupDb(m_bean.getWebAppRfsPath()); 267 try { 268 // try to connect as the runtime user 269 db.setConnection( 270 m_bean.getDbDriver(), 271 m_bean.getDbWorkConStr(), 272 m_bean.getDbConStrParams(), 273 m_bean.getDbWorkUser(), 274 m_bean.getDbWorkPwd(), 275 false); 276 if (!db.noErrors()) { 277 // try to connect as the setup user 278 db.closeConnection(); 279 db.clearErrors(); 280 db.setConnection( 281 m_bean.getDbDriver(), 282 m_bean.getDbCreateConStr(), 283 m_bean.getDbConStrParams(), 284 m_bean.getDbCreateUser(), 285 m_bean.getDbCreatePwd()); 286 } 287 if (!db.noErrors() || !m_bean.validateJdbc()) { 288 throw new Exception("DB Connection test faild."); 289 } 290 } finally { 291 db.clearErrors(); 292 db.closeConnection(); 293 } 294 } 295 296 System.out.println("DB connection tested successfully."); 297 298 CmsSetupDb db = null; 299 boolean dbExists = false; 300 if (m_bean.isInitialized()) { 301 if (m_props.isCreateDb() || m_props.isCreateTables()) { 302 db = new CmsSetupDb(m_bean.getWebAppRfsPath()); 303 // check if database exists 304 if (m_bean.getDatabase().startsWith("oracle") 305 || m_bean.getDatabase().startsWith("db2") 306 || m_bean.getDatabase().startsWith("as400")) { 307 db.setConnection( 308 m_bean.getDbDriver(), 309 m_bean.getDbWorkConStr(), 310 m_bean.getDbConStrParams(), 311 m_bean.getDbWorkUser(), 312 m_bean.getDbWorkPwd()); 313 } else { 314 db.setConnection( 315 m_bean.getDbDriver(), 316 m_bean.getDbWorkConStr(), 317 m_bean.getDbConStrParams(), 318 m_bean.getDbCreateUser(), 319 m_bean.getDbCreatePwd(), 320 false); 321 dbExists = db.noErrors(); 322 if (dbExists) { 323 db.closeConnection(); 324 } else { 325 db.clearErrors(); 326 } 327 } 328 if (!dbExists || m_props.isDropDb()) { 329 db.closeConnection(); 330 if (!m_bean.getDatabase().startsWith("db2") && !m_bean.getDatabase().startsWith("as400")) { 331 db.setConnection( 332 m_bean.getDbDriver(), 333 m_bean.getDbCreateConStr(), 334 m_bean.getDbConStrParams(), 335 m_bean.getDbCreateUser(), 336 m_bean.getDbCreatePwd()); 337 } 338 } 339 } 340 } 341 if (!m_props.isCreateDb() && !m_props.isCreateTables() && !dbExists) { 342 throw new Exception("You have not created the Alkacon OpenCms database."); 343 } 344 if (dbExists && m_props.isCreateTables() && !m_props.isDropDb() && (db != null)) { 345 throw new Exception("You have selected to not drop existing DBs, but a DB with the given name exists."); 346 } 347 if (dbExists && m_props.isCreateDb() && m_props.isDropDb() && (db != null)) { 348 // drop the DB 349 db.closeConnection(); 350 db.setConnection( 351 m_bean.getDbDriver(), 352 m_bean.getDbWorkConStr(), 353 m_bean.getDbConStrParams(), 354 m_bean.getDbCreateUser(), 355 m_bean.getDbCreatePwd()); 356 db.dropDatabase(m_bean.getDatabase(), m_bean.getReplacer()); 357 if (!db.noErrors()) { 358 for (String error : db.getErrors()) { 359 System.err.println(error + "\n"); 360 System.err.println(HR + "\n"); 361 } 362 db.clearErrors(); 363 throw new Exception("Error ocurred while dropping the DB!"); 364 } 365 System.out.println("Database dropped successfully."); 366 } 367 368 if (m_props.isCreateDb() && (db != null)) { 369 // Create Database 370 db.createDatabase(m_bean.getDatabase(), m_bean.getReplacer()); 371 if (!db.noErrors()) { 372 for (String error : db.getErrors()) { 373 System.err.println(error + "\n"); 374 System.err.println(HR + "\n"); 375 } 376 db.clearErrors(); 377 throw new Exception("Error ocurred while creating the DB!"); 378 } 379 db.closeConnection(); 380 System.out.println("Database created successfully."); 381 } 382 383 if (m_props.isCreateTables() && (db != null)) { 384 db.setConnection( 385 m_bean.getDbDriver(), 386 m_bean.getDbWorkConStr(), 387 m_bean.getDbConStrParams(), 388 m_bean.getDbWorkUser(), 389 m_bean.getDbWorkPwd()); 390 //Drop Tables (intentionally quiet) 391 db.dropTables(m_bean.getDatabase()); 392 db.clearErrors(); 393 db.closeConnection(); 394 // reopen the connection in order to display errors 395 db.setConnection( 396 m_bean.getDbDriver(), 397 m_bean.getDbWorkConStr(), 398 m_bean.getDbConStrParams(), 399 m_bean.getDbWorkUser(), 400 m_bean.getDbWorkPwd()); 401 //Create Tables 402 db.createTables(m_bean.getDatabase(), m_bean.getReplacer()); 403 if (!db.noErrors()) { 404 for (String error : db.getErrors()) { 405 System.err.println(error + "\n"); 406 System.err.println(HR + "\n"); 407 } 408 db.clearErrors(); 409 throw new Exception("Error ocurred while creating tables."); 410 } 411 db.closeConnection(); 412 System.out.println("Tables created successfully."); 413 } 414 if (db != null) { 415 db.closeConnection(); 416 } 417 System.out.println("Database setup was successful."); 418 } 419}