001/* 002 * Copyright c 2018 Rusi Popov, MDA Tools.net All rights reserved. 003 * 004 * This program and the accompanying materials are made available under the terms of the 005 * Eclipse Public License v2.0 which accompanies this distribution, and is available at 006 * http://www.eclipse.org/legal/epl-v20.html 007 */ 008package net.mdatools.modelant.uml13.maven.plugin.reverse; 009 010import java.io.File; 011import java.sql.Connection; 012import java.sql.DriverManager; 013import java.sql.SQLException; 014 015import javax.jmi.reflect.RefPackage; 016 017import org.apache.maven.plugin.AbstractMojo; 018import org.apache.maven.plugin.MojoExecutionException; 019import org.apache.maven.plugins.annotations.Execute; 020import org.apache.maven.plugins.annotations.LifecyclePhase; 021import org.apache.maven.plugins.annotations.Mojo; 022import org.apache.maven.plugins.annotations.Parameter; 023 024import net.mdatools.modelant.core.api.Function; 025import net.mdatools.modelant.repository.api.ModelRepository; 026import net.mdatools.modelant.repository.api.ModelRepositoryFactory; 027import net.mdatools.modelant.uml13.reverse.ReverseDatabaseOperation; 028 029/** 030 * Reverse engineering logic for database schemas and storing the results as 031 * UML 1.3 objects. The model produced is in fact a Platform Specific Model, which might need 032 * additional processing and tuning. 033 * Conventions for the model produced: 034 * <ol> 035 * <li>The database column types are converted to DataType instances named: <type 036 * name>[_<column size>[_<column precision>]]. Additionally as tagged values named 037 * {@link net.mdatools.modelant.uml13.metamodel.Convention.TAG_VALUE_DATA_LENGTH} and {@link net.mdatools.modelant.uml13.metamodel.Convention.TAG_VALUE_DATA_TYPE_PRECISION} 038 * these values are bound to the concrete data type. 039 * <li>The {@link net.mdatools.modelant.uml13.metamodel.Convention.TAG_VALUE_DATA_TYPE_PRECISION} tagged value is optional. When not provided, the precision 040 * should be treated as 0 041 * <li>The {@link net.mdatools.modelant.uml13.metamodel.Convention.TAG_VALUE_DATA_LENGTH} tagged value is mandatory. 042 * <li>Any comments found while reverse engineering the database are bound as 'documentation' tagged 043 * values. These tagged values are compatible with the Rose's approach to documentation. They are 044 * optional. 045 * <li>Each attribute pertaining to the table's primary key is bound a {@link net.mdatools.modelant.uml13.metamodel.Convention.TAG_VALUE_PRIMARY_KEY} tagged value 046 * with "Primaty Key" value. Its value is the sequence order of the column in the tible's primary key. 047 * </ol> 048 * 049 * @author Rusi Popov (popovr@mdatools.net) 050 */ 051@Mojo(name="database-to-uml13", 052 defaultPhase=LifecyclePhase.COMPILE 053) 054@Execute(phase=LifecyclePhase.COMPILE) 055public class ReverseEngineerDatabaseMojo extends AbstractMojo { 056 057 /** 058 * Database driver-specific URL 059 */ 060 @Parameter(required=true) 061 private String url; 062 063 /** 064 * Database user to connect the database 065 */ 066 @Parameter(required=true) 067 private String user; 068 069 /** 070 * Database user's password 071 */ 072 @Parameter(required=true) 073 private String password; 074 075 /** 076 * The java class name of the database driver to connect the database. 077 * The .jar with that class file should be provided as a dependency of this plugin 078 */ 079 @Parameter(required=true) 080 private String driver; 081 082 /** 083 * A comma-separated list of database schemes to reverse engineer into a dingle model 084 */ 085 @Parameter(required=true) 086 private String[] schema; 087 088 /** 089 * The name of the file where to export the produced UML 1.3 model in XMI 1.2 format 090 */ 091 @Parameter(required=true) 092 private File outputFile; 093 094 /** 095 * The directory where to store the repository files 096 */ 097 @Parameter(property="project.build.directory",required=true) 098 private File workDir; 099 100 /** 101 * Performs the reverse engineering of the database by describing the database schema into the 102 * repository provided. 103 * @throws MojoExecutionException 104 */ 105 public void execute() throws MojoExecutionException { 106 Connection connection; 107 ModelRepository modelRepository; 108 RefPackage extent; 109 Function<Connection, RefPackage> operation; 110 111 try { 112 modelRepository = ModelRepositoryFactory.construct(workDir); 113 try { 114 Class.forName( driver ); 115 connection = DriverManager.getConnection( url, user, password ); 116 try { 117 operation = new ReverseDatabaseOperation(modelRepository, schema); 118 extent = operation.execute( connection ); 119 } finally { 120 connection.close(); 121 } 122 modelRepository.writeExtent( extent, 123 outputFile, 124 ModelRepository.DEFAULT_XMI_VERSION); 125 } finally { 126 modelRepository.shutdown(); 127 } 128 } catch (SQLException e) { 129 throw new MojoExecutionException( "Connecting database:" + url + " with user:" + user + " and password:" + password 130 + " caused exception:", e); 131 } catch (ClassNotFoundException e) { 132 throw new MojoExecutionException( "Driver class " + driver + " not found", e); 133 134 } catch (Exception e) { 135 throw new MojoExecutionException( "", e); 136 } 137 } 138}