Author: bcarothers
Date: 2009-11-27 11:52:16 -0500 (Fri, 27 Nov 2009)
New Revision: 1365
Added:
trunk/utils/dna-jpa-ddl-gen/
trunk/utils/dna-jpa-ddl-gen/.classpath
trunk/utils/dna-jpa-ddl-gen/.project
trunk/utils/dna-jpa-ddl-gen/pom.xml
trunk/utils/dna-jpa-ddl-gen/src/
trunk/utils/dna-jpa-ddl-gen/src/main/
trunk/utils/dna-jpa-ddl-gen/src/main/java/
trunk/utils/dna-jpa-ddl-gen/src/main/java/org/
trunk/utils/dna-jpa-ddl-gen/src/main/java/org/jboss/
trunk/utils/dna-jpa-ddl-gen/src/main/java/org/jboss/dna/
trunk/utils/dna-jpa-ddl-gen/src/main/java/org/jboss/dna/util/
trunk/utils/dna-jpa-ddl-gen/src/main/java/org/jboss/dna/util/SchemaGen.java
trunk/utils/dna-jpa-ddl-gen/src/main/resources/
trunk/utils/dna-jpa-ddl-gen/src/main/resources/log4j.properties
trunk/utils/dna-jpa-ddl-gen/src/test/
trunk/utils/dna-jpa-ddl-gen/src/test/java/
trunk/utils/dna-jpa-ddl-gen/src/test/java/org/
trunk/utils/dna-jpa-ddl-gen/src/test/java/org/jboss/
trunk/utils/dna-jpa-ddl-gen/src/test/java/org/jboss/dna/
trunk/utils/dna-jpa-ddl-gen/src/test/java/org/jboss/dna/util/
trunk/utils/dna-jpa-ddl-gen/src/test/java/org/jboss/dna/util/SchemaGenTest.java
Modified:
trunk/docs/reference/src/main/docbook/en-US/content/connectors/jdbc_storage.xml
trunk/pom.xml
Log:
DNA-511 The JPA Source should provide a way of producing the DDL for the database dialect
Committed new version of previous patch that adds comments, documentation, and more
tolerance for variations on the dialect parameter.
Modified: trunk/docs/reference/src/main/docbook/en-US/content/connectors/jdbc_storage.xml
===================================================================
---
trunk/docs/reference/src/main/docbook/en-US/content/connectors/jdbc_storage.xml 2009-11-27
03:08:49 UTC (rev 1364)
+++
trunk/docs/reference/src/main/docbook/en-US/content/connectors/jdbc_storage.xml 2009-11-27
16:52:16 UTC (rev 1365)
@@ -263,6 +263,25 @@
Of course, setting other more advanced properties would entail calling
<code>setProperty(...)</code> for each. Since almost all
of the properties have acceptable default values, however, we don't need to set
very many of them.
</para>
+ <para>
+ DNA users who prefer not to give DDL privileges to the DNA database user for this
connector can use the DNA JPA DDL generation
+ tool to create the proper DDL files for their database dialect. This tool is packaged
as an executable jar in the
+ utils/dna-jpa-ddl-gen subproject and can be executed with the following syntax:
+ </para>
+<programlisting>
+java -jar <jar_name> -dialect <dialect name> -model
<model_name> [-out <path to output directory>]
+</programlisting>
+ <para>
+ The dialect and model parameters should match the value of the
<code>dialect</code> and <code>model</code> properties specified
for the
+ JPA connector.
+ </para>
+ <para>
+ Running this executable will create two files in the output directory (or the current
directory if no output directory
+ was specified): create.dna-jpa-connector.ddl and drop.dna-jpa-connector.ddl. The former
contains the DDL to create or replace the tables,
+ foreign keys, indices, and sequences needed by the JPA connector and the latter
containts the DDL to drop any tables, foreign keys, indices, and
+ sequences needed by the JPA connector.
+ </para>
+
<sect2>
<title>Basic Model</title>
<para>
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-11-27 03:08:49 UTC (rev 1364)
+++ trunk/pom.xml 2009-11-27 16:52:16 UTC (rev 1365)
@@ -145,6 +145,7 @@
<module>web/dna-web-jcr-rest</module>
<module>web/dna-web-jcr-rest-client</module>
<module>web/dna-web-jcr-rest-war</module>
+ <module>utils/dna-jpa-ddl-gen</module>
</modules>
<properties>
<!-- These are properties used in the database profiles. Must initialize them to be
empty so that Maven applies
Added: trunk/utils/dna-jpa-ddl-gen/.classpath
===================================================================
--- trunk/utils/dna-jpa-ddl-gen/.classpath (rev 0)
+++ trunk/utils/dna-jpa-ddl-gen/.classpath 2009-11-27 16:52:16 UTC (rev 1365)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes"
path="src/main/java"/>
+ <classpathentry kind="src" path="src/test/java"/>
+ <classpathentry kind="src" path="src/main/resources"/>
+ <classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con"
path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Added: trunk/utils/dna-jpa-ddl-gen/.project
===================================================================
--- trunk/utils/dna-jpa-ddl-gen/.project (rev 0)
+++ trunk/utils/dna-jpa-ddl-gen/.project 2009-11-27 16:52:16 UTC (rev 1365)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>dna-jpa-ddl-gen</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
+</projectDescription>
Added: trunk/utils/dna-jpa-ddl-gen/pom.xml
===================================================================
--- trunk/utils/dna-jpa-ddl-gen/pom.xml (rev 0)
+++ trunk/utils/dna-jpa-ddl-gen/pom.xml 2009-11-27 16:52:16 UTC (rev 1365)
@@ -0,0 +1,111 @@
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna</artifactId>
+ <version>0.7-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <!-- The groupId and version values are inherited from parent -->
+ <artifactId>dna-jpa-ddl-gen</artifactId>
+ <packaging>jar</packaging>
+ <name>JBoss JPA Connector DDL Generator</name>
+ <description>
+ Utility application to generate ddl for JBoss DNA JPA connector
+ </description>
+ <
url>http://labs.jboss.org/dna</url>
+ <!--
+ Define the dependencies. Note that all version and scopes default to
+ those defined in the dependencyManagement section of the parent pom.
+ -->
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ <mainClass>org.jboss.dna.util.SchemaGen</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-my-jar-with-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!--
+ Common
+ -->
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-connector-store-jpa</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-tools</artifactId>
+ <version>3.2.4.GA</version>
+ </dependency>
+ <!--
+ Testing (note the scope)
+ -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-library</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <!--
+ Logging (require SLF4J API for compiling, but use Log4J and its SLF4J
+ binding for testing)
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <!-- This defaults to test scope; needs to be compile scope to be in executable
JAR -->
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <!-- This defaults to test scope; needs to be compile scope to be in executable
JAR -->
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
\ No newline at end of file
Property changes on: trunk/utils/dna-jpa-ddl-gen/pom.xml
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/utils/dna-jpa-ddl-gen/src/main/java/org/jboss/dna/util/SchemaGen.java
===================================================================
--- trunk/utils/dna-jpa-ddl-gen/src/main/java/org/jboss/dna/util/SchemaGen.java
(rev 0)
+++ trunk/utils/dna-jpa-ddl-gen/src/main/java/org/jboss/dna/util/SchemaGen.java 2009-11-27
16:52:16 UTC (rev 1365)
@@ -0,0 +1,128 @@
+package org.jboss.dna.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+import org.jboss.dna.connector.store.jpa.JpaSource;
+import org.jboss.dna.connector.store.jpa.Model;
+
+/**
+ * Main class to generate DDL that can be used to build the schema for the {@link
JpaSource JPA connector}. The class is intended
+ * to be bundled into an executable jar file and invoked with the following syntax:
+ *
+ * <pre>
+ * java -jar <jar_name> -dialect <dialect name> -model
<model_name> [-out <path to output directory>]
+ * Example: java -jar dna-jpa-ddl-gen-0.7-jar-with-dependencies.jar -dialect HSQL
-model Basic -out /tmp
+ * </pre>
+ */
+public class SchemaGen {
+
+ public static final String CREATE_FILE_NAME =
"create.dna-jpa-connector.ddl";
+ public static final String DROP_FILE_NAME = "drop.dna-jpa-connector.ddl";
+
+ private final Dialect dialect;
+ private final Model model;
+ private final File outputPath;
+
+ public SchemaGen( String dialect,
+ String model,
+ File outputPath ) {
+
+ this.dialect = dialectFor(dialect);
+ this.model = JpaSource.Models.getModel(model);
+ this.outputPath = outputPath;
+ }
+
+ /**
+ * Returns the {@link Dialect Hibernate dialect} that corresponds to the provided
name.
+ * <p>
+ * This method will tolerate certain kinds of abbreviations for the dialect. Since
all Hibernate dialects have a name equal to
+ * their fully-qualified name, all valid dialect names start with
"org.hibernate.dialect.". If the given {@code
+ * dialectName} does not begin with this string, this string will be prepended.
+ * </p>
+ * <p>
+ * Additionally, all Hibernate dialect names end in "Dialect". If
the given dialect name does not end with
+ * "Dialect", this will be appended to the dialect name before the
Hibernate dialect is looked up.
+ * </p>
+ * <p>
+ * The net effect of these rules is that callers wishing to retrieve a dialect (e.g.,
org.hibernate.dialect.HSQLDialect) can
+ * specify the dialect as "org.hibernate.dialect.HSQLDialect",
"HSQLDialect", "org.hibernate.dialect.HSQL", or just
"HSQL".
+ * </p>
+ *
+ * @param dialectName the name of the {@code Dialect} to return
+ * @return the {@link Dialect Hibernate dialect} that corresponds to the provided
name.
+ */
+ private Dialect dialectFor( String dialectName ) {
+ Properties props = new Properties();
+
+ if (!dialectName.endsWith("Dialect")) dialectName +=
"Dialect";
+ if (!dialectName.startsWith("org.hibernate.dialect.")) dialectName =
"org.hibernate.dialect." + dialectName;
+
+ props.put(Environment.DIALECT, dialectName);
+
+ return Dialect.getDialect(props);
+ }
+
+ /**
+ * Writes {@link SchemaExport#create(boolean, boolean) create} and {@link
SchemaExport#drop(boolean, boolean) drop} DDL files
+ * to the given {@link #outputPath output directory} or the current directory if no
output directory was provided.
+ *
+ * @throws IOException
+ */
+ void generate() throws IOException {
+ Ejb3Configuration configurator = new Ejb3Configuration();
+ configurator.setProperty(Environment.DIALECT, dialect.toString());
+ model.configure(configurator);
+ // cfg.setProperties(properties);
+ SchemaExport export = new
SchemaExport(configurator.getHibernateConfiguration());
+ export.setOutputFile(new File(outputPath, CREATE_FILE_NAME).getCanonicalPath());
+ export.create(false, false);
+
+ export.setOutputFile(new File(outputPath, DROP_FILE_NAME).getCanonicalPath());
+ export.drop(false, false);
+ }
+
+ public static final String USAGE = "java -jar <jar_name> -dialect
<dialect name> -model <model_name> [-out <path to output
directory>]\n"
+ + "\tExample: java -jar
dna-jpa-ddl-gen-0.7-jar-with-dependencies.jar -dialect HSQL -model Basic -out /tmp";
+
+ public static void main( String[] args ) throws IOException {
+ String modelName = null;
+ String dialectName = null;
+ File outputFile = new File(".");
+
+ int i = 0;
+ while (i < args.length) {
+ if ("-dialect".equals(args[i])) {
+ if (i == args.length - 1) printUsage();
+ dialectName = args[++i];
+ } else if ("-model".equals(args[i])) {
+ if (i == args.length - 1) printUsage();
+ modelName = args[++i];
+ } else if ("-out".equals(args[i])) {
+ if (i == args.length - 1) printUsage();
+ outputFile = new File(args[++i]);
+ } else if ("-help".equals(args[i]) ||
"-?".equals(args[i])) {
+ printUsage();
+ }
+ i++;
+ }
+
+ if (modelName == null || dialectName == null) printUsage();
+
+ SchemaGen main = new SchemaGen(dialectName, modelName, outputFile);
+ main.generate();
+ }
+
+ /**
+ * Print the usage message and exit with a non-zero return code.
+ */
+ private static void printUsage() {
+ System.err.println(USAGE);
+ System.exit(1);
+ }
+
+}
Property changes on:
trunk/utils/dna-jpa-ddl-gen/src/main/java/org/jboss/dna/util/SchemaGen.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added: trunk/utils/dna-jpa-ddl-gen/src/main/resources/log4j.properties
===================================================================
--- trunk/utils/dna-jpa-ddl-gen/src/main/resources/log4j.properties
(rev 0)
+++ trunk/utils/dna-jpa-ddl-gen/src/main/resources/log4j.properties 2009-11-27 16:52:16
UTC (rev 1365)
@@ -0,0 +1,20 @@
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %m%n
+
+# Root logger option
+log4j.rootLogger=INFO, stdout
+
+# Set up the default logging to be INFO level, then override specific units
+log4j.logger.org.jboss.dna=INFO
+log4j.logger.org.junit=DEBUG
+#
log4j.logger.org.jboss.dna.tests.integration.jackrabbit.JackrabbitMySqlStressTest=DEBUG
+log4j.logger.org.hibernate=WARN, stdout
+
+
+# Jackrabbit logging
+log4j.logger.org.apache.jackrabbit=WARN, stdout
+log4j.logger.org.apache.derby=INFO, stdout
+
Added: trunk/utils/dna-jpa-ddl-gen/src/test/java/org/jboss/dna/util/SchemaGenTest.java
===================================================================
--- trunk/utils/dna-jpa-ddl-gen/src/test/java/org/jboss/dna/util/SchemaGenTest.java
(rev 0)
+++
trunk/utils/dna-jpa-ddl-gen/src/test/java/org/jboss/dna/util/SchemaGenTest.java 2009-11-27
16:52:16 UTC (rev 1365)
@@ -0,0 +1,66 @@
+package org.jboss.dna.util;
+
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import java.io.File;
+import java.io.IOException;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SchemaGenTest {
+
+ private static final File outputPath = new File("target");
+
+ @Before
+ public void beforeEach() {
+ cleanFiles();
+ }
+
+ @AfterClass
+ // Run this after the last test to keep the target directory clean
+ public static void cleanFiles() {
+ new File(outputPath, SchemaGen.CREATE_FILE_NAME).delete();
+ new File(outputPath, SchemaGen.DROP_FILE_NAME).delete();
+ }
+
+ private void checkFiles() {
+ File createFile = new File(outputPath, SchemaGen.CREATE_FILE_NAME);
+ assertThat(createFile.exists(), is(true));
+ assertThat(createFile.length(), greaterThan(0L));
+
+ File dropFile = new File(outputPath, SchemaGen.DROP_FILE_NAME);
+ assertThat(dropFile.exists(), is(true));
+ assertThat(dropFile.length(), greaterThan(0L));
+ }
+
+ @Test
+ public void shouldCreateSchemaForHSqlDialect() throws IOException {
+ SchemaGen main = new SchemaGen("org.hibernate.dialect.HSQLDialect",
"Basic", outputPath);
+ main.generate();
+ checkFiles();
+ }
+
+ @Test
+ public void shouldCreateSchemaForOracleDialect() throws IOException {
+ SchemaGen main = new
SchemaGen("org.hibernate.dialect.Oracle10gDialect", "Basic",
outputPath);
+ main.generate();
+ checkFiles();
+ }
+
+ @Test
+ public void shouldCreateSchemaForDialectThatIsNotFullyQualified() throws IOException
{
+ SchemaGen main = new SchemaGen("HSQLDialect", "Basic",
outputPath);
+ main.generate();
+ checkFiles();
+ }
+
+ @Test
+ public void shouldCreateSchemaForShortFormDialect() throws IOException {
+ SchemaGen main = new SchemaGen("HSQL", "Basic", outputPath);
+ main.generate();
+ checkFiles();
+ }
+
+}
Property changes on:
trunk/utils/dna-jpa-ddl-gen/src/test/java/org/jboss/dna/util/SchemaGenTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF