ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akuznet...@apache.org
Subject [01/18] ignite git commit: Web console beta-4.
Date Wed, 28 Sep 2016 02:26:41 GMT
Repository: ignite
Updated Branches:
  refs/heads/master f77f93cd2 -> 4ffb5860b


http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/app/services/LegacyUtils.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/services/LegacyUtils.service.js b/modules/web-console/frontend/app/services/LegacyUtils.service.js
index ed555a1..dcf0bc8 100644
--- a/modules/web-console/frontend/app/services/LegacyUtils.service.js
+++ b/modules/web-console/frontend/app/services/LegacyUtils.service.js
@@ -122,45 +122,6 @@ export default ['IgniteLegacyUtils', ['IgniteErrorPopover', (ErrorPopover) => {
         'VARCHAR'
     ];
 
-    const ALL_JDBC_TYPES = [
-        {dbName: 'BIT', dbType: -7, javaType: 'Boolean', primitiveType: 'boolean'},
-        {dbName: 'TINYINT', dbType: -6, javaType: 'Byte', primitiveType: 'byte'},
-        {dbName: 'SMALLINT', dbType: 5, javaType: 'Short', primitiveType: 'short'},
-        {dbName: 'INTEGER', dbType: 4, javaType: 'Integer', primitiveType: 'int'},
-        {dbName: 'BIGINT', dbType: -5, javaType: 'Long', primitiveType: 'long'},
-        {dbName: 'FLOAT', dbType: 6, javaType: 'Float', primitiveType: 'float'},
-        {dbName: 'REAL', dbType: 7, javaType: 'Double', primitiveType: 'double'},
-        {dbName: 'DOUBLE', dbType: 8, javaType: 'Double', primitiveType: 'double'},
-        {dbName: 'NUMERIC', dbType: 2, javaType: 'BigDecimal'},
-        {dbName: 'DECIMAL', dbType: 3, javaType: 'BigDecimal'},
-        {dbName: 'CHAR', dbType: 1, javaType: 'String'},
-        {dbName: 'VARCHAR', dbType: 12, javaType: 'String'},
-        {dbName: 'LONGVARCHAR', dbType: -1, javaType: 'String'},
-        {dbName: 'DATE', dbType: 91, javaType: 'Date'},
-        {dbName: 'TIME', dbType: 92, javaType: 'Time'},
-        {dbName: 'TIMESTAMP', dbType: 93, javaType: 'Timestamp'},
-        {dbName: 'BINARY', dbType: -2, javaType: 'Object'},
-        {dbName: 'VARBINARY', dbType: -3, javaType: 'Object'},
-        {dbName: 'LONGVARBINARY', dbType: -4, javaType: 'Object'},
-        {dbName: 'NULL', dbType: 0, javaType: 'Object'},
-        {dbName: 'OTHER', dbType: 1111, javaType: 'Object'},
-        {dbName: 'JAVA_OBJECT', dbType: 2000, javaType: 'Object'},
-        {dbName: 'DISTINCT', dbType: 2001, javaType: 'Object'},
-        {dbName: 'STRUCT', dbType: 2002, javaType: 'Object'},
-        {dbName: 'ARRAY', dbType: 2003, javaType: 'Object'},
-        {dbName: 'BLOB', dbType: 2004, javaType: 'Object'},
-        {dbName: 'CLOB', dbType: 2005, javaType: 'String'},
-        {dbName: 'REF', dbType: 2006, javaType: 'Object'},
-        {dbName: 'DATALINK', dbType: 70, javaType: 'Object'},
-        {dbName: 'BOOLEAN', dbType: 16, javaType: 'Boolean', primitiveType: 'boolean'},
-        {dbName: 'ROWID', dbType: -8, javaType: 'Object'},
-        {dbName: 'NCHAR', dbType: -15, javaType: 'String'},
-        {dbName: 'NVARCHAR', dbType: -9, javaType: 'String'},
-        {dbName: 'LONGNVARCHAR', dbType: -16, javaType: 'String'},
-        {dbName: 'NCLOB', dbType: 2011, javaType: 'String'},
-        {dbName: 'SQLXML', dbType: 2009, javaType: 'Object'}
-    ];
-
     /*eslint-disable */
     const JAVA_KEYWORDS = [
         'abstract',
@@ -361,11 +322,6 @@ export default ['IgniteLegacyUtils', ['IgniteErrorPopover', (ErrorPopover) => {
         },
         isEmptyString,
         SUPPORTED_JDBC_TYPES,
-        findJdbcType(jdbcType) {
-            const res = _.find(ALL_JDBC_TYPES, (item) => item.dbType === jdbcType);
-
-            return res ? res : {dbName: 'Unknown', javaType: 'Unknown'};
-        },
         javaBuiltInClasses,
         javaBuiltInTypes,
         isJavaBuiltInClass,

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/app/services/SqlTypes.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/services/SqlTypes.service.js b/modules/web-console/frontend/app/services/SqlTypes.service.js
new file mode 100644
index 0000000..2a16e9d
--- /dev/null
+++ b/modules/web-console/frontend/app/services/SqlTypes.service.js
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+import _ from 'lodash';
+
+// List of H2 reserved SQL keywords.
+import H2_SQL_KEYWORDS from '../data/sql-keywords.json';
+
+// List of JDBC type descriptors.
+import JDBC_TYPES from '../data/jdbc-types.json';
+
+// Regular expression to check H2 SQL identifier.
+const VALID_IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_$]*$/im;
+
+// Descriptor for unknown JDBC type.
+const UNKNOWN_JDBC_TYPE = {
+    dbName: 'Unknown',
+    signed: {javaType: 'Unknown', primitiveType: 'Unknown'},
+    unsigned: {javaType: 'Unknown', primitiveType: 'Unknown'}
+};
+
+/**
+ * Utility service for various check on SQL types.
+ */
+export default class SqlTypes {
+    /**
+     * @param value {String} Value to check.
+     * @returns {boolean} 'true' if given text is valid Java class name.
+     */
+    validIdentifier(value) {
+        return !!(value && VALID_IDENTIFIER.test(value));
+    }
+
+    /**
+     * @param value {String} Value to check.
+     * @returns {boolean} 'true' if given text is one of H2 reserved keywords.
+     */
+    isKeyword(value) {
+        return !!(value && _.includes(H2_SQL_KEYWORDS, value.toUpperCase()));
+    }
+
+    /**
+     * Find JDBC type descriptor for specified JDBC type and options.
+     *
+     * @param dbType {Number} Column db type.
+     * @return {String} Java type.
+     */
+    findJdbcType(dbType) {
+        const jdbcType = _.find(JDBC_TYPES, (item) => item.dbType === dbType);
+
+        return jdbcType ? jdbcType : UNKNOWN_JDBC_TYPE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/controllers/admin-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/admin-controller.js b/modules/web-console/frontend/controllers/admin-controller.js
index 57a39b2..7004301 100644
--- a/modules/web-console/frontend/controllers/admin-controller.js
+++ b/modules/web-console/frontend/controllers/admin-controller.js
@@ -17,8 +17,8 @@
 
 // Controller for Admin screen.
 export default ['adminController', [
-    '$rootScope', '$scope', '$http', '$q', '$state', 'IgniteMessages', 'IgniteConfirm', 'User', 'IgniteCountries',
-    ($rootScope, $scope, $http, $q, $state, Messages, Confirm, User, Countries) => {
+    '$rootScope', '$scope', '$http', '$q', '$state', 'IgniteMessages', 'IgniteConfirm', 'User', 'IgniteNotebookData', 'IgniteCountries',
+    ($rootScope, $scope, $http, $q, $state, Messages, Confirm, User, Notebook, Countries) => {
         $scope.users = null;
 
         const _reloadUsers = () => {
@@ -41,12 +41,13 @@ export default ['adminController', [
         $scope.becomeUser = function(user) {
             $http.get('/api/v1/admin/become', { params: {viewedUserId: user._id}})
                 .catch(({data}) => Promise.reject(data))
-                .then(User.load)
+                .then(() => User.load())
                 .then((becomeUser) => {
                     $rootScope.$broadcast('user', becomeUser);
 
                     $state.go('base.configuration.clusters');
                 })
+                .then(() => Notebook.load())
                 .catch(Messages.showError);
         };
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/controllers/domains-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/domains-controller.js b/modules/web-console/frontend/controllers/domains-controller.js
index 6cb3540..2d450db 100644
--- a/modules/web-console/frontend/controllers/domains-controller.js
+++ b/modules/web-console/frontend/controllers/domains-controller.js
@@ -17,8 +17,8 @@
 
 // Controller for Domain model screen.
 export default ['domainsController', [
-    '$rootScope', '$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteConfirmBatch', 'IgniteClone', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteAgentMonitor', 'IgniteLegacyTable', 'igniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils',
-    function($root, $scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Focus, Confirm, ConfirmBatch, Clone, Loading, ModelNormalizer, UnsavedChangesGuard, IgniteAgentMonitor, LegacyTable, Resource, ErrorPopover, FormUtils) {
+    '$rootScope', '$scope', '$http', '$state', '$filter', '$timeout', '$modal', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteConfirmBatch', 'IgniteClone', 'IgniteLoading', 'IgniteModelNormalizer', 'IgniteUnsavedChangesGuard', 'IgniteAgentMonitor', 'IgniteLegacyTable', 'igniteConfigurationResource', 'IgniteErrorPopover', 'IgniteFormUtils', 'JavaTypes', 'SqlTypes',
+    function($root, $scope, $http, $state, $filter, $timeout, $modal, LegacyUtils, Messages, Focus, Confirm, ConfirmBatch, Clone, Loading, ModelNormalizer, UnsavedChangesGuard, IgniteAgentMonitor, LegacyTable, Resource, ErrorPopover, FormUtils, JavaTypes, SqlTypes) {
         UnsavedChangesGuard.install($scope);
 
         const emptyDomain = {empty: true};
@@ -533,10 +533,15 @@ export default ['domainsController', [
             return 'Associate with ' + cacheName;
         };
 
-        function toJavaClassName(name) {
+        function isValidJavaIdentifier(s) {
+            return JavaTypes.validIdentifier(s) && !JavaTypes.isKeyword(s) &&
+                SqlTypes.validIdentifier(s) && !SqlTypes.isKeyword(s);
+        }
+
+        function toJavaIdentifier(name) {
             const len = name.length;
 
-            let buf = '';
+            let ident = '';
 
             let capitalizeNext = true;
 
@@ -546,21 +551,35 @@ export default ['domainsController', [
                 if (ch === ' ' || ch === '_')
                     capitalizeNext = true;
                 else if (capitalizeNext) {
-                    buf += ch.toLocaleUpperCase();
+                    ident += ch.toLocaleUpperCase();
 
                     capitalizeNext = false;
                 }
                 else
-                    buf += ch.toLocaleLowerCase();
+                    ident += ch.toLocaleLowerCase();
             }
 
-            return buf;
+            return ident;
         }
 
-        function toJavaName(dbName) {
-            const javaName = toJavaClassName(dbName);
+        function toJavaClassName(name) {
+            const clazzName = toJavaIdentifier(name);
+
+            if (isValidJavaIdentifier(clazzName))
+                return clazzName;
 
-            return javaName.charAt(0).toLocaleLowerCase() + javaName.slice(1);
+            return 'Class' + clazzName;
+        }
+
+        function toJavaFieldName(dbName) {
+            const javaName = toJavaIdentifier(dbName);
+
+            const fieldName = javaName.charAt(0).toLocaleLowerCase() + javaName.slice(1);
+
+            if (isValidJavaIdentifier(fieldName))
+                return fieldName;
+
+            return 'field' + javaName;
         }
 
         function _fillCommonCachesOrTemplates(item) {
@@ -588,6 +607,7 @@ export default ['domainsController', [
                     item.cacheOrTemplate = item.cachesOrTemplates[0].value;
             };
         }
+
         /**
          * Load list of database tables.
          */
@@ -752,18 +772,16 @@ export default ['domainsController', [
             let containKey = true;
             let containDup = false;
 
-            function queryField(name, jdbcType) {
-                return {name: toJavaName(name), className: jdbcType.javaType};
-            }
+            function dbField(name, jdbcType, nullable, unsigned) {
+                const javaTypes = (unsigned && jdbcType.unsigned) ? jdbcType.unsigned : jdbcType.signed;
+                const javaFieldType = (!nullable && javaTypes.primitiveType && $scope.ui.usePrimitives) ? javaTypes.primitiveType : javaTypes.javaType;
 
-            function dbField(name, jdbcType, nullable) {
                 return {
-                    jdbcType,
                     databaseFieldName: name,
                     databaseFieldType: jdbcType.dbName,
-                    javaFieldName: toJavaName(name),
-                    javaFieldType: nullable ? jdbcType.javaType :
-                        ($scope.ui.usePrimitives && jdbcType.primitiveType ? jdbcType.primitiveType : jdbcType.javaType)
+                    javaType: javaTypes.javaType,
+                    javaFieldName: toJavaFieldName(name),
+                    javaFieldType
                 };
             }
 
@@ -790,17 +808,17 @@ export default ['domainsController', [
                     let _containKey = false;
 
                     _.forEach(table.cols, function(col) {
-                        const colName = col.name;
-                        const jdbcType = LegacyUtils.findJdbcType(col.type);
-                        const nullable = col.nullable;
+                        const fld = dbField(col.name, SqlTypes.findJdbcType(col.type), col.nullable, col.unsigned);
 
-                        qryFields.push(queryField(colName, jdbcType));
+                        qryFields.push({name: fld.javaFieldName, className: fld.javaType});
 
-                        const fld = dbField(colName, jdbcType, nullable);
+                        const dbName = fld.databaseFieldName;
 
-                        if ($scope.ui.generateAliases && !_.find(aliases, {field: fld.javaFieldName}) &&
-                            fld.javaFieldName.toUpperCase() !== fld.databaseFieldName.toUpperCase())
-                            aliases.push({field: fld.javaFieldName, alias: fld.databaseFieldName});
+                        if ($scope.ui.generateAliases &&
+                            SqlTypes.validIdentifier(dbName) && !SqlTypes.isKeyword(dbName) &&
+                            !_.find(aliases, {field: fld.javaFieldName}) &&
+                            fld.javaFieldName.toUpperCase() !== dbName.toUpperCase())
+                            aliases.push({field: fld.javaFieldName, alias: dbName});
 
                         if (col.key) {
                             keyFields.push(fld);
@@ -820,7 +838,7 @@ export default ['domainsController', [
                             indexes.push({
                                 name: idx.name, indexType: 'SORTED', fields: _.map(fields, function(fieldName) {
                                     return {
-                                        name: toJavaName(fieldName),
+                                        name: toJavaFieldName(fieldName),
                                         direction: idx.fields[fieldName]
                                     };
                                 })
@@ -828,9 +846,7 @@ export default ['domainsController', [
                         });
                     }
 
-                    const domainFound = _.find($scope.domains, function(domain) {
-                        return domain.valueType === valType;
-                    });
+                    const domainFound = _.find($scope.domains, (domain) => domain.valueType === valType);
 
                     const newDomain = {
                         confirm: false,
@@ -864,17 +880,13 @@ export default ['domainsController', [
                     if ($scope.ui.builtinKeys && newDomain.keyFields.length === 1) {
                         const keyField = newDomain.keyFields[0];
 
-                        newDomain.keyType = keyField.jdbcType.javaType;
+                        newDomain.keyType = keyField.javaType;
 
                         // Exclude key column from query fields and indexes.
-                        newDomain.fields = _.filter(newDomain.fields, function(field) {
-                            return field.name !== keyField.javaFieldName;
-                        });
+                        newDomain.fields = _.filter(newDomain.fields, (field) => field.name !== keyField.javaFieldName);
 
                         _.forEach(newDomain.indexes, function(index) {
-                            index.fields = _.filter(index.fields, function(field) {
-                                return field.name !== keyField.javaFieldName;
-                            });
+                            index.fields = _.filter(index.fields, (field) => field.name !== keyField.javaFieldName);
                         });
 
                         newDomain.indexes = _.filter(newDomain.indexes, (index) => !_.isEmpty(index.fields));

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/controllers/profile-controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/controllers/profile-controller.js b/modules/web-console/frontend/controllers/profile-controller.js
index 9499db5..fd595d9 100644
--- a/modules/web-console/frontend/controllers/profile-controller.js
+++ b/modules/web-console/frontend/controllers/profile-controller.js
@@ -19,7 +19,8 @@
 export default ['profileController', [
     '$rootScope', '$scope', '$http', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteCountries', 'User',
     function($root, $scope, $http, LegacyUtils, Messages, Focus, Confirm, Countries, User) {
-        $scope.user = angular.copy($root.user);
+        User.read()
+            .then((user) => $scope.user = angular.copy(user));
 
         $scope.countries = Countries.getAll();
 
@@ -74,7 +75,7 @@ export default ['profileController', [
         $scope.saveUser = () => {
             $http.post('/api/v1/profile/save', $scope.user)
                 .catch(({data}) => Promise.reject(data))
-                .then(User.read)
+                .then(User.load)
                 .then(() => {
                     if ($scope.expandedPassword)
                         $scope.togglePassword();

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/generator/generator-common.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/generator/generator-common.js b/modules/web-console/frontend/generator/generator-common.js
index 124a1b7..d502c8a 100644
--- a/modules/web-console/frontend/generator/generator-common.js
+++ b/modules/web-console/frontend/generator/generator-common.js
@@ -39,9 +39,14 @@ $generatorCommon.formatDate = function(date) {
     return mm + '/' + dd + '/' + yyyy + ' ' + $generatorCommon.addLeadingZero(date.getHours(), 2) + ':' + $generatorCommon.addLeadingZero(date.getMinutes(), 2);
 };
 
-// Generate comment for generated XML, Java, ... files.
-$generatorCommon.mainComment = function mainComment() {
-    return 'This configuration was generated by Ignite Web Console (' + $generatorCommon.formatDate(new Date()) + ')';
+/**
+ * Generate title comment for XML, Java, ... files.
+ *
+ * @param sbj {string} What is generated.
+ * @returns {string} Text to add as title comment in generated java class.
+ */
+$generatorCommon.mainComment = function mainComment(sbj) {
+    return 'This ' + sbj + ' was generated by Ignite Web Console (' + $generatorCommon.formatDate(new Date()) + ')';
 };
 
 // Create result holder with service functions and properties for XML and java code generation.
@@ -489,6 +494,14 @@ $generatorCommon.IGFS_IPC_CONFIGURATION = {
     }
 };
 
+$generatorCommon.ODBC_CONFIGURATION = {
+    className: 'org.apache.ignite.configuration.OdbcConfiguration',
+    fields: {
+        endpointAddress: {dflt: '0.0.0.0:10800..10810'},
+        maxOpenCursors: {dflt: 128}
+    }
+};
+
 // Check that cache has datasource.
 $generatorCommon.cacheHasDatasource = function(cache) {
     if (cache.cacheStoreFactory && cache.cacheStoreFactory.kind) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/generator/generator-java.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/generator/generator-java.js b/modules/web-console/frontend/generator/generator-java.js
index 6cc3323..db54928 100644
--- a/modules/web-console/frontend/generator/generator-java.js
+++ b/modules/web-console/frontend/generator/generator-java.js
@@ -1296,6 +1296,21 @@ $generatorJava.clusterTime = function(cluster, res) {
     return res;
 };
 
+// Generate ODBC configuration group.
+$generatorJava.clusterODBC = function(odbc, res) {
+    if (!res)
+        res = $generatorCommon.builder();
+
+    if (odbc && odbc.odbcEnabled) {
+        $generatorJava.beanProperty(res, 'cfg', odbc, 'odbcConfiguration', 'odbcConfiguration',
+            $generatorCommon.ODBC_CONFIGURATION.className, $generatorCommon.ODBC_CONFIGURATION.fields, true);
+    }
+
+    res.needEmptyLine = true;
+
+    return res;
+};
+
 // Generate thread pools group.
 $generatorJava.clusterPools = function(cluster, res) {
     if (!res)
@@ -2332,7 +2347,7 @@ $generatorJava.javaClassCode = function(domain, key, pkg, useConstructor, includ
     res.line('/**');
     res.line(' * ' + type + ' definition.');
     res.line(' *');
-    res.line(' * ' + $generatorCommon.mainComment());
+    res.line(' * ' + $generatorCommon.mainComment('POJO'));
     res.line(' */');
 
     res.startBlock('public class ' + type + ' implements ' + res.importClass('java.io.Serializable') + ' {');
@@ -2537,7 +2552,7 @@ $generatorJava.javaClassCode = function(domain, key, pkg, useConstructor, includ
 
     res.endBlock('}');
 
-    return 'package ' + pkg + ';' + '\n\n' + res.generateImports() + '\n\n' + res.generateStaticImports() + '\n\n' + res.asString();
+    return 'package ' + pkg + ';' + '\n\n' + res.generateImports() + '\n' + res.generateStaticImports() + '\n' + res.asString();
 };
 
 /**
@@ -2872,6 +2887,8 @@ $generatorJava.clusterConfiguration = function(cluster, clientNearCfg, res) {
 
     $generatorJava.clusterLogger(cluster.logger, res);
 
+    $generatorJava.clusterODBC(cluster.odbc, res);
+
     $generatorJava.clusterMarshaller(cluster, res);
 
     $generatorJava.clusterMetrics(cluster, res);
@@ -2938,7 +2955,7 @@ $generatorJava.cluster = function(cluster, pkg, javaClass, clientNearCfg) {
         res.mergeProps(resCfg);
 
         res.line('/**');
-        res.line(' * ' + $generatorCommon.mainComment());
+        res.line(' * ' + $generatorCommon.mainComment('configuration'));
         res.line(' */');
         res.startBlock('public class ' + javaClass + ' {');
 
@@ -3002,7 +3019,7 @@ $generatorJava.cluster = function(cluster, pkg, javaClass, clientNearCfg) {
 
         res.endBlock('}');
 
-        return 'package ' + pkg + ';\n\n' + res.generateImports() + '\n\n' + res.generateStaticImports() + '\n\n' + res.asString();
+        return 'package ' + pkg + ';\n\n' + res.generateImports() + '\n' + res.generateStaticImports() + '\n' + res.asString();
     }
 
     return res.asString();
@@ -3447,7 +3464,7 @@ $generatorJava.nodeStartup = function(cluster, pkg, cls, cfg, factoryCls, client
     const res = $generatorCommon.builder();
 
     res.line('/**');
-    res.line(' * ' + $generatorCommon.mainComment());
+    res.line(' * ' + $generatorCommon.mainComment('node start up'));
 
     if (demo) {
         res.line(' *');
@@ -3528,7 +3545,67 @@ $generatorJava.nodeStartup = function(cluster, pkg, cls, cfg, factoryCls, client
 
     res.endBlock('}');
 
-    return 'package ' + pkg + ';\n\n' + res.generateImports() + '\n\n' + res.generateStaticImports() + '\n\n' + res.asString();
+    return 'package ' + pkg + ';\n\n' + res.generateImports() + '\n' + res.generateStaticImports() + '\n' + res.asString();
 };
 
+/**
+ * Function to generate java class for load caches.
+ *
+ * @param caches Caches to load.
+ * @param pkg Class package name.
+ * @param cls Class name.
+ * @param cfg Config.
+ */
+$generatorJava.loadCaches = function(caches, pkg, cls, cfg) {
+    const res = $generatorCommon.builder();
+
+    res.line('/**');
+    res.line(' * ' + $generatorCommon.mainComment('utility'));
+    res.line(' */');
+    res.startBlock('public class ' + cls + ' {');
+
+    res.line('/**');
+    res.line(' * <p>');
+    res.line(' * Utility to load caches from database.');
+    res.line(' * <p>');
+    res.line(' * How to use:');
+    res.line(' * <ul>');
+    res.line(' *    <li>Start cluster.</li>');
+    res.line(' *    <li>Start this utility and wait while load complete.</li>');
+    res.line(' * </ul>');
+    res.line(' *');
+    res.line(' * @param args Command line arguments, none required.');
+    res.line(' * @throws Exception If failed.');
+    res.line(' */');
+
+    res.startBlock('public static void main(String[] args) throws Exception {');
+
+    res.startBlock('try (' + res.importClass('org.apache.ignite.Ignite') + ' ignite = ' +
+        res.importClass('org.apache.ignite.Ignition') + '.start(' + cfg + ')) {');
+
+    res.line('System.out.println(">>> Loading caches...");');
+
+    res.needEmptyLine = true;
+
+    _.forEach(caches, (cache) => {
+        res.line('System.out.println(">>> Loading cache: ' + cache.name + '");');
+        res.line('ignite.cache("' + cache.name + '").loadCache(null);');
+
+        res.needEmptyLine = true;
+    });
+
+    res.needEmptyLine = true;
+
+    res.line('System.out.println(">>> All caches loaded!");');
+
+    res.endBlock('}');
+
+    res.endBlock('}');
+
+    res.endBlock('}');
+
+    return 'package ' + pkg + ';\n\n' + res.generateImports() + '\n' + res.generateStaticImports() + '\n' + res.asString();
+};
+
+
 export default $generatorJava;

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/generator/generator-properties.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/generator/generator-properties.js b/modules/web-console/frontend/generator/generator-properties.js
index 9d1e7e3..5742713 100644
--- a/modules/web-console/frontend/generator/generator-properties.js
+++ b/modules/web-console/frontend/generator/generator-properties.js
@@ -41,7 +41,7 @@ $generatorProperties.jdbcUrlTemplate = function(dialect) {
 $generatorProperties.createBuilder = function() {
     const res = $generatorCommon.builder();
 
-    res.line('# ' + $generatorCommon.mainComment());
+    res.line('# ' + $generatorCommon.mainComment('list of properties'));
 
     return res;
 };

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/generator/generator-xml.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/generator/generator-xml.js b/modules/web-console/frontend/generator/generator-xml.js
index b49b052..ded93af 100644
--- a/modules/web-console/frontend/generator/generator-xml.js
+++ b/modules/web-console/frontend/generator/generator-xml.js
@@ -1009,6 +1009,19 @@ $generatorXml.clusterTime = function(cluster, res) {
     return res;
 };
 
+// Generate OBC configuration group.
+$generatorXml.clusterODBC = function(odbc, res) {
+    if (!res)
+        res = $generatorCommon.builder();
+
+    if (odbc && odbc.odbcEnabled)
+        $generatorXml.beanProperty(res, odbc, 'odbcConfiguration', $generatorCommon.ODBC_CONFIGURATION, true);
+
+    res.needEmptyLine = true;
+
+    return res;
+};
+
 // Generate thread pools group.
 $generatorXml.clusterPools = function(cluster, res) {
     if (!res)
@@ -2003,6 +2016,8 @@ $generatorXml.clusterConfiguration = function(cluster, clientNearCfg, res) {
 
     $generatorXml.clusterLogger(cluster.logger, res);
 
+    $generatorXml.clusterODBC(cluster.odbc, res);
+
     $generatorXml.clusterMarshaller(cluster, res);
 
     $generatorXml.clusterMetrics(cluster, res);
@@ -2058,7 +2073,7 @@ $generatorXml.cluster = function(cluster, clientNearCfg) {
         // 1. Add header.
         let xml = '<?xml version="1.0" encoding="UTF-8"?>\n\n';
 
-        xml += '<!-- ' + $generatorCommon.mainComment() + ' -->\n\n';
+        xml += '<!-- ' + $generatorCommon.mainComment('configuration') + ' -->\n\n';
         xml += '<beans xmlns="http://www.springframework.org/schema/beans"\n';
         xml += '       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n';
         xml += '       xmlns:util="http://www.springframework.org/schema/util"\n';

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/public/stylesheets/form-field.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/stylesheets/form-field.scss b/modules/web-console/frontend/public/stylesheets/form-field.scss
new file mode 100644
index 0000000..f126786
--- /dev/null
+++ b/modules/web-console/frontend/public/stylesheets/form-field.scss
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+.details-row,
+.settings-row {
+    &_small-label {
+        @media (min-width: $screen-xs-min) {
+            .ignite-form-field__label {
+                @include make-xs-column(4);
+            }
+
+            .ignite-form-field__control {
+                @include make-xs-column(8);
+            }
+        }
+
+        @media (min-width: $screen-sm-min) {
+            .ignite-form-field__label {
+                @include make-sm-column(2);
+            }
+
+            .ignite-form-field__control {
+                @include make-sm-column(10);
+            }
+        }
+
+        @media (min-width: $screen-md-min) {
+            .ignite-form-field__label {
+                @include make-md-column(2);
+            }
+
+            .ignite-form-field__control {
+                @include make-md-column(10);
+            }
+        }
+
+        @media (min-width: $screen-lg-min) {
+            .ignite-form-field__label {
+                @include make-lg-column(2);
+            }
+
+            .ignite-form-field__control {
+                @include make-lg-column(10);
+            }
+        }
+    }
+
+    .ignite-form-field__label,
+    .ignite-form-field__control {
+        display: inline-block;
+        vertical-align: middle;
+        float: none;
+    }
+}
+
+@media (min-width: $screen-xs-min) {
+    .ignite-form-field__label {
+        @include make-xs-column(4);
+    }
+
+    .ignite-form-field__control {
+        @include make-xs-column(8);
+    }
+}
+
+@media (min-width: $screen-sm-min) {
+    .ignite-form-field__label {
+        @include make-sm-column(4);
+    }
+
+    .ignite-form-field__control {
+        @include make-sm-column(8);
+    }
+}
+
+@media (min-width: $screen-md-min) {
+    .ignite-form-field__label {
+        @include make-md-column(4);
+    }
+
+    .ignite-form-field__control {
+        @include make-md-column(8);
+    }
+}
+
+@media (min-width: $screen-lg-min) {
+    .ignite-form-field__label {
+        @include make-lg-column(4);
+    }
+
+    .ignite-form-field__control {
+        @include make-lg-column(8);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/public/stylesheets/style.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/public/stylesheets/style.scss b/modules/web-console/frontend/public/stylesheets/style.scss
index 4db7127..0784560 100644
--- a/modules/web-console/frontend/public/stylesheets/style.scss
+++ b/modules/web-console/frontend/public/stylesheets/style.scss
@@ -21,6 +21,7 @@
 @import "~roboto-font/css/fonts.css";
 @import "./../../app/directives/information/information.scss";
 @import "./blocks/error";
+@import "./form-field";
 
 hr {
     margin: 20px 0;

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/test/unit/JavaTypes.test.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/test/unit/JavaTypes.test.js b/modules/web-console/frontend/test/unit/JavaTypes.test.js
index 25c0f67..7b12168 100644
--- a/modules/web-console/frontend/test/unit/JavaTypes.test.js
+++ b/modules/web-console/frontend/test/unit/JavaTypes.test.js
@@ -17,53 +17,91 @@
 
 import JavaTypes from '../../app/services/JavaTypes.service.js';
 
-import { assert } from 'chai';
+const INSTANCE = new JavaTypes();
 
-const { nonBuiltInClass, fullClassName, validIdentifier, validPackage, packageSpecified, isKeywords, isJavaPrimitive} = JavaTypes[1]();
+import { assert } from 'chai';
 
 suite('JavaTypesTestsSuite', () => {
     test('nonBuiltInClass', () => {
-        assert.equal(nonBuiltInClass('BigDecimal'), false);
-        assert.equal(nonBuiltInClass('java.math.BigDecimal'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('BigDecimal'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('java.math.BigDecimal'), false);
 
-        assert.equal(nonBuiltInClass('String'), false);
-        assert.equal(nonBuiltInClass('java.lang.String'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('String'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('java.lang.String'), false);
 
-        assert.equal(nonBuiltInClass('Timestamp'), false);
-        assert.equal(nonBuiltInClass('java.sql.Timestamp'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('Timestamp'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('java.sql.Timestamp'), false);
 
-        assert.equal(nonBuiltInClass('Date'), false);
-        assert.equal(nonBuiltInClass('java.sql.Date'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('Date'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('java.sql.Date'), false);
 
-        assert.equal(nonBuiltInClass('Date'), false);
-        assert.equal(nonBuiltInClass('java.util.Date'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('Date'), false);
+        assert.equal(INSTANCE.nonBuiltInClass('java.util.Date'), false);
 
-        assert.equal(nonBuiltInClass('CustomClass'), true);
-        assert.equal(nonBuiltInClass('java.util.CustomClass'), true);
-        assert.equal(nonBuiltInClass('my.package.CustomClass'), true);
+        assert.equal(INSTANCE.nonBuiltInClass('CustomClass'), true);
+        assert.equal(INSTANCE.nonBuiltInClass('java.util.CustomClass'), true);
+        assert.equal(INSTANCE.nonBuiltInClass('my.package.CustomClass'), true);
     });
 
     test('fullClassName', () => {
-        assert.equal(fullClassName('BigDecimal'), 'java.math.BigDecimal');
+        assert.equal(INSTANCE.fullClassName('BigDecimal'), 'java.math.BigDecimal');
     });
 
     test('validIdentifier', () => {
-        assert.equal(validIdentifier('java.math.BigDecimal'), true);
+        assert.equal(INSTANCE.validIdentifier('myIdent'), true);
+        assert.equal(INSTANCE.validIdentifier('java.math.BigDecimal'), false);
+        assert.equal(INSTANCE.validIdentifier('2Demo'), false);
+        assert.equal(INSTANCE.validIdentifier('abra kadabra'), false);
+        assert.equal(INSTANCE.validIdentifier(undefined), false);
+        assert.equal(INSTANCE.validIdentifier(null), false);
+        assert.equal(INSTANCE.validIdentifier(''), false);
+        assert.equal(INSTANCE.validIdentifier(' '), false);
+    });
+
+    test('validClassName', () => {
+        assert.equal(INSTANCE.validClassName('java.math.BigDecimal'), true);
+        assert.equal(INSTANCE.validClassName('2Demo'), false);
+        assert.equal(INSTANCE.validClassName('abra kadabra'), false);
+        assert.equal(INSTANCE.validClassName(undefined), false);
+        assert.equal(INSTANCE.validClassName(null), false);
+        assert.equal(INSTANCE.validClassName(''), false);
+        assert.equal(INSTANCE.validClassName(' '), false);
     });
 
     test('validPackage', () => {
-        assert.equal(validPackage('java.math.BigDecimal'), true);
+        assert.equal(INSTANCE.validPackage('java.math.BigDecimal'), true);
+        assert.equal(INSTANCE.validPackage('my.org.SomeClass'), true);
+        assert.equal(INSTANCE.validPackage('25'), false);
+        assert.equal(INSTANCE.validPackage('abra kadabra'), false);
+        assert.equal(INSTANCE.validPackage(''), false);
+        assert.equal(INSTANCE.validPackage(' '), false);
     });
 
     test('packageSpecified', () => {
-        assert.equal(packageSpecified('java.math.BigDecimal'), true);
+        assert.equal(INSTANCE.packageSpecified('java.math.BigDecimal'), true);
+        assert.equal(INSTANCE.packageSpecified('BigDecimal'), false);
     });
 
-    test('isKeywords', () => {
-        assert.equal(isKeywords('abstract'), true);
+    test('isKeyword', () => {
+        assert.equal(INSTANCE.isKeyword('abstract'), true);
+        assert.equal(INSTANCE.isKeyword('Abstract'), true);
+        assert.equal(INSTANCE.isKeyword('abra kadabra'), false);
+        assert.equal(INSTANCE.isKeyword(undefined), false);
+        assert.equal(INSTANCE.isKeyword(null), false);
+        assert.equal(INSTANCE.isKeyword(''), false);
+        assert.equal(INSTANCE.isKeyword(' '), false);
     });
 
     test('isJavaPrimitive', () => {
-        assert.equal(isJavaPrimitive('boolean'), true);
+        assert.equal(INSTANCE.isJavaPrimitive('boolean'), true);
+    });
+
+    test('validUUID', () => {
+        assert.equal(INSTANCE.validUUID('123e4567-e89b-12d3-a456-426655440000'), true);
+        assert.equal(INSTANCE.validUUID('12345'), false);
+        assert.equal(INSTANCE.validUUID(undefined), false);
+        assert.equal(INSTANCE.validUUID(null), false);
+        assert.equal(INSTANCE.validUUID(''), false);
+        assert.equal(INSTANCE.validUUID(' '), false);
     });
 });

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/test/unit/SqlTypes.test.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/test/unit/SqlTypes.test.js b/modules/web-console/frontend/test/unit/SqlTypes.test.js
new file mode 100644
index 0000000..3cfaafc
--- /dev/null
+++ b/modules/web-console/frontend/test/unit/SqlTypes.test.js
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.
+ */
+
+import SqlTypes from '../../app/services/SqlTypes.service.js';
+
+const INSTANCE = new SqlTypes();
+
+import { assert } from 'chai';
+
+suite('SqlTypesTestsSuite', () => {
+    test('validIdentifier', () => {
+        assert.equal(INSTANCE.validIdentifier('myIdent'), true);
+        assert.equal(INSTANCE.validIdentifier('java.math.BigDecimal'), false);
+        assert.equal(INSTANCE.validIdentifier('2Demo'), false);
+        assert.equal(INSTANCE.validIdentifier('abra kadabra'), false);
+        assert.equal(INSTANCE.validIdentifier(undefined), false);
+        assert.equal(INSTANCE.validIdentifier(null), false);
+        assert.equal(INSTANCE.validIdentifier(''), false);
+        assert.equal(INSTANCE.validIdentifier(' '), false);
+    });
+
+    test('isKeyword', () => {
+        assert.equal(INSTANCE.isKeyword('group'), true);
+        assert.equal(INSTANCE.isKeyword('Group'), true);
+        assert.equal(INSTANCE.isKeyword('select'), true);
+        assert.equal(INSTANCE.isKeyword('abra kadabra'), false);
+        assert.equal(INSTANCE.isKeyword(undefined), false);
+        assert.equal(INSTANCE.isKeyword(null), false);
+        assert.equal(INSTANCE.isKeyword(''), false);
+        assert.equal(INSTANCE.isKeyword(' '), false);
+    });
+
+    test('findJdbcType', () => {
+        assert.equal(INSTANCE.findJdbcType(0).dbName, 'NULL');
+        assert.equal(INSTANCE.findJdbcType(5555).dbName, 'Unknown');
+    })
+});

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/views/configuration/clusters.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/configuration/clusters.jade b/modules/web-console/frontend/views/configuration/clusters.jade
index b10a477..b79b1ea 100644
--- a/modules/web-console/frontend/views/configuration/clusters.jade
+++ b/modules/web-console/frontend/views/configuration/clusters.jade
@@ -56,6 +56,7 @@ include ../../app/helpers/jade/mixins.jade
                             include ../../app/modules/states/configuration/clusters/logger.jade
                             include ../../app/modules/states/configuration/clusters/marshaller.jade
                             include ../../app/modules/states/configuration/clusters/metrics.jade
+                            include ../../app/modules/states/configuration/clusters/odbc.jade
                             include ../../app/modules/states/configuration/clusters/ssl.jade
                             include ../../app/modules/states/configuration/clusters/swap.jade
                             include ../../app/modules/states/configuration/clusters/thread.jade

http://git-wip-us.apache.org/repos/asf/ignite/blob/48d4a925/modules/web-console/frontend/views/configuration/domains-import.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/configuration/domains-import.jade b/modules/web-console/frontend/views/configuration/domains-import.jade
index d95e98a..e2eaf97 100644
--- a/modules/web-console/frontend/views/configuration/domains-import.jade
+++ b/modules/web-console/frontend/views/configuration/domains-import.jade
@@ -53,64 +53,31 @@ mixin td-ellipses-lbl(w, lbl)
                                 li Copy h2-x.x.x.jar into agent 'jdbc-drivers' folder and try again
                                 li Refer to agent README.txt for more information
                 .import-domain-model-wizard-page(ng-if='importDomain.action == "connect" && !importDomain.demo')
-                    - var form = 'connectForm'
+                    -var form = 'connectForm'
 
                     form.form-horizontal(name=form novalidate)
+                        .settings-row.settings-row_small-label
+                            +ignite-form-field-dropdown('Driver JAR:', 'ui.selectedJdbcDriverJar', '"jdbcDriverJar"', false, true, false,
+                                'Choose JDBC driver', '', 'jdbcDriverJars',
+                                'Select appropriate JAR with JDBC driver<br> To add another driver you need to place it into "/jdbc-drivers" folder of Ignite Web Agent<br> Refer to Ignite Web Agent README.txt for for more information'
+                            )(data-container='.modal-domain-import')
+                        .settings-row.settings-row_small-label
+                            +java-class('JDBC driver:', 'selectedPreset.jdbcDriverClass', '"jdbcDriverClass"', true, true, 'Fully qualified class name of JDBC driver that will be used to connect to database')
+                        .settings-row.settings-row_small-label
+                            +text('JDBC URL:', 'selectedPreset.jdbcUrl', '"jdbcUrl"', true, 'JDBC URL', 'JDBC URL for connecting to database<br>Refer to your database documentation for details')
+                        .settings-row.settings-row_small-label
+                            +text('User:', 'selectedPreset.user', '"jdbdUser"', false, '', 'User name for connecting to database')
+                        .settings-row.settings-row_small-label
+                            +password('Password:', 'selectedPreset.password', '"jdbcPassword"', false, '', 'Password for connecting to database<br>Note, password would not be saved in preferences for security reasons')(ignite-on-enter='importDomainNext()')
                         .settings-row
-                            label.col-xs-4.col-sm-2.col-md-2.required Driver JAR:
-                            .col-xs-8.col-sm-10.col-md-10
-                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Select appropriate JAR with JDBC driver<br> To add another driver you need to place it into "/jdbc-drivers" folder of Ignite Web Agent<br> Refer to Ignite Web Agent README.txt for for more information')
-                                .input-tip
-                                    button.select-toggle.form-control(id='jdbcDriverJar' bs-select data-container='.modal-domain-import' ng-model='ui.selectedJdbcDriverJar' ng-class='{placeholder: !(jdbcDriverJars && jdbcDriverJars.length > 0)}' placeholder='Choose JDBC driver' bs-options='item.value as item.label for item in jdbcDriverJars')
-                        .settings-row
-                            label.col-xs-4.col-sm-2.col-md-2.required JDBC driver:
-                            .col-xs-8.col-sm-10.col-md-10
-                                - var name = '"jdbcDriverClass"'
-                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Fully qualified class name of JDBC driver that will be used to connect to database')
-
-                                +form-field-feedback(name, 'javaBuiltInClass', 'JDBC Driver should not be the Java built-in class!')
-                                +form-field-feedback(name, 'javaKeywords', 'JDBC Driver could not contains reserved Java keyword!')
-                                +form-field-feedback(name, 'javaPackageSpecified', 'JDBC Driver does not have package specified!')
-                                +form-field-feedback(name, 'javaIdentifier', 'JDBC Driver is invalid Java identifier!')
-
-                                .input-tip
-                                    +ignite-form-field-input(name, 'selectedPreset.jdbcDriverClass', false, true, 'Enter fully qualified class name')(
-                                        data-java-identifier='true'
-                                        data-java-package-specified='true'
-                                        data-java-keywords='true'
-                                        data-java-built-in-class='true'
-                                    )
-                        .settings-row
-                            label.col-xs-4.col-sm-2.col-md-2.required JDBC URL:
-                            .col-xs-8.col-sm-10.col-md-10
-                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='JDBC URL for connecting to database<br>Refer to your database documentation for details')
-                                .input-tip
-                                    +ignite-form-field-input('jdbcUrl', 'selectedPreset.jdbcUrl', false, true, 'JDBC URL')
-                        .settings-row
-                            label.col-xs-4.col-sm-2.col-md-2 User:
-                            .col-xs-8.col-sm-10.col-md-10
-                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='User name for connecting to database')
-                                .input-tip
-                                    input.form-control(id='user' type='text' ng-model='selectedPreset.user')
-                        .settings-row
-                            label.col-xs-4.col-sm-2.col-md-2 Password:
-                            .col-xs-8.col-sm-10.col-md-10
-                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Password for connecting to database<br>Note, password would not be saved in preferences for security reasons')
-                                .input-tip
-                                    input.form-control(id='password' type='password' ng-model='selectedPreset.password' ignite-on-enter='importDomainNext()')
-                        .settings-row
-                            .checkbox
-                                label
-                                    input(id='tablesOnly' type='checkbox' ng-model='selectedPreset.tablesOnly')
-                                    | Tables only
-                                i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='If selected, then only tables metadata will be parsed<br>Otherwise table and view metadata will be parsed')
+                            +checkbox('Tables only', 'selectedPreset.tablesOnly', '"tablesOnly"', 'If selected, then only tables metadata will be parsed<br>Otherwise table and view metadata will be parsed')
                 .import-domain-model-wizard-page(ng-show='importDomain.action == "schemas"')
                     table.table.metadata(st-table='importDomain.displayedSchemas' st-safe-src='importDomain.schemas')
                         thead
                             tr
                                 th.header(colspan='2')
                                     .col-sm-4.pull-right(style='margin-bottom: 5px')
-                                        input.form-control(type='text' st-search='name' placeholder='Filter schemas...' ng-model='importDomain.displayedSchemasFilter' ng-change='selectSchema()')
+                                        input.form-control(type='text' st-search='name' placeholder='Filter schemas...' ng-model='importDomain.displayedSchemasFilter' )
                             tr
                                 th(width='30px')
                                     +chk('importDomain.allSchemasSelected',  'selectAllSchemas()', 'Select all schemas')
@@ -174,49 +141,22 @@ mixin td-ellipses-lbl(w, lbl)
                         .col-sm-1(style='padding-left: 5px')
                             button.btn.btn-primary(ng-click='applyDefaults()') Apply
                 .import-domain-model-wizard-page(ng-show='importDomain.action == "options"')
-                    - var form = 'optionsForm'
-                    form.form-horizontal(name='optionsForm' novalidate)
-                        .settings-row
-                            .col-xs-3.col-sm-2.col-md-2.required
-                                label.required Package:
-                            .col-xs-9.col-sm-10.col-md-10
-                                - var name = '"domainPackageName"'
-                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Package that will be used for POJOs generation')
-
-                                +form-field-feedback(name, 'javaPackageName', 'Package name is invalid')
-                                +form-field-feedback(name, 'javaKeywords', 'Package name could not contains reserved java keyword')
+                    -var form = 'optionsForm'
 
-                                .input-tip
-                                    +ignite-form-field-input(name, 'ui.packageName', false, true, 'Enter package name')(
-                                        data-java-keywords='true'
-                                        data-java-package-name='package-only'
-                                        ng-model-options='{allowInvalid: true}'
-                                    )
-                        .settings-row
-                            .checkbox
-                                label
-                                    input(id='domainBuiltinKeys' type='checkbox' ng-model='ui.builtinKeys')
-                                    | Use Java built-in types for keys
-                                    i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Use Java built-in types like "Integer", "Long", "String" instead of POJO generation in case when table primary key contains only one field')
+                    form.form-horizontal(name=form novalidate)
+                        .settings-row.settings-row_small-label
+                            +java-package('Package:', 'ui.packageName', '"domainPackageName"', true, true, 'Package that will be used for POJOs generation')(data-container='.modal-domain-import')
                         .settings-row
-                            .checkbox
-                                label
-                                    input(id='domainUsePrimitives' type='checkbox' ng-model='ui.usePrimitives')
-                                    | Use primitive types for NOT NULL table columns
-                                    i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Use primitive types like "int", "long", "double" for POJOs fields generation in case of NOT NULL columns')
+                            +checkbox('Use Java built-in types for keys', 'ui.builtinKeys', '"domainBuiltinKeys"', 'Use Java built-in types like "Integer", "Long", "String" instead of POJO generation in case when table primary key contains only one field')
                         .settings-row
-                            .checkbox
-                                label
-                                    input(id='domainGenerateAliases' type='checkbox' ng-model='ui.generateAliases')
-                                    | Generate aliases for query fields
-                                    i.tipLabel.fa.fa-question-circle(bs-tooltip='' data-title='Generate aliases for query fields with database field names when database field name differ from Java field name')
+                            +checkbox('Use primitive types for NOT NULL table columns', 'ui.usePrimitives', '"domainUsePrimitives"', 'Use primitive types like "int", "long", "double" for POJOs fields generation in case of NOT NULL columns')
                         .settings-row
-                            .col-xs-3.col-sm-2.col-md-2.required
-                                label Clusters:
-                            .col-xs-9.col-sm-10.col-md-10
-                                i.tipField.fa.fa-question-circle(bs-tooltip='' data-title='Choose clusters that will be associated with generated caches')
-                                .input-tip
-                                    button.select-toggle.form-control(id='generatedCachesClusters' bs-select ng-model='ui.generatedCachesClusters' ng-class='{placeholder: !(ui.generatedCachesClusters && ui.generatedCachesClusters.length > 0)}' data-container='.modal-domain-import' data-multiple='1' placeholder='Choose clusters for generated caches' bs-options='item.value as item.label for item in clusters')
+                            +checkbox('Generate aliases for query fields', 'ui.generateAliases', '"domainGenerateAliases"', 'Generate aliases for query fields with database field names when database field name differ from Java field name')
+                        .settings-row.settings-row_small-label
+                            +ignite-form-field-dropdown('Clusters:', 'ui.generatedCachesClusters', '"generatedCachesClusters"', false, false, true,
+                                'Choose clusters for generated caches', '', 'clusters',
+                                'Choose clusters that will be associated with generated caches'
+                            )(data-container='.modal-domain-import')
             .modal-footer
                 label(ng-hide='importDomain.action == "drivers" || (importDomain.action == "connect" && importDomain.demo)').labelField {{importDomain.info}}
                 a.btn.btn-primary(ng-hide='importDomain.action == "drivers" || importDomain.action == "connect"' ng-click='importDomainPrev()' bs-tooltip='' data-title='{{prevTooltipText()}}' data-placement='bottom') Prev


Mime
View raw message