Java tutorial
/** * OLAT - Online Learning and Training<br> * http://www.olat.org * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Copyright (c) 1999-2006 at Multimedia- & E-Learning Services (MELS),<br> * University of Zurich, Switzerland. * <p> */ package org.olat.core.commons.persistence; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.hibernate.MappingException; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.hibernate.tool.hbm2ddl.SchemaUpdate; import org.olat.core.CoreSpringFactory; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.springframework.core.io.Resource; /** * Initial Date: 25.10.2002 * * @author Florian Gnaegi Comment: Use this class to create the initial OLAT database */ public class DatabaseSetup { private static final OLog log = Tracing.createLoggerFor(DatabaseSetup.class); private static Configuration cf; /** * Method datastoreConfiguration is the central mapping definition of all OLAT objects and their mapping to a relational database. When a new mapping is accomplished, * it has to be added here. * * @return Datastore * @throws MappingException */ public static Configuration datastoreConfiguration() throws MappingException { cf = new Configuration(); List<String> filesAlreadyAdded = new ArrayList<String>(); List<String> ignoredFiles = new ArrayList<String>(); // TODO // loading hbm files out of a jar needs an start root directory. So change it to: // CoreSpringFactory.getResources("classpath*:org/**/*.hbm.xml"); // If you do the fix above you also need to ensure that no *hbm.xml files are // present both in .jars and in WEB-INF/classes, otherwise the startup process // will fail. ignoredFiles.add("LoggingObject.hbm.xml"); ignoredFiles.add("UserCommentImpl.hbm.xml"); ignoredFiles.add("UserRatingImpl.hbm.xml"); addHibernateFilesMatching("classpath*:**/*.hbm.xml", filesAlreadyAdded, ignoredFiles); // OLAT-4109 : the LoggingAction.hbm.xml file is in the core jar and is not found // since it's not in the classes directory but in the jar. // as documented above, when you want to have hbm.xml files // found by the CoreSpringFactory.getResources() method // you can't just specify "classpath*:**/*.hbm.xml" // but need to specify at least the first path segment, // i.e. it will work when you do this: "classpath*:org/**/*.hbm.xml" // Now the problem with this is that it will find too // many - i.e. it will find duplicates if you have some in a jar // and some in the classpath // To fix this we now just restrict it to loggingObject - // plus adding the ignoredFiles "trick" // TODO // Might be an idea to generalize this whole way we deal with this // i.e. we have the core jar which can contain any htm.xml or spring.xml files // so for production we want to add load them here - but for // development we have the core java directory mounted so we have // under classes as well - hence the whole problem addHibernateFilesMatching("classpath*:org/**/LoggingObject.hbm.xml", filesAlreadyAdded, new ArrayList<String>()); addHibernateFilesMatching("classpath*:org/**/UserCommentImpl.hbm.xml", filesAlreadyAdded, new ArrayList<String>()); addHibernateFilesMatching("classpath*:org/**/UserRatingImpl.hbm.xml", filesAlreadyAdded, new ArrayList<String>()); return cf; } private static void addHibernateFilesMatching(final String resourcePath, List<String> filesAlreadyAdded, List<String> ignoredFiles) { Resource[] ress = CoreSpringFactory.getResources(resourcePath); for (int i = 0; i < ress.length; i++) { Resource res = ress[i]; InputStream is; String fileName = res.getFilename(); if (ignoredFiles.contains(fileName)) { // then ignore it - dont log either continue; } if (!filesAlreadyAdded.contains(fileName)) { filesAlreadyAdded.add(fileName); try { log.info("Start adding hibernate mapping (xml mapping stream): " + res.getDescription()); is = res.getInputStream(); cf.addInputStream(is); log.info("Loaded hibernate mapping (xml mapping stream): " + res.getDescription()); } catch (IOException e) { throw new AssertException( "i/o error while getting inputstream of resource:" + res.getDescription()); } } else { log.warn("Douplicate hibernate mapping file::" + fileName + " found on classpath, skipping " + res.toString()); } } } /** * Execute commands from the command line: 'setup' or 'drop' currently available * * @param args One of createTables, dropTables, toFile, updateDDL * @throws Exception e.g. DatabaseSetup org.hibernate.dialect.MySQLDialect createScript */ public static void main(String[] args) throws Exception { if (args.length == 2) { cf = datastoreConfiguration(); cf.setProperty("hibernate.dialect", args[0]); if (args[1].equals("createTables")) createTables(); else if (args[1].equals("dropTables")) dropTables(); else if (args[1].equals("createScript")) exportDDLtoFile(); else if (args[1].equals("updateDDL")) updateDatabaseDDL(); } else { // write to file as default see database/setupDatabase.sql System.out.println( "Usage: DatabaseSetup DIALECT ACTION\nwhere ACTION is one of: createTables | dropTables | createScript | updateDLL"); } } /** * Setup OLAT database. This will drop all tables first if available. * * @throws Exception */ public static void createTables() throws Exception { log.info("Creating tables"); new SchemaExport(cf).create(false, true); // set first bolean to true for debugging. } /** * Drop all OLAT tables * * @throws Exception */ public static void dropTables() throws Exception { log.info("Dropping tables"); new SchemaExport(cf).drop(false, true); } /** * Generates alter database DDL and EXECUTES it. */ private static void updateDatabaseDDL() { boolean printToOut = true; // write to System.out boolean updateDatabase = false; try { new SchemaUpdate(cf).execute(printToOut, updateDatabase); } catch (Exception e) { log.error("DDL export to file failed: Reason: ", e); } } /** * Write database configuration to file. Includes differences to existing database. Filename: "database/setupDatabase.sql" */ private static void exportDDLtoFile() { String outputFile = "database/setupDatabase.sql"; boolean script = true; // write DDL boolean export = false; // don't update databse try { SchemaExport se = new SchemaExport(cf); se.setOutputFile(outputFile); se.setDelimiter(";"); se.create(script, export); } catch (Exception e) { log.error("DDL export to file failed: Reason: ", e); } } }