/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jnerator.persistence; import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.io.Reader; import java.sql.Connection; import java.sql.DriverManager; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import com.jnerator.persistence.db.plugin.IGeneratorPlugin; import com.jnerator.persistence.db.plugin.Plugins; import com.jnerator.persistence.tool.jdo.DataObjectCreate; import com.jnerator.persistence.tool.jdo.data.JdoInfo; import com.jnerator.persistence.tool.sql.ConnectionInfo; import com.jnerator.persistence.tool.sql.DatabaseInfo; import com.jnerator.persistence.tool.sql.data.TableInfo; import java.util.Scanner; import java.util.Map.Entry; /** * Generate persistence layer code based on the specified plugin * * @goal generate * * @phase generate-sources */ public class PersistenceGeneratorMojo extends AbstractMojo { /** * Location of the generated persistence artifacts. * * @parameter expression="${basedir}/src/main/jnerator-persistence/" * alias="outputDirectory" * @required */ private File outputDirectory; /** * Package base name for generated artifacts. * * @parameter expression="${project.groupId}.persistence" * alias="packageName" * @required */ private String packageName; /** * Class name of the jdbc driver to use (i.e. com.mysql.jdbc.Driver for * MySQL, oracle.jdbc.OracleDriver for Oracle, org.postgresql.Driver for * Postgresql, etc.) * * @parameter alias="driverClassName" * @required */ private String driverClassName; /** * The jdbc url to extract database model information * * @parameter alias="jdbcUrl" * @required */ private String jdbcUrl; /** * The user login to connect to the underlying database * * @parameter alias="login" * @required */ private String login; /** * The user password to connect to the underlying database * * @parameter default-value="" alias="password" */ private String password; /** * A pattern to search for tables. You can use the joker character '%'. If * you want to generate DataObjects for every tables, just set '%' * * @parameter expression="" default-value="%" alias="tablesNames" * @required */ private String tablesNames; /** * The name of your database schema * * @parameter expression="" default-value="" alias="schema" */ private String schema; /** * The plugin to use for the artifacts generation. * * @parameter expression="EJB3AndHibernateDao" * default-value="EJB3AndHibernateDao" alias="plugin" * @required */ private String plugin; /** * You can choose a prefix that will be added to every classes that the * plugin considers as a table. As an example if you run the Hibernate * plugin on a table named "PERSON", a pojo mapping this table will be * generated. By default its name would be "Person" but if you set a prefix * the generated name will be prefix+"Person". * * @parameter alias="prefix" alias="prefix" */ private String prefix; /** * You can set an offset to ignore first characters of table names. As an * example if you run the Hibernate plugin on a table named "TB_PERSON", a * pojo mapping this table will be generated. By default its name would be * "TbPerson" but if you set nameOffset to 3, the generated name will be * "Person" because the first characters "TB_" have been ignored. * * * @parameter expression="0" default-value="0" alias="nameOffset" */ private int nameOffset; /** * If set to true, the Generator will follow foreign keys on table to * retrieve dependants tables to execute plugin on them as well. It is * recursive (see maxDepth). * * @parameter expression="false" alias="followForeignKeys" */ private boolean followForeignKeys; /** * When you set followForeignKeys to true, you need to set a max depth to * retrieve dependants table, otherwise you will retrieve the whole * database. * * @parameter expression="0" default-value="0" alias="maxDepth" */ private int maxDepth; /** * If set to false, views will be ignored by the Generator. Default is true. * * @parameter expression="true" default-value="true" alias="generateView" */ private boolean generateView; public void execute() throws MojoExecutionException { getLog().info("Salto-DB ANT Generator - Salto Consulting"); getLog().info("Generating artifacts in: " + outputDirectory); listPluginsAndSelectOne(); Connection defaultConn = null; try { ConnectionInfo connectionInfo = new ConnectionInfo(driverClassName, jdbcUrl, login, password, schema); try { getLog().debug("Loading driver: " + driverClassName); Class.forName(driverClassName); } catch (Exception e) { throw new MojoExecutionException("Unable to load JDBC driver=" + driverClassName); } defaultConn = DriverManager.getConnection(jdbcUrl, login, password); connectionInfo.setConn(defaultConn); getLog().info("Successfully connected to database"); String tableNames[] = tablesNames.split(","); Set set = new HashSet(); for (int k = 0; k < tableNames.length; k++) { TableInfo[] tableInfos = DatabaseInfo.getTables(defaultConn, null, schema, tableNames[k]); getLog().info(tableInfos.length + " table(s) found for table name '" + tableNames[k] + "'"); set.addAll(Arrays.asList(tableInfos)); } TableInfo[] tableInfos = (TableInfo[]) set.toArray(new TableInfo[set.size()]); IGeneratorPlugin p = Plugins.getInstance().getPlugin(plugin); if (p == null) { throw new Exception("Cannot find plugin " + plugin); } getLog().info("******************************************"); getLog().info(p.getShortDescription()); getLog().info("******************************************"); if (prefix == null) { prefix = p.getDefaultPrefix(); } // JdoInfo[] jdoInfos = new JdoInfo[tableInfos.length]; List jdoInfos = new ArrayList(); for (int j = 0; j < tableInfos.length; j++) { if (!tableInfos[j].getTableType().equalsIgnoreCase("VIEW") && !tableInfos[j].getTableType().equalsIgnoreCase("TABLE")) { continue; } if (!generateView && tableInfos[j].getTableType().equals("VIEW")) { getLog().info( "Not applying plugin '" + plugin + "' to " + tableInfos[j].getTableType() + " '" + tableInfos[j].getTableName() + "' because it's a view and generateView is set to false."); } else { try { getLog().info( "Applying plugin '" + plugin + "' to " + tableInfos[j].getTableType() + " '" + tableInfos[j].getTableName() + "'"); tableInfos[j].setConnInfo(connectionInfo); JdoInfo jdoInfo = DataObjectCreate.createJdoInfoFromTableInfo(tableInfos[j]); jdoInfos.add(jdoInfo); } catch (Exception e) { getLog().info( "Skipping " + tableInfos[j].getTableType() + " '" + tableInfos[j].getTableName() + "' because it throws an error " + e); } } } if (jdoInfos.size() > 0) { if (followForeignKeys) { getLog().info("followForeignKeys enabled"); if (this.maxDepth > 0) { getLog().info("maxDepth = " + this.maxDepth); } } else { this.maxDepth = 0; } new DataObjectCreate().creerDoSimple(prefix, nameOffset, outputDirectory.getPath(), packageName, (JdoInfo[]) jdoInfos.toArray(new JdoInfo[jdoInfos.size()]), plugin, maxDepth); } } catch (Exception e) { getLog().error("Unexpected error: " + e.getMessage()); throw new MojoExecutionException(e.getMessage(), e); } finally { try { getLog().info("Closing connection to database"); defaultConn.close(); } catch (Exception e) { } } } public void listPluginsAndSelectOne() throws MojoExecutionException{ getLog().info("-----------------------------------------"); getLog().info("Loaded Plugins : "); List<Entry<String, String>> pList = new ArrayList<Entry<String, String>>(Plugins.getInstance().getPlugins().entrySet()); for (int idx = 0; idx < pList.size();idx++) { Entry<String, String> entry = pList.get(idx); getLog().info(idx + ") " + entry.getKey()); } getLog().info("-----------------------------------------"); getLog().info("Choose one or hit enter to use default (default is '"+plugin+"'):"); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); try{ while(true){ String tmp = reader.readLine(); if(tmp != null && "".equals(tmp.trim())){ break; }else { if(tmp != null){ int opt = Integer.MIN_VALUE; try{ opt = Integer.parseInt(tmp); if(opt >= 0 && opt <= pList.size()){ Entry<String, String> entry = pList.get(opt); plugin = entry.getKey(); break; } }catch(Exception e){} } } } getLog().info("You have selected: "+ plugin); }catch(Exception e){ throw new MojoExecutionException("Error reading user inputs.", e); } finally{ try{ reader.close(); }catch(Exception e){getLog().error("Error closing reader.",e);} } } }