buildframework/helium/sf/java/metadata/src/com/nokia/helium/metadata/DerbyFactoryManagerCreator.java
changeset 628 7c4a911dc066
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildframework/helium/sf/java/metadata/src/com/nokia/helium/metadata/DerbyFactoryManagerCreator.java	Fri Aug 13 14:59:05 2010 +0300
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:  
+ *
+ */
+package com.nokia.helium.metadata;
+
+import java.io.File;
+import java.io.OutputStream;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Hashtable;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.apache.commons.io.FileUtils;
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+
+import com.nokia.helium.metadata.ant.types.SeverityEnum;
+import com.nokia.helium.metadata.model.Version;
+import com.nokia.helium.metadata.model.metadata.Severity;
+
+/**
+ * Class implementing a EntityManagerFactoryCreator for the derby database.
+ * This will be used to create new EntityManagerFactory for each database. It also
+ * handles the driver management, and basic factory settings. 
+ *
+ */
+public class DerbyFactoryManagerCreator implements EntityManagerFactoryCreator {
+
+    public static final OutputStream DEV_NULL = new OutputStream() {         
+        public void write(int b) { }     
+    };
+
+    public synchronized EntityManagerFactory create(File database) throws MetadataException {
+        EntityManagerFactory factory;
+        String name = "metadata";
+        Hashtable<String, String> persistProperties = new Hashtable<String, String>();
+        persistProperties.put("javax.persistence.jdbc.driver", "org.apache.derby.jdbc.EmbeddedDriver");
+        // This swallow all the output log from derby.
+        System.setProperty("derby.stream.error.field", "com.nokia.helium.metadata.DerbyFactoryManagerCreator.DEV_NULL");
+        persistProperties.put("javax.persistence.jdbc.url",
+               "jdbc:derby:" + database.getAbsolutePath());
+        persistProperties.put(
+                PersistenceUnitProperties.PERSISTENCE_CONTEXT_CLOSE_ON_COMMIT,
+                "false");
+        persistProperties.put(
+                PersistenceUnitProperties.PERSISTENCE_CONTEXT_REFERENCE_MODE,
+                "WEAK");
+        persistProperties.put(PersistenceUnitProperties.BATCH_WRITING,
+                "JDBC");
+        persistProperties.put("eclipselink.read-only", "true");
+        persistProperties.put(PersistenceUnitProperties.LOGGING_LEVEL, "warning");
+        if (database.exists()) {
+            if (!checkDatabaseIntegrity(database)) {
+                try {
+                    FileUtils.forceDelete(database);
+                } catch (java.io.IOException iex) {
+                    throw new MetadataException("Failed deleting corrupted db: " + iex, iex);
+                }
+            } else {
+                return
+                    Persistence.createEntityManagerFactory(
+                        name,
+                        persistProperties);
+            }
+        }
+        persistProperties.put("javax.persistence.jdbc.url",
+               "jdbc:derby:" + database + ";create=true");
+        persistProperties.put(PersistenceUnitProperties.DDL_GENERATION,
+                "create-tables");
+        persistProperties.put(
+                PersistenceUnitProperties.DDL_GENERATION_MODE,
+                "database");
+        persistProperties.put(
+                PersistenceUnitProperties.PERSISTENCE_CONTEXT_CLOSE_ON_COMMIT,
+                "false");
+        persistProperties.put(
+                PersistenceUnitProperties.PERSISTENCE_CONTEXT_REFERENCE_MODE,
+                "WEAK");
+        persistProperties.put(PersistenceUnitProperties.BATCH_WRITING,
+                "JDBC");
+        persistProperties.put("eclipselink.read-only", "true");
+        factory = Persistence.createEntityManagerFactory(
+                name,
+                persistProperties);
+        EntityManager entityManager = factory.createEntityManager();
+        // Pushing default data into the current schema
+        try {
+            entityManager.getTransaction().begin();
+            // Version of the schema is pushed.
+            entityManager.persist(new Version());
+            // Default set of severity is pushed.
+            for (SeverityEnum.Severity severity : SeverityEnum.Severity.values()) {
+                Severity pData = new Severity();
+                pData.setSeverity(severity.toString());
+                entityManager.persist(pData);
+            }
+            entityManager.getTransaction().commit();
+        } finally {
+            if (entityManager.getTransaction().isActive()) {
+                entityManager.getTransaction().rollback();
+                entityManager.clear();
+            }
+            entityManager.close();
+        }
+        return factory;
+    }
+    
+    /**
+     * Checks the database integrity.
+     * @param urlPath - database path to be connected to.
+     * @return boolean - true if db is valid false otherwise.
+     */
+    private static boolean checkDatabaseIntegrity(File database) throws MetadataException {
+        boolean result = false;
+        Connection connection = null;
+        try {
+            connection = DriverManager.getConnection("jdbc:derby:" + database);
+            if (connection != null) {
+                Statement stmt = connection.createStatement();
+                ResultSet rs = stmt.executeQuery("select version from version");
+                int version = -1;
+                if ( rs.next()) {
+                    version = rs.getInt(1);
+                }
+                rs.close();
+                stmt.close();
+                connection.close();
+                connection = null;
+                result = version == Version.DB_VERSION; 
+            }
+        } catch (SQLException ex) {
+            try {
+                DriverManager.getConnection("jdbc:derby:;shutdown=true");
+            } catch (java.sql.SQLException sex) {
+                // normal exception during database shutdown
+                connection = null;
+            }
+            return false;
+        } finally {
+            try {            
+                if (connection != null) {
+                    connection.close();
+                }
+            } catch (java.sql.SQLException sex) {
+                // normal exception during database shutdown
+                connection = null;
+            }
+            connection = null;
+            if (!result) {
+                try {
+                    DriverManager.getConnection("jdbc:derby:;shutdown=true");
+                } catch (java.sql.SQLException sex) {
+                    // normal exception during database shutdown
+                    connection = null;
+                }
+            }
+        }
+        //shutdown unloads the driver, driver need to be loaded again.
+        return result;
+    }
+    
+    public synchronized void unload(File database) {
+        try {
+            DriverManager.getConnection("jdbc:derby:" + database + ";shutdown=true");
+        } catch (SQLException e) {
+            // normal exception during database shutdown
+            e = null;
+        }        
+    }
+    
+    public synchronized void initialize() throws MetadataException {
+        try {
+            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
+        } catch (java.lang.ClassNotFoundException e) {
+            throw new MetadataException("JDBC Driver could not be found", e);
+        }
+    }
+    
+}