ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sboi...@apache.org
Subject [1/2] incubator-ignite git commit: # IGNITE-32 WIP: Working on GUI. Refactored model to separate classes. Refactored database to separate class (for testing). Added generation date to XML and POJO. Pretty printing for XML.
Date Sun, 25 Jan 2015 15:49:48 GMT
Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-32 47266bb6f -> 69feb3925


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/69feb392/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java
index 4aca16a..c373654 100644
--- a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java
+++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java
@@ -18,7 +18,6 @@
 package org.apache.ignite.schema.ui;
 
 import javafx.application.*;
-import javafx.beans.property.*;
 import javafx.beans.value.*;
 import javafx.collections.*;
 import javafx.concurrent.*;
@@ -29,20 +28,18 @@ import javafx.scene.control.*;
 import javafx.scene.layout.*;
 import javafx.stage.*;
 import javafx.util.*;
-import org.apache.ignite.lang.*;
 import org.apache.ignite.schema.generator.*;
+import org.apache.ignite.schema.model.*;
+import org.apache.ignite.schema.parser.*;
 import org.gridgain.grid.cache.query.*;
 
 import java.io.*;
-import java.math.*;
 import java.net.*;
 import java.sql.*;
-import java.sql.Date;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.prefs.*;
 
-import static java.sql.Types.*;
 import static javafx.embed.swing.SwingFXUtils.*;
 import static org.apache.ignite.schema.ui.Controls.*;
 
@@ -137,7 +134,6 @@ public class SchemaLoadApp extends Application {
 
     /** */
     private final ExecutorService exec = Executors.newSingleThreadExecutor(new ThreadFactory() {
-        /** {@inheritDoc} */
         @Override public Thread newThread(Runnable r) {
             Thread t = new Thread(r, "schema-load-worker");
 
@@ -202,7 +198,7 @@ public class SchemaLoadApp extends Application {
                 long started = System.currentTimeMillis();
 
                 try (Connection conn = connect()) {
-                    pojos = parse(conn);
+                    pojos = DatabaseMetadataParser.parse(conn);
                 }
 
                 perceptualDelay(started);
@@ -263,9 +259,9 @@ public class SchemaLoadApp extends Application {
      * Generate XML and POJOs.
      */
     private void generate() {
-        Collection<PojoDescriptor> selItems = selectedItems();
+        final Collection<PojoDescriptor> selPojos = selectedItems();
 
-        if (selItems.isEmpty()) {
+        if (selPojos.isEmpty()) {
             MessageBox.warningDialog(owner, "Please select tables to generate XML and POJOs files!");
 
             return;
@@ -280,11 +276,10 @@ public class SchemaLoadApp extends Application {
         final File destFolder = new File(outFolder);
 
         Runnable task = new Task<Void>() {
-            private void checkEmpty(Collection<GridCacheQueryTypeDescriptor> items,
-                final PojoDescriptor pojo, String msg) {
-                if (items.isEmpty()) {
+            private void checkEmpty(final PojoDescriptor pojo, Collection<GridCacheQueryTypeDescriptor> descs,
+                String msg) {
+                if (descs.isEmpty()) {
                     Platform.runLater(new Runnable() {
-                        /** {@inheritDoc} */
                         @Override public void run() {
                             pojosTbl.getSelectionModel().select(pojo);
                         }
@@ -304,41 +299,19 @@ public class SchemaLoadApp extends Application {
                 Collection<GridCacheQueryTypeMetadata> all = new ArrayList<>();
 
                 boolean constructor = pojoConstructorCh.isSelected();
-                boolean include = pojoIncludeKeysCh.isSelected();
+                boolean includeKeys = pojoIncludeKeysCh.isSelected();
                 boolean singleXml = xmlSingleFileCh.isSelected();
 
                 ConfirmCallable askOverwrite = new ConfirmCallable(owner, "File already exists: %s\nOverwrite?");
 
                 // Generate XML and POJO.
-                for (PojoDescriptor pojo : pojos) {
+                for (PojoDescriptor pojo : selPojos) {
                     if (pojo.selected()) {
-                        GridCacheQueryTypeMetadata meta = pojo.metadata();
-
-                        Collection<GridCacheQueryTypeDescriptor> keys = new ArrayList<>();
-
-                        Collection<GridCacheQueryTypeDescriptor> vals = new ArrayList<>();
-
-                        // Fill list with key and value type descriptors.
-                        for (PojoField fld : pojo.fields()) {
-                            GridCacheQueryTypeDescriptor desc = fld.descriptor();
-
-                            if (fld.key()) {
-                                keys.add(desc);
-
-                                if (include)
-                                    vals.add(desc);
-                            }
-                            else
-                                vals.add(desc);
-                        }
-
-                        checkEmpty(keys, pojo, "No key fields specified for type: ");
-
-                        checkEmpty(vals, pojo, "No value fields specified for type: ");
+                        GridCacheQueryTypeMetadata meta = pojo.metadata(includeKeys);
 
-                        meta.setKeyDescriptors(keys);
+                        checkEmpty(pojo, meta.getKeyDescriptors(), "No key fields specified for type: ");
 
-                        meta.setValueDescriptors(vals);
+                        checkEmpty(pojo, meta.getValueDescriptors(), "No value fields specified for type: ");
 
                         all.add(meta);
 
@@ -346,13 +319,11 @@ public class SchemaLoadApp extends Application {
                             XmlGenerator.generate(pkg, meta, new File(destFolder, meta.getType() + ".xml"),
                                 askOverwrite);
 
-                        PojoGenerator.generate(meta, outFolder, pkg, constructor, askOverwrite);
+                        PojoGenerator.generate(pojo, outFolder, pkg, constructor, includeKeys, askOverwrite);
                     }
                 }
 
-                if (all.isEmpty())
-                    throw new IllegalStateException("Nothing selected!");
-                else if (singleXml)
+                if (singleXml)
                     XmlGenerator.generate(pkg, all, new File(outFolder, "Ignite.xml"), askOverwrite);
 
                 perceptualDelay(started);
@@ -562,6 +533,11 @@ public class SchemaLoadApp extends Application {
         connPnl.addColumn(100, 100, Double.MAX_VALUE, Priority.ALWAYS);
         connPnl.addColumn(35, 35, 35, Priority.NEVER);
 
+        connPnl.add(text("This utility is designed to automatically generate configuration XML files and" +
+            " POGO classes from database schema information.", 550), 3);
+
+        connPnl.wrap();
+
         jdbcDrvJarTf = connPnl.addLabeled("Driver JAR:", textField("Path to driver jar"));
 
         connPnl.add(button("...", "Select JDBC driver jar or zip", new EventHandler<ActionEvent>() {
@@ -594,6 +570,55 @@ public class SchemaLoadApp extends Application {
     }
 
     /**
+     * Check if new class name is unique.
+     *
+     * @param pojo Current edited POJO.
+     * @param newVal New value for class name.
+     * @param key {@code true} if key class name is checked.
+     * @return {@code true} if class name is valid.
+     */
+    private boolean checkClassNameUnique(PojoDescriptor pojo, String newVal, boolean key) {
+        for (PojoDescriptor otherPojo : pojos)
+            if (pojo != otherPojo) {
+                String otherKeyCls = otherPojo.keyClassName();
+                String otherValCls = otherPojo.valueClassName();
+
+                if (newVal.equals(otherKeyCls) || newVal.equals(otherValCls)) {
+                    MessageBox.warningDialog(owner, (key ? "Key" : "Value") + " class name must be unique!");
+
+                    return false;
+                }
+            }
+
+        return true;
+    }
+
+    /**
+     * Check if new class name is valid.
+     *
+     * @param pojo Current edited POJO.
+     * @param newVal New value for class name.
+     * @param key {@code true} if key class name is checked.
+     * @return {@code true} if class name is valid.
+     */
+    private boolean checkClassName(PojoDescriptor pojo, String newVal, boolean key) {
+        if (key) {
+            if (newVal.equals(pojo.valueClassName())) {
+                MessageBox.warningDialog(owner, "Key class name must be different from value class name!");
+
+                return false;
+            }
+        }
+        else if (newVal.equals(pojo.keyClassName())) {
+            MessageBox.warningDialog(owner, "Value class name must be different from key class name!");
+
+            return false;
+        }
+
+        return checkClassNameUnique(pojo, newVal, key);
+    }
+
+    /**
      * Create generate pane with controls.
      */
     private void createGeneratePane() {
@@ -607,19 +632,21 @@ public class SchemaLoadApp extends Application {
         genPnl.addRows(7);
 
         TableColumn<PojoDescriptor, Boolean> useCol = customColumn("Schema / Table", "use",
-            "If checked then this table will be used for XML and POJOs generation", SchemaCell.cellFactory());
-
-        TableColumn<PojoDescriptor, String> keyClsCol = textColumn("Key Class", "keyClass", "Key class name");
+            "If checked then this table will be used for XML and POJOs generation", PojoDescriptorCell.cellFactory());
 
-        keyClsCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<PojoDescriptor, String>>() {
-            @Override public void handle(TableColumn.CellEditEvent<PojoDescriptor, String> evt) {
-                System.out.println("committed: " + evt.getNewValue());
-
-                evt.getRowValue().keyClsName.set(evt.getNewValue() + "boom");
-            }
-        });
+        TableColumn<PojoDescriptor, String> keyClsCol = textColumn("Key Class", "keyClassName", "Key class name",
+            new TextColumnValidator<PojoDescriptor>() {
+                @Override public boolean valid(PojoDescriptor rowVal, String newVal) {
+                    return checkClassName(rowVal, newVal, true);
+                }
+            });
 
-        TableColumn<PojoDescriptor, String> valClsCol = textColumn("Value Class", "valueClass", "Value class name");
+        TableColumn<PojoDescriptor, String> valClsCol = textColumn("Value Class", "valueClassName", "Value class name",
+            new TextColumnValidator<PojoDescriptor>() {
+                @Override public boolean valid(PojoDescriptor rowVal, String newVal) {
+                    return checkClassName(rowVal, newVal, false);
+                }
+            });
 
         pojosTbl = tableView("Tables not found in database", useCol, keyClsCol, valClsCol);
 
@@ -630,73 +657,27 @@ public class SchemaLoadApp extends Application {
 
         TableColumn<PojoField, String> dbTypeNameCol = tableColumn("DB Type", "dbTypeName", "Field type in database");
 
-        TableColumn<PojoField, String> javaNameCol = textColumn("Ignite Name", "javaName", "Field name in POJO class");
-
-        TableColumn<PojoField, String> javaTypeNameCol = customColumn("Java Type", "javaTypeName",
-            "Field java type in POJO class", JavaTypeCell.cellFactory());
-
-        final TableView<PojoField> fieldsTbl = tableView("Select table to see table columns",
-            keyCol, dbNameCol, dbTypeNameCol, javaNameCol, javaTypeNameCol);
-
-        final Button upBtn = button(imageView("navigate_up", 24), "Move selected row up",
-            new EventHandler<ActionEvent>() {
-                @Override public void handle(ActionEvent evt) {
-                    TableView.TableViewSelectionModel<PojoField> selMdl = fieldsTbl.getSelectionModel();
-
-                    int selIdx = selMdl.getSelectedIndex();
-
-                    if (selIdx > 0) {
-                        ObservableList<PojoField> items = fieldsTbl.getItems();
-
-                        int newId = selIdx - 1;
-
-                        items.add(newId, items.remove(selIdx));
-
-                        if (newId == 0)
-                            fieldsTbl.requestFocus();
-
-                        selMdl.select(newId);
-                    }
-                }
-            });
-
-        upBtn.setDisable(true);
+        TableColumn<PojoField, String> javaNameCol = textColumn("Ignite Name", "javaName", "Field name in POJO class",
+            new TextColumnValidator<PojoField>() {
+                @Override public boolean valid(PojoField rowVal, String newVal) {
+                    for (PojoField field : curPojo.fields())
+                        if (rowVal != field && newVal.equals(field.javaName())) {
+                            MessageBox.warningDialog(owner, "Ignite name must be unique!");
 
-        final Button downBtn = button(imageView("navigate_down", 24), "Move selected row down",
-            new EventHandler<ActionEvent>() {
-                @Override public void handle(ActionEvent evt) {
-                    TableView.TableViewSelectionModel<PojoField> selMdl = fieldsTbl.getSelectionModel();
-
-                    int selIdx = selMdl.getSelectedIndex();
-
-                    ObservableList<PojoField> items = fieldsTbl.getItems();
-
-                    int maxIdx = items.size() - 1;
-
-                    if (selIdx < maxIdx) {
-                        int newId = selIdx + 1;
-
-                        items.add(newId, items.remove(selIdx));
-
-                        if (newId == maxIdx)
-                            fieldsTbl.requestFocus();
-
-                        selMdl.select(newId);
+                            return false;
+                        }
 
-                    }
+                    return true;
                 }
             });
 
-        downBtn.setDisable(true);
+        TableColumn<PojoField, String> javaTypeNameCol = customColumn("Java Type", "javaTypeName",
+            "Field java type in POJO class", JavaTypeCell.cellFactory());
 
-        fieldsTbl.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
-            @Override public void changed(ObservableValue<? extends Number> observable, Number oldVal, Number newVal) {
-                upBtn.setDisable(newVal == null || newVal.intValue() == 0);
-                downBtn.setDisable(newVal == null || newVal.intValue() == fieldsTbl.getItems().size() - 1);
-            }
-        });
+        final TableView<PojoField> fieldsTbl = tableView("Select table to see table columns",
+            keyCol, dbNameCol, dbTypeNameCol, javaNameCol, javaTypeNameCol);
 
-        genPnl.add(splitPane(pojosTbl, borderPane(null, fieldsTbl, null, null, vBox(10, upBtn, downBtn)), 0.6), 3);
+        genPnl.add(splitPane(pojosTbl, fieldsTbl, 0.6), 3);
 
         final GridPaneEx keyValPnl = paneEx(0, 0, 0, 0);
         keyValPnl.addColumn(100, 100, Double.MAX_VALUE, Priority.ALWAYS);
@@ -704,62 +685,11 @@ public class SchemaLoadApp extends Application {
         keyValPnl.addColumn(100, 100, Double.MAX_VALUE, Priority.ALWAYS);
         keyValPnl.addColumn();
 
-//        keyValPnl.add(button("Apply", "Change key and value class names", new EventHandler<ActionEvent>() {
-//            @Override public void handle(ActionEvent evt) {
-//                if (checkInput(keyClsTf, true, "Key class name must not be empty!") ||
-//                    checkInput(valClsTf, true, "Value class name must not be empty!"))
-//                    return;
-//
-//                String keyCls = keyClsTf.getText().trim();
-//
-//                String valCls = valClsTf.getText().trim();
-//
-//                if (keyCls.equals(valCls)) {
-//                    MessageBox.warningDialog(owner, "Key class name must be different from value class name!");
-//
-//                    keyClsTf.requestFocus();
-//
-//                    return;
-//                }
-//
-//                for (PojoDescriptor pojo : pojos)
-//                    if (pojo != curPojo) {
-//                        String pojoKeyCls = pojo.keyClassName();
-//
-//                        String pojoValCls = pojo.valueClassName();
-//
-//                        if (keyCls.equals(pojoKeyCls) || keyCls.equals(pojoValCls)) {
-//                            MessageBox.warningDialog(owner, "Key class name must be unique!");
-//
-//                            keyClsTf.requestFocus();
-//
-//                            return;
-//                        }
-//
-//                        if (valCls.equals(pojoKeyCls) || valCls.equals(pojoValCls)) {
-//                            MessageBox.warningDialog(owner, "Value class name must be unique!");
-//
-//                            valClsTf.requestFocus();
-//
-//                            return;
-//                        }
-//                    }
-//
-//                curPojo.keyClassName(keyCls);
-//                curPojo.valueClassName(valCls);
-//            }
-//        }));
-//
-//        keyValPnl.setDisable(true);
-//
-//        genPnl.add(keyValPnl, 2);
-
         pkgTf = genPnl.addLabeled("Package:", textField("Package that will be used for POJOs generation"), 2);
 
         outFolderTf = genPnl.addLabeled("Output Folder:", textField("Output folder for XML and POJOs files"));
 
         genPnl.add(button("...", "Select output folder", new EventHandler<ActionEvent>() {
-            /** {@inheritDoc} */
             @Override public void handle(ActionEvent evt) {
                 DirectoryChooser dc = new DirectoryChooser();
 
@@ -794,7 +724,6 @@ public class SchemaLoadApp extends Application {
 
         final Button renBtn = button("Rename", "Replace Ignite names by provided regular expression for current table",
             new EventHandler<ActionEvent>() {
-                /** {@inheritDoc} */
                 @Override public void handle(ActionEvent evt) {
                     if (curPojo == null) {
                         MessageBox.warningDialog(owner, "Please select table to rename Ignite names!");
@@ -821,7 +750,6 @@ public class SchemaLoadApp extends Application {
         renBtn.setDisable(true);
 
         final Button revertBtn = button("Revert", "Revert changes to Ignite names for current table", new EventHandler<ActionEvent>() {
-            /** {@inheritDoc} */
             @Override public void handle(ActionEvent evt) {
                 if (curPojo != null)
                     curPojo.revertJavaNames();
@@ -835,7 +763,6 @@ public class SchemaLoadApp extends Application {
             renBtn,
             button("Rename All", "Replace Ignite names by provided regular expression for all selected tables",
                 new EventHandler<ActionEvent>() {
-                    /** {@inheritDoc} */
                     @Override public void handle(ActionEvent evt) {
                         if (checkInput(regexTf, false, "Regular expression should not be empty!"))
                             return;
@@ -868,7 +795,6 @@ public class SchemaLoadApp extends Application {
                 }),
             revertBtn,
             button("Revert All", "Revert changes to Ignite names for all selected tables", new EventHandler<ActionEvent>() {
-                /** {@inheritDoc} */
                 @Override public void handle(ActionEvent evt) {
                     Collection<PojoDescriptor> selItems = selectedItems();
 
@@ -891,7 +817,7 @@ public class SchemaLoadApp extends Application {
         pojosTbl.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<PojoDescriptor>() {
             @Override public void changed(ObservableValue<? extends PojoDescriptor> val,
                 PojoDescriptor oldVal, PojoDescriptor newItem) {
-                if (newItem != null && newItem.parent != null) {
+                if (newItem != null && newItem.parent() != null) {
                     curPojo = newItem;
 
                     fieldsTbl.setItems(curPojo.fields());
@@ -910,8 +836,6 @@ public class SchemaLoadApp extends Application {
 
                     renBtn.setDisable(true);
                     revertBtn.setDisable(true);
-                    upBtn.setDisable(true);
-                    downBtn.setDisable(true);
                 }
             }
         });
@@ -1043,260 +967,6 @@ public class SchemaLoadApp extends Application {
     }
 
     /**
-     * @param name Source name.
-     * @return String converted to java class name notation.
-     */
-    private String toJavaClassName(String name) {
-        int len = name.length();
-
-        StringBuilder buf = new StringBuilder(len);
-
-        boolean capitalizeNext = true;
-
-        for (int i = 0; i < len; i++) {
-            char ch = name.charAt(i);
-
-            if (Character.isWhitespace(ch) || '_' == ch)
-                capitalizeNext = true;
-            else if (capitalizeNext) {
-                buf.append(Character.toUpperCase(ch));
-
-                capitalizeNext = false;
-            }
-            else
-                buf.append(Character.toLowerCase(ch));
-        }
-
-        return buf.toString();
-    }
-
-    /**
-     * @param name Source name.
-     * @return String converted to java field name notation.
-     */
-    private String toJavaFieldName(String name) {
-        String javaName = toJavaClassName(name);
-
-        return Character.toLowerCase(javaName.charAt(0)) + javaName.substring(1);
-    }
-
-    /**
-     * Convert JDBC data type to java type.
-     *
-     * @param type JDBC SQL data type.
-     * @return Java data type.
-     */
-    private Class<?> dataType(int type) {
-        switch (type) {
-            case BIT:
-            case BOOLEAN:
-                return Boolean.class;
-
-            case TINYINT:
-                return Byte.class;
-
-            case SMALLINT:
-                return Short.class;
-
-            case INTEGER:
-                return Integer.class;
-
-            case BIGINT:
-                return Long.class;
-
-            case REAL:
-                return Float.class;
-
-            case FLOAT:
-            case DOUBLE:
-                return Double.class;
-
-            case NUMERIC:
-            case DECIMAL:
-                return BigDecimal.class;
-
-            case CHAR:
-            case VARCHAR:
-            case LONGVARCHAR:
-            case NCHAR:
-            case NVARCHAR:
-            case LONGNVARCHAR:
-                return String.class;
-
-            case DATE:
-                return Date.class;
-
-            case TIME:
-                return Time.class;
-
-            case TIMESTAMP:
-                return Timestamp.class;
-
-            case BINARY:
-            case VARBINARY:
-            case LONGVARBINARY:
-            case ARRAY:
-            case BLOB:
-            case CLOB:
-            case NCLOB:
-                return Array.class;
-
-            case NULL:
-                return Void.class;
-
-            case DATALINK:
-                return URL.class;
-
-            // OTHER, JAVA_OBJECT, DISTINCT, STRUCT, REF, ROWID, SQLXML
-            default:
-                return Object.class;
-        }
-    }
-
-    /**
-     * Parse database metadata.
-     *
-     * @param dbMeta Database metadata.
-     * @param catalog Catalog name.
-     * @param schema Schema name.
-     * @param tbl Table name.
-     * @return New initialized instance of {@code GridCacheQueryTypeMetadata}.
-     * @throws SQLException If parsing failed.
-     */
-    private PojoDescriptor parseTable(PojoDescriptor parent, DatabaseMetaData dbMeta, String catalog,
-        String schema, String tbl) throws SQLException {
-        GridCacheQueryTypeMetadata typeMeta = new GridCacheQueryTypeMetadata();
-
-        typeMeta.setSchema(schema);
-        typeMeta.setTableName(tbl);
-
-        typeMeta.setType(toJavaClassName(tbl));
-        typeMeta.setKeyType(typeMeta.getType() + "Key");
-
-        Collection<GridCacheQueryTypeDescriptor> keyDescs = typeMeta.getKeyDescriptors();
-        Collection<GridCacheQueryTypeDescriptor> valDescs = typeMeta.getValueDescriptors();
-
-        Map<String, Class<?>> qryFields = typeMeta.getQueryFields();
-        Map<String, Class<?>> ascFields = typeMeta.getAscendingFields();
-        Map<String, Class<?>> descFields = typeMeta.getDescendingFields();
-        Map<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> groups = typeMeta.getGroups();
-
-        Set<String> pkFlds = new LinkedHashSet<>();
-
-        try (ResultSet pk = dbMeta.getPrimaryKeys(catalog, schema, tbl)) {
-            while (pk.next())
-                pkFlds.add(pk.getString(4));
-        }
-
-        try (ResultSet flds = dbMeta.getColumns(catalog, schema, tbl, null)) {
-            while (flds.next()) {
-                String dbName = flds.getString(4);
-                int dbType = flds.getInt(5);
-
-                String javaName = toJavaFieldName(dbName);
-                Class<?> javaType = dataType(dbType);
-
-                GridCacheQueryTypeDescriptor desc = new GridCacheQueryTypeDescriptor(javaName, javaType, dbName, dbType);
-
-                if (pkFlds.contains(dbName))
-                    keyDescs.add(desc);
-                else
-                    valDescs.add(desc);
-
-                qryFields.put(javaName, javaType);
-            }
-        }
-
-        try (ResultSet idxs = dbMeta.getIndexInfo(catalog, schema, tbl, false, true)) {
-            while (idxs.next()) {
-                String idx = toJavaFieldName(idxs.getString(6));
-                String col = toJavaFieldName(idxs.getString(9));
-                String askOrDesc = idxs.getString(10);
-
-                LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>> idxCols = groups.get(idx);
-
-                if (idxCols == null) {
-                    idxCols = new LinkedHashMap<>();
-
-                    groups.put(idx, idxCols);
-                }
-
-                Class<?> dataType = qryFields.get(col);
-
-                Boolean desc = askOrDesc != null ? "D".equals(askOrDesc) : null;
-
-                if (desc != null) {
-                    if (desc)
-                        descFields.put(col, dataType);
-                    else
-                        ascFields.put(col, dataType);
-                }
-
-                idxCols.put(col, new IgniteBiTuple<Class<?>, Boolean>(dataType, desc));
-            }
-        }
-
-        List<PojoField> flds = new ArrayList<>();
-
-        return new PojoDescriptor(parent, typeMeta, flds);
-    }
-
-    /**
-     * Parse database metadata.
-     *
-     * @param conn Connection to database.
-     * @return Map with schemes and tables metadata.
-     * @throws SQLException If parsing failed.
-     */
-    private ObservableList<PojoDescriptor> parse(Connection conn) throws SQLException {
-        DatabaseMetaData dbMeta = conn.getMetaData();
-
-        List<PojoDescriptor> res = new ArrayList<>();
-
-        try (ResultSet schemas = dbMeta.getSchemas()) {
-            while (schemas.next()) {
-                String schema = schemas.getString(1);
-
-                // Skip system tables from INFORMATION_SCHEMA.
-                if ("INFORMATION_SCHEMA".equalsIgnoreCase(schema))
-                    continue;
-
-                String catalog = schemas.getString(2);
-
-                PojoDescriptor parent = PojoDescriptor.createSchema(schema);
-
-                List<PojoDescriptor> children = new ArrayList<>();
-
-                try (ResultSet tbls = dbMeta.getTables(catalog, schema, "%", null)) {
-                    while (tbls.next()) {
-                        String tbl = tbls.getString(3);
-
-                        children.add(parseTable(parent, dbMeta, catalog, schema, tbl));
-                    }
-                }
-
-                if (!children.isEmpty()) {
-                    parent.children(children);
-
-                    res.add(parent);
-                    res.addAll(children);
-                }
-            }
-        }
-
-        Collections.sort(res, new Comparator<PojoDescriptor>() {
-            @Override public int compare(PojoDescriptor o1, PojoDescriptor o2) {
-                GridCacheQueryTypeMetadata t1 = o1.typeMeta;
-                GridCacheQueryTypeMetadata t2 = o2.typeMeta;
-
-                return (t1.getSchema() + t1.getTableName()).compareTo(t2.getSchema() + t2.getTableName());
-            }
-        });
-
-        return FXCollections.observableList(res);
-    }
-
-    /**
      * Schema load utility launcher.
      *
      * @param args Command line arguments passed to the application.
@@ -1330,568 +1000,6 @@ public class SchemaLoadApp extends Application {
     }
 
     /**
-     * Field descriptor with properties for JavaFX GUI bindings.
-     */
-    public static class PojoField {
-        /** If this field belongs to primary key. */
-        private final BooleanProperty key;
-
-        /** Field name for POJO. */
-        private final StringProperty javaName;
-
-        /** Field type for POJO. */
-        private final StringProperty javaTypeName;
-
-        /** Field name in database. */
-        private final StringProperty dbName;
-
-        /** Field type in database. */
-        private final StringProperty dbTypeName;
-
-        /** Is NULL allowed for field in database. */
-        private final boolean nullable;
-
-        /** Field type descriptor. */
-        private final GridCacheQueryTypeDescriptor desc;
-
-        /** List of possible java type conversions. */
-        private final ObservableList<String> conversions;
-
-        /** */
-        private static final Map<String, Class<?>> classesMap = new HashMap<>();
-
-        /**
-         * @param clss Class to add.
-         */
-        private static void fillClassesMap(Class<?>... clss) {
-            for (Class<?> cls : clss)
-                classesMap.put(cls.getName(), cls);
-        }
-
-        /**
-         * @param clss List of classes to get class names.
-         * @return List of classes names to show in UI for manual select.
-         */
-        private static List<String> classNames(Class<?>... clss) {
-            List<String> names = new ArrayList<>(clss.length);
-
-            for (Class<?> cls : clss)
-                names.add(cls.getName());
-
-            return names;
-        }
-
-        /** Null number conversions. */
-        private static final ObservableList<String> NULL_NUM_CONVERSIONS = FXCollections.observableArrayList();
-
-        /** Not null number conversions. */
-        private static final ObservableList<String> NOT_NULL_NUM_CONVERSIONS = FXCollections.observableArrayList();
-
-        static {
-            List<String> primitives = classNames(boolean.class, byte.class, short.class,
-                int.class, long.class, float.class, double.class);
-
-            List<String> objects = classNames(Boolean.class, Byte.class, Short.class, Integer.class,
-                Long.class, Float.class, Double.class, BigDecimal.class);
-
-            NULL_NUM_CONVERSIONS.addAll(objects);
-
-            NOT_NULL_NUM_CONVERSIONS.addAll(primitives);
-            NOT_NULL_NUM_CONVERSIONS.addAll(objects);
-
-            fillClassesMap(boolean.class, Boolean.class,
-                byte.class, Byte.class,
-                short.class, Short.class,
-                int.class, Integer.class,
-                long.class, Long.class,
-                float.class, Float.class,
-                double.class, Double.class,
-                BigDecimal.class,
-                String.class,
-                java.sql.Date.class, java.sql.Time.class, java.sql.Timestamp.class,
-                Array.class, Void.class, URL.class, Object.class);
-        }
-
-        /**
-         * @param dbType Database type.
-         * @param nullable Nullable.
-         * @param dflt Default.
-         * @return List of possible type conversions.
-         */
-        private static ObservableList<String> conversions(int dbType, boolean nullable, String dflt) {
-            switch (dbType) {
-                case TINYINT:
-                case SMALLINT:
-                case INTEGER:
-                case BIGINT:
-                case REAL:
-                case FLOAT:
-                case DOUBLE:
-                    return nullable ? NULL_NUM_CONVERSIONS : NOT_NULL_NUM_CONVERSIONS;
-
-                default:
-                    return FXCollections.singletonObservableList(dflt);
-            }
-        }
-
-        /**
-         * @param key {@code true} if this field belongs to primary key.
-         * @param nullable {@code true} if {@code NULL} is allowed for this field in database.
-         * @param desc Field type descriptor.
-         */
-        private PojoField(boolean key, boolean nullable, GridCacheQueryTypeDescriptor desc) {
-            this.desc = desc;
-            this.key = new SimpleBooleanProperty(key);
-
-            javaName = new SimpleStringProperty(desc.getJavaName());
-
-            String typeName = desc.getJavaType().getName();
-
-            javaTypeName = new SimpleStringProperty(typeName);
-
-            dbName = new SimpleStringProperty(desc.getDbName());
-
-            dbTypeName = new SimpleStringProperty(jdbcTypeName(desc.getDbType()));
-
-            this.nullable = nullable;
-
-            conversions = conversions(desc.getDbType(), nullable, typeName);
-        }
-
-        /**
-         * Copy constructor.
-         *
-         * @param src Source POJO field descriptor.
-         */
-        private PojoField(PojoField src) {
-            this(src.key(), src.nullable(), src.descriptor());
-        }
-
-        /**
-         * @param jdbcType String name for JDBC type.
-         */
-        private String jdbcTypeName(int jdbcType) {
-            switch (jdbcType) {
-                case BIT:
-                    return "BIT";
-                case TINYINT:
-                    return "TINYINT";
-                case SMALLINT:
-                    return "SMALLINT";
-                case INTEGER:
-                    return "INTEGER";
-                case BIGINT:
-                    return "BIGINT";
-                case FLOAT:
-                    return "FLOAT";
-                case REAL:
-                    return "REAL";
-                case DOUBLE:
-                    return "DOUBLE";
-                case NUMERIC:
-                    return "NUMERIC";
-                case DECIMAL:
-                    return "DECIMAL";
-                case CHAR:
-                    return "CHAR";
-                case VARCHAR:
-                    return "VARCHAR";
-                case LONGVARCHAR:
-                    return "LONGVARCHAR";
-                case DATE:
-                    return "DATE";
-                case TIME:
-                    return "TIME";
-                case TIMESTAMP:
-                    return "TIMESTAMP";
-                case BINARY:
-                    return "BINARY";
-                case VARBINARY:
-                    return "VARBINARY";
-                case LONGVARBINARY:
-                    return "LONGVARBINARY";
-                case NULL:
-                    return "NULL";
-                case OTHER:
-                    return "OTHER";
-                case JAVA_OBJECT:
-                    return "JAVA_OBJECT";
-                case DISTINCT:
-                    return "DISTINCT";
-                case STRUCT:
-                    return "STRUCT";
-                case ARRAY:
-                    return "ARRAY";
-                case BLOB:
-                    return "BLOB";
-                case CLOB:
-                    return "CLOB";
-                case REF:
-                    return "REF";
-                case DATALINK:
-                    return "DATALINK";
-                case BOOLEAN:
-                    return "BOOLEAN";
-                case ROWID:
-                    return "ROWID";
-                case NCHAR:
-                    return "NCHAR";
-                case NVARCHAR:
-                    return "NVARCHAR";
-                case LONGNVARCHAR:
-                    return "LONGNVARCHAR";
-                case NCLOB:
-                    return "NCLOB";
-                case SQLXML:
-                    return "SQLXML";
-                default:
-                    return "Unknown";
-            }
-        }
-
-        /**
-         * @return {@code true} if this field belongs to primary key.
-         */
-        public boolean key() {
-            return key.get();
-        }
-
-        /**
-         * @param pk {@code true} if this field belongs to primary key.
-         */
-        public void key(boolean pk) {
-            key.set(pk);
-        }
-
-        /**
-         * @return POJO field java name.
-         */
-        public String javaName() {
-            return javaName.get();
-        }
-
-        /**
-         * @param name POJO field java name.
-         */
-        public void javaName(String name) {
-            javaName.set(name);
-        }
-
-        /**
-         * @return POJO field java type name.
-         */
-        public String javaTypeName() {
-            return javaTypeName.get();
-        }
-
-        /**
-         * @return Type descriptor.
-         */
-        public GridCacheQueryTypeDescriptor descriptor() {
-            desc.setJavaName(javaName.get());
-            desc.setJavaType(classesMap.get(javaTypeName()));
-
-            return desc;
-        }
-
-        /**
-         * @return Is NULL allowed for field in database.
-         */
-        public boolean nullable() {
-            return nullable;
-        }
-
-        /**
-         * @return POJO field JDBC type in database.
-         */
-        public int dbType() {
-            return desc.getDbType();
-        }
-
-        /**
-         * @return Boolean property support for {@code key} property.
-         */
-        public BooleanProperty keyProperty() {
-            return key;
-        }
-
-        /**
-         * @return String property support for {@code javaName} property.
-         */
-        public StringProperty javaNameProperty() {
-            return javaName;
-        }
-
-        /**
-         * @return String property support for {@code javaTypeName} property.
-         */
-        public StringProperty javaTypeNameProperty() {
-            return javaTypeName;
-        }
-
-        /**
-         * @return String property support for {@code dbName} property.
-         */
-        public StringProperty dbNameProperty() {
-            return dbName;
-        }
-
-        /**
-         * @return String property support for {@code dbName} property.
-         */
-        public StringProperty dbTypeNameProperty() {
-            return dbTypeName;
-        }
-
-        /**
-         * @return List of possible java type conversions.
-         */
-        public ObservableList<String> conversions() {
-            return conversions;
-        }
-    }
-
-    /**
-     * Descriptor for java type.
-     */
-    public static class PojoDescriptor {
-        /** Selected property. */
-        private final BooleanProperty use;
-
-        /** Schema name to show on screen. */
-        private final String schema;
-
-        /** Table name to show on screen. */
-        private final String tbl;
-
-        /** Key class name to show on screen. */
-        private final StringProperty keyClsName;
-
-        /** Previous name for key class. */
-        private final String keyClsNamePrev;
-
-        /** Value class name to show on screen. */
-        private final StringProperty valClsName;
-
-        /** Previous name for value class. */
-        private final String valClsNamePrev;
-
-        /** Parent item (schema name). */
-        private final PojoDescriptor parent;
-
-        /** Children items (tables names). */
-        private Collection<PojoDescriptor> children = Collections.emptyList();
-
-        /** Indeterminate state of parent. */
-        private final BooleanProperty indeterminate = new SimpleBooleanProperty(false);
-
-        /** Java class fields. */
-        private final ObservableList<PojoField> fields;
-
-        /** Java class fields. */
-        private final List<PojoField> fieldsPrev;
-
-        /** Type metadata. */
-        private final GridCacheQueryTypeMetadata typeMeta;
-
-        private static PojoDescriptor createSchema(String schema) {
-            GridCacheQueryTypeMetadata schemaMeta = new GridCacheQueryTypeMetadata();
-
-            schemaMeta.setSchema(schema);
-            schemaMeta.setTableName("");
-
-            return new PojoDescriptor(null, schemaMeta, Collections.<PojoField>emptyList());
-        }
-
-        /**
-         * @param prn
-         * @param typeMeta
-         * @param flds
-         */
-        private PojoDescriptor(PojoDescriptor prn, GridCacheQueryTypeMetadata typeMeta, List<PojoField> flds) {
-            parent = prn;
-
-            boolean isTbl = parent != null;
-
-            schema = isTbl ? "" : typeMeta.getSchema();
-            tbl = isTbl ? typeMeta.getTableName() : "";
-
-            keyClsNamePrev = isTbl ? typeMeta.getKeyType() : "";
-            keyClsName = new SimpleStringProperty(keyClsNamePrev);
-
-            valClsNamePrev = isTbl ? typeMeta.getType() : "";
-            valClsName = new SimpleStringProperty(valClsNamePrev);
-
-            use = new SimpleBooleanProperty(true);
-
-            use.addListener(new ChangeListener<Boolean>() {
-                @Override public void changed(ObservableValue<? extends Boolean> val, Boolean oldVal, Boolean newVal) {
-                    for (PojoDescriptor child : children)
-                        child.use.set(newVal);
-
-                    if (parent != null && !parent.children.isEmpty()) {
-                        Iterator<PojoDescriptor> it = parent.children.iterator();
-
-                        boolean parentIndeterminate = false;
-                        boolean first = it.next().use.get();
-
-                        while (it.hasNext()) {
-                            if (it.next().use.get() != first) {
-                                parentIndeterminate = true;
-
-                                break;
-                            }
-                        }
-
-                        parent.indeterminate.set(parentIndeterminate);
-
-                        if (!parentIndeterminate)
-                            parent.use.set(first);
-                    }
-                }
-            });
-
-            if (isTbl) {
-                fieldsPrev = new ArrayList<>(flds.size());
-
-                for (PojoField fld : flds)
-                    fieldsPrev.add(new PojoField(fld));
-
-                fields = FXCollections.observableList(flds);
-
-//                Collection<GridCacheQueryTypeDescriptor> keys = typeMeta.getKeyDescriptors();
-//
-//                Collection<GridCacheQueryTypeDescriptor> vals = typeMeta.getValueDescriptors();
-//
-//                int sz = keys.size() + vals.size();
-//
-//                List<PojoField> flds = new ArrayList<>(sz);
-//                fieldsPrev = new ArrayList<>(sz);
-//
-//                for (GridCacheQueryTypeDescriptor key : keys) {
-//                    flds.add(new PojoField(true, false /* TODO: IGNITE-32 FIX nullable*/, key));
-//                    fieldsPrev.add(new PojoField(true, false /* TODO: IGNITE-32 FIX nullable*/, key));
-//                }
-//
-//                for (GridCacheQueryTypeDescriptor val : vals) {
-//                    flds.add(new PojoField(false, false /* TODO: IGNITE-32 FIX nullable*/, val));
-//                    fieldsPrev.add(new PojoField(false, false /* TODO: IGNITE-32 FIX nullable*/, val));
-//                }
-//
-//                fields = FXCollections.observableList(flds);
-            }
-            else {
-                fields = FXCollections.emptyObservableList();
-                fieldsPrev = FXCollections.emptyObservableList();
-            }
-
-            this.typeMeta = typeMeta;
-        }
-
-        /**
-         * @return {@code true} if POJO descriptor is a table descriptor and selected in GUI.
-         */
-        public boolean selected() {
-            return parent != null && use.get();
-        }
-
-        /**
-         * @return Boolean property support for {@code use} property.
-         */
-        public BooleanProperty useProperty() {
-            return use;
-        }
-
-        /**
-         * @return Boolean property support for parent {@code indeterminate} property.
-         */
-        public BooleanProperty indeterminate() {
-            return indeterminate;
-        }
-
-        /**
-         * @return Key class name property.
-         */
-        public StringProperty keyClassProperty() {
-            return keyClsName;
-        }
-
-        /**
-         * @return Value class name property.
-         */
-        public StringProperty valueClassProperty() {
-            return valClsName;
-        }
-
-        /**
-         * @return Schema name.
-         */
-        public String schema() {
-            return schema;
-        }
-
-        /**
-         * @return Table name.
-         */
-        public String table() {
-            return tbl;
-        }
-
-        /**
-         * Sets children items.
-         *
-         * @param children Items to set.
-         */
-        public void children(Collection<PojoDescriptor> children) {
-            this.children = children;
-        }
-
-        /**
-         * @return {@code true} if descriptor was changed by user via GUI.
-         */
-        public boolean changed() {
-            boolean diff = !keyClsName.get().equals(keyClsNamePrev) || !valClsName.get().equals(valClsNamePrev);
-
-            if (!diff)
-                for (int i = 0; i < fields.size(); i++) {
-                    PojoField cur = fields.get(i);
-                    PojoField prev = fieldsPrev.get(i);
-
-                    // User can change via GUI only key and java name properties.
-                    if (cur.key() != prev.key() || !cur.javaName().equals(prev.javaName())) {
-                        diff = true;
-
-                        break;
-                    }
-                }
-
-            return diff;
-        }
-
-        /**
-         * Revert changes to java names made by user.
-         */
-        public void revertJavaNames() {
-            for (int i = 0; i < fields.size(); i++)
-                fields.get(i).javaName(fieldsPrev.get(i).javaName());
-        }
-
-        /**
-         * @return Java class fields.
-         */
-        public ObservableList<PojoField> fields() {
-            return fields;
-        }
-
-        /**
-         * @return Type metadata.
-         */
-        public GridCacheQueryTypeMetadata metadata() {
-            return typeMeta;
-        }
-    }
-
-    /**
      * Special table cell to select possible java type conversions.
      */
     private static class JavaTypeCell extends TableCell<PojoField, String> {
@@ -1901,7 +1009,6 @@ public class SchemaLoadApp extends Application {
         /** Creates a ComboBox cell factory for use in TableColumn controls. */
         public static Callback<TableColumn<PojoField, String>, TableCell<PojoField, String>> cellFactory() {
             return new Callback<TableColumn<PojoField, String>, TableCell<PojoField, String>>() {
-                /** {@inheritDoc} */
                 @Override public TableCell<PojoField, String> call(TableColumn<PojoField, String> col) {
                     return new JavaTypeCell();
                 }
@@ -1915,7 +1022,6 @@ public class SchemaLoadApp extends Application {
             comboBox = new ComboBox<>(FXCollections.<String>emptyObservableList());
 
             comboBox.valueProperty().addListener(new ChangeListener<String>() {
-                /** {@inheritDoc} */
                 @Override public void changed(ObservableValue<? extends String> val, String oldVal, String newVal) {
                     if (isEditing())
                         commitEdit(newVal);
@@ -1969,17 +1075,19 @@ public class SchemaLoadApp extends Application {
     /**
      * Special table cell to select schema or table.
      */
-    private static class SchemaCell extends TableCell<PojoDescriptor, Boolean> {
+    private static class PojoDescriptorCell extends TableCell<PojoDescriptor, Boolean> {
         /** Creates a ComboBox cell factory for use in TableColumn controls. */
         public static Callback<TableColumn<PojoDescriptor, Boolean>, TableCell<PojoDescriptor, Boolean>> cellFactory() {
             return new Callback<TableColumn<PojoDescriptor, Boolean>, TableCell<PojoDescriptor, Boolean>>() {
-                /** {@inheritDoc} */
                 @Override public TableCell<PojoDescriptor, Boolean> call(TableColumn<PojoDescriptor, Boolean> col) {
-                    return new SchemaCell();
+                    return new PojoDescriptorCell();
                 }
             };
         }
 
+        /** Previous POJO bound to cell. */
+        private PojoDescriptor prevPojo;
+
         /** {@inheritDoc} */
         @Override public void updateItem(Boolean item, boolean empty) {
             super.updateItem(item, empty);
@@ -1988,16 +1096,20 @@ public class SchemaLoadApp extends Application {
                 TableRow row = getTableRow();
 
                 if (row != null) {
-                    final PojoDescriptor schemaItem = (PojoDescriptor)row.getItem();
+                    final PojoDescriptor pojo = (PojoDescriptor)row.getItem();
 
-                    if (schemaItem != null && getGraphic() == null) {
-                        boolean isTbl = schemaItem.schema.isEmpty();
+                    if (pojo != prevPojo) {
+                        prevPojo = pojo;
 
-                        final CheckBox ch = new CheckBox(isTbl ? schemaItem.table() : schemaItem.schema());
+                        boolean isTbl = pojo.parent() != null;
+
+                        CheckBox ch = new CheckBox(isTbl ? pojo.table() : pojo.schema());
 
                         ch.setAllowIndeterminate(false);
-                        ch.selectedProperty().bindBidirectional(schemaItem.useProperty());
-                        ch.indeterminateProperty().bindBidirectional(schemaItem.indeterminate());
+                        ch.setMnemonicParsing(false);
+
+                        ch.indeterminateProperty().bindBidirectional(pojo.indeterminate());
+                        ch.selectedProperty().bindBidirectional(pojo.useProperty());
 
                         Pane pnl = new HBox();
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/69feb392/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/TextColumnValidator.java
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/TextColumnValidator.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/TextColumnValidator.java
new file mode 100644
index 0000000..d92ae08
--- /dev/null
+++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/TextColumnValidator.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.ignite.schema.ui;
+
+/**
+ * Validator for editable table view text column.
+ */
+public interface TextColumnValidator<T> {
+    /**
+     * Validate new value of text.
+     *
+     * @param rowVal Row value.
+     * @param newVal New value of text.
+     * @return {@code true} if text is valid.
+     */
+    public boolean valid(T rowVal, String newVal);
+}


Mime
View raw message