You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2012/03/16 11:07:22 UTC

svn commit: r1301413 - in /openejb/trunk/openejb/container/openejb-core/src: main/java/org/apache/openejb/assembler/classic/ test/java/org/apache/openejb/assembler/classic/ test/resources/

Author: rmannibucau
Date: Fri Mar 16 10:07:22 2012
New Revision: 1301413

URL: http://svn.apache.org/viewvc?rev=1301413&view=rev
Log:
OPENEJB-1799 import sql script automatically when in the app classloader and named import-<unit-name>.sql

Added:
    openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ImportSqlScriptTest.java
    openejb/trunk/openejb/container/openejb-core/src/test/resources/import-ImportSqlScriptTest.sql
Modified:
    openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java

Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java?rev=1301413&r1=1301412&r2=1301413&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java Fri Mar 16 10:07:22 2012
@@ -16,21 +16,34 @@
  */
 package org.apache.openejb.assembler.classic;
 
+import org.apache.openejb.OpenEJBRuntimeException;
 import org.apache.openejb.persistence.PersistenceUnitInfoImpl;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
 
-import javax.persistence.Cache;
-import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
-import javax.persistence.PersistenceUnitUtil;
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.metamodel.Metamodel;
 import javax.persistence.spi.PersistenceProvider;
+import javax.sql.DataSource;
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Properties;
 import java.util.concurrent.Callable;
 
 public class EntityManagerFactoryCallable implements Callable<EntityManagerFactory> {
+    private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB, EntityManagerFactoryCallable.class.getName());
+
+    public static final String IMPORT_FILE_PREFIX = "import-";
+    public static final String IMPORT_FILE_EXTENSION = ".sql";
+
     private final String persistenceProviderClassName;
     private final PersistenceUnitInfoImpl unitInfo;
 
@@ -41,16 +54,116 @@ public class EntityManagerFactoryCallabl
 
     @Override
     public EntityManagerFactory call() throws Exception {
-        Class clazz = Thread.currentThread().getContextClassLoader().loadClass(persistenceProviderClassName);
+        final ClassLoader appClassLoader = Thread.currentThread().getContextClassLoader();
+        Class clazz = appClassLoader.loadClass(persistenceProviderClassName);
         PersistenceProvider persistenceProvider = (PersistenceProvider) clazz.newInstance();
 
         // Create entity manager factories with the validator factory
         Map<String, Object> properties = new HashMap<String, Object>();
         properties.put("javax.persistence.validator.ValidatorFactory", new ValidatorFactoryWrapper());
         EntityManagerFactory emf = persistenceProvider.createContainerEntityManagerFactory(unitInfo, properties);
+
+        importSqlScripts(appClassLoader, emf);
+
         return emf;
     }
 
+    private void importSqlScripts(final ClassLoader cl, final EntityManagerFactory emf) {
+        final Enumeration<URL> imports;
+        try {
+            imports = cl.getResources(IMPORT_FILE_PREFIX.concat(unitInfo.getPersistenceUnitName()).concat(IMPORT_FILE_EXTENSION));
+        } catch (IOException e) {
+            throw new OpenEJBRuntimeException("can't look for init sql script", e);
+        }
+
+        Statement statement;
+        if (imports.hasMoreElements()) {
+            // force OpenJPA to initialize the database if configured this way
+            // doing it this way let us be provider independent
+            emf.createEntityManager().close();
+
+            final DataSource ds = unitInfo.getNonJtaDataSource();
+            if (ds == null) {
+                LOGGER.error("no non jta datasource for unit " + unitInfo.getPersistenceUnitName() + "; import script will be ignored.");
+                return;
+            }
+
+            Connection connection = null;
+            try {
+                connection = ds.getConnection();
+                statement = connection.createStatement();
+            } catch (SQLException e) {
+                LOGGER.error("can't create a statement, import scripts will be ignored", e);
+                if (connection != null) {
+                    try {
+                        connection.close();
+                    } catch (SQLException ignored) {
+                        // no-op
+                    }
+                }
+                return;
+            }
+
+            try {
+                while (imports.hasMoreElements()) {
+                    final URL scriptToImport = imports.nextElement();
+                    LOGGER.info("importing " + scriptToImport.toExternalForm());
+
+                    importSql(scriptToImport, statement);
+                }
+            } finally {
+                try {
+                    connection.close();
+                } catch (SQLException e) {
+                    // ignored
+                }
+            }
+        }
+    }
+
+    private void importSql(final URL script, final Statement statement) {
+        final BufferedReader bufferedReader;
+        try {
+            bufferedReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(script.openStream())));
+        } catch (IOException e) {
+            LOGGER.error("can't open " + script.toExternalForm(), e);
+            return;
+        }
+
+        try {
+            for (String sql = bufferedReader.readLine(); sql != null; sql = bufferedReader.readLine()) {
+                String trimmedSql = sql.trim();
+
+                // empty or comment
+                if (trimmedSql.isEmpty() || trimmedSql.startsWith("--") || trimmedSql.startsWith("//") || trimmedSql.startsWith("/*")) {
+                    continue;
+                }
+
+                if (trimmedSql.endsWith(";")) {
+                    trimmedSql = trimmedSql.substring(0, trimmedSql.length() - 1);
+                }
+
+                try {
+                    if (!trimmedSql.toLowerCase().startsWith("select")) {
+                        statement.executeUpdate(trimmedSql);
+                    } else { // why could it be the case?
+                        statement.executeQuery(trimmedSql);
+                    }
+
+                    SQLWarning warnings = statement.getWarnings();
+                    while (warnings != null) {
+                        LOGGER.warning(warnings.getMessage());
+                        warnings = warnings.getNextWarning();
+                    }
+                } catch (SQLException e) {
+                    LOGGER.error("error importing script " + script.toExternalForm(), e);
+                }
+            }
+        } catch (IOException e) {
+            LOGGER.error("can't import " + script.toExternalForm(), e);
+        }
+    }
+
     public PersistenceUnitInfoImpl getUnitInfo() {
         return unitInfo;
     }

Added: openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ImportSqlScriptTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ImportSqlScriptTest.java?rev=1301413&view=auto
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ImportSqlScriptTest.java (added)
+++ openejb/trunk/openejb/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/ImportSqlScriptTest.java Fri Mar 16 10:07:22 2012
@@ -0,0 +1,79 @@
+package org.apache.openejb.assembler.classic;
+
+import org.apache.openejb.jee.Empty;
+import org.apache.openejb.jee.SingletonBean;
+import org.apache.openejb.jee.jpa.unit.Persistence;
+import org.apache.openejb.jee.jpa.unit.PersistenceUnit;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.junit.Configuration;
+import org.apache.openejb.junit.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.EJB;
+import javax.ejb.LocalBean;
+import javax.ejb.Stateless;
+import javax.persistence.Entity;
+import javax.persistence.EntityManager;
+import javax.persistence.Id;
+import javax.persistence.PersistenceContext;
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(ApplicationComposer.class)
+public class ImportSqlScriptTest {
+    @EJB
+    private Persister persister;
+
+    @Configuration
+    public Properties config() {
+        final Properties p = new Properties();
+        p.put("ImportSqlScriptTest", "new://Resource?type=DataSource");
+        p.put("ImportSqlScriptTest.JdbcDriver", "org.hsqldb.jdbcDriver");
+        p.put("ImportSqlScriptTest.JdbcUrl", "jdbc:hsqldb:mem:bval");
+        return p;
+    }
+
+    @Module
+    public SingletonBean app() throws Exception {
+        final SingletonBean bean = new SingletonBean(Persister.class);
+        bean.setLocalBean(new Empty());
+        return bean;
+    }
+
+    @Module public Persistence persistence() {
+        final PersistenceUnit unit = new PersistenceUnit("ImportSqlScriptTest");
+        unit.addClass(Something.class);
+        unit.setProperty("openjpa.RuntimeUnenhancedClasses", "supported");
+        unit.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
+        unit.setProperty("openjpa.Log", "DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE");
+        unit.setExcludeUnlistedClasses(true);
+
+        final Persistence persistence = new Persistence(unit);
+        persistence.setVersion("2.0");
+        return persistence;
+    }
+
+    @LocalBean
+    @Stateless
+    public static class Persister {
+        @PersistenceContext
+        private EntityManager em;
+
+        public int count() {
+            return ((Number) em.createQuery("select count(s) from ImportSqlScriptTest$Something s").getSingleResult()).intValue();
+        }
+    }
+
+    @Entity
+    public static class Something {
+        @Id
+        private long id;
+    }
+
+    @Test
+    public void checkImportData()  {
+        assertEquals(3, persister.count());
+    }
+}

Added: openejb/trunk/openejb/container/openejb-core/src/test/resources/import-ImportSqlScriptTest.sql
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/test/resources/import-ImportSqlScriptTest.sql?rev=1301413&view=auto
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/test/resources/import-ImportSqlScriptTest.sql (added)
+++ openejb/trunk/openejb/container/openejb-core/src/test/resources/import-ImportSqlScriptTest.sql Fri Mar 16 10:07:22 2012
@@ -0,0 +1,3 @@
+insert into "ImportSqlScriptTest$Something" (id) values(1);
+insert into "ImportSqlScriptTest$Something" (id) values(2);
+insert into "ImportSqlScriptTest$Something" (id) values(3);