mirror of
https://github.com/Wisser/Jailer.git
synced 2026-05-15 12:08:24 -05:00
Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| acd0ec4f17 | |||
| a4ef8ac522 | |||
| 0bb4e9f649 | |||
| da1e4ccd2a | |||
| cecf7d33b8 | |||
| 95951cf824 | |||
| e1c7f5074f | |||
| 408ecfc5fc | |||
| 971a870e51 | |||
| 25cedf87d0 | |||
| b750d45050 | |||
| 97b435aa1b | |||
| 40aa392935 | |||
| 0046ef0f2d | |||
| 5eb5677799 | |||
| 03a2bf820e | |||
| 6592f0f86f | |||
| efd799b217 | |||
| 7c0ce25871 | |||
| d0b1465177 | |||
| e7e9634768 | |||
| 3a95e5e86c | |||
| 40b56a2f0f | |||
| 9ae5037037 | |||
| b217529023 | |||
| 108791f0b4 | |||
| 3934482984 | |||
| 7efa9721c9 | |||
| 78977fde51 | |||
| 40d80f6ae1 | |||
| 0bf59e8340 | |||
| 1099d41e68 | |||
| cf52be38ec | |||
| a0db0e8387 | |||
| a48b4faba1 | |||
| 75e2b1164c | |||
| 253032ba92 | |||
| 20da29b810 | |||
| 7b12c5df99 | |||
| 2e487cd77a | |||
| c0d097e8ea | |||
| 42c7f60ac6 | |||
| 3683debe1e | |||
| 1026bab646 | |||
| 8a0ef29cda | |||
| 029459a9d5 | |||
| 9bd30aef3e | |||
| 17161ed441 | |||
| 0a1c74b8d0 | |||
| 67a0f71a31 | |||
| a72e7fdb20 | |||
| ae60ccd0fc | |||
| d9ff02d0d9 | |||
| 09be36cade | |||
| e50d88ddfe | |||
| 7146e61013 | |||
| 67e552a7a1 | |||
| 5a48e73bc1 | |||
| cd838a2858 | |||
| 5a2ce2eac8 | |||
| 68ddf0a175 | |||
| e389c53861 | |||
| 9ee90fc714 | |||
| c2c04ab1fb | |||
| e3093b9593 | |||
| 971613186f | |||
| 3463fb4766 | |||
| 282c1cd180 | |||
| 3a1f98c7bd | |||
| e1b0c23404 | |||
| 07f25822d5 | |||
| 3d03b1227a | |||
| 1d7806f96d | |||
| dc5992e0e5 | |||
| c9f53810d1 | |||
| 051d24e1b1 | |||
| 7ae893da24 | |||
| ed913077c7 | |||
| f35c5b0329 | |||
| 33262683f1 | |||
| 40a6d7d853 | |||
| aded0c6529 | |||
| db972ee841 | |||
| 1f3e0182c9 | |||
| aaaa07b381 | |||
| d26423bf9f | |||
| 09bc381a4e | |||
| 8f5147f870 | |||
| e367fc6062 | |||
| 395b447f86 | |||
| 0ed829c065 | |||
| 9c85f3955e | |||
| 2a379b8543 | |||
| d00acf3881 | |||
| ce3c3192e9 | |||
| 29cbd7dcf9 | |||
| f92e7d6f13 | |||
| 6c55ea8092 | |||
| b2ce10891f | |||
| d86866758b | |||
| f3224ad625 | |||
| 5b391b85b7 | |||
| 8a8cd325b1 | |||
| c1a885f220 | |||
| 2fa811b6c6 | |||
| 3bfc6aa51d | |||
| 322c830054 | |||
| 29e460f79f | |||
| 0254c26e09 | |||
| c37064be01 | |||
| 92bc5b3ef9 | |||
| 6a99fd76a6 | |||
| a584fa787b | |||
| 8e08a70e21 | |||
| b72802c67c | |||
| 04a5df43e8 | |||
| 1518e02736 | |||
| 9e2a04abd1 |
+25
-17
@@ -1,17 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/test"/>
|
||||
<classpathentry kind="src" path="src/main/engine"/>
|
||||
<classpathentry kind="src" path="src/main/gui"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/dbunit-2.4.4.jar"/>
|
||||
<classpathentry kind="lib" path="lib/junit-4.4.jar"/>
|
||||
<classpathentry kind="lib" path="lib/log4j.jar"/>
|
||||
<classpathentry kind="lib" path="lib/prefuse.jar" />
|
||||
<classpathentry kind="lib" path="lib/sdoc-0.5.0-beta.jar" />
|
||||
<classpathentry kind="lib" path="lib/args4j.jar"/>
|
||||
<classpathentry kind="lib" path="config"/>
|
||||
<classpathentry kind="lib" path="lib/jsqlparser-1.1.jar" />
|
||||
<classpathentry kind="lib" path="lib/tablefilter-swing-5.3.1.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/test"/>
|
||||
<classpathentry kind="src" path="src/main/engine"/>
|
||||
<classpathentry kind="src" path="src/main/gui"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="lib/dbunit-2.4.4.jar"/>
|
||||
<classpathentry kind="lib" path="lib/junit-4.4.jar"/>
|
||||
<classpathentry kind="lib" path="lib/log4j.jar"/>
|
||||
<classpathentry kind="lib" path="lib/prefuse.jar"/>
|
||||
<classpathentry kind="lib" path="lib/sdoc-0.5.0-beta.jar"/>
|
||||
<classpathentry kind="lib" path="lib/args4j.jar"/>
|
||||
<classpathentry kind="lib" path="config"/>
|
||||
<classpathentry kind="lib" path="lib/jsqlparser-1.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/tablefilter-swing-5.3.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jaxb-api-2.3.0-b170201.1204.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jaxb-core-2.3.0-b170127.1453.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jaxb-impl-2.3.0-b170127.1453.jar"/>
|
||||
<classpathentry kind="lib" path="lib/activation-1.0.2.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ Informix Dynamic Server;jdbc:informix-sqli://<HOST>:<PORT>/<DB>:INFORMIXSERVER=<
|
||||
InstantDB (v3.13 and earlier);jdbc:idb:<DB>;jdbc.idbDriver
|
||||
InstantDB (v3.14 and later);jdbc:idb:<DB>;org.enhydra.instantdb.jdbc.idbDriver
|
||||
Interbase (InterClient Driver);jdbc:interbase://<HOST>/<DB>;interbase.interclient.Driver
|
||||
H2 embedded (Java SQL database);jdbc:h2:<DB-File>;org.h2.Driver;lib/h2-1.3.160.jar
|
||||
H2 TCP (Java SQL database);jdbc:h2:tcp://<HOST>/<DB-File>;org.h2.Driver;lib/h2-1.3.160.jar
|
||||
H2 embedded (Java SQL database);jdbc:h2:<DB-File>;org.h2.Driver;lib/h2-1.3.175.jar
|
||||
H2 TCP (Java SQL database);jdbc:h2:tcp://<HOST>/<DB-File>;org.h2.Driver;lib/h2-1.3.175.jar
|
||||
HyperSQL;jdbc:hsqldb:<file|hsql|http>:<DB>;org.hsqldb.jdbcDriver
|
||||
# Microsoft SQL Server (jTDS);jdbc:jtds:sqlserver://<server>[:<port>][/<database>];net.sourceforge.jtds.jdbc.Driver;lib/jtds-1.3.1.jar
|
||||
# Microsoft SQL Server (JTurbo Driver);jdbc:JTurbo://<HOST>:<PORT>/<DB>;com.ashna.jturbo.driver.Driver
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
+43
-1
@@ -1,4 +1,46 @@
|
||||
7.10.1
|
||||
8.0.1
|
||||
- Foreign key columns can be set to null if parent row is not exported.
|
||||
- Increased responsiveness and performance of the data browser GUI.
|
||||
|
||||
8.0
|
||||
- The new "PathFinder" feature allows elaborate finding
|
||||
of association paths between tables in complex data models.
|
||||
|
||||
7.11.1
|
||||
- Closing a root table did not work properly in the data browser.
|
||||
- Minor bug fixes.
|
||||
|
||||
7.11
|
||||
- Database analysis not only finds primary keys and foreign keys for tables,
|
||||
but also for views and synonyms by analyzing the underlying tables.
|
||||
- Fixed a memory leak in data browser.
|
||||
|
||||
7.10.8
|
||||
- Data browser improvements
|
||||
- New layout feature: "align table horizontally with predecessor"
|
||||
- Improved layout strategy in the data browser.
|
||||
- Improved row-to-row-link rendering performance.
|
||||
- Feature Request "Improve the usability of the Data Model Editor" (partially). see https://sourceforge.net/p/jailer/feature-requests/43/
|
||||
|
||||
7.10.7
|
||||
- Zoom in / out using the mouse wheel in the data browser
|
||||
|
||||
7.10.6
|
||||
- Minor bug fixes.
|
||||
|
||||
7.10.5
|
||||
- Animated desktop layout in the data browser.
|
||||
- Improved row-link rendering quality and performance.
|
||||
|
||||
7.10.4
|
||||
- The estimated number of rows of the tables is displayed.
|
||||
- Limited fetch size of statements to prevent an OOM exception when the default fetch size is too large (MySQL).
|
||||
- Updated H2 DBMS from version 1.3.160 to 1.3.175
|
||||
|
||||
7.10.3
|
||||
- Fix for "Can't connect to SOCKS proxy:http" https://github.com/Wisser/Jailer/issues/8
|
||||
|
||||
7.10.2
|
||||
- Added context menu to columns view of results table.
|
||||
|
||||
7.10
|
||||
|
||||
@@ -77,7 +77,7 @@ public class ExecutionContext {
|
||||
this.importFilterMappingTableSchema = other.importFilterMappingTableSchema;
|
||||
this.scope = other.scope;
|
||||
this.rawparameters = other.rawparameters;
|
||||
this.progressListenerRegistry = other.progressListenerRegistry;
|
||||
// don't share progressListenerRegistry, was: this.progressListenerRegistry = other.progressListenerRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -639,7 +639,7 @@ public class ExecutionContext {
|
||||
}
|
||||
|
||||
private URL datamodelURL;
|
||||
|
||||
|
||||
/**
|
||||
* Gets URL of the current data model (the datamodels base folder)
|
||||
*/
|
||||
@@ -652,14 +652,14 @@ public class ExecutionContext {
|
||||
fn = datamodelFolder + File.separator + currentModelSubfolder;
|
||||
}
|
||||
try {
|
||||
datamodelURL = new File(fn).toURI().toURL();
|
||||
return new File(fn).toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return datamodelURL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets URL of the current data model (the datamodels base folder)
|
||||
*/
|
||||
@@ -815,4 +815,4 @@ public class ExecutionContext {
|
||||
return map == null? null : new HashMap<String, String>(map);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ public class JailerVersion {
|
||||
/**
|
||||
* The Jailer version.
|
||||
*/
|
||||
public static final String VERSION = "7.10.1";
|
||||
public static final String VERSION = "8.0.1";
|
||||
|
||||
/**
|
||||
* The Jailer working tables version.
|
||||
|
||||
@@ -42,7 +42,7 @@ public class APIExample {
|
||||
new BasicDataSource(
|
||||
"org.h2.Driver", "jdbc:h2:demo-scott", "sa", "",
|
||||
POOL_SIZE,
|
||||
new File("lib/h2-1.3.160.jar")),
|
||||
new File("lib/h2-1.3.175.jar")),
|
||||
null,
|
||||
APIExample.class.getResource("Demo-Scott"),
|
||||
APIExample.class.getResource("Demo-Scott.csv"),
|
||||
@@ -54,7 +54,7 @@ public class APIExample {
|
||||
new BasicDataSource(
|
||||
"org.h2.Driver", "jdbc:h2:demo-scott-subset", "sa", "",
|
||||
10,
|
||||
new File("lib/h2-1.3.160.jar")));
|
||||
new File("lib/h2-1.3.175.jar")));
|
||||
|
||||
/**
|
||||
* Exports data related with employee "SCOTT"
|
||||
|
||||
@@ -104,6 +104,9 @@ public class DBMS {
|
||||
this.rowidName = other.rowidName;
|
||||
this.supportsSchemasInIndexDefinitions = other.supportsSchemasInIndexDefinitions;
|
||||
this.useInlineViewsInDataBrowser = other.useInlineViewsInDataBrowser;
|
||||
this.viewTextOrDDLQuery = other.viewTextOrDDLQuery;
|
||||
this.synonymTableQuery = other.synonymTableQuery;
|
||||
this.estimatedRowCountQuery = other.estimatedRowCountQuery;
|
||||
this.virtualColumnsQuery = other.virtualColumnsQuery;
|
||||
this.userDefinedColumnsQuery = other.userDefinedColumnsQuery;
|
||||
this.importedKeysQuery = other.importedKeysQuery;
|
||||
@@ -291,12 +294,12 @@ public class DBMS {
|
||||
private Boolean supportsSchemasInIndexDefinitions = null;
|
||||
private boolean useInlineViewsInDataBrowser = true;
|
||||
private String virtualColumnsQuery = null;
|
||||
private String synonymTableQuery;
|
||||
private String viewTextOrDDLQuery = "SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '%1$s' and TABLE_NAME = '%2$s'";
|
||||
private String estimatedRowCountQuery = null;
|
||||
private String userDefinedColumnsQuery = null;
|
||||
|
||||
private String importedKeysQuery = null;
|
||||
|
||||
private String primaryKeysQuery = null;
|
||||
|
||||
private String indexInfoQuery = null;
|
||||
private String identifierQuoteString = "\"";
|
||||
|
||||
@@ -520,7 +523,11 @@ public class DBMS {
|
||||
public Map<String, String> getTypeReplacement() {
|
||||
if (!this.equals(DBMS.ORACLE)) {
|
||||
if (typeReplacement == null || !typeReplacement.containsKey("VARCHAR2")) {
|
||||
typeReplacement = new HashMap<String, String>(typeReplacement);
|
||||
if (typeReplacement == null) {
|
||||
typeReplacement = new HashMap<String, String>();
|
||||
} else {
|
||||
typeReplacement = new HashMap<String, String>(typeReplacement);
|
||||
}
|
||||
typeReplacement.put("VARCHAR2", "VARCHAR");
|
||||
}
|
||||
}
|
||||
@@ -1007,6 +1014,42 @@ public class DBMS {
|
||||
this.constraintsQuery = constraintsQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets query to get row count.
|
||||
*/
|
||||
public String getEstimatedRowCountQuery() {
|
||||
return estimatedRowCountQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets query to get row count.
|
||||
*/
|
||||
public void setEstimatedRowCountQuery(String estimatedRowCountQuery) {
|
||||
this.estimatedRowCountQuery = estimatedRowCountQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets query to get view text.
|
||||
*/
|
||||
public String getViewTextOrDDLQuery() {
|
||||
return viewTextOrDDLQuery;
|
||||
}
|
||||
|
||||
public void setViewTextOrDDLQuery(String viewTextOrDDLQuery) {
|
||||
this.viewTextOrDDLQuery = viewTextOrDDLQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets query to get underlying table of a synonym.
|
||||
*/
|
||||
public String getSynonymTableQuery() {
|
||||
return synonymTableQuery;
|
||||
}
|
||||
|
||||
public void setSynonymTableQuery(String synonymTableQuery) {
|
||||
this.synonymTableQuery = synonymTableQuery;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
|
||||
@@ -32,7 +32,7 @@ public class LocalDatabaseConfiguration {
|
||||
private String password = "";
|
||||
|
||||
private String driver = "org.h2.Driver";
|
||||
private String lib = "lib/h2-1.3.160.jar";
|
||||
private String lib = "lib/h2-1.3.175.jar";
|
||||
|
||||
/**
|
||||
* @return the localPKType
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<!-- Configuration of the local database -->
|
||||
<localDatabase>
|
||||
<databaseFolder>local</databaseFolder>
|
||||
<lib>lib/h2-1.3.160.jar</lib>
|
||||
<lib>lib/h2-1.3.175.jar</lib>
|
||||
<driver>org.h2.Driver</driver>
|
||||
<urlPattern>jdbc:h2:%s;LOG=0;UNDO_LOG=0</urlPattern>
|
||||
<localPKType>VARCHAR</localPKType>
|
||||
@@ -63,12 +63,6 @@
|
||||
<key>CatalogOptions</key>
|
||||
<value>0</value>
|
||||
</entry>
|
||||
<!--
|
||||
<entry>
|
||||
<key>includeSynonyms</key>
|
||||
<value>true</value>
|
||||
</entry>
|
||||
-->
|
||||
</jdbcProperties>
|
||||
<statisticRenovator>
|
||||
<scriptFileName>script/oracle/gatherStatistics.sql</scriptFileName>
|
||||
@@ -111,6 +105,7 @@
|
||||
<rowidName>ROWID</rowidName>
|
||||
<rowidType>ROWID</rowidType>
|
||||
<useInlineViewsInDataBrowser>false</useInlineViewsInDataBrowser>
|
||||
<estimatedRowCountQuery>select TABLE_NAME, NUM_ROWS from all_tables where OWNER = '%s'</estimatedRowCountQuery>
|
||||
<virtualColumnsQuery>SELECT TABLE_NAME, COLUMN_NAME FROM ALL_TAB_COLS WHERE OWNER = '${SCHEMA}' AND VIRTUAL_COLUMN = 'YES' AND NOT DATA_TYPE = 'XMLTYPE'</virtualColumnsQuery>
|
||||
<importedKeysQuery>SELECT null, c_dest.OWNER, c_dest.TABLE_NAME, c_dest.COLUMN_NAME, null, c_src.OWNER, c_src.TABLE_NAME, c_src.COLUMN_NAME, c_src.POSITION, null, null, c_list.CONSTRAINT_NAME, c_list.R_CONSTRAINT_NAME, null FROM ALL_CONSTRAINTS c_list, ALL_CONS_COLUMNS c_src, ALL_CONS_COLUMNS c_dest WHERE c_list.CONSTRAINT_NAME = c_src.CONSTRAINT_NAME AND c_list.OWNER = c_src.OWNER AND c_list.R_CONSTRAINT_NAME = c_dest.CONSTRAINT_NAME AND c_list.R_OWNER = c_dest.OWNER AND c_list.CONSTRAINT_TYPE = 'R' AND c_src.POSITION = c_dest.POSITION AND c_src.OWNER = '${SCHEMA}' ORDER BY c_src.POSITION</importedKeysQuery>
|
||||
<primaryKeysQuery>SELECT null, c_src.OWNER, c_src.TABLE_NAME, c_src.COLUMN_NAME, c_src.POSITION, c_list.CONSTRAINT_NAME FROM ALL_CONSTRAINTS c_list, ALL_CONS_COLUMNS c_src WHERE c_list.CONSTRAINT_NAME = c_src.CONSTRAINT_NAME AND c_list.OWNER = c_src.OWNER AND c_list.CONSTRAINT_TYPE = 'P' AND c_list.CONSTRAINT_NAME not like 'BIN$%' AND c_src.OWNER = '${SCHEMA}' ORDER BY c_src.POSITION</primaryKeysQuery>
|
||||
@@ -120,6 +115,8 @@
|
||||
<explainPrepare>explain plan set statement_id = '%2$s' for %1$s</explainPrepare>
|
||||
<explainQuery>select * from table(dbms_xplan.display(NULL, '%2$s'))</explainQuery>
|
||||
<explainCleanup></explainCleanup>
|
||||
<synonymTableQuery>select '"' || TABLE_OWNER || '"."' || TABLE_NAME || '"' from ALL_SYNONYMS where OWNER = '%1$s' and SYNONYM_NAME = '%2$s'</synonymTableQuery>
|
||||
<viewTextOrDDLQuery>select TEXT from all_views where OWNER = '%1$s' and VIEW_NAME = '%2$s'</viewTextOrDDLQuery>
|
||||
<functionSourceQuery>SELECT 'Source', text FROM all_source WHERE type = 'FUNCTION' and name = '%2$s' AND owner = '%1$s' ORDER BY line</functionSourceQuery>
|
||||
<procedureSourceQuery>SELECT 'Source', text FROM all_source WHERE type = 'PROCEDURE' and name = '%2$s' AND owner = '%1$s' ORDER BY line</procedureSourceQuery>
|
||||
<packageNamesQuery>SELECT OBJECT_NAME FROM ALL_OBJECTS WHERE OBJECT_TYPE = 'PACKAGE' AND OWNER = '%1$s'</packageNamesQuery>
|
||||
@@ -260,6 +257,15 @@ union all
|
||||
<avoidLeftJoin>false</avoidLeftJoin>
|
||||
<supportsSchemasInIndexDefinitions>false</supportsSchemasInIndexDefinitions>
|
||||
<useInlineViewsInDataBrowser>true</useInlineViewsInDataBrowser>
|
||||
<estimatedRowCountQuery>
|
||||
SELECT tbl.name, p.rows
|
||||
FROM sys.tables AS tbl
|
||||
INNER JOIN sys.indexes AS idx ON idx.object_id = tbl.object_id and idx.index_id < 2
|
||||
INNER JOIN sys.partitions AS p ON p.object_id=CAST(tbl.object_id AS int)
|
||||
AND p.index_id=idx.index_id
|
||||
WHERE SCHEMA_NAME(tbl.schema_id)='%s'
|
||||
</estimatedRowCountQuery>
|
||||
<viewTextOrDDLQuery>SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '%1$s' and TABLE_NAME = '%2$s'</viewTextOrDDLQuery>
|
||||
<virtualColumnsQuery>SELECT sysobjects.name AS TableName, syscolumns.name AS ColumnName FROM syscolumns JOIN sysobjects ON syscolumns.id = sysobjects.id AND sysobjects.xtype = 'U' WHERE syscolumns.iscomputed = 1</virtualColumnsQuery>
|
||||
<userDefinedColumnsQuery>SELECT distinct DOMAIN_NAME from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '%s' AND DOMAIN_NAME is not null</userDefinedColumnsQuery>
|
||||
<!--
|
||||
@@ -435,7 +441,10 @@ union all
|
||||
<binaryPattern>x'%s'</binaryPattern>
|
||||
<avoidLeftJoin>false</avoidLeftJoin>
|
||||
<useInlineViewsInDataBrowser>true</useInlineViewsInDataBrowser>
|
||||
<virtualColumnsQuery>SELECT TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '${SCHEMA}' AND EXTRA LIKE '%VIRTUAL%'</virtualColumnsQuery>
|
||||
<estimatedRowCountQuery>select TABLE_NAME, CARDINALITY from INFORMATION_SCHEMA.STATISTICS where TABLE_SCHEMA = '%s'</estimatedRowCountQuery>
|
||||
<viewTextOrDDLQuery>SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '%1$s' and TABLE_NAME = '%2$s'</viewTextOrDDLQuery>
|
||||
|
||||
<virtualColumnsQuery>SELECT TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '${SCHEMA}' AND EXTRA LIKE '%VIRTUAL%'</virtualColumnsQuery>
|
||||
<!--
|
||||
<importedKeysQuery>SELECT PKCU.TABLE_SCHEMA, null, PKCU.TABLE_NAME, PKCU.COLUMN_NAME, KCU.TABLE_SCHEMA, null, KCU.TABLE_NAME, KCU.COLUMN_NAME, KCU.ORDINAL_POSITION, null, null, RC.CONSTRAINT_NAME, RC.UNIQUE_CONSTRAINT_NAME, null FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU ON KCU.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG AND KCU.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA AND KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE PKCU ON PKCU.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG AND PKCU.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA AND PKCU.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME AND PKCU.TABLE_NAME = RC.REFERENCED_TABLE_NAME AND PKCU.ORDINAL_POSITION = KCU.ORDINAL_POSITION WHERE PKCU.TABLE_SCHEMA = '${SCHEMA}' ORDER BY KCU.ORDINAL_POSITION</importedKeysQuery>
|
||||
<primaryKeysQuery>SELECT null, KCU.TABLE_SCHEMA, KCU.TABLE_NAME, KCU.COLUMN_NAME, KCU.ORDINAL_POSITION, C.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS C JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU ON KCU.CONSTRAINT_CATALOG = C.CONSTRAINT_CATALOG AND KCU.CONSTRAINT_SCHEMA = C.CONSTRAINT_SCHEMA AND KCU.TABLE_NAME = C.TABLE_NAME AND KCU.CONSTRAINT_NAME = C.CONSTRAINT_NAME WHERE C.CONSTRAINT_TYPE = 'PRIMARY KEY' AND KCU.TABLE_SCHEMA = '${SCHEMA}' ORDER BY KCU.ORDINAL_POSITION</primaryKeysQuery>
|
||||
@@ -548,6 +557,8 @@ union all
|
||||
<binaryPattern>x'%s'</binaryPattern>
|
||||
<avoidLeftJoin>false</avoidLeftJoin>
|
||||
<useInlineViewsInDataBrowser>true</useInlineViewsInDataBrowser>
|
||||
<estimatedRowCountQuery>SELECT TABNAME, CARD FROM SYSSTAT.TABLES WHERE TABSCHEMA = '%s'</estimatedRowCountQuery>
|
||||
<viewTextOrDDLQuery>SELECT TEXT FROM SYSCAT.VIEWS WHERE VIEWSCHEMA = '%1$s' and VIEWNAME = '%2$s'</viewTextOrDDLQuery>
|
||||
<virtualColumnsQuery>SELECT TABNAME, COLNAME from syscat.columns WHERE TABSCHEMA='${SCHEMA}' AND GENERATED='A'</virtualColumnsQuery>
|
||||
<importedKeysQuery> SELECT null, REF.REFTABSCHEMA, REF.REFTABNAME, PKCOL.COLNAME, null, REF.TABSCHEMA, REF.TABNAME, FKCOL.COLNAME, FKCOL.COLSEQ, null, null, REF.CONSTNAME, REF.REFKEYNAME, null FROM syscat.references REF, syscat.keycoluse PKCOL, syscat.keycoluse FKCOL WHERE REF.CONSTNAME = FKCOL.CONSTNAME AND REF.TABSCHEMA = FKCOL.TABSCHEMA AND REF.TABNAME = FKCOL.TABNAME AND REF.REFKEYNAME = PKCOL.CONSTNAME AND REF.REFTABSCHEMA = PKCOL.TABSCHEMA AND REF.REFTABNAME = PKCOL.TABNAME AND FKCOL.COLSEQ = PKCOL.COLSEQ AND REF.REFTABSCHEMA = '${SCHEMA}' ORDER BY FKCOL.COLSEQ</importedKeysQuery>
|
||||
<primaryKeysQuery> SELECT null, CONST.TABSCHEMA, CONST.TABNAME, PKCOL.COLNAME, PKCOL.COLSEQ, CONST.CONSTNAME FROM syscat.tabconst CONST, syscat.keycoluse PKCOL WHERE CONST.CONSTNAME = PKCOL.CONSTNAME AND CONST.TABSCHEMA = PKCOL.TABSCHEMA AND CONST.TABNAME = PKCOL.TABNAME AND CONST.TYPE = 'P' AND CONST.TABSCHEMA = '${SCHEMA}' ORDER BY PKCOL.COLSEQ</primaryKeysQuery>
|
||||
@@ -664,6 +675,8 @@ Select CNAME, TNAME, COLNAME, CTYPE, DETAIL From
|
||||
<binaryPattern>x'%s'</binaryPattern>
|
||||
<avoidLeftJoin>false</avoidLeftJoin>
|
||||
<useInlineViewsInDataBrowser>true</useInlineViewsInDataBrowser>
|
||||
<viewTextOrDDLQuery>SELECT TEXT FROM SYSCAT.VIEWS WHERE VIEWSCHEMA = '%1$s' and VIEWNAME = '%2$s'</viewTextOrDDLQuery>
|
||||
<estimatedRowCountQuery>SELECT TABNAME, CARD FROM SYSSTAT.TABLES WHERE TABSCHEMA = '%s'</estimatedRowCountQuery>
|
||||
<virtualColumnsQuery>SELECT TABNAME, COLNAME from syscat.columns WHERE TABSCHEMA='${SCHEMA}' AND GENERATED='A'</virtualColumnsQuery>
|
||||
<importedKeysQuery>SELECT null, REF.REFTABSCHEMA, REF.REFTABNAME, PKCOL.COLNAME, null, REF.TABSCHEMA, REF.TABNAME, FKCOL.COLNAME, FKCOL.COLSEQ, null, null, REF.CONSTNAME, REF.REFKEYNAME, null FROM syscat.references REF, syscat.keycoluse PKCOL, syscat.keycoluse FKCOL WHERE REF.CONSTNAME = FKCOL.CONSTNAME AND REF.TABSCHEMA = FKCOL.TABSCHEMA AND REF.TABNAME = FKCOL.TABNAME AND REF.REFKEYNAME = PKCOL.CONSTNAME AND REF.REFTABSCHEMA = PKCOL.TABSCHEMA AND REF.REFTABNAME = PKCOL.TABNAME AND FKCOL.COLSEQ = PKCOL.COLSEQ AND REF.REFTABSCHEMA = '${SCHEMA}' ORDER BY FKCOL.COLSEQ</importedKeysQuery>
|
||||
<primaryKeysQuery>SELECT null, CONST.TABSCHEMA, CONST.TABNAME, PKCOL.COLNAME, PKCOL.COLSEQ, CONST.CONSTNAME FROM syscat.tabconst CONST, syscat.keycoluse PKCOL WHERE CONST.CONSTNAME = PKCOL.CONSTNAME AND CONST.TABSCHEMA = PKCOL.TABSCHEMA AND CONST.TABNAME = PKCOL.TABNAME AND CONST.TYPE = 'P' AND CONST.TABSCHEMA = '${SCHEMA}' ORDER BY PKCOL.COLSEQ</primaryKeysQuery>
|
||||
@@ -792,6 +805,13 @@ Select CNAME, TNAME, COLNAME, CTYPE, DETAIL From
|
||||
<supportsSchemasInIndexDefinitions>false</supportsSchemasInIndexDefinitions>
|
||||
<useInlineViewsInDataBrowser>true</useInlineViewsInDataBrowser>
|
||||
<identifierQuoteString>"</identifierQuoteString>
|
||||
<viewTextOrDDLQuery>SELECT VIEW_DEFINITION FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = '%1$s' and TABLE_NAME = '%2$s'</viewTextOrDDLQuery>
|
||||
<estimatedRowCountQuery>
|
||||
SELECT c.relname, c.reltuples::bigint AS estimate
|
||||
FROM pg_class c
|
||||
JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||
WHERE n.nspname = '%s'
|
||||
</estimatedRowCountQuery>
|
||||
<explainPrepare></explainPrepare>
|
||||
<explainQuery>explain %1$s</explainQuery>
|
||||
<explainCleanup></explainCleanup>
|
||||
@@ -1109,6 +1129,7 @@ union all
|
||||
<binaryPattern>x'%s'</binaryPattern>
|
||||
<avoidLeftJoin>false</avoidLeftJoin>
|
||||
<useInlineViewsInDataBrowser>false</useInlineViewsInDataBrowser>
|
||||
<estimatedRowCountQuery>select TABLE_NAME, ROW_COUNT_ESTIMATE from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = '%s'</estimatedRowCountQuery>
|
||||
<virtualColumnsQuery>SELECT TABLE_NAME, COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='${SCHEMA}' AND IS_COMPUTED</virtualColumnsQuery>
|
||||
<identifierQuoteString>"</identifierQuoteString>
|
||||
<explainPrepare></explainPrepare>
|
||||
|
||||
@@ -19,10 +19,12 @@ import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -48,7 +50,7 @@ public class BasicDataSource implements DataSource {
|
||||
/**
|
||||
* Name of JDBC-driver class.
|
||||
*/
|
||||
private final String driverClassName;
|
||||
final String driverClassName;
|
||||
|
||||
/**
|
||||
* The DB URL.
|
||||
@@ -196,6 +198,8 @@ public class BasicDataSource implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<String> registeredDriverClassNames = new HashSet<String>();
|
||||
|
||||
private void loadDriver(URL[] jdbcDriverURL) {
|
||||
ClassLoader classLoaderForJdbcDriver = addJarToClasspath(jdbcDriverURL);
|
||||
try {
|
||||
@@ -204,6 +208,7 @@ public class BasicDataSource implements DataSource {
|
||||
try {
|
||||
d = (Driver) Class.forName(driverClassName, true, classLoaderForJdbcDriver).newInstance();
|
||||
DriverManager.registerDriver(new DriverShim(d));
|
||||
registeredDriverClassNames.add(driverClassName);
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -215,7 +220,9 @@ public class BasicDataSource implements DataSource {
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
if (!registeredDriverClassNames.contains(driverClassName)) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -201,6 +201,11 @@ public class Session {
|
||||
*/
|
||||
public final DBMS dbms;
|
||||
|
||||
/**
|
||||
* The DBMS.
|
||||
*/
|
||||
public final String driverClassName;
|
||||
|
||||
/**
|
||||
* The dbUrl (<code>null</code> if unknown)
|
||||
*/
|
||||
@@ -238,6 +243,7 @@ public class Session {
|
||||
this.local = local;
|
||||
this.scope = scope;
|
||||
this.dbms = dbms;
|
||||
this.driverClassName = (dataSource instanceof BasicDataSource)? ((BasicDataSource) dataSource).driverClassName : null;
|
||||
this.dbUrl = (dataSource instanceof BasicDataSource)? ((BasicDataSource) dataSource).dbUrl : null;
|
||||
this.schema = (dataSource instanceof BasicDataSource)? ((BasicDataSource) dataSource).dbUser : "";
|
||||
this.temporaryTableScope = scope;
|
||||
|
||||
@@ -552,4 +552,51 @@ public class Association extends ModelElement {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
}
|
||||
public boolean hasNullableFK() {
|
||||
if (!isInsertDestinationBeforeSource()) {
|
||||
return false;
|
||||
}
|
||||
Map<Column, Column> sdMap = createSourceToDestinationKeyMapping();
|
||||
if (sdMap.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (Column c: sdMap.keySet()) {
|
||||
if (!c.isNullable) {
|
||||
return false;
|
||||
}
|
||||
if (c.getFilter() != null && !c.getFilter().isDerived() && !c.getFilter().isNullFilter()) {
|
||||
return false;
|
||||
}
|
||||
for (Column pk: source.primaryKey.getColumns()) {
|
||||
if (c.name.equals(pk.name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean fkHasNullFilter() {
|
||||
Map<Column, Column> sdMap = createSourceToDestinationKeyMapping();
|
||||
for (Column c: sdMap.keySet()) {
|
||||
if (c.getFilter() == null || !c.getFilter().isNullFilter()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setOrResetFKNullFilter(boolean set) {
|
||||
Map<Column, Column> sdMap = createSourceToDestinationKeyMapping();
|
||||
for (Column c: sdMap.keySet()) {
|
||||
if (set) {
|
||||
c.setFilter(new Filter("null", null, false, null));
|
||||
} else {
|
||||
c.setFilter(null);
|
||||
}
|
||||
}
|
||||
getDataModel().deriveFilters();
|
||||
getDataModel().version++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -184,4 +184,8 @@ public class Filter {
|
||||
return applyAtExport;
|
||||
}
|
||||
|
||||
public boolean isNullFilter() {
|
||||
return "null".equalsIgnoreCase(expression.trim());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -200,6 +200,11 @@ public class PrimaryKey {
|
||||
return toSQL(null);
|
||||
}
|
||||
|
||||
public void assign(List<Column> primaryKeyColumns) {
|
||||
columns.clear();
|
||||
columns.addAll(primaryKeyColumns);
|
||||
}
|
||||
|
||||
public static boolean isIncreasable(Column uPKColumn, Column column) {
|
||||
if(!uPKColumn.type.equals(column.type)) {
|
||||
return false;
|
||||
@@ -228,4 +233,5 @@ public class PrimaryKey {
|
||||
// never should get THIS far !
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+599
-81
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package net.sf.jailer.modelbuilder;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
@@ -26,8 +27,10 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@@ -48,6 +51,44 @@ import net.sf.jailer.util.CancellationHandler;
|
||||
import net.sf.jailer.util.Pair;
|
||||
import net.sf.jailer.util.Quoting;
|
||||
import net.sf.jailer.util.SqlUtil;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.statement.Commit;
|
||||
import net.sf.jsqlparser.statement.SetStatement;
|
||||
import net.sf.jsqlparser.statement.StatementVisitor;
|
||||
import net.sf.jsqlparser.statement.Statements;
|
||||
import net.sf.jsqlparser.statement.UseStatement;
|
||||
import net.sf.jsqlparser.statement.alter.Alter;
|
||||
import net.sf.jsqlparser.statement.create.index.CreateIndex;
|
||||
import net.sf.jsqlparser.statement.create.table.CreateTable;
|
||||
import net.sf.jsqlparser.statement.create.view.AlterView;
|
||||
import net.sf.jsqlparser.statement.create.view.CreateView;
|
||||
import net.sf.jsqlparser.statement.delete.Delete;
|
||||
import net.sf.jsqlparser.statement.drop.Drop;
|
||||
import net.sf.jsqlparser.statement.execute.Execute;
|
||||
import net.sf.jsqlparser.statement.insert.Insert;
|
||||
import net.sf.jsqlparser.statement.merge.Merge;
|
||||
import net.sf.jsqlparser.statement.replace.Replace;
|
||||
import net.sf.jsqlparser.statement.select.AllColumns;
|
||||
import net.sf.jsqlparser.statement.select.AllTableColumns;
|
||||
import net.sf.jsqlparser.statement.select.FromItemVisitor;
|
||||
import net.sf.jsqlparser.statement.select.LateralSubSelect;
|
||||
import net.sf.jsqlparser.statement.select.ParenthesisFromItem;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.Select;
|
||||
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
|
||||
import net.sf.jsqlparser.statement.select.SelectItem;
|
||||
import net.sf.jsqlparser.statement.select.SelectItemVisitor;
|
||||
import net.sf.jsqlparser.statement.select.SelectVisitor;
|
||||
import net.sf.jsqlparser.statement.select.SetOperationList;
|
||||
import net.sf.jsqlparser.statement.select.SubJoin;
|
||||
import net.sf.jsqlparser.statement.select.SubSelect;
|
||||
import net.sf.jsqlparser.statement.select.TableFunction;
|
||||
import net.sf.jsqlparser.statement.select.ValuesList;
|
||||
import net.sf.jsqlparser.statement.select.WithItem;
|
||||
import net.sf.jsqlparser.statement.truncate.Truncate;
|
||||
import net.sf.jsqlparser.statement.update.Update;
|
||||
import net.sf.jsqlparser.statement.upsert.Upsert;
|
||||
|
||||
/**
|
||||
* Finds associations and tables by analyzing the JDBC meta data.
|
||||
@@ -123,11 +164,26 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
Quoting quoting = new Quoting(session);
|
||||
ResultSet resultSet;
|
||||
String defaultSchema = getDefaultSchema(session, session.getSchema());
|
||||
|
||||
for (Table table: dataModel.getTables()) {
|
||||
Set<Association> toRemove = new HashSet<Association>();
|
||||
|
||||
for (Table viewOrTable: dataModel.getTables()) {
|
||||
Table table;
|
||||
Table underlyingTable = null;
|
||||
UnderlyingTableInfo uti = null;
|
||||
uti = underlyingTableInfos.get(viewOrTable.getName());
|
||||
if (uti != null) {
|
||||
underlyingTable = uti.underlyingTable;
|
||||
}
|
||||
table = viewOrTable;
|
||||
_log.info("find associations with " + table.getName());
|
||||
try {
|
||||
resultSet = getImportedKeys(session, metaData, quoting.unquote(table.getOriginalSchema(quoting.quote(defaultSchema))), quoting.unquote(table.getUnqualifiedName()), true);
|
||||
Table child = underlyingTable != null? underlyingTable : table;
|
||||
String ikSchema = quoting.unquote(child.getOriginalSchema(quoting.quote(defaultSchema)));
|
||||
Session ikSession = session;
|
||||
if (sessionWithPermissionToReadSchema.containsKey(Quoting.normalizeIdentifier(ikSchema))) {
|
||||
ikSession = sessionWithPermissionToReadSchema.get(Quoting.normalizeIdentifier(ikSchema));
|
||||
}
|
||||
resultSet = getImportedKeys(ikSession, metaData, ikSchema, quoting.unquote(child.getUnqualifiedName()), true);
|
||||
} catch (Exception e) {
|
||||
_log.info("failed. " + e.getMessage());
|
||||
continue;
|
||||
@@ -135,38 +191,82 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
Map<String, Association> fkMap = new HashMap<String, Association>();
|
||||
Map<String, Integer> unknownFKCounter = new HashMap<String, Integer>();
|
||||
while (resultSet.next()) {
|
||||
Table pkTable = dataModel.getTable(toQualifiedTableName(quoting.quote(defaultSchema), quoting.quote(resultSet.getString(DBMS.MySQL.equals(session.dbms)? 1 : 2)), quoting.quote(resultSet.getString(3))));
|
||||
String pkColumn = quoting.quote(resultSet.getString(4));
|
||||
Table fkTable = dataModel.getTable(toQualifiedTableName(quoting.quote(defaultSchema), quoting.quote(resultSet.getString(DBMS.MySQL.equals(session.dbms)? 5 : 6)), quoting.quote(resultSet.getString(7))));
|
||||
String qualifiedPKTableName = toQualifiedTableName(quoting.quote(defaultSchema), quoting.quote(resultSet.getString(DBMS.MySQL.equals(session.dbms)? 1 : 2)), quoting.quote(resultSet.getString(3)));
|
||||
// String qualifiedFKTableName = toQualifiedTableName(quoting.quote(defaultSchema), quoting.quote(resultSet.getString(DBMS.MySQL.equals(session.dbms)? 5 : 6)), quoting.quote(resultSet.getString(7)));
|
||||
Table defaultPkTable = dataModel.getTable(qualifiedPKTableName);
|
||||
|
||||
Table fkTable = table;
|
||||
|
||||
String fkColumn = quoting.quote(resultSet.getString(8));
|
||||
String foreignKey = resultSet.getString(12);
|
||||
if (fkTable != null) {
|
||||
if (foreignKey == null || foreignKey.trim().length() == 0) {
|
||||
foreignKey = pkTable.getName();
|
||||
int seq = resultSet.getInt(9);
|
||||
String fkKey = fkTable.getName() + "." + foreignKey;
|
||||
if (seq == 1) {
|
||||
Integer count = unknownFKCounter.get(fkKey);
|
||||
if (count == null) {
|
||||
count = 1;
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
unknownFKCounter.put(fkKey, count);
|
||||
}
|
||||
foreignKey += "." + unknownFKCounter.get(fkKey);
|
||||
if (uti != null) {
|
||||
fkColumn = uti.columnMapping.get(fkColumn);
|
||||
}
|
||||
|
||||
// collect all PKTables
|
||||
Map<Table, UnderlyingTableInfo> infos = new LinkedHashMap<Table, UnderlyingTableInfo>();
|
||||
if (defaultPkTable != null) {
|
||||
infos.put(defaultPkTable, null);
|
||||
}
|
||||
for (Entry<String, UnderlyingTableInfo> e: underlyingTableInfos.entrySet()) {
|
||||
Table view = dataModel.getTable(e.getKey());
|
||||
if (view != null && qualifiedPKTableName.equals(e.getValue().underlyingTable.getName())) {
|
||||
infos.put(view, e.getValue());
|
||||
}
|
||||
String fkName = fkTable.getName() + "." + foreignKey;
|
||||
if (foreignKey != null && fkMap.containsKey(fkName)) {
|
||||
fkMap.get(fkName).appendCondition("A." + fkColumn + "=B." + pkColumn);
|
||||
} else {
|
||||
if (pkTable != null && fkTable != null) {
|
||||
Association association = new Association(fkTable, pkTable, false, true, "A." + fkColumn + "=B." + pkColumn, dataModel, false, Cardinality.MANY_TO_ONE);
|
||||
association.setAuthor(metaData.getDriverName());
|
||||
associations.add(association);
|
||||
fkMap.put(fkName, association);
|
||||
if (foreignKey != null) {
|
||||
namingSuggestion.put(association, new String[] { foreignKey, fkTable.getUnqualifiedName() + "." + foreignKey });
|
||||
}
|
||||
|
||||
for (Entry<Table, UnderlyingTableInfo> e: infos.entrySet()) {
|
||||
Table pkTable = e.getKey();
|
||||
String pkColumn = quoting.quote(resultSet.getString(4));
|
||||
String foreignKey = resultSet.getString(12);
|
||||
|
||||
UnderlyingTableInfo info = e.getValue();
|
||||
if (info != null) {
|
||||
pkColumn = info.columnMapping.get(pkColumn);
|
||||
}
|
||||
|
||||
if (pkTable != null) {
|
||||
if (foreignKey == null || foreignKey.trim().length() == 0) {
|
||||
foreignKey = pkTable.getName();
|
||||
if (info != null) {
|
||||
foreignKey += "." + quoting.unquote(pkTable.getUnqualifiedName());
|
||||
}
|
||||
int seq = resultSet.getInt(9);
|
||||
String fkKey = pkTable.getName() + "." + foreignKey;
|
||||
if (seq == 1) {
|
||||
Integer count = unknownFKCounter.get(fkKey);
|
||||
if (count == null) {
|
||||
count = 1;
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
unknownFKCounter.put(fkKey, count);
|
||||
}
|
||||
foreignKey += "." + unknownFKCounter.get(fkKey);
|
||||
} else {
|
||||
if (info != null) {
|
||||
foreignKey += "." + quoting.unquote(pkTable.getUnqualifiedName());
|
||||
}
|
||||
}
|
||||
String fkName = pkTable.getName() + "." + foreignKey;
|
||||
|
||||
if (foreignKey != null && fkMap.containsKey(fkName)) {
|
||||
if (fkColumn == null || pkColumn == null) {
|
||||
toRemove.add(fkMap.get(fkName));
|
||||
} else {
|
||||
fkMap.get(fkName).appendCondition("A." + fkColumn + "=B." + pkColumn);
|
||||
}
|
||||
} else {
|
||||
if (pkTable != null && fkTable != null) {
|
||||
Association association = new Association(fkTable, pkTable, false, true, "A." + fkColumn + "=B." + pkColumn, dataModel, false, Cardinality.MANY_TO_ONE);
|
||||
association.setAuthor(metaData.getDriverName());
|
||||
associations.add(association);
|
||||
fkMap.put(fkName, association);
|
||||
if (foreignKey != null) {
|
||||
namingSuggestion.put(association, new String[] { foreignKey, fkTable.getUnqualifiedName() + "." + foreignKey });
|
||||
}
|
||||
if (fkColumn == null || pkColumn == null) {
|
||||
toRemove.add(association);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,6 +275,8 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
resultSet.close();
|
||||
CancellationHandler.checkForCancellation(null);
|
||||
}
|
||||
associations.removeAll(toRemove);
|
||||
shutDownSessionsWithPermissionToReadSchema();
|
||||
return associations;
|
||||
}
|
||||
|
||||
@@ -219,6 +321,31 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
return table;
|
||||
}
|
||||
|
||||
private class UnderlyingTableInfo {
|
||||
Table underlyingTable;
|
||||
Map<String, String> columnMapping = new LinkedHashMap<String, String>();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UnderlyingTableInfo [underlyingTable=" + underlyingTable + ", columnMapping=" + columnMapping + "]";
|
||||
}
|
||||
|
||||
public void join() {
|
||||
UnderlyingTableInfo u2TableInfo = underlyingTableInfos.get(underlyingTable.getName());
|
||||
if (u2TableInfo != null) {
|
||||
Map<String, String> newColumnMapping = new HashMap<String, String>();
|
||||
for (Entry<String, String> e: u2TableInfo.columnMapping.entrySet()) {
|
||||
String cMapped = columnMapping.get(e.getValue());
|
||||
if (cMapped != null) {
|
||||
newColumnMapping.put(e.getKey(), cMapped);
|
||||
}
|
||||
}
|
||||
columnMapping = newColumnMapping;
|
||||
underlyingTable = u2TableInfo.underlyingTable;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds all tables in DB schema.
|
||||
*
|
||||
@@ -226,6 +353,28 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
*/
|
||||
@Override
|
||||
public Set<Table> findTables(Session session, ExecutionContext executionContext) throws Exception {
|
||||
String introspectionSchema = session.getIntrospectionSchema();
|
||||
String tableNamePattern = "%";
|
||||
|
||||
return findTables(session, executionContext, introspectionSchema, tableNamePattern, 0);
|
||||
}
|
||||
|
||||
private Map<String, UnderlyingTableInfo> underlyingTableInfos = new LinkedHashMap<String, UnderlyingTableInfo>();
|
||||
private Map<String, String> tableTypes = new HashMap<String, String>();
|
||||
|
||||
/**
|
||||
* Finds all tables in DB schema.
|
||||
*
|
||||
* @param session the statement executor for executing SQL-statements
|
||||
* @param introspectionSchema the schema
|
||||
* @param tableNamePattern table name pattern
|
||||
*/
|
||||
private Set<Table> findTables(Session session, ExecutionContext executionContext, String introspectionSchema,
|
||||
String tableNamePattern, int depth) throws SQLException {
|
||||
final int MAX_DEPTH = 100;
|
||||
if (depth > MAX_DEPTH) {
|
||||
return new HashSet<Table>();
|
||||
}
|
||||
PrimaryKeyFactory primaryKeyFactory = new PrimaryKeyFactory();
|
||||
|
||||
Set<Table> tables = new HashSet<Table>();
|
||||
@@ -233,14 +382,14 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
Quoting quoting = new Quoting(session);
|
||||
ResultSet resultSet;
|
||||
List<String> types = getTypes(executionContext);
|
||||
resultSet = getTables(session, metaData, session.getIntrospectionSchema(), "%", types.toArray(new String[0]));
|
||||
resultSet = getTables(session, metaData, introspectionSchema, tableNamePattern, types.toArray(new String[0]));
|
||||
List<String> tableNames = new ArrayList<String>();
|
||||
while (resultSet.next()) {
|
||||
String tableName = resultSet.getString(3);
|
||||
if (resultSet.getString(4) != null && types.contains(resultSet.getString(4).toUpperCase())) {
|
||||
if (isValidName(tableName, session)) {
|
||||
tableName = quoting.quote(tableName);
|
||||
if (executionContext.getQualifyNames()) {
|
||||
if (executionContext.getQualifyNames() || (depth > 0 && introspectionSchema != null && !introspectionSchema.equals(session.getIntrospectionSchema()))) {
|
||||
String schemaName = resultSet.getString(DBMS.MySQL.equals(session.dbms)? 1 : 2);
|
||||
if (schemaName != null) {
|
||||
schemaName = quoting.quote(schemaName.trim());
|
||||
@@ -250,6 +399,7 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
}
|
||||
}
|
||||
tableNames.add(tableName);
|
||||
tableTypes.put(tableName, resultSet.getString(4).toUpperCase());
|
||||
_log.info("found table " + tableName);
|
||||
} else {
|
||||
_log.info("skip table " + tableName);
|
||||
@@ -261,7 +411,7 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
Map<String, Map<Integer, Column>> pkColumns = new HashMap<String, Map<Integer, Column>>();
|
||||
for (String tableName: tableNames) {
|
||||
Table tmp = new Table(tableName, null, false, false);
|
||||
resultSet = getPrimaryKeys(session, metaData, quoting.unquote(tmp.getOriginalSchema(quoting.quote(session.getIntrospectionSchema()))), quoting.unquote(tmp.getUnqualifiedName()), true);
|
||||
resultSet = getPrimaryKeys(session, metaData, quoting.unquote(tmp.getOriginalSchema(quoting.quote(introspectionSchema))), quoting.unquote(tmp.getUnqualifiedName()), true);
|
||||
Map<Integer, Column> pk = pkColumns.get(tableName);
|
||||
if (pk == null) {
|
||||
pk = new HashMap<Integer, Column>();
|
||||
@@ -280,7 +430,7 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
}
|
||||
if (!hasPK) {
|
||||
_log.info("find unique index of table " + tableName);
|
||||
hasPK = findUniqueIndexBasedKey(metaData, quoting, session, tmp, pk);
|
||||
hasPK = findUniqueIndexBasedKey(metaData, quoting, session, tmp, pk, tableTypes.get(tableName));
|
||||
}
|
||||
_log.info((hasPK? "" : "no ") + "primary key found for table " + tableName);
|
||||
resultSet.close();
|
||||
@@ -288,8 +438,8 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
}
|
||||
for (String tableName: tableNames) {
|
||||
Table tmp = new Table(tableName, null, false, false);
|
||||
_log.info("getting columns for " + quoting.unquote(tmp.getOriginalSchema(quoting.quote(session.getIntrospectionSchema()))) + "." + quoting.unquote(tmp.getUnqualifiedName()));
|
||||
resultSet = getColumns(session, metaData, quoting.unquote(tmp.getOriginalSchema(quoting.quote(session.getIntrospectionSchema()))), quoting.unquote(tmp.getUnqualifiedName()), "%", true);
|
||||
_log.info("getting columns for " + quoting.unquote(tmp.getOriginalSchema(quoting.quote(introspectionSchema))) + "." + quoting.unquote(tmp.getUnqualifiedName()));
|
||||
resultSet = getColumns(session, metaData, quoting.unquote(tmp.getOriginalSchema(quoting.quote(introspectionSchema))), quoting.unquote(tmp.getUnqualifiedName()), tableNamePattern, true, tableTypes.get(tableName));
|
||||
_log.info("done");
|
||||
Map<Integer, Column> pk = pkColumns.get(tableName);
|
||||
while (resultSet.next()) {
|
||||
@@ -349,9 +499,299 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
CancellationHandler.checkForCancellation(null);
|
||||
}
|
||||
|
||||
for (Table table: tables) {
|
||||
String viewText = null;
|
||||
String viewTextOrDDLQuery = session.dbms.getViewTextOrDDLQuery();
|
||||
if ("VIEW".equals(tableTypes.get(table.getName())) && viewTextOrDDLQuery != null) {
|
||||
String viewTextQuery = String.format(viewTextOrDDLQuery, introspectionSchema, table.getUnqualifiedName());
|
||||
final String[] viewTextContainer = new String[1];
|
||||
try {
|
||||
session.executeQuery(viewTextQuery, new Session.AbstractResultSetReader() {
|
||||
@Override
|
||||
public void readCurrentRow(ResultSet resultSet) throws SQLException {
|
||||
viewTextContainer[0] = resultSet.getString(1);
|
||||
}
|
||||
});
|
||||
viewText = viewTextContainer[0];
|
||||
if (viewText != null) {
|
||||
viewText = viewText.trim();
|
||||
viewText = viewText.replaceFirst("(?is)^create.*as\\b(\\W*select\\b)(.*)$", "$1$2").trim();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
_log.info("can't get view text: " + viewTextQuery);
|
||||
_log.info(e.getMessage());
|
||||
}
|
||||
} else if ("SYNONYM".equals(tableTypes.get(table.getName())) || "ALIAS".equals(tableTypes.get(table.getName()))) {
|
||||
if (session.dbms.getSynonymTableQuery() != null) {
|
||||
String synonymTableQuery = String.format(session.dbms.getSynonymTableQuery(), introspectionSchema, table.getUnqualifiedName());
|
||||
final String[] synonymTableQueryContainer = new String[1];
|
||||
try {
|
||||
session.executeQuery(synonymTableQuery, new Session.AbstractResultSetReader() {
|
||||
@Override
|
||||
public void readCurrentRow(ResultSet resultSet) throws SQLException {
|
||||
synonymTableQueryContainer[0] = "Select * from " + resultSet.getString(1);
|
||||
}
|
||||
});
|
||||
viewText = synonymTableQueryContainer[0];
|
||||
} catch (Exception e) {
|
||||
_log.info("can't get synonym table: " + synonymTableQuery);
|
||||
_log.info(e.getMessage());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (viewText != null) {
|
||||
UnderlyingTableInfo uti = parseViewText(session, executionContext, quoting, depth, viewText, introspectionSchema, table);
|
||||
if (uti != null) {
|
||||
List<Column> columns = findColumns(table, session, executionContext);
|
||||
uti.join();
|
||||
if (table.primaryKey.getColumns().isEmpty()) {
|
||||
if (uti.underlyingTable.primaryKey != null && !uti.underlyingTable.primaryKey.getColumns().isEmpty()) {
|
||||
List<Column> newPK = new ArrayList<Column>();
|
||||
for (Column pkc: uti.underlyingTable.primaryKey.getColumns()) {
|
||||
String newPkc = uti.columnMapping.get(quoting.normalizeCase(Quoting.staticUnquote(pkc.name)));
|
||||
if (newPkc != null) {
|
||||
Column newC = null;
|
||||
for (Column c: columns) {
|
||||
if (Quoting.equalsIgnoreQuotingAndCase(c.name, newPkc)) {
|
||||
newC = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newC != null) {
|
||||
newPK.add(newC);
|
||||
} else {
|
||||
newPK = null;
|
||||
}
|
||||
} else {
|
||||
newPK = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newPK != null) {
|
||||
table.primaryKey.assign(newPK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
private UnderlyingTableInfo parseViewText(final Session session, final ExecutionContext executionContext, final Quoting quoting, final int depth, String viewText, final String defaultSchema, final Table view) {
|
||||
net.sf.jsqlparser.statement.Statement st;
|
||||
try {
|
||||
_log.info("analyzing view \"" + view.getName() + "\": " + viewText.replaceAll("\\s+", " "));
|
||||
final List<Column> columns = findColumns(view, session, executionContext);
|
||||
final boolean[] isValid = new boolean[] { true };
|
||||
final boolean[] selectExists = new boolean[] { false };
|
||||
final UnderlyingTableInfo underlyingTableInfo = new UnderlyingTableInfo();
|
||||
st = CCJSqlParserUtil.parse(viewText);
|
||||
st.accept(new StatementVisitor() {
|
||||
@Override
|
||||
public void visit(Upsert arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Select select) {
|
||||
select.getSelectBody().accept(new SelectVisitor() {
|
||||
@Override
|
||||
public void visit(WithItem withItem) {
|
||||
isValid[0] = false;
|
||||
}
|
||||
@Override
|
||||
public void visit(SetOperationList setOpList) {
|
||||
isValid[0] = false;
|
||||
}
|
||||
@Override
|
||||
public void visit(PlainSelect plainSelect) {
|
||||
if (plainSelect.getFromItem() != null && plainSelect.getJoins() == null) {
|
||||
selectExists[0] = true;
|
||||
for (SelectItem sItem: plainSelect.getSelectItems()) {
|
||||
sItem.accept(new SelectItemVisitor() {
|
||||
@Override
|
||||
public void visit(SelectExpressionItem eItem) {
|
||||
Expression expression = eItem.getExpression();
|
||||
if (expression instanceof net.sf.jsqlparser.schema.Column) {
|
||||
String column = ((net.sf.jsqlparser.schema.Column) expression).getColumnName();
|
||||
column = Quoting.staticUnquote(column);
|
||||
String alias = column;
|
||||
if (eItem.getAlias() != null) {
|
||||
if (eItem.getAlias().getName() != null) {
|
||||
alias = Quoting.staticUnquote(eItem.getAlias().getName());
|
||||
}
|
||||
}
|
||||
underlyingTableInfo.columnMapping.put(quoting.normalizeCase(Quoting.staticUnquote(column)), quoting.normalizeCase(Quoting.staticUnquote(alias)));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void visit(AllTableColumns arg0) {
|
||||
for (Column column: columns) {
|
||||
underlyingTableInfo.columnMapping.put(quoting.normalizeCase(Quoting.staticUnquote(column.name)), quoting.normalizeCase(Quoting.staticUnquote(column.name)));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void visit(AllColumns arg0) {
|
||||
for (Column column: columns) {
|
||||
underlyingTableInfo.columnMapping.put(quoting.normalizeCase(Quoting.staticUnquote(column.name)), quoting.normalizeCase(Quoting.staticUnquote(column.name)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
FromItemVisitor fromItemVisitor = new FromItemVisitor() {
|
||||
private void unknownTable() {
|
||||
isValid[0] = false;
|
||||
selectExists[0] = false;
|
||||
}
|
||||
@Override
|
||||
public void visit(TableFunction tableFunction) {
|
||||
unknownTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ValuesList valuesList) {
|
||||
unknownTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LateralSubSelect lateralSubSelect) {
|
||||
unknownTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(SubJoin subjoin) {
|
||||
unknownTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(SubSelect subSelect) {
|
||||
unknownTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(net.sf.jsqlparser.schema.Table tableName) {
|
||||
String schema = Quoting.staticUnquote(tableName.getSchemaName());
|
||||
if (schema == null) {
|
||||
schema = defaultSchema;
|
||||
}
|
||||
String name = Quoting.staticUnquote(tableName.getName());
|
||||
if (tableName.getPivot() != null) {
|
||||
unknownTable();
|
||||
} else {
|
||||
try {
|
||||
Session theSession = session;
|
||||
while (theSession != null) {
|
||||
Quoting quoting = new Quoting(theSession);
|
||||
Set<Table> tables = findTables(theSession, executionContext, quoting.normalizeCase(schema), quoting.normalizeCase(name), depth + 1);
|
||||
if (tables.size() < 1) {
|
||||
tables = findTables(theSession, executionContext, schema, name, depth + 1);
|
||||
}
|
||||
if (tables.size() >= 1) {
|
||||
underlyingTableInfo.underlyingTable = tables.iterator().next();
|
||||
break;
|
||||
} else {
|
||||
if (session == theSession && Quoting.equalsIgnoreQuotingAndCase(theSession.getIntrospectionSchema(), schema)
|
||||
||
|
||||
checkReadPermission(theSession, schema)
|
||||
|| checkReadPermission(theSession, quoting.normalizeCase(schema))) {
|
||||
_log.warn("View or Synonym \"" + view.getName() + "\": can't find underlying table \"" + schema + "." + name + "\"");
|
||||
break;
|
||||
} else {
|
||||
Session newSession = sessionWithPermissionToReadSchema.get(Quoting.normalizeIdentifier(schema));
|
||||
if (newSession != null && newSession != theSession) {
|
||||
theSession = newSession;
|
||||
} else {
|
||||
theSession = askForSessionWithPermissionToReadSchema(session, view, Quoting.normalizeIdentifier(schema), quoting.normalizeCase(schema), quoting.normalizeCase(name), executionContext);
|
||||
if (theSession == null) {
|
||||
_log.warn("Insufficient privileges to analyze table \"" + schema + "." + name + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
_log.error("paring failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void visit(ParenthesisFromItem aThis) {
|
||||
if (aThis.getFromItem() != null) {
|
||||
aThis.getFromItem().accept(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
plainSelect.getFromItem().accept(fromItemVisitor);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void visit(Merge arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(SetStatement arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Execute arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Statements arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Alter arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(AlterView arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(CreateView arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(CreateTable arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(CreateIndex arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Truncate arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Drop arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Replace arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Insert arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Update arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Delete arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(Commit arg0) {
|
||||
}
|
||||
@Override
|
||||
public void visit(UseStatement use) {
|
||||
}
|
||||
});
|
||||
if (isValid[0] && selectExists[0] && underlyingTableInfo.underlyingTable != null) {
|
||||
underlyingTableInfos.put(view.getName(), underlyingTableInfo);
|
||||
return underlyingTableInfo;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
_log.info("can't parse view definition");
|
||||
_log.info(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<String> getTypes(ExecutionContext executionContext) {
|
||||
ArrayList<String> result = new ArrayList<String>();
|
||||
result.add("TABLE");
|
||||
@@ -395,10 +835,11 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
|
||||
/**
|
||||
* Find a key of a table based on an unique index on non-nullable columns.
|
||||
* @param string
|
||||
*/
|
||||
private boolean findUniqueIndexBasedKey(DatabaseMetaData metaData, Quoting quoting, Session session, Table tmp, Map<Integer, Column> pk) {
|
||||
private boolean findUniqueIndexBasedKey(DatabaseMetaData metaData, Quoting quoting, Session session, Table tmp, Map<Integer, Column> pk, String tableType) {
|
||||
try {
|
||||
ResultSet resultSet = getColumns(session, metaData, quoting.unquote(tmp.getOriginalSchema(quoting.quote(session.getIntrospectionSchema()))), quoting.unquote(tmp.getUnqualifiedName()), "%", true);
|
||||
ResultSet resultSet = getColumns(session, metaData, quoting.unquote(tmp.getOriginalSchema(quoting.quote(session.getIntrospectionSchema()))), quoting.unquote(tmp.getUnqualifiedName()), "%", true, tableType);
|
||||
|
||||
List<String> nonNullColumns = new ArrayList<String>();
|
||||
boolean hasNullable = false;
|
||||
@@ -470,22 +911,22 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasNullable) {
|
||||
if (nonNullColumns.size() <= 6) {
|
||||
for (int i = 1; i <= nonNullColumns.size(); ++i) {
|
||||
pk.put(i, new Column(quoting.quote(nonNullColumns.get(i - 1)), "", 0, -1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// if (!hasNullable && "TABLE".equalsIgnoreCase(tableType)) {
|
||||
// if (nonNullColumns.size() <= 6) {
|
||||
// for (int i = 1; i <= nonNullColumns.size(); ++i) {
|
||||
// pk.put(i, new Column(quoting.quote(nonNullColumns.get(i - 1)), "", 0, -1));
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
_log.error(e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ResultSet getIndexInfo(Session session, DatabaseMetaData metaData, String schema, String table, boolean unique, boolean approximate) throws SQLException {
|
||||
final String NAME = "getIndexInfo " + schema;
|
||||
MetaDataCache metaDataCache = (MetaDataCache) session.getSessionProperty(JDBCMetaDataBasedModelElementFinder.class, NAME);
|
||||
@@ -518,38 +959,63 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
* Calls {@link DatabaseMetaData#getColumns(String, String, String, String)}. Uses schemaPattern as catalogPattern on MySQL.
|
||||
* @param withCaching
|
||||
*/
|
||||
public static ResultSet getColumns(Session session, DatabaseMetaData metaData, String schemaPattern, String tableNamePattern, String columnNamePattern, boolean withCaching) throws SQLException {
|
||||
if (withCaching) {
|
||||
synchronized (session) {
|
||||
final String NAME = "getColumns " + schemaPattern;
|
||||
MetaDataCache metaDataCache = (MetaDataCache) session.getSessionProperty(JDBCMetaDataBasedModelElementFinder.class, NAME);
|
||||
if (metaDataCache == null) {
|
||||
metaDataCache = MetaDataCache.readColumns(session, metaData, schemaPattern);
|
||||
session.setSessionProperty(JDBCMetaDataBasedModelElementFinder.class, NAME, metaDataCache);
|
||||
}
|
||||
ResultSet resultSet = metaDataCache.forTable(tableNamePattern);
|
||||
if (resultSet != null) {
|
||||
return resultSet;
|
||||
}
|
||||
public static ResultSet getColumns(Session session, DatabaseMetaData metaData, String schemaPattern, String tableNamePattern, String columnNamePattern, boolean withCaching, String tableType) throws SQLException {
|
||||
boolean includeSynonym = false;
|
||||
if (DBMS.ORACLE.equals(session.dbms)) {
|
||||
if ("ALIAS".equalsIgnoreCase(tableType) || "SYNONYM".equalsIgnoreCase(tableType)) {
|
||||
includeSynonym = true;
|
||||
}
|
||||
}
|
||||
if (DBMS.MySQL.equals(session.dbms)) {
|
||||
return metaData.getColumns(schemaPattern, null, tableNamePattern, columnNamePattern);
|
||||
includeSynonym = setIncludeSynonyms(includeSynonym, session);
|
||||
}
|
||||
try {
|
||||
return metaData.getColumns(null, schemaPattern, tableNamePattern, columnNamePattern);
|
||||
} catch (Exception e) {
|
||||
String catalogs = "";
|
||||
try {
|
||||
ResultSet r = metaData.getCatalogs();
|
||||
while (r.next()) {
|
||||
catalogs += r.getString(1) + " ";
|
||||
if (withCaching) {
|
||||
synchronized (session) {
|
||||
final String NAME = "getColumns " + includeSynonym + " " + schemaPattern;
|
||||
MetaDataCache metaDataCache = (MetaDataCache) session.getSessionProperty(JDBCMetaDataBasedModelElementFinder.class, NAME);
|
||||
if (metaDataCache == null) {
|
||||
metaDataCache = MetaDataCache.readColumns(session, metaData, schemaPattern);
|
||||
session.setSessionProperty(JDBCMetaDataBasedModelElementFinder.class, NAME, metaDataCache);
|
||||
}
|
||||
ResultSet resultSet = metaDataCache.forTable(tableNamePattern);
|
||||
if (resultSet != null) {
|
||||
return resultSet;
|
||||
}
|
||||
}
|
||||
r.close();
|
||||
} catch (Exception e2) {
|
||||
catalogs += "?";
|
||||
}
|
||||
throw new RuntimeException("Error in getColumns(): catalogs= " + catalogs + ", schemaPattern=" + schemaPattern + ", tableNamePattern=" + tableNamePattern + ", columnNamePattern=" + columnNamePattern, e);
|
||||
if (DBMS.MySQL.equals(session.dbms)) {
|
||||
return metaData.getColumns(schemaPattern, null, tableNamePattern, columnNamePattern);
|
||||
}
|
||||
try {
|
||||
return metaData.getColumns(null, schemaPattern, tableNamePattern, columnNamePattern);
|
||||
} catch (Exception e) {
|
||||
String catalogs = "";
|
||||
try {
|
||||
ResultSet r = metaData.getCatalogs();
|
||||
while (r.next()) {
|
||||
catalogs += r.getString(1) + " ";
|
||||
}
|
||||
r.close();
|
||||
} catch (Exception e2) {
|
||||
catalogs += "?";
|
||||
}
|
||||
throw new RuntimeException("Error in getColumns(): catalogs= " + catalogs + ", schemaPattern=" + schemaPattern + ", tableNamePattern=" + tableNamePattern + ", columnNamePattern=" + columnNamePattern, e);
|
||||
}
|
||||
} finally {
|
||||
if (DBMS.ORACLE.equals(session.dbms)) {
|
||||
if (includeSynonym) {
|
||||
setIncludeSynonyms(false, session);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean setIncludeSynonyms(boolean includeSynonyms, Session session) {
|
||||
try {
|
||||
Connection con = session.getConnection();
|
||||
con.getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection").getMethod("setIncludeSynonyms", new Class[] { boolean.class }).invoke(con, includeSynonyms);
|
||||
return includeSynonyms;
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,7 +1113,9 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
return schema;
|
||||
}
|
||||
if (schema.equalsIgnoreCase(userName.trim())) {
|
||||
userSchema = schema;
|
||||
if (userSchema == null || !userSchema.equals(userName.trim())) {
|
||||
userSchema = schema;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (userSchema != null) {
|
||||
@@ -672,7 +1140,7 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
* @throws Exception on each error
|
||||
*/
|
||||
@Override
|
||||
public List<Column> findColumns(Table table, Session session, ExecutionContext executionContext) throws Exception {
|
||||
public List<Column> findColumns(Table table, Session session, ExecutionContext executionContext) throws SQLException {
|
||||
List<Column> columns = new ArrayList<Column>();
|
||||
DatabaseMetaData metaData = session.getMetaData();
|
||||
Quoting quoting = new Quoting(session);
|
||||
@@ -685,7 +1153,7 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
String schemaName = quoting.unquote(table.getOriginalSchema(defaultSchema));
|
||||
String tableName = quoting.unquote(table.getUnqualifiedName());
|
||||
_log.info("getting columns for " + table.getOriginalSchema(defaultSchema) + "." + tableName);
|
||||
ResultSet resultSet = getColumns(session, metaData, schemaName, tableName, "%", true);
|
||||
ResultSet resultSet = getColumns(session, metaData, schemaName, tableName, "%", true, tableTypes.get(table.getName()));
|
||||
_log.info("done");
|
||||
while (resultSet.next()) {
|
||||
String colName = quoting.quote(resultSet.getString(4));
|
||||
@@ -906,6 +1374,56 @@ public class JDBCMetaDataBasedModelElementFinder implements ModelElementFinder {
|
||||
session.removeSessionProperties(JDBCMetaDataBasedModelElementFinder.class);
|
||||
}
|
||||
|
||||
private Map<String, Session> sessionWithPermissionToReadSchema = new HashMap<String, Session>();
|
||||
|
||||
private void shutDownSessionsWithPermissionToReadSchema() {
|
||||
for (Session s: sessionWithPermissionToReadSchema.values()) {
|
||||
try {
|
||||
s.shutDown();
|
||||
} catch (SQLException e) {
|
||||
_log.warn(e.getMessage());
|
||||
}
|
||||
}
|
||||
sessionWithPermissionToReadSchema.clear();
|
||||
}
|
||||
|
||||
public static interface PrivilegedSessionProvider {
|
||||
Session askForSessionWithPermissionToReadSchema(Session session, Table view, String schema, String tableName, ExecutionContext executionContext);
|
||||
};
|
||||
|
||||
public static PrivilegedSessionProvider privilegedSessionProvider;
|
||||
|
||||
private Session askForSessionWithPermissionToReadSchema(Session session, Table view, String schemaID, String schema, String tableName, ExecutionContext executionContext) {
|
||||
if (privilegedSessionProvider == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Quoting.equalsIgnoreQuotingAndCase(session.getIntrospectionSchema(), schema)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Session newSession = privilegedSessionProvider.askForSessionWithPermissionToReadSchema(session, view, schema, tableName, executionContext);
|
||||
|
||||
if (newSession != null) {
|
||||
Session s = sessionWithPermissionToReadSchema.get(schemaID);
|
||||
if (s != null) {
|
||||
try {
|
||||
s.shutDown();
|
||||
} catch (SQLException e) {
|
||||
// ignore
|
||||
}
|
||||
sessionWithPermissionToReadSchema.remove(schemaID);
|
||||
}
|
||||
sessionWithPermissionToReadSchema.put(schemaID, newSession);
|
||||
}
|
||||
|
||||
return newSession;
|
||||
}
|
||||
|
||||
private boolean checkReadPermission(Session theSession, String schema) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets description.
|
||||
*/
|
||||
|
||||
@@ -76,7 +76,7 @@ public class MetaDataCache {
|
||||
MetaDataCache metaDataCache = new MetaDataCache();
|
||||
try {
|
||||
Set<Integer> intIndex = new HashSet<Integer>(Arrays.asList(5));
|
||||
readMetaData(metaDataCache, session, primaryKeysQuery.replace("${SCHEMA}", schema), intIndex);
|
||||
readMetaData(metaDataCache, session, primaryKeysQuery.replace("${SCHEMA}", schema), intIndex, 2);
|
||||
return metaDataCache;
|
||||
} catch (Exception e) {
|
||||
_log.info(e.getMessage());
|
||||
@@ -104,7 +104,7 @@ public class MetaDataCache {
|
||||
MetaDataCache metaDataCache = new MetaDataCache();
|
||||
try {
|
||||
Set<Integer> intIndex = new HashSet<Integer>(Arrays.asList(4));
|
||||
readMetaData(metaDataCache, session, indexInfoQuery.replace("${SCHEMA}", schema), intIndex);
|
||||
readMetaData(metaDataCache, session, indexInfoQuery.replace("${SCHEMA}", schema), intIndex, 2);
|
||||
return metaDataCache;
|
||||
} catch (Exception e) {
|
||||
_log.info(e.getMessage());
|
||||
@@ -132,7 +132,7 @@ public class MetaDataCache {
|
||||
MetaDataCache metaDataCache = new MetaDataCache();
|
||||
try {
|
||||
Set<Integer> intIndex = new HashSet<Integer>(Arrays.asList(9, 10, 11, 14));
|
||||
readMetaData(metaDataCache, session, importedKeysQuery.replace("${SCHEMA}", schema), intIndex);
|
||||
readMetaData(metaDataCache, session, importedKeysQuery.replace("${SCHEMA}", schema), intIndex, 6);
|
||||
return metaDataCache;
|
||||
} catch (Exception e) {
|
||||
_log.info(e.getMessage());
|
||||
@@ -226,7 +226,7 @@ public class MetaDataCache {
|
||||
* Reads meta data.
|
||||
*/
|
||||
private static void readMetaData(final MetaDataCache metaDataCache, Session session, String query,
|
||||
final Set<Integer> intIndex) throws SQLException {
|
||||
final Set<Integer> intIndex, final int tableIndex) throws SQLException {
|
||||
metaDataCache.cache = new HashMap<String, List<Object[]>>();
|
||||
boolean wasSilent = session.getSilent();
|
||||
session.setSilent(true);
|
||||
@@ -243,7 +243,7 @@ public class MetaDataCache {
|
||||
row[i - 1] = resultSet.getString(i);
|
||||
}
|
||||
}
|
||||
String table = (String) row[2];
|
||||
String table = (String) row[tableIndex];
|
||||
List<Object[]> rowList = metaDataCache.cache.get(table);
|
||||
if (rowList == null) {
|
||||
rowList = new LinkedList<Object[]>();
|
||||
|
||||
@@ -270,6 +270,11 @@ public class RestrictionModel {
|
||||
}
|
||||
restriction.put(association, condition);
|
||||
}
|
||||
if (!association.isIgnored()) {
|
||||
if (association.hasNullableFK() && association.fkHasNullFilter()) {
|
||||
association.setOrResetFKNullFilter(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+4
-4
@@ -1,5 +1,5 @@
|
||||
-- keeps DB-statistic up-to-date for the following tables:
|
||||
-- JAILER_ENTITY
|
||||
-- JAILER_GRAPH
|
||||
-- JAILER_DEPENDENCY
|
||||
-- JAILER_SET
|
||||
ANALYZE TABLE ${JAILER_ENTITY};
|
||||
ANALYZE TABLE ${JAILER_GRAPH};
|
||||
ANALYZE TABLE ${JAILER_DEPENDENCY};
|
||||
ANALYZE TABLE ${JAILER_SET};
|
||||
|
||||
Executable → Regular
Executable → Regular
@@ -245,10 +245,11 @@ public class CsvFile {
|
||||
* @return decoded and splitted line
|
||||
*/
|
||||
public static String[] decodeLine(String line) {
|
||||
List<String> cells = new ArrayList<String>();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<String> cells = new ArrayList<String>(1000);
|
||||
StringBuilder sb = new StringBuilder(1000);
|
||||
boolean esc = false;
|
||||
for (int i = 0; i < line.length(); ++i) {
|
||||
int length = line.length();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
char c = line.charAt(i);
|
||||
if (c == '\\') {
|
||||
if (esc) {
|
||||
|
||||
@@ -248,6 +248,9 @@ public class Quoting {
|
||||
private static boolean isQuoted(String identifier, String qu) {
|
||||
if (identifier != null && identifier.length() > 1) {
|
||||
String q = identifier.substring(0, 1);
|
||||
if (q.equals("[") && identifier.endsWith("]")) {
|
||||
return true;
|
||||
}
|
||||
if (identifier.endsWith(q)) {
|
||||
char c = q.charAt(0);
|
||||
if (q.equals(qu) || isPotentialIdentifierQuote(c)) {
|
||||
@@ -287,6 +290,19 @@ public class Quoting {
|
||||
return staticUnquote(identifier).toUpperCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
public String normalizeCase(String identifier) {
|
||||
if (identifier == null) {
|
||||
return null;
|
||||
}
|
||||
if (unquotedIdentifierInMixedCase) {
|
||||
return identifier;
|
||||
}
|
||||
if (unquotedIdentifierInUpperCase) {
|
||||
return identifier.toUpperCase();
|
||||
}
|
||||
return identifier.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares a String to another String, ignoring case considerations and quoting.
|
||||
*
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package net.sf.jailer.util;
|
||||
|
||||
public class ToDo {
|
||||
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
package net.sf.jailer.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Image;
|
||||
@@ -430,7 +429,7 @@ public class AdditionalSubjectsDialog extends javax.swing.JDialog {
|
||||
|
||||
private void addAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addAllButtonActionPerformed
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
|
||||
List<Table> tables = new ArrayList<Table>(remaining);
|
||||
Collections.sort(tables);
|
||||
@@ -443,7 +442,7 @@ public class AdditionalSubjectsDialog extends javax.swing.JDialog {
|
||||
additionalSubjectListEditor.setModel(subjects);
|
||||
collectRemaining();
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}//GEN-LAST:event_addAllButtonActionPerformed
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-64,0,0,3,124"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-64,0,0,2,121"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
@@ -133,7 +133,7 @@
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="13" weightX="1.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="7" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="13" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@@ -153,7 +153,7 @@
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="-1" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@@ -164,6 +164,39 @@
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="5" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="4" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="findPathComboBox">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="4">
|
||||
<StringItem index="0" value="Item 1"/>
|
||||
<StringItem index="1" value="Item 2"/>
|
||||
<StringItem index="2" value="Item 3"/>
|
||||
<StringItem index="3" value="Item 4"/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findPathComboBoxActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="findPathButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Search"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findPathButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="4" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
|
||||
@@ -21,11 +21,13 @@ import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
@@ -45,6 +47,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.Stack;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Vector;
|
||||
@@ -67,6 +70,10 @@ import javax.swing.table.TableColumn;
|
||||
import net.sf.jailer.datamodel.Association;
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.ui.StringSearchPanel.AdditionalComponentFactory;
|
||||
import net.sf.jailer.ui.pathfinder.HistoryPanel;
|
||||
import net.sf.jailer.ui.pathfinder.PathFinder;
|
||||
import net.sf.jailer.ui.pathfinder.PathFinder.Result;
|
||||
import net.sf.jailer.ui.scrollmenu.JScrollMenu;
|
||||
import net.sf.jailer.ui.scrollmenu.JScrollPopupMenu;
|
||||
import net.sf.jailer.util.Pair;
|
||||
@@ -167,6 +174,71 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
findButton.setVisible(false);
|
||||
searchButton.setText("Find Table");
|
||||
|
||||
AutoCompletion.enable(findPathComboBox);
|
||||
findPathComboBox.getEditor().getEditorComponent().addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
if (e.getKeyChar() == '\n') {
|
||||
findButtonActionPerformed(null);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void keyPressed(KeyEvent arg0) {
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 3;
|
||||
gridBagConstraints.gridy = 2;
|
||||
Object currentSelection = rootTable.getSelectedItem();
|
||||
Table source = null;
|
||||
if (currentSelection instanceof String) {
|
||||
source = getDataModel().getTableByDisplayName((String) currentSelection);
|
||||
}
|
||||
final javax.swing.JComboBox comboBox = findPathComboBox;
|
||||
JButton stFindButtonButton = StringSearchPanel.createSearchButton(extractionModelEditor.extractionModelFrame, comboBox,
|
||||
new Object() {
|
||||
public String toString() {
|
||||
Table source = null;
|
||||
Object currentSelection = ClosureView.this.rootTable.getSelectedItem();
|
||||
if (currentSelection instanceof String) {
|
||||
source = getDataModel().getTableByDisplayName((String) currentSelection);
|
||||
}
|
||||
return (source != null? ("From " + getDataModel().getDisplayName(source) + " - ") : "") + "Select destination or choose from History";
|
||||
}
|
||||
},
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
findPathButtonActionPerformed(null);
|
||||
}
|
||||
}, null, null, null, true,
|
||||
new AdditionalComponentFactory() {
|
||||
@Override
|
||||
public JComponent create(final StringSearchPanel searchPanel) {
|
||||
HistoryPanel historyPanel = new HistoryPanel(ClosureView.this.getSelectedTable(), getDataModel()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void close() {
|
||||
searchPanel.close();
|
||||
}
|
||||
@Override
|
||||
protected void apply(Table source, Table destination) {
|
||||
findPath(source, destination, true);
|
||||
}
|
||||
};
|
||||
return historyPanel;
|
||||
}
|
||||
});
|
||||
tablePanel.add(stFindButtonButton, gridBagConstraints);
|
||||
|
||||
findPathComboBox.setVisible(false);
|
||||
findPathButton.setVisible(false);
|
||||
stFindButtonButton.setText("Find Path to...");
|
||||
|
||||
columnsComboBox.setModel(new DefaultComboBoxModel<Integer>(new Integer[] {
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
|
||||
}));
|
||||
@@ -245,6 +317,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
};
|
||||
closureTable.setShowGrid(false);
|
||||
closureTable.setSurrendersFocusOnKeystroke(true);
|
||||
closureTable.getTableHeader().setReorderingAllowed(false);
|
||||
jScrollPane1.setViewportView(closureTable);
|
||||
|
||||
closureTable.addMouseListener(new MouseListener() {
|
||||
@@ -262,7 +335,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
if (value == null || !(value instanceof String)) return;
|
||||
Table table = getDataModel().getTableByDisplayName((String) value);
|
||||
if (table != null) {
|
||||
JPopupMenu popup = ClosureView.this.extractionModelEditor.graphView.createPopupMenu(table, true);
|
||||
JPopupMenu popup = ClosureView.this.extractionModelEditor.graphView.createPopupMenu(table, createFindPathMenuItem(table), true);
|
||||
popup.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
@@ -362,7 +435,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
selectTableCell(column, row);
|
||||
}
|
||||
|
||||
ClosureView.this.extractionModelEditor.graphView.createPopupMenu(table, false);
|
||||
ClosureView.this.extractionModelEditor.graphView.createPopupMenu(table, null, false);
|
||||
popup.show(e.getComponent(), cellRect.x, cellRect.y + cellRect.height + 4);
|
||||
}
|
||||
}
|
||||
@@ -385,6 +458,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
private Font font = new JLabel("normal").getFont();
|
||||
private Font normal = new Font(font.getName(), font.getStyle() & ~Font.BOLD, font.getSize());
|
||||
private Font bold = new Font(font.getName(), font.getStyle() | Font.BOLD, font.getSize());
|
||||
// private Font italic = new Font(font.getName(), font.getStyle() | Font.ITALIC, font.getSize());
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table,
|
||||
@@ -436,6 +510,10 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
} else if (!allDisabled && someRestricted) {
|
||||
((JLabel) render).setForeground(new Color(0, 80, 160));
|
||||
}
|
||||
if (currentForcedDistance != null && currentForcedDistance.containsKey(t)) {
|
||||
((JLabel) render).setFont(bold);
|
||||
// ((JLabel) render).setForeground(new Color(150, 150, 150));
|
||||
}
|
||||
}
|
||||
}
|
||||
return render;
|
||||
@@ -541,8 +619,8 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
Table table = getDataModel().getTableByDisplayName(selectedTable);
|
||||
if (table != null) {
|
||||
CellInfo selectionInfo = cellInfo.get(selectedTable);
|
||||
selectionInfo.select();
|
||||
if (selectionInfo != null) {
|
||||
selectionInfo.select();
|
||||
Association association = null;
|
||||
for (CellInfo parent: selectionInfo.parents) {
|
||||
Table pre = parent.table;
|
||||
@@ -557,6 +635,58 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
}
|
||||
}
|
||||
}
|
||||
Stack<Table> toSelect = new Stack<Table>();
|
||||
CellInfo ci = selectionInfo;
|
||||
final int MAX_PATH_LENGTH = 1000;
|
||||
while (ci != null) {
|
||||
if (toSelect.size() > MAX_PATH_LENGTH) {
|
||||
break;
|
||||
}
|
||||
if (ci.table != null) {
|
||||
toSelect.push(ci.table);
|
||||
}
|
||||
CellInfo nextCi = null;
|
||||
for (CellInfo parent: ci.parents) {
|
||||
Table pre = parent.table;
|
||||
if (pre != null) {
|
||||
CellInfo preInfo = cellInfo.get(getDataModel().getDisplayName(pre));
|
||||
if (preInfo != null) {
|
||||
if (preInfo.selected) {
|
||||
if (preInfo.table != null) {
|
||||
nextCi = preInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ci = nextCi;
|
||||
}
|
||||
Table selTable = getSelectedTable();
|
||||
if (currentForcedDistance != null) {
|
||||
if (selTable != null && !toSelect.contains(selTable)
|
||||
||
|
||||
!currentForcedDistance.containsKey(table)) {
|
||||
refresh();
|
||||
selectTableCell(col, row);
|
||||
return;
|
||||
}
|
||||
}
|
||||
extractionModelEditor.incCaptureLevel();
|
||||
try {
|
||||
if (!toSelect.isEmpty()) {
|
||||
Table source = toSelect.pop();
|
||||
while (!toSelect.isEmpty()) {
|
||||
Table dest = toSelect.pop();
|
||||
if (!ClosureView.this.extractionModelEditor.graphView.isTableVisible(dest)) {
|
||||
ClosureView.this.extractionModelEditor.graphView.showTable(source, dest);
|
||||
}
|
||||
source = dest;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
extractionModelEditor.decCaptureLevel();
|
||||
}
|
||||
if (association != null && ClosureView.this.extractionModelEditor.select(association)) {
|
||||
return;
|
||||
}
|
||||
@@ -617,7 +747,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
// }
|
||||
|
||||
// table model
|
||||
refreshTableModel();
|
||||
refreshTableModel(null);
|
||||
|
||||
refreshing = false;
|
||||
}
|
||||
@@ -627,7 +757,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
*/
|
||||
public void refresh() {
|
||||
String prevSelection = selectedTable;
|
||||
refreshTableModel();
|
||||
refreshTableModel(null);
|
||||
if (cellInfo.containsKey(prevSelection)) {
|
||||
selectedTable = prevSelection;
|
||||
} else {
|
||||
@@ -637,15 +767,23 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
repaintClosureView();
|
||||
}
|
||||
|
||||
private Map<Table, Integer> currentForcedDistance = null;
|
||||
|
||||
/**
|
||||
* Refreshes the table model.
|
||||
* @param excludedTables
|
||||
* @param path
|
||||
*/
|
||||
private void refreshTableModel() {
|
||||
private void refreshTableModel(Map<Table, Integer> forcedDistance) {
|
||||
cellInfo.clear();
|
||||
dependencies.clear();
|
||||
currentForcedDistance = forcedDistance;
|
||||
if (forcedDistance == null) {
|
||||
forcedDistance = new HashMap<Table, Integer>();
|
||||
}
|
||||
Table selectedTable = getSelectedTable();
|
||||
refreshAssociationView(selectedTable);
|
||||
|
||||
|
||||
Object[] columns = new Object[tablesPerLine + 1];
|
||||
for (int i = 0; i < columns.length; ++i) {
|
||||
columns[i] = "";
|
||||
@@ -682,6 +820,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
TreeSet<String> nonIsolated = new TreeSet<String>();
|
||||
|
||||
while (!currentLine.isEmpty()) {
|
||||
|
||||
// add current line to table model
|
||||
if (distance == OMEGA || isolated) {
|
||||
Object[] lineAsObjects = new Object[tablesPerLine + 1];
|
||||
@@ -725,18 +864,32 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
|
||||
// get next line
|
||||
List<String> nextLine = new ArrayList<String>();
|
||||
|
||||
for (String t: currentLine) {
|
||||
Table table = getDataModel().getTableByDisplayName(t);
|
||||
if (table != null) {
|
||||
CellInfo cellInfoT = this.cellInfo.get(t);
|
||||
for (Association association: table.associations) {
|
||||
Integer fd = forcedDistance.get(association.destination);
|
||||
if (fd != null && fd != distance + 1) {
|
||||
continue;
|
||||
}
|
||||
boolean addToParent = true;
|
||||
if (forcedDistance.containsKey(association.destination)) {
|
||||
if (!forcedDistance.containsKey(table)) {
|
||||
addToParent = false;
|
||||
}
|
||||
}
|
||||
String displayName = getDataModel().getDisplayName(association.destination);
|
||||
if (!association.isIgnored()) {
|
||||
if (!association.isIgnored() ||
|
||||
(forcedDistance.containsKey(association.source) && forcedDistance.containsKey(association.destination))) {
|
||||
if (!visited.contains(displayName)) {
|
||||
nextLine.add(displayName);
|
||||
visited.add(displayName);
|
||||
CellInfo cellInfo = new CellInfo(distance);
|
||||
cellInfo.parents.add(cellInfoT);
|
||||
if (addToParent) {
|
||||
cellInfo.parents.add(cellInfoT);
|
||||
}
|
||||
cellInfo.table = association.destination;
|
||||
if (association.isInsertDestinationBeforeSource()) {
|
||||
dependencies.add(new Pair<String, String>(t, displayName));
|
||||
@@ -744,7 +897,9 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
this.cellInfo.put(displayName, cellInfo);
|
||||
} else {
|
||||
if (nextLine.contains(displayName)) {
|
||||
this.cellInfo.get(displayName).parents.add(cellInfoT);
|
||||
if (addToParent) {
|
||||
this.cellInfo.get(displayName).parents.add(cellInfoT);
|
||||
}
|
||||
if (association.isInsertDestinationBeforeSource()) {
|
||||
dependencies.add(new Pair<String, String>(t, displayName));
|
||||
}
|
||||
@@ -852,6 +1007,8 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
vector.addAll(nonIsolated);
|
||||
searchComboBox.setModel(new DefaultComboBoxModel<String>(vector));
|
||||
searchComboBox.setSelectedItem("");
|
||||
findPathComboBox.setModel(new DefaultComboBoxModel<String>(vector));
|
||||
findPathComboBox.setSelectedItem("");
|
||||
}
|
||||
|
||||
private Table getSelectedTable() {
|
||||
@@ -1102,9 +1259,9 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (SwingUtilities.isRightMouseButton(e)) {
|
||||
if (tableName != null) {
|
||||
Table table = getDataModel().getTable(tableName);
|
||||
final Table table = getDataModel().getTable(tableName);
|
||||
if (table != null) {
|
||||
JPopupMenu popup = ClosureView.this.extractionModelEditor.graphView.createPopupMenu(table, false);
|
||||
JPopupMenu popup = ClosureView.this.extractionModelEditor.graphView.createPopupMenu(table, createFindPathMenuItem(table), false);
|
||||
popup.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
@@ -1125,7 +1282,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Collects names of associations in the closure ordered by distance into {@link #associationClosure}.
|
||||
*
|
||||
@@ -1209,10 +1366,12 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
tablePanel = new javax.swing.JPanel();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
closureTable = new javax.swing.JTable();
|
||||
searchComboBox = new net.sf.jailer.ui.JComboBox();
|
||||
searchComboBox = new JComboBox();
|
||||
jLabel7 = new javax.swing.JLabel();
|
||||
columnsComboBox = new net.sf.jailer.ui.JComboBox();
|
||||
columnsComboBox = new JComboBox();
|
||||
findButton = new javax.swing.JButton();
|
||||
findPathComboBox = new JComboBox();
|
||||
findPathButton = new javax.swing.JButton();
|
||||
associationPane = new javax.swing.JPanel();
|
||||
associationPanel = new javax.swing.JPanel();
|
||||
jScrollPane2 = new javax.swing.JScrollPane();
|
||||
@@ -1236,8 +1395,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
|
||||
tabbedPane.setMinimumSize(new java.awt.Dimension(182, 190));
|
||||
tabbedPane.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
tabbedPaneStateChanged(evt);
|
||||
}
|
||||
});
|
||||
@@ -1277,8 +1435,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
|
||||
searchComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
|
||||
searchComboBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
searchComboBoxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
@@ -1289,7 +1446,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
|
||||
jLabel7.setText("Columns ");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 3;
|
||||
gridBagConstraints.gridx = 7;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
@@ -1297,29 +1454,50 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
|
||||
columnsComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
|
||||
columnsComboBox.addItemListener(new java.awt.event.ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
columnsComboBoxItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 2;
|
||||
tablePanel.add(columnsComboBox, gridBagConstraints);
|
||||
|
||||
findButton.setText("Search");
|
||||
findButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
findButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 5;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
|
||||
tablePanel.add(findButton, gridBagConstraints);
|
||||
|
||||
findPathComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
|
||||
findPathComboBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
findPathComboBoxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 2;
|
||||
tablePanel.add(findPathComboBox, gridBagConstraints);
|
||||
|
||||
findPathButton.setText("Search");
|
||||
findPathButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
findPathButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 3;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
|
||||
tablePanel.add(findButton, gridBagConstraints);
|
||||
tablePanel.add(findPathButton, gridBagConstraints);
|
||||
|
||||
tablePane.add(tablePanel);
|
||||
|
||||
@@ -1388,8 +1566,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
|
||||
showOnlyEnabledCheckBox.setText("Show only enabled associations");
|
||||
showOnlyEnabledCheckBox.addItemListener(new java.awt.event.ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
showOnlyEnabledCheckBoxItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
@@ -1466,6 +1643,72 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
}
|
||||
}//GEN-LAST:event_findButtonActionPerformed
|
||||
|
||||
private void findPathComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_findPathComboBoxActionPerformed
|
||||
}//GEN-LAST:event_findPathComboBoxActionPerformed
|
||||
|
||||
private void findPathButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_findPathButtonActionPerformed
|
||||
Object toFind = findPathComboBox.getSelectedItem();
|
||||
if (toFind != null) {
|
||||
CellInfo cellInfo = this.cellInfo.get(toFind);
|
||||
if (cellInfo != null) {
|
||||
Object currentSelection = rootTable.getSelectedItem();
|
||||
if (currentSelection instanceof String) {
|
||||
final Table source = getDataModel().getTableByDisplayName((String) currentSelection);
|
||||
// if (source.closure(true).contains(cellInfo.table)) {
|
||||
findPath(source, cellInfo.table, false);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_findPathButtonActionPerformed
|
||||
|
||||
protected JMenuItem createFindPathMenuItem(final Table table) {
|
||||
JMenuItem findPath = new JMenuItem("Find Path to " + getDataModel().getDisplayName(table));
|
||||
Object currentSelection = rootTable.getSelectedItem();
|
||||
if (currentSelection instanceof String) {
|
||||
final Table source = getDataModel().getTableByDisplayName((String) currentSelection);
|
||||
if (source.closure(false).contains(table)) {
|
||||
findPath.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
findPath(source, table, false);
|
||||
}
|
||||
});
|
||||
return findPath;
|
||||
}
|
||||
}
|
||||
findPath.setEnabled(false);
|
||||
return findPath;
|
||||
}
|
||||
|
||||
private void findPath(Table source, Table destination, boolean fromHistory) {
|
||||
Frame parent = null;
|
||||
Window w = SwingUtilities.getWindowAncestor(rootTable);
|
||||
if (w instanceof Frame) {
|
||||
parent = (Frame) w;
|
||||
}
|
||||
Result result = new PathFinder().find(source, destination, getDataModel(), false, fromHistory, parent);
|
||||
if (result != null) {
|
||||
Map<Table, Integer> fd = new HashMap<Table, Integer>();
|
||||
for (int i = 0; i < result.path.size(); ++i) {
|
||||
fd.put(result.path.get(i), i);
|
||||
}
|
||||
refreshTableModel(fd);
|
||||
List<Table> path = result.path;
|
||||
Table table = null;
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
table = path.get(i);
|
||||
// ClosureView.this.extractionModelEditor.select(table);
|
||||
}
|
||||
if (table != null) {
|
||||
CellInfo ci = cellInfo.get(getDataModel().getDisplayName(table));
|
||||
if (ci != null) {
|
||||
selectTableCell(ci.column, ci.row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initTabbedPane() {
|
||||
if (tabbedPane.getSelectedIndex() == 2) {
|
||||
tabAssTabPanel.removeAll();
|
||||
@@ -1493,9 +1736,11 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
private javax.swing.JPanel associationPane;
|
||||
private javax.swing.JPanel associationPanel;
|
||||
private javax.swing.JTable closureTable;
|
||||
private net.sf.jailer.ui.JComboBox columnsComboBox;
|
||||
private JComboBox columnsComboBox;
|
||||
public javax.swing.JPanel contentPanel;
|
||||
private javax.swing.JButton findButton;
|
||||
private javax.swing.JButton findPathButton;
|
||||
private JComboBox findPathComboBox;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel jLabel3;
|
||||
private javax.swing.JLabel jLabel4;
|
||||
@@ -1505,7 +1750,7 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JScrollPane jScrollPane2;
|
||||
private javax.swing.JSeparator jSeparator1;
|
||||
private net.sf.jailer.ui.JComboBox searchComboBox;
|
||||
private JComboBox searchComboBox;
|
||||
private javax.swing.JCheckBox showOnlyEnabledCheckBox;
|
||||
private javax.swing.JPanel tabAssAssPanel;
|
||||
private javax.swing.JPanel tabAssPanel;
|
||||
@@ -1523,4 +1768,9 @@ public abstract class ClosureView extends javax.swing.JDialog {
|
||||
public void addTabComponent(String titel, Container tab) {
|
||||
tabbedPane.addTab(titel, tab);
|
||||
}
|
||||
|
||||
public void selectTabComponent(Container tab) {
|
||||
tabbedPane.setSelectedComponent(tab);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package net.sf.jailer.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Font;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
@@ -179,7 +178,7 @@ public class ColumnOrderEditor extends javax.swing.JPanel {
|
||||
};
|
||||
|
||||
try {
|
||||
owner.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(owner);
|
||||
|
||||
Set<String> pks = new HashSet<String>();
|
||||
Set<String> fks = new HashSet<String>();
|
||||
@@ -236,7 +235,7 @@ public class ColumnOrderEditor extends javax.swing.JPanel {
|
||||
columnOrderTable.getRowSorter().setSortKeys(keys);
|
||||
adjustTableColumnsWidth();
|
||||
} finally {
|
||||
owner.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(owner);
|
||||
}
|
||||
dialog = new EscapableDialog(owner, "Column Ordering") {
|
||||
};
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
package net.sf.jailer.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.sql.SQLException;
|
||||
@@ -34,6 +37,8 @@ import javax.swing.JScrollPane;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.fife.rsta.ui.EscapableDialog;
|
||||
|
||||
import net.sf.jailer.datamodel.Column;
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
@@ -50,12 +55,12 @@ import net.sf.jailer.util.SqlUtil;
|
||||
*
|
||||
* @author Ralf Wisser
|
||||
*/
|
||||
public class ConditionEditor extends javax.swing.JDialog {
|
||||
|
||||
public class ConditionEditor extends EscapableDialog {
|
||||
|
||||
private boolean ok;
|
||||
private ParameterSelector parameterSelector;
|
||||
private DataModelBasedSQLCompletionProvider provider;
|
||||
|
||||
|
||||
/** Creates new form ConditionEditor */
|
||||
public ConditionEditor(java.awt.Frame parent, ParameterSelector.ParametersGetter parametersGetter, DataModel dataModel) {
|
||||
super(parent, true);
|
||||
@@ -525,6 +530,21 @@ public class ConditionEditor extends javax.swing.JDialog {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void setLocationAndFit(Point pos) {
|
||||
setLocation(pos);
|
||||
// UIUtil.fit(this);
|
||||
try {
|
||||
// Get the size of the screen
|
||||
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int hd = getY() - (dim.height - 80);
|
||||
if (hd > 0) {
|
||||
setLocation(getX(), Math.max(getY() - hd, 0));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts multi-line text into single line presentation.
|
||||
*/
|
||||
@@ -610,4 +630,5 @@ public class ConditionEditor extends javax.swing.JDialog {
|
||||
public final RSyntaxTextAreaWithSQLSyntaxStyle editorPane;
|
||||
|
||||
private static final long serialVersionUID = -5169934807182707970L;
|
||||
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ public class CyclesView extends javax.swing.JDialog {
|
||||
if (value == null || !(value instanceof String)) return;
|
||||
Table table = getDataModel().getTableByDisplayName((String) value);
|
||||
if (table != null) {
|
||||
JPopupMenu popup = CyclesView.this.extractionModelFrame.extractionModelEditor.graphView.createPopupMenu(table, false);
|
||||
JPopupMenu popup = CyclesView.this.extractionModelFrame.extractionModelEditor.graphView.createPopupMenu(table, null, false);
|
||||
UIUtil.fit(popup);
|
||||
popup.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ package net.sf.jailer.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.io.File;
|
||||
@@ -41,6 +43,7 @@ import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.RowSorter.SortKey;
|
||||
import javax.swing.SortOrder;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
@@ -53,6 +56,8 @@ import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.table.TableRowSorter;
|
||||
|
||||
import net.coderazzi.filters.gui.AutoChoices;
|
||||
import net.coderazzi.filters.gui.TableFilterHeader;
|
||||
import net.sf.jailer.ExecutionContext;
|
||||
import net.sf.jailer.JailerVersion;
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
@@ -243,7 +248,17 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
|
||||
sortLineList(associations, false);
|
||||
initComponents();
|
||||
|
||||
|
||||
TableFilterHeader filterHeader = new TableFilterHeader();
|
||||
filterHeader.setAutoChoices(AutoChoices.ENABLED);
|
||||
filterHeader.setTable(tablesTable);
|
||||
filterHeader.setMaxVisibleRows(20);
|
||||
|
||||
filterHeader = new TableFilterHeader();
|
||||
filterHeader.setAutoChoices(AutoChoices.ENABLED);
|
||||
filterHeader.setTable(associationsTable);
|
||||
filterHeader.setMaxVisibleRows(20);
|
||||
|
||||
String modelpath = executionContext.getQualifiedDatamodelFolder();
|
||||
try {
|
||||
modelpath = new File(modelpath).getAbsolutePath();
|
||||
@@ -278,8 +293,13 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
UIUtil.wireComponentWithButton(tablesTable, editTable);
|
||||
UIUtil.wireComponentWithButton(associationsTable, editAssociation);
|
||||
|
||||
setSize(1000, 700);
|
||||
setLocation(100, 32);
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
if (screenSize == null || screenSize.width < 1200) {
|
||||
setSize(1000, 700);
|
||||
} else {
|
||||
setSize(Math.min(screenSize.width - 2 * getX(), 2000), Math.min(screenSize.height - 2 * getY(), 800));
|
||||
}
|
||||
|
||||
File modelFinderColumnFile = new File(ModelBuilder.getModelBuilderColumnsFilename(executionContext));
|
||||
if (merge && modelFinderColumnFile.exists()) {
|
||||
@@ -310,73 +330,47 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
boolean fromModelFinder = linesFromModelFinder.contains(value);
|
||||
if (!(value instanceof CsvFile.Line)) {
|
||||
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
if (value == null) {
|
||||
value = "";
|
||||
}
|
||||
CsvFile.Line line = (CsvFile.Line) value;
|
||||
String tableName = line.cells.get(0);
|
||||
String pk = "";
|
||||
for (int i = 2; i < line.length; ++i) {
|
||||
if (line.cells.get(i).length() == 0) {
|
||||
break;
|
||||
}
|
||||
if (pk.length() > 0) {
|
||||
pk += ", ";
|
||||
}
|
||||
pk += line.cells.get(i);
|
||||
}
|
||||
value = column == 0? line.cells.get(0) : (pk.isEmpty()? "" : pk);
|
||||
boolean fromModelFinder = tableTableRowsFromModelFinder.contains(tablesTable.getRowSorter().convertRowIndexToModel(row));
|
||||
Component render = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
|
||||
render.setForeground(Color.BLACK);
|
||||
if (pk.equals("")) {
|
||||
render.setForeground(Color.RED);
|
||||
}
|
||||
if (fromModelFinder || modifiedColumnTables.contains(tableName)) {
|
||||
if (fromModelFinder || modifiedColumnTables.contains(value) && column == 0) {
|
||||
render.setBackground(isSelected? BG_SELCOLOR : BG_COLOR);
|
||||
} else {
|
||||
render.setBackground(isSelected? BG_SELCOLOR : (row % 2 == 0) ? BG1 : BG2);
|
||||
}
|
||||
if (tableTableRowsWithoutPK.contains(tablesTable.getRowSorter().convertRowIndexToModel(row))) {
|
||||
render.setForeground(Color.RED);
|
||||
}
|
||||
if (render instanceof JLabel) {
|
||||
((JLabel) render).setToolTipText(UIUtil.toHTML(String.valueOf(value), 100));
|
||||
if (!"".equals(value)) {
|
||||
((JLabel) render).setToolTipText(UIUtil.toHTML(String.valueOf(value), 100));
|
||||
} else {
|
||||
((JLabel) render).setToolTipText(null);
|
||||
}
|
||||
}
|
||||
return render;
|
||||
}
|
||||
private static final long serialVersionUID = -8591324056536900244L;
|
||||
};
|
||||
|
||||
|
||||
DefaultTableCellRenderer associationsListItemRenderer = new DefaultTableCellRenderer() {
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
boolean fromModelFinder = linesFromModelFinder.contains(value);
|
||||
if (!(value instanceof CsvFile.Line)) {
|
||||
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
||||
boolean fromModelFinder = associationTableRowsFromModelFinder.contains(associationsTable.getRowSorter().convertRowIndexToModel(row));
|
||||
if (value == null) {
|
||||
value = "";
|
||||
}
|
||||
CsvFile.Line line = (CsvFile.Line) value;
|
||||
String type = "associates";
|
||||
String typeTT = "associates";
|
||||
if ("B".equalsIgnoreCase(line.cells.get(2))) {
|
||||
type = "depends on";
|
||||
if (value.equals("depends on")) {
|
||||
typeTT = "depends on (has parent)";
|
||||
}
|
||||
if ("A".equalsIgnoreCase(line.cells.get(2))) {
|
||||
type = "has dependent (has child)";
|
||||
typeTT = "has dependent";
|
||||
if (value.equals("has dependent")) {
|
||||
typeTT = "has dependent (has child)";
|
||||
}
|
||||
String name = "";
|
||||
if (line.cells.get(5).length() > 0) {
|
||||
name = line.cells.get(5);
|
||||
}
|
||||
switch (column) {
|
||||
case 0: value = line.cells.get(0); break;
|
||||
case 1: value = line.cells.get(1); break;
|
||||
case 2: value = line.cells.get(4); break;
|
||||
case 3: value = type; break;
|
||||
case 4: value = line.cells.get(3); break;
|
||||
case 5: value = name; break;
|
||||
}
|
||||
// value = line.cells.get(0) + " " + type + " " + line.cells.get(1) + " " + name + line.cells.get(3) + " on " + line.cells.get(4);
|
||||
Component render = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
|
||||
if (fromModelFinder) {
|
||||
render.setBackground(isSelected? BG_SELCOLOR: BG_COLOR);
|
||||
@@ -399,7 +393,7 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
tablesTable.setAutoCreateRowSorter(true);
|
||||
|
||||
tablesTable.setDefaultRenderer(Object.class, tablesListItemRenderer);
|
||||
tablesTable.setModel(createTablesListModel());
|
||||
resetTableTableModel();
|
||||
|
||||
// tablesTable.setRowSelectionAllowed(false);
|
||||
tablesTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
@@ -409,17 +403,13 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
updateButtons();
|
||||
}
|
||||
});
|
||||
initRowSorter(tablesTable, new int[] { 0, 2 });
|
||||
initRowSorter(tablesTable);
|
||||
adjustTableColumnsWidth(tablesTable);
|
||||
|
||||
associationsTable.setDefaultRenderer(Object.class, associationsListItemRenderer);
|
||||
|
||||
associationsTable.setAutoCreateRowSorter(true);
|
||||
// List<SortKey> keys = new ArrayList<SortKey>();
|
||||
// keys.add(new SortKey(1, SortOrder.ASCENDING));
|
||||
// keys.add(new SortKey(3, SortOrder.ASCENDING));
|
||||
// associationsTable.getRowSorter().setSortKeys(keys);
|
||||
associationsTable.setModel(createAssociationsListModel());
|
||||
resetAssociationTableModel();
|
||||
adjustTableColumnsWidth(associationsTable);
|
||||
|
||||
associationsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@@ -428,7 +418,7 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
updateButtons();
|
||||
}
|
||||
});
|
||||
initRowSorter(associationsTable, new int[] { 0, 1, 4, 2, 3, 5 });
|
||||
initRowSorter(associationsTable);
|
||||
|
||||
invalidate();
|
||||
if (initiallyDirty) {
|
||||
@@ -463,6 +453,7 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
if (toEdit.getName().equals(l.cells.get(0))) {
|
||||
if (new TableEditor(DataModelEditor.this, displayNames, tables, associations, excludeFromDeletion).edit(l, columns)) {
|
||||
markDirty();
|
||||
resetTableTableModel();
|
||||
repaint();
|
||||
}
|
||||
break;
|
||||
@@ -471,13 +462,13 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (merge) {
|
||||
ModelBuilder.cleanUp(executionContext);
|
||||
}
|
||||
}
|
||||
|
||||
private void initRowSorter(JTable table, final int[] mapping) {
|
||||
private void initRowSorter(JTable table) {
|
||||
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()) {
|
||||
@Override
|
||||
protected boolean useToString(int column) {
|
||||
@@ -495,22 +486,6 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
}
|
||||
super.toggleSortOrder(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<?> getComparator(final int n) {
|
||||
return new Comparator<Object>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public int compare(Object o1, Object o2) {
|
||||
if (o1 instanceof Line) {
|
||||
if (o2 instanceof Line) {
|
||||
return ((Line) o1).cells.get(mapping[n]).compareTo(((Line) o2).cells.get(mapping[n]));
|
||||
}
|
||||
}
|
||||
return String.valueOf(o1).compareTo(String.valueOf(o2));
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
table.setRowSorter(sorter);
|
||||
}
|
||||
@@ -529,9 +504,9 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
comp = table.getCellRenderer(line, i).getTableCellRendererComponent(table, dtm.getValueAt(line, i), false, false, line, i);
|
||||
width = Math.max(width, comp.getPreferredSize().width);
|
||||
}
|
||||
column.setPreferredWidth(Math.min(width, 200));
|
||||
column.setPreferredWidth(Math.min(width, 400));
|
||||
}
|
||||
table.getColumnModel().getColumn(table.getColumnModel().getColumnCount() - 1).setPreferredWidth(80);
|
||||
table.getColumnModel().getColumn(table.getColumnModel().getColumnCount() - 1).setPreferredWidth(120);
|
||||
}
|
||||
|
||||
private KnownIdentifierMap createKnownIdentifierMap() throws IOException {
|
||||
@@ -853,7 +828,7 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
CsvFile.Line line = new CsvFile.Line("?", cells);
|
||||
if (new AssociationEditor(this, tables, associations, columns).edit(line)) {
|
||||
associations.add(0, line);
|
||||
associationsTable.setModel(createAssociationsListModel());
|
||||
resetAssociationTableModel();
|
||||
repaint();
|
||||
markDirty();
|
||||
}
|
||||
@@ -866,12 +841,29 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
}
|
||||
if (line != null) {
|
||||
if (new AssociationEditor(this, tables, associations, columns).edit(line)) {
|
||||
resetAssociationTableModel();
|
||||
markDirty();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_editAssociationActionPerformed
|
||||
|
||||
private void resetAssociationTableModel() {
|
||||
List<? extends SortKey> keys = associationsTable.getRowSorter().getSortKeys();
|
||||
associationsTable.setModel(createAssociationsListModel());
|
||||
initRowSorter(associationsTable);
|
||||
adjustTableColumnsWidth(associationsTable);
|
||||
associationsTable.getRowSorter().setSortKeys(keys);
|
||||
}
|
||||
|
||||
private void resetTableTableModel() {
|
||||
List<? extends SortKey> keys = tablesTable.getRowSorter().getSortKeys();
|
||||
tablesTable.setModel(createTablesListModel());
|
||||
initRowSorter(tablesTable);
|
||||
adjustTableColumnsWidth(tablesTable);
|
||||
tablesTable.getRowSorter().setSortKeys(keys);
|
||||
}
|
||||
|
||||
private void newTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newTableActionPerformed
|
||||
List<String> cells = new ArrayList<String>();
|
||||
cells.add("");
|
||||
@@ -884,7 +876,7 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
CsvFile.Line line = new CsvFile.Line("?", cells);
|
||||
if (new TableEditor(this, displayNames, tables, associations, excludeFromDeletion).edit(line, columns)) {
|
||||
tables.add(0, line);
|
||||
tablesTable.setModel(createTablesListModel());
|
||||
resetTableTableModel();
|
||||
markDirty();
|
||||
repaint();
|
||||
}
|
||||
@@ -895,6 +887,7 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
CsvFile.Line line = tables.get(tablesTable.getRowSorter().convertRowIndexToModel(tablesTable.getSelectedRow()));
|
||||
if (new TableEditor(this, displayNames, tables, associations, excludeFromDeletion).edit(line, columns)) {
|
||||
markDirty();
|
||||
resetTableTableModel();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
@@ -931,9 +924,9 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
displayNames.remove(k);
|
||||
}
|
||||
excludeFromDeletion.removeAll(namesOfTablesToDelete);
|
||||
tablesTable.setModel(createTablesListModel());
|
||||
resetTableTableModel();
|
||||
associations.removeAll(assToDelete);
|
||||
associationsTable.setModel(createAssociationsListModel());
|
||||
resetAssociationTableModel();
|
||||
for (Line l: toDelete) {
|
||||
columns.remove(l.cells.get(0));
|
||||
}
|
||||
@@ -947,10 +940,14 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
toDelete.add(associations.get(associationsTable.getRowSorter().convertRowIndexToModel(i)));
|
||||
}
|
||||
associations.removeAll(toDelete);
|
||||
associationsTable.setModel(createAssociationsListModel());
|
||||
resetAssociationTableModel();
|
||||
markDirty();
|
||||
}//GEN-LAST:event_deleteAssociationsActionPerformed
|
||||
|
||||
private Set<Integer> tableTableRowsFromModelFinder = new HashSet<Integer>();
|
||||
private Set<Integer> tableTableRowsWithoutPK = new HashSet<Integer>();
|
||||
private Set<Integer> associationTableRowsFromModelFinder = new HashSet<Integer>();
|
||||
|
||||
/**
|
||||
* Creates model for tables-list component.
|
||||
*
|
||||
@@ -963,8 +960,28 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
tableTableRowsFromModelFinder.clear();
|
||||
tableTableRowsWithoutPK.clear();
|
||||
int row = 0;
|
||||
for (CsvFile.Line line: tables) {
|
||||
tablesTableModel.addRow(new Object[] { line, line });
|
||||
String pk = "";
|
||||
for (int i = 2; i < line.length; ++i) {
|
||||
if (line.cells.get(i).length() == 0) {
|
||||
break;
|
||||
}
|
||||
if (pk.length() > 0) {
|
||||
pk += ", ";
|
||||
}
|
||||
pk += line.cells.get(i);
|
||||
}
|
||||
if (linesFromModelFinder.contains(line)) {
|
||||
tableTableRowsFromModelFinder.add(row);
|
||||
}
|
||||
if (pk.isEmpty()) {
|
||||
tableTableRowsWithoutPK.add(row);
|
||||
}
|
||||
tablesTableModel.addRow(new Object[] { line.cells.get(0), pk });
|
||||
++row;
|
||||
}
|
||||
return tablesTableModel;
|
||||
}
|
||||
@@ -981,8 +998,25 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
associationTableRowsFromModelFinder.clear();
|
||||
int row = 0;
|
||||
for (CsvFile.Line line: associations) {
|
||||
associationsTableModel.addRow(new Object[] { line, line, line, line, line, line });
|
||||
String type = "associates";
|
||||
if ("B".equalsIgnoreCase(line.cells.get(2))) {
|
||||
type = "depends on";
|
||||
}
|
||||
if ("A".equalsIgnoreCase(line.cells.get(2))) {
|
||||
type = "has dependent";
|
||||
}
|
||||
String name = "";
|
||||
if (line.cells.get(5).length() > 0) {
|
||||
name = line.cells.get(5);
|
||||
}
|
||||
if (linesFromModelFinder.contains(line)) {
|
||||
associationTableRowsFromModelFinder.add(row);
|
||||
}
|
||||
associationsTableModel.addRow(new Object[] { line.cells.get(0), line.cells.get(1), line.cells.get(4), type, line.cells.get(3), name });
|
||||
++row;
|
||||
}
|
||||
return associationsTableModel;
|
||||
}
|
||||
@@ -1156,4 +1190,4 @@ public class DataModelEditor extends javax.swing.JDialog {
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
private static final long serialVersionUID = -1267039412732180237L;
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,7 @@ import javax.swing.table.TableColumn;
|
||||
import net.sf.jailer.ExecutionContext;
|
||||
import net.sf.jailer.JailerVersion;
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
import net.sf.jailer.modelbuilder.JDBCMetaDataBasedModelElementFinder;
|
||||
import net.sf.jailer.modelbuilder.ModelBuilder;
|
||||
import net.sf.jailer.util.CancellationHandler;
|
||||
import net.sf.jailer.util.Pair;
|
||||
@@ -788,6 +789,7 @@ public abstract class DataModelManagerDialog extends javax.swing.JFrame {
|
||||
activateCurrentModel();
|
||||
|
||||
try {
|
||||
JDBCMetaDataBasedModelElementFinder.privilegedSessionProvider = new PrivilegedSessionProviderDialog.Provider(this);
|
||||
DbConnectionDialog dbConnectionDialog = new DbConnectionDialog(this, applicationName,
|
||||
new InfoBar("Connect with Database",
|
||||
"Select a connection to the database to be analyzed, or create a new connection.\n" +
|
||||
@@ -837,6 +839,7 @@ public abstract class DataModelManagerDialog extends javax.swing.JFrame {
|
||||
UIUtil.showException(this, "Error", e);
|
||||
} finally {
|
||||
ModelBuilder.assocFilter = null;
|
||||
JDBCMetaDataBasedModelElementFinder.privilegedSessionProvider = null;
|
||||
}
|
||||
|
||||
}//GEN-LAST:event_analyzeButtonActionPerformed
|
||||
@@ -844,6 +847,7 @@ public abstract class DataModelManagerDialog extends javax.swing.JFrame {
|
||||
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
|
||||
String folder = choseFolder();
|
||||
if (folder != null) {
|
||||
new File(folder).mkdir();
|
||||
executionContext.setDatamodelFolder(folder);
|
||||
baseFolders.remove(folder);
|
||||
baseFolders.add(0, folder);
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
<Container class="javax.swing.JPanel" name="jPanel2">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="100" gridWidth="4" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
<GridBagConstraints gridX="0" gridY="100" gridWidth="4" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="4" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
@@ -178,14 +178,14 @@
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="okButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value=" Ok "/>
|
||||
<Property name="text" type="java.lang.String" value=" Ok "/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="0" insetsRight="4" anchor="14" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="0" insetsRight="4" anchor="14" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@@ -198,7 +198,7 @@
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="14" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="3" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="14" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@@ -209,6 +209,19 @@
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="testConnectionButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="0" insetsRight="12" anchor="14" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="selectConnectionButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Select Connection "/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectConnectionButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="0" insetsRight="12" anchor="14" weightX="1.0" weightY="0.0"/>
|
||||
@@ -228,6 +241,9 @@
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JPasswordField" name="password">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="80" gridWidth="3" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="1.0"/>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package net.sf.jailer.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
@@ -42,6 +43,11 @@ public class DbConnectionDetailsEditor extends javax.swing.JDialog {
|
||||
* The connection to edit.
|
||||
*/
|
||||
private ConnectionInfo ci;
|
||||
|
||||
/**
|
||||
* <code>true</code> if connection must be tested on OK.
|
||||
*/
|
||||
private final boolean needsTest;
|
||||
|
||||
/**
|
||||
* Opens detail editor for a connection.
|
||||
@@ -50,6 +56,18 @@ public class DbConnectionDetailsEditor extends javax.swing.JDialog {
|
||||
* @return <code>true</code> if connection has been edited
|
||||
*/
|
||||
public boolean edit(ConnectionInfo ci) {
|
||||
setDetails(ci);
|
||||
setVisible(true);
|
||||
return isOk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets details.
|
||||
*
|
||||
* @param ci the connection
|
||||
* @return <code>true</code> if connection has been edited
|
||||
*/
|
||||
public void setDetails(ConnectionInfo ci) {
|
||||
this.ci = ci;
|
||||
alias.setText(ci.alias);
|
||||
dbUrl.setText(ci.url);
|
||||
@@ -60,16 +78,32 @@ public class DbConnectionDetailsEditor extends javax.swing.JDialog {
|
||||
jar2.setText(ci.jar2);
|
||||
jar3.setText(ci.jar3);
|
||||
jar4.setText(ci.jar4);
|
||||
setVisible(true);
|
||||
return isOk;
|
||||
}
|
||||
|
||||
|
||||
/** Creates new form DbConnectionDialog
|
||||
* @param forNew */
|
||||
public DbConnectionDetailsEditor(java.awt.Frame parent, final String jdbcHelpURL, boolean forNew) {
|
||||
this(parent, jdbcHelpURL, forNew, null, false);
|
||||
}
|
||||
|
||||
private final Frame parent;
|
||||
|
||||
/** Creates new form DbConnectionDialog
|
||||
* @param forNew
|
||||
* @param b */
|
||||
public DbConnectionDetailsEditor(java.awt.Frame parent, final String jdbcHelpURL, boolean forNew, InfoBar infoBar, boolean needsTest) {
|
||||
super(parent, true);
|
||||
this.parent = parent;
|
||||
this.needsTest = needsTest;
|
||||
initComponents();
|
||||
if (forNew) {
|
||||
if (needsTest) {
|
||||
testConnectionButton.setVisible(false);
|
||||
} else {
|
||||
selectConnectionButton.setVisible(false);
|
||||
}
|
||||
if (infoBar != null) {
|
||||
UIUtil.replace(infoBarLabel, infoBar);
|
||||
} else if (forNew) {
|
||||
UIUtil.replace(infoBarLabel, new InfoBar("New Connection",
|
||||
"Enter connection credentials for the database.\n" +
|
||||
"Replace placeholders (\"<...>\") with appropriate URL parameters.", null));
|
||||
@@ -173,6 +207,7 @@ public class DbConnectionDetailsEditor extends javax.swing.JDialog {
|
||||
okButton = new javax.swing.JButton();
|
||||
cancelButton = new javax.swing.JButton();
|
||||
testConnectionButton = new javax.swing.JButton();
|
||||
selectConnectionButton = new javax.swing.JButton();
|
||||
jLabel11 = new javax.swing.JLabel();
|
||||
password = new javax.swing.JPasswordField();
|
||||
helpjdbc = new javax.swing.JLabel();
|
||||
@@ -288,14 +323,14 @@ public class DbConnectionDetailsEditor extends javax.swing.JDialog {
|
||||
|
||||
jPanel2.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
okButton.setText(" Ok ");
|
||||
okButton.setText(" Ok ");
|
||||
okButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
okButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHEAST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 4);
|
||||
@@ -308,7 +343,7 @@ public class DbConnectionDetailsEditor extends javax.swing.JDialog {
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridx = 3;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHEAST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
|
||||
@@ -321,13 +356,27 @@ public class DbConnectionDetailsEditor extends javax.swing.JDialog {
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHEAST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 12);
|
||||
jPanel2.add(testConnectionButton, gridBagConstraints);
|
||||
|
||||
selectConnectionButton.setText("Select Connection ");
|
||||
selectConnectionButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
selectConnectionButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHEAST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 12);
|
||||
jPanel2.add(selectConnectionButton, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 100;
|
||||
@@ -335,6 +384,7 @@ public class DbConnectionDetailsEditor extends javax.swing.JDialog {
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
|
||||
jPanel1.add(jPanel2, gridBagConstraints);
|
||||
|
||||
jLabel11.setText(" ");
|
||||
@@ -448,14 +498,23 @@ public class DbConnectionDetailsEditor extends javax.swing.JDialog {
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
|
||||
if (fillConnectionInfo()) {
|
||||
isOk = true;
|
||||
setVisible(false);
|
||||
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
|
||||
if (fillConnectionInfo()) {
|
||||
if (needsTest) {
|
||||
if (!DbConnectionDialog.testConnection(isVisible()? this : parent, ci)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
isOk = true;
|
||||
onClose(isOk, ci);
|
||||
}
|
||||
}//GEN-LAST:event_okButtonActionPerformed
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void onClose(boolean ok, ConnectionInfo info) {
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean fillConnectionInfo() {
|
||||
boolean ok = true;
|
||||
Color red = new Color(255, 200, 180);
|
||||
@@ -486,13 +545,13 @@ private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS
|
||||
}
|
||||
|
||||
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
||||
setVisible(false);
|
||||
onClose(false, ci);
|
||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||
|
||||
private void testConnectionButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_testConnectionButtonActionPerformed
|
||||
if (fillConnectionInfo()) {
|
||||
if (DbConnectionDialog.testConnection(this, ci)) {
|
||||
JOptionPane.showMessageDialog(this, "Successfully established connection.", "Connected", JOptionPane.INFORMATION_MESSAGE);
|
||||
if (DbConnectionDialog.testConnection(isVisible()? this : parent, ci)) {
|
||||
JOptionPane.showMessageDialog(isVisible()? this : parent, "Successfully established connection.", "Connected", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
}//GEN-LAST:event_testConnectionButtonActionPerformed
|
||||
@@ -509,6 +568,13 @@ private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS
|
||||
private void loadButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadButton4ActionPerformed
|
||||
}//GEN-LAST:event_loadButton4ActionPerformed
|
||||
|
||||
private void selectConnectionButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectConnectionButtonActionPerformed
|
||||
onSelect();
|
||||
}//GEN-LAST:event_selectConnectionButtonActionPerformed
|
||||
|
||||
protected void onSelect() {
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
public javax.swing.JTextField alias;
|
||||
private javax.swing.JButton cancelButton;
|
||||
@@ -539,7 +605,8 @@ private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS
|
||||
private javax.swing.JButton loadButton3;
|
||||
private javax.swing.JButton loadButton4;
|
||||
private javax.swing.JButton okButton;
|
||||
private javax.swing.JPasswordField password;
|
||||
javax.swing.JPasswordField password;
|
||||
private javax.swing.JButton selectConnectionButton;
|
||||
private javax.swing.JButton testConnectionButton;
|
||||
public javax.swing.JTextField user;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@@ -354,11 +354,7 @@ public class DbConnectionDialog extends javax.swing.JDialog {
|
||||
|
||||
private boolean inRefresh = false;
|
||||
|
||||
private String jdbcHelpURL = "http://jailer.sourceforge.net/doc/jdbc.html?src=app";
|
||||
|
||||
public synchronized void setJdbcHelpURL(String jdbcHelpURL) {
|
||||
this.jdbcHelpURL = jdbcHelpURL;
|
||||
}
|
||||
public static final String jdbcHelpURL = "http://jailer.sourceforge.net/doc/jdbc.html?src=app";
|
||||
|
||||
/**
|
||||
* Refreshes the dialog after model changes.
|
||||
@@ -526,7 +522,7 @@ public class DbConnectionDialog extends javax.swing.JDialog {
|
||||
ConnectionInfo ci = new ConnectionInfo(executionContext);
|
||||
ci.alias = "Demo Scott";
|
||||
ci.driverClass = "org.h2.Driver";
|
||||
ci.jar1 = "lib" + File.separator + "h2-1.3.160.jar";
|
||||
ci.jar1 = "lib" + File.separator + "h2-1.3.175.jar";
|
||||
ci.url = "jdbc:h2:" + Environment.newFile("demo-scott").getPath();
|
||||
ci.user = "sa";
|
||||
ci.password = "";
|
||||
@@ -538,7 +534,7 @@ public class DbConnectionDialog extends javax.swing.JDialog {
|
||||
ConnectionInfo ci = new ConnectionInfo(executionContext);
|
||||
ci.alias = "Demo Sakila";
|
||||
ci.driverClass = "org.h2.Driver";
|
||||
ci.jar1 = "lib" + File.separator + "h2-1.3.160.jar";
|
||||
ci.jar1 = "lib" + File.separator + "h2-1.3.175.jar";
|
||||
ci.url = "jdbc:h2:" + Environment.newFile("demo-sakila").getPath();
|
||||
ci.user = "sa";
|
||||
ci.password = "";
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
@@ -439,7 +440,7 @@
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="80" green="80" red="80" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" (best for single-thread performance)"/>
|
||||
<Property name="text" type="java.lang.String" value=" (best for single-threaded performance)"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
@@ -452,7 +453,7 @@
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="80" green="80" red="80" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" (best for multi-thread performance)"/>
|
||||
<Property name="text" type="java.lang.String" value=" (best for multi-threaded performance)"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
@@ -465,7 +466,7 @@
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="80" green="80" red="80" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" (no write-access needed)"/>
|
||||
<Property name="text" type="java.lang.String" value=" (no write-access required)"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,6 @@ import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
@@ -218,7 +217,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
* The execution context.
|
||||
*/
|
||||
private final ExecutionContext executionContext;
|
||||
|
||||
|
||||
/**
|
||||
* Creates new form ModelTree.
|
||||
*
|
||||
@@ -240,12 +239,6 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
}
|
||||
};
|
||||
columnMapperDialog = new ColumnMapperDialog(extractionModelFrame, parametersGetter);
|
||||
try {
|
||||
dataModel = new DataModel(executionContext);
|
||||
} catch (Exception e) {
|
||||
UIUtil.showException(this, "Error in Data Model", e);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (extractionModelFile == null || !new File(extractionModelFile).exists()) {
|
||||
needsSave = extractionModelFile != null;
|
||||
@@ -282,10 +275,10 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
public void itemStateChanged(ItemEvent arg0) {
|
||||
Object o1 = rootTable.getSelectedItem();
|
||||
Object o2 = subjectTable.getSelectedItem();
|
||||
resetFocus.setEnabled(!(o1 == null && o2 == null || o1 != null && o1.equals(o2)));
|
||||
resetFocus.setEnabled(!(o1 == null && o2 == null || o1 != null && o1.equals(o2)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
rootTable.addItemListener(aListener);
|
||||
subjectTable.addItemListener(aListener);
|
||||
|
||||
@@ -320,6 +313,10 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
|
||||
closureView.addTabComponent("Closure Border", closureBorderView.getContentPane());
|
||||
closureBorderView.dispose();
|
||||
|
||||
restrDepsView = extractionModelFrame.restrictedDependenciesView.getContentPane();
|
||||
closureView.addTabComponent("Restricted Dependencies", restrDepsView);
|
||||
extractionModelFrame.restrictedDependenciesView.dispose();
|
||||
|
||||
Container cVContentPane = closureView.getContentPane();
|
||||
closureView.dispose();
|
||||
@@ -480,6 +477,15 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
onApply(false);
|
||||
}
|
||||
});
|
||||
restrictionEditor.fkToNullCheckBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (currentAssociation != null) {
|
||||
currentAssociation.setOrResetFKNullFilter(restrictionEditor.fkToNullCheckBox.isSelected());
|
||||
}
|
||||
onApply(false);
|
||||
}
|
||||
});
|
||||
// restrictionEditor.jump.addActionListener(new ActionListener() {
|
||||
// public void actionPerformed(ActionEvent e) {
|
||||
// onJump();
|
||||
@@ -659,7 +665,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
/**
|
||||
* The "closure view" component.
|
||||
*/
|
||||
private ClosureView closureView;
|
||||
ClosureView closureView;
|
||||
|
||||
void setOrientation(boolean horizontal) {
|
||||
isHorizontalLayout = horizontal;
|
||||
@@ -1388,7 +1394,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
if (selNode instanceof Association) {
|
||||
table = ((Association) selNode).destination;
|
||||
}
|
||||
JPopupMenu popup = graphView.createPopupMenu(table, false);
|
||||
JPopupMenu popup = graphView.createPopupMenu(table, null, false);
|
||||
popup.show(evt.getComponent(), evt.getX(), evt.getY());
|
||||
}
|
||||
}
|
||||
@@ -1763,7 +1769,11 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
private void initRestrictedDependencyWarningField() {
|
||||
restrictionEditor.restrictedDependencyWarning.setVisible(currentAssociation != null && !ScriptFormat.XML.equals(scriptFormat) && currentAssociation.isInsertDestinationBeforeSource() && currentAssociation.isRestricted());
|
||||
boolean restrictedDep = currentAssociation != null && !ScriptFormat.XML.equals(scriptFormat) && currentAssociation.isInsertDestinationBeforeSource() && currentAssociation.isRestricted();
|
||||
restrictionEditor.restrictedDependencyWarning.setVisible(restrictedDep);
|
||||
restrictionEditor.fkToNullCheckBox.setVisible(restrictedDep);
|
||||
restrictionEditor.fkToNullCheckBox.setEnabled(restrictedDep && currentAssociation.hasNullableFK());
|
||||
restrictionEditor.fkToNullCheckBox.setSelected(restrictedDep && currentAssociation.fkHasNullFilter());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1801,6 +1811,11 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
needsSave = true;
|
||||
extractionModelFrame.updateTitle(needsSave);
|
||||
}
|
||||
|
||||
if (restrictionEditor.restricted.isSelected() && currentAssociation.hasNullableFK() && currentAssociation.fkHasNullFilter()) {
|
||||
currentAssociation.setOrResetFKNullFilter(false);
|
||||
}
|
||||
|
||||
String condition;
|
||||
if (restrictionEditor.ignore.getModel().isSelected()) {
|
||||
condition = "ignore";
|
||||
@@ -2048,10 +2063,10 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
private void additionalSubjectsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_additionalSubjectsButtonActionPerformed
|
||||
AdditionalSubjectsDialog additionalSubjectsDialog;
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
additionalSubjectsDialog = new AdditionalSubjectsDialog(extractionModelFrame, extractionModel, subject, condition.getText());
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
if (additionalSubjectsDialog.edit()) {
|
||||
needsSave = true;
|
||||
@@ -2223,24 +2238,28 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (DefaultMutableTreeNode node: treeNodes) {
|
||||
if (node.getChildCount() > 0) {
|
||||
Table t = null;
|
||||
Association a = null;
|
||||
if (node.getUserObject() instanceof Association) {
|
||||
a = (Association) node.getUserObject();
|
||||
t = a.destination;
|
||||
}
|
||||
if (t != null && a != null && table.equals(t)) {
|
||||
select(a);
|
||||
TreePath treePath = new TreePath(node.getPath());
|
||||
tree.expandPath(treePath);
|
||||
for (int i = 0; i < node.getChildCount(); ++i) {
|
||||
DefaultMutableTreeNode c = (DefaultMutableTreeNode) node.getChildAt(i);
|
||||
tree.collapsePath(new TreePath(c.getPath()));
|
||||
for (boolean checkVisibility: new boolean [] { true, false }) {
|
||||
for (DefaultMutableTreeNode node: treeNodes) {
|
||||
if (node.getChildCount() > 0) {
|
||||
Table t = null;
|
||||
Association a = null;
|
||||
if (node.getUserObject() instanceof Association) {
|
||||
a = (Association) node.getUserObject();
|
||||
t = a.destination;
|
||||
}
|
||||
if (t != null && a != null && table.equals(t)) {
|
||||
if (!checkVisibility || (graphView.isTableVisible(a.source) && graphView.isTableVisible(a.destination))) {
|
||||
select(a);
|
||||
TreePath treePath = new TreePath(node.getPath());
|
||||
tree.expandPath(treePath);
|
||||
for (int i = 0; i < node.getChildCount(); ++i) {
|
||||
DefaultMutableTreeNode c = (DefaultMutableTreeNode) node.getChildAt(i);
|
||||
tree.collapsePath(new TreePath(c.getPath()));
|
||||
}
|
||||
tree.scrollPathToVisible(treePath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
tree.scrollPathToVisible(treePath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2931,7 +2950,9 @@ public class ExtractionModelEditor extends javax.swing.JPanel {
|
||||
private javax.swing.JPanel xmlMappingPanel;
|
||||
private javax.swing.JButton xmlTagApply;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
|
||||
Container restrDepsView;
|
||||
|
||||
private Icon dropDownIcon;
|
||||
private Icon conditionEditorIcon;
|
||||
private Icon conditionEditorSelectedIcon;
|
||||
|
||||
@@ -471,14 +471,6 @@
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cycleViewActionPerformed"/>
|
||||
</Events>
|
||||
</MenuItem>
|
||||
<MenuItem class="javax.swing.JMenuItem" name="restrictedDependenciesToolMenuItem">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Restricted Dependencies View"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="restrictedDependenciesToolMenuItemActionPerformed"/>
|
||||
</Events>
|
||||
</MenuItem>
|
||||
<MenuItem class="javax.swing.JMenuItem" name="renderHtml">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="HTML Rendering"/>
|
||||
|
||||
@@ -17,7 +17,6 @@ package net.sf.jailer.ui;
|
||||
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
@@ -45,12 +44,12 @@ import java.util.logging.Logger;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.InputMap;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.ToolTipManager;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UIManager.LookAndFeelInfo;
|
||||
import javax.swing.WindowConstants;
|
||||
@@ -70,6 +69,7 @@ import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.ddl.DDLCreator;
|
||||
import net.sf.jailer.extractionmodel.ExtractionModel;
|
||||
import net.sf.jailer.extractionmodel.ExtractionModel.AdditionalSubject;
|
||||
import net.sf.jailer.modelbuilder.JDBCMetaDataBasedModelElementFinder;
|
||||
import net.sf.jailer.modelbuilder.ModelBuilder;
|
||||
import net.sf.jailer.render.HtmlDataModelRenderer;
|
||||
import net.sf.jailer.subsetting.ScriptFormat;
|
||||
@@ -146,6 +146,29 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
initAnimationSteptime();
|
||||
isHorizontalLayout = isHorizonal;
|
||||
horizontalLayoutMenuItem.setSelected(isHorizontalLayout);
|
||||
|
||||
restrictedDependenciesView = new RestrictedDependenciesListDialog(this) {
|
||||
private static final long serialVersionUID = -7426280043553389753L;
|
||||
@Override
|
||||
protected Table getRoot() {
|
||||
return extractionModelEditor == null? null : extractionModelEditor.root;
|
||||
}
|
||||
@Override
|
||||
protected DataModel getDataModel() {
|
||||
return extractionModelEditor == null? null : extractionModelEditor.dataModel;
|
||||
}
|
||||
@Override
|
||||
protected void removeRestrictions(Collection<Association> associations) {
|
||||
if (extractionModelEditor != null) {
|
||||
extractionModelEditor.removeRestrictions(associations);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onSelect(Association association) {
|
||||
extractionModelEditor.select(association);
|
||||
}
|
||||
};
|
||||
|
||||
editorPanel.add(extractionModelEditor = new ExtractionModelEditor(extractionModelFile, this, isHorizontalLayout, getConnectivityState(), getConnectivityStateToolTip(), executionContext), "editor");
|
||||
extractionModelEditor.extractionModelFile = extractionModelFile;
|
||||
pack();
|
||||
@@ -176,28 +199,6 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
|
||||
updateMenuItems();
|
||||
|
||||
restrictedDependenciesView = new RestrictedDependenciesListDialog(this) {
|
||||
private static final long serialVersionUID = -7426280043553389753L;
|
||||
@Override
|
||||
protected Table getRoot() {
|
||||
return extractionModelEditor == null? null : extractionModelEditor.root;
|
||||
}
|
||||
@Override
|
||||
protected DataModel getDataModel() {
|
||||
return extractionModelEditor == null? null : extractionModelEditor.dataModel;
|
||||
}
|
||||
@Override
|
||||
protected void removeRestrictions(Collection<Association> associations) {
|
||||
if (extractionModelEditor != null) {
|
||||
extractionModelEditor.removeRestrictions(associations);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onSelect(Association association) {
|
||||
extractionModelEditor.select(association);
|
||||
}
|
||||
};
|
||||
|
||||
cycleViewDialog = new CyclesView(this);
|
||||
filterEditorDialog = new FilterEditorDialog(this, new ParameterSelector.ParametersGetter() {
|
||||
@Override
|
||||
@@ -217,7 +218,8 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
for (final String item: list) {
|
||||
JMenuItem menuItem = new JMenuItem(item.split(",")[0]);
|
||||
sandBox.add(menuItem);
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
final ActionListener a;
|
||||
menuItem.addActionListener(a = new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
@@ -225,12 +227,20 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
String tmpFileName = Configuration.getInstance().createTempFile().getPath();
|
||||
extractionModelEditor.save(tmpFileName);
|
||||
ExtractionModel extractionModel = new ExtractionModel(tmpFileName, new HashMap<String, String>(), new HashMap<String, String>(), executionContext);
|
||||
c.getMethod("main", ExtractionModel.class).invoke(c.newInstance(), extractionModel);
|
||||
c.getMethod("main", ExtractionModel.class, JFrame.class).invoke(c.newInstance(), extractionModel, ExtractionModelFrame.this);
|
||||
} catch (Throwable t) {
|
||||
UIUtil.showException(ExtractionModelFrame.this, "Error", t);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (menuItem.getText().endsWith("!")) {
|
||||
UIUtil.invokeLater(4, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
a.actionPerformed(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
@@ -346,7 +356,6 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
openDataBrowserItem = new javax.swing.JMenuItem();
|
||||
queryBuilder = new javax.swing.JMenuItem();
|
||||
cycleView = new javax.swing.JMenuItem();
|
||||
restrictedDependenciesToolMenuItem = new javax.swing.JMenuItem();
|
||||
renderHtml = new javax.swing.JMenuItem();
|
||||
jMenu2 = new javax.swing.JMenu();
|
||||
helpContent = new javax.swing.JMenuItem();
|
||||
@@ -823,14 +832,6 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
});
|
||||
jMenu3.add(cycleView);
|
||||
|
||||
restrictedDependenciesToolMenuItem.setText("Restricted Dependencies View");
|
||||
restrictedDependenciesToolMenuItem.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
restrictedDependenciesToolMenuItemActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
jMenu3.add(restrictedDependenciesToolMenuItem);
|
||||
|
||||
renderHtml.setText("HTML Rendering");
|
||||
renderHtml.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
@@ -1072,6 +1073,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
@Override
|
||||
public Boolean call() {
|
||||
try {
|
||||
JDBCMetaDataBasedModelElementFinder.privilegedSessionProvider = new PrivilegedSessionProviderDialog.Provider(ExtractionModelFrame.this);
|
||||
if (connectToDBIfNeeded("Analyze Database")) {
|
||||
List<String> args = new ArrayList<String>();
|
||||
args.add("build-model-wo-merge");
|
||||
@@ -1080,13 +1082,13 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
AnalyseOptionsDialog analyseOptionsDialog = new AnalyseOptionsDialog(ExtractionModelFrame.this, extractionModelEditor.dataModel, executionContext);
|
||||
boolean[] isDefaultSchema = new boolean[1];
|
||||
String[] defaultSchema = new String[1];
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(ExtractionModelFrame.this);
|
||||
List<String> schemas;
|
||||
try {
|
||||
CancellationHandler.reset(null);
|
||||
schemas = dbConnectionDialog.getDBSchemas(defaultSchema);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(ExtractionModelFrame.this);
|
||||
}
|
||||
if (analyseOptionsDialog.edit(schemas, defaultSchema[0], isDefaultSchema, dbConnectionDialog.currentConnection.user)) {
|
||||
String schema = analyseOptionsDialog.getSelectedSchema();
|
||||
@@ -1113,6 +1115,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
UIUtil.showException(ExtractionModelFrame.this, "Error", e);
|
||||
} finally {
|
||||
ModelBuilder.assocFilter = null;
|
||||
JDBCMetaDataBasedModelElementFinder.privilegedSessionProvider = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1148,11 +1151,10 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
if (restrictedDependency != null) {
|
||||
switch (JOptionPane.showOptionDialog(this,
|
||||
"Dependency from '" + restrictedDependency.source.getName() + "' to '" + restrictedDependency.destination.getName() + "'\n" +
|
||||
"is restricted.\nReferential integrity is not guaranteed!", "Restricted Dependency", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, new Object[] { "Ok", "Cancel", "Show Dependency" }, "Cancel")) {
|
||||
"is restricted.\nReferential integrity is not guaranteed!", "Restricted Dependency", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, null, new Object[] { "Ok", "Cancel", "Show dependency" }, "Cancel")) {
|
||||
case 1: return;
|
||||
case 2:
|
||||
restrictedDependenciesView.setVisible(true);
|
||||
restrictedDependenciesView.toFront();
|
||||
extractionModelEditor.closureView.selectTabComponent(extractionModelEditor.restrDepsView);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1260,7 +1262,9 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
private Association findRestrictedDependency(DataModel dataModel) {
|
||||
for (Association association: dataModel.namedAssociations.values()) {
|
||||
if (association.isInsertDestinationBeforeSource() && association.isRestricted()) {
|
||||
return association;
|
||||
if (!association.fkHasNullFilter()) {
|
||||
return association;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -1388,10 +1392,10 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
load(modelFile);
|
||||
} else {
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
createFrame(modelFile, false);
|
||||
UIUtil.setWaitCursor(this);
|
||||
createFrame(modelFile, false, executionContext);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1427,7 +1431,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
JOptionPane.showMessageDialog(this, "Unable to load \"" + new File(modelFile).getName() + "\"\nExtraction model is assigned to data model \"" + DataModelManager.getModelDetails(dmf, executionContext).a + "\"", "Wrong Data Model", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
extractionModelEditor.extractionModelFrame = null;
|
||||
editorPanel.remove(extractionModelEditor);
|
||||
extractionModelEditor = null;
|
||||
@@ -1440,13 +1444,13 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
} catch (Throwable t) {
|
||||
UIUtil.showException(this, "Error", t);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void newModelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newModelActionPerformed
|
||||
try {
|
||||
createFrame(null, false);
|
||||
createFrame(null, false, executionContext);
|
||||
} catch (Throwable t) {
|
||||
UIUtil.showException(this, "Error", t);
|
||||
} finally {
|
||||
@@ -1455,7 +1459,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
|
||||
private void reload() {
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
extractionModelEditor.extractionModelFrame = null;
|
||||
editorPanel.remove(extractionModelEditor);
|
||||
editorPanel.add(extractionModelEditor = new ExtractionModelEditor(extractionModelEditor.extractionModelFile, this, isHorizontalLayout, getConnectivityState(), getConnectivityStateToolTip(), executionContext), "editor");
|
||||
@@ -1467,7 +1471,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
} catch (Throwable t) {
|
||||
UIUtil.showException(this, "Error", t);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1688,11 +1692,6 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
extractionModelEditor.closureBorderView.toFront();
|
||||
}//GEN-LAST:event_closureBorderToolMenuItemActionPerformed
|
||||
|
||||
private void restrictedDependenciesToolMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_restrictedDependenciesToolMenuItemActionPerformed
|
||||
restrictedDependenciesView.setVisible(true);
|
||||
restrictedDependenciesView.toFront();
|
||||
}//GEN-LAST:event_restrictedDependenciesToolMenuItemActionPerformed
|
||||
|
||||
private void reloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reloadActionPerformed
|
||||
try {
|
||||
if (extractionModelEditor.extractionModelFile == null) {
|
||||
@@ -1801,12 +1800,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
* Changes some nimbus LAF defaults.
|
||||
*/
|
||||
public static void customizeNimbus() {
|
||||
try {
|
||||
ToolTipManager.sharedInstance().setInitialDelay(500);
|
||||
ToolTipManager.sharedInstance().setDismissDelay(7000);
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
// nothing to do yet
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1873,6 +1867,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
UIManager.put("InternalFrame:InternalFrameTitlePane[Enabled].textForeground", Color.BLUE);
|
||||
}
|
||||
|
||||
UIUtil.prepareUI();
|
||||
} catch (Exception x) {
|
||||
}
|
||||
|
||||
@@ -1884,7 +1879,7 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
file = commandLine.arguments.get(0);
|
||||
}
|
||||
}
|
||||
createFrame(file, true);
|
||||
createFrame(file, true, null);
|
||||
} catch (Throwable e) {
|
||||
UIUtil.showException(null, "Error", e);
|
||||
}
|
||||
@@ -1941,11 +1936,15 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
return extractionModelFrame;
|
||||
}
|
||||
|
||||
public static void createFrame(String file, final boolean withStartupWizzard) {
|
||||
public static void createFrame(String file, final boolean withStartupWizzard, ExecutionContext executionContext) {
|
||||
try {
|
||||
final String finalFile = file;
|
||||
if (file != null && new File(file).exists()) {
|
||||
ExecutionContext executionContext = new ExecutionContext(CommandLineInstance.getInstance());
|
||||
if (executionContext == null) {
|
||||
executionContext = new ExecutionContext(CommandLineInstance.getInstance());
|
||||
} else {
|
||||
executionContext = new ExecutionContext(executionContext);
|
||||
}
|
||||
DataModelManager.setCurrentModelSubfolder(ExtractionModel.loadDatamodelFolder(file, executionContext), executionContext);
|
||||
createFrame(finalFile, true, true, null, executionContext);
|
||||
} else {
|
||||
@@ -2070,7 +2069,6 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
public javax.swing.JMenuItem reload;
|
||||
private javax.swing.JMenuItem removeAllRestrictions;
|
||||
private javax.swing.JMenuItem renderHtml;
|
||||
private javax.swing.JMenuItem restrictedDependenciesToolMenuItem;
|
||||
private javax.swing.JMenuItem save;
|
||||
private javax.swing.JMenuItem saveAs;
|
||||
private javax.swing.JCheckBoxMenuItem showIgnored;
|
||||
@@ -2096,4 +2094,4 @@ public class ExtractionModelFrame extends javax.swing.JFrame {
|
||||
|
||||
private static final long serialVersionUID = -2252377308370736756L;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -108,8 +108,10 @@ public class NeighborhoodPanel extends javax.swing.JPanel {
|
||||
length = graphView.getHeight() / (getFontMetrics(font).getHeight() + 2) - 12;
|
||||
if (length < 2) {
|
||||
length = 2;
|
||||
} else if (length > 20) {
|
||||
length = 20;
|
||||
}
|
||||
|
||||
|
||||
initTableList(dataModel, table, hideIgnored, graphView);
|
||||
createTableLinks(dataModel, table, graphView, hideIgnored);
|
||||
|
||||
@@ -161,7 +163,7 @@ public class NeighborhoodPanel extends javax.swing.JPanel {
|
||||
@Override
|
||||
protected void onRightClick(MouseEvent e) {
|
||||
if (t != null) {
|
||||
JPopupMenu popup = graphView.createPopupMenu(t, true);
|
||||
JPopupMenu popup = graphView.createPopupMenu(t, null, true);
|
||||
popup.show(e.getComponent(), e.getX(), e.getY());
|
||||
popup.addPopupMenuListener(new PopupMenuListener() {
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="detailsContainerPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright 2007 - 2018 the original author or authors.
|
||||
*
|
||||
* 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 net.sf.jailer.ui;
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import net.sf.jailer.ExecutionContext;
|
||||
import net.sf.jailer.JailerVersion;
|
||||
import net.sf.jailer.database.BasicDataSource;
|
||||
import net.sf.jailer.database.Session;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.modelbuilder.JDBCMetaDataBasedModelElementFinder;
|
||||
import net.sf.jailer.ui.DbConnectionDialog.ConnectionInfo;
|
||||
import net.sf.jailer.util.ClasspathUtil;
|
||||
|
||||
/**
|
||||
* Asks for an alternative connection if the database analyzers connection has
|
||||
* insufficient privileges to analyze a certain schema.
|
||||
*
|
||||
* @author Ralf Wisser
|
||||
*/
|
||||
public class PrivilegedSessionProviderDialog extends javax.swing.JDialog {
|
||||
|
||||
public static class Provider implements JDBCMetaDataBasedModelElementFinder.PrivilegedSessionProvider {
|
||||
private final Frame parent;
|
||||
private Set<String> tabu = new HashSet<String>();
|
||||
|
||||
public Provider(Frame parent) {
|
||||
synchronized(this) {
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session askForSessionWithPermissionToReadSchema(final Session session, final Table view, final String schema, final String tableName,
|
||||
final ExecutionContext executionContext) {
|
||||
final Frame theParent;
|
||||
synchronized(this) {
|
||||
theParent = parent;
|
||||
}
|
||||
if (tabu.contains(schema)) {
|
||||
return null;
|
||||
}
|
||||
final AtomicReference<Session> newSession = new AtomicReference<>();
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
InfoBar infoBar = new InfoBar("Insufficient Privileges",
|
||||
"Need to analyze schema \"" + schema + "\" because\n" +
|
||||
"view \"" + view.getName() + "\" is based on table \"" + schema + "." + tableName +"\".\n" +
|
||||
"but that's not possible with the current connection.\n ",
|
||||
"Please choose an alternative connection with the required privileges."
|
||||
);
|
||||
final PrivilegedSessionProviderDialog dialog = new PrivilegedSessionProviderDialog(theParent);
|
||||
ConnectionInfo ci = new ConnectionInfo();
|
||||
final DbConnectionDialog connectionDialog = new DbConnectionDialog(theParent, JailerVersion.APPLICATION_NAME, infoBar, executionContext, true) {
|
||||
@Override
|
||||
protected boolean isAssignedToDataModel(String dataModelFolder) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
final DbConnectionDetailsEditor detailsEditor = new DbConnectionDetailsEditor(theParent, DbConnectionDialog.jdbcHelpURL, false, infoBar, true) {
|
||||
@Override
|
||||
protected void onClose(boolean ok, ConnectionInfo info) {
|
||||
dialog.setVisible(false);
|
||||
if (ok) {
|
||||
try {
|
||||
BasicDataSource dataSource = new BasicDataSource(info.driverClass,
|
||||
info.url, info.user,
|
||||
info.password, 0, ClasspathUtil.toURLArray(info.jar1, info.jar2, info.jar3, info.jar4));
|
||||
newSession.set(new Session(dataSource, dataSource.dbms));
|
||||
} catch (Exception e) {
|
||||
UIUtil.showException(theParent, "Error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onSelect() {
|
||||
if (connectionDialog.connect("Analyze Database")) {
|
||||
try {
|
||||
setDetails((ConnectionInfo) connectionDialog.currentConnection.clone());
|
||||
} catch (CloneNotSupportedException e) {
|
||||
setDetails(connectionDialog.currentConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
ci.alias = "(temporary)";
|
||||
ci.driverClass = session.driverClassName;
|
||||
ci.url = session.dbUrl;
|
||||
ci.user = schema;
|
||||
detailsEditor.setDetails(ci);
|
||||
dialog.detailsContainerPanel.add(detailsEditor.getContentPane());
|
||||
detailsEditor.password.grabFocus();
|
||||
dialog.setLocation(100, 150);
|
||||
dialog.pack();
|
||||
dialog.setSize(Math.max(500, dialog.getWidth()), dialog.getHeight());
|
||||
UIUtil.initPeer();
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
Session result = newSession.get();
|
||||
if (result == null) {
|
||||
tabu.add(schema);
|
||||
}
|
||||
return result;
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new form PrivilegedSessionProvider
|
||||
*/
|
||||
public PrivilegedSessionProviderDialog(Frame parent) {
|
||||
super(parent, true);
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
java.awt.GridBagConstraints gridBagConstraints;
|
||||
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
detailsContainerPanel = new javax.swing.JPanel();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
getContentPane().setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
jPanel1.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
detailsContainerPanel.setLayout(new java.awt.BorderLayout());
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(detailsContainerPanel, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
getContentPane().add(jPanel1, gridBagConstraints);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JPanel detailsContainerPanel;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
@@ -198,6 +198,19 @@
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JCheckBox" name="fkToNullCheckBox">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Set foreign key columns to null"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="1"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="10" gridWidth="6" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel4">
|
||||
|
||||
@@ -72,6 +72,7 @@ public class RestrictionEditor extends javax.swing.JPanel {
|
||||
jPanel9 = new javax.swing.JPanel();
|
||||
restriction = new javax.swing.JTextField();
|
||||
apply = new javax.swing.JButton();
|
||||
fkToNullCheckBox = new javax.swing.JCheckBox();
|
||||
jPanel4 = new javax.swing.JPanel();
|
||||
columnsA = new javax.swing.JLabel();
|
||||
source = new javax.swing.JLabel();
|
||||
@@ -168,6 +169,15 @@ public class RestrictionEditor extends javax.swing.JPanel {
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
|
||||
jPanel7.add(jPanel9, gridBagConstraints);
|
||||
|
||||
fkToNullCheckBox.setText("Set foreign key columns to null");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 10;
|
||||
gridBagConstraints.gridwidth = 6;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.insets = new java.awt.Insets(2, 0, 0, 0);
|
||||
jPanel7.add(fkToNullCheckBox, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 3;
|
||||
@@ -257,6 +267,7 @@ public class RestrictionEditor extends javax.swing.JPanel {
|
||||
javax.swing.JLabel columnsA;
|
||||
javax.swing.JLabel columnsB;
|
||||
public javax.swing.JLabel destination;
|
||||
public javax.swing.JCheckBox fkToNullCheckBox;
|
||||
public javax.swing.JRadioButton ignore;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel4;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,85,0,0,1,-63"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
@@ -200,5 +200,14 @@
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="plugInPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="10" gridY="1" gridWidth="1" gridHeight="3" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
||||
@@ -17,7 +17,6 @@ package net.sf.jailer.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridLayout;
|
||||
@@ -30,6 +29,8 @@ import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -48,6 +49,8 @@ import javax.swing.DefaultListModel;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
@@ -56,6 +59,8 @@ import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.event.ListDataEvent;
|
||||
import javax.swing.event.ListDataListener;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
@@ -80,29 +85,46 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
public interface Prepare {
|
||||
void prepare(Set<MDSchema> selectedSchemas);
|
||||
}
|
||||
|
||||
public static JButton createSearchButton(final Frame owner, final javax.swing.JComboBox comboBox, final String titel, final Runnable onSuccess) {
|
||||
return createSearchButton(owner, comboBox, titel, onSuccess, null);
|
||||
|
||||
public interface AdditionalComponentFactory {
|
||||
JComponent create(StringSearchPanel searchPanel);
|
||||
}
|
||||
|
||||
public static JButton createSearchButton(final Frame owner, final javax.swing.JComboBox comboBox, final Object titel, final Runnable onSuccess) {
|
||||
return createSearchButton(owner, comboBox, titel, onSuccess, false);
|
||||
}
|
||||
|
||||
public static JButton createSearchButton(final Frame owner, final javax.swing.JComboBox comboBox, final Object titel, final Runnable onSuccess, boolean alternativeIcon) {
|
||||
return createSearchButton(owner, comboBox, titel, onSuccess, null, alternativeIcon);
|
||||
}
|
||||
|
||||
public static JButton createSearchButton(final Frame owner, final javax.swing.JComboBox comboBox, final String titel, final Runnable onSuccess, final Prepare prepare) {
|
||||
return createSearchButton(owner, comboBox, titel, onSuccess, null, null, null);
|
||||
public static JButton createSearchButton(final Frame owner, final javax.swing.JComboBox comboBox, final Object titel, final Runnable onSuccess, final Prepare prepare, boolean alternativeIcon) {
|
||||
return createSearchButton(owner, comboBox, titel, onSuccess, null, null, null, alternativeIcon, null);
|
||||
}
|
||||
|
||||
public static JButton createSearchButton(final Frame owner, final javax.swing.JComboBox comboBox, final String titel, final Runnable onSuccess, final Prepare prepare, final MetaDataSource metaDataSource, final DataModel dataModel) {
|
||||
public static JButton createSearchButton(final Frame owner, final javax.swing.JComboBox comboBox, final Object titel, final Runnable onSuccess, final Prepare prepare, final MetaDataSource metaDataSource, final DataModel dataModel) {
|
||||
return createSearchButton(owner, comboBox, titel, onSuccess, prepare, metaDataSource, dataModel, false, null);
|
||||
}
|
||||
|
||||
public static JButton createSearchButton(final Frame owner, final javax.swing.JComboBox comboBox, final Object titel, final Runnable onSuccess, final Prepare prepare, final MetaDataSource metaDataSource, final DataModel dataModel, boolean alternativeIcon, final AdditionalComponentFactory additionalComponentFactory) {
|
||||
final JButton button = new JButton();
|
||||
button.setIcon(UIUtil.scaleIcon(button, icon));
|
||||
button.setIcon(UIUtil.scaleIcon(button, alternativeIcon? icon2 : icon));
|
||||
button.setToolTipText("Find Table");
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
button.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(button);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Point location = button.getLocationOnScreen();
|
||||
StringSearchPanel searchPanel = new StringSearchPanel(comboBox, metaDataSource, dataModel, prepare);
|
||||
if (additionalComponentFactory != null) {
|
||||
searchPanel.plugInPanel.add(additionalComponentFactory.create(searchPanel), java.awt.BorderLayout.CENTER);
|
||||
} else {
|
||||
searchPanel.plugInPanel.setVisible(false);
|
||||
}
|
||||
String result = searchPanel.find(owner, titel, location.x, location.y);
|
||||
if (result != null && !result.equals(searchPanel.showAllLabel)) {
|
||||
comboBox.setSelectedItem(result);
|
||||
@@ -111,17 +133,44 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
button.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(button);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (prepare == null) {
|
||||
updateEnabledState(button, comboBox);
|
||||
comboBox.getModel().addListDataListener(new ListDataListener() {
|
||||
@Override
|
||||
public void intervalRemoved(ListDataEvent arg0) {
|
||||
updateEnabledState(button, comboBox);
|
||||
}
|
||||
@Override
|
||||
public void intervalAdded(ListDataEvent arg0) {
|
||||
updateEnabledState(button, comboBox);
|
||||
}
|
||||
@Override
|
||||
public void contentsChanged(ListDataEvent arg0) {
|
||||
updateEnabledState(button, comboBox);
|
||||
}
|
||||
});
|
||||
comboBox.addPropertyChangeListener("model", new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent arg0) {
|
||||
updateEnabledState(button, comboBox);
|
||||
}
|
||||
});
|
||||
}
|
||||
return button;
|
||||
}
|
||||
|
||||
public String find(Frame owner, String titel, int x, int y) {
|
||||
dialog = new EscapableDialog(owner, titel, true) {
|
||||
|
||||
private static void updateEnabledState(JButton button, JComboBox comboBox) {
|
||||
button.setEnabled(comboBox.getModel().getSize() > 1 || comboBox.getModel().getSize() == 1 && !"".equals(comboBox.getModel().getElementAt(0)));
|
||||
}
|
||||
|
||||
public String find(Frame owner, Object titel, int x, int y) {
|
||||
dialog = new EscapableDialog(owner, String.valueOf(titel), true) {
|
||||
};
|
||||
dialog.getContentPane().add(this);
|
||||
dialog.pack();
|
||||
@@ -214,12 +263,12 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
if (e.getKeyChar() == KeyEvent.VK_ESCAPE) {
|
||||
dialog.setVisible(false);
|
||||
close();
|
||||
} else if (e.getKeyChar() == KeyEvent.VK_DOWN) {
|
||||
searchList.grabFocus();
|
||||
} else if (e.getKeyChar() == '\n') {
|
||||
result = searchList.getSelectedValue();
|
||||
dialog.setVisible(false);
|
||||
close();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@@ -276,9 +325,9 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
}
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() >1) {
|
||||
if (e.getClickCount() > 1) {
|
||||
result = searchList.getSelectedValue();
|
||||
dialog.setVisible(false);
|
||||
close();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -500,6 +549,7 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
okButton = new javax.swing.JButton();
|
||||
cancelButton = new javax.swing.JButton();
|
||||
plugInPanel = new javax.swing.JPanel();
|
||||
|
||||
loadingPanel.setBackground(java.awt.Color.white);
|
||||
|
||||
@@ -509,8 +559,7 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
|
||||
cancelLoadiingButton.setText("Cancel");
|
||||
cancelLoadiingButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cancelLoadiingButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
@@ -529,10 +578,8 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
|
||||
searchList.setModel(new javax.swing.AbstractListModel<String>() {
|
||||
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
|
||||
@Override
|
||||
public int getSize() { return strings.length; }
|
||||
@Override
|
||||
public String getElementAt(int i) { return strings[i]; }
|
||||
public int getSize() { return strings.length; }
|
||||
public String getElementAt(int i) { return strings[i]; }
|
||||
});
|
||||
jScrollPane1.setViewportView(searchList);
|
||||
|
||||
@@ -576,8 +623,7 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
|
||||
selectAllButton.setText("Select all");
|
||||
selectAllButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
selectAllButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
@@ -608,8 +654,7 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
|
||||
okButton.setText(" Ok ");
|
||||
okButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
okButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
@@ -622,8 +667,7 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
|
||||
cancelButton.setText("Cancel");
|
||||
cancelButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cancelButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
@@ -638,17 +682,29 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
gridBagConstraints.gridwidth = 3;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
|
||||
add(jPanel1, gridBagConstraints);
|
||||
|
||||
plugInPanel.setLayout(new java.awt.BorderLayout());
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 10;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.gridheight = 3;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
add(plugInPanel, gridBagConstraints);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
|
||||
result = searchList.getSelectedValue();
|
||||
dialog.setVisible(false);
|
||||
close();
|
||||
}//GEN-LAST:event_okButtonActionPerformed
|
||||
|
||||
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
|
||||
dialog.setVisible(false);
|
||||
close();
|
||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||
|
||||
public void close() {
|
||||
dialog.setVisible(false);
|
||||
}
|
||||
|
||||
private void cancelLoadiingButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelLoadiingButtonActionPerformed
|
||||
cancelLoading.set(true);
|
||||
}//GEN-LAST:event_cancelLoadiingButtonActionPerformed
|
||||
@@ -670,6 +726,7 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
private javax.swing.JScrollPane jScrollPane2;
|
||||
private javax.swing.JPanel loadingPanel;
|
||||
private javax.swing.JButton okButton;
|
||||
private javax.swing.JPanel plugInPanel;
|
||||
private javax.swing.JPanel schemaPanel;
|
||||
private javax.swing.JList<String> searchList;
|
||||
private javax.swing.JTextField searchTextField;
|
||||
@@ -678,12 +735,14 @@ public class StringSearchPanel extends javax.swing.JPanel {
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
static private ImageIcon icon;
|
||||
static private ImageIcon icon2;
|
||||
static {
|
||||
String dir = "/net/sf/jailer/ui/resource";
|
||||
|
||||
// load images
|
||||
try {
|
||||
icon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/search.png"));
|
||||
icon2 = new ImageIcon(MetaDataPanel.class.getResource(dir + "/search2.png"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package net.sf.jailer.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FileDialog;
|
||||
@@ -34,6 +35,8 @@ import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -49,6 +52,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -80,6 +84,7 @@ import net.sf.jailer.ui.databrowser.BrowserContentPane.TableModelItem;
|
||||
import net.sf.jailer.ui.databrowser.Row;
|
||||
import net.sf.jailer.ui.scrollmenu.JScrollC2PopupMenu;
|
||||
import net.sf.jailer.ui.scrollmenu.JScrollPopupMenu;
|
||||
import net.sf.jailer.ui.syntaxtextarea.RSyntaxTextAreaWithSQLSyntaxStyle;
|
||||
import net.sf.jailer.util.CancellationException;
|
||||
import net.sf.jailer.util.CancellationHandler;
|
||||
import net.sf.jailer.util.CycleFinder;
|
||||
@@ -947,7 +952,7 @@ public class UIUtil {
|
||||
/**
|
||||
* Pair of Icon and Text.
|
||||
*/
|
||||
public static class IconWithText {
|
||||
public static class IconWithText implements Comparable<IconWithText> {
|
||||
public final String text;
|
||||
public final ImageIcon icon;
|
||||
|
||||
@@ -960,9 +965,42 @@ public class UIUtil {
|
||||
public String toString() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(IconWithText o) {
|
||||
return text.compareTo(o.text);
|
||||
}
|
||||
}
|
||||
|
||||
public static void invokeLater(final int ticks, final Runnable runnable) {
|
||||
private static boolean isPopupActive = false;
|
||||
|
||||
public static synchronized boolean isPopupActive() {
|
||||
return isPopupActive;
|
||||
}
|
||||
|
||||
private static synchronized void setPopupActive(boolean b) {
|
||||
isPopupActive = b;
|
||||
}
|
||||
|
||||
public static void showPopup(final Component invoker, final int x, final int y, final JPopupMenu popup) {
|
||||
popup.addPropertyChangeListener("visible", new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (Boolean.FALSE.equals(evt.getNewValue())) {
|
||||
setPopupActive(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setPopupActive(true);
|
||||
popup.show(invoker, x, y);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void invokeLater(final int ticks, final Runnable runnable) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
int count = ticks;
|
||||
@Override
|
||||
@@ -975,5 +1013,40 @@ public class UIUtil {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static Map<Component, Integer> waitLevel = new WeakHashMap<Component, Integer>();
|
||||
|
||||
public static void setWaitCursor(Component component) {
|
||||
if (component != null) {
|
||||
Integer level = waitLevel.get(component);
|
||||
if (level != null) {
|
||||
waitLevel.put(component, level + 1);
|
||||
} else {
|
||||
waitLevel.put(component, 1);
|
||||
component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetWaitCursor(Component component) {
|
||||
if (component != null) {
|
||||
Integer level = waitLevel.get(component);
|
||||
if (level != null) {
|
||||
if (level == 1) {
|
||||
component.setCursor(null);
|
||||
waitLevel.remove(component);
|
||||
} else {
|
||||
waitLevel.put(component, level - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers UI initializations.
|
||||
*/
|
||||
public static void prepareUI() {
|
||||
new RSyntaxTextAreaWithSQLSyntaxStyle(false, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ import net.sf.jsqlparser.statement.Commit;
|
||||
import net.sf.jsqlparser.statement.SetStatement;
|
||||
import net.sf.jsqlparser.statement.StatementVisitor;
|
||||
import net.sf.jsqlparser.statement.Statements;
|
||||
import net.sf.jsqlparser.statement.UseStatement;
|
||||
import net.sf.jsqlparser.statement.alter.Alter;
|
||||
import net.sf.jsqlparser.statement.create.index.CreateIndex;
|
||||
import net.sf.jsqlparser.statement.create.table.CreateTable;
|
||||
@@ -70,6 +71,7 @@ import net.sf.jsqlparser.statement.select.AllTableColumns;
|
||||
import net.sf.jsqlparser.statement.select.FromItemVisitor;
|
||||
import net.sf.jsqlparser.statement.select.Join;
|
||||
import net.sf.jsqlparser.statement.select.LateralSubSelect;
|
||||
import net.sf.jsqlparser.statement.select.ParenthesisFromItem;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.Select;
|
||||
import net.sf.jsqlparser.statement.select.SelectBody;
|
||||
@@ -405,12 +407,16 @@ public class AssociationProposer {
|
||||
if (subjoin.getLeft() != null) {
|
||||
subjoin.getLeft().accept(this);
|
||||
}
|
||||
if (subjoin.getJoin() != null) {
|
||||
if (subjoin.getJoin().getRightItem() != null) {
|
||||
subjoin.getJoin().getRightItem().accept(this);
|
||||
}
|
||||
if (subjoin.getJoin().getOnExpression() != null) {
|
||||
scopes.peek().expressions.add(subjoin.getJoin().getOnExpression());
|
||||
if (subjoin.getJoinList() != null) {
|
||||
for (Join join: subjoin.getJoinList()) {
|
||||
if (join != null) {
|
||||
if (join.getRightItem() != null) {
|
||||
join.getRightItem().accept(this);
|
||||
}
|
||||
if (join.getOnExpression() != null) {
|
||||
scopes.peek().expressions.add(join.getOnExpression());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -437,6 +443,13 @@ public class AssociationProposer {
|
||||
fn += Quoting.normalizeIdentifier(tableName.getName());
|
||||
scopes.peek().aliasToTable.put(Quoting.normalizeIdentifier(alias), fn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ParenthesisFromItem aThis) {
|
||||
if (aThis.getFromItem() != null) {
|
||||
aThis.getFromItem().accept(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (plainSelect.getFromItem() != null) {
|
||||
plainSelect.getFromItem().accept(fromItemVisitor);
|
||||
@@ -508,6 +521,10 @@ public class AssociationProposer {
|
||||
public void visit(AnalyticExpression expr) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(UseStatement use) {
|
||||
}
|
||||
|
||||
private void analyseTopScope() {
|
||||
for (Expression expr: scopes.peek().expressions) {
|
||||
expr.accept(new ExpressionVisitorAdapter() {
|
||||
@@ -629,7 +646,6 @@ public class AssociationProposer {
|
||||
return dColumn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="openEditorLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value=" And "/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
@@ -34,151 +39,10 @@
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel7">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="8" gridWidth="5" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="loadButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value=" Reload "/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="loadButtonActionPerformed"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="1"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="onPanel">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[66, 17]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="6" gridWidth="4" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="16" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="on">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="jLabel3"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="joinPanel">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[66, 17]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="5" gridWidth="4" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="16" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="join">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="jLabel3"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel6">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" as B "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel10">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[66, 17]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="4" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="from">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="jLabel3"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel5">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
<Property name="text" type="java.lang.String" value=" as A"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="pendingNonpendingPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="12" gridWidth="7" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
@@ -675,180 +539,344 @@
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" Join "/>
|
||||
</Properties>
|
||||
<Container class="javax.swing.JPanel" name="menuPanel">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel4">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" On "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="6" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="andLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" Where "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="8" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="openEditorLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value=" And "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="8" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel3">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" From "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="jPanel3">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="9" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="rrPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="7" gridY="4" gridWidth="2" gridHeight="3" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="2" anchor="11" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="relatedRowsPanel">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="f0" red="e0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.SoftBevelBorderInfo">
|
||||
<BevelBorder/>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Container class="javax.swing.JPanel" name="jPanel7">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="7" gridY="4" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="0" insetsBottom="4" insetsRight="0" anchor="13" weightX="0.0" weightY="1.0"/>
|
||||
<GridBagConstraints gridX="4" gridY="8" gridWidth="5" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="relatedRowsLabel">
|
||||
<Component class="javax.swing.JButton" name="loadButton">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="f0" red="e0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" Related Rows "/>
|
||||
<Property name="opaque" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value=" Reload "/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="loadButtonActionPerformed"/>
|
||||
</Events>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="1"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="sqlPanel">
|
||||
<Container class="javax.swing.JPanel" name="onPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.SoftBevelBorderInfo">
|
||||
<BevelBorder/>
|
||||
</Border>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[66, 17]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="8" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="12" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="4" gridY="6" gridWidth="4" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="16" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="on">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="jLabel3"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="joinPanel">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[66, 17]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="5" gridWidth="4" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="16" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="join">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="jLabel3"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel6">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" as B "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel10">
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[66, 17]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="4" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="from">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="0"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="jLabel3"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel5">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="horizontalAlignment" type="int" value="2"/>
|
||||
<Property name="text" type="java.lang.String" value=" as A"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" Join "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel4">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" On "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="6" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="andLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" Where "/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="8" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel3">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" From "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="jPanel3">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="9" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="rrPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="7" gridY="4" gridWidth="2" gridHeight="3" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="2" anchor="11" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="sqlLabel1">
|
||||
<Container class="javax.swing.JPanel" name="relatedRowsPanel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value=" Menu "/>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="f0" red="e0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.SoftBevelBorderInfo">
|
||||
<BevelBorder/>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="7" gridY="4" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="0" insetsBottom="4" insetsRight="0" anchor="13" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="relatedRowsLabel">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="f0" red="e0" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value=" Related Rows "/>
|
||||
<Property name="opaque" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="sqlPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.SoftBevelBorderInfo">
|
||||
<BevelBorder/>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="8" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="12" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="sqlLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value=" Menu "/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel9">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="5" gridY="5" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="dropA">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="drop"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="dropB">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="drop"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="openEditorButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="jButton1"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="8" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel9">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="5" gridY="5" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="dropA">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="drop"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="4" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="dropB">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||
<Font name="DejaVu Sans" size="13" style="1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="drop"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="5" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.awt.BasicStroke;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Frame;
|
||||
@@ -529,7 +528,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
* {@link Association} with parent row
|
||||
*/
|
||||
public BrowserContentPane(final DataModel dataModel, final Table table, String condition, Session session, Row parentRow, List<Row> parentRows,
|
||||
final Association association, Frame parentFrame, RowsClosure rowsClosure,
|
||||
final Association association, final Frame parentFrame, RowsClosure rowsClosure,
|
||||
Boolean selectDistinct, boolean reload, ExecutionContext executionContext) {
|
||||
this.table = table;
|
||||
this.session = session;
|
||||
@@ -766,11 +765,8 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
registerAccelerator(KS_DETAILS, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Point loc = SwingUtilities.convertPoint(
|
||||
BrowserContentPane.this,
|
||||
0, 0,
|
||||
SwingUtilities.getWindowAncestor(BrowserContentPane.this)
|
||||
);
|
||||
Point loc = new Point(18, 16);
|
||||
SwingUtilities.convertPointToScreen(loc, rowsTable);
|
||||
openDetails(loc.x, loc.y);
|
||||
}
|
||||
});
|
||||
@@ -829,7 +825,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
|
||||
Component render = defaultTableCellRenderer.getTableCellRendererComponent(rowsTable, value, isSelected, false, row, column);
|
||||
final RowSorter<?> rowSorter = rowsTable.getRowSorter();
|
||||
if (rowSorter.getViewRowCount() == 0) {
|
||||
if (rowSorter.getViewRowCount() == 0 && table == rowsTable) {
|
||||
return render;
|
||||
}
|
||||
|
||||
@@ -965,7 +961,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
JPopupMenu popup;
|
||||
popup = createPopupMenu(row, i, p.x + getOwner().getX(), p.y + getOwner().getY(), rows.size() == 1);
|
||||
if (popup != null) {
|
||||
showPopup(source, x, y, popup);
|
||||
UIUtil.showPopup(source, x, y, popup);
|
||||
popup.addPropertyChangeListener("visible", new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
@@ -1005,20 +1001,21 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
rowsTableScrollPane.addMouseListener(rowTableListener);
|
||||
singleRowViewScrollContentPanel.addMouseListener(rowTableListener);
|
||||
|
||||
andConditionEditor = new ConditionEditor(parentFrame, null, dataModel);
|
||||
openEditorLabel.setIcon(conditionEditorIcon);
|
||||
openEditorLabel.setText(null);
|
||||
openEditorLabel.addMouseListener(new java.awt.event.MouseAdapter() {
|
||||
openEditorButton.setIcon(UIUtil.scaleIcon(this, conditionEditorIcon));
|
||||
openEditorButton.setText(null);
|
||||
openEditorButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
mouseClicked(e);
|
||||
}
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final Point pos = new Point(openEditorButton.getX(), openEditorButton.getY() + openEditorButton.getHeight());
|
||||
SwingUtilities.convertPointToScreen(pos, openEditorButton.getParent());
|
||||
loadButton.grabFocus();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (andConditionEditor == null) {
|
||||
andConditionEditor = new ConditionEditor(parentFrame, null, dataModel);
|
||||
}
|
||||
andConditionEditor.setLocationAndFit(pos);
|
||||
String cond = andConditionEditor.edit(getAndConditionText(), "Table", "A", table, null, null, null, false, true);
|
||||
if (cond != null) {
|
||||
if (!getAndConditionText().equals(ConditionEditor.toSingleLine(cond))) {
|
||||
@@ -1031,16 +1028,6 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(java.awt.event.MouseEvent evt) {
|
||||
openEditorLabel.setIcon(conditionEditorSelectedIcon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(java.awt.event.MouseEvent evt) {
|
||||
openEditorLabel.setIcon(conditionEditorIcon);
|
||||
}
|
||||
});
|
||||
relatedRowsLabel.setIcon(UIUtil.scaleIcon(this, relatedRowsIcon));
|
||||
relatedRowsLabel.setFont(relatedRowsLabel.getFont().deriveFont(relatedRowsLabel.getFont().getSize() * 1.1f));
|
||||
@@ -1057,11 +1044,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// if (rows.size() == 1) {
|
||||
// popup = createPopupMenu(rows.get(0), 0, 0, 0);
|
||||
// } else {
|
||||
popup = createPopupMenu(null, -1, 0, 0, false);
|
||||
// }
|
||||
popup = createPopupMenu(null, -1, 0, 0, false);
|
||||
setCurrentRowSelectionAndReloadChildrenIfLimitIsExceeded(-2);
|
||||
popup.addPropertyChangeListener("visible", new PropertyChangeListener() {
|
||||
@Override
|
||||
@@ -1073,7 +1056,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
});
|
||||
showPopup(relatedRowsPanel, 0, relatedRowsPanel.getHeight(), popup);
|
||||
UIUtil.showPopup(relatedRowsPanel, 0, relatedRowsPanel.getHeight(), popup);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1107,7 +1090,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
@Override
|
||||
public void run() {
|
||||
Point loc = sqlPanel.getLocationOnScreen();
|
||||
popup = createSqlPopupMenu(BrowserContentPane.this.parentRow, 0, (int) loc.getX(), (int) loc.getY(), false);
|
||||
popup = createSqlPopupMenu(BrowserContentPane.this.parentRow, 0, (int) loc.getX(), (int) loc.getY(), false, BrowserContentPane.this);
|
||||
setCurrentRowSelectionAndReloadChildrenIfLimitIsExceeded(-2);
|
||||
popup.addPropertyChangeListener("visible", new PropertyChangeListener() {
|
||||
@Override
|
||||
@@ -1119,7 +1102,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
});
|
||||
showPopup(sqlPanel, 0, sqlPanel.getHeight(), popup);
|
||||
UIUtil.showPopup(sqlPanel, 0, sqlPanel.getHeight(), popup);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1264,9 +1247,10 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
if (parent == null) {
|
||||
parent = BrowserContentPane.this;
|
||||
}
|
||||
parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(parent);
|
||||
try {
|
||||
Desktop.noArrangeLayoutOnNewTableBrowser = true;
|
||||
Desktop.noArrangeLayoutOnNewTableBrowserWithAnchor = todoList.size() > 1;
|
||||
Desktop.resetLastArrangeLayoutOnNewTableBrowser();
|
||||
for (int i = 0; i < todoList.size(); ++i) {
|
||||
if (i == todoList.size() - 1) {
|
||||
@@ -1276,7 +1260,8 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
}
|
||||
} finally {
|
||||
Desktop.noArrangeLayoutOnNewTableBrowser = false;
|
||||
parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
Desktop.noArrangeLayoutOnNewTableBrowserWithAnchor = false;
|
||||
UIUtil.resetWaitCursor(parent);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1325,8 +1310,21 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
* @param runnable
|
||||
*/
|
||||
public JPopupMenu createPopupMenu(final Row row, final int rowIndex, final int x, final int y, boolean navigateFromAllRows, JMenuItem altCopyTCB, final Runnable repaint) {
|
||||
return createPopupMenu(row, rowIndex, x, y, navigateFromAllRows, altCopyTCB, repaint, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates popup menu for navigation.
|
||||
* @param navigateFromAllRows
|
||||
* @param runnable
|
||||
*/
|
||||
public JPopupMenu createPopupMenu(final Row row, final int rowIndex, final int x, final int y, boolean navigateFromAllRows, JMenuItem altCopyTCB, final Runnable repaint, final boolean withKeyStroke) {
|
||||
JMenuItem tableFilter = new JCheckBoxMenuItem("Table Filter");
|
||||
tableFilter.setAccelerator(KS_FILTER);
|
||||
if (withKeyStroke) {
|
||||
tableFilter.setAccelerator(KS_FILTER);
|
||||
} else {
|
||||
tableFilter.setVisible(false);
|
||||
}
|
||||
tableFilter.setSelected(isTableFilterEnabled);
|
||||
if (isLimitExceeded) {
|
||||
tableFilter.setForeground(Color.red);
|
||||
@@ -1344,7 +1342,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
copyTCB = altCopyTCB;
|
||||
} else {
|
||||
copyTCB = new JMenuItem("Copy to Clipboard");
|
||||
copyTCB.setAccelerator(KS_COPY_TO_CLIPBOARD);
|
||||
if (withKeyStroke) {
|
||||
copyTCB.setAccelerator(KS_COPY_TO_CLIPBOARD);
|
||||
}
|
||||
copyTCB.setEnabled(rowsTable.getSelectedColumnCount() > 0);
|
||||
copyTCB.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@@ -1358,7 +1358,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
JPopupMenu jPopupMenu = new JPopupMenu();
|
||||
if (row != null) {
|
||||
JMenuItem det = new JMenuItem("Details");
|
||||
det.setAccelerator(KS_DETAILS);
|
||||
if (withKeyStroke) {
|
||||
det.setAccelerator(KS_DETAILS);
|
||||
}
|
||||
jPopupMenu.add(det);
|
||||
jPopupMenu.add(new JSeparator());
|
||||
det.addActionListener(new ActionListener() {
|
||||
@@ -1376,7 +1378,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
jPopupMenu.addSeparator();
|
||||
jPopupMenu.add(tableFilter);
|
||||
JMenuItem editMode = new JMenuItem("Edit Mode");
|
||||
editMode.setAccelerator(KS_EDIT);
|
||||
if (withKeyStroke) {
|
||||
editMode.setAccelerator(KS_EDIT);
|
||||
}
|
||||
jPopupMenu.add(editMode);
|
||||
editMode.setEnabled(false);
|
||||
return jPopupMenu;
|
||||
@@ -1456,7 +1460,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
|
||||
if (row != null) {
|
||||
JMenuItem det = new JMenuItem("Details");
|
||||
det.setAccelerator(KS_DETAILS);
|
||||
if (withKeyStroke) {
|
||||
det.setAccelerator(KS_DETAILS);
|
||||
}
|
||||
popup.insert(det, 0);
|
||||
popup.insert(new JSeparator(), 1);
|
||||
det.addActionListener(new ActionListener() {
|
||||
@@ -1477,9 +1483,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
qb.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
List<String> whereClauses = new ArrayList<String>();
|
||||
whereClauses.add(SqlUtil.replaceAliases(row.rowId, "A", "A"));
|
||||
getQueryBuilderDialog().buildQuery(table, true, false, new ArrayList<Association>(), whereClauses, dataModel, session, getMetaDataSource(), false);
|
||||
openQueryBuilder(false, SqlUtil.replaceAliases(row.rowId, "A", "A"));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1489,9 +1493,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
sqlConsole.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
List<String> whereClauses = new ArrayList<String>();
|
||||
whereClauses.add(SqlUtil.replaceAliases(row.rowId, "A", "A"));
|
||||
getQueryBuilderDialog().buildQuery(table, true, false, new ArrayList<Association>(), whereClauses, dataModel, session, getMetaDataSource(), true);
|
||||
openQueryBuilder(true, SqlUtil.replaceAliases(row.rowId, "A", "A"));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1605,7 +1607,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
popup.addSeparator();
|
||||
popup.add(tableFilter);
|
||||
JCheckBoxMenuItem editMode = new JCheckBoxMenuItem("Edit Mode");
|
||||
editMode.setAccelerator(KS_EDIT);
|
||||
if (withKeyStroke) {
|
||||
editMode.setAccelerator(KS_EDIT);
|
||||
}
|
||||
editMode.setSelected(isEditMode);
|
||||
editMode.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@@ -1626,8 +1630,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
/**
|
||||
* Creates popup menu for SQL.
|
||||
* @param forNavTree
|
||||
* @param browserContentPane
|
||||
*/
|
||||
public JPopupMenu createSqlPopupMenu(final Row parentrow, final int rowIndex, final int x, final int y, boolean forNavTree) {
|
||||
public JPopupMenu createSqlPopupMenu(final Row parentrow, final int rowIndex, final int x, final int y, boolean forNavTree, final Component parentComponent) {
|
||||
JPopupMenu popup = new JPopupMenu();
|
||||
|
||||
JMenuItem qb = new JMenuItem("Query Builder");
|
||||
@@ -1734,7 +1739,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
});
|
||||
|
||||
popup.addSeparator();
|
||||
JMenuItem m = new JMenuItem("Hide from View");
|
||||
JMenuItem m = new JMenuItem("Hide (Minimize)");
|
||||
popup.add(m);
|
||||
m.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@@ -1742,27 +1747,12 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
onHide();
|
||||
}
|
||||
});
|
||||
m = new JMenuItem("Close" + (getChildBrowsers().isEmpty()? "" : " Subtree"));
|
||||
m = new JMenuItem("Close");
|
||||
popup.add(m);
|
||||
m.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Component parent = SwingUtilities.getWindowAncestor(BrowserContentPane.this);
|
||||
if (parent == null) {
|
||||
parent = BrowserContentPane.this;
|
||||
}
|
||||
parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
try {
|
||||
closeSubTree(BrowserContentPane.this);
|
||||
} finally {
|
||||
parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
private void closeSubTree(BrowserContentPane cp) {
|
||||
for (RowBrowser c: cp.getChildBrowsers()) {
|
||||
closeSubTree(c.browserContentPane);
|
||||
}
|
||||
cp.close();
|
||||
closeWithChildren(parentComponent);
|
||||
}
|
||||
});
|
||||
popup.add(new JSeparator());
|
||||
@@ -1795,6 +1785,65 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
return popup;
|
||||
}
|
||||
|
||||
public boolean closeWithChildren(Component parentComponent) {
|
||||
int count = countSubNodes(this);
|
||||
Component parent = SwingUtilities.getWindowAncestor(this);
|
||||
if (parent == null) {
|
||||
parent = BrowserContentPane.this;
|
||||
}
|
||||
boolean closeThisToo = true;
|
||||
if (count > 1) {
|
||||
int o = JOptionPane.showOptionDialog(parentComponent, "Which tables do you want to close?", "Close",
|
||||
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
|
||||
new Object[] {
|
||||
"Only this table",
|
||||
"This and related tables (" + (count) + ")",
|
||||
"Related tables (" + (count - 1) + ")"
|
||||
},
|
||||
null);
|
||||
if (o == 0) {
|
||||
UIUtil.setWaitCursor(parent);
|
||||
try {
|
||||
close();
|
||||
} finally {
|
||||
UIUtil.resetWaitCursor(parent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (o == 1) {
|
||||
closeThisToo = true;
|
||||
} else if (o == 2) {
|
||||
closeThisToo = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
UIUtil.setWaitCursor(parent);
|
||||
try {
|
||||
closeSubTree(BrowserContentPane.this, closeThisToo);
|
||||
} finally {
|
||||
UIUtil.resetWaitCursor(parent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private int countSubNodes(BrowserContentPane cp) {
|
||||
int count = 0;
|
||||
for (RowBrowser c: cp.getChildBrowsers()) {
|
||||
count += countSubNodes(c.browserContentPane);
|
||||
}
|
||||
return count + 1;
|
||||
}
|
||||
|
||||
private void closeSubTree(BrowserContentPane cp, boolean closeThisToo) {
|
||||
for (RowBrowser c: cp.getChildBrowsers()) {
|
||||
closeSubTree(c.browserContentPane, true);
|
||||
}
|
||||
if (closeThisToo) {
|
||||
cp.close();
|
||||
}
|
||||
}
|
||||
|
||||
private JMenu createInsertChildMenu(Row row, final int x, final int y) {
|
||||
JScrollMenu insertNewRow = new JScrollMenu("Insert Child");
|
||||
if (table == null || table.getName() == null) {
|
||||
@@ -1863,7 +1912,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
if (parent == null) {
|
||||
parent = this;
|
||||
}
|
||||
parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(parent);
|
||||
try {
|
||||
String file;
|
||||
String ts = new SimpleDateFormat("HH-mm-ss-SSS").format(new Date());
|
||||
@@ -2037,10 +2086,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
}
|
||||
newFile.delete();
|
||||
} catch (Throwable e) {
|
||||
parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.showException(this, "Error", e, session);
|
||||
} finally {
|
||||
parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2252,7 +2300,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
private void openSQLDialog(String titel, int x, int y, Object sql) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
JDialog d;
|
||||
try {
|
||||
String LF = System.getProperty("line.separator", "\n");
|
||||
@@ -2299,7 +2347,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
UIUtil.showException(this, "Error", e);
|
||||
return;
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
d.setVisible(true);
|
||||
}
|
||||
@@ -2394,6 +2442,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
++l;
|
||||
|
||||
final JMenuItem item = new JMenuItem(" " + (name.substring(1)) + " ");
|
||||
item.setToolTipText(association.getUnrestrictedJoinCondition());
|
||||
final JLabel countLabel = new JLabel(". >99999 ") {
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
@@ -2473,7 +2522,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String cs = " " + (count.count < 0? "?" : (count.count > MAX_RC)? (">" + MAX_RC) : count.isExact? count.count : (">=" + count.count)) + " ";
|
||||
String cs = " " + (count.count < 0? "?" : (count.count > MAX_RC)? (">" + MAX_RC) : count.isExact? count.count : (">" + count.count)) + " ";
|
||||
countLabel.setText(cs);
|
||||
if (count.count == 0) {
|
||||
countLabel.setForeground(Color.lightGray);
|
||||
@@ -2587,7 +2636,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
String defaultSchema = JDBCMetaDataBasedModelElementFinder.getDefaultSchema(session, session.getSchema());
|
||||
String schema = quoting.unquote(table.getOriginalSchema(defaultSchema));
|
||||
String tableName = quoting.unquote(table.getUnqualifiedName());
|
||||
ResultSet resultSet = JDBCMetaDataBasedModelElementFinder.getColumns(session, metaData, schema, tableName, "%", false);
|
||||
ResultSet resultSet = JDBCMetaDataBasedModelElementFinder.getColumns(session, metaData, schema, tableName, "%", false, null);
|
||||
while (resultSet.next()) {
|
||||
String colName = resultSet.getString(4).toLowerCase();
|
||||
columns.add(colName);
|
||||
@@ -2601,7 +2650,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
schema = schema.toLowerCase();
|
||||
tableName = tableName.toLowerCase();
|
||||
}
|
||||
resultSet = JDBCMetaDataBasedModelElementFinder.getColumns(session, metaData, schema, tableName, "%", false);
|
||||
resultSet = JDBCMetaDataBasedModelElementFinder.getColumns(session, metaData, schema, tableName, "%", false, null);
|
||||
while (resultSet.next()) {
|
||||
String colName = resultSet.getString(4).toLowerCase();
|
||||
columns.add(colName);
|
||||
@@ -2991,14 +3040,10 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
f = false;
|
||||
}
|
||||
f = true;
|
||||
String orderBy = "";
|
||||
String olapOrderBy = "";
|
||||
if (selectParentPK) {
|
||||
int j = 0;
|
||||
for (Column pk: rowIdSupport.getPrimaryKey(association.source, session).getColumns()) {
|
||||
parentPkColumnNames.add(quoting.requote(pk.name));
|
||||
orderBy += (f ? "" : ", ") + "B." + quoting.requote(pk.name);
|
||||
olapOrderBy += (f ? "" : ", ") + "S.B" + j;
|
||||
++j;
|
||||
f = false;
|
||||
}
|
||||
@@ -3006,8 +3051,6 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
int j = 0;
|
||||
for (Column pk: rowIdSupport.getPrimaryKey(table, session).getColumns()) {
|
||||
pkColumnNames.add(quoting.requote(pk.name));
|
||||
orderBy += (f ? "" : ", ") + "A." + quoting.requote(pk.name);
|
||||
olapOrderBy += (f ? "" : ", ") + "S.A" + j;
|
||||
++j;
|
||||
f = false;
|
||||
}
|
||||
@@ -3086,14 +3129,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
if (andCond.trim().length() > 0) {
|
||||
sql += (whereExists ? " and" : " Where") + " (" + ConditionEditor.toMultiLine(andCond) + ")";
|
||||
}
|
||||
if (orderBy.length() > 0) {
|
||||
if (sqlLimitSuffix != null && !useOLAPLimitation) {
|
||||
sql += " order by " + orderBy;
|
||||
}
|
||||
}
|
||||
olapPrefix += " From (";
|
||||
if (useOLAPLimitation) {
|
||||
sql = olapPrefix + sql + olapSuffix + " Order by " + olapOrderBy;
|
||||
sql = olapPrefix + sql + olapSuffix;
|
||||
}
|
||||
if (sqlLimitSuffix != null && !limitSuffixInSelectClause) {
|
||||
sql += " " + (sqlLimitSuffix.replace("%s", Integer.toString(limit)));
|
||||
@@ -3552,6 +3590,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
@Override
|
||||
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
|
||||
if (table != rowsTable) {
|
||||
column = table.convertColumnIndexToModel(column);
|
||||
if (column == 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -3924,6 +3963,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
if (table == null || table instanceof SqlStatementTable || getQueryBuilderDialog() == null /* SQL Console */) {
|
||||
return -1;
|
||||
}
|
||||
if (association != null && association.isInsertDestinationBeforeSource()) {
|
||||
return table.getColumns().size() - 1;
|
||||
}
|
||||
if (table.primaryKey.getColumns() != null && table.primaryKey.getColumns().size() > 0) {
|
||||
Column pk = table.primaryKey.getColumns().get(0);
|
||||
for (int i = 0; i < table.getColumns().size(); ++i) {
|
||||
@@ -4025,16 +4067,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
java.awt.GridBagConstraints gridBagConstraints;
|
||||
|
||||
andCondition = new javax.swing.JComboBox();
|
||||
jPanel7 = new javax.swing.JPanel();
|
||||
loadButton = new javax.swing.JButton();
|
||||
onPanel = new javax.swing.JPanel();
|
||||
on = new javax.swing.JLabel();
|
||||
joinPanel = new javax.swing.JPanel();
|
||||
join = new javax.swing.JLabel();
|
||||
jLabel6 = new javax.swing.JLabel();
|
||||
jPanel10 = new javax.swing.JPanel();
|
||||
from = new javax.swing.JLabel();
|
||||
jLabel5 = new javax.swing.JLabel();
|
||||
openEditorLabel = new javax.swing.JLabel();
|
||||
pendingNonpendingPanel = new javax.swing.JPanel();
|
||||
cardPanel = new javax.swing.JPanel();
|
||||
tablePanel = new javax.swing.JPanel();
|
||||
@@ -4072,10 +4105,20 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
jLabel8 = new javax.swing.JLabel();
|
||||
jPanel8 = new javax.swing.JPanel();
|
||||
jLabel11 = new javax.swing.JLabel();
|
||||
menuPanel = new javax.swing.JPanel();
|
||||
jPanel7 = new javax.swing.JPanel();
|
||||
loadButton = new javax.swing.JButton();
|
||||
onPanel = new javax.swing.JPanel();
|
||||
on = new javax.swing.JLabel();
|
||||
joinPanel = new javax.swing.JPanel();
|
||||
join = new javax.swing.JLabel();
|
||||
jLabel6 = new javax.swing.JLabel();
|
||||
jPanel10 = new javax.swing.JPanel();
|
||||
from = new javax.swing.JLabel();
|
||||
jLabel5 = new javax.swing.JLabel();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
jLabel4 = new javax.swing.JLabel();
|
||||
andLabel = new javax.swing.JLabel();
|
||||
openEditorLabel = new javax.swing.JLabel();
|
||||
jLabel3 = new javax.swing.JLabel();
|
||||
jPanel3 = new javax.swing.JPanel();
|
||||
rrPanel = new javax.swing.JPanel();
|
||||
@@ -4086,103 +4129,15 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
jPanel9 = new javax.swing.JPanel();
|
||||
dropA = new javax.swing.JLabel();
|
||||
dropB = new javax.swing.JLabel();
|
||||
openEditorButton = new javax.swing.JButton();
|
||||
|
||||
andCondition.setEditable(true);
|
||||
andCondition.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
|
||||
|
||||
openEditorLabel.setText(" And ");
|
||||
|
||||
setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
jPanel7.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
loadButton.setText(" Reload ");
|
||||
loadButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
loadButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 1;
|
||||
jPanel7.add(loadButton, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 8;
|
||||
gridBagConstraints.gridwidth = 5;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
add(jPanel7, gridBagConstraints);
|
||||
|
||||
onPanel.setMinimumSize(new java.awt.Dimension(66, 17));
|
||||
onPanel.setLayout(new java.awt.BorderLayout());
|
||||
|
||||
on.setFont(new java.awt.Font("DejaVu Sans", 0, 13)); // NOI18N
|
||||
on.setText("jLabel3");
|
||||
onPanel.add(on, java.awt.BorderLayout.CENTER);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
add(onPanel, gridBagConstraints);
|
||||
|
||||
joinPanel.setMinimumSize(new java.awt.Dimension(66, 17));
|
||||
joinPanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
join.setFont(new java.awt.Font("DejaVu Sans", 0, 13)); // NOI18N
|
||||
join.setText("jLabel3");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
joinPanel.add(join, gridBagConstraints);
|
||||
|
||||
jLabel6.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
jLabel6.setText(" as B ");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
joinPanel.add(jLabel6, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
add(joinPanel, gridBagConstraints);
|
||||
|
||||
jPanel10.setMinimumSize(new java.awt.Dimension(66, 17));
|
||||
jPanel10.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
from.setFont(new java.awt.Font("DejaVu Sans", 0, 13)); // NOI18N
|
||||
from.setText("jLabel3");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
jPanel10.add(from, gridBagConstraints);
|
||||
|
||||
jLabel5.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
jLabel5.setText(" as A");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
jPanel10.add(jLabel5, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
add(jPanel10, gridBagConstraints);
|
||||
|
||||
pendingNonpendingPanel.setLayout(new java.awt.CardLayout());
|
||||
|
||||
cardPanel.setLayout(new java.awt.CardLayout());
|
||||
@@ -4530,21 +4485,113 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
pendingNonpendingPanel.add(jPanel8, "pending");
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 12;
|
||||
gridBagConstraints.gridwidth = 7;
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
add(pendingNonpendingPanel, gridBagConstraints);
|
||||
|
||||
menuPanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
jPanel7.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
loadButton.setText(" Reload ");
|
||||
loadButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
loadButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 1;
|
||||
jPanel7.add(loadButton, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 8;
|
||||
gridBagConstraints.gridwidth = 5;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
menuPanel.add(jPanel7, gridBagConstraints);
|
||||
|
||||
onPanel.setMinimumSize(new java.awt.Dimension(66, 17));
|
||||
onPanel.setLayout(new java.awt.BorderLayout());
|
||||
|
||||
on.setFont(new java.awt.Font("DejaVu Sans", 0, 13)); // NOI18N
|
||||
on.setText("jLabel3");
|
||||
onPanel.add(on, java.awt.BorderLayout.CENTER);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
menuPanel.add(onPanel, gridBagConstraints);
|
||||
|
||||
joinPanel.setMinimumSize(new java.awt.Dimension(66, 17));
|
||||
joinPanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
join.setFont(new java.awt.Font("DejaVu Sans", 0, 13)); // NOI18N
|
||||
join.setText("jLabel3");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
joinPanel.add(join, gridBagConstraints);
|
||||
|
||||
jLabel6.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
jLabel6.setText(" as B ");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
joinPanel.add(jLabel6, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.gridwidth = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
menuPanel.add(joinPanel, gridBagConstraints);
|
||||
|
||||
jPanel10.setMinimumSize(new java.awt.Dimension(66, 17));
|
||||
jPanel10.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
from.setFont(new java.awt.Font("DejaVu Sans", 0, 13)); // NOI18N
|
||||
from.setText("jLabel3");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
jPanel10.add(from, gridBagConstraints);
|
||||
|
||||
jLabel5.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
|
||||
jLabel5.setText(" as A");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
jPanel10.add(jLabel5, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
menuPanel.add(jPanel10, gridBagConstraints);
|
||||
|
||||
jLabel1.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
jLabel1.setText(" Join ");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
add(jLabel1, gridBagConstraints);
|
||||
menuPanel.add(jLabel1, gridBagConstraints);
|
||||
|
||||
jLabel4.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
jLabel4.setText(" On ");
|
||||
@@ -4553,7 +4600,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
add(jLabel4, gridBagConstraints);
|
||||
menuPanel.add(jLabel4, gridBagConstraints);
|
||||
|
||||
andLabel.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
andLabel.setText(" Where ");
|
||||
@@ -4561,14 +4608,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 8;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
add(andLabel, gridBagConstraints);
|
||||
|
||||
openEditorLabel.setText(" And ");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 3;
|
||||
gridBagConstraints.gridy = 8;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
add(openEditorLabel, gridBagConstraints);
|
||||
menuPanel.add(andLabel, gridBagConstraints);
|
||||
|
||||
jLabel3.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
jLabel3.setText(" From ");
|
||||
@@ -4576,7 +4616,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 4;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
add(jLabel3, gridBagConstraints);
|
||||
menuPanel.add(jLabel3, gridBagConstraints);
|
||||
|
||||
jPanel3.setLayout(new javax.swing.BoxLayout(jPanel3, javax.swing.BoxLayout.LINE_AXIS));
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
@@ -4584,7 +4624,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
gridBagConstraints.gridy = 9;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
add(jPanel3, gridBagConstraints);
|
||||
menuPanel.add(jPanel3, gridBagConstraints);
|
||||
|
||||
rrPanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
@@ -4632,7 +4672,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
gridBagConstraints.gridheight = 3;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 2);
|
||||
add(rrPanel, gridBagConstraints);
|
||||
menuPanel.add(rrPanel, gridBagConstraints);
|
||||
|
||||
jPanel9.setLayout(new java.awt.GridBagLayout());
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
@@ -4641,21 +4681,33 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 0);
|
||||
add(jPanel9, gridBagConstraints);
|
||||
menuPanel.add(jPanel9, gridBagConstraints);
|
||||
|
||||
dropA.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
dropA.setText("drop");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 3;
|
||||
gridBagConstraints.gridy = 4;
|
||||
add(dropA, gridBagConstraints);
|
||||
menuPanel.add(dropA, gridBagConstraints);
|
||||
|
||||
dropB.setFont(new java.awt.Font("DejaVu Sans", 1, 13)); // NOI18N
|
||||
dropB.setText("drop");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 3;
|
||||
gridBagConstraints.gridy = 5;
|
||||
add(dropB, gridBagConstraints);
|
||||
menuPanel.add(dropB, gridBagConstraints);
|
||||
|
||||
openEditorButton.setText("jButton1");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 3;
|
||||
gridBagConstraints.gridy = 8;
|
||||
menuPanel.add(openEditorButton, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
add(menuPanel, gridBagConstraints);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void cancelLoadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelLoadButtonActionPerformed
|
||||
@@ -4691,9 +4743,16 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
}
|
||||
}// GEN-LAST:event_limitBoxItemStateChanged
|
||||
|
||||
private void openQueryBuilder(boolean openSQLConsole) {
|
||||
void openQueryBuilder(boolean openSQLConsole) {
|
||||
openQueryBuilder(openSQLConsole, null);
|
||||
}
|
||||
|
||||
void openQueryBuilder(boolean openSQLConsole, String alternativeWhere) {
|
||||
QueryBuilderDialog.Relationship root = createQBRelations(true);
|
||||
if (root != null) {
|
||||
if (alternativeWhere != null) {
|
||||
root.whereClause = alternativeWhere;
|
||||
}
|
||||
root.selectColumns = true;
|
||||
getQueryBuilderDialog().buildQuery(table, root, dataModel, session, getMetaDataSource(), openSQLConsole);
|
||||
}
|
||||
@@ -4701,7 +4760,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
javax.swing.JComboBox andCondition;
|
||||
private javax.swing.JLabel andLabel;
|
||||
javax.swing.JLabel andLabel;
|
||||
private javax.swing.JButton cancelLoadButton;
|
||||
private javax.swing.JPanel cardPanel;
|
||||
private javax.swing.JButton deselectButton;
|
||||
@@ -4740,13 +4799,15 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
private javax.swing.JLabel loadingCauseLabel;
|
||||
private javax.swing.JLabel loadingLabel;
|
||||
private javax.swing.JPanel loadingPanel;
|
||||
javax.swing.JPanel menuPanel;
|
||||
private javax.swing.JPanel noRowsFoundPanel;
|
||||
private javax.swing.JLabel on;
|
||||
private javax.swing.JPanel onPanel;
|
||||
private javax.swing.JButton openEditorButton;
|
||||
private javax.swing.JLabel openEditorLabel;
|
||||
private javax.swing.JPanel pendingNonpendingPanel;
|
||||
private javax.swing.JLabel relatedRowsLabel;
|
||||
private javax.swing.JPanel relatedRowsPanel;
|
||||
javax.swing.JPanel relatedRowsPanel;
|
||||
private javax.swing.JButton removeConditionButton;
|
||||
public javax.swing.JLabel rowsCount;
|
||||
public javax.swing.JTable rowsTable;
|
||||
@@ -4760,12 +4821,13 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
private javax.swing.JPanel singleRowViewScrollPaneContainer;
|
||||
public javax.swing.JCheckBox sortColumnsCheckBox;
|
||||
private javax.swing.JLabel sqlLabel1;
|
||||
private javax.swing.JPanel sqlPanel;
|
||||
javax.swing.JPanel sqlPanel;
|
||||
private javax.swing.JPanel tablePanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
JPanel thumbnail;
|
||||
private ConditionEditor andConditionEditor;
|
||||
private Icon conditionEditorIcon;
|
||||
private ImageIcon conditionEditorIcon;
|
||||
private Icon conditionEditorSelectedIcon;
|
||||
{
|
||||
String dir = "/net/sf/jailer/ui/resource";
|
||||
@@ -4878,7 +4940,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
popup.add(m);
|
||||
}
|
||||
UIUtil.fit(popup);
|
||||
showPopup(label, 0, label.getHeight(), popup);
|
||||
UIUtil.showPopup(label, 0, label.getHeight(), popup);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4924,7 +4986,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract void navigateTo(Association association, int rowIndex, Row row);
|
||||
protected abstract RowBrowser navigateTo(Association association, int rowIndex, Row row);
|
||||
|
||||
protected abstract void onContentChange(List<Row> rows, boolean reloadChildren);
|
||||
|
||||
@@ -5232,7 +5294,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
private Map<Table, int[]> pkColumnIndexes = new HashMap<Table, int[]>();
|
||||
|
||||
private String[] alternativeColumnLabels;
|
||||
|
||||
|
||||
public void setAlternativeColumnLabels(String[] columnLabels) {
|
||||
this.alternativeColumnLabels = columnLabels;
|
||||
}
|
||||
@@ -5281,7 +5343,7 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String readCharacterStream(final Reader reader)
|
||||
throws IOException {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
@@ -5321,15 +5383,6 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private void showPopup(final Component invoker, final int x, final int y, final JPopupMenu popup) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
popup.show(invoker, x, y);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static String readClob(Clob clob) throws SQLException, IOException {
|
||||
return readCharacterStream(clob.getCharacterStream());
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="20" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="13" weightX="1.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="7" gridY="20" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="13" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@@ -140,7 +140,7 @@
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="20" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
<GridBagConstraints gridX="8" gridY="20" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
@@ -237,6 +237,39 @@
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="findPathComboBox">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="4">
|
||||
<StringItem index="0" value="Item 1"/>
|
||||
<StringItem index="1" value="Item 2"/>
|
||||
<StringItem index="2" value="Item 3"/>
|
||||
<StringItem index="3" value="Item 4"/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findPathComboBoxActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="20" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="findPathButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Find Path to..."/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="findPathButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="5" gridY="20" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="4" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
|
||||
@@ -53,7 +53,7 @@ import java.util.Vector;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
@@ -70,9 +70,15 @@ import net.sf.jailer.datamodel.Association;
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.ui.AutoCompletion;
|
||||
import net.sf.jailer.ui.ClosureView;
|
||||
import net.sf.jailer.ui.JComboBox;
|
||||
import net.sf.jailer.ui.StringSearchPanel;
|
||||
import net.sf.jailer.ui.UIUtil;
|
||||
import net.sf.jailer.ui.StringSearchPanel.AdditionalComponentFactory;
|
||||
import net.sf.jailer.ui.databrowser.Desktop.RowBrowser;
|
||||
import net.sf.jailer.ui.pathfinder.HistoryPanel;
|
||||
import net.sf.jailer.ui.pathfinder.PathFinder;
|
||||
import net.sf.jailer.ui.pathfinder.PathFinder.Result;
|
||||
import net.sf.jailer.util.Pair;
|
||||
|
||||
/**
|
||||
@@ -97,7 +103,282 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
*/
|
||||
private final List<Color> bgColor = new ArrayList<Color>();
|
||||
|
||||
/**
|
||||
private final class TableMouseListener implements MouseListener {
|
||||
private Map<Integer, String> manuallySelected = new TreeMap<Integer, String>();
|
||||
|
||||
public void openPathFinder(final Table table, boolean fromHistory) {
|
||||
PathFinder pathFinder = new PathFinder();
|
||||
Result result = pathFinder.find(getRootTable(), table, getDataModel(), true, fromHistory, DBClosureView.this.parent);
|
||||
if (result != null) {
|
||||
List<Table> path = result.path;
|
||||
mainPath.clear();
|
||||
mainPathAsSet.clear();
|
||||
Map<Table, Integer> fd = new HashMap<Table, Integer>();
|
||||
for (int i = 0; i < result.path.size(); ++i) {
|
||||
fd.put(result.path.get(i), i);
|
||||
}
|
||||
refreshTableModel(fd);
|
||||
selectedTable = null;
|
||||
// refresh();
|
||||
|
||||
for (int i = 0; i < path.size(); ++i) {
|
||||
Table r = path.get(i);
|
||||
String tabName = getDataModel().getDisplayName(r);
|
||||
selectCell(result.expand && i == path.size() - 1, tabName, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void expandPath() {
|
||||
List<Table> path = new ArrayList<Table>();
|
||||
for (CellInfo ci: mainPath) {
|
||||
path.add(ci.table);
|
||||
}
|
||||
expandTablePath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(final MouseEvent e) {
|
||||
// reset view
|
||||
{
|
||||
Point position = e.getPoint();
|
||||
int row = closureTable.rowAtPoint(position);
|
||||
int column = closureTable.columnAtPoint(position);
|
||||
if (row >= 0 && column >= 0) {
|
||||
Object value = closureTable.getModel().getValueAt(row, column);
|
||||
CellInfo ci = cellInfo.get(value);
|
||||
if (currentForcedDistance != null && ci != null && !mainPathAsSet.contains(ci)) {
|
||||
mainPath.clear();
|
||||
mainPathAsSet.clear();
|
||||
currentForcedDistance = null;
|
||||
refreshTableModel(null);
|
||||
selectedTable = null;
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// context menu
|
||||
if (SwingUtilities.isRightMouseButton(e)) {
|
||||
int row = closureTable.rowAtPoint(e.getPoint());
|
||||
int column = closureTable.columnAtPoint(e.getPoint());
|
||||
if (row < 0 || column < 0) return;
|
||||
final Object value = closureTable.getModel().getValueAt(row, column);
|
||||
if (value == null || !(value instanceof String)) return;
|
||||
final Table table = getDataModel().getTableByDisplayName((String) value);
|
||||
if (table != null) {
|
||||
if (selectedTable == null || !selectedTable.equals(value)) {
|
||||
if (cellInfo.containsKey(value) && !cellInfo.get(value).selected) {
|
||||
selectTableCell(column, row);
|
||||
}
|
||||
}
|
||||
// int tableLevel = -1;
|
||||
// if (cellInfo.containsKey(value)) {
|
||||
// tableLevel = cellInfo.get(value).level;
|
||||
// }
|
||||
// JCheckBoxMenuItem exclude = new JCheckBoxMenuItem("Exclude " + getDataModel().getDisplayName(table) + " from Path");
|
||||
// exclude.setSelected(excludedFromPath.contains(table));
|
||||
// exclude.setEnabled(mainPath.contains(cellInfo.get(value)) || excludedFromPath.contains(table));
|
||||
// exclude.addActionListener(new ActionListener() {
|
||||
// @Override
|
||||
// public void actionPerformed(ActionEvent e) {
|
||||
// if (!excludedFromPath.contains(table)) {
|
||||
// excludedFromPath.add(table);
|
||||
// } else {
|
||||
// excludedFromPath.remove(table);
|
||||
// }
|
||||
// mainPath.clear();
|
||||
// mainPathAsSet.clear();
|
||||
// refresh();
|
||||
// CellInfo ci = cellInfo.get(selectedTable);
|
||||
// if (ci != null) {
|
||||
// String st = selectedTable;
|
||||
// selectedTable = null;
|
||||
// select(st, ci);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// final Set<Table> toExclude = new HashSet<Table>();
|
||||
// for (Entry<String, CellInfo> ciE: cellInfo.entrySet()) {
|
||||
// if (ciE.getValue().selected && ciE.getValue().level == tableLevel) {
|
||||
// Table tableByDisplayName = getDataModel().getTableByDisplayName(ciE.getKey());
|
||||
// if (tableByDisplayName != null) {
|
||||
// toExclude.add(tableByDisplayName);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// JCheckBoxMenuItem excludeAll = new JCheckBoxMenuItem("Exclude all with Distance " + (tableLevel + 1) + " from Path");
|
||||
// excludeAll.setEnabled(toExclude.size() > 1);
|
||||
// excludeAll.addActionListener(new ActionListener() {
|
||||
// @Override
|
||||
// public void actionPerformed(ActionEvent e) {
|
||||
// excludedFromPath.addAll(toExclude);
|
||||
// mainPath.clear();
|
||||
// mainPathAsSet.clear();
|
||||
// refresh();
|
||||
// CellInfo ci = cellInfo.get(selectedTable);
|
||||
// if (ci != null) {
|
||||
// String st = selectedTable;
|
||||
// selectedTable = null;
|
||||
// select(st, ci);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// JMenuItem deselect = new JMenuItem("Deselect path");
|
||||
// deselect.addActionListener(new ActionListener() {
|
||||
// @Override
|
||||
// public void actionPerformed(ActionEvent e) {
|
||||
// mainPath.clear();
|
||||
// mainPathAsSet.clear();
|
||||
// excludedFromPath.clear();
|
||||
// refreshTableModel();
|
||||
// selectedTable = null;
|
||||
// refresh();
|
||||
// }
|
||||
// });
|
||||
JMenuItem pathFinder = new JMenuItem("Find more complex path to " + getDataModel().getDisplayName(table));
|
||||
Table rt = getRootTable();
|
||||
if (rt == null || !rt.closure(false).contains(table)) {
|
||||
pathFinder.setEnabled(false);
|
||||
}
|
||||
pathFinder.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
openPathFinder(table, false);
|
||||
}
|
||||
});
|
||||
|
||||
JMenuItem openPath = new JMenuItem("Open path to " + getDataModel().getDisplayName(table));
|
||||
if (rt == null || !rt.closure(false).contains(table)) {
|
||||
openPath.setEnabled(false);
|
||||
}
|
||||
openPath.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
expandPath();
|
||||
DBClosureView.this.select(selectedTable);
|
||||
}
|
||||
});
|
||||
|
||||
RowBrowser rb = getVisibleTables().get(table);
|
||||
if (rb == null) {
|
||||
if (!mainPath.isEmpty()) {
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
menu.add(openPath);
|
||||
menu.add(new JSeparator());
|
||||
menu.add(pathFinder);
|
||||
UIUtil.showPopup(e.getComponent(), e.getX(), e.getY(), menu);
|
||||
}
|
||||
} else {
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
JMenuItem select = new JMenuItem("Select " + getDataModel().getDisplayName(table));
|
||||
select.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
DBClosureView.this.select((String) value);
|
||||
}
|
||||
});
|
||||
menu.add(select);
|
||||
// menu.addSeparator();
|
||||
// menu.add(exclude);
|
||||
// menu.add(excludeAll);
|
||||
menu.addSeparator();
|
||||
JPopupMenu popup = rb.browserContentPane.createPopupMenu(null, -1, 0, 0, false);
|
||||
JPopupMenu popup2 = rb.browserContentPane.createSqlPopupMenu(null, -1, 0, 0, true, closureTable);
|
||||
popup.add(new JSeparator());
|
||||
for (Component c : popup.getComponents()) {
|
||||
menu.add(c);
|
||||
}
|
||||
for (Component c : popup2.getComponents()) {
|
||||
menu.add(c);
|
||||
}
|
||||
if (!mainPath.isEmpty()) {
|
||||
// menu.addSeparator();
|
||||
// menu.add(deselect);
|
||||
menu.addSeparator();
|
||||
menu.add(openPath);
|
||||
menu.add(pathFinder);
|
||||
}
|
||||
UIUtil.showPopup(e.getComponent(), e.getX(), e.getY(), menu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||
Point position = e.getPoint();
|
||||
int row = closureTable.rowAtPoint(position);
|
||||
int column = closureTable.columnAtPoint(position);
|
||||
if (row < 0 || column < 0) return;
|
||||
|
||||
Object value = closureTable.getModel().getValueAt(row, column);
|
||||
if (value == null || !(value instanceof String)) return;
|
||||
final Table table = getDataModel().getTableByDisplayName((String) value);
|
||||
selectCell(e.getClickCount() > 1, value, table);
|
||||
}
|
||||
}
|
||||
|
||||
private void selectCell(boolean expandPath, Object value, final Table table) {
|
||||
if (table != null) {
|
||||
if (cellInfo.containsKey(value)) {
|
||||
String prevSelectedTable = selectedTable;
|
||||
CellInfo selectedCellInfo = cellInfo.get(value);
|
||||
if (selectedCellInfo.selected && !mainPathAsSet.contains(selectedCellInfo)) {
|
||||
manuallySelected.put(selectedCellInfo.level, (String) value);
|
||||
select(prevSelectedTable, selectedCellInfo);
|
||||
} else if (!selectedCellInfo.selected) {
|
||||
manuallySelected.clear();
|
||||
selectTableCell((String) value);
|
||||
} else {
|
||||
scrollToTable(table);
|
||||
}
|
||||
}
|
||||
|
||||
if (expandPath) {
|
||||
if (!mainPath.isEmpty()) {
|
||||
expandPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void select(String toSelect, CellInfo selectedCellInfo) {
|
||||
TreeMap<Integer, String> newMS = new TreeMap<Integer, String>(manuallySelected);
|
||||
String lastFound = null;
|
||||
for (Entry<Integer, String> ms: manuallySelected.entrySet()) {
|
||||
find(ms.getValue());
|
||||
if (selectedCellInfo.level < ms.getKey() && !mainPathAsSet.contains(selectedCellInfo)) {
|
||||
manuallySelected = newMS;
|
||||
if (lastFound != null) {
|
||||
find(lastFound);
|
||||
}
|
||||
break;
|
||||
}
|
||||
newMS.put(ms.getKey(), ms.getValue());
|
||||
lastFound = ms.getValue();
|
||||
}
|
||||
if (toSelect != null && !toSelect.equals(selectedTable)) {
|
||||
find(toSelect);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Holds infos about a cell in the closure-table.
|
||||
*/
|
||||
private class CellInfo {
|
||||
@@ -126,8 +407,10 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
private List<CellInfo> mainPath = new ArrayList<CellInfo>();
|
||||
private HashSet<CellInfo> mainPathAsSet = new HashSet<CellInfo>();
|
||||
private Set<Pair<String, String>> dependencies = new HashSet<Pair<String,String>>();
|
||||
private Set<Table> excludedFromPath = new HashSet<Table>();
|
||||
private Map<Table, Integer> currentForcedDistance = null;
|
||||
private final JFrame parent;
|
||||
|
||||
private TableMouseListener tableMouseListener;
|
||||
|
||||
/** Creates new form FindDialog
|
||||
* @param rootTable */
|
||||
@@ -166,6 +449,68 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
findButton.setVisible(false);
|
||||
searchButton.setText("Find Table");
|
||||
|
||||
AutoCompletion.enable(findPathComboBox);
|
||||
findPathComboBox.getEditor().getEditorComponent().addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
if (e.getKeyChar() == '\n') {
|
||||
findPathComboBoxActionPerformed(null);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void keyPressed(KeyEvent arg0) {
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 20;
|
||||
JButton stFindPathButton = StringSearchPanel.createSearchButton(
|
||||
this.parent, findPathComboBox,
|
||||
new Object() {
|
||||
public String toString() {
|
||||
Table rootTable = getRootTable();
|
||||
return (rootTable != null? ("From " + getDataModel().getDisplayName(rootTable) + " - ") : "") + "Select destination or choose from History";
|
||||
}
|
||||
},
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Object toFind = findPathComboBox.getSelectedItem();
|
||||
if (toFind != null) {
|
||||
CellInfo cellInfo = DBClosureView.this.cellInfo.get(toFind);
|
||||
if (cellInfo != null) {
|
||||
tableMouseListener.openPathFinder(cellInfo.table, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null, null, null, true, new AdditionalComponentFactory() {
|
||||
@Override
|
||||
public JComponent create(final StringSearchPanel searchPanel) {
|
||||
HistoryPanel historyPanel = new HistoryPanel(getRootTable(), getDataModel()) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void close() {
|
||||
searchPanel.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(Table source, Table destination) {
|
||||
tableMouseListener.openPathFinder(destination, true);
|
||||
}
|
||||
};
|
||||
return historyPanel;
|
||||
}
|
||||
});
|
||||
tablePanel.add(stFindPathButton, gridBagConstraints);
|
||||
|
||||
findPathComboBox.setVisible(false);
|
||||
findPathButton.setVisible(false);
|
||||
stFindPathButton.setText("Find Path to...");
|
||||
|
||||
columnsComboBox.setModel(new DefaultComboBoxModel<Integer>(new Integer[] {
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
|
||||
}));
|
||||
@@ -245,199 +590,10 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
};
|
||||
closureTable.setShowGrid(false);
|
||||
closureTable.setSurrendersFocusOnKeystroke(true);
|
||||
closureTable.getTableHeader().setReorderingAllowed(false);
|
||||
jScrollPane1.setViewportView(closureTable);
|
||||
|
||||
closureTable.addMouseListener(new MouseListener() {
|
||||
|
||||
private Map<Integer, String> manuallySelected = new TreeMap<Integer, String>();
|
||||
|
||||
private void expandPath() {
|
||||
List<Table> path = new ArrayList<Table>();
|
||||
for (CellInfo ci: mainPath) {
|
||||
path.add(ci.table);
|
||||
}
|
||||
expandTablePath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(final MouseEvent e) {
|
||||
mouseReleased(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
// context menu
|
||||
if (SwingUtilities.isRightMouseButton(e)) {
|
||||
int row = closureTable.rowAtPoint(e.getPoint());
|
||||
int column = closureTable.columnAtPoint(e.getPoint());
|
||||
if (row < 0 || column < 0) return;
|
||||
final Object value = closureTable.getModel().getValueAt(row, column);
|
||||
if (value == null || !(value instanceof String)) return;
|
||||
final Table table = getDataModel().getTableByDisplayName((String) value);
|
||||
if (table != null) {
|
||||
if (selectedTable == null || !selectedTable.equals(value)) {
|
||||
if (cellInfo.containsKey(value) && !cellInfo.get(value).selected) {
|
||||
selectTableCell(column, row);
|
||||
}
|
||||
}
|
||||
JCheckBoxMenuItem exclude = new JCheckBoxMenuItem("Exclude " + getDataModel().getDisplayName(table) + " from Path");
|
||||
exclude.setSelected(excludedFromPath.contains(table));
|
||||
exclude.setEnabled(mainPath.contains(cellInfo.get(value)) || excludedFromPath.contains(table));
|
||||
exclude.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (!excludedFromPath.contains(table)) {
|
||||
excludedFromPath.add(table);
|
||||
} else {
|
||||
excludedFromPath.remove(table);
|
||||
}
|
||||
mainPath.clear();
|
||||
mainPathAsSet.clear();
|
||||
refresh();
|
||||
CellInfo ci = cellInfo.get(selectedTable);
|
||||
if (ci != null) {
|
||||
String st = selectedTable;
|
||||
selectedTable = null;
|
||||
select(st, ci);
|
||||
}
|
||||
}
|
||||
});
|
||||
JMenuItem deselect = new JMenuItem("Deselect Path");
|
||||
deselect.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mainPath.clear();
|
||||
mainPathAsSet.clear();
|
||||
excludedFromPath.clear();
|
||||
refreshTableModel();
|
||||
selectedTable = null;
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
RowBrowser rb = getVisibleTables().get(table);
|
||||
if (rb == null) {
|
||||
if (!mainPath.isEmpty()) {
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
JMenuItem open = new JMenuItem("Open Path to " + selectedTable);
|
||||
open.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
expandPath();
|
||||
}
|
||||
});
|
||||
menu.add(open);
|
||||
JMenuItem openAndSelect = new JMenuItem("Open Path to and Select " + selectedTable);
|
||||
openAndSelect.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
expandPath();
|
||||
DBClosureView.this.select(selectedTable);
|
||||
}
|
||||
});
|
||||
menu.add(openAndSelect);
|
||||
menu.add(new JSeparator());
|
||||
menu.add(exclude);
|
||||
menu.add(deselect);
|
||||
menu.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
} else {
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
JMenuItem select = new JMenuItem("Select " + getDataModel().getDisplayName(table));
|
||||
select.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
DBClosureView.this.select((String) value);
|
||||
}
|
||||
});
|
||||
menu.add(select);
|
||||
menu.addSeparator();
|
||||
menu.add(exclude);
|
||||
menu.addSeparator();
|
||||
JPopupMenu popup = rb.browserContentPane.createPopupMenu(null, -1, 0, 0, false);
|
||||
JPopupMenu popup2 = rb.browserContentPane.createSqlPopupMenu(null, -1, 0, 0, true);
|
||||
popup.add(new JSeparator());
|
||||
for (Component c : popup.getComponents()) {
|
||||
menu.add(c);
|
||||
}
|
||||
for (Component c : popup2.getComponents()) {
|
||||
menu.add(c);
|
||||
}
|
||||
if (!mainPath.isEmpty()) {
|
||||
menu.addSeparator();
|
||||
menu.add(deselect);
|
||||
}
|
||||
UIUtil.fit(popup);
|
||||
menu.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||
Point position = e.getPoint();
|
||||
int row = closureTable.rowAtPoint(position);
|
||||
int column = closureTable.columnAtPoint(position);
|
||||
if (row < 0 || column < 0) return;
|
||||
|
||||
Object value = closureTable.getModel().getValueAt(row, column);
|
||||
if (value == null || !(value instanceof String)) return;
|
||||
final Table table = getDataModel().getTableByDisplayName((String) value);
|
||||
if (table != null) {
|
||||
if (cellInfo.containsKey(value)) {
|
||||
String prevSelectedTable = selectedTable;
|
||||
CellInfo selectedCellInfo = cellInfo.get(value);
|
||||
if (selectedCellInfo.selected && !mainPathAsSet.contains(selectedCellInfo)) {
|
||||
manuallySelected.put(selectedCellInfo.level, (String) value);
|
||||
select(prevSelectedTable, selectedCellInfo);
|
||||
} else if (!selectedCellInfo.selected) {
|
||||
manuallySelected.clear();
|
||||
selectTableCell(column, row);
|
||||
} else {
|
||||
scrollToTable(table);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.getClickCount() > 1) {
|
||||
RowBrowser rb = getVisibleTables().get(table);
|
||||
if (rb == null) {
|
||||
if (!mainPath.isEmpty()) {
|
||||
expandPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void select(String toSelect, CellInfo selectedCellInfo) {
|
||||
TreeMap<Integer, String> newMS = new TreeMap<Integer, String>(manuallySelected);
|
||||
String lastFound = null;
|
||||
for (Entry<Integer, String> ms: manuallySelected.entrySet()) {
|
||||
find(ms.getValue());
|
||||
if (selectedCellInfo.level < ms.getKey() && !mainPathAsSet.contains(selectedCellInfo)) {
|
||||
manuallySelected = newMS;
|
||||
if (lastFound != null) {
|
||||
find(lastFound);
|
||||
}
|
||||
break;
|
||||
}
|
||||
newMS.put(ms.getKey(), ms.getValue());
|
||||
lastFound = ms.getValue();
|
||||
}
|
||||
if (toSelect != null && !toSelect.equals(selectedTable)) {
|
||||
find(toSelect);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
});
|
||||
closureTable.addMouseListener(tableMouseListener = new TableMouseListener());
|
||||
|
||||
searchComboBox.setMaximumRowCount(30);
|
||||
|
||||
@@ -508,9 +664,9 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
} else if (getVisibleTables().containsKey(t)) {
|
||||
((JLabel) render).setFont(onPath? italicBold : italic);
|
||||
}
|
||||
if (excludedFromPath.contains(t)) {
|
||||
((JLabel) render).setForeground(new Color(180, 180, 180));
|
||||
}
|
||||
// if (currentForcedDistance != null && currentForcedDistance.containsKey(t)) {
|
||||
// ((JLabel) render).setForeground(new Color(180, 180, 180));
|
||||
// }
|
||||
if (getVisibleTables().containsKey(t)) {
|
||||
((JLabel) render).setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.lightGray, Color.gray));
|
||||
}
|
||||
@@ -599,42 +755,46 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
private void selectTableCell(int col, int row) {
|
||||
if (col >= 1 && row >= 0) {
|
||||
String displayName = (String) closureTable.getModel().getValueAt(row, col);
|
||||
closureTable.getSelectionModel().clearSelection();
|
||||
for (CellInfo c: cellInfo.values()) {
|
||||
c.selected = false;
|
||||
selectTableCell(displayName);
|
||||
}
|
||||
}
|
||||
|
||||
private void selectTableCell(String displayName) {
|
||||
closureTable.getSelectionModel().clearSelection();
|
||||
for (CellInfo c: cellInfo.values()) {
|
||||
c.selected = false;
|
||||
}
|
||||
if (displayName != null && !"".equals(displayName)) {
|
||||
Table prevTable = null;
|
||||
if (selectedTable != null) {
|
||||
prevTable = getDataModel().getTableByDisplayName(selectedTable);
|
||||
}
|
||||
if (displayName != null && !"".equals(displayName)) {
|
||||
Table prevTable = null;
|
||||
if (selectedTable != null) {
|
||||
prevTable = getDataModel().getTableByDisplayName(selectedTable);
|
||||
}
|
||||
selectedTable = displayName;
|
||||
searchComboBox.setSelectedItem(selectedTable);
|
||||
repaintClosureView();
|
||||
Table table = getDataModel().getTableByDisplayName(selectedTable);
|
||||
if (table != null) {
|
||||
CellInfo selectionInfo = cellInfo.get(selectedTable);
|
||||
selectionInfo.select();
|
||||
if (prevTable != table) {
|
||||
Set<Table> visibleTables = getVisibleTables().keySet();
|
||||
Set<Table> mainPathTables = new HashSet<Table>();
|
||||
for (CellInfo ci: mainPath) {
|
||||
mainPathTables.add(ci.table);
|
||||
}
|
||||
Set<CellInfo> pathToVisibleTable = shortestPathToVisibleTable(visibleTables, selectionInfo);
|
||||
Set<CellInfo> pathToMainPathTable = shortestPathToVisibleTable(mainPathTables, selectionInfo);
|
||||
List<CellInfo> pathVT = new ArrayList<CellInfo>();
|
||||
int vtMaxRow = fillPath(selectionInfo, visibleTables, pathToVisibleTable, pathVT);
|
||||
List<CellInfo> pathST = new ArrayList<CellInfo>();
|
||||
int stMaxRow = fillPath(selectionInfo, mainPathTables, pathToMainPathTable, pathST);
|
||||
if (pathToMainPathTable.isEmpty()) { // (vtMaxRow > stMaxRow) {
|
||||
mainPath = pathVT;
|
||||
} else {
|
||||
mainPath = pathST;
|
||||
}
|
||||
selectedTable = displayName;
|
||||
searchComboBox.setSelectedItem(selectedTable);
|
||||
repaintClosureView();
|
||||
Table table = getDataModel().getTableByDisplayName(selectedTable);
|
||||
if (table != null) {
|
||||
CellInfo selectionInfo = cellInfo.get(selectedTable);
|
||||
selectionInfo.select();
|
||||
if (prevTable != table) {
|
||||
Set<Table> visibleTables = getVisibleTables().keySet();
|
||||
Set<Table> mainPathTables = new HashSet<Table>();
|
||||
for (CellInfo ci: mainPath) {
|
||||
mainPathTables.add(ci.table);
|
||||
}
|
||||
Set<CellInfo> pathToVisibleTable = shortestPathToVisibleTable(visibleTables, selectionInfo);
|
||||
Set<CellInfo> pathToMainPathTable = shortestPathToVisibleTable(mainPathTables, selectionInfo);
|
||||
List<CellInfo> pathVT = new ArrayList<CellInfo>();
|
||||
int vtMaxRow = fillPath(selectionInfo, visibleTables, pathToVisibleTable, pathVT);
|
||||
List<CellInfo> pathST = new ArrayList<CellInfo>();
|
||||
int stMaxRow = fillPath(selectionInfo, mainPathTables, pathToMainPathTable, pathST);
|
||||
if (pathToMainPathTable.isEmpty()) { // (vtMaxRow > stMaxRow) {
|
||||
mainPath = pathVT;
|
||||
} else {
|
||||
mainPath = pathST;
|
||||
}
|
||||
mainPathAsSet = new HashSet<CellInfo>(mainPath);
|
||||
}
|
||||
mainPathAsSet = new HashSet<CellInfo>(mainPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -698,7 +858,7 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
*/
|
||||
public void refresh() {
|
||||
String prevSelection = selectedTable;
|
||||
refreshTableModel();
|
||||
refreshTableModel(null);
|
||||
if (cellInfo.containsKey(prevSelection)) {
|
||||
selectedTable = prevSelection;
|
||||
} else {
|
||||
@@ -710,12 +870,17 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
/**
|
||||
* Refreshes the table model.
|
||||
*/
|
||||
private void refreshTableModel() {
|
||||
private void refreshTableModel(Map<Table, Integer> forcedDistance) {
|
||||
cellInfo.clear();
|
||||
dependencies.clear();
|
||||
Table selectedTable = getSelectedTable();
|
||||
|
||||
Object[] columns = new Object[tablesPerLine + 1];
|
||||
currentForcedDistance = forcedDistance;
|
||||
if (forcedDistance == null) {
|
||||
forcedDistance = new HashMap<Table, Integer>();
|
||||
}
|
||||
|
||||
Object[] columns = new Object[tablesPerLine + 1];
|
||||
for (int i = 0; i < columns.length; ++i) {
|
||||
columns[i] = "";
|
||||
}
|
||||
@@ -798,27 +963,40 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
Table table = getDataModel().getTableByDisplayName(t);
|
||||
if (table != null) {
|
||||
CellInfo cellInfoT = this.cellInfo.get(t);
|
||||
if (!excludedFromPath.contains(table)) {
|
||||
for (Association association: table.associations) {
|
||||
String displayName = getDataModel().getDisplayName(association.destination);
|
||||
if (!association.isIgnored()) {
|
||||
if (!visited.contains(displayName)) {
|
||||
nextLine.add(displayName);
|
||||
visited.add(displayName);
|
||||
CellInfo cellInfo = new CellInfo(distance);
|
||||
cellInfo.parents.add(cellInfoT);
|
||||
cellInfo.table = association.destination;
|
||||
for (Association association: table.associations) {
|
||||
Integer fd = forcedDistance.get(association.destination);
|
||||
if (fd != null && fd != distance + 1) {
|
||||
continue;
|
||||
}
|
||||
boolean addToParent = true;
|
||||
if (forcedDistance.containsKey(association.destination)) {
|
||||
if (!forcedDistance.containsKey(table)) {
|
||||
addToParent = false;
|
||||
}
|
||||
}
|
||||
String displayName = getDataModel().getDisplayName(association.destination);
|
||||
if (!association.isIgnored() ||
|
||||
(forcedDistance.containsKey(association.source) && forcedDistance.containsKey(association.destination))) {
|
||||
if (!visited.contains(displayName)) {
|
||||
nextLine.add(displayName);
|
||||
visited.add(displayName);
|
||||
CellInfo cellInfo = new CellInfo(distance);
|
||||
if (addToParent) {
|
||||
cellInfo.parents.add(cellInfoT);
|
||||
}
|
||||
cellInfo.table = association.destination;
|
||||
if (association.isInsertDestinationBeforeSource()) {
|
||||
dependencies.add(new Pair<String, String>(t, displayName));
|
||||
}
|
||||
this.cellInfo.put(displayName, cellInfo);
|
||||
} else {
|
||||
if (nextLine.contains(displayName)) {
|
||||
if (addToParent) {
|
||||
this.cellInfo.get(displayName).parents.add(cellInfoT);
|
||||
}
|
||||
if (association.isInsertDestinationBeforeSource()) {
|
||||
dependencies.add(new Pair<String, String>(t, displayName));
|
||||
}
|
||||
this.cellInfo.put(displayName, cellInfo);
|
||||
} else {
|
||||
if (nextLine.contains(displayName)) {
|
||||
this.cellInfo.get(displayName).parents.add(cellInfoT);
|
||||
if (association.isInsertDestinationBeforeSource()) {
|
||||
dependencies.add(new Pair<String, String>(t, displayName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -941,6 +1119,8 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
vector.addAll(nonIsolated);
|
||||
searchComboBox.setModel(new DefaultComboBoxModel<String>(vector));
|
||||
searchComboBox.setSelectedItem("");
|
||||
findPathComboBox.setModel(new DefaultComboBoxModel<String>(vector));
|
||||
findPathComboBox.setSelectedItem("");
|
||||
}
|
||||
|
||||
private Table getSelectedTable() {
|
||||
@@ -967,9 +1147,9 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
tablePanel = new javax.swing.JPanel();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
closureTable = new javax.swing.JTable();
|
||||
searchComboBox = new net.sf.jailer.ui.JComboBox();
|
||||
searchComboBox = new JComboBox();
|
||||
jLabel7 = new javax.swing.JLabel();
|
||||
columnsComboBox = new net.sf.jailer.ui.JComboBox();
|
||||
columnsComboBox = new javax.swing.JComboBox();
|
||||
findButton = new javax.swing.JButton();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
@@ -979,6 +1159,8 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
jLabel6 = new javax.swing.JLabel();
|
||||
jLabel8 = new javax.swing.JLabel();
|
||||
jLabel9 = new javax.swing.JLabel();
|
||||
findPathComboBox = new JComboBox();
|
||||
findPathButton = new javax.swing.JButton();
|
||||
|
||||
contentPanel.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
@@ -1020,8 +1202,7 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
|
||||
searchComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
|
||||
searchComboBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
searchComboBoxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
@@ -1032,7 +1213,7 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
|
||||
jLabel7.setText("Columns ");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 3;
|
||||
gridBagConstraints.gridx = 7;
|
||||
gridBagConstraints.gridy = 20;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
@@ -1040,20 +1221,18 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
|
||||
columnsComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
|
||||
columnsComboBox.addItemListener(new java.awt.event.ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
columnsComboBoxItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridx = 8;
|
||||
gridBagConstraints.gridy = 20;
|
||||
tablePanel.add(columnsComboBox, gridBagConstraints);
|
||||
|
||||
findButton.setText("Find");
|
||||
findButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
findButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
@@ -1112,6 +1291,30 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
gridBagConstraints.gridy = 8;
|
||||
tablePanel.add(jLabel9, gridBagConstraints);
|
||||
|
||||
findPathComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
|
||||
findPathComboBox.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
findPathComboBoxActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 20;
|
||||
tablePanel.add(findPathComboBox, gridBagConstraints);
|
||||
|
||||
findPathButton.setText("Find Path to...");
|
||||
findPathButton.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
findPathButtonActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 5;
|
||||
gridBagConstraints.gridy = 20;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
|
||||
tablePanel.add(findPathButton, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
@@ -1134,6 +1337,12 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
find((String) toFind);
|
||||
}//GEN-LAST:event_findButtonActionPerformed
|
||||
|
||||
private void findPathComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_findPathComboBoxActionPerformed
|
||||
}//GEN-LAST:event_findPathComboBoxActionPerformed
|
||||
|
||||
private void findPathButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_findPathButtonActionPerformed
|
||||
}//GEN-LAST:event_findPathButtonActionPerformed
|
||||
|
||||
protected void find(String toFind) {
|
||||
if (toFind != null && !toFind.equals(selectedTable)) {
|
||||
CellInfo cellInfo = this.cellInfo.get(toFind);
|
||||
@@ -1149,11 +1358,13 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
protected abstract void select(String selectedTable);
|
||||
protected abstract void scrollToTable(Table table);
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JTable closureTable;
|
||||
private net.sf.jailer.ui.JComboBox columnsComboBox;
|
||||
private javax.swing.JComboBox columnsComboBox;
|
||||
public javax.swing.JPanel contentPanel;
|
||||
private javax.swing.JButton findButton;
|
||||
private javax.swing.JButton findPathButton;
|
||||
private JComboBox findPathComboBox;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel jLabel3;
|
||||
@@ -1164,7 +1375,7 @@ public abstract class DBClosureView extends javax.swing.JDialog {
|
||||
private javax.swing.JLabel jLabel8;
|
||||
private javax.swing.JLabel jLabel9;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private net.sf.jailer.ui.JComboBox searchComboBox;
|
||||
private JComboBox searchComboBox;
|
||||
public javax.swing.JPanel tablePanel;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ import java.awt.dnd.DropTargetEvent;
|
||||
import java.awt.dnd.DropTargetListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.AdjustmentEvent;
|
||||
import java.awt.event.AdjustmentListener;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
@@ -88,7 +92,6 @@ import javax.swing.JTree;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.ToolTipManager;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UIManager.LookAndFeelInfo;
|
||||
import javax.swing.WindowConstants;
|
||||
@@ -108,6 +111,7 @@ import net.sf.jailer.database.Session;
|
||||
import net.sf.jailer.datamodel.Association;
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.modelbuilder.JDBCMetaDataBasedModelElementFinder;
|
||||
import net.sf.jailer.modelbuilder.ModelBuilder;
|
||||
import net.sf.jailer.ui.About;
|
||||
import net.sf.jailer.ui.AnalyseOptionsDialog;
|
||||
@@ -127,6 +131,7 @@ import net.sf.jailer.ui.Environment;
|
||||
import net.sf.jailer.ui.ExtractionModelFrame;
|
||||
import net.sf.jailer.ui.ImportDialog;
|
||||
import net.sf.jailer.ui.JComboBox;
|
||||
import net.sf.jailer.ui.PrivilegedSessionProviderDialog;
|
||||
import net.sf.jailer.ui.SessionForUI;
|
||||
import net.sf.jailer.ui.StringSearchPanel;
|
||||
import net.sf.jailer.ui.UIUtil;
|
||||
@@ -236,6 +241,22 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
tableTreesTabbedPane.setTabComponentAt(0, new JLabel("Navigation", navigationIcon, JLabel.LEFT));
|
||||
tableTreesTabbedPane.setTabComponentAt(1, new JLabel("Database", databaseIcon, JLabel.LEFT));
|
||||
|
||||
tableTreesTabbedPane.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
if (createMetaDataPanel != null && tableTreesTabbedPane.getSelectedComponent() == tablesPanel) {
|
||||
UIUtil.invokeLater(10, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (createMetaDataPanel != null) {
|
||||
createMetaDataPanel.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
initialized = true;
|
||||
|
||||
tablesComboBox = new JComboBox<String>() {
|
||||
@@ -287,7 +308,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
metaDataViewPanel.add(metaDataDetailsPanel);
|
||||
|
||||
jLayeredPane1.removeAll();
|
||||
jLayeredPane1.setLayout(new GridBagLayout());
|
||||
jLayeredPane1.setLayout(null);
|
||||
jLayeredPane1.setLayer(layeredPaneContent, JLayeredPane.PALETTE_LAYER);
|
||||
jLayeredPane1.setLayer(dummy, JLayeredPane.DEFAULT_LAYER);
|
||||
gridBagConstraints = new GridBagConstraints();
|
||||
@@ -296,16 +317,106 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.weightx = 1;
|
||||
gridBagConstraints.weighty = 1;
|
||||
jLayeredPane1.add(layeredPaneContent, gridBagConstraints);
|
||||
jLayeredPane1.add(dummy, gridBagConstraints);
|
||||
jLayeredPane1.add(layeredPaneContent /*, gridBagConstraints */);
|
||||
layeredPaneContent.setLocation(0, 0);
|
||||
// jLayeredPane1.add(dummy /*, gridBagConstraints */);
|
||||
|
||||
addComponentListener(new ComponentListener() {
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
layeredPaneContent.setSize(jLayeredPane1.getSize());
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
desktopSplitPane.setDividerLocation(0.75);
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
}
|
||||
});
|
||||
|
||||
jLayeredPane1.addComponentListener(new ComponentListener() {
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
layeredPaneContent.setSize(jLayeredPane1.getSize());
|
||||
}
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
layeredPaneContent.setSize(jLayeredPane1.getSize());
|
||||
}
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
layeredPaneContent.setSize(jLayeredPane1.getSize());
|
||||
}
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
}
|
||||
});
|
||||
|
||||
gridBagConstraints = new GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.weightx = 1;
|
||||
gridBagConstraints.weighty = 1;
|
||||
JPanel anchorPanel = new JPanel(null);
|
||||
anchorPanel.setOpaque(false);
|
||||
jLayeredPane1.setLayer(anchorPanel, JLayeredPane.POPUP_LAYER);
|
||||
jLayeredPane1.add(anchorPanel/* , gridBagConstraints */);
|
||||
|
||||
anchorManager = new DesktopAnchorManager(anchorPanel) {
|
||||
@Override
|
||||
protected void layout(RowBrowser anchor) {
|
||||
try {
|
||||
anchor.internalFrame.setSelected(true);
|
||||
} catch (PropertyVetoException e) {
|
||||
// ignore
|
||||
}
|
||||
arrangeLayout(true, anchor);
|
||||
}
|
||||
@Override
|
||||
protected boolean isApplicable(RowBrowser tableBrowser) {
|
||||
if (tableBrowser.parent == null) {
|
||||
return false;
|
||||
}
|
||||
if (desktop.desktopAnimation != null && desktop.desktopAnimation.isActive()) {
|
||||
return false;
|
||||
}
|
||||
RowBrowser visParent = tableBrowser.parent;
|
||||
while (visParent != null && !visParent.internalFrame.isVisible()) {
|
||||
visParent = visParent.parent;
|
||||
}
|
||||
return visParent != null && Math.abs(tableBrowser.internalFrame.getY() - visParent.internalFrame.getY()) > 2;
|
||||
}
|
||||
};
|
||||
|
||||
if (jScrollPane1.getVerticalScrollBar() != null) {
|
||||
jScrollPane1.getVerticalScrollBar().setUnitIncrement(16);
|
||||
jScrollPane1.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
|
||||
@Override
|
||||
public void adjustmentValueChanged(AdjustmentEvent e) {
|
||||
anchorManager.reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (jScrollPane1.getHorizontalScrollBar() != null) {
|
||||
jScrollPane1.getHorizontalScrollBar().setUnitIncrement(16);
|
||||
jScrollPane1.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
|
||||
@Override
|
||||
public void adjustmentValueChanged(AdjustmentEvent e) {
|
||||
anchorManager.reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
hiddenPanel.setVisible(false);
|
||||
borderBrowserPanel.add(borderBrowser, java.awt.BorderLayout.CENTER);
|
||||
|
||||
@@ -424,7 +535,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
if (dbConnectionDialog != null) {
|
||||
createSession(dbConnectionDialog);
|
||||
}
|
||||
desktop = new Desktop(this.datamodel, jailerIcon, session, this, dbConnectionDialog, executionContext) {
|
||||
desktop = new Desktop(this.datamodel, jailerIcon, session, this, dbConnectionDialog, anchorManager, executionContext) {
|
||||
@Override
|
||||
public void openSchemaAnalyzer() {
|
||||
updateDataModel();
|
||||
@@ -493,6 +604,18 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
}
|
||||
return ROW_LIMIT_DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDesktopVisible() {
|
||||
return workbenchTabbedPane.getSelectedComponent() == desktopSplitPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkAnchorRetension() {
|
||||
if (anchorManager != null) {
|
||||
anchorManager.checkRetention();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
jScrollPane1.setViewportView(desktop);
|
||||
@@ -557,6 +680,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
if (newY > maxY)
|
||||
newY = maxY;
|
||||
jv.setViewPosition(new Point(newX, newY));
|
||||
DesktopAnimation.stopScrolling = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,6 +692,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
|
||||
m_XDifference = e.getX();
|
||||
m_YDifference = e.getY();
|
||||
DesktopAnimation.stopScrolling = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -575,7 +700,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
if (e.getButton() == MouseEvent.BUTTON3) {
|
||||
return;
|
||||
}
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
setCursor(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -644,7 +769,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
largeLayoutRadioButtonMenuItemActionPerformed(e);
|
||||
}
|
||||
});
|
||||
showPopup(desktop, e.getX(), e.getY(), popup);
|
||||
UIUtil.showPopup(desktop, e.getX(), e.getY(), popup);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1989,7 +2114,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
}// GEN-LAST:event_tinyLayoutRadioButtonMenuItemActionPerformed
|
||||
|
||||
private void wheelzoomTip() {
|
||||
TipDialog.showTip(this, "WHEELZOOM", "While holding down the Ctrl-key you can use the mouse-wheel to zoom in or out.");
|
||||
TipDialog.showTip(this, "WHEELZOOM", "You can use the mouse-wheel to zoom in or out.");
|
||||
}
|
||||
|
||||
private void smallLayoutRadioButtonMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_smallLayoutRadioButtonMenuItemActionPerformed
|
||||
@@ -2035,6 +2160,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
if (rowBrowser != null) {
|
||||
desktop.scrollToCenter(rowBrowser.internalFrame);
|
||||
desktop.getiFrameStateChangeRenderer().onIFrameSelected(rowBrowser.internalFrame);
|
||||
navigationTree.setSelectionPath(node);
|
||||
}
|
||||
}
|
||||
if (evt.getButton() == MouseEvent.BUTTON3) {
|
||||
@@ -2043,7 +2169,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
navigationTree.setSelectionRow(row);
|
||||
JPopupMenu popup = rowBrowser.browserContentPane.createPopupMenu(null, -1, 0, 0, false);
|
||||
if (popup != null) {
|
||||
JPopupMenu popup2 = rowBrowser.browserContentPane.createSqlPopupMenu(null, -1, 0, 0, true);
|
||||
JPopupMenu popup2 = rowBrowser.browserContentPane.createSqlPopupMenu(null, -1, 0, 0, true, navigationTreeScrollPane);
|
||||
if (popup2.getComponentCount() > 0 && popup.getComponentCount() > 0) {
|
||||
popup.add(new JSeparator());
|
||||
}
|
||||
@@ -2051,38 +2177,36 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
popup.add(c);
|
||||
}
|
||||
UIUtil.fit(popup);
|
||||
showPopup(evt.getComponent(), evt.getX(), evt.getY(), popup);
|
||||
UIUtil.showPopup(evt.getComponent(), evt.getX(), evt.getY(), popup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}// GEN-LAST:event_navigationTreeMouseClicked
|
||||
|
||||
private void showPopup(final Component invoker, final int x, final int y, final JPopupMenu popup) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
popup.show(invoker, x, y);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void layoutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_layoutMenuItemActionPerformed
|
||||
arrangeLayout(true);
|
||||
}// GEN-LAST:event_layoutMenuItemActionPerformed
|
||||
|
||||
public void arrangeLayout(boolean scrollToCenter) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
arrangeLayout(scrollToCenter, Desktop.noArrangeLayoutOnNewTableBrowserWithAnchor? null : anchorManager.getNewestBrowser());
|
||||
anchorManager.setNewestBrowser(null);
|
||||
}
|
||||
|
||||
public void arrangeLayout(boolean scrollToCenter, RowBrowser anchor) {
|
||||
UIUtil.setWaitCursor(this);
|
||||
try {
|
||||
desktop.layoutBrowser(null, scrollToCenter);
|
||||
desktop.layoutBrowser(null, scrollToCenter, anchor);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void jScrollPane1MouseWheelMoved(java.awt.event.MouseWheelEvent evt) {// GEN-FIRST:event_jScrollPane1MouseWheelMoved
|
||||
desktop.onMouseWheelMoved(evt);
|
||||
desktop.onMouseWheelMoved(evt, jScrollPane1);
|
||||
long currentTime = System.currentTimeMillis();
|
||||
desktop.startRescaleMode(currentTime, evt);
|
||||
desktop.onMouseWheelMoved(evt, currentTime);
|
||||
desktop.onMouseWheelMoved(evt, jScrollPane1, currentTime);
|
||||
}// GEN-LAST:event_jScrollPane1MouseWheelMoved
|
||||
|
||||
private void openNewTableBrowser(boolean offerAlternatives) {
|
||||
@@ -2204,11 +2328,9 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
UIManager.put("InternalFrame:InternalFrameTitlePane[Enabled].textForeground", Color.BLUE);
|
||||
}
|
||||
|
||||
UIUtil.prepareUI();
|
||||
} catch (Exception x) {
|
||||
}
|
||||
ToolTipManager.sharedInstance().setInitialDelay(500);
|
||||
ToolTipManager.sharedInstance().setDismissDelay(7000);
|
||||
|
||||
createFrame();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -2318,6 +2440,8 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
|
||||
private void updateDataModel(String schemaName, boolean withViews, boolean withSynonyms) {
|
||||
try {
|
||||
JDBCMetaDataBasedModelElementFinder.privilegedSessionProvider = new PrivilegedSessionProviderDialog.Provider(this);
|
||||
|
||||
List<String> args = new ArrayList<String>();
|
||||
args.add("build-model-wo-merge");
|
||||
dbConnectionDialog.addDbArgs(args);
|
||||
@@ -2328,12 +2452,12 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
boolean[] isDefaultSchema = new boolean[1];
|
||||
String[] defaultSchema = new String[1];
|
||||
List<String> schemas;
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
try {
|
||||
CancellationHandler.reset(null);
|
||||
schemas = dbConnectionDialog.getDBSchemas(defaultSchema);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
if (analyseOptionsDialog.edit(schemas, defaultSchema[0], schemaName == null? null : Quoting.staticUnquote(schemaName), isDefaultSchema, dbConnectionDialog.currentConnection.user)) {
|
||||
String schema = analyseOptionsDialog.getSelectedSchema();
|
||||
@@ -2369,6 +2493,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
UIUtil.showException(this, "Error", e, session);
|
||||
} finally {
|
||||
ModelBuilder.assocFilter = null;
|
||||
JDBCMetaDataBasedModelElementFinder.privilegedSessionProvider = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2690,7 +2815,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
|
||||
Collection<AssociationModel> model = new ArrayList<AssociationModel>();
|
||||
if (desktop != null) {
|
||||
@@ -2726,7 +2851,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
|
||||
borderBrowser.setModel(model);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2745,7 +2870,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(DataBrowser.this);
|
||||
if (dataModelViewFrame == null) {
|
||||
dataModelViewFrame = ExtractionModelFrame.createFrame(null, false, false, null, executionContext);
|
||||
JComponent graphViewContainer = dataModelViewFrame.tearOutGraphViewContainer();
|
||||
@@ -2781,7 +2906,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(DataBrowser.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -2789,7 +2914,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
|
||||
protected void resolveSelection(Collection<AssociationModel> selection) {
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
|
||||
disableBorderBrowserUpdates = true;
|
||||
JInternalFrame currentSelection = desktop.getSelectedFrame();
|
||||
@@ -2807,7 +2932,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
disableBorderBrowserUpdates = false;
|
||||
updateBorderBrowser();
|
||||
}
|
||||
@@ -2898,9 +3023,9 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
try {
|
||||
JInternalFrame iFrame = ((TreeNodeForRowBrowser) userObject).rowBrowser.internalFrame;
|
||||
desktop.scrollToCenter(iFrame);
|
||||
desktop.getiFrameStateChangeRenderer().onIFrameSelected(iFrame);
|
||||
iFrame.setSelected(true);
|
||||
iFrame.grabFocus();
|
||||
desktop.getiFrameStateChangeRenderer().onIFrameSelected(iFrame);
|
||||
} catch (PropertyVetoException e1) {
|
||||
// ignore
|
||||
}
|
||||
@@ -3018,12 +3143,18 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
desktop.getiFrameStateChangeRenderer().startAtomic();
|
||||
disableBorderBrowserUpdates = true;
|
||||
suppressUpdateClosureBrowser = true;
|
||||
RowBrowser nextRb = null;
|
||||
while (i > 0) {
|
||||
Table table = path.get(i);
|
||||
RowBrowser rb = getVisibleTables().get(table);
|
||||
RowBrowser rb;
|
||||
if (nextRb != null && nextRb.association != null && nextRb.association.destination.equals(table)) {
|
||||
rb = nextRb;
|
||||
} else {
|
||||
rb = getVisibleTables().get(table);
|
||||
}
|
||||
Association association = associations[i - 1];
|
||||
if (association != null) {
|
||||
rb.browserContentPane.navigateTo(association, -1, null);
|
||||
nextRb = rb.browserContentPane.navigateTo(association, -1, null);
|
||||
visibleTables = null;
|
||||
} else {
|
||||
break;
|
||||
@@ -3065,6 +3196,9 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
}
|
||||
|
||||
private Association[] openAssociationPathPanel(List<Table> path) {
|
||||
if (path.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final AssociationPathPanel assocPanel = new AssociationPathPanel(getDataModel(), path, dependsOn.getForeground(), hasDependent.getForeground(), associatedWith.getForeground(), ignored.getForeground());
|
||||
if (!assocPanel.needToAsk) {
|
||||
return assocPanel.selectedAssociations;
|
||||
@@ -3119,7 +3253,8 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
}
|
||||
|
||||
private MetaDataPanel metaDataPanel;
|
||||
|
||||
private Runnable createMetaDataPanel;
|
||||
|
||||
private void onNewSession(Session newSession) {
|
||||
if (session == null) {
|
||||
return;
|
||||
@@ -3128,7 +3263,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
ConnectionInfo connection = dbConnectionDialog != null ? dbConnectionDialog.currentConnection : null;
|
||||
String alias = connection != null ? " " + connection.alias : " ";
|
||||
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
try {
|
||||
updateNavigationCombobox();
|
||||
|
||||
@@ -3150,150 +3285,7 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
metaDataViewPanel.remove(metaDataDetailsPanel);
|
||||
metaDataDetailsPanel = createMetaDataDetailsPanel(executionContext);
|
||||
metaDataViewPanel.add(metaDataDetailsPanel);
|
||||
|
||||
if (metaDataPanel == null) {
|
||||
metaDataPanel = new MetaDataPanel(this, metaDataSource, metaDataDetailsPanel, datamodel.get(), executionContext) {
|
||||
@Override
|
||||
protected void open(Table table) {
|
||||
if (!selectNavTreeNode(navigationTree.getModel().getRoot(), table)) {
|
||||
if (workbenchTabbedPane.getSelectedComponent() != getCurrentSQLConsole()) {
|
||||
desktop.addTableBrowser(null, null, 0, table, null, "", null, true);
|
||||
}
|
||||
}
|
||||
try {
|
||||
String sql;
|
||||
Quoting quoting = new Quoting(session);
|
||||
MDTable mdTable = getMetaDataSource(session).toMDTable(table);
|
||||
String tableName;
|
||||
String schemaName;
|
||||
if (mdTable != null) {
|
||||
tableName = mdTable.getName();
|
||||
schemaName = mdTable.getSchema().isDefaultSchema? "": mdTable.getSchema().getName();
|
||||
} else {
|
||||
tableName = table.getUnqualifiedName();
|
||||
schemaName = table.getSchema("");
|
||||
}
|
||||
sql = "Select * From " + (schemaName == null || schemaName.length() == 0? "" : quoting.quote(schemaName) + ".") + quoting.quote(tableName);
|
||||
if (workbenchTabbedPane.getSelectedComponent() == getCurrentSQLConsole()) {
|
||||
workbenchTabbedPane.setSelectedComponent(getCurrentSQLConsole());
|
||||
getCurrentSQLConsole().grabFocus();
|
||||
getCurrentSQLConsole().appendStatement(sql, true);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
UIUtil.showException(this, "Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean selectNavTreeNode(Object root, Table table) {
|
||||
if (root instanceof DefaultMutableTreeNode) {
|
||||
Object userObject = ((DefaultMutableTreeNode) root).getUserObject();
|
||||
if (userObject instanceof TreeNodeForRowBrowser) {
|
||||
RowBrowser rowBrowser = ((TreeNodeForRowBrowser) userObject).rowBrowser;
|
||||
if (table.equals(rowBrowser.browserContentPane.table)) {
|
||||
navigationTree.getSelectionModel().setSelectionPath(new TreePath(((DefaultMutableTreeNode) root).getPath()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
int cc = ((DefaultMutableTreeNode) root).getChildCount();
|
||||
for (int i = 0; i < cc; ++i) {
|
||||
if (selectNavTreeNode(((DefaultMutableTreeNode) root).getChildAt(i), table)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean selectNavTreeNode(Object root, MDTable mdTable) {
|
||||
if (root instanceof DefaultMutableTreeNode) {
|
||||
Object userObject = ((DefaultMutableTreeNode) root).getUserObject();
|
||||
if (userObject instanceof TreeNodeForRowBrowser) {
|
||||
RowBrowser rowBrowser = ((TreeNodeForRowBrowser) userObject).rowBrowser;
|
||||
if (mdTable.equals(rowBrowser.getMDTable())) {
|
||||
navigationTree.getSelectionModel().setSelectionPath(new TreePath(((DefaultMutableTreeNode) root).getPath()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
int cc = ((DefaultMutableTreeNode) root).getChildCount();
|
||||
for (int i = 0; i < cc; ++i) {
|
||||
if (selectNavTreeNode(((DefaultMutableTreeNode) root).getChildAt(i), mdTable)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void analyseSchema(String schemaName) {
|
||||
updateDataModel(schemaName, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void open(MDTable mdTable) {
|
||||
String schemaName = mdTable.getSchema().isDefaultSchema? null : mdTable.getSchema().getName();
|
||||
String tableName = mdTable.getName();
|
||||
try {
|
||||
Quoting quoting = new Quoting(session);
|
||||
String sql = "Select * From " + (schemaName == null? "" : quoting.quote(schemaName) + ".") + quoting.quote(tableName);
|
||||
if (!selectNavTreeNode(navigationTree.getModel().getRoot(), mdTable)
|
||||
|| workbenchTabbedPane.getSelectedComponent() == getCurrentSQLConsole()) {
|
||||
workbenchTabbedPane.setSelectedComponent(getCurrentSQLConsole());
|
||||
getCurrentSQLConsole().grabFocus();
|
||||
getCurrentSQLConsole().appendStatement(sql, true);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
UIUtil.showException(this, "Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendScript(String script, boolean execute) {
|
||||
try {
|
||||
workbenchTabbedPane.setSelectedComponent(getCurrentSQLConsole());
|
||||
getCurrentSQLConsole().grabFocus();
|
||||
getCurrentSQLConsole().appendStatement(script, execute);
|
||||
} catch (Throwable e) {
|
||||
UIUtil.showException(this, "Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTableSelect(MDTable mdTable) {
|
||||
metaDataDetailsPanel
|
||||
.showMetaDataDetails(mdTable, getMetaDataSource(session).toTable(mdTable), datamodel.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMDOtherSelect(MDGeneric mdOther, ExecutionContext executionContext) {
|
||||
metaDataDetailsPanel
|
||||
.showMetaDataDetails(mdOther, executionContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSchemaSelect(MDSchema mdSchema) {
|
||||
metaDataDetailsPanel.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void openNewTableBrowser() {
|
||||
DataBrowser.this.openNewTableBrowser(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateDataModelView(Table table) {
|
||||
DataBrowser.this.updateDataModelView(table);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCaretPosition(int position) {
|
||||
getCurrentSQLConsole().setCaretPosition(position);
|
||||
}
|
||||
};
|
||||
}
|
||||
session.setSessionProperty(getClass(), "metaDataPanel", metaDataPanel);
|
||||
tablesPanel.add(metaDataPanel, java.awt.BorderLayout.CENTER);
|
||||
|
||||
try {
|
||||
if (sqlConsoles.isEmpty()) {
|
||||
createNewSQLConsole(metaDataSource);
|
||||
@@ -3306,9 +3298,163 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
final MetaDataSource fMetaDataSource = metaDataSource;
|
||||
createMetaDataPanel = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (metaDataPanel == null) {
|
||||
metaDataPanel = new MetaDataPanel(DataBrowser.this, fMetaDataSource, metaDataDetailsPanel, datamodel.get(), executionContext) {
|
||||
@Override
|
||||
protected void open(Table table) {
|
||||
if (!selectNavTreeNode(navigationTree.getModel().getRoot(), table)) {
|
||||
if (workbenchTabbedPane.getSelectedComponent() != getCurrentSQLConsole()) {
|
||||
desktop.addTableBrowser(null, null, 0, table, null, "", null, true);
|
||||
}
|
||||
}
|
||||
try {
|
||||
String sql;
|
||||
Quoting quoting = new Quoting(session);
|
||||
MDTable mdTable = getMetaDataSource(session).toMDTable(table);
|
||||
String tableName;
|
||||
String schemaName;
|
||||
if (mdTable != null) {
|
||||
tableName = mdTable.getName();
|
||||
schemaName = mdTable.getSchema().isDefaultSchema? "": mdTable.getSchema().getName();
|
||||
} else {
|
||||
tableName = table.getUnqualifiedName();
|
||||
schemaName = table.getSchema("");
|
||||
}
|
||||
sql = "Select * From " + (schemaName == null || schemaName.length() == 0? "" : quoting.quote(schemaName) + ".") + quoting.quote(tableName);
|
||||
if (workbenchTabbedPane.getSelectedComponent() == getCurrentSQLConsole()) {
|
||||
workbenchTabbedPane.setSelectedComponent(getCurrentSQLConsole());
|
||||
getCurrentSQLConsole().grabFocus();
|
||||
getCurrentSQLConsole().appendStatement(sql, true);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
UIUtil.showException(this, "Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean selectNavTreeNode(Object root, Table table) {
|
||||
if (root instanceof DefaultMutableTreeNode) {
|
||||
Object userObject = ((DefaultMutableTreeNode) root).getUserObject();
|
||||
if (userObject instanceof TreeNodeForRowBrowser) {
|
||||
RowBrowser rowBrowser = ((TreeNodeForRowBrowser) userObject).rowBrowser;
|
||||
if (table.equals(rowBrowser.browserContentPane.table)) {
|
||||
navigationTree.getSelectionModel().setSelectionPath(new TreePath(((DefaultMutableTreeNode) root).getPath()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
int cc = ((DefaultMutableTreeNode) root).getChildCount();
|
||||
for (int i = 0; i < cc; ++i) {
|
||||
if (selectNavTreeNode(((DefaultMutableTreeNode) root).getChildAt(i), table)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean selectNavTreeNode(Object root, MDTable mdTable) {
|
||||
if (root instanceof DefaultMutableTreeNode) {
|
||||
Object userObject = ((DefaultMutableTreeNode) root).getUserObject();
|
||||
if (userObject instanceof TreeNodeForRowBrowser) {
|
||||
RowBrowser rowBrowser = ((TreeNodeForRowBrowser) userObject).rowBrowser;
|
||||
if (mdTable.equals(rowBrowser.getMDTable())) {
|
||||
navigationTree.getSelectionModel().setSelectionPath(new TreePath(((DefaultMutableTreeNode) root).getPath()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
int cc = ((DefaultMutableTreeNode) root).getChildCount();
|
||||
for (int i = 0; i < cc; ++i) {
|
||||
if (selectNavTreeNode(((DefaultMutableTreeNode) root).getChildAt(i), mdTable)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void analyseSchema(String schemaName) {
|
||||
updateDataModel(schemaName, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void open(MDTable mdTable) {
|
||||
String schemaName = mdTable.getSchema().isDefaultSchema? null : mdTable.getSchema().getName();
|
||||
String tableName = mdTable.getName();
|
||||
try {
|
||||
Quoting quoting = new Quoting(session);
|
||||
String sql = "Select * From " + (schemaName == null? "" : quoting.quote(schemaName) + ".") + quoting.quote(tableName);
|
||||
if (!selectNavTreeNode(navigationTree.getModel().getRoot(), mdTable)
|
||||
|| workbenchTabbedPane.getSelectedComponent() == getCurrentSQLConsole()) {
|
||||
workbenchTabbedPane.setSelectedComponent(getCurrentSQLConsole());
|
||||
getCurrentSQLConsole().grabFocus();
|
||||
getCurrentSQLConsole().appendStatement(sql, true);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
UIUtil.showException(this, "Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendScript(String script, boolean execute) {
|
||||
try {
|
||||
workbenchTabbedPane.setSelectedComponent(getCurrentSQLConsole());
|
||||
getCurrentSQLConsole().grabFocus();
|
||||
getCurrentSQLConsole().appendStatement(script, execute);
|
||||
} catch (Throwable e) {
|
||||
UIUtil.showException(this, "Error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTableSelect(MDTable mdTable) {
|
||||
metaDataDetailsPanel
|
||||
.showMetaDataDetails(mdTable, getMetaDataSource(session).toTable(mdTable), datamodel.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMDOtherSelect(MDGeneric mdOther, ExecutionContext executionContext) {
|
||||
metaDataDetailsPanel
|
||||
.showMetaDataDetails(mdOther, executionContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSchemaSelect(MDSchema mdSchema) {
|
||||
metaDataDetailsPanel.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void openNewTableBrowser() {
|
||||
DataBrowser.this.openNewTableBrowser(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateDataModelView(Table table) {
|
||||
DataBrowser.this.updateDataModelView(table);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setCaretPosition(int position) {
|
||||
getCurrentSQLConsole().setCaretPosition(position);
|
||||
}
|
||||
};
|
||||
}
|
||||
session.setSessionProperty(getClass(), "metaDataPanel", metaDataPanel);
|
||||
tablesPanel.add(metaDataPanel, java.awt.BorderLayout.CENTER);
|
||||
createMetaDataPanel = null;
|
||||
}
|
||||
};
|
||||
|
||||
if (tableTreesTabbedPane.getSelectedComponent() == tablesPanel) {
|
||||
createMetaDataPanel.run();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3326,17 +3472,23 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
|
||||
@Override
|
||||
protected void refreshMetaData() {
|
||||
metaDataPanel.reset();
|
||||
if (metaDataPanel != null) {
|
||||
metaDataPanel.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void selectTable(MDTable mdTable) {
|
||||
metaDataPanel.select(mdTable);
|
||||
if (metaDataPanel != null) {
|
||||
metaDataPanel.select(mdTable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setOutlineTables(List<OutlineInfo> outlineTables, int indexOfInfoAtCaret) {
|
||||
metaDataPanel.setOutline(outlineTables, indexOfInfoAtCaret);
|
||||
if (metaDataPanel != null) {
|
||||
metaDataPanel.setOutline(outlineTables, indexOfInfoAtCaret);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3474,12 +3626,12 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
}
|
||||
}
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
createNewSQLConsole(getMetaDataSource()).loadFromFile(file);
|
||||
} catch (Throwable e) {
|
||||
UIUtil.showException(this, "Error", e, session);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3490,12 +3642,12 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
saveScriptAsMenuItemActionPerformed(evt);
|
||||
} else {
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
sqlConsole.storeToFile(null);
|
||||
} catch (Throwable e) {
|
||||
UIUtil.showException(this, "Error", e, session);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3508,12 +3660,12 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
if (fName != null) {
|
||||
File file = new File(fName);
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(this);
|
||||
sqlConsole.storeToFile(file);
|
||||
} catch (Throwable e) {
|
||||
UIUtil.showException(this, "Error", e, session);
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3659,7 +3811,9 @@ public class DataBrowser extends javax.swing.JFrame {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private DesktopAnchorManager anchorManager;
|
||||
|
||||
private ImageIcon tableIcon;
|
||||
private ImageIcon databaseIcon;
|
||||
private ImageIcon redIcon;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright 2007 - 2018 the original author or authors.
|
||||
*
|
||||
* 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 net.sf.jailer.ui.databrowser;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.InternalFrameEvent;
|
||||
import javax.swing.event.InternalFrameListener;
|
||||
import javax.swing.plaf.basic.BasicInternalFrameUI;
|
||||
|
||||
import net.sf.jailer.ui.databrowser.Desktop.RowBrowser;
|
||||
|
||||
/**
|
||||
* Desktop Anchor Manager.
|
||||
*
|
||||
* @author Ralf Wisser
|
||||
*/
|
||||
public abstract class DesktopAnchorManager {
|
||||
|
||||
private final JPanel anchorPanel;
|
||||
private final JButton anchorButton;
|
||||
private Long disabledUntil;
|
||||
private Long showedAt;
|
||||
private RowBrowser currentBrowser;
|
||||
private RowBrowser newestBrowser;
|
||||
private final static int MAX_RETENDION = 2000;
|
||||
|
||||
public DesktopAnchorManager(JPanel anchorPanel) {
|
||||
this.anchorPanel = anchorPanel;
|
||||
this.anchorButton = new JButton(anchorIcon);
|
||||
|
||||
this.anchorPanel.setVisible(false);
|
||||
|
||||
anchorPanel.add(anchorButton);
|
||||
anchorButton.setToolTipText("align horizontally with predecessors");
|
||||
anchorButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (currentBrowser != null) {
|
||||
reset(1000);
|
||||
layout(currentBrowser);
|
||||
}
|
||||
}
|
||||
});
|
||||
anchorButton.addMouseListener(new MouseListener() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
showedAt = System.currentTimeMillis();
|
||||
}
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
showedAt = null;
|
||||
}
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onNewTableBrowser(final RowBrowser tableBrowser) {
|
||||
newestBrowser = tableBrowser;
|
||||
tableBrowser.internalFrame.addInternalFrameListener(new InternalFrameListener() {
|
||||
@Override
|
||||
public void internalFrameOpened(InternalFrameEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalFrameIconified(InternalFrameEvent e) {
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalFrameDeiconified(InternalFrameEvent e) {
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalFrameDeactivated(InternalFrameEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalFrameClosing(InternalFrameEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalFrameClosed(InternalFrameEvent e) {
|
||||
reset();
|
||||
newestBrowser = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalFrameActivated(InternalFrameEvent e) {
|
||||
}
|
||||
});
|
||||
MouseListener showButton = new MouseListener() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
if (isApplicable(tableBrowser)) {
|
||||
showButton(tableBrowser);
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
};
|
||||
tableBrowser.browserContentPane.menuPanel.addMouseListener(showButton);
|
||||
|
||||
Stack<JPanel> panels = new Stack<JPanel>();
|
||||
panels.add(tableBrowser.browserContentPane.menuPanel);
|
||||
while (!panels.isEmpty()) {
|
||||
JPanel panel = panels.pop();
|
||||
synchronized (panel.getTreeLock()) {
|
||||
for (Component comp: panel.getComponents()) {
|
||||
if (comp instanceof JPanel) {
|
||||
if (comp != tableBrowser.browserContentPane.sqlPanel) {
|
||||
if (comp != tableBrowser.browserContentPane.relatedRowsPanel) {
|
||||
panels.push((JPanel) comp);
|
||||
}
|
||||
}
|
||||
} else if (comp instanceof JLabel) {
|
||||
comp.addMouseListener(showButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tableBrowser.browserContentPane.addMouseListener(showButton);
|
||||
tableBrowser.browserContentPane.sqlPanel.addMouseListener(showButton);
|
||||
tableBrowser.browserContentPane.relatedRowsPanel.addMouseListener(showButton);
|
||||
tableBrowser.browserContentPane.loadButton.addMouseListener(showButton);
|
||||
tableBrowser.browserContentPane.rowsTable.addMouseListener(showButton);
|
||||
if (tableBrowser.browserContentPane.thumbnail != null) {
|
||||
tableBrowser.browserContentPane.thumbnail.addMouseListener(showButton);
|
||||
}
|
||||
if (tableBrowser.browserContentPane.andCondition.getEditor() != null) {
|
||||
if (tableBrowser.browserContentPane.andCondition.getEditor().getEditorComponent() != null) {
|
||||
tableBrowser.browserContentPane.andCondition.getEditor().getEditorComponent().addMouseListener(showButton);
|
||||
}
|
||||
}
|
||||
Object bi = tableBrowser.internalFrame.getUI();
|
||||
if (bi instanceof BasicInternalFrameUI) {
|
||||
JComponent northPane = ((BasicInternalFrameUI) bi).getNorthPane();
|
||||
if (northPane != null) {
|
||||
northPane.addMouseListener(showButton);
|
||||
}
|
||||
}
|
||||
tableBrowser.internalFrame.addComponentListener(new ComponentListener() {
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
}
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
reset(100);
|
||||
}
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
reset(100);
|
||||
}
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
reset();
|
||||
}
|
||||
});
|
||||
reset();
|
||||
}
|
||||
|
||||
protected void showButton(RowBrowser tableBrowser) {
|
||||
if (disabledUntil != null && disabledUntil > System.currentTimeMillis()) {
|
||||
return;
|
||||
}
|
||||
currentBrowser = tableBrowser;
|
||||
anchorButton.setSize(anchorButton.getPreferredSize());
|
||||
anchorPanel.setSize(anchorButton.getPreferredSize());
|
||||
Point loc;
|
||||
loc = tableBrowser.internalFrame.getLocation();
|
||||
loc.translate(-anchorButton.getWidth(), 0);
|
||||
anchorPanel.setLocation(0, 0);
|
||||
loc = SwingUtilities.convertPoint(tableBrowser.internalFrame.getParent(), loc, anchorPanel);
|
||||
anchorPanel.setLocation(loc);
|
||||
anchorButton.setVisible(true);
|
||||
anchorPanel.setVisible(true);
|
||||
showedAt = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
reset(0);
|
||||
}
|
||||
|
||||
void reset(int delay) {
|
||||
anchorButton.setVisible(false);
|
||||
anchorPanel.setVisible(false);
|
||||
if (delay > 0) {
|
||||
disabledUntil = System.currentTimeMillis() + delay;
|
||||
}
|
||||
}
|
||||
|
||||
public RowBrowser getNewestBrowser() {
|
||||
return newestBrowser;
|
||||
}
|
||||
|
||||
public void setNewestBrowser(RowBrowser browser) {
|
||||
newestBrowser = browser;
|
||||
}
|
||||
|
||||
public void checkRetention() {
|
||||
long now = System.currentTimeMillis();
|
||||
if (showedAt != null && showedAt + MAX_RETENDION < now) {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void layout(RowBrowser anchor);
|
||||
protected abstract boolean isApplicable(RowBrowser tableBrowser);
|
||||
|
||||
private ImageIcon anchorIcon;
|
||||
{
|
||||
String dir = "/net/sf/jailer/ui/resource";
|
||||
|
||||
// load images
|
||||
try {
|
||||
anchorIcon = new ImageIcon(DataBrowser.class.getResource(dir + "/anchor.png"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright 2007 - 2018 the original author or authors.
|
||||
*
|
||||
* 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 net.sf.jailer.ui.databrowser;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import net.sf.jailer.ui.UIUtil;
|
||||
|
||||
/**
|
||||
* Animates layout changes of {@link Desktop}.
|
||||
*
|
||||
* @author Ralf Wisser
|
||||
*/
|
||||
public class DesktopAnimation {
|
||||
|
||||
private final double DURATION = 750;
|
||||
private final Desktop desktop;
|
||||
|
||||
/**
|
||||
* Animation.
|
||||
*/
|
||||
abstract class Animation {
|
||||
private long startTime;
|
||||
public void start() {
|
||||
startTime = System.currentTimeMillis();
|
||||
stopScrolling = false;
|
||||
}
|
||||
abstract boolean animate(double f);
|
||||
};
|
||||
|
||||
/**
|
||||
* Animation per subject (started).
|
||||
*/
|
||||
private Map<Object, Animation> animations = Collections.synchronizedMap(new LinkedHashMap<Object, Animation>());
|
||||
|
||||
/**
|
||||
* Animation per subject (waiting).
|
||||
*/
|
||||
private Map<Object, Animation> waiting = new LinkedHashMap<Object, Animation>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param desktop the desktop
|
||||
*/
|
||||
public DesktopAnimation(Desktop desktop) {
|
||||
this.desktop = desktop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls desktop to a given location.
|
||||
*/
|
||||
class ScrollTo extends Animation {
|
||||
private final Point scrollFrom;
|
||||
private final int initialWidth;
|
||||
private final int initialHeight;
|
||||
private final Rectangle scrollTo;
|
||||
|
||||
public ScrollTo(Rectangle scrollTo, Point scrollFrom, int initialWidth, int initialHeight) {
|
||||
this.scrollFrom = scrollFrom;
|
||||
this.initialWidth = initialWidth;
|
||||
this.initialHeight = initialHeight;
|
||||
this.scrollTo = scrollTo;
|
||||
}
|
||||
|
||||
public boolean animate(double f) {
|
||||
if (stopScrolling) {
|
||||
return false;
|
||||
}
|
||||
if (scrollTo != null) {
|
||||
int w = wAvg(f, initialWidth, scrollTo.width);
|
||||
int h = wAvg(f, initialHeight, scrollTo.height);
|
||||
int x = (int) (scrollFrom.x + f * (scrollTo.x + scrollTo.width / 2 - scrollFrom.x)) - w / 2;
|
||||
int y = (int) (scrollFrom.y + f * (scrollTo.y + scrollTo.height / 2 - scrollFrom.y)) - h / 2;
|
||||
desktop.checkDesktopSize();
|
||||
desktop.scrollRectToVisible(new Rectangle(x, y, w, h));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves an internal frame of the desktop.
|
||||
*/
|
||||
class MoveIFrame extends Animation {
|
||||
private final JInternalFrame iFrame;
|
||||
private final Rectangle moveTo;
|
||||
private final Rectangle moveFrom;
|
||||
private final BrowserContentPane browserContentPane;
|
||||
|
||||
public MoveIFrame(JInternalFrame iFrame, BrowserContentPane browserContentPane, Rectangle moveTo) {
|
||||
this.iFrame = iFrame;
|
||||
this.browserContentPane = browserContentPane;
|
||||
this.moveTo = moveTo;
|
||||
this.moveFrom = iFrame.getBounds();
|
||||
}
|
||||
|
||||
public boolean animate(double f) {
|
||||
int wx = wAvg(f, moveFrom.x, moveTo.x);
|
||||
int wy = wAvg(f, moveFrom.y, moveTo.y);
|
||||
int ww = wAvg(f, moveFrom.width, moveTo.width);
|
||||
int wh = wAvg(f, moveFrom.height, moveTo.height);
|
||||
if (f < 1.0 && Math.abs(ww - iFrame.getWidth()) < 4 && Math.abs(wh - iFrame.getHeight()) < 4) {
|
||||
iFrame.setLocation(wx, wy);
|
||||
} else {
|
||||
iFrame.setBounds(wx, wy, ww, wh);
|
||||
}
|
||||
if (f == 1.0) {
|
||||
browserContentPane.adjustRowTableColumnsWidth();
|
||||
}
|
||||
return !(wx == moveTo.x && wy == moveTo.y && ww == moveTo.width && wh == moveTo.height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an animation step for each animation.
|
||||
*/
|
||||
public boolean animate() {
|
||||
boolean result = false;
|
||||
for (Iterator<Entry<Object, Animation>> i = animations.entrySet().iterator(); i.hasNext(); ) {
|
||||
Animation animation = i.next().getValue();
|
||||
double f = (System.currentTimeMillis() - animation.startTime) / DURATION;
|
||||
double fs;
|
||||
|
||||
if (f > 1.0) {
|
||||
f = 1.0;
|
||||
fs = 1.0;
|
||||
} else {
|
||||
final double M1 = -3;
|
||||
final double M2 = 5;
|
||||
fs = sig(f * (-M1 + M2) + M1);
|
||||
}
|
||||
|
||||
if (!animation.animate(fs)) {
|
||||
i.remove();
|
||||
continue;
|
||||
}
|
||||
result = true;
|
||||
|
||||
if (f == 1.0) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
desktop.checkDesktopSize();
|
||||
return result;
|
||||
}
|
||||
|
||||
private double sig(double x) {
|
||||
return 1.0 / (1.0 + Math.exp(-x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls desktop to a given location (animated).
|
||||
*
|
||||
* @param vr the location
|
||||
*/
|
||||
public void scrollRectToVisible(Rectangle vr) {
|
||||
Rectangle svr = desktop.getScrollPane().getViewport().getViewRect();
|
||||
if (!svr.contains(vr)) {
|
||||
int mx = vr.x + vr.width / 2;
|
||||
int my = vr.y + vr.height / 2;
|
||||
if (mx < svr.x) {
|
||||
mx = svr.x;
|
||||
}
|
||||
if (my < svr.y) {
|
||||
my = svr.y;
|
||||
}
|
||||
if (mx > svr.x + svr.width) {
|
||||
mx = svr.x + svr.width;
|
||||
}
|
||||
if (my > svr.y + svr.height) {
|
||||
my = svr.y + svr.height;
|
||||
}
|
||||
startAnimation(desktop, new ScrollTo(vr, new Point(mx, my), 2 * Math.min(mx - svr.x, svr.x + svr.width - mx), 2 * Math.min(my - svr.y, svr.y + svr.height - my)));
|
||||
} else {
|
||||
waiting.remove(desktop);
|
||||
animations.remove(desktop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls desktop to a given location (immediately).
|
||||
*
|
||||
* @param vr the location
|
||||
*/
|
||||
public void scrollRectToVisibleImmediately(Rectangle vr) {
|
||||
desktop.scrollRectToVisible(vr);
|
||||
waiting.remove(desktop);
|
||||
animations.remove(desktop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bounds of an internal frame (animated).
|
||||
*
|
||||
* @param iFrame the frame
|
||||
* @param browserContentPane the content pane
|
||||
* @param r new bounds
|
||||
*/
|
||||
public void setIFrameBounds(JInternalFrame iFrame, BrowserContentPane browserContentPane, Rectangle r) {
|
||||
startAnimation(iFrame, new MoveIFrame(iFrame, browserContentPane, r));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bounds of an internal frame (immediately).
|
||||
*
|
||||
* @param iFrame the frame
|
||||
* @param browserContentPane the content pane
|
||||
* @param r new bounds
|
||||
*/
|
||||
public void setIFrameBoundsImmediately(JInternalFrame internalFrame, BrowserContentPane browserContentPane, Rectangle newBounds) {
|
||||
internalFrame.setBounds(newBounds);
|
||||
browserContentPane.adjustRowTableColumnsWidth();
|
||||
waiting.remove(internalFrame);
|
||||
animations.remove(internalFrame);
|
||||
}
|
||||
|
||||
public Rectangle getIFrameBounds(JInternalFrame iFrame) {
|
||||
Animation animation = animations.get(iFrame);
|
||||
if (animation instanceof MoveIFrame) {
|
||||
return ((MoveIFrame) animation).moveTo;
|
||||
}
|
||||
animation = waiting.get(iFrame);
|
||||
if (animation instanceof MoveIFrame) {
|
||||
return ((MoveIFrame) animation).moveTo;
|
||||
}
|
||||
return iFrame.getBounds();
|
||||
}
|
||||
|
||||
private int wAvg(double f, int a, int b) {
|
||||
return (int) (a + f * (b - a));
|
||||
}
|
||||
|
||||
private void startAnimation(Object key, Animation animation) {
|
||||
Component desktopAncestor = SwingUtilities.getWindowAncestor(desktop);
|
||||
if (desktopAncestor == null) {
|
||||
desktopAncestor = desktop;
|
||||
}
|
||||
final Component fDesktopAncestor = desktopAncestor;
|
||||
UIUtil.setWaitCursor(desktopAncestor);
|
||||
waiting.put(key, animation);
|
||||
UIUtil.invokeLater(12, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UIUtil.resetWaitCursor(fDesktopAncestor);
|
||||
for (Entry<Object, Animation> e: waiting.entrySet()) {
|
||||
e.getValue().start();
|
||||
animations.put(e.getKey(), e.getValue());
|
||||
}
|
||||
waiting.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean stopScrolling = false;
|
||||
|
||||
public boolean isActive() {
|
||||
return !animations.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,7 +39,7 @@ import net.sf.jailer.ui.UIUtil;
|
||||
*/
|
||||
public class DesktopIFrameStateChangeRenderer {
|
||||
|
||||
private final double DURATION = 1000.0;
|
||||
private final double DURATION = 1500.0;
|
||||
private List<JInternalFrame> atomicBlock = null;
|
||||
|
||||
private class StateChange {
|
||||
@@ -70,16 +70,23 @@ public class DesktopIFrameStateChangeRenderer {
|
||||
onIFrameSelected(iFrame, 0);
|
||||
}
|
||||
|
||||
public void onIFrameSelected(JInternalFrame iFrame, double factorOffset) {
|
||||
public void onIFrameSelected(final JInternalFrame iFrame, final double factorOffset) {
|
||||
if (atomicBlock == null) {
|
||||
StateChange stateChange = new StateChange();
|
||||
stateChange.iFrame = iFrame;
|
||||
stateChange.startTime = System.currentTimeMillis();
|
||||
stateChange.factorOffset = factorOffset;
|
||||
stateChanges.put(iFrame, stateChange);
|
||||
UIUtil.invokeLater(12, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!stateChanges.containsKey(iFrame)) {
|
||||
StateChange stateChange = new StateChange();
|
||||
stateChange.iFrame = iFrame;
|
||||
stateChange.startTime = System.currentTimeMillis();
|
||||
stateChange.factorOffset = factorOffset;
|
||||
stateChanges.put(iFrame, stateChange);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void render(Graphics2D g2d) {
|
||||
for (Iterator<Entry<JInternalFrame, StateChange>> iter = stateChanges.entrySet().iterator(); iter.hasNext(); ) {
|
||||
StateChange stateChange = iter.next().getValue();
|
||||
@@ -94,25 +101,27 @@ public class DesktopIFrameStateChangeRenderer {
|
||||
factor = 0;
|
||||
}
|
||||
|
||||
Color color = new Color(255, 255, 0, (int) (170 * (1 - factor)));
|
||||
g2d.setColor(color);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
double width = stateChange.iFrame.getWidth() / 12 * ((factor - stateChange.factorOffset) / (1 - stateChange.factorOffset) + 0.1);
|
||||
BasicStroke stroke = new BasicStroke((float) width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
|
||||
g2d.setStroke(stroke);
|
||||
|
||||
Rectangle rect = stateChange.iFrame.getBounds();
|
||||
int w = (int) (0.5 * width);
|
||||
rect = new Rectangle(rect.x + w / 2, rect.y + w / 2, rect.width - w, rect.height - w);
|
||||
|
||||
Path2D.Double path = new Path2D.Double();
|
||||
path.moveTo(rect.getX(), rect.getY());
|
||||
path.lineTo(rect.getX() + rect.getWidth(), rect.getY());
|
||||
path.lineTo(rect.getX() + rect.getWidth(), rect.getY() + rect.getHeight());
|
||||
path.lineTo(rect.getX(), rect.getY() + rect.getHeight());
|
||||
path.lineTo(rect.getX(), rect.getY());
|
||||
|
||||
g2d.draw(path);
|
||||
if (stateChange.iFrame.isVisible()) {
|
||||
Color color = new Color(255, 255, 0, (int) (170 * (1 - factor)));
|
||||
g2d.setColor(color);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
double width = stateChange.iFrame.getWidth() / 12 * ((factor - stateChange.factorOffset) / (1 - stateChange.factorOffset) + 0.1);
|
||||
BasicStroke stroke = new BasicStroke((float) width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
|
||||
g2d.setStroke(stroke);
|
||||
|
||||
Rectangle rect = stateChange.iFrame.getBounds();
|
||||
int w = (int) (0.5 * width);
|
||||
rect = new Rectangle(rect.x + w / 2, rect.y + w / 2, rect.width - w, rect.height - w);
|
||||
|
||||
Path2D.Double path = new Path2D.Double();
|
||||
path.moveTo(rect.getX(), rect.getY());
|
||||
path.lineTo(rect.getX() + rect.getWidth(), rect.getY());
|
||||
path.lineTo(rect.getX() + rect.getWidth(), rect.getY() + rect.getHeight());
|
||||
path.lineTo(rect.getX(), rect.getY() + rect.getHeight());
|
||||
path.lineTo(rect.getX(), rect.getY());
|
||||
|
||||
g2d.draw(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package net.sf.jailer.ui.databrowser;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
@@ -132,8 +133,7 @@ public abstract class DetailsView extends javax.swing.JPanel {
|
||||
@Override
|
||||
public void ancestorAdded(AncestorEvent event) {
|
||||
closeButton.grabFocus();
|
||||
jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMinimum());
|
||||
jScrollPane1.getHorizontalScrollBar().setValue(jScrollPane1.getHorizontalScrollBar().getMinimum());
|
||||
resetScrollPane();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -158,7 +158,8 @@ public abstract class DetailsView extends javax.swing.JPanel {
|
||||
private int currentRow;
|
||||
private boolean sortColumns;
|
||||
private JPanel content;
|
||||
|
||||
private boolean isPacked = false;
|
||||
|
||||
private void setCurrentRow(int row, boolean selectableFields) {
|
||||
currentRow = row;
|
||||
|
||||
@@ -167,7 +168,7 @@ public abstract class DetailsView extends javax.swing.JPanel {
|
||||
labels.clear();
|
||||
labelColors.clear();
|
||||
|
||||
JPanel oldContent = content;
|
||||
final JPanel oldContent = content;
|
||||
content = new JPanel(new GridBagLayout());
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.weightx = 1;
|
||||
@@ -271,12 +272,30 @@ public abstract class DetailsView extends javax.swing.JPanel {
|
||||
gridBagConstraints.gridy = i;
|
||||
content.add(l, gridBagConstraints);
|
||||
}
|
||||
jPanel1.add(content, gridBagConstraints);
|
||||
if (oldContent != null) {
|
||||
jPanel1.remove(oldContent);
|
||||
Runnable update = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (oldContent != null) {
|
||||
jPanel1.remove(oldContent);
|
||||
}
|
||||
GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.weightx = 1;
|
||||
gridBagConstraints.weighty = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
jPanel1.add(content, gridBagConstraints);
|
||||
jPanel1.revalidate();
|
||||
jPanel1.repaint();
|
||||
}
|
||||
};
|
||||
if (isPacked) {
|
||||
UIUtil.invokeLater(2, update);
|
||||
} else {
|
||||
update.run();
|
||||
isPacked = true;
|
||||
}
|
||||
jPanel1.revalidate();
|
||||
jPanel1.repaint();
|
||||
onRowChanged(row);
|
||||
}
|
||||
|
||||
@@ -370,6 +389,12 @@ public abstract class DetailsView extends javax.swing.JPanel {
|
||||
private void sortCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sortCheckBoxActionPerformed
|
||||
sortColumns = !sortColumns;
|
||||
setCurrentRow(currentRow, showSpinner);
|
||||
UIUtil.invokeLater(4, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
resetScrollPane();
|
||||
}
|
||||
});
|
||||
}//GEN-LAST:event_sortCheckBoxActionPerformed
|
||||
|
||||
private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
|
||||
@@ -412,4 +437,9 @@ public abstract class DetailsView extends javax.swing.JPanel {
|
||||
setCurrentRow(currentRow, showSpinner);
|
||||
}
|
||||
|
||||
private void resetScrollPane() {
|
||||
jScrollPane1.getVerticalScrollBar().setValue(jScrollPane1.getVerticalScrollBar().getMinimum());
|
||||
jScrollPane1.getHorizontalScrollBar().setValue(jScrollPane1.getHorizontalScrollBar().getMinimum());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -204,7 +204,6 @@ public class SbEDialog extends javax.swing.JDialog {
|
||||
}//GEN-LAST:event_jButton3ActionPerformed
|
||||
|
||||
private void regardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_regardButtonActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_regardButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package net.sf.jailer.ui.databrowser;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Window;
|
||||
import java.io.File;
|
||||
@@ -36,6 +35,7 @@ import net.sf.jailer.modelbuilder.JDBCMetaDataBasedModelElementFinder;
|
||||
import net.sf.jailer.ui.DbConnectionDialog;
|
||||
import net.sf.jailer.ui.Environment;
|
||||
import net.sf.jailer.ui.JComboBox;
|
||||
import net.sf.jailer.ui.UIUtil;
|
||||
|
||||
/**
|
||||
* Schema Mapping Dialog.
|
||||
@@ -58,7 +58,7 @@ public class SchemaMappingDialog extends javax.swing.JDialog {
|
||||
Window windowAncestor = parent; // SwingUtilities.getWindowAncestor(parent);
|
||||
try {
|
||||
if (windowAncestor != null) {
|
||||
windowAncestor.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(windowAncestor);
|
||||
}
|
||||
String defSchema = JDBCMetaDataBasedModelElementFinder.getDefaultSchema(session, session.getSchema());
|
||||
if (!defSchema.isEmpty()) {
|
||||
@@ -108,7 +108,7 @@ public class SchemaMappingDialog extends javax.swing.JDialog {
|
||||
}
|
||||
} finally {
|
||||
if (windowAncestor != null) {
|
||||
windowAncestor.setCursor(Cursor.getDefaultCursor());
|
||||
UIUtil.resetWaitCursor(windowAncestor);
|
||||
}
|
||||
}
|
||||
pack();
|
||||
|
||||
@@ -29,6 +29,7 @@ public class TreeLayoutOptimizer<T> {
|
||||
public static class Node<T> {
|
||||
private final T userObject;
|
||||
private final List<Node<T>> children = new ArrayList<Node<T>>();
|
||||
private final boolean isAnchor;
|
||||
int level = 0;
|
||||
Node<T> parent = null;
|
||||
double position = 0;
|
||||
@@ -37,8 +38,9 @@ public class TreeLayoutOptimizer<T> {
|
||||
return userObject;
|
||||
}
|
||||
|
||||
public Node(T userObject) {
|
||||
public Node(T userObject, boolean isAnchor) {
|
||||
this.userObject = userObject;
|
||||
this.isAnchor = isAnchor;
|
||||
}
|
||||
|
||||
public void addChild(Node<T> child) {
|
||||
@@ -67,6 +69,21 @@ public class TreeLayoutOptimizer<T> {
|
||||
return 1 + maxChildDepth;
|
||||
}
|
||||
|
||||
public double getMinPosition() {
|
||||
double minPos = position;
|
||||
for (Node<T> child: children) {
|
||||
minPos = Math.min(minPos, child.getMinPosition());
|
||||
}
|
||||
return minPos;
|
||||
}
|
||||
|
||||
public void adjustPosition(double delta) {
|
||||
position -= delta;
|
||||
for (Node<T> child: children) {
|
||||
child.adjustPosition(delta);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNodesCount() {
|
||||
int count = 1;
|
||||
for (Node<T> child: children) {
|
||||
@@ -77,15 +94,36 @@ public class TreeLayoutOptimizer<T> {
|
||||
|
||||
public double getCompactness() {
|
||||
double compactness = 0;
|
||||
if (children.size() > 1) {
|
||||
if (children.size() > 0) {
|
||||
compactness = children.get(children.size() - 1).position - children.get(0).position;
|
||||
compactness *= compactness;
|
||||
Node<T> pre = null;
|
||||
for (Node<T> child: children) {
|
||||
compactness += child.getCompactness();
|
||||
if (pre != null) {
|
||||
if (pre.position + 1 > child.position) {
|
||||
double w = pre.position + 1 - child.position;
|
||||
compactness += w * w * 1000;
|
||||
}
|
||||
}
|
||||
pre = child;
|
||||
}
|
||||
}
|
||||
return compactness;
|
||||
}
|
||||
|
||||
public double getAnchorQuality() {
|
||||
double quality = 0;
|
||||
for (Node<T> child: children) {
|
||||
quality += child.getAnchorQuality();
|
||||
}
|
||||
|
||||
if (isAnchor && parent != null) {
|
||||
double d = parent.position - position;
|
||||
quality += d * d;
|
||||
}
|
||||
return quality;
|
||||
}
|
||||
};
|
||||
|
||||
public static <T> void optimizeTreeLayout(Node<T> root) {
|
||||
@@ -93,6 +131,7 @@ public class TreeLayoutOptimizer<T> {
|
||||
optimizeChildrenOrder(root, System.currentTimeMillis(), MAX_OPTIM_TIME_MS, numNodes);
|
||||
layoutTree(root, numNodes);
|
||||
optimizeLeafs(root);
|
||||
root.adjustPosition(root.getMinPosition());
|
||||
}
|
||||
|
||||
private static long MAX_OPTIM_TIME_MS = 1000;
|
||||
@@ -111,7 +150,7 @@ public class TreeLayoutOptimizer<T> {
|
||||
sumMaxPositionSqr += maxPositionPerLevel[i] * maxPositionPerLevel[i];
|
||||
}
|
||||
}
|
||||
return sumMaxPositionSqr / numNodes + root.getCompactness();
|
||||
return sumMaxPositionSqr / numNodes + root.getCompactness() + root.getAnchorQuality();
|
||||
}
|
||||
|
||||
private static <T> void layoutNode(Node<T> node, double[] maxPositionPerLevel) {
|
||||
@@ -125,18 +164,31 @@ public class TreeLayoutOptimizer<T> {
|
||||
|
||||
private static <T> void adjustParentPosition(Node<T> node, double[] maxPositionPerLevel) {
|
||||
while (node != null) {
|
||||
double parentPos = node.children.get(0).position + (maxPositionPerLevel[node.level + 1] - node.children.get(0).position) / 2.0;
|
||||
if (node.position < parentPos) {
|
||||
node.position = parentPos;
|
||||
// node.position = (node.position + parentPos) / 2.0;
|
||||
maxPositionPerLevel[node.level] = parentPos;
|
||||
Node<T> anchorChild = null;
|
||||
if (node.isAnchor) {
|
||||
for (Node<T> child: node.children) {
|
||||
if (child.isAnchor) {
|
||||
anchorChild = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (anchorChild != null) {
|
||||
node.position = anchorChild.position;
|
||||
} else {
|
||||
break;
|
||||
double parentPos = node.children.get(0).position + (maxPositionPerLevel[node.level + 1] - node.children.get(0).position) / 2.0;
|
||||
if (node.position < parentPos) {
|
||||
node.position = parentPos;
|
||||
// node.position = (node.position + parentPos) / 2.0;
|
||||
maxPositionPerLevel[node.level] = parentPos;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static <T> void optimizeLeafs(Node<T> node) {
|
||||
if (node.children.isEmpty() && node.parent != null && node.position < node.parent.position) {
|
||||
int i = node.parent.children.indexOf(node);
|
||||
|
||||
@@ -36,6 +36,7 @@ import javax.swing.ImageIcon;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import net.sf.jailer.database.Session.AbstractResultSetReader;
|
||||
import net.sf.jailer.modelbuilder.MemorizedResultSet;
|
||||
import net.sf.jailer.ui.UIUtil;
|
||||
import net.sf.jailer.util.Quoting;
|
||||
@@ -148,6 +149,7 @@ public class MDSchema extends MDObject {
|
||||
if (tables == null) {
|
||||
try {
|
||||
tables = new ArrayList<MDTable>();
|
||||
Map<String, Long> estimatedRowCounts = readEstimatedRowCounts();
|
||||
MetaDataSource metaDataSource = getMetaDataSource();
|
||||
synchronized (metaDataSource.getSession().getMetaData()) {
|
||||
ResultSet rs = metaDataSource.readTables(getName());
|
||||
@@ -156,7 +158,8 @@ public class MDSchema extends MDObject {
|
||||
String tableName = metaDataSource.getQuoting().quote(rs.getString(3));
|
||||
final MDTable table = new MDTable(tableName, this, "VIEW".equalsIgnoreCase(rs.getString(4)),
|
||||
"SYNONYM".equalsIgnoreCase(rs.getString(4))
|
||||
|| "ALIAS".equalsIgnoreCase(rs.getString(4)));
|
||||
|| "ALIAS".equalsIgnoreCase(rs.getString(4)),
|
||||
estimatedRowCounts.get(rs.getString(3)));
|
||||
tables.add(table);
|
||||
if (loadTableColumns) {
|
||||
loadJobs.put(tableName, new Runnable() {
|
||||
@@ -194,6 +197,30 @@ public class MDSchema extends MDObject {
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Long> readEstimatedRowCounts() {
|
||||
final Map<String, Long> result = new HashMap<String, Long>();
|
||||
|
||||
String query = getMetaDataSource().getSession().dbms.getEstimatedRowCountQuery();
|
||||
if (query != null) {
|
||||
try {
|
||||
getMetaDataSource().getSession().executeQuery(String.format(query, getUnquotedName()), new AbstractResultSetReader() {
|
||||
@Override
|
||||
public void readCurrentRow(ResultSet resultSet) throws SQLException {
|
||||
String tableName = resultSet.getString(1);
|
||||
long rowCount = resultSet.getLong(2);
|
||||
if (!resultSet.wasNull() && rowCount >= 0) {
|
||||
result.put(tableName, rowCount);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (SQLException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Have the tables of the schema been loaded?
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package net.sf.jailer.ui.databrowser.metadata;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
@@ -42,6 +41,7 @@ import net.sf.jailer.database.Session;
|
||||
import net.sf.jailer.datamodel.Column;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.modelbuilder.JDBCMetaDataBasedModelElementFinder;
|
||||
import net.sf.jailer.ui.UIUtil;
|
||||
import net.sf.jailer.util.Quoting;
|
||||
import net.sf.jailer.util.SqlUtil;
|
||||
|
||||
@@ -67,6 +67,8 @@ public class MDTable extends MDObject {
|
||||
private final boolean isView;
|
||||
private final boolean isSynonym;
|
||||
|
||||
public final Long estimatedRowCount;
|
||||
|
||||
// DDL of the table or <code>null</code>, if no DDL is available
|
||||
private String ddl;
|
||||
|
||||
@@ -76,11 +78,12 @@ public class MDTable extends MDObject {
|
||||
* @param name table name
|
||||
* @param schema the tables schema
|
||||
*/
|
||||
public MDTable(String name, MDSchema schema, boolean isView, boolean isSynonym) {
|
||||
public MDTable(String name, MDSchema schema, boolean isView, boolean isSynonym, Long estimatedRowCount) {
|
||||
super(name, schema.getMetaDataSource());
|
||||
this.isView = isView;
|
||||
this.isSynonym = isSynonym;
|
||||
this.schema = schema;
|
||||
this.estimatedRowCount = estimatedRowCount;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,7 +114,7 @@ public class MDTable extends MDObject {
|
||||
if (isLoaded()) {
|
||||
return getColumns();
|
||||
}
|
||||
waitCursorSubject.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(waitCursorSubject);
|
||||
try {
|
||||
loading.set(true);
|
||||
queue.add(new Runnable() {
|
||||
@@ -132,7 +135,7 @@ public class MDTable extends MDObject {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
waitCursorSubject.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(waitCursorSubject);
|
||||
}
|
||||
if (loading.get()) {
|
||||
return new ArrayList<String>();
|
||||
@@ -159,7 +162,7 @@ public class MDTable extends MDObject {
|
||||
MetaDataSource metaDataSource = getMetaDataSource();
|
||||
synchronized (metaDataSource.getSession().getMetaData()) {
|
||||
ResultSet resultSet = JDBCMetaDataBasedModelElementFinder.getColumns(getSchema().getMetaDataSource().getSession(), getSchema().getMetaDataSource().getSession().getMetaData(), Quoting.staticUnquote(getSchema().getName()), Quoting.staticUnquote(getName()), "%",
|
||||
true);
|
||||
true, isSynonym? "SYNONYM" : null);
|
||||
while (resultSet.next()) {
|
||||
String colName = metaDataSource.getQuoting().quote(resultSet.getString(4));
|
||||
columns.add(colName);
|
||||
@@ -208,7 +211,23 @@ public class MDTable extends MDObject {
|
||||
}
|
||||
pk.put(keySeq, metaDataSource.getQuoting().quote(resultSet.getString(4)));
|
||||
}
|
||||
primaryKey.addAll(pk.values());
|
||||
if (pk.isEmpty()) {
|
||||
Table table = metaDataSource.toTable(this);
|
||||
if (table != null) {
|
||||
if (table.primaryKey != null) {
|
||||
for (Column c: table.primaryKey.getColumns()) {
|
||||
for (String mc: columns) {
|
||||
if (Quoting.equalsIgnoreQuotingAndCase(c.name, mc)) {
|
||||
primaryKey.add(mc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
primaryKey.addAll(pk.values());
|
||||
}
|
||||
resultSet.close();
|
||||
}
|
||||
} finally {
|
||||
@@ -327,6 +346,22 @@ public class MDTable extends MDObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ddl == null && isView) {
|
||||
String viewTextOrDDLQuery = session.dbms.getViewTextOrDDLQuery();
|
||||
if (viewTextOrDDLQuery != null) {
|
||||
String viewTextQuery = String.format(viewTextOrDDLQuery, Quoting.staticUnquote(getSchema().getName()), Quoting.staticUnquote(getName()));
|
||||
try {
|
||||
session.executeQuery(viewTextQuery, new Session.AbstractResultSetReader() {
|
||||
@Override
|
||||
public void readCurrentRow(ResultSet resultSet) throws SQLException {
|
||||
ddl = resultSet.getString(1);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ddl == null) {
|
||||
try {
|
||||
ddl = createDDL();
|
||||
|
||||
@@ -39,7 +39,7 @@ public enum MetaDataDetails {
|
||||
COLUMNS("Columns", 0) {
|
||||
@Override
|
||||
public ResultSet readMetaDataDetails(Session session, MDTable mdTable) throws SQLException {
|
||||
return JDBCMetaDataBasedModelElementFinder.getColumns(session, session.getMetaData(), Quoting.staticUnquote(mdTable.getSchema().getName()), Quoting.staticUnquote(mdTable.getName()), "%", true);
|
||||
return JDBCMetaDataBasedModelElementFinder.getColumns(session, session.getMetaData(), Quoting.staticUnquote(mdTable.getSchema().getName()), Quoting.staticUnquote(mdTable.getName()), "%", true, mdTable.isSynonym()? "SYNONYM" : null);
|
||||
}
|
||||
@Override
|
||||
public void adjustRowsTable(JTable rowsTable) {
|
||||
|
||||
@@ -262,7 +262,8 @@ public abstract class MetaDataDetailsPanel extends javax.swing.JPanel {
|
||||
protected void onContentChange(List<Row> rows, boolean reloadChildren) {
|
||||
}
|
||||
@Override
|
||||
protected void navigateTo(Association association, int rowIndex, Row row) {
|
||||
protected RowBrowser navigateTo(Association association, int rowIndex, Row row) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected List<RowBrowser> getTableBrowser() {
|
||||
@@ -365,7 +366,7 @@ public abstract class MetaDataDetailsPanel extends javax.swing.JPanel {
|
||||
rs.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logger.info("error", e);
|
||||
// ignore
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,6 @@ package net.sf.jailer.ui.databrowser.metadata;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
@@ -699,7 +698,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
popup.add(menu);
|
||||
++itemCount;
|
||||
menu.add(createScriptMenuItem("Delete Script", "Delete from %1$s;", "", mdTables, false));
|
||||
menu.add(createScriptMenuItem("Drop Table Script", "Drop Table %1$s;", "", mdTables, false));
|
||||
menu.add(createScriptMenuItem("Drop Table Script", "Drop %2$s %1$s;", "", mdTables, false));
|
||||
menu.addSeparator();
|
||||
menu.add(createScriptMenuItem("Count Rows Script", "Select '%1$s' as Tab, count(*) as NumberOfRows From %1$s", " union all", mdTables, true));
|
||||
}
|
||||
@@ -709,7 +708,9 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
if (evt.getButton() == MouseEvent.BUTTON1) {
|
||||
if (mdTable != null) {
|
||||
if (evt.getClickCount() > 1) {
|
||||
openTable(mdTable);
|
||||
if (node != null && metaDataTree.getSelectionModel().isPathSelected(node)) {
|
||||
openTable(mdTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -725,12 +726,19 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
script.append(separator + "\n");
|
||||
}
|
||||
String tableName;
|
||||
String tableType = "Table";
|
||||
if (mdTable.isView()) {
|
||||
tableType = "View";
|
||||
}
|
||||
if (mdTable.isSynonym()) {
|
||||
tableType = "Synonym";
|
||||
}
|
||||
if (mdTable.getSchema().isDefaultSchema) {
|
||||
tableName = mdTable.getName();
|
||||
} else {
|
||||
tableName = mdTable.getSchema() + "." + mdTable.getName();
|
||||
}
|
||||
script.append(String.format(template, tableName));
|
||||
script.append(String.format(template, tableName, tableType));
|
||||
}
|
||||
script.append("\n");
|
||||
appendScript(script.toString(), execute);
|
||||
@@ -815,6 +823,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
boolean isSynonym = false;
|
||||
Boolean isDirty = false;
|
||||
Icon image = null;
|
||||
Long estRowCount = null;
|
||||
if (value instanceof DefaultMutableTreeNode) {
|
||||
Object uo = ((DefaultMutableTreeNode) value).getUserObject();
|
||||
if (uo instanceof JLabel) {
|
||||
@@ -851,11 +860,11 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ModelBuilder.isJailerTable(((MDTable) uo).getUnquotedName())) {
|
||||
isJailerTable = true;
|
||||
}
|
||||
isView = ((MDTable) uo).isView();
|
||||
isSynonym = ((MDTable) uo).isSynonym();
|
||||
if (!isView) {
|
||||
estRowCount = ((MDTable) uo).estimatedRowCount;
|
||||
}
|
||||
if (isView) {
|
||||
image = viewIcon;
|
||||
} else if (isSynonym) {
|
||||
@@ -863,6 +872,9 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
} else {
|
||||
image = tableIcon;
|
||||
}
|
||||
if (ModelBuilder.isJailerTable(((MDTable) uo).getUnquotedName())) {
|
||||
isJailerTable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Component comp = super.getTreeCellRendererComponent(tree, value + (unknownTable? "" : (isDirty? " !" : " ")), sel, expanded, leaf, row, hasFocus);
|
||||
@@ -874,13 +886,29 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
// TODO tooltips dont work with tree nodes
|
||||
tooltip = text;
|
||||
}
|
||||
if (estRowCount != null) {
|
||||
Color fg = ((JLabel) comp).getForeground();
|
||||
String estRowCountFormatted;
|
||||
if (estRowCount >= 1000000) {
|
||||
estRowCountFormatted = String.format("%1.1f M", (double) estRowCount / 1000000.0);
|
||||
} else if (estRowCount >= 1000) {
|
||||
estRowCountFormatted = String.format("%1.1f K", (double) estRowCount / 1000.0);
|
||||
} else {
|
||||
estRowCountFormatted = estRowCount.toString();
|
||||
}
|
||||
if (fg.getRed() + fg.getGreen() + fg.getBlue() < 255 * 3 / 2) {
|
||||
((JLabel) comp).setText("<html>" + text + " <font color=\"#7777ff\">(~</font><font color=\"#3333ff\">" + estRowCountFormatted + "</font><font color=\"#7777ff\">)</font>");
|
||||
} else {
|
||||
((JLabel) comp).setText("<html>" + text + " <font color=\"#aaaaff\">(~</font><font color=\"#eeeeff\">" + estRowCountFormatted + "</font><font color=\"#aaaaff\">)</font>");
|
||||
}
|
||||
}
|
||||
}
|
||||
Font font = comp.getFont();
|
||||
if (font != null) {
|
||||
Font bold = new Font(font.getName(), unknownTable || isDirty? (font.getStyle() | Font.ITALIC) : (font.getStyle() & ~Font.ITALIC), font.getSize());
|
||||
comp.setFont(bold);
|
||||
}
|
||||
if (isJailerTable) {
|
||||
if (isJailerTable && !sel) {
|
||||
comp.setEnabled(false);
|
||||
}
|
||||
if (image != null) {
|
||||
@@ -941,7 +969,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(MetaDataPanel.this);
|
||||
try {
|
||||
if (metaDataTree.getSelectionPath() != null && metaDataTree.getSelectionPath().getLastPathComponent() == last) {
|
||||
if (uo instanceof MDSchema) {
|
||||
@@ -961,7 +989,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(MetaDataPanel.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1040,7 +1068,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
refreshButton.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(refreshButton);
|
||||
JDBCMetaDataBasedModelElementFinder.resetCaches(metaDataSource.getSession());
|
||||
setOutline(new ArrayList<OutlineInfo>(), -1);
|
||||
proceduresPerSchema.clear();
|
||||
@@ -1071,7 +1099,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
refreshButton.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(refreshButton);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1100,7 +1128,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
if (bounds != null) {
|
||||
int b = 18;
|
||||
bounds = new Rectangle(bounds.x, Math.max(bounds.y - b, 0), bounds.width, bounds.height + 2 * b);
|
||||
metaDataTree.scrollRectToVisible(new Rectangle(bounds.x, bounds.y, 1, bounds.height));
|
||||
metaDataTree.scrollRectToVisible(new Rectangle(0, bounds.y, 1, bounds.height));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1200,12 +1228,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
}
|
||||
DefaultTreeModel treeModel = new DefaultTreeModel(root);
|
||||
metaDataTree.setModel(treeModel);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
metaDataTree.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
|
||||
}
|
||||
});
|
||||
metaDataTree.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
|
||||
selectSchema(metaDataSource.getDefaultSchema());
|
||||
}
|
||||
|
||||
@@ -1262,10 +1285,10 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(MetaDataPanel.this);
|
||||
expandImmediatelly();
|
||||
} finally {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
UIUtil.resetWaitCursor(MetaDataPanel.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -34,6 +34,7 @@ import net.sf.jailer.database.Session;
|
||||
import net.sf.jailer.datamodel.Association;
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.modelbuilder.MemorizedResultSet;
|
||||
import net.sf.jailer.ui.DbConnectionDialog;
|
||||
import net.sf.jailer.ui.QueryBuilderDialog;
|
||||
import net.sf.jailer.ui.QueryBuilderDialog.Relationship;
|
||||
@@ -71,7 +72,11 @@ public class ResultSetRenderer extends javax.swing.JPanel {
|
||||
null, null, new RowsClosure(), Integer.MAX_VALUE, false, false,
|
||||
resultSet.getMetaData().getColumnCount() > 1? 180 : 400,
|
||||
executionContext);
|
||||
rb.setTableFilterEnabled(false);
|
||||
if (resultSet instanceof MemorizedResultSet && ((MemorizedResultSet) resultSet).getSize() > 1) {
|
||||
rb.setTableFilterEnabled(true);
|
||||
} else {
|
||||
rb.setTableFilterEnabled(false);
|
||||
}
|
||||
LoadJob loadJob = rb.newLoadJob(resultSet, Integer.MAX_VALUE);
|
||||
loadJob.run();
|
||||
JComponent rTabContainer = rb.getRowsTableContainer();
|
||||
@@ -140,7 +145,7 @@ public class ResultSetRenderer extends javax.swing.JPanel {
|
||||
this.limit = limit;
|
||||
rowsTableScrollPane.setWheelScrollingEnabled(true);
|
||||
rowsCount.setVisible(false);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected int getReloadLimit() {
|
||||
if (limit == null) {
|
||||
@@ -174,7 +179,8 @@ public class ResultSetRenderer extends javax.swing.JPanel {
|
||||
protected void onContentChange(List<Row> rows, boolean reloadChildren) {
|
||||
}
|
||||
@Override
|
||||
protected void navigateTo(Association association, int rowIndex, Row row) {
|
||||
protected RowBrowser navigateTo(Association association, int rowIndex, Row row) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected List<RowBrowser> getTableBrowser() {
|
||||
|
||||
+18
-6
@@ -47,11 +47,13 @@ import net.sf.jsqlparser.expression.TimeKeyExpression;
|
||||
import net.sf.jsqlparser.expression.TimeValue;
|
||||
import net.sf.jsqlparser.expression.TimestampValue;
|
||||
import net.sf.jsqlparser.expression.UserVariable;
|
||||
import net.sf.jsqlparser.expression.ValueListExpression;
|
||||
import net.sf.jsqlparser.expression.WhenClause;
|
||||
import net.sf.jsqlparser.expression.WithinGroupExpression;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseRightShift;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
|
||||
@@ -305,11 +307,6 @@ class AbstractExpressionVisitor implements ExpressionVisitor {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WithinGroupExpression arg0) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ExtractExpression arg0) {
|
||||
|
||||
@@ -389,4 +386,19 @@ class AbstractExpressionVisitor implements ExpressionVisitor {
|
||||
public void visit(NotExpression arg0) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BitwiseRightShift arg0) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BitwiseLeftShift arg0) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ValueListExpression arg0) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ public class ColumnsTable extends JTable {
|
||||
setRowSelectionAllowed(true);
|
||||
setColumnSelectionAllowed(true);
|
||||
setCellSelectionEnabled(true);
|
||||
// getTableHeader().setReorderingAllowed(false);
|
||||
setShowGrid(false);
|
||||
setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
||||
setModel(cDm);
|
||||
@@ -223,7 +224,7 @@ public class ColumnsTable extends JTable {
|
||||
return null;
|
||||
}
|
||||
JMenuItem copyTCB = new JMenuItem("Copy to Clipboard");
|
||||
copyTCB.setAccelerator(KS_COPY_TO_CLIPBOARD);
|
||||
// copyTCB.setAccelerator(KS_COPY_TO_CLIPBOARD);
|
||||
copyTCB.setEnabled(getSelectedColumnCount() > 0);
|
||||
copyTCB.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@@ -244,7 +245,7 @@ public class ColumnsTable extends JTable {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
private void adjustTableColumnsWidth() {
|
||||
|
||||
@@ -67,11 +67,13 @@ import net.sf.jsqlparser.expression.TimeKeyExpression;
|
||||
import net.sf.jsqlparser.expression.TimeValue;
|
||||
import net.sf.jsqlparser.expression.TimestampValue;
|
||||
import net.sf.jsqlparser.expression.UserVariable;
|
||||
import net.sf.jsqlparser.expression.ValueListExpression;
|
||||
import net.sf.jsqlparser.expression.WhenClause;
|
||||
import net.sf.jsqlparser.expression.WithinGroupExpression;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseRightShift;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
|
||||
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
|
||||
@@ -102,6 +104,7 @@ import net.sf.jsqlparser.statement.SetStatement;
|
||||
import net.sf.jsqlparser.statement.Statement;
|
||||
import net.sf.jsqlparser.statement.StatementVisitor;
|
||||
import net.sf.jsqlparser.statement.Statements;
|
||||
import net.sf.jsqlparser.statement.UseStatement;
|
||||
import net.sf.jsqlparser.statement.alter.Alter;
|
||||
import net.sf.jsqlparser.statement.create.index.CreateIndex;
|
||||
import net.sf.jsqlparser.statement.create.table.CreateTable;
|
||||
@@ -118,6 +121,7 @@ import net.sf.jsqlparser.statement.select.AllTableColumns;
|
||||
import net.sf.jsqlparser.statement.select.FromItemVisitor;
|
||||
import net.sf.jsqlparser.statement.select.Join;
|
||||
import net.sf.jsqlparser.statement.select.LateralSubSelect;
|
||||
import net.sf.jsqlparser.statement.select.ParenthesisFromItem;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.Select;
|
||||
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
|
||||
@@ -310,9 +314,9 @@ public class QueryTypeAnalyser {
|
||||
|
||||
@Override
|
||||
public void visit(PlainSelect plainSelect) {
|
||||
ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(result);
|
||||
final ExpressionAnalyzer expressionAnalyzer = new ExpressionAnalyzer(result);
|
||||
if (plainSelect.getFromItem() != null) {
|
||||
FromItemVisitor fromItemVisitor = new FromItemVisitor() {
|
||||
final FromItemVisitor fromItemVisitor = new FromItemVisitor() {
|
||||
private void unknownTable() {
|
||||
result.put("-unknown-" + (unknownTableCounter++), null);
|
||||
}
|
||||
@@ -333,7 +337,18 @@ public class QueryTypeAnalyser {
|
||||
|
||||
@Override
|
||||
public void visit(SubJoin subjoin) {
|
||||
unknownTable();
|
||||
subjoin.getLeft().accept(this);
|
||||
if (subjoin.getJoinList() != null) {
|
||||
for (Join join: subjoin.getJoinList()) {
|
||||
join.getRightItem().accept(this);
|
||||
}
|
||||
for (Join join: subjoin.getJoinList()) {
|
||||
expressionAnalyzer.setOuterJoinExpression(join.isOuter() || join.isLeft() || join.isRight());
|
||||
if (join.getOnExpression() != null) {
|
||||
join.getOnExpression().accept(expressionAnalyzer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -364,6 +379,12 @@ public class QueryTypeAnalyser {
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void visit(ParenthesisFromItem parenthesisFromItem) {
|
||||
if (parenthesisFromItem.getFromItem() != null) {
|
||||
parenthesisFromItem.getFromItem().accept(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
plainSelect.getFromItem().accept(fromItemVisitor);
|
||||
if (plainSelect.getJoins() != null) {
|
||||
@@ -562,11 +583,6 @@ public class QueryTypeAnalyser {
|
||||
noSubexpression[0] = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WithinGroupExpression wgexpr) {
|
||||
noSubexpression[0] = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(AnalyticExpression aexpr) {
|
||||
noSubexpression[0] = false;
|
||||
@@ -781,6 +797,21 @@ public class QueryTypeAnalyser {
|
||||
public void visit(NullValue nullValue) {
|
||||
noSubexpression[0] = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BitwiseRightShift aThis) {
|
||||
noSubexpression[0] = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BitwiseLeftShift aThis) {
|
||||
noSubexpression[0] = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ValueListExpression valueList) {
|
||||
noSubexpression[0] = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -875,6 +906,11 @@ public class QueryTypeAnalyser {
|
||||
public void visit(Upsert upsert) {
|
||||
throw new QueryTooComplexException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(UseStatement use) {
|
||||
throw new QueryTooComplexException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.awt.Font;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
@@ -160,6 +161,8 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
private JMenuItem menuItemToggle;
|
||||
private JMenuItem menuItemSubstituteVariables;
|
||||
private JMenuItem menuItemAnalyse;
|
||||
private int initialTabbedPaneSelection = 0;
|
||||
private int initialTabbedPaneSelectionLoc = -1;
|
||||
|
||||
private final String IGNORED_STATEMENTS = "(\\s*/\\s*)";
|
||||
|
||||
@@ -676,7 +679,7 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
* @param statementStartOffset
|
||||
* @param explain
|
||||
*/
|
||||
private void executeSQL(final String sql, Status status, int statementStartOffset, final boolean explain) {
|
||||
private void executeSQL(final String sql, final Status status, int statementStartOffset, final boolean explain) {
|
||||
Statement statement = null;
|
||||
ResultSet resultSet = null;
|
||||
final Status localStatus = new Status();
|
||||
@@ -688,6 +691,7 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
localStatus.numStatements++;
|
||||
status.updateView(false);
|
||||
statement = session.getConnection().createStatement();
|
||||
// SqlUtil.limitFetchSize(statement, session);
|
||||
CancellationHandler.begin(statement, SQLConsole.this);
|
||||
long startTime = System.currentTimeMillis();
|
||||
sqlStatement =
|
||||
@@ -723,7 +727,7 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
hasUpdateCount = false;
|
||||
hasResultSet = false;
|
||||
} else {
|
||||
hasResultSet = statement.execute(sqlStatement);
|
||||
hasResultSet = executeStatementWithLimit(statement, sqlStatement, session);
|
||||
}
|
||||
}
|
||||
if (hasResultSet) {
|
||||
@@ -863,9 +867,17 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
rTabContainer = tabContentPanel;
|
||||
final int MAXLENGTH = 30;
|
||||
String title = shortSQL(sqlE, MAXLENGTH);
|
||||
final int loc = status != null && status.location != null? status.location.a : -1;
|
||||
if (initialTabbedPaneSelection >= 0 && initialTabbedPaneSelectionLoc == loc) {
|
||||
if (initialTabbedPaneSelection < tabContentPanel.tabbedPane.getTabCount()) {
|
||||
tabContentPanel.tabbedPane.setSelectedIndex(initialTabbedPaneSelection);
|
||||
}
|
||||
}
|
||||
tabContentPanel.tabbedPane.addChangeListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
initialTabbedPaneSelection = tabContentPanel.tabbedPane.getSelectedIndex();
|
||||
initialTabbedPaneSelectionLoc = loc;
|
||||
updateColumnsAndTextView(rb, tabContentPanel);
|
||||
}
|
||||
});
|
||||
@@ -901,8 +913,19 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
if (tabContentPanel.tabbedPane.getSelectedComponent() == tabContentPanel.columnsPanel || tabContentPanel.tabbedPane.getSelectedComponent() == tabContentPanel.contentPanel) {
|
||||
Point vp = null;
|
||||
if (columnsTable != null) {
|
||||
if (tabContentPanel.columnsScrollPane.getViewport() != null) {
|
||||
vp = tabContentPanel.columnsScrollPane.getViewport().getViewPosition();
|
||||
}
|
||||
}
|
||||
columnsTable = new ColumnsTable(rb);
|
||||
tabContentPanel.columnsScrollPane.setViewportView(columnsTable);
|
||||
if (vp != null) {
|
||||
if (tabContentPanel.columnsScrollPane.getViewport() != null) {
|
||||
tabContentPanel.columnsScrollPane.getViewport().setViewPosition(vp);
|
||||
}
|
||||
}
|
||||
tabContentPanel.columnsSortedStateLabel.setText(" " + tableSortAndFilterState);
|
||||
tabContentPanel.columnsSortedStateLabel.setVisible(!tableSortAndFilterState.isEmpty());
|
||||
}
|
||||
@@ -1000,6 +1023,17 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean executeStatementWithLimit(Statement statement, String sqlStatement, Session session) throws SQLException {
|
||||
if (DBMS.MySQL.equals(session.dbms)) {
|
||||
try {
|
||||
return statement.execute("(" + sqlStatement + "\n) limit " + (1 + (Integer) limitComboBox.getSelectedItem()));
|
||||
} catch (Throwable e) {
|
||||
return statement.execute(sqlStatement);
|
||||
}
|
||||
}
|
||||
return statement.execute(sqlStatement);
|
||||
}
|
||||
|
||||
public void setCaretPosition(int position) {
|
||||
if (editorPane.getDocument().getLength() >= position) {
|
||||
try {
|
||||
@@ -1016,6 +1050,7 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
private void updateOutline(String sql, int startPosition) {
|
||||
sql = sql.replaceFirst(";\\s*$", "");
|
||||
final int MAX_CONTEXT_LENGTH = 80;
|
||||
final int MAX_TOOLTIP_LENGTH = 100;
|
||||
List<OutlineInfo> outlineInfos = new ArrayList<OutlineInfo>();
|
||||
@@ -1547,6 +1582,7 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
statusLabel.setText("Canceling...");
|
||||
statusLabel.setForeground(Color.RED);
|
||||
CancellationHandler.cancel(this);
|
||||
cancelButton.setEnabled(false);
|
||||
}//GEN-LAST:event_cancelButtonActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
@@ -1609,7 +1645,8 @@ public abstract class SQLConsole extends javax.swing.JPanel {
|
||||
protected void onContentChange(List<Row> rows, boolean reloadChildren) {
|
||||
}
|
||||
@Override
|
||||
protected void navigateTo(Association association, int rowIndex, Row row) {
|
||||
protected RowBrowser navigateTo(Association association, int rowIndex, Row row) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected List<RowBrowser> getTableBrowser() {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.sf.jailer.ui.graphical_view;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
@@ -16,6 +15,7 @@ import java.util.HashSet;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JFileChooser;
|
||||
|
||||
import net.sf.jailer.ui.UIUtil;
|
||||
import prefuse.Display;
|
||||
import prefuse.Visualization;
|
||||
import prefuse.util.GraphicsLib;
|
||||
@@ -113,7 +113,7 @@ public class DisplayExporter {
|
||||
String m_group = Visualization.ALL_ITEMS;
|
||||
|
||||
try {
|
||||
display.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
UIUtil.setWaitCursor(display);
|
||||
|
||||
// Now comes the nice part
|
||||
|
||||
@@ -165,7 +165,7 @@ public class DisplayExporter {
|
||||
|
||||
return true;
|
||||
} finally {
|
||||
display.setCursor(Cursor.getDefaultCursor());
|
||||
UIUtil.resetWaitCursor(display);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ public class GraphicalDataModelView extends JPanel {
|
||||
/**
|
||||
* Maximum number of tables to make visible during expansion ("expand single table").
|
||||
*/
|
||||
public static final int EXPAND_SINGLE_TABLE_LIMIT = 10;
|
||||
public static final int EXPAND_SINGLE_TABLE_LIMIT = 4;
|
||||
|
||||
/**
|
||||
* The selected association.
|
||||
@@ -362,7 +362,7 @@ public class GraphicalDataModelView extends JPanel {
|
||||
popup.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
if (table != null) {
|
||||
JPopupMenu popup = createPopupMenu(table, true);
|
||||
JPopupMenu popup = createPopupMenu(table, null, true);
|
||||
popup.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
@@ -693,9 +693,10 @@ public class GraphicalDataModelView extends JPanel {
|
||||
* Creates popup menu.
|
||||
*
|
||||
* @param table the table for which the menu pops up
|
||||
* @param findPathMenuItem additional menu item
|
||||
* @return the popup menu
|
||||
*/
|
||||
public JPopupMenu createPopupMenu(final Table table, boolean withNavigation) {
|
||||
public JPopupMenu createPopupMenu(final Table table, JMenuItem findPathMenuItem, boolean withNavigation) {
|
||||
JPopupMenu popup = new JScrollPopupMenu();
|
||||
boolean withModifications = modelEditor.getAdditionalPopupMenuItems().isEmpty();
|
||||
|
||||
@@ -771,7 +772,7 @@ public class GraphicalDataModelView extends JPanel {
|
||||
// modelEditor.select(table);
|
||||
// }
|
||||
// });
|
||||
JMenuItem selectAsRoot = new JMenuItem("Focus " + table.getName());
|
||||
JMenuItem selectAsRoot = new JMenuItem("Focus on " + table.getName());
|
||||
selectAsRoot.addActionListener(new ActionListener () {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@@ -892,6 +893,9 @@ public class GraphicalDataModelView extends JPanel {
|
||||
if (navigateTo != null) {
|
||||
popup.add(navigateTo);
|
||||
}
|
||||
if (findPathMenuItem != null) {
|
||||
popup.add(findPathMenuItem);
|
||||
}
|
||||
if (withModifications){
|
||||
popup.add(dataBrowser);
|
||||
}
|
||||
@@ -1360,10 +1364,12 @@ public class GraphicalDataModelView extends JPanel {
|
||||
* Creates visible node for given table.
|
||||
*/
|
||||
public void showTable(Table source, Table destination) {
|
||||
List<Table> toCheck = new ArrayList<Table>();
|
||||
toCheck.add(destination);
|
||||
addEdges(theGraph, source, null, toCheck, false, new HashSet<Table>(toCheck));
|
||||
checkForExpansion(theGraph, model.getTables(), true);
|
||||
synchronized (visualization) {
|
||||
List<Table> toCheck = new ArrayList<Table>();
|
||||
toCheck.add(destination);
|
||||
addEdges(theGraph, source, null, toCheck, false, new HashSet<Table>(toCheck));
|
||||
checkForExpansion(theGraph, model.getTables(), true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2007 - 2018 the original author or authors.
|
||||
*
|
||||
* 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 net.sf.jailer.ui.pathfinder;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Item in the path-history of {@link PathFinderView}.
|
||||
*
|
||||
* @author Ralf Wisser
|
||||
*/
|
||||
public class HistoryItem implements Serializable {
|
||||
private static final long serialVersionUID = -2228012653415732355L;
|
||||
|
||||
public String source;
|
||||
public String destination;
|
||||
public boolean implicit = false;
|
||||
|
||||
public List<String> pathStations;
|
||||
public List<String> path;
|
||||
public Set<String> excludedTables;
|
||||
|
||||
public boolean isValid() {
|
||||
return path != null && pathStations != null && excludedTables != null && source != null && destination != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel2">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="History"/>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="historyTable">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
|
||||
<Table columnCount="4" rowCount="4">
|
||||
<Column editable="true" title="Title 1" type="java.lang.Object"/>
|
||||
<Column editable="true" title="Title 2" type="java.lang.Object"/>
|
||||
<Column editable="true" title="Title 3" type="java.lang.Object"/>
|
||||
<Column editable="true" title="Title 4" type="java.lang.Object"/>
|
||||
</Table>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value=" "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package net.sf.jailer.ui.pathfinder;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.ui.UIUtil;
|
||||
|
||||
/**
|
||||
* Path History Panel.
|
||||
*
|
||||
* @author Ralf Wisser
|
||||
*/
|
||||
public abstract class HistoryPanel extends javax.swing.JPanel {
|
||||
private static final long serialVersionUID = -482021751302785536L;
|
||||
|
||||
private final DataModel dataModel;
|
||||
private final Table source;
|
||||
|
||||
/**
|
||||
* Creates new form HistoryPanel
|
||||
*/
|
||||
public HistoryPanel(Table source, DataModel dataModel) {
|
||||
this.dataModel = dataModel;
|
||||
this.source = source;
|
||||
initComponents();
|
||||
if (source == null) {
|
||||
setVisible(false);
|
||||
} else {
|
||||
initTable();
|
||||
}
|
||||
}
|
||||
|
||||
private void initTable() {
|
||||
final TableCellRenderer defaultTableCellRenderer = historyTable.getDefaultRenderer(String.class);
|
||||
TableCellRenderer renderer = new TableCellRenderer() {
|
||||
final Color BG1 = new Color(255, 255, 255);
|
||||
final Color BG2 = new Color(242, 255, 242);
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
Component render = defaultTableCellRenderer.getTableCellRendererComponent(table, value, isSelected, false, row, column);
|
||||
if (!isSelected) {
|
||||
render.setBackground((row % 2 == 0) ? BG1 : BG2);
|
||||
}
|
||||
if (render instanceof JLabel) {
|
||||
((JLabel) render).setToolTipText(UIUtil.toHTML(String.valueOf(value), 200));
|
||||
}
|
||||
return render;
|
||||
}
|
||||
};
|
||||
historyTable.getColumnModel().getColumn(0).setCellRenderer(renderer);
|
||||
historyTable.setDefaultRenderer(Object.class, renderer);
|
||||
historyTable.setAutoCreateRowSorter(true);
|
||||
historyTable.setRowSelectionAllowed(true);
|
||||
historyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
|
||||
historyTable.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent arg0) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int sr = historyTable.getSelectedRow();
|
||||
if (sr >= 0) {
|
||||
close();
|
||||
apply(source, dests.get(historyTable.getRowSorter().convertRowIndexToModel(sr)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
historyTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
}
|
||||
});
|
||||
|
||||
DefaultTableModel tableModel = new DefaultTableModel(new String[] { "Destination" }, 0) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return column == 0;
|
||||
}
|
||||
};
|
||||
dests = PathFinderView.getHistoricDestinations(source, dataModel);
|
||||
|
||||
for (Table table: dests) {
|
||||
tableModel.addRow(new Object[] { dataModel.getDisplayName(table) });
|
||||
}
|
||||
|
||||
historyTable.setModel(tableModel);
|
||||
|
||||
adjustTableColumnsWidth(historyTable);
|
||||
}
|
||||
|
||||
private List<Table> dests;
|
||||
|
||||
public void adjustTableColumnsWidth(JTable table) {
|
||||
DefaultTableModel dtm = (DefaultTableModel) table.getModel();
|
||||
DefaultTableCellRenderer defaultTableCellRenderer = new DefaultTableCellRenderer();
|
||||
for (int i = 0; i < table.getColumnCount(); i++) {
|
||||
TableColumn column = table.getColumnModel().getColumn(i);
|
||||
Component comp = defaultTableCellRenderer.getTableCellRendererComponent(table, column.getHeaderValue(), false, false, 0, i);
|
||||
int width = 1;
|
||||
width = Math.max(width, comp.getPreferredSize().width);
|
||||
|
||||
int line = 0;
|
||||
for (; line < table.getRowCount(); ++line) {
|
||||
comp = table.getCellRenderer(line, i).getTableCellRendererComponent(table, dtm.getValueAt(line, i), false, false, line, i);
|
||||
width = Math.max(width, comp.getPreferredSize().width);
|
||||
}
|
||||
column.setPreferredWidth(Math.min(width, 400));
|
||||
if (i == 0) {
|
||||
column.setWidth(column.getPreferredWidth());
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
java.awt.GridBagConstraints gridBagConstraints;
|
||||
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
jPanel2 = new javax.swing.JPanel();
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
historyTable = new javax.swing.JTable();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
|
||||
setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
jPanel1.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("History"));
|
||||
jPanel2.setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
historyTable.setModel(new javax.swing.table.DefaultTableModel(
|
||||
new Object [][] {
|
||||
{null, null, null, null},
|
||||
{null, null, null, null},
|
||||
{null, null, null, null},
|
||||
{null, null, null, null}
|
||||
},
|
||||
new String [] {
|
||||
"Title 1", "Title 2", "Title 3", "Title 4"
|
||||
}
|
||||
));
|
||||
jScrollPane1.setViewportView(historyTable);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel2.add(jScrollPane1, gridBagConstraints);
|
||||
|
||||
jLabel1.setText(" ");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 2;
|
||||
jPanel2.add(jLabel1, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
jPanel1.add(jPanel2, gridBagConstraints);
|
||||
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||
gridBagConstraints.weightx = 1.0;
|
||||
gridBagConstraints.weighty = 1.0;
|
||||
add(jPanel1, gridBagConstraints);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JTable historyTable;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JPanel jPanel2;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
protected abstract void close();
|
||||
protected abstract void apply(Table source, Table destination);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2007 - 2018 the original author or authors.
|
||||
*
|
||||
* 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 net.sf.jailer.ui.pathfinder;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.util.List;
|
||||
|
||||
import org.fife.rsta.ui.EscapableDialog;
|
||||
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.ui.UIUtil;
|
||||
|
||||
/**
|
||||
* Finds path between two tables.
|
||||
*
|
||||
* @author Ralf Wisser
|
||||
*/
|
||||
public class PathFinder {
|
||||
|
||||
private List<Table> path;
|
||||
private boolean expand;
|
||||
|
||||
public class Result {
|
||||
public List<Table> path;
|
||||
public boolean expand;
|
||||
}
|
||||
|
||||
public Result find(Table source, Table destination, DataModel dataModel, boolean withOpenTablesButton, boolean fromHistory, Frame owner) {
|
||||
final EscapableDialog dialog = new EscapableDialog(owner, "PathFinder", true) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
};
|
||||
|
||||
final PathFinderView view = new PathFinderView(dataModel, source, destination, withOpenTablesButton, fromHistory) {
|
||||
@Override
|
||||
protected void applyPath(List<Table> path, boolean expand) {
|
||||
PathFinder.this.path = path;
|
||||
PathFinder.this.expand = expand;
|
||||
dialog.setVisible(false);
|
||||
}
|
||||
private static final long serialVersionUID = 1L;
|
||||
};
|
||||
|
||||
view.showGraph(true);
|
||||
|
||||
dialog.getContentPane().add(view);
|
||||
dialog.pack();
|
||||
int minWidth = 1200;
|
||||
dialog.setSize(minWidth, Math.min(Math.max(dialog.getHeight() + 20, 440), 600));
|
||||
dialog.addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentShown(ComponentEvent arg0) {
|
||||
view.sepLabel.setVisible(false);
|
||||
}
|
||||
});
|
||||
Point ownerLoc;
|
||||
Dimension ownerSize;
|
||||
if (owner != null) {
|
||||
ownerLoc = owner.getLocation();
|
||||
ownerSize = owner.getSize();
|
||||
} else {
|
||||
ownerLoc = new Point();
|
||||
ownerSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
}
|
||||
int x = (int) (ownerLoc.getX() + ownerSize.getWidth() / 2 - dialog.getWidth() / 2);
|
||||
int y = (int) (ownerLoc.getY() + ownerSize.getHeight() / 2 - dialog.getHeight() / 2);
|
||||
dialog.setLocation(x, y);
|
||||
int h = dialog.getHeight();
|
||||
UIUtil.fit(dialog);
|
||||
if (h > dialog.getHeight()) {
|
||||
dialog.setLocation(x, y - (h - dialog.getHeight()));
|
||||
dialog.setSize(Math.max(minWidth, dialog.getWidth()), Math.min(Math.max(dialog.getHeight() + 20, 400), 600));
|
||||
UIUtil.fit(dialog);
|
||||
}
|
||||
|
||||
dialog.setVisible(true);
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
Result result = new Result();
|
||||
result.path = path;
|
||||
result.expand = expand;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,83,0,0,2,-34"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JSplitPane" name="jSplitPane1">
|
||||
<Properties>
|
||||
<Property name="resizeWeight" type="double" value="1.0"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel2">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Union of all shortest paths without excluded tables."/>
|
||||
</Border>
|
||||
</Property>
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="ff" id="white" palette="1" red="ff" type="palette"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="left"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="1" gridWidth="3" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="pathContainerPanel">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="ff" green="ff" id="white" palette="1" red="ff" type="palette"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="okButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Show Path"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="13" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="okExpandButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Show Path and open Tables"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okExpandButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="2" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="13" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="sepLabel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value=" "/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="2" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="80" green="80" id="gray" palette="1" red="80" type="palette"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="Open context menu (right mouse click on table) to define its direct successor."/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="2" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel3">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||
<TitledBorder title="Excluded Tables"/>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
|
||||
<JSplitPaneConstraints position="right"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTable" name="exclusionTable">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
|
||||
<Table columnCount="4" rowCount="4">
|
||||
<Column editable="true" title="Title 1" type="java.lang.Object"/>
|
||||
<Column editable="true" title="Title 2" type="java.lang.Object"/>
|
||||
<Column editable="true" title="Title 3" type="java.lang.Object"/>
|
||||
<Column editable="true" title="Title 4" type="java.lang.Object"/>
|
||||
</Table>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value=" "/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel4">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="undoButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="jButton1"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="undoButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="redoButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="jButton1"/>
|
||||
<Property name="focusable" type="boolean" value="false"/>
|
||||
<Property name="horizontalTextPosition" type="int" value="0"/>
|
||||
<Property name="verticalTextPosition" type="int" value="3"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="redoButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="jSeparator2">
|
||||
<Properties>
|
||||
<Property name="orientation" type="int" value="1"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="3" gridY="0" gridWidth="1" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="0" insetsRight="8" anchor="10" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="historyButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="From History"/>
|
||||
<Property name="toolTipText" type="java.lang.String" value="Take the previously determined path."/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="historyButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="jSeparator3">
|
||||
<Properties>
|
||||
<Property name="orientation" type="int" value="1"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="5" gridY="0" gridWidth="1" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="0" insetsRight="8" anchor="10" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="considerRestrictionsCheckbox">
|
||||
<Properties>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Consider restrictions"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="considerRestrictionsCheckboxActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="10" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="8" anchor="13" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="resetButton">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Reset"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="resetButtonActionPerformed"/>
|
||||
</Events>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="6" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JSeparator" name="jSeparator1">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright 2007 - 2018 the original author or authors.
|
||||
*
|
||||
* 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 net.sf.jailer.ui.pathfinder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.jailer.datamodel.Association;
|
||||
import net.sf.jailer.datamodel.DataModel;
|
||||
import net.sf.jailer.datamodel.Table;
|
||||
import net.sf.jailer.util.Pair;
|
||||
|
||||
/**
|
||||
* Union of equi-length paths as directed graph.
|
||||
*
|
||||
* @author Ralf Wisser
|
||||
*/
|
||||
public class PathGraph {
|
||||
|
||||
private final Table source;
|
||||
private final Table destination;
|
||||
|
||||
private Map<Table, Node> nodePerTable = new HashMap<Table, Node>();
|
||||
private Map<Pair<Node, Node>, EdgeType> edgeTypes = new HashMap<Pair<Node, Node>, EdgeType>();
|
||||
private Set<Table> visitedExcludedTables = new HashSet<Table>();
|
||||
|
||||
public enum EdgeType { PARENT, CHILD, ASSOCIATION, IGNORED };
|
||||
|
||||
public class Node {
|
||||
Table table;
|
||||
int column;
|
||||
Set<Node> next = new HashSet<Node>();
|
||||
Set<Node> prev = new HashSet<Node>();
|
||||
|
||||
public String toString() {
|
||||
return table.getName() + ":" + column;
|
||||
}
|
||||
|
||||
public void collectPrevClosure(Set<Table> closure) {
|
||||
if (!closure.contains(table)) {
|
||||
closure.add(table);
|
||||
for (Node p: prev) {
|
||||
p.collectPrevClosure(closure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void collectNextClosure(Set<Table> closure) {
|
||||
if (!closure.contains(table)) {
|
||||
closure.add(table);
|
||||
for (Node p: next) {
|
||||
p.collectNextClosure(closure);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node of a given table.
|
||||
*
|
||||
* @param table the table
|
||||
* @return node representing table
|
||||
*/
|
||||
public Node getNode(Table table) {
|
||||
return nodePerTable.get(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all nodes on a given column.
|
||||
*
|
||||
* @param column the column
|
||||
* @return all nodes on a given column
|
||||
*/
|
||||
public List<Node> getNodes(int column) {
|
||||
List<Node> result = new ArrayList<Node>();
|
||||
for (Entry<Table, Node> e:nodePerTable.entrySet()) {
|
||||
if (e.getValue().column == column) {
|
||||
result.add(e.getValue());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets edge-type of a given edge.
|
||||
*
|
||||
* @param from left node of edge
|
||||
* @param to right node of edge
|
||||
* @return edge type
|
||||
*/
|
||||
public EdgeType getEdgeType(Node from, Node to) {
|
||||
Pair<Node, Node> edgeKey = new Pair<Node, Node>(from, to);
|
||||
return edgeTypes.get(edgeKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the graph to an empty graph.
|
||||
*/
|
||||
private void reset() {
|
||||
nodePerTable.clear();
|
||||
edgeTypes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this graph is empty.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return nodePerTable.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Graph.
|
||||
* @param excludedTables
|
||||
* @param pathStations
|
||||
* @param considerRestrictions
|
||||
*/
|
||||
public PathGraph(DataModel dataModel, Table source, Table destination, Set<Table> excludedTables, List<Table> pathStations, boolean considerRestrictions) {
|
||||
this(dataModel, source, destination, excludedTables, pathStations, considerRestrictions, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Graph.
|
||||
* @param excludedTables
|
||||
* @param pathStations
|
||||
* @param considerRestrictions
|
||||
*/
|
||||
public PathGraph(DataModel dataModel, Table source, Table destination, Set<Table> excludedTables, List<Table> pathStations, boolean considerRestrictions, boolean strict) {
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
|
||||
List<Table> stations = new ArrayList<Table>(pathStations);
|
||||
Node destNode;
|
||||
for (;;) {
|
||||
visitedExcludedTables.clear();
|
||||
createGraph(excludedTables, stations, visitedExcludedTables, considerRestrictions);
|
||||
destNode = nodePerTable.get(this.destination);
|
||||
if (destNode == null) {
|
||||
// retry with shorter path
|
||||
if (!stations.isEmpty() && !strict) {
|
||||
stations.remove(stations.size() - 1);
|
||||
continue;
|
||||
}
|
||||
reset();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Set<Table> destClosure = new HashSet<Table>();
|
||||
destNode.collectPrevClosure(destClosure);
|
||||
Set<Table> excluded = new HashSet<Table>(dataModel.getTables());
|
||||
excluded.removeAll(destClosure);
|
||||
excluded.addAll(excludedTables);
|
||||
visitedExcludedTables.clear();
|
||||
createGraph(excluded, stations, visitedExcludedTables, considerRestrictions);
|
||||
visitedExcludedTables.retainAll(excludedTables);
|
||||
}
|
||||
|
||||
private void createGraph(Set<Table> excluded, List<Table> pathStations, Set<Table> visitedExTables, boolean considerRestrictions) {
|
||||
reset();
|
||||
|
||||
Map<Table, Table> forcedSucc = new HashMap<Table, Table>();
|
||||
|
||||
for (int i = 1; i < pathStations.size(); ++i) {
|
||||
Table a = pathStations.get(i - 1);
|
||||
Table b = pathStations.get(i);
|
||||
for (Association as: a.associations) {
|
||||
if (!as.isIgnored() || !considerRestrictions) {
|
||||
if (as.destination.equals(b)) {
|
||||
forcedSucc.put(a, b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set<Table> currentColumn = new HashSet<Table>();
|
||||
currentColumn.add(source);
|
||||
int column = 0;
|
||||
Node node = new Node();
|
||||
node.table = source;
|
||||
node.column = column;
|
||||
nodePerTable.put(source, node);
|
||||
List<Table> stations = new LinkedList<Table>(pathStations);
|
||||
stations.remove(source);
|
||||
stations.remove(destination);
|
||||
stations.removeAll(excluded);
|
||||
Set<Table> onPath = new HashSet<Table>(pathStations);
|
||||
onPath.add(source);
|
||||
onPath.add(destination);
|
||||
Set<Table> lastVisitedExTables = new HashSet<Table>();
|
||||
do {
|
||||
boolean onStation = false;
|
||||
if (!stations.isEmpty()) {
|
||||
Table nextStat = stations.get(0);
|
||||
if (currentColumn.contains(nextStat)) {
|
||||
currentColumn.clear();
|
||||
currentColumn.add(nextStat);
|
||||
stations.remove(0);
|
||||
onStation = true;
|
||||
}
|
||||
}
|
||||
if (!onStation) {
|
||||
visitedExTables.addAll(lastVisitedExTables);
|
||||
}
|
||||
lastVisitedExTables.clear();
|
||||
Set<Table> nextColumn = new HashSet<Table>();
|
||||
for (Table table: currentColumn) {
|
||||
node = nodePerTable.get(table);
|
||||
for (Association a: table.associations) {
|
||||
if (!a.isIgnored() || !considerRestrictions
|
||||
|| (onPath.contains(a.source) && onPath.contains(a.destination))) {
|
||||
Table dest = a.destination;
|
||||
if (excluded.contains(dest)) {
|
||||
lastVisitedExTables.add(dest);
|
||||
continue;
|
||||
}
|
||||
if (forcedSucc.containsKey(table) && !forcedSucc.get(table).equals(dest)) {
|
||||
continue;
|
||||
}
|
||||
Node newNode = nodePerTable.get(dest);
|
||||
if (newNode != null && newNode.column != column + 1) {
|
||||
continue;
|
||||
}
|
||||
nextColumn.add(dest);
|
||||
EdgeType type;
|
||||
if (a.isIgnored()) {
|
||||
type = EdgeType.IGNORED;
|
||||
} else if (a.isInsertDestinationBeforeSource()) {
|
||||
type = EdgeType.PARENT;
|
||||
} else if (a.isInsertSourceBeforeDestination()) {
|
||||
type = EdgeType.CHILD;
|
||||
} else {
|
||||
type = EdgeType.ASSOCIATION;
|
||||
}
|
||||
if (newNode == null) {
|
||||
newNode = new Node();
|
||||
newNode.table = dest;
|
||||
newNode.column = column + 1;
|
||||
nodePerTable.put(dest, newNode);
|
||||
}
|
||||
Pair<Node, Node> edgeKey = new Pair<Node, Node>(node, newNode);
|
||||
EdgeType oldType = edgeTypes.get(edgeKey);
|
||||
if (oldType != null && !oldType.equals(EdgeType.IGNORED) && !type.equals(oldType)) {
|
||||
type = EdgeType.ASSOCIATION;
|
||||
}
|
||||
edgeTypes.put(edgeKey, type);
|
||||
node.next.add(newNode);
|
||||
newNode.prev.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
++column;
|
||||
currentColumn = nextColumn;
|
||||
} while (!currentColumn.isEmpty());
|
||||
visitedExTables.addAll(lastVisitedExTables);
|
||||
}
|
||||
|
||||
public Set<Table> getVisitedExcludedTables() {
|
||||
return visitedExcludedTables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this graph a unique non-empty path?
|
||||
*/
|
||||
public boolean isUnique() {
|
||||
if (isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (int column = 0; ; ++column) {
|
||||
int n = getNodes(column).size();
|
||||
if (n == 0) {
|
||||
return true;
|
||||
} else if (n > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 449 B |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -5,6 +5,7 @@ import java.awt.event.MouseListener;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public abstract class SmallButton extends JLabel {
|
||||
|
||||
@@ -14,7 +15,9 @@ public abstract class SmallButton extends JLabel {
|
||||
addMouseListener(new MouseListener() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
onClick();
|
||||
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||
onClick();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
@@ -29,7 +32,9 @@ public abstract class SmallButton extends JLabel {
|
||||
}
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
onClick();
|
||||
if (SwingUtilities.isLeftMouseButton(e)) {
|
||||
onClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ public class UpdateInfoManager {
|
||||
}
|
||||
}
|
||||
|
||||
System.setProperty("java.net.useSystemProxies", "true");
|
||||
URI uri = new URI(versionURL);
|
||||
URLConnection connection = uri.toURL().openConnection();
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
@@ -63,17 +62,19 @@ public class UpdateInfoManager {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Thread.sleep(DELAY);
|
||||
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(lastTSFile));
|
||||
out.writeLong(System.currentTimeMillis());
|
||||
out.close();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
infoLabel.setText("Release " + versions[0].trim() + " available");
|
||||
ui.setVisible(true);
|
||||
}
|
||||
});
|
||||
if (isValid(versions[0].trim())) {
|
||||
Thread.sleep(DELAY);
|
||||
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(lastTSFile));
|
||||
out.writeLong(System.currentTimeMillis());
|
||||
out.close();
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
infoLabel.setText("Release " + versions[0].trim() + " available");
|
||||
ui.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// ignore
|
||||
@@ -85,6 +86,10 @@ public class UpdateInfoManager {
|
||||
checkThread.start();
|
||||
}
|
||||
|
||||
private static boolean isValid(String version) {
|
||||
return version.matches("\\d+\\.\\d+(\\.\\d+)?");
|
||||
}
|
||||
|
||||
public static void download() {
|
||||
try {
|
||||
URI uri = new URI(downloadURL);
|
||||
@@ -93,4 +98,5 @@ public class UpdateInfoManager {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user