diff --git a/gdxapp4d-app-mmdoc/pom.xml b/gdxapp4d-app-mmdoc/pom.xml new file mode 100644 index 00000000..145d8259 --- /dev/null +++ b/gdxapp4d-app-mmdoc/pom.xml @@ -0,0 +1,84 @@ + + 4.0.0 + + love.distributedrebirth.gdxapp4d + gdxapp4d + 0.0.1-SNAPSHOT + + gdxapp4d-app-mmdoc + GDXApp⁴ᴰ-App-MMDoc + bundle + + + love.distributedrebirth.gdxapp4d + gdxapp4d-vrgem4 + ${project.version} + provided + + + org.x4o + x4o-eld-doc + + + org.x4o + x4o-html + + + org.eobjects.metamodel + MetaModel-full + + + MetaModel-openoffice + org.eobjects.metamodel + + + MetaModel-excel + org.eobjects.metamodel + + + MetaModel-couchdb + org.eobjects.metamodel + + + org.mongodb + mongo-java-driver + + + + + org.mongodb + mongo-java-driver + + + postgresql + postgresql + + + com.h2database + h2 + + + + + + org.apache.felix + maven-bundle-plugin + true + + true + true + + <_donotcopy>(.git) + <_dsannotations>* + <_metatypeannotations>* + + ${tos4.packages}, + ${vrgem4.packages} + + distributedrebirth.love + + + + + + \ No newline at end of file diff --git a/gdxapp4d-app-mmdoc/src/main/java/love/distributedrebirth/gdxapp4d/app/mmdoc/MMDocComponent.java b/gdxapp4d-app-mmdoc/src/main/java/love/distributedrebirth/gdxapp4d/app/mmdoc/MMDocComponent.java new file mode 100644 index 00000000..d5d23710 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/love/distributedrebirth/gdxapp4d/app/mmdoc/MMDocComponent.java @@ -0,0 +1,41 @@ +package love.distributedrebirth.gdxapp4d.app.mmdoc; + +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; + +import love.distributedrebirth.bassboonyd.BãßBȍőnAuthorInfoʸᴰ; +import love.distributedrebirth.gdxapp4d.tos4.service.SystemGdxLog; +import love.distributedrebirth.gdxapp4d.vrgem4.service.VrGem4DeskAppService; +import love.distributedrebirth.gdxapp4d.vrgem4.service.deskapp.DeskAppLauncher; +import love.distributedrebirth.gdxapp4d.vrgem4.service.deskapp.DeskAppMenuSection; + +@Component +@BãßBȍőnAuthorInfoʸᴰ(name = "للَّٰهِilLצسُو", copyright = "©Δ∞ 仙上主天") +public class MMDocComponent { + + @Reference + private SystemGdxLog log; + + @Reference + private VrGem4DeskAppService deskAppService; + + private final DeskAppLauncher launcher; + + public MMDocComponent() { + launcher = new DeskAppLauncher(DeskAppMenuSection.PROGRAMMING, "MMDoc", () -> new MMDocDeskApp()); + } + + @Activate + void open() { + log.debug(this, SystemGdxLog.ACTIVATE); + deskAppService.installDeskApp(launcher); + } + + @Deactivate + void close() { + log.debug(this, SystemGdxLog.DEACTIVATE); + deskAppService.removeDeskApp(launcher); + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/love/distributedrebirth/gdxapp4d/app/mmdoc/MMDocDeskApp.java b/gdxapp4d-app-mmdoc/src/main/java/love/distributedrebirth/gdxapp4d/app/mmdoc/MMDocDeskApp.java new file mode 100644 index 00000000..3f7a9ca1 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/love/distributedrebirth/gdxapp4d/app/mmdoc/MMDocDeskApp.java @@ -0,0 +1,58 @@ +package love.distributedrebirth.gdxapp4d.app.mmdoc; + +import imgui.ImGui; +import imgui.flag.ImGuiTableFlags; +import love.distributedrebirth.bassboonyd.BãßBȍőnAuthorInfoʸᴰ; +import love.distributedrebirth.gdxapp4d.vrgem4.service.deskapp.AbstractDeskApp; +import love.distributedrebirth.gdxapp4d.vrgem4.service.deskapp.DeskAppContourSection; +import love.distributedrebirth.gdxapp4d.vrgem4.service.deskapp.DeskAppRenderer; + +@BãßBȍőnAuthorInfoʸᴰ(name = "للَّٰهِilLצسُو", copyright = "©Δ∞ 仙上主天") +public class MMDocDeskApp extends AbstractDeskApp implements DeskAppRenderer { + + public void create() { + getContours().setTitle("MMDoc"); + getContours().registrateContour(DeskAppContourSection.MAIN, this); + } + + @Override + public void render() { + ImGui.text("Current amount:"); + ImGui.sameLine(); + ImGui.text("0000"); + ImGui.separator(); + + if (ImGui.button("Add")) { + + } + ImGui.sameLine(); + if (ImGui.button("Generate")) { + + } + + ImGui.separator(); + ImGui.text("DataSources:"); + int flags = ImGuiTableFlags.ScrollX | ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersOuter | ImGuiTableFlags.BordersV | ImGuiTableFlags.Resizable; + ImGui.beginTable("DataSources", 4, flags); + ImGui.tableSetupColumn("In/Out"); + ImGui.tableSetupColumn("Amount"); + ImGui.tableSetupColumn("Fraction"); + ImGui.tableSetupColumn("Decimal"); + ImGui.tableHeadersRow(); + + String[] walletData = {"test", "test", "test"}; + + for (String data:walletData) { + ImGui.tableNextRow(); + ImGui.tableNextColumn(); + ImGui.text(data); + ImGui.tableNextColumn(); + ImGui.text(data); + ImGui.tableNextColumn(); + ImGui.text(data); + ImGui.tableNextColumn(); + ImGui.text(data); + } + ImGui.endTable(); + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/love/distributedrebirth/gdxapp4d/app/mmdoc/MMDocManager.java b/gdxapp4d-app-mmdoc/src/main/java/love/distributedrebirth/gdxapp4d/app/mmdoc/MMDocManager.java new file mode 100644 index 00000000..5672756a --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/love/distributedrebirth/gdxapp4d/app/mmdoc/MMDocManager.java @@ -0,0 +1,89 @@ +package love.distributedrebirth.gdxapp4d.app.mmdoc; + +import java.io.File; +import java.sql.DriverManager; +import java.sql.SQLException; + +import org.eobjects.metamodel.doc.DocModelDataStore; +import org.eobjects.metamodel.doc.DocModelWriter; +import org.eobjects.metamodel.jdbc.JdbcDataContext; +import org.eobjects.metamodel.mongodb.MongoDbDataContext; + +import com.mongodb.Mongo; +import com.mongodb.MongoOptions; +import com.mongodb.ServerAddress; + +public enum MMDocManager { + + INSTANCE; + + private String DB_URL = "jdbc:mariadb://localhost/"; + private String DB_USER = "test"; + private String DB_PASS = "test"; + private String PDB_URL = "jdbc:postgresql:"; + private String PDB_USER = "postgres"; + private String PDB_PASS = "postgresql"; + private String MONGO_HOST = "localhost"; + private String MS_URL = "jdbc:sqlserver://localhost"; + private String MS_USER = "sa"; + private String MS_PASS = "admin123"; + private Mongo mongo = null; + + private MMDocManager() { + } + + public void testWriteDocModel() throws Exception { + Class.forName(org.postgresql.Driver.class.getName()); + Class.forName(org.h2.Driver.class.getName()); + //Class.forName(com.microsoft.sqlserver.jdbc.SQLServerDriver.class.getName()); + mongo = new Mongo(new ServerAddress(MONGO_HOST),new MongoOptions()); + + File targetPath = new File("target/mm-doc2"); + DocModelDataStore dms = buildDocModelStore(); + try { + DocModelWriter writer = new DocModelWriter(dms); + writer.writeModelDoc(targetPath); + } finally { + dms.clearAndCloseAllSafe(); + } + //assertTrue(targetPath.exists()); + } + + private DocModelDataStore buildDocModelStore() throws SQLException { + DocModelDataStore dms = new DocModelDataStore(); + + //buildDocModelStoreJdbcPg(dms,"dellstore2"); + + buildDocModelStoreJdbcPg(dms,"fsim"); + buildDocModelStoreJdbcPg(dms,"openbravo"); + buildDocModelStoreJdbcPg(dms,"dellstore2"); + buildDocModelStoreJdbcPg(dms,"pagila"); + + /* + buildDocModelStoreMongoDB(dms,"lia"); + buildDocModelStoreMongoDB(dms,"lefiona"); + + dms.addDataContext("xml-pom-doc",new XmlDomDataContext(new File("pom.xml"),false)); + + dms.addDataContext("csv-people",new CsvDataContext(new File("src/test/resources/junit/csv-data/meta-people.csv"))); + dms.addDataContext("csv-project",new CsvDataContext(new File("src/test/resources/junit/csv-data/meta-project.csv"))); + */ + return dms; + } + + private void buildDocModelStoreJdbcMy(DocModelDataStore ds,String dbName) throws SQLException { + ds.addDataContext("my-"+dbName,new JdbcDataContext(DriverManager.getConnection(DB_URL+dbName,DB_USER,DB_PASS))); + } + + private void buildDocModelStoreJdbcPg(DocModelDataStore ds,String dbName) throws SQLException { + ds.addDataContext("pg-"+dbName,new JdbcDataContext(DriverManager.getConnection(PDB_URL+dbName,PDB_USER,PDB_PASS))); + } + + private void buildDocModelStoreMongoDB(DocModelDataStore ds,String dbName) { + ds.addDataContext("mongo-"+dbName,new MongoDbDataContext(mongo.getDB(dbName))); + } + + private void buildDocModelStoreJdbcMs(DocModelDataStore ds,String dbName) throws SQLException { + ds.addDataContext("ms-"+dbName,new JdbcDataContext(DriverManager.getConnection(MS_URL+";databaseName="+dbName,MS_USER,MS_PASS))); + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelDataStore.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelDataStore.java new file mode 100644 index 00000000..0bc12249 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelDataStore.java @@ -0,0 +1,59 @@ +package org.eobjects.metamodel.doc; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.Map.Entry; + +import org.eobjects.metamodel.DataContext; +import org.eobjects.metamodel.jdbc.JdbcDataContext; + +public class DocModelDataStore { + + private Map dataContexts = null; + + public DocModelDataStore() { + dataContexts = new TreeMap(); + } + + public void addDataContext(String id,DataContext dataContext) { + dataContexts.put(id,dataContext); + } + + public void removeDataContext(String id) { + dataContexts.remove(id); + } + + public Set> entrySet() { + return dataContexts.entrySet(); + } + + public List getDataContexts() { + return new ArrayList(dataContexts.values()); // are ordered on id. + } + + public String getDataContextKey(DataContext dc) { + for (Entry entry:entrySet()) { + if (entry.getValue().equals(dc)) { + return entry.getKey(); + } + } + throw new IllegalArgumentException("Could not find key for data context: "+dc.toString()); + } + + public void clearAndCloseAllSafe() { + for (DataContext dc:dataContexts.values()) { + if (dc instanceof JdbcDataContext) { // TODO: only support jdbc, MM need 'DataContextLifeCycle extends DataContext' + try { + ((JdbcDataContext)dc).getConnection().close(); + } catch (SQLException e) { // swallow exception is 'Safe' postfix. + // TODO: logger.warn + } + } + } + dataContexts.clear(); + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelWriter.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelWriter.java new file mode 100644 index 00000000..6da43734 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelWriter.java @@ -0,0 +1,172 @@ +package org.eobjects.metamodel.doc; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.eobjects.metamodel.DataContext; +import org.eobjects.metamodel.schema.Column; +import org.eobjects.metamodel.schema.Relationship; +import org.eobjects.metamodel.schema.Schema; +import org.eobjects.metamodel.schema.Table; +import org.x4o.xml.eld.doc.api.ApiDocWriter; +import org.x4o.xml.eld.doc.api.DefaultPageWriterHelp; +import org.x4o.xml.eld.doc.api.DefaultPageWriterIndexAll; +import org.x4o.xml.eld.doc.api.DefaultPageWriterTree; +import org.x4o.xml.eld.doc.api.dom.ApiDoc; +import org.x4o.xml.eld.doc.api.dom.ApiDocConcept; +import org.x4o.xml.eld.doc.api.dom.ApiDocNode; +import org.xml.sax.SAXException; + +public class DocModelWriter { + + private static final String[] C_DATA_STORE = {"data-store","Overview","All data stores.","The data stores of user defines resources."}; + private static final String[] C_DATA_CONTEXT = {"data-context","DataContext","The MetaModel DataContext.","The MetaModel DataContext provides the meta schema definitions."}; + private static final String[] C_SCHEMA = {"schema","Schema","The schema.","The schema hold the tables and other data types."}; + private static final String[] C_TABLE = {"table","Table","The Data Table.","The table has columns so can hold row/column data."}; + //private static final String[] C_VIEW = {"view","Table","The Data Table.","The table has columns so can hold row/column data."}; + + private static final String[] CC_RS = {"relationship","Relationship","The relationships.","The telationships data."}; + + private ApiDocWriter writer = null; + private ApiDoc doc = null; + + public DocModelWriter(DocModelDataStore dmds) { + if (dmds==null) { + throw new NullPointerException("Can't write null "+DocModelDataStore.class.getSimpleName()); + } + doc = buildApiDoc(dmds); + writer = new ApiDocWriter(); + } + + public ApiDoc getApiDoc() { + return doc; + } + + public void writeModelDoc(File basePath) throws IOException, SAXException { + doc.checkModel(); + writer.write(doc,basePath); + } + + private ApiDoc buildApiDoc(DocModelDataStore dmds) { + ApiDoc doc = new ApiDoc(); + doc.setName("MetaModel"); + doc.setDescription("MetaModel generic schema overview."); + doc.setDocAbout("MetaModel of\nDataContexts"); + doc.createDocCopyright(System.getProperty("user.name")); + doc.setDocPageSubTitle("MMDB 1.0 API"); + doc.addMetaKeywordAll(createLanguageKeywords()); + doc.setNoFrameAllName("All Schemas"); + doc.setFrameNavOverviewPrintParent(true); + doc.setFrameNavPrintParent(true); + doc.setFrameNavPrintParentParent(true); + doc.setGroupTypeName("summary", "Summary",1); + doc.setGroupTypeName("overview", "Overview",2); + + //doc.addRemoteClass(new ApiDocRemoteClass("file:///home/willemc/devv/git/x4o/x4o-driver/target/apidocs")); + //doc.addRemoteClass(new ApiDocRemoteClass("http://docs.oracle.com/javase/7/docs/api/")); + + doc.addTreeNodeClassExclude(Relationship.class); + + doc.setFrameNavConceptClass(Table.class); + + doc.addTreeNodePageModeClass(DocModelDataStore.class); + doc.addTreeNodePageModeClass(DataContext.class); + doc.addTreeNodePageModeClass(Schema.class); + + doc.addAnnotatedClasses(DocModelWriterSchema.class); + doc.addAnnotatedClasses(DocModelWriterTable.class); + + ApiDocConcept adc1 = doc.addConcept(new ApiDocConcept(null,C_DATA_STORE,DocModelDataStore.class)); + ApiDocConcept adc2 = doc.addConcept(new ApiDocConcept(adc1,C_DATA_CONTEXT,DataContext.class)); + ApiDocConcept adc3 = doc.addConcept(new ApiDocConcept(adc2,C_SCHEMA,Schema.class)); + ApiDocConcept adc4 = doc.addConcept(new ApiDocConcept(adc3,C_TABLE,Table.class)); + + adc4.addChildConcepts(new ApiDocConcept(adc4, CC_RS, Relationship.class)); + + doc.addDocPage(DefaultPageWriterTree.createDocPage()); + doc.addDocPage(DefaultPageWriterIndexAll.createDocPage()); + doc.addDocPage(DefaultPageWriterHelp.createDocPage()); + + ApiDocNode rootNode = new ApiDocNode(dmds,"data-store","DataStore","All schemas from all data contexts."); + doc.setRootNode(rootNode); + for (Entry entry:dmds.entrySet()) { + ApiDocNode dcNode = rootNode.addNode(createNodeDataContext(entry)); + for (Schema schema:entry.getValue().getSchemas()) {; + if (isInvalidDocSchema(schema)) { + continue; + } + ApiDocNode schemaNode = dcNode.addNode(createNodeSchema(schema)); + for (Table table:schema.getTables()) { + schemaNode.addNode(createNodeTable(table)); + } + for (Relationship rs:schema.getRelationships()) { + schemaNode.addNode(createNodeRelationship(rs)); + } + } + } + return doc; + } + + private boolean isInvalidDocSchema(Schema schema) { + if (schema.getName().toLowerCase().startsWith("information_schema")) { + return true; + } + if (schema.getName().toLowerCase().equals("sys") || schema.getName().toLowerCase().equals("dbo") ) { + return true; + } + if (schema.getTableCount()==0) { + return true; + } + return false; + } + + private ApiDocNode createNodeDataContext(Entry entry) { + return new ApiDocNode(entry.getValue(),entry.getKey(),entry.getKey(),entry.getKey()); + } + private ApiDocNode createNodeSchema(Schema schema) { + return new ApiDocNode(schema,schema.getName(),schema.getQualifiedLabel(),schema.getName()); + } + private ApiDocNode createNodeTable(Table table) { + return new ApiDocNode(table,table.getName(),table.getQualifiedLabel(),table.getRemarks()); + } + private ApiDocNode createNodeRelationship(Relationship rs) { + String name = rsName(rs); + return new ApiDocNode(rs,name,name,name); + } + + private String rsName(Relationship rs) { + StringBuilder buf = new StringBuilder(); + buf.append(rs.getPrimaryTable().getName()); + buf.append('_'); + for (Column c:rs.getPrimaryColumns()) { + buf.append(c.getName()); + buf.append('_'); + } + buf.append(rs.getForeignTable().getName()); + buf.append('_'); + for (Column c:rs.getForeignColumns()) { + buf.append(c.getName()); + buf.append('_'); + } + buf.append("RS"); + return buf.toString(); + } + + private List createLanguageKeywords() { + List keywords = new ArrayList(10); + keywords.add("eobjects"); + keywords.add("metamodel"); + keywords.add("meta-model"); + keywords.add("schema"); + keywords.add("schema-model"); + keywords.add("database"); + keywords.add("database-model"); + keywords.add("documentation"); + keywords.add("javadoc"); + keywords.add("x4o"); + return keywords; + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelWriterSchema.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelWriterSchema.java new file mode 100644 index 00000000..5ab738b8 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelWriterSchema.java @@ -0,0 +1,76 @@ +package org.eobjects.metamodel.doc; + +import java.util.ArrayList; +import java.util.List; + +import org.eobjects.metamodel.DataContext; +import org.eobjects.metamodel.data.DataSet; +import org.eobjects.metamodel.query.FunctionType; +import org.eobjects.metamodel.schema.Schema; +import org.eobjects.metamodel.schema.Table; +import org.eobjects.metamodel.schema.TableType; +import org.x4o.xml.eld.doc.api.ApiDocContentCss; +import org.x4o.xml.eld.doc.api.ApiDocContentWriter; +import org.x4o.xml.eld.doc.api.ApiDocNodeWriterMethod; +import org.x4o.xml.eld.doc.api.dom.ApiDocNode; +import org.x4o.xml.eld.doc.api.dom.ApiDocNodeBody; +import org.x4o.xml.eld.doc.api.dom.ApiDocWriteEvent; +import org.xml.sax.SAXException; + +public class DocModelWriterSchema { + + private List filterTables(Schema schema,TableType tableType,boolean addEquals) { + List
result = new ArrayList
(); + for (Table table:schema.getTables()) { + if (addEquals==tableType.equals(table.getType())) { + result.add(table); + } + } + return result; + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={Schema.class}) + public void writeSchemaTableSummary(ApiDocWriteEvent event) throws SAXException { + ApiDocContentWriter writer = event.getWriter(); + Schema schema = (Schema)event.getEventObject().getUserData(); + DataContext dc = (DataContext)event.getEventObject().getParent().getUserData(); + List
tables = filterTables(schema,TableType.VIEW,false); + if (tables.isEmpty()) { + return; + } + writer.docTableStart("Table Summary", "All tables in the schema.",ApiDocContentCss.overviewSummary); + writer.docTableHeader("Name", "Description"); + for (Table table:tables) { + Number tableCount = 0l; + if (table.getColumnCount()>0) { + DataSet ds = dc.query().from(table).select(FunctionType.COUNT, table.getColumns()[0]).execute(); + ds.next(); + tableCount = (Number)ds.getRow().getValue(0); + ds.close(); + } + String link = ApiDocContentWriter.toSafeUri(table.getName())+"/index.html"; + writer.docTableRowLink(link,table.getName(),"Record Count: "+tableCount); + } + writer.docTableEnd(); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={Schema.class}) + public void writeSchemaViewSummary(ApiDocWriteEvent event) throws SAXException { + ApiDocContentWriter writer = event.getWriter(); + Schema schema = (Schema)event.getEventObject().getUserData(); + List
tables = filterTables(schema,TableType.VIEW,true); + if (tables.isEmpty()) { + return; + } + writer.docTableStart("View Summary", "All views in the schema.",ApiDocContentCss.overviewSummary); + writer.docTableHeader("Name", "Description"); + for (Table table:schema.getTables()) { + if (!TableType.VIEW.equals(table.getType())) { + continue; + } + String link = ApiDocContentWriter.toSafeUri(table.getName())+"/index.html"; + writer.docTableRowLink(link,table.getName(),table.getQualifiedLabel()); + } + writer.docTableEnd(); + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelWriterTable.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelWriterTable.java new file mode 100644 index 00000000..c4494c71 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/DocModelWriterTable.java @@ -0,0 +1,412 @@ +package org.eobjects.metamodel.doc; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eobjects.metamodel.DataContext; +import org.eobjects.metamodel.doc.jdbc.DBIndex; +import org.eobjects.metamodel.doc.jdbc.DBIndexColumn; +import org.eobjects.metamodel.doc.jdbc.DBTable; +import org.eobjects.metamodel.doc.jdbc.DBTableFactory; +import org.eobjects.metamodel.jdbc.JdbcDataContext; +import org.eobjects.metamodel.schema.Column; +import org.eobjects.metamodel.schema.Relationship; +import org.eobjects.metamodel.schema.Table; +import org.eobjects.metamodel.schema.TableType; +import org.x4o.html.ContentWriterHtml.Tag; +import org.x4o.xml.eld.doc.api.ApiDocContentCss; +import org.x4o.xml.eld.doc.api.ApiDocContentWriter; +import org.x4o.xml.eld.doc.api.ApiDocNodeWriterMethod; +import org.x4o.xml.eld.doc.api.dom.ApiDocIndexItem; +import org.x4o.xml.eld.doc.api.dom.ApiDocNode; +import org.x4o.xml.eld.doc.api.dom.ApiDocNodeBody; +import org.x4o.xml.eld.doc.api.dom.ApiDocWriteEvent; +import org.xml.sax.SAXException; + +public class DocModelWriterTable { + + private DBTableFactory dbTableFactory; + private DBTable currentDBTable; + + public DocModelWriterTable() { + dbTableFactory = new DBTableFactory(); + } + + private DBTable getDBTable(ApiDocWriteEvent event) { + Table table = (Table)event.getEventObject().getUserData(); + if (currentDBTable!=null && currentDBTable.getTable().getQualifiedLabel().equals(table.getQualifiedLabel())) + { + return currentDBTable; + } + DataContext dcRaw = (DataContext)event.getEventObject().getParent().getParent().getUserData(); + if (dcRaw instanceof JdbcDataContext) { + JdbcDataContext dc = (JdbcDataContext) dcRaw; + try { + currentDBTable = dbTableFactory.loadMetaTable(dc, table); + return currentDBTable; + } catch (SQLException e) { + throw new IllegalStateException("Could not fetch meta table: "+e.getMessage(),e); + } + } else { + return null; + } + } + + private List rsFilter(Relationship[] rsa,Table table,boolean filterPrimary) { + List result = new ArrayList(10); + for (int i=0;i event) throws SAXException { + ApiDocContentWriter writer = event.getWriter(); + Table table = (Table)event.getEventObject().getUserData(); + + if (!TableType.VIEW.equals(table.getType())) { + Iterator rsIn = rsFilter(table.getRelationships(),table,false).iterator(); + Iterator rsOut = rsFilter(table.getRelationships(),table,true).iterator(); + writer.printTagStart(Tag.dl); + writer.printTagCharacters(Tag.dt,"All Incoming Relations:"); + writer.printTagStart(Tag.dd); + if (!rsIn.hasNext()) { + writer.printCharacters("Table is not referenced."); + } + while (rsIn.hasNext()) { + Relationship rs = rsIn.next(); + String uri = "../../"+ApiDocContentWriter.toSafeUri(rs.getForeignTable().getSchema().getName())+"/"+ApiDocContentWriter.toSafeUri(rs.getForeignTable().getName())+"/index.html"; + writer.printHref(uri, rs.getForeignTable().getName()); + if (rsIn.hasNext()) { + writer.printCharacters(", "); + } + } + writer.printTagEnd(Tag.dd); + writer.printTagEnd(Tag.dl); + + writer.printTagStart(Tag.dl); + writer.printTagCharacters(Tag.dt,"All Referenced Tables:"); + writer.printTagStart(Tag.dd); + if (!rsOut.hasNext()) { + writer.printCharacters("Table has no references."); + } + while (rsOut.hasNext()) { + Relationship rs = rsOut.next(); + String uri = "../../"+ApiDocContentWriter.toSafeUri(rs.getPrimaryTable().getSchema().getName())+"/"+ApiDocContentWriter.toSafeUri(rs.getPrimaryTable().getName())+"/index.html"; + writer.printHref(uri, rs.getPrimaryTable().getName()); + if (rsOut.hasNext()) { + writer.printCharacters(", "); + } + } + writer.printTagEnd(Tag.dd); + writer.printTagEnd(Tag.dl); + } + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.DESCRIPTION_NODE,targetClasses={Table.class}) + public void writeTableSqlView(ApiDocWriteEvent event) throws SAXException { + ApiDocContentWriter writer = event.getWriter(); + Table table = (Table)event.getEventObject().getUserData(); + + // fixme or only normal + if (!TableType.VIEW.equals(table.getType())) { + event.getWriter().printCharacters(event.getEventObject().getDescription()); + } else { + event.getWriter().printCharacters("View "+table.getQualifiedLabel()); + } + + DBTable tableDB = getDBTable(event); + if (tableDB!=null && tableDB.getSqlScript()!=null) { + writeSqlBlock(writer,tableDB.getSqlScript()); + for (DBIndex index:tableDB.getIndexes()) { + if (index.getSqlScript()!=null) { + writeSqlBlock(writer,index.getSqlScript()); + } + } + } + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={Table.class},nodeBodyOrders={3},contentGroup="Columns",contentGroupType="summary") + public void writeTableSummary(ApiDocWriteEvent event) throws SAXException { + ApiDocContentWriter writer = event.getWriter(); + Table table = (Table)event.getEventObject().getUserData(); + if (TableType.VIEW.equals(table.getType())) { + writer.docTableStart("Column Summary", "All column of the view.",null); + } else { + writer.docTableStart("Column Summary", "All column of the table.",null); + } + writer.docTableHeader("Name", "Description"); + for (Column column:table.getColumns()) { + writer.docTableRowLink("#"+ApiDocContentWriter.toSafeUri(column.getName()),column.getName(),column.getQualifiedLabel()); + } + writer.docTableEnd(); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={Table.class},nodeBodyOrders={1},contentGroup="Primary Key",contentGroupType="summary") + public void writeTablePKSummary(ApiDocWriteEvent event) throws SAXException { + ApiDocContentWriter writer = event.getWriter(); + Table table = (Table)event.getEventObject().getUserData(); + DBTable tableDB = getDBTable(event); + if (tableDB==null) { + writer.docPageBlockStart("Primary Key.","primary_key",null); + writer.printTagStart(Tag.code); + Column[] cols = table.getPrimaryKeys(); + for (int i=0;i cols = new ArrayList(5); + if (tableDB.getPrimaryKey()!=null) { + cols.addAll(tableDB.getPrimaryKey().getColumnNames()); + writer.docPageBlockStart("Primary Key: "+tableDB.getPrimaryKey().getName(),"primary_key",null); + } else { + writer.docPageBlockStart("Primary Key: None","primary_key",null); + } + writer.printTagStart(Tag.code); + + for (int i=0;i event) throws SAXException { + ApiDocContentWriter writer = event.getWriter(); + Table table = (Table)event.getEventObject().getUserData(); + DBTable tableDB = getDBTable(event); + if (tableDB==null) { + Column[] columns = table.getIndexedColumns(); + if (columns.length==0) { + return; + } + writer.printHrefNamed("column_indexes"); + writer.printTagCharacters(Tag.h3, "Indexed Columns"); + writer.printTagStart(Tag.code); + for (Column column:columns) { + writer.printHref("#"+ApiDocContentWriter.toSafeUri(column.getName()), column.getName()); + } + writer.printTagEnd(Tag.code); + } else { + writer.printHrefNamed("column_indexes"); + //writer.printTagCharacters(Tag.h3, "Indexes"); + writer.docTableStart("Column Indexes", "All indexes of the table.",null); + writer.docTableHeader("Name", "Columns"); + for (DBIndex index:tableDB.getIndexes()) { + StringBuilder buf = new StringBuilder(30); + List cols = index.getIndexColumns(); + for (int i=0;i event) throws SAXException { + ApiDocContentWriter writer = event.getWriter(); + //Table table = (Table)event.getEventObject().getUserData(); + DBTable tableDB = getDBTable(event); + if (tableDB==null) { + return; + } + for (DBIndex index:tableDB.getIndexes()) { + writer.printHrefNamed(index.getName()); + writer.docPageBlockStart(); + writer.printTagCharacters(Tag.h4, index.getName()); + + writer.printTagStart(Tag.pre); + writer.printCharacters("INDEX "); + writer.printCharacters(index.getSchema()); + writer.printCharacters("."); + writer.printCharacters(index.getName()); + if (index.getUnique()!=null && index.getUnique()) { + writer.printCharacters(" UNIQUE=true"); + } + if (index.getIndexQualifier()!=null) { + writer.printCharacters(" QUALIFIER="); + writer.printCharacters(index.getIndexQualifier()); + } + if (index.getCatalog()!=null) { + writer.printCharacters(" CATELOG="); + writer.printCharacters(index.getCatalog()); + } + writer.printTagEnd(Tag.pre); + + + writer.printTagStart(Tag.div,ApiDocContentCss.block); + writer.printCharacters("Type: "); + writer.printCharacters(index.getType().name()); + writer.printTagEnd(Tag.div); + + if (index.getSqlScript()!=null) { + writeSqlBlock(writer,index.getSqlScript()); + } + + writer.printTagStart(Tag.dl); + writer.printTagStart(Tag.dt); + writer.printTagStart(Tag.span,ApiDocContentCss.strong); + writer.printCharacters("Columns:"); + writer.printTagEnd(Tag.span); + writer.printTagEnd(Tag.dt); + for (DBIndexColumn column:index.getIndexColumns()) { + writer.printTagStart(Tag.dd); + writer.printTagStart(Tag.code); + writer.printHref("#"+ApiDocContentWriter.toSafeUri(column.getColumn()), column.getColumn()); + writer.printTagEnd(Tag.code); + writer.printCharacters(" ORDER "); + if (column.getAscending()!=null && column.getAscending()) { + writer.printCharacters("ASC"); + } else { + writer.printCharacters("DESC"); + } + writer.printTagEnd(Tag.dd); + } + writer.printTagEnd(Tag.dl); + + writer.docPageBlockEnd(); + } + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.DETAIL,targetClasses={Table.class},nodeBodyOrders={2},contentGroup="Columns",contentGroupType="overview") + public void writeTableDetail(ApiDocWriteEvent event) throws SAXException { + ApiDocContentWriter writer = event.getWriter(); + Table table = (Table)event.getEventObject().getUserData(); + DBTable tableDB = getDBTable(event); + for (Column column:table.getColumns()) { + + ApiDocIndexItem indexItem = new ApiDocIndexItem(); + indexItem.setLinkText(column.getName()); + event.getDoc().getNodeData().addIndexItem(indexItem); + + writer.printHrefNamed(column.getName()); + writer.docPageBlockStart(); + writer.printTagCharacters(Tag.h4, column.getName()); + + writer.printTagStart(Tag.pre); + writer.printCharacters(column.getQualifiedLabel()); + writer.printCharacters(" "); + if (column.getNativeType() != null) { + writer.printCharacters(column.getNativeType().toUpperCase()); + } + if (column.getColumnSize()!=null) { + writer.printCharacters(" ("); + writer.printCharacters(""+column.getColumnSize()); + writer.printCharacters(")"); + } + if (column.isNullable()) { + writer.printCharacters(" NULL"); + } else { + writer.printCharacters(" NOT NULL"); + } + if (column.isPrimaryKey()) { + writer.printCharacters(" PRIMARY KEY"); + } + writer.printTagEnd(Tag.pre); + + + writer.printTagStart(Tag.div,ApiDocContentCss.block); + writer.printCharacters("Description: "); + writer.printCharacters(column.getQuotedName()); + writer.printTagEnd(Tag.div); + + writer.printTagStart(Tag.dl); + if (column.isIndexed()) { + List idx = null; + if (tableDB!=null) { + idx = tableDB.getIndexesByColumn(column.getName()); + } + writer.printTagStart(Tag.dt); + writer.printTagStart(Tag.span,ApiDocContentCss.strong); + writer.printCharacters("Indexes:"); + writer.printTagEnd(Tag.span); + writer.printTagEnd(Tag.dt); + + if (idx!=null) { + writer.printTagStart(Tag.dd); + writer.printTagStart(Tag.code); + for (int i=0;i indexColumns = null; + private String sqlScript = null; + + public DBIndex() { + indexColumns = new ArrayList(3); + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + protected void setName(String name) { + this.name = name; + } + + /** + * @return the schema + */ + public String getSchema() { + return schema; + } + + /** + * @param schema the schema to set + */ + protected void setSchema(String schema) { + this.schema = schema; + } + + /** + * @return the unique + */ + public Boolean getUnique() { + return unique; + } + + /** + * @param unique the unique to set + */ + protected void setUnique(Boolean unique) { + this.unique = unique; + } + + /** + * @return the indexQualifier + */ + public String getIndexQualifier() { + return indexQualifier; + } + + /** + * @param indexQualifier the indexQualifier to set + */ + protected void setIndexQualifier(String indexQualifier) { + this.indexQualifier = indexQualifier; + } + + /** + * @return the type + */ + public DBIndexType getType() { + return type; + } + + /** + * @param type the type to set + */ + protected void setType(DBIndexType type) { + this.type = type; + } + + /** + * @return the catalog + */ + public String getCatalog() { + return catalog; + } + + /** + * @param catalog the catalog to set + */ + protected void setCatalog(String catalog) { + this.catalog = catalog; + } + + /** + * @return the indexColumns + */ + public List getIndexColumns() { + return indexColumns; + } + + /** + * @param indexColumn the indexColumn to add + */ + protected void addIndexColumn(DBIndexColumn indexColumn) { + this.indexColumns.add(indexColumn); + } + + /** + * @return the sqlScript + */ + public String getSqlScript() { + return sqlScript; + } + + /** + * @param sqlScript the sqlScript to set + */ + public void setSqlScript(String sqlScript) { + this.sqlScript = sqlScript; + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBIndexColumn.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBIndexColumn.java new file mode 100644 index 00000000..605c8976 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBIndexColumn.java @@ -0,0 +1,50 @@ +package org.eobjects.metamodel.doc.jdbc; + +public class DBIndexColumn { + + private String table = null; + private String column = null; + private Boolean ascending = null; + + /** + * @return the table + */ + public String getTable() { + return table; + } + + /** + * @param table the table to set + */ + public void setTable(String table) { + this.table = table; + } + + /** + * @return the column + */ + public String getColumn() { + return column; + } + + /** + * @param column the column to set + */ + public void setColumn(String column) { + this.column = column; + } + + /** + * @return the ascending + */ + public Boolean getAscending() { + return ascending; + } + + /** + * @param ascending the ascending to set + */ + public void setAscending(Boolean ascending) { + this.ascending = ascending; + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBIndexType.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBIndexType.java new file mode 100644 index 00000000..608cebef --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBIndexType.java @@ -0,0 +1,27 @@ +package org.eobjects.metamodel.doc.jdbc; + +import java.sql.DatabaseMetaData; + +public enum DBIndexType { + + STATISTIC, + CLUSTERED, + HASHED, + OTHER; + + public static DBIndexType parseJdbcMetaInfo(short dbType) { + if (dbType==DatabaseMetaData.tableIndexClustered) { + return CLUSTERED; + } + if (dbType==DatabaseMetaData.tableIndexHashed) { + return HASHED; + } + if (dbType==DatabaseMetaData.tableIndexOther) { + return OTHER; + } + if (dbType==DatabaseMetaData.tableIndexStatistic) { + return STATISTIC; + } + throw new IllegalArgumentException("Unknown index type: "+dbType); + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBPrimaryKey.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBPrimaryKey.java new file mode 100644 index 00000000..239a88ef --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBPrimaryKey.java @@ -0,0 +1,87 @@ +package org.eobjects.metamodel.doc.jdbc; + +import java.util.ArrayList; +import java.util.List; + +public class DBPrimaryKey { + + private String name = null; + private String catalog = null; + private String schema = null; + private String tableName = null; + private List columnNames = null; + + public DBPrimaryKey() { + columnNames = new ArrayList(3); + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the catalog + */ + public String getCatalog() { + return catalog; + } + + /** + * @param catalog the catalog to set + */ + public void setCatalog(String catalog) { + this.catalog = catalog; + } + + /** + * @return the schema + */ + public String getSchema() { + return schema; + } + + /** + * @param schema the schema to set + */ + public void setSchema(String schema) { + this.schema = schema; + } + + /** + * @return the tableName + */ + public String getTableName() { + return tableName; + } + + /** + * @param tableName the tableName to set + */ + public void setTableName(String tableName) { + this.tableName = tableName; + } + + /** + * @return the columnNames + */ + public List getColumnNames() { + return columnNames; + } + + /** + * @param columnNames the columnNames to set + */ + protected void addColumnName(String columnName) { + this.columnNames.add(columnName); + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBTable.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBTable.java new file mode 100644 index 00000000..acf0326c --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBTable.java @@ -0,0 +1,105 @@ +package org.eobjects.metamodel.doc.jdbc; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eobjects.metamodel.schema.Table; + +public class DBTable { + + private Table table; + private DBPrimaryKey primaryKey; + private List indexes; + private String sqlScript = null; + + public DBTable() { + indexes = new ArrayList(20); + } + + /** + * @return the table + */ + public Table getTable() { + return table; + } + + /** + * @param table the table to set + */ + public void setTable(Table table) { + this.table = table; + } + + /** + * @return the primaryKey + */ + public DBPrimaryKey getPrimaryKey() { + return primaryKey; + } + + /** + * @param primaryKey the primaryKey to set + */ + public void setPrimaryKey(DBPrimaryKey primaryKey) { + this.primaryKey = primaryKey; + } + + /** + * @return the indexes + */ + public List getIndexes() { + return indexes; + } + + /** + * @param index the indexes to add. + */ + public void addIndex(DBIndex index) { + this.indexes.add(index); + } + + /** + * @param indexes the indexes to add. + */ + public void addIndexes(Collection indexes) { + this.indexes.addAll(indexes); + } + + /** + * @param index the indexes to remove. + */ + public void removeIndex(DBIndex index) { + this.indexes.remove(index); + } + + /** + * @param index the indexes to add. + */ + public List getIndexesByColumn(String column) { + List result = new ArrayList(3); + for (DBIndex index:indexes) { + for (DBIndexColumn col:index.getIndexColumns()) { + if (col.getColumn().equals(column)) { + result.add(index); + break; + } + } + } + return result; + } + + /** + * @return the sqlScript + */ + public String getSqlScript() { + return sqlScript; + } + + /** + * @param sqlScript the sqlScript to set + */ + public void setSqlScript(String sqlScript) { + this.sqlScript = sqlScript; + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBTableFactory.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBTableFactory.java new file mode 100644 index 00000000..1bd5ea8a --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/DBTableFactory.java @@ -0,0 +1,157 @@ +package org.eobjects.metamodel.doc.jdbc; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.eobjects.metamodel.doc.jdbc.db.DBType; +import org.eobjects.metamodel.doc.jdbc.db.DBTypeFactory; +import org.eobjects.metamodel.jdbc.JdbcDataContext; +import org.eobjects.metamodel.schema.Table; +import org.eobjects.metamodel.schema.TableType; + +public class DBTableFactory { + + public DBTable loadMetaTable(JdbcDataContext dc,Table table) throws SQLException { + Connection conn = dc.getConnection(); + DatabaseMetaData meta = conn.getMetaData(); + DBTable result = new DBTable(); + result.setPrimaryKey(fetchPrimaryKeyInfo(meta, dc, table)); + result.setTable(table); + result.addIndexes(fetchIndexInfo(meta, dc, table)); + + DBType dbType = DBTypeFactory.getDBType(dc.getConnection()); + if (dbType!=null) { + String sqlScript; + if (TableType.VIEW.equals(table.getType())) { + sqlScript = dbType.getViewScript(dc.getConnection(), table.getName()); + } else { + sqlScript = dbType.getTableScript(dc.getConnection(), table); + } + result.setSqlScript(sqlScript); + } + return result; + } + + private DBPrimaryKey fetchPrimaryKeyInfo(DatabaseMetaData meta,JdbcDataContext dc,Table table) throws SQLException { + DBPrimaryKey result = new DBPrimaryKey(); + TreeMap columns = new TreeMap(); + ResultSet indexInformation = meta.getPrimaryKeys(dc.getCatalogName(), table.getSchema().getName(), table.getName()); + while (indexInformation.next()) { + String dbCatalog = indexInformation.getString("TABLE_CAT"); + String dbSchema = indexInformation.getString("TABLE_SCHEM"); + String dbTableName = indexInformation.getString("TABLE_NAME"); + String dbColumnName = indexInformation.getString("COLUMN_NAME"); + short dbKeySeq = indexInformation.getShort("KEY_SEQ"); + String dbPkName = indexInformation.getString("PK_NAME"); + + result.setCatalog(dbCatalog); + result.setName(dbPkName); + result.setSchema(dbSchema); + result.setTableName(dbTableName); + columns.put(dbKeySeq, dbColumnName); + } + if (result.getName()==null) { + return null; // no PK on table ! + } + result.getColumnNames().addAll(columns.values()); + return result; + } + + private List fetchIndexInfo(DatabaseMetaData meta,JdbcDataContext dc,Table table) throws SQLException { + + Map indexScripts = null; + DBType dbType = DBTypeFactory.getDBType(dc.getConnection()); + if (dbType!=null) { + indexScripts = dbType.getIndexScripts(dc.getConnection(), table.getName()); + } + + DBIndex index = new DBIndex(); + List result = new ArrayList(); + ResultSet indexInformation = meta.getIndexInfo(dc.getCatalogName(), table.getSchema().getName(), table.getName(), false, false); + while (indexInformation.next()) { + String dbCatalog = indexInformation.getString("TABLE_CAT"); + String dbSchema = indexInformation.getString("TABLE_SCHEM"); + String dbTableName = indexInformation.getString("TABLE_NAME"); + boolean dbNoneUnique = indexInformation.getBoolean("NON_UNIQUE"); + String dbIndexQualifier = indexInformation.getString("INDEX_QUALIFIER"); + String dbIndexName = indexInformation.getString("INDEX_NAME"); + short indexType = indexInformation.getShort("TYPE"); +// short dbOrdinalPosition = indexInformation.getShort("ORDINAL_POSITION"); + String dbColumnName = indexInformation.getString("COLUMN_NAME"); + String dbAscOrDesc = indexInformation.getString("ASC_OR_DESC"); +// int dbCardinality = indexInformation.getInt("CARDINALITY"); +// int dbPages = indexInformation.getInt("PAGES"); +// String dbFilterCondition = indexInformation.getString("FILTER_CONDITION"); + + if (!dbIndexName.equals(index.getName())) { + index = new DBIndex(); + result.add(index); + + if (indexScripts!=null) { + String indexScript = indexScripts.get(dbIndexName); + index.setSqlScript(indexScript); + } + } + index.setCatalog(dbCatalog); + index.setIndexQualifier(dbIndexQualifier); + index.setName(dbIndexName); + index.setSchema(dbSchema); + index.setType(DBIndexType.parseJdbcMetaInfo(indexType)); + index.setUnique(false==dbNoneUnique); + + DBIndexColumn col = new DBIndexColumn(); + col.setTable(dbTableName); + col.setColumn(dbColumnName); + col.setAscending("A".equalsIgnoreCase(dbAscOrDesc)); + index.addIndexColumn(col); + } + return result; + } + + + private List fetchExportedKeys(DatabaseMetaData meta,JdbcDataContext dc,Table table) throws SQLException { + DBIndex index = new DBIndex(); + List result = new ArrayList(); + ResultSet indexInformation = meta.getExportedKeys(dc.getCatalogName(), table.getSchema().getName(), table.getName()); + while (indexInformation.next()) { + String dbCatalog = indexInformation.getString("TABLE_CAT"); + String dbSchema = indexInformation.getString("TABLE_SCHEM"); + String dbTableName = indexInformation.getString("TABLE_NAME"); + boolean dbNoneUnique = indexInformation.getBoolean("NON_UNIQUE"); + String dbIndexQualifier = indexInformation.getString("INDEX_QUALIFIER"); + String dbIndexName = indexInformation.getString("INDEX_NAME"); + short dbType = indexInformation.getShort("TYPE"); +// short dbOrdinalPosition = indexInformation.getShort("ORDINAL_POSITION"); + String dbColumnName = indexInformation.getString("COLUMN_NAME"); + String dbAscOrDesc = indexInformation.getString("ASC_OR_DESC"); +// int dbCardinality = indexInformation.getInt("CARDINALITY"); +// int dbPages = indexInformation.getInt("PAGES"); +// String dbFilterCondition = indexInformation.getString("FILTER_CONDITION"); + + if (!dbIndexName.equals(index.getName())) { + index = new DBIndex(); + result.add(index); + } + index.setCatalog(dbCatalog); + index.setIndexQualifier(dbIndexQualifier); + index.setName(dbIndexName); + index.setSchema(dbSchema); + index.setType(DBIndexType.parseJdbcMetaInfo(dbType)); + index.setUnique(false==dbNoneUnique); + + DBIndexColumn col = new DBIndexColumn(); + col.setTable(dbTableName); + col.setColumn(dbColumnName); + col.setAscending("A".equalsIgnoreCase(dbAscOrDesc)); + index.addIndexColumn(col); + } + return result; + } + +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/DBType.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/DBType.java new file mode 100644 index 00000000..a8bdd978 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/DBType.java @@ -0,0 +1,18 @@ +package org.eobjects.metamodel.doc.jdbc.db; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Map; + +import org.eobjects.metamodel.schema.Table; + +public interface DBType { + + String getDatabaseProductName(); + + Map getIndexScripts(Connection conn,String table) throws SQLException; + + String getViewScript(Connection conn,String viewName) throws SQLException; + + String getTableScript(Connection conn,Table table) throws SQLException; +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/DBTypeFactory.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/DBTypeFactory.java new file mode 100644 index 00000000..6c4bdb02 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/DBTypeFactory.java @@ -0,0 +1,29 @@ +package org.eobjects.metamodel.doc.jdbc.db; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class DBTypeFactory { + + static private List types = new ArrayList(5); + + static { + types.add(new PostgresqlDBType()); + } + + static public final DBType getDBType(Connection conn) throws SQLException { + if (conn==null) { + throw new NullPointerException("Can't resolve db on null connection."); + } + String jdbcProductName = conn.getMetaData().getDatabaseProductName(); + for (DBType type:types) { + if (jdbcProductName.equalsIgnoreCase(type.getDatabaseProductName())) { + return type; + } + } + + return null; + } +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/DBTypeTableScripter.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/DBTypeTableScripter.java new file mode 100644 index 00000000..0cbdaeb1 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/DBTypeTableScripter.java @@ -0,0 +1,49 @@ +package org.eobjects.metamodel.doc.jdbc.db; + +import java.sql.Connection; + +import org.eobjects.metamodel.schema.Column; +import org.eobjects.metamodel.schema.Table; + +public class DBTypeTableScripter { + + + public String createTableScript(Connection conn,Table table) { + StringBuilder buf = new StringBuilder(100); + buf.append("CREATE TABLE (\n"); + Column[] cols = table.getColumns(); + for (int i=0;i getIndexScripts(Connection conn,String table) throws SQLException { + Map result = new HashMap(); + + Statement s = conn.createStatement(); + s.execute("select indexname,indexdef from pg_indexes where schemaname != 'pg_catalog' and schemaname != 'information_schema' and tablename= '"+table+"'"); + ResultSet rs = s.getResultSet(); + while (rs.next()) { + result.put(rs.getString(1), rs.getString(2)); + } + rs.close(); + + return result; + } + + public String getViewScript(Connection conn,String viewName) throws SQLException { + String result = null; + Statement s = conn.createStatement(); + s.execute("select viewname,definition from pg_views where schemaname != 'pg_catalog' and schemaname != 'information_schema' and viewname= '"+viewName+"'"); + ResultSet rs = s.getResultSet(); + if (rs.next()) { + result = rs.getString(2); + } + rs.close(); + return result; + } + + public String getTableScript(Connection conn,Table table) throws SQLException { + return new DBTypeTableScripter().createTableScript(conn, table); + } + +} diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/package-info.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/package-info.java new file mode 100644 index 00000000..554bc953 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/db/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author willemc + * + */ +package org.eobjects.metamodel.doc.jdbc.db; \ No newline at end of file diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/package-info.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/package-info.java new file mode 100644 index 00000000..184b8b41 --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/jdbc/package-info.java @@ -0,0 +1,6 @@ + +/** + * @author willemc + * + */ +package org.eobjects.metamodel.doc.jdbc; \ No newline at end of file diff --git a/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/package-info.java b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/package-info.java new file mode 100644 index 00000000..e05823ef --- /dev/null +++ b/gdxapp4d-app-mmdoc/src/main/java/org/eobjects/metamodel/doc/package-info.java @@ -0,0 +1,8 @@ + + + +/** + * @author Willem Cazander + * + */ +package org.eobjects.metamodel.doc; \ No newline at end of file diff --git a/gdxapp4d-boot-desktop/local-override.xml b/gdxapp4d-boot-desktop/local-override.xml index 0c8722e3..ae9ebddd 100644 --- a/gdxapp4d-boot-desktop/local-override.xml +++ b/gdxapp4d-boot-desktop/local-override.xml @@ -14,6 +14,7 @@ ../gdxapp4d-app-tosamp/target/classes ../gdxapp4d-app-notepad/target/classes ../gdxapp4d-app-glyphdemo/target/classes + ../gdxapp4d-app-mmdoc/target/classes ../gdxapp4d-chain-mod-vrgem4/target/chain ../gdxapp4d-vrgem4/target/classes diff --git a/gdxapp4d-chain-boot-ship-engine/pom.xml b/gdxapp4d-chain-boot-ship-engine/pom.xml index 956e69c1..1289cd7e 100644 --- a/gdxapp4d-chain-boot-ship-engine/pom.xml +++ b/gdxapp4d-chain-boot-ship-engine/pom.xml @@ -24,9 +24,9 @@ - - - + + + diff --git a/gdxapp4d-chain-boot-warp-sea/pom.xml b/gdxapp4d-chain-boot-warp-sea/pom.xml index 159dad9e..1cf4ca39 100644 --- a/gdxapp4d-chain-boot-warp-sea/pom.xml +++ b/gdxapp4d-chain-boot-warp-sea/pom.xml @@ -24,9 +24,9 @@ - - - + + + diff --git a/gdxapp4d-chain-default-apps/pom.xml b/gdxapp4d-chain-default-apps/pom.xml index 6978ef07..85adc42a 100644 --- a/gdxapp4d-chain-default-apps/pom.xml +++ b/gdxapp4d-chain-default-apps/pom.xml @@ -39,6 +39,12 @@ ${project.version} provided + + love.distributedrebirth.gdxapp4d + gdxapp4d-app-mmdoc + ${project.version} + provided + @@ -58,14 +64,15 @@ + - - - + + + diff --git a/gdxapp4d-chain-default-apps/src/main/chain/warp-hash.xml b/gdxapp4d-chain-default-apps/src/main/chain/warp-hash.xml index 47fe579c..aff19cd8 100644 --- a/gdxapp4d-chain-default-apps/src/main/chain/warp-hash.xml +++ b/gdxapp4d-chain-default-apps/src/main/chain/warp-hash.xml @@ -9,4 +9,5 @@ + diff --git a/gdxapp4d-chain-default-apps/src/main/chain/warp-sea.xml b/gdxapp4d-chain-default-apps/src/main/chain/warp-sea.xml index 6ea79d60..c0e8fc04 100644 --- a/gdxapp4d-chain-default-apps/src/main/chain/warp-sea.xml +++ b/gdxapp4d-chain-default-apps/src/main/chain/warp-sea.xml @@ -9,5 +9,6 @@ + diff --git a/gdxapp4d-chain-default-music/pom.xml b/gdxapp4d-chain-default-music/pom.xml index 13bf9257..240105c9 100644 --- a/gdxapp4d-chain-default-music/pom.xml +++ b/gdxapp4d-chain-default-music/pom.xml @@ -24,9 +24,9 @@ - - - + + + diff --git a/gdxapp4d-chain-dep-osgi-lib/pom.xml b/gdxapp4d-chain-dep-osgi-lib/pom.xml index b7328ff5..07c17798 100644 --- a/gdxapp4d-chain-dep-osgi-lib/pom.xml +++ b/gdxapp4d-chain-dep-osgi-lib/pom.xml @@ -23,7 +23,6 @@ org.apache.maven.plugins maven-dependency-plugin - 3.3.0 unpack-dependencies @@ -54,9 +53,9 @@ - - - + + + diff --git a/gdxapp4d-chain-dep-osgi-scr/pom.xml b/gdxapp4d-chain-dep-osgi-scr/pom.xml index 282cbc9c..9ac01d96 100644 --- a/gdxapp4d-chain-dep-osgi-scr/pom.xml +++ b/gdxapp4d-chain-dep-osgi-scr/pom.xml @@ -24,9 +24,9 @@ - - - + + + diff --git a/gdxapp4d-chain-font-unicode4d/pom.xml b/gdxapp4d-chain-font-unicode4d/pom.xml index 5aff2643..c16640a2 100644 --- a/gdxapp4d-chain-font-unicode4d/pom.xml +++ b/gdxapp4d-chain-font-unicode4d/pom.xml @@ -24,9 +24,9 @@ - - - + + + diff --git a/gdxapp4d-chain-mod-unitxc/pom.xml b/gdxapp4d-chain-mod-unitxc/pom.xml index 99c4daaa..11e62440 100644 --- a/gdxapp4d-chain-mod-unitxc/pom.xml +++ b/gdxapp4d-chain-mod-unitxc/pom.xml @@ -35,9 +35,9 @@ - - - + + + diff --git a/gdxapp4d-chain-mod-vrgem4/pom.xml b/gdxapp4d-chain-mod-vrgem4/pom.xml index f7fd0cbb..73c34c0c 100644 --- a/gdxapp4d-chain-mod-vrgem4/pom.xml +++ b/gdxapp4d-chain-mod-vrgem4/pom.xml @@ -35,9 +35,9 @@ - - - + + + diff --git a/gdxapp4d-chain-mod-vrsys5/pom.xml b/gdxapp4d-chain-mod-vrsys5/pom.xml index 9f77ab4a..0ef4619d 100644 --- a/gdxapp4d-chain-mod-vrsys5/pom.xml +++ b/gdxapp4d-chain-mod-vrsys5/pom.xml @@ -35,9 +35,9 @@ - - - + + + diff --git a/gdxapp4d-lib-x4o/pom.xml b/gdxapp4d-lib-x4o/pom.xml index ee0e63c0..8991aaf4 100644 --- a/gdxapp4d-lib-x4o/pom.xml +++ b/gdxapp4d-lib-x4o/pom.xml @@ -15,7 +15,6 @@ org.apache.maven.plugins maven-install-plugin - 2.5.2 deploy-local-x4o-driver @@ -26,9 +25,9 @@ org.x4o x4o-driver - 0.8.7-SNAPSHOT2 + ${x4o.version} jar - ${project.basedir}/../local-lib/x4o-driver-0.8.7-SNAPSHOT2.jar + ${project.basedir}/../local-lib/x4o-driver-${x4o.version}.jar @@ -40,9 +39,9 @@ org.x4o x4o-eld-doc - 0.8.7-SNAPSHOT2 + ${x4o.version} jar - ${project.basedir}/../local-lib/x4o-eld-doc-0.8.7-SNAPSHOT2.jar + ${project.basedir}/../local-lib/x4o-eld-doc-${x4o.version}.jar @@ -54,9 +53,9 @@ org.x4o x4o-html - 0.8.7-SNAPSHOT2 + ${x4o.version} jar - ${project.basedir}/../local-lib/x4o-html-0.8.7-SNAPSHOT2.jar + ${project.basedir}/../local-lib/x4o-html-${x4o.version}.jar @@ -68,9 +67,9 @@ org.x4o x4o-meta - 0.8.7-SNAPSHOT2 + ${x4o.version} jar - ${project.basedir}/../local-lib/x4o-meta-0.8.7-SNAPSHOT2.jar + ${project.basedir}/../local-lib/x4o-meta-${x4o.version}.jar @@ -82,9 +81,9 @@ org.x4o.tool x4o-tool-ant-plugin - 0.8.7-SNAPSHOT2 + ${x4o.version} jar - ${project.basedir}/../local-lib/x4o-tool-ant-plugin-0.8.7-SNAPSHOT2.jar + ${project.basedir}/../local-lib/x4o-tool-ant-plugin-${x4o.version}.jar @@ -96,9 +95,9 @@ org.x4o.tool x4o-tool-maven-plugin - 0.8.7-SNAPSHOT2 + ${x4o.version} jar - ${project.basedir}/../local-lib/x4o-tool-maven-plugin-0.8.7-SNAPSHOT2.jar + ${project.basedir}/../local-lib/x4o-tool-maven-plugin-${x4o.version}.jar @@ -110,10 +109,10 @@ org.x4o x4o-driver - 0.8.7-SNAPSHOT2 + ${x4o.version} jar sources - ${project.basedir}/../local-lib/x4o-driver-0.8.7-SNAPSHOT2-sources.jar + ${project.basedir}/../local-lib/x4o-driver-${x4o.version}-sources.jar @@ -125,10 +124,10 @@ org.x4o x4o-eld-doc - 0.8.7-SNAPSHOT2 + ${x4o.version} jar sources - ${project.basedir}/../local-lib/x4o-eld-doc-0.8.7-SNAPSHOT2-sources.jar + ${project.basedir}/../local-lib/x4o-eld-doc-${x4o.version}-sources.jar @@ -140,10 +139,10 @@ org.x4o x4o-html - 0.8.7-SNAPSHOT2 + ${x4o.version} jar sources - ${project.basedir}/../local-lib/x4o-html-0.8.7-SNAPSHOT2-sources.jar + ${project.basedir}/../local-lib/x4o-html-${x4o.version}-sources.jar @@ -155,10 +154,10 @@ org.x4o x4o-meta - 0.8.7-SNAPSHOT2 + ${x4o.version} jar sources - ${project.basedir}/../local-lib/x4o-meta-0.8.7-SNAPSHOT2-sources.jar + ${project.basedir}/../local-lib/x4o-meta-${x4o.version}-sources.jar @@ -170,10 +169,10 @@ org.x4o.tool x4o-tool-ant-plugin - 0.8.7-SNAPSHOT2 + ${x4o.version} jar sources - ${project.basedir}/../local-lib/x4o-tool-ant-plugin-0.8.7-SNAPSHOT2-sources.jar + ${project.basedir}/../local-lib/x4o-tool-ant-plugin-${x4o.version}-sources.jar @@ -185,10 +184,10 @@ org.x4o.tool x4o-tool-maven-plugin - 0.8.7-SNAPSHOT2 + ${x4o.version} jar sources - ${project.basedir}/../local-lib/x4o-tool-maven-plugin-0.8.7-SNAPSHOT2-sources.jar + ${project.basedir}/../local-lib/x4o-tool-maven-plugin-${x4o.version}-sources.jar @@ -273,27 +272,27 @@ org.apache.tomcat jasper-el - 6.0.20 + ${jasper-el.version} org.x4o x4o-driver - 0.8.7-SNAPSHOT2 + ${x4o.version} org.x4o x4o-eld-doc - 0.8.7-SNAPSHOT2 + ${x4o.version} org.x4o x4o-html - 0.8.7-SNAPSHOT2 + ${x4o.version} org.x4o.tool x4o-tool-ant-plugin - 0.8.7-SNAPSHOT2 + ${x4o.version} diff --git a/pom.xml b/pom.xml index 92facc70..4c498fb2 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,7 @@ gdxapp4d-chain-mod-vrgem4 gdxapp4d-chain-mod-vrsys5 gdxapp4d-lib-x4o + gdxapp4d-app-mmdoc UTF-8 @@ -43,6 +44,8 @@ 1.10.0 1.86.0 1.0.0 + 6.0.20 + 0.8.7-SNAPSHOT3 org.osgi.framework, org.osgi.service.packageadmin, @@ -199,12 +202,22 @@ org.x4o x4o-driver - 0.8.7-SNAPSHOT2 + ${x4o.version} + + + org.x4o + x4o-eld-doc + ${x4o.version} + + + org.x4o + x4o-html + ${x4o.version} org.apache.tomcat jasper-el - 6.0.20 + ${jasper-el.version} io.github.spair @@ -277,6 +290,26 @@ 1.10.0 natives-desktop + + org.eobjects.metamodel + MetaModel-full + 3.4.11 + + + org.mongodb + mongo-java-driver + 3.10.2 + + + postgresql + postgresql + 9.1-901-1.jdbc4 + + + com.h2database + h2 + 1.3.170 + @@ -320,6 +353,11 @@ maven-dependency-plugin 3.3.0 + + org.apache.maven.plugins + maven-install-plugin + 2.5.2 +