You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/12/29 04:12:38 UTC

ignite git commit: IGNITE-2281 Smart save tables.

Repository: ignite
Updated Branches:
  refs/heads/ignite-843-rc2 4fb46540f -> 2dc4d2034


IGNITE-2281 Smart save tables.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2dc4d203
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2dc4d203
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2dc4d203

Branch: refs/heads/ignite-843-rc2
Commit: 2dc4d203474384846370f6ba0afbd3a5f0ce4171
Parents: 4fb4654
Author: vsisko <vs...@gridgain.com>
Authored: Tue Dec 29 10:12:20 2015 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Tue Dec 29 10:12:20 2015 +0700

----------------------------------------------------------------------
 .../main/js/controllers/caches-controller.js    | 111 ++++++--
 .../main/js/controllers/clusters-controller.js  | 147 ++++++----
 .../src/main/js/controllers/common-module.js    |  69 +++--
 .../src/main/js/controllers/igfs-controller.js  |  96 +++++--
 .../main/js/controllers/metadata-controller.js  | 275 ++++++++++++-------
 .../main/js/helpers/generator/generator-java.js |  14 +-
 .../src/main/js/views/includes/controls.jade    |  20 +-
 7 files changed, 489 insertions(+), 243 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2dc4d203/modules/control-center-web/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/caches-controller.js b/modules/control-center-web/src/main/js/controllers/caches-controller.js
index eb1c9df..5ab3a19 100644
--- a/modules/control-center-web/src/main/js/controllers/caches-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/caches-controller.js
@@ -36,24 +36,76 @@ consoleModule.controller('cachesController', [
             $scope.panelExpanded = $common.panelExpanded;
 
             $scope.tableVisibleRow = $table.tableVisibleRow;
-            $scope.tableReset = $table.tableReset;
-            $scope.tableNewItem = $table.tableNewItem;
+
+            $scope.tableSave = function (field, index, stopEdit) {
+                switch (field.type) {
+                    case 'table-simple':
+                        if ($table.tableSimpleSaveVisible(field, index))
+                            return $table.tableSimpleSave($scope.tableSimpleValid, $scope.backupItem, field, index, stopEdit);
+
+                        break;
+
+                    case 'indexedTypes':
+                        if ($table.tablePairSaveVisible(field, index))
+                            return $table.tablePairSave($scope.tablePairValid, $scope.backupItem, field, index, stopEdit);
+
+                        break;
+                }
+
+                return true;
+            };
+
+            $scope.tableReset = function (save) {
+                var field = $table.tableField();
+
+                if (!save || !$common.isDefined(field) || $scope.tableSave(field, $table.tableEditedRowIndex(), true)) {
+                    $table.tableReset();
+
+                    return true;
+                }
+
+                return false;
+            };
+
+            $scope.tableNewItem = function (field) {
+                if ($scope.tableReset(true))
+                    $table.tableNewItem(field);
+            };
+
             $scope.tableNewItemActive = $table.tableNewItemActive;
+
+            $scope.tableStartEdit = function (item, field, index) {
+                if ($scope.tableReset(true))
+                    $table.tableStartEdit(item, field, index);
+            };
+
             $scope.tableEditing = $table.tableEditing;
-            $scope.tableStartEdit = $table.tableStartEdit;
+
             $scope.tableRemove = function (item, field, index) {
-                $table.tableRemove(item, field, index);
+                if ($scope.tableReset(true))
+                    $table.tableRemove(item, field, index);
             };
 
             $scope.tableSimpleSave = $table.tableSimpleSave;
             $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
-            $scope.tableSimpleUp = $table.tableSimpleUp;
-            $scope.tableSimpleDown = $table.tableSimpleDown;
+
+            $scope.tableSimpleUp = function (item, field, index) {
+                if ($scope.tableReset(true))
+                    $table.tableSimpleUp(item, field, index);
+            };
+
+            $scope.tableSimpleDown = function (item, field, index) {
+                if ($scope.tableReset(true))
+                    $table.tableSimpleDown(item, field, index);
+            };
+
             $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
 
             $scope.tablePairSave = $table.tablePairSave;
             $scope.tablePairSaveVisible = $table.tablePairSaveVisible;
 
+            $scope.tableEditedRowIndex = $table.tableEditedRowIndex;
+
             var previews = [];
 
             $scope.previewInit = function (preview) {
@@ -276,7 +328,7 @@ consoleModule.controller('cachesController', [
 
                                 if (lastSelectedCache) {
                                     var idx = _.findIndex($scope.caches, function (cache) {
-                                        return cache._id == lastSelectedCache;
+                                        return cache._id === lastSelectedCache;
                                     });
 
                                     if (idx >= 0)
@@ -426,13 +478,13 @@ consoleModule.controller('cachesController', [
 
             // Add new cache.
             $scope.createItem = function (id) {
-                $table.tableReset();
-
-                $timeout(function () {
-                    $common.ensureActivePanel($scope.panels, 'general', 'cacheName');
-                });
+                if ($scope.tableReset(true)) {
+                    $timeout(function () {
+                        $common.ensureActivePanel($scope.panels, 'general', 'cacheName');
+                    });
 
-                $scope.selectItem(undefined, prepareNewItem(id));
+                    $scope.selectItem(undefined, prepareNewItem(id));
+                }
             };
 
             // Check cache logical consistency.
@@ -440,7 +492,7 @@ consoleModule.controller('cachesController', [
                 if ($common.isEmptyString(item.name))
                     return showPopoverMessage($scope.panels, 'general', 'cacheName', 'Name should not be empty');
 
-                if (item.memoryMode === 'OFFHEAP_TIERED' && item.offHeapMaxMemory == null)
+                if (item.memoryMode === 'OFFHEAP_TIERED' && !$common.isDefined(item.offHeapMaxMemory))
                     return showPopoverMessage($scope.panels, 'memory', 'offHeapMaxMemory',
                         'Off-heap max memory should be specified');
 
@@ -507,7 +559,7 @@ consoleModule.controller('cachesController', [
                         $scope.ui.markPristine();
 
                         var idx = _.findIndex($scope.caches, function (cache) {
-                            return cache._id == _id;
+                            return cache._id === _id;
                         });
 
                         if (idx >= 0)
@@ -528,27 +580,28 @@ consoleModule.controller('cachesController', [
 
             // Save cache.
             $scope.saveItem = function () {
-                $table.tableReset();
+                if ($scope.tableReset(true)) {
 
-                var item = $scope.backupItem;
+                    var item = $scope.backupItem;
 
-                if (validate(item))
-                    save(item);
+                    if (validate(item))
+                        save(item);
+                }
             };
 
             // Save cache with new name.
             $scope.cloneItem = function () {
-                $table.tableReset();
+                if ($scope.tableReset(true)) {
+                    if (validate($scope.backupItem))
+                        $clone.confirm($scope.backupItem.name).then(function (newName) {
+                            var item = angular.copy($scope.backupItem);
 
-                if (validate($scope.backupItem))
-                    $clone.confirm($scope.backupItem.name).then(function (newName) {
-                        var item = angular.copy($scope.backupItem);
+                            item._id = undefined;
+                            item.name = newName;
 
-                        item._id = undefined;
-                        item.name = newName;
-
-                        save(item);
-                    });
+                            save(item);
+                        });
+                }
             };
 
             // Remove cache from db.
@@ -568,7 +621,7 @@ consoleModule.controller('cachesController', [
                                     var caches = $scope.caches;
 
                                     var idx = _.findIndex(caches, function (cache) {
-                                        return cache._id == _id;
+                                        return cache._id === _id;
                                     });
 
                                     if (idx >= 0) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/2dc4d203/modules/control-center-web/src/main/js/controllers/clusters-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/clusters-controller.js b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
index 53a7eb3..55d916f 100644
--- a/modules/control-center-web/src/main/js/controllers/clusters-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/clusters-controller.js
@@ -34,37 +34,81 @@ consoleModule.controller('clustersController', [
         $scope.panelExpanded = $common.panelExpanded;
 
         $scope.tableVisibleRow = $table.tableVisibleRow;
-        $scope.tableReset = $table.tableReset;
-        $scope.tableNewItem = function (field) {
-            if (field.type === 'typeConfigurations') {
-                var binary = $scope.backupItem.binaryConfiguration;
 
-                if (!binary)
-                    $scope.backupItem.binaryConfiguration = { typeConfigurations: [{}] };
-                else if (!$common.isDefined(binary.typeConfigurations))
-                    binary.typeConfigurations = [{}];
+        $scope.tableSave = function (field, index, stopEdit) {
+            switch (field.type) {
+                case 'table-simple':
+                    if ($table.tableSimpleSaveVisible(field, index))
+                        return $table.tableSimpleSave($scope.tableSimpleValid, $scope.backupItem, field, index, stopEdit);
+
+                    break;
+            }
+
+            return true;
+        };
+
+        $scope.tableReset = function (save) {
+            var field = $table.tableField();
+
+            if (!save || !$common.isDefined(field) || $scope.tableSave(field, $table.tableEditedRowIndex(), true)) {
+                $table.tableReset();
+
+                return true;
+            }
+
+            return false;
+        };
+
+        $scope.tableNewItem = function (field) {
+            if ($scope.tableReset(true)) {
+                if (field.type === 'typeConfigurations') {
+                    var binary = $scope.backupItem.binaryConfiguration;
+
+                    if (!binary)
+                        $scope.backupItem.binaryConfiguration = {typeConfigurations: [{}]};
+                    else if (!$common.isDefined(binary.typeConfigurations))
+                        binary.typeConfigurations = [{}];
+                    else
+                        binary.typeConfigurations.push({});
+                }
                 else
-                    binary.typeConfigurations.push({});
+                    $table.tableNewItem(field);
             }
-            else
-                $table.tableNewItem(field);
         };
         $scope.tableNewItemActive = $table.tableNewItemActive;
+
+        $scope.tableStartEdit = function (item, field, index) {
+            if ($scope.tableReset(true))
+                $table.tableStartEdit(item, field, index);
+        };
         $scope.tableEditing = $table.tableEditing;
-        $scope.tableStartEdit = $table.tableStartEdit;
+
         $scope.tableRemove = function (item, field, index) {
-            if (field.type === 'typeConfigurations')
-                $scope.backupItem.binaryConfiguration.typeConfigurations.splice(index, 1);
-            else
-                $table.tableRemove(item, field, index);
+            if ($scope.tableReset(true)) {
+                if (field.type === 'typeConfigurations')
+                    $scope.backupItem.binaryConfiguration.typeConfigurations.splice(index, 1);
+                else
+                    $table.tableRemove(item, field, index);
+            }
         };
 
         $scope.tableSimpleSave = $table.tableSimpleSave;
         $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
-        $scope.tableSimpleUp = $table.tableSimpleUp;
-        $scope.tableSimpleDown = $table.tableSimpleDown;
+
+        $scope.tableSimpleUp = function (item, field, index) {
+            if ($scope.tableReset(true))
+                $table.tableSimpleUp(item, field, index);
+        };
+
+        $scope.tableSimpleDown = function (item, field, index) {
+            if ($scope.tableReset(true))
+                $table.tableSimpleDown(item, field, index);
+        };
+
         $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
 
+        $scope.tableEditedRowIndex = $table.tableEditedRowIndex;
+
         var previews = [];
 
         $scope.previewInit = function (preview) {
@@ -74,8 +118,8 @@ consoleModule.controller('clustersController', [
         };
 
         $scope.trustManagersConfigured = function() {
-            return $scope.backupItem.sslEnabled && $common.isDefined($scope.backupItem.sslContextFactory)
-                && !$common.isEmptyArray($scope.backupItem.sslContextFactory.trustManagers)
+            return $scope.backupItem.sslEnabled && $common.isDefined($scope.backupItem.sslContextFactory) &&
+                !$common.isEmptyArray($scope.backupItem.sslContextFactory.trustManagers);
         };
 
         $scope.previewChanged = $preview.previewChanged;
@@ -163,14 +207,14 @@ consoleModule.controller('clustersController', [
         $scope.tableSimpleValid = function (item, field, val, index) {
             var model = $common.getModel(item, field)[field.model];
 
-            if (field.model == 'trustManagers' && !$common.isValidJavaClass('Trust manager', val, false,  $table.tableFieldId(index, 'trustManagers'), false))
+            if (field.model === 'trustManagers' && !$common.isValidJavaClass('Trust manager', val, false,  $table.tableFieldId(index, 'trustManagers'), false))
                 return false;
 
             if ($common.isDefined(model)) {
                 var idx = _.indexOf(model, val);
 
                 // Found duplicate.
-                if (idx >= 0 && idx != index) {
+                if (idx >= 0 && idx !== index) {
                     var simpleTable = simpleTables[field.model];
 
                     if (simpleTable) {
@@ -235,7 +279,7 @@ consoleModule.controller('clustersController', [
 
                             if (lastSelectedCluster) {
                                 var idx = _.findIndex($scope.clusters, function (cluster) {
-                                    return cluster._id == lastSelectedCluster;
+                                    return cluster._id === lastSelectedCluster;
                                 });
 
                                 if (idx >= 0)
@@ -406,18 +450,18 @@ consoleModule.controller('clustersController', [
 
         // Add new cluster.
         $scope.createItem = function(id) {
-            $table.tableReset();
-
-            $timeout(function () {
-                $common.ensureActivePanel($scope.panels, "general", 'clusterName');
-            });
+            if ($scope.tableReset(true)) {
+                $timeout(function () {
+                    $common.ensureActivePanel($scope.panels, "general", 'clusterName');
+                });
 
-            $scope.selectItem(undefined, prepareNewItem(id));
+                $scope.selectItem(undefined, prepareNewItem(id));
+            }
         };
 
         $scope.indexOfCache = function (cacheId) {
             return _.findIndex($scope.caches, function (cache) {
-                return cache.value == cacheId;
+                return cache.value === cacheId;
             });
         };
 
@@ -552,13 +596,13 @@ consoleModule.controller('clustersController', [
             if (!$common.isEmptyString(d.authenticator) && !$common.isValidJavaClass('Node authenticator', d.authenticator, false, 'authenticator', false, $scope.panels, 'discovery'))
                 return false;
 
-            if (item.discovery.kind == 'Vm' && item.discovery.Vm.addresses.length == 0)
+            if (item.discovery.kind === 'Vm' && item.discovery.Vm.addresses.length === 0)
                 return showPopoverMessage($scope.panels, 'general', 'addresses', 'Addresses are not specified');
 
-            if (item.discovery.kind == 'S3' && $common.isEmptyString(item.discovery.S3.bucketName))
+            if (item.discovery.kind === 'S3' && $common.isEmptyString(item.discovery.S3.bucketName))
                 return showPopoverMessage($scope.panels, 'general', 'bucketName', 'Bucket name should not be empty');
 
-            if (item.discovery.kind == 'Cloud') {
+            if (item.discovery.kind === 'Cloud') {
                 if ($common.isEmptyString(item.discovery.Cloud.identity))
                     return showPopoverMessage($scope.panels, 'general', 'identity', 'Identity should not be empty');
 
@@ -566,7 +610,7 @@ consoleModule.controller('clustersController', [
                     return showPopoverMessage($scope.panels, 'general', 'provider', 'Provider should not be empty');
             }
 
-            if (item.discovery.kind == 'GoogleStorage') {
+            if (item.discovery.kind === 'GoogleStorage') {
                 if ($common.isEmptyString(item.discovery.GoogleStorage.projectName))
                     return showPopoverMessage($scope.panels, 'general', 'projectName', 'Project name should not be empty');
 
@@ -581,8 +625,7 @@ consoleModule.controller('clustersController', [
             }
 
             if (item.sslEnabled) {
-                if (!$common.isDefined(item.sslContextFactory)
-                    || $common.isEmptyString(item.sslContextFactory.keyStoreFilePath))
+                if (!$common.isDefined(item.sslContextFactory) || $common.isEmptyString(item.sslContextFactory.keyStoreFilePath))
                     return showPopoverMessage($scope.panels, 'sslConfiguration', 'keyStoreFilePath', 'Key store file should not be empty');
 
                 if ($common.isEmptyString(item.sslContextFactory.trustStoreFilePath) && $common.isEmptyArray(item.sslContextFactory.trustManagers))
@@ -616,7 +659,7 @@ consoleModule.controller('clustersController', [
                     $scope.ui.markPristine();
 
                     var idx = _.findIndex($scope.clusters, function (cluster) {
-                        return cluster._id == _id;
+                        return cluster._id === _id;
                     });
 
                     if (idx >= 0)
@@ -637,27 +680,27 @@ consoleModule.controller('clustersController', [
 
         // Save cluster.
         $scope.saveItem = function () {
-            $table.tableReset();
-
-            var item = $scope.backupItem;
+            if ($scope.tableReset(true)) {
+                var item = $scope.backupItem;
 
-            if (validate(item))
-                save(item);
+                if (validate(item))
+                    save(item);
+            }
         };
 
         // Copy cluster with new name.
         $scope.cloneItem = function () {
-            $table.tableReset();
+            if ($scope.tableReset(true)) {
+                if (validate($scope.backupItem))
+                    $clone.confirm($scope.backupItem.name).then(function (newName) {
+                        var item = angular.copy($scope.backupItem);
 
-            if (validate($scope.backupItem))
-                $clone.confirm($scope.backupItem.name).then(function (newName) {
-                    var item = angular.copy($scope.backupItem);
+                        item._id = undefined;
+                        item.name = newName;
 
-                    item._id = undefined;
-                    item.name = newName;
-
-                    save(item);
-                });
+                        save(item);
+                    });
+            }
         };
 
         // Remove cluster from db.
@@ -677,7 +720,7 @@ consoleModule.controller('clustersController', [
                                 var clusters = $scope.clusters;
 
                                 var idx = _.findIndex(clusters, function (cluster) {
-                                    return cluster._id == _id;
+                                    return cluster._id === _id;
                                 });
 
                                 if (idx >= 0) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/2dc4d203/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index 59ebb72..d389264 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -1169,14 +1169,16 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
     var table = {name: 'none', editIndex: -1};
 
     function _tableReset() {
+        table.field = undefined;
         table.name = 'none';
         table.editIndex = -1;
 
         $common.hidePopover();
     }
 
-    function _tableState(name, editIndex) {
-        table.name = name;
+    function _tableState(field, editIndex, specName) {
+        table.field = field;
+        table.name = specName || field.model;
         table.editIndex = editIndex;
     }
 
@@ -1199,7 +1201,7 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
     }
 
     function _tableStartEdit(item, field, index) {
-        _tableState(field.model, index);
+        _tableState(field, index);
 
         var val = _model(item, field)[field.model][index];
 
@@ -1234,7 +1236,7 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
     }
 
     function _tableNewItem(field) {
-        _tableState(field.model, -1);
+        _tableState(field, -1);
 
         var ui = _tableUI(field);
 
@@ -1264,21 +1266,14 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
 
             _tableFocus(field.focusId, -1);
         }
-        else if (ui === 'table-index-fields') {
-            _tableFocus('FieldName' + (field.sorted ? 'S' : '') + field.indexIdx, -1);
-        }
     }
 
     return {
         tableVisibleRow: function (rows, row) {
             return !row || !row._id || _.findIndex(rows, function(item) {return item._id === row._id;}) >= 0;
         },
-        tableState: function (name, editIndex) {
-            _tableState(name, editIndex);
-        },
-        tableReset: function () {
-            _tableReset();
-        },
+        tableState: _tableState,
+        tableReset: _tableReset,
         tableNewItem: _tableNewItem,
         tableNewItemActive: function (field) {
             return table.name === field.model && table.editIndex < 0;
@@ -1286,16 +1281,24 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
         tableEditing: function (field, index) {
             return table.name === field.model && table.editIndex === index;
         },
+        tableEditedRowIndex: function () {
+            return table.editIndex;
+        },
+        tableField: function () {
+            return table.field;
+        },
         tableStartEdit: _tableStartEdit,
         tableRemove: function (item, field, index) {
             _tableReset();
 
             _model(item, field)[field.model].splice(index, 1);
         },
-        tableSimpleSave: function (valueValid, item, field, index) {
+        tableSimpleSave: function (valueValid, item, field, index, stopEdit) {
             var simpleValue = _tableSimpleValue(field, index);
 
-            if (valueValid(item, field, simpleValue, index)) {
+            var valid = valueValid(item, field, simpleValue, index);
+
+            if (valid) {
                 _tableReset();
 
                 if (index < 0) {
@@ -1304,19 +1307,24 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
                     else
                         _model(item, field)[field.model] = [simpleValue];
 
-                    _tableNewItem(field);
+                    if (!stopEdit)
+                        _tableNewItem(field);
                 }
                 else {
                     var arr = _model(item, field)[field.model];
 
                     arr[index] = simpleValue;
 
-                    if (index < arr.length - 1)
-                        _tableStartEdit(item, field, index + 1);
-                    else
-                        _tableNewItem(field);
+                    if (!stopEdit) {
+                        if (index < arr.length - 1)
+                            _tableStartEdit(item, field, index + 1);
+                        else
+                            _tableNewItem(field);
+                    }
                 }
             }
+
+            return valid;
         },
         tableSimpleSaveVisible: function (field, index) {
             return !$common.isEmptyString(_tableSimpleValue(field, index));
@@ -1335,8 +1343,10 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
             return index < _model(item, field)[field.model].length - 1;
         },
         tablePairValue: _tablePairValue,
-        tablePairSave: function (pairValid, item, field, index) {
-            if (pairValid(item, field, index)) {
+        tablePairSave: function (pairValid, item, field, index, stopEdit) {
+            var valid = pairValid(item, field, index);
+
+            if (valid) {
                 var pairValue = _tablePairValue(field, index);
 
                 var pairModel = {};
@@ -1350,7 +1360,8 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
                     else
                         item[field.model] = [pairModel];
 
-                    _tableNewItem(field);
+                    if (!stopEdit)
+                        _tableNewItem(field);
                 }
                 else {
                     pairModel = item[field.model][index];
@@ -1358,12 +1369,16 @@ consoleModule.service('$table', ['$common', '$focus', function ($common, $focus)
                     pairModel[field.keyName] = pairValue.key;
                     pairModel[field.valueName] = pairValue.value;
 
-                    if (index < item[field.model].length - 1)
-                        _tableStartEdit(item, field, index + 1);
-                    else
-                        _tableNewItem(field);
+                    if (!stopEdit) {
+                        if (index < item[field.model].length - 1)
+                            _tableStartEdit(item, field, index + 1);
+                        else
+                            _tableNewItem(field);
+                    }
                 }
             }
+
+            return valid;
         },
         tablePairSaveVisible: function (field, index) {
             var pairValue = _tablePairValue(field, index);

http://git-wip-us.apache.org/repos/asf/ignite/blob/2dc4d203/modules/control-center-web/src/main/js/controllers/igfs-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/igfs-controller.js b/modules/control-center-web/src/main/js/controllers/igfs-controller.js
index e2960de..be9344d 100644
--- a/modules/control-center-web/src/main/js/controllers/igfs-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/igfs-controller.js
@@ -35,19 +35,63 @@ consoleModule.controller('igfsController', [
             $scope.panelExpanded = $common.panelExpanded;
 
             $scope.tableVisibleRow = $table.tableVisibleRow;
-            $scope.tableReset = $table.tableReset;
-            $scope.tableNewItem = $table.tableNewItem;
+
+            $scope.tableSave = function (field, index, stopEdit) {
+                switch (field.type) {
+                    case 'pathModes':
+                        if ($table.tablePairSaveVisible(field, index))
+                            return $table.tablePairSave($scope.tablePairValid, $scope.backupItem, field, index, stopEdit);
+
+                        break;
+                }
+
+                return true;
+            };
+
+            $scope.tableReset = function (save) {
+                var field = $table.tableField();
+
+                if (!save || !$common.isDefined(field) || $scope.tableSave(field, $table.tableEditedRowIndex(), true)) {
+                    $table.tableReset();
+
+                    return true;
+                }
+
+                return false;
+            };
+
+            $scope.tableNewItem = function (field) {
+                if ($scope.tableReset(true))
+                    $table.tableNewItem(field);
+            };
+
             $scope.tableNewItemActive = $table.tableNewItemActive;
+
+            $scope.tableStartEdit = function (item, field, index) {
+                if ($scope.tableReset(true))
+                    $table.tableStartEdit(item, field, index);
+            };
+
             $scope.tableEditing = $table.tableEditing;
-            $scope.tableStartEdit = $table.tableStartEdit;
+
             $scope.tableRemove = function (item, field, index) {
-                $table.tableRemove(item, field, index);
+                if ($scope.tableReset(true))
+                    $table.tableRemove(item, field, index);
             };
 
             $scope.tableSimpleSave = $table.tableSimpleSave;
             $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
-            $scope.tableSimpleUp = $table.tableSimpleUp;
-            $scope.tableSimpleDown = $table.tableSimpleDown;
+
+            $scope.tableSimpleUp = function (item, field, index) {
+                if ($scope.tableReset(true))
+                    $table.tableSimpleUp(item, field, index);
+            };
+
+            $scope.tableSimpleDown = function (item, field, index) {
+                if ($scope.tableReset(true))
+                    $table.tableSimpleDown(item, field, index);
+            };
+
             $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
 
             $scope.tablePairSave = $table.tablePairSave;
@@ -250,13 +294,13 @@ consoleModule.controller('igfsController', [
 
             // Add new IGFS.
             $scope.createItem = function (id) {
-                $table.tableReset();
-
-                $timeout(function () {
-                    $common.ensureActivePanel($scope.panels, 'general', 'igfsName');
-                });
+                if ($scope.tableReset(true)) {
+                    $timeout(function () {
+                        $common.ensureActivePanel($scope.panels, 'general', 'igfsName');
+                    });
 
-                $scope.selectItem(undefined, prepareNewItem(id));
+                    $scope.selectItem(undefined, prepareNewItem(id));
+                }
             };
 
             // Check IGFS logical consistency.
@@ -322,27 +366,27 @@ consoleModule.controller('igfsController', [
 
             // Save IGFS.
             $scope.saveItem = function () {
-                $table.tableReset();
-
-                var item = $scope.backupItem;
+                if ($scope.tableReset(true)) {
+                    var item = $scope.backupItem;
 
-                if (validate(item))
-                    save(item);
+                    if (validate(item))
+                        save(item);
+                }
             };
 
             // Save IGFS with new name.
             $scope.cloneItem = function () {
-                $table.tableReset();
+                if ($scope.tableReset(true)) {
+                    if (validate($scope.backupItem))
+                        $clone.confirm($scope.backupItem.name).then(function (newName) {
+                            var item = angular.copy($scope.backupItem);
 
-                if (validate($scope.backupItem))
-                    $clone.confirm($scope.backupItem.name).then(function (newName) {
-                        var item = angular.copy($scope.backupItem);
+                            item._id = undefined;
+                            item.name = newName;
 
-                        item._id = undefined;
-                        item.name = newName;
-
-                        save(item);
-                    });
+                            save(item);
+                        });
+                }
             };
 
             // Remove IGFS from db.

http://git-wip-us.apache.org/repos/asf/ignite/blob/2dc4d203/modules/control-center-web/src/main/js/controllers/metadata-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/metadata-controller.js b/modules/control-center-web/src/main/js/controllers/metadata-controller.js
index 29fafac..10a047a 100644
--- a/modules/control-center-web/src/main/js/controllers/metadata-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/metadata-controller.js
@@ -39,19 +39,82 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
             $scope.panelExpanded = $common.panelExpanded;
 
             $scope.tableVisibleRow = $table.tableVisibleRow;
-            $scope.tableReset = $table.tableReset;
-            $scope.tableNewItem = $table.tableNewItem;
+
+            $scope.tableSave = function (field, index, stopEdit) {
+                if ($table.tableEditing({model: 'table-index-fields'}, $table.tableEditedRowIndex())) {
+                    if ($scope.tableIndexItemSaveVisible(field, index))
+                        return $scope.tableIndexItemSave(field, field.indexIdx, index, stopEdit);
+                }
+                else {
+                    switch (field.type) {
+                        case 'fields':
+                        case 'aliases':
+                            if ($table.tablePairSaveVisible(field, index))
+                                return $table.tablePairSave($scope.tablePairValid, $scope.backupItem, field, index, stopEdit);
+
+                            break;
+
+                        case 'indexes':
+                            if ($scope.tableIndexSaveVisible(field, index))
+                                return $scope.tableIndexSave(field, index, stopEdit);
+
+                            break;
+
+                        case 'table-db-fields':
+                            if ($scope.tableDbFieldSaveVisible(field, index))
+                                return $scope.tableDbFieldSave(field, index, stopEdit);
+
+                            break;
+                    }
+                }
+
+                return true;
+            };
+
+            $scope.tableReset = function (save) {
+                var field = $table.tableField();
+
+                if (!save || !$common.isDefined(field) || $scope.tableSave(field, $table.tableEditedRowIndex(), true)) {
+                    $table.tableReset();
+
+                    return true;
+                }
+
+                return false;
+            };
+
+            $scope.tableNewItem = function (field) {
+                if ($scope.tableReset(true))
+                    $table.tableNewItem(field);
+            };
+
             $scope.tableNewItemActive = $table.tableNewItemActive;
+
+            $scope.tableStartEdit = function (item, field, index) {
+                if ($scope.tableReset(true))
+                    $table.tableStartEdit(item, field, index);
+            };
+
             $scope.tableEditing = $table.tableEditing;
-            $scope.tableStartEdit = $table.tableStartEdit;
+
             $scope.tableRemove = function (item, field, index) {
-                $table.tableRemove(item, field, index);
+                if ($scope.tableReset(true))
+                    $table.tableRemove(item, field, index);
             };
 
             $scope.tableSimpleSave = $table.tableSimpleSave;
             $scope.tableSimpleSaveVisible = $table.tableSimpleSaveVisible;
-            $scope.tableSimpleUp = $table.tableSimpleUp;
-            $scope.tableSimpleDown = $table.tableSimpleDown;
+
+            $scope.tableSimpleUp = function (item, field, index) {
+                if ($scope.tableReset(true))
+                    $table.tableSimpleUp(item, field, index);
+            };
+
+            $scope.tableSimpleDown = function (item, field, index) {
+                if ($scope.tableReset(true))
+                    $table.tableSimpleDown(item, field, index);
+            };
+
             $scope.tableSimpleDownVisible = $table.tableSimpleDownVisible;
 
             $scope.tablePairStartEdit = $table.tablePairStartEdit;
@@ -301,7 +364,7 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                 loadMetaModal.$promise.then(loadMetaModal.show);
 
                     // Get available JDBC drivers via agent.
-                    if ($scope.loadMeta.action == 'drivers') {
+                    if ($scope.loadMeta.action === 'drivers') {
                         $loading.start('loadingMetadataFromDb');
 
                         $http.post('/api/v1/agent/drivers')
@@ -478,12 +541,12 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
 
                     $http.post('/api/v1/configuration/metadata/save/batch', batch)
                         .success(function (savedBatch) {
-                            var lastItem = undefined;
+                            var lastItem;
                             var newItems = [];
 
                             _.forEach(savedBatch, function (savedItem) {
                                 var idx = _.findIndex($scope.metadatas, function (meta) {
-                                    return meta._id == savedItem._id;
+                                    return meta._id === savedItem._id;
                                 });
 
                                 if (idx >= 0)
@@ -538,6 +601,19 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
 
                 var containKey = true;
 
+                function queryField(name, jdbcType) {
+                    return {name: toJavaName(name), className: jdbcType.javaType};
+                }
+
+                function dbField(name, jdbcType) {
+                    return {
+                        databaseFieldName: name,
+                        databaseFieldType: jdbcType.dbName,
+                        javaFieldName: toJavaName(name),
+                        javaFieldType: jdbcType.javaType
+                    };
+                }
+
                 _.forEach($scope.loadMeta.tables, function (table) {
                     if (table.use) {
                         var qryFields = [];
@@ -554,19 +630,6 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
 
                         var valType = $commonUtils.toJavaPackageName($scope.ui.packageName) + '.' + toJavaClassName(tableName);
 
-                        function queryField(name, jdbcType) {
-                            return {name: toJavaName(name), className: jdbcType.javaType};
-                        }
-
-                        function dbField(name, jdbcType) {
-                            return {
-                                databaseFieldName: name,
-                                databaseFieldType: jdbcType.dbName,
-                                javaFieldName: toJavaName(name),
-                                javaFieldType: jdbcType.javaType
-                            };
-                        }
-
                         var _containKey = false;
 
                         _.forEach(table.cols, function (col) {
@@ -748,7 +811,7 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
 
                                 if (lastSelectedMetadata) {
                                     var idx = _.findIndex($scope.metadatas, function (metadata) {
-                                        return metadata._id == lastSelectedMetadata;
+                                        return metadata._id === lastSelectedMetadata;
                                     });
 
                                     if (idx >= 0)
@@ -830,8 +893,8 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
 
                 $common.confirmUnsavedChanges($scope.ui.isDirty(), selectItem);
 
-                $scope.ui.formTitle = $common.isDefined($scope.backupItem) && $scope.backupItem._id
-                    ? 'Selected metadata: ' + $scope.backupItem.valueType
+                $scope.ui.formTitle = $common.isDefined($scope.backupItem) && $scope.backupItem._id ?
+                    'Selected metadata: ' + $scope.backupItem.valueType
                     : 'New metadata';
             };
 
@@ -844,14 +907,14 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
 
             // Add new metadata.
             $scope.createItem = function (cacheId) {
-                $table.tableReset();
-
-                $timeout(function () {
-                    $common.ensureActivePanel($scope.panels, 'query');
-                    $common.ensureActivePanel($scope.panels, 'general', 'keyType');
-                });
+                if ($scope.tableReset(true)) {
+                    $timeout(function () {
+                        $common.ensureActivePanel($scope.panels, 'query');
+                        $common.ensureActivePanel($scope.panels, 'general', 'keyType');
+                    });
 
-                $scope.selectItem(undefined, prepareNewItem(cacheId));
+                    $scope.selectItem(undefined, prepareNewItem(cacheId));
+                }
             };
 
             // Check metadata logical consistency.
@@ -924,7 +987,7 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                         var savedMeta = res[0];
 
                         var idx = _.findIndex($scope.metadatas, function (metadata) {
-                            return metadata._id == savedMeta._id;
+                            return metadata._id === savedMeta._id;
                         });
 
                         if (idx >= 0)
@@ -943,27 +1006,27 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
 
             // Save cache type metadata.
             $scope.saveItem = function () {
-                $table.tableReset();
-
-                var item = $scope.backupItem;
+                if ($scope.tableReset(true)) {
+                    var item = $scope.backupItem;
 
-                if (validate(item))
-                    save(item);
+                    if (validate(item))
+                        save(item);
+                }
             };
 
             // Save cache type metadata with new name.
             $scope.cloneItem = function () {
-                $table.tableReset();
+                if ($scope.tableReset(true)) {
+                    if (validate($scope.backupItem))
+                        $clone.confirm($scope.backupItem.valueType).then(function (newName) {
+                            var item = angular.copy($scope.backupItem);
 
-                if (validate($scope.backupItem))
-                    $clone.confirm($scope.backupItem.valueType).then(function (newName) {
-                        var item = angular.copy($scope.backupItem);
+                            item._id = undefined;
+                            item.valueType = newName;
 
-                        item._id = undefined;
-                        item.valueType = newName;
-
-                        save(item);
-                    });
+                            save(item);
+                        });
+                }
             };
 
             // Remove metadata from db.
@@ -983,7 +1046,7 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                                     var metadatas = $scope.metadatas;
 
                                     var idx = _.findIndex(metadatas, function (metadata) {
-                                        return metadata._id == _id;
+                                        return metadata._id === _id;
                                     });
 
                                     if (idx >= 0) {
@@ -1035,7 +1098,7 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                 var validFilter = $filter('metadatasValidation');
 
                 var idx = _.findIndex(validFilter($scope.metadatas, $scope.ui.showValid, true), function (metadata) {
-                    return metadata._id == $scope.selectedItem._id;
+                    return metadata._id === $scope.selectedItem._id;
                 });
 
                 if (idx === -1)
@@ -1057,11 +1120,11 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
 
                     if ($common.isDefined(model)) {
                         var idx = _.findIndex(model, function (pair) {
-                            return pair[pairField.searchCol] == pairValue[pairField.valueCol];
+                            return pair[pairField.searchCol] === pairValue[pairField.valueCol];
                         });
 
                         // Found duplicate by key.
-                        if (idx >= 0 && idx != index)
+                        if (idx >= 0 && idx !== index)
                             return showPopoverMessage($scope.panels, 'query', $table.tableFieldId(index, pairField.idPrefix + pairField.id), 'Field with such ' + pairField.dupObjName + ' already exists!');
                     }
 
@@ -1073,8 +1136,8 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
             };
 
             function tableDbFieldValue(field, index) {
-                return (index < 0)
-                    ? {
+                return (index < 0) ?
+                    {
                         databaseFieldName: field.newDatabaseFieldName,
                         databaseFieldType: field.newDatabaseFieldType,
                         javaFieldName: field.newJavaFieldName,
@@ -1100,7 +1163,7 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                 valueFields: {msg: 'Value field', id: 'ValueField'}
             };
 
-            $scope.tableDbFieldSave = function (field, index) {
+            $scope.tableDbFieldSave = function (field, index, stopEdit) {
                 var dbFieldTable = dbFieldTables[field.model];
 
                 if (dbFieldTable) {
@@ -1148,13 +1211,19 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                         item[field.model] = model;
                     }
 
-                    if (index < 0)
-                        $table.tableNewItem(field);
-                    else  if (index < model.length - 1)
-                        $table.tableStartEdit(item, field, index + 1);
-                    else
-                        $table.tableNewItem(field);
+                    if (!stopEdit) {
+                        if (index < 0)
+                            $table.tableNewItem(field);
+                        else if (index < model.length - 1)
+                            $table.tableStartEdit(item, field, index + 1);
+                        else
+                            $table.tableNewItem(field);
+                    }
+
+                    return true;
                 }
+
+                return false;
             };
 
             function tableIndexName(field, index) {
@@ -1169,7 +1238,7 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                 return !$common.isEmptyString(tableIndexName(field, index)) && $common.isDefined(tableIndexType(field, index));
             };
 
-            $scope.tableIndexSave = function (field, curIdx) {
+            $scope.tableIndexSave = function (field, curIdx, stopEdit) {
                 var indexName = tableIndexName(field, curIdx);
                 var indexType = tableIndexType(field, curIdx);
 
@@ -1187,6 +1256,8 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                         return showPopoverMessage($scope.panels, 'query', $table.tableFieldId(curIdx, 'IndexName'), 'Index with such name already exists!');
                 }
 
+                $table.tableReset();
+
                 if (curIdx < 0) {
                     var newIndex = {name: indexName, indexType: indexType};
 
@@ -1200,79 +1271,88 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                     item.indexes[curIdx].indexType = indexType;
                 }
 
-                if (curIdx < 0)
-                    $scope.tableIndexNewItem(field, item.indexes.length - 1);
-                else {
-                    var index = item.indexes[curIdx];
+                if (!stopEdit) {
+                    if (curIdx < 0)
+                        $scope.tableIndexNewItem(field, item.indexes.length - 1);
+                    else {
+                        var index = item.indexes[curIdx];
 
-                    if (index.fields && index.fields.length > 0)
-                        $scope.tableIndexItemStartEdit(field, curIdx, 0);
-                    else
-                        $scope.tableIndexNewItem(field, curIdx);
+                        if (index.fields && index.fields.length > 0)
+                            $scope.tableIndexItemStartEdit(field, curIdx, 0);
+                        else
+                            $scope.tableIndexNewItem(field, curIdx);
+                    }
                 }
+
+                return true;
             };
 
             $scope.tableIndexNewItem = function (field, indexIdx) {
-                var index = $scope.backupItem.indexes[indexIdx];
-
-                var indexName = index.name;
+                if ($scope.tableReset(true)) {
+                    var index = $scope.backupItem.indexes[indexIdx];
 
-                $table.tableNewItem({ui: 'table-index-fields', model: indexName, sorted: index.indexType === 'SORTED', indexIdx: indexIdx});
+                    $table.tableState(field, -1, 'table-index-fields');
+                    $table.tableFocusInvalidField('FieldName' + (index.indexType === 'SORTED' ? 'S' : ''), indexIdx);
 
-                field.newFieldName = null;
-                field.newDirection = true;
+                    field.newFieldName = null;
+                    field.newDirection = true;
+                    field.indexIdx = indexIdx;
+                }
             };
 
-            $scope.tableIndexNewItemActive = function (itemIndex) {
+            $scope.tableIndexNewItemActive = function (field, itemIndex) {
                 var indexes = $scope.backupItem.indexes;
 
                 if (indexes) {
                     var index = indexes[itemIndex];
 
                     if (index)
-                        return $table.tableNewItemActive({model: index.name});
+                        return $table.tableNewItemActive({model: 'table-index-fields'}) && field.indexIdx === itemIndex;
                 }
 
                 return false;
             };
 
-            $scope.tableIndexItemEditing = function (itemIndex, curIdx) {
+            $scope.tableIndexItemEditing = function (field, itemIndex, curIdx) {
                 var indexes = $scope.backupItem.indexes;
 
                 if (indexes) {
                     var index = indexes[itemIndex];
 
                     if (index)
-                        return $table.tableEditing({model: index.name}, curIdx);
+                        return $table.tableEditing({model: 'table-index-fields'}, curIdx) && field.indexIdx === itemIndex;
                 }
 
                 return false;
             };
 
             function tableIndexItemValue(field, index) {
-                return index < 0
-                    ? {name: field.newFieldName, direction: field.newDirection}
+                return index < 0 ?
+                    {name: field.newFieldName, direction: field.newDirection}
                     : {name: field.curFieldName, direction: field.curDirection};
             }
 
             $scope.tableIndexItemStartEdit = function (field, indexIdx, curIdx) {
-                var index = $scope.backupItem.indexes[indexIdx];
+                if ($scope.tableReset(true)) {
+                    var index = $scope.backupItem.indexes[indexIdx];
 
-                $table.tableState(index.name, curIdx);
+                    $table.tableState(field, curIdx, 'table-index-fields');
 
-                var indexItem = index.fields[curIdx];
+                    var indexItem = index.fields[curIdx];
 
-                field.curFieldName = indexItem.name;
-                field.curDirection = indexItem.direction;
+                    field.curFieldName = indexItem.name;
+                    field.curDirection = indexItem.direction;
+                    field.indexIdx = indexIdx;
 
-                $focus('curFieldName' + (index.indexType === 'SORTED' ? 'S' : '') + indexIdx + '-' + curIdx);
+                    $focus('curFieldName' + (index.indexType === 'SORTED' ? 'S' : '') + field.indexIdx + '-' + curIdx);
+                }
             };
 
             $scope.tableIndexItemSaveVisible = function (field, index) {
                 return !$common.isEmptyString(tableIndexItemValue(field, index).name);
             };
 
-            $scope.tableIndexItemSave = function (field, indexIdx, curIdx) {
+            $scope.tableIndexItemSave = function (field, indexIdx, curIdx, stopEdit) {
                 var indexItemValue = tableIndexItemValue(field, curIdx);
 
                 var index = $scope.backupItem.indexes[indexIdx];
@@ -1289,22 +1369,31 @@ consoleModule.controller('metadataController', function ($filter, $http, $timeou
                         return showPopoverMessage($scope.panels, 'query', $table.tableFieldId(curIdx, 'FieldName' + (index.indexType === 'SORTED' ? 'S' : '') + indexIdx + (curIdx >= 0 ? '-' : '')), 'Field with such name already exists in index!');
                 }
 
+                $table.tableReset();
+
                 if (curIdx < 0) {
                     if (index.fields)
                         index.fields.push(indexItemValue);
                     else
                         index.fields = [indexItemValue];
 
-                    $scope.tableIndexNewItem(field, indexIdx);
+                    if (!stopEdit)
+                        $scope.tableIndexNewItem(field, indexIdx);
                 }
                 else {
                     index.fields[curIdx] = indexItemValue;
 
-                    if (curIdx < index.fields.length - 1)
-                        $scope.tableIndexItemStartEdit(field, indexIdx, curIdx + 1);
-                    else
-                        $scope.tableIndexNewItem(field, indexIdx);
+                    if (!stopEdit) {
+                        if (curIdx < index.fields.length - 1)
+                            $scope.tableIndexItemStartEdit(field, indexIdx, curIdx + 1);
+                        else
+                            $scope.tableIndexNewItem(field, indexIdx);
+                    }
                 }
+
+                field.indexIdx = -1;
+
+                return true;
             };
 
             $scope.tableRemoveIndexItem = function (index, curIdx) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/2dc4d203/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/helpers/generator/generator-java.js b/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
index fea1d1f..27e5f35 100644
--- a/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
+++ b/modules/control-center-web/src/main/js/helpers/generator/generator-java.js
@@ -567,8 +567,10 @@ $generatorJava.clusterBinary = function (cluster, res) {
             $generatorJava.declareVariable(res, arrVar, 'java.util.Collection', 'java.util.ArrayList', 'org.apache.ignite.binary.BinaryTypeConfiguration');
 
             _.forEach(binary.typeConfigurations, function (type) {
-                // TODO IGNITE-2269 Replace using of separated methods for binary type configurations to extended constructors.
-                res.line(arrVar + '.add(' + $generatorJava.binaryTypeFunctionName(type.typeName) + '());');
+                if (!$commonUtils.isDefinedAndNotEmpty(type.typeName)) {
+                    // TODO IGNITE-2269 Replace using of separated methods for binary type configurations to extended constructors.
+                    res.line(arrVar + '.add(' + $generatorJava.binaryTypeFunctionName(type.typeName) + '());');
+                }
             });
 
             res.needEmptyLine = true;
@@ -1616,7 +1618,7 @@ $generatorJava.clusterCaches = function (caches, igfss, isSrvCfg, res) {
 
 // Generate cluster caches.
 $generatorJava.clusterCacheUse = function (caches, igfss, res) {
-    function clusterCacheInvoke(res, cache, names) {
+    function clusterCacheInvoke(cache, names) {
         names.push($generatorJava.cacheVariableName(cache, names) + '(' + ($generatorCommon.cacheHasDatasource(cache) ? 'props' : '') + ')');
     }
 
@@ -1626,7 +1628,7 @@ $generatorJava.clusterCacheUse = function (caches, igfss, res) {
     var names = [];
 
     _.forEach(caches, function (cache) {
-        clusterCacheInvoke(res, cache, names);
+        clusterCacheInvoke(cache, names);
     });
 
     if (names.length > 0) {
@@ -1639,8 +1641,8 @@ $generatorJava.clusterCacheUse = function (caches, igfss, res) {
     var igfsNames = [];
 
     _.forEach(igfss, function (igfs) {
-        clusterCacheInvoke(res, $generatorCommon.igfsDataCache(igfs), igfsNames);
-        clusterCacheInvoke(res, $generatorCommon.igfsMetaCache(igfs), igfsNames);
+        clusterCacheInvoke($generatorCommon.igfsDataCache(igfs), igfsNames);
+        clusterCacheInvoke($generatorCommon.igfsMetaCache(igfs), igfsNames);
     });
 
     if (igfsNames.length > 0) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/2dc4d203/modules/control-center-web/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade
index b816859..7fe47bb 100644
--- a/modules/control-center-web/src/main/js/views/includes/controls.jade
+++ b/modules/control-center-web/src/main/js/views/includes/controls.jade
@@ -146,7 +146,7 @@ mixin details-row(lblClasses, fieldClasses)
     - var lblDetailClasses = lblClasses + ' details-label'
 
     - var detailMdl = 'getModel(backupItem, detail)[detail.model]';
-    - var detailCommon = {'ng-model': detailMdl, 'ng-required': '{{detail.required}}', 'ng-disabled': '{{detail.disabled}}'};
+    - var detailCommon = {'ng-model': detailMdl, 'ng-required': '{{detail.required}}', 'ng-disabled': '{{detail.disabled}}', 'ng-focus': 'tableReset(true)'};
     - var dropdownPlaceholder = {'ng-class': '{placeholder: !(' + detailMdl + ' && ' + detailMdl + '.length > 0)}'}
 
     - var customValidators = {'ng-attr-ipaddress': '{{detail.ipaddress}}'}
@@ -304,7 +304,7 @@ mixin table-row(lblClasses, fieldClasses)
     - var lblRowClasses = lblClasses + ' details-label'
 
     - var rowMdl = 'getModel(backupItem, field)[field.model][rowIndex][tableField.model]';
-    - var rowCommon = {'ng-model': rowMdl, 'ng-required': '{{tableField.required}}', 'ng-disabled': '{{tableField.disabled}}'};
+    - var rowCommon = {'ng-model': rowMdl, 'ng-required': '{{tableField.required}}', 'ng-disabled': '{{tableField.disabled}}', 'ng-focus': 'tableReset(true)'};
 
     div(ng-switch='tableField.type')
         div.checkbox(ng-switch-when='check')
@@ -326,7 +326,7 @@ mixin form-row(dataSource)
 
 mixin form-row-custom(lblClasses, fieldClasses, dataSource)
     - var fieldMdl = 'getModel('+ dataSource + ', field)[field.model]';
-    - var fieldCommon = {'ng-model': fieldMdl, 'ng-required': 'field.required || required(field)'};
+    - var fieldCommon = {'ng-model': fieldMdl, 'ng-required': 'field.required || required(field)', 'ng-focus': 'tableReset(true)'};
     - var fieldRequiredClass = '{true: "required"}[field.required || required(field)]'
     - var fieldHide = '{{field.hide}}'
     - var fieldDisabled = {'ng-disabled': '{{field.disabled}}'}
@@ -346,13 +346,13 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource)
             div(class=fieldClasses)
                 +tipField('field.tip')
                 .input-tip
-                    input.form-control(id='{{::field.id}}' type='text' placeholder='{{::field.placeholder}}' ng-focus='tableReset()')&attributes(fieldCommon)&attributes(fieldDisabled)
+                    input.form-control(id='{{::field.id}}' type='text' placeholder='{{::field.placeholder}}')&attributes(fieldCommon)&attributes(fieldDisabled)
         div(ng-switch-when='typeahead' ng-hide=fieldHide)
             label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
             div(class=fieldClasses)
                 +tipField('field.tip')
                 .input-tip
-                    input.form-control(id='{{::field.id}}' type='text' placeholder='{{::field.placeholder}}' ng-focus='tableReset()' bs-typeahead container='body' retain-selection data-min-length='1' bs-options='item for item in {{::field.items}}')&attributes(fieldCommon)
+                    input.form-control(id='{{::field.id}}' type='text' placeholder='{{::field.placeholder}}' bs-typeahead container='body' retain-selection data-min-length='1' bs-options='item for item in {{::field.items}}')&attributes(fieldCommon)
         div(ng-switch-when='password' ng-hide=fieldHide)
             label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}:
             div(class=fieldClasses)
@@ -364,7 +364,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource)
             div(class=fieldClasses)
                 +tipField('field.tip')
                 .input-tip
-                    input.form-control(id='{{::field.id}}' name='{{field.model}}' type='number' placeholder='{{::field.placeholder}}' ng-focus='tableReset()' min='{{field.min ? field.min : 0}}' max='{{field.max ? field.max : Number.MAX_VALUE}}')&attributes(fieldCommon)&attributes(fieldDisabled)
+                    input.form-control(id='{{::field.id}}' name='{{field.model}}' type='number' placeholder='{{::field.placeholder}}' min='{{field.min ? field.min : 0}}' max='{{field.max ? field.max : Number.MAX_VALUE}}')&attributes(fieldCommon)&attributes(fieldDisabled)
                     +ico-exclamation('{{field.model}}', 'min', 'Value is less than allowable minimum.')
                     +ico-exclamation('{{field.model}}', 'max', 'Value is more than allowable maximum.')
                     +ico-exclamation('{{field.model}}', 'number', 'Invalid value. Only numbers allowed.')
@@ -421,7 +421,7 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource)
                                         +btn-up('field.reordering && $index > 0', 'tableSimpleUp(backupItem, field, $index)')
                                     div(ng-if='tableEditing(field, $index)')
                                         label.labelField {{$index + 1}})
-                                        +btn-save('tableSimpleSaveVisible(field, $index)', 'tableSimpleSave(tableSimpleValid, backupItem, field, $index)')
+                                        +btn-save('tableSimpleSaveVisible(field, $index)', 'tableSave(field, $index)')
                                         .input-tip
                                             input.form-control(id='cur{{::field.focusId + $index}}' type='text' ng-model='field.curValue' placeholder='{{::field.placeholder}}' on-enter='tableSimpleSaveVisible(field) && tableSimpleSave(tableSimpleValid, backupItem, field, $index)' on-escape='tableReset()')
                         tfoot(ng-show='tableNewItemActive(field)')
@@ -496,13 +496,13 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource)
                                             tbody
                                                 tr(ng-repeat='itemItem in item.fields')
                                                     td
-                                                        div(ng-show='!tableIndexItemEditing(itemIndex, $index)')
+                                                        div(ng-show='!tableIndexItemEditing(field, itemIndex, $index)')
                                                             a.labelFormField(ng-if='item.indexType == "SORTED"' ng-click='tableIndexItemStartEdit(field, itemIndex, $index)') {{$index + 1}}) {{itemItem.name}} / {{itemItem.direction ? "ASC" : "DESC"}}
                                                             a.labelFormField(ng-if='item.indexType != "SORTED"' ng-click='tableIndexItemStartEdit(field, itemIndex, $index)') {{$index + 1}}) {{itemItem.name}}
                                                             +btn-remove('tableRemoveIndexItem(item, $index)', 'field.removeItemTip')
-                                                        div(ng-show='tableIndexItemEditing(itemIndex, $index)')
+                                                        div(ng-show='tableIndexItemEditing(field, itemIndex, $index)')
                                                             +table-index-item-edit('cur', '$index', 'item.indexType == "SORTED"', 'itemIndex + "-" + $index')
-                                            tfoot(ng-show='tableIndexNewItemActive(itemIndex)')
+                                            tfoot(ng-show='tableIndexNewItemActive(field, itemIndex)')
                                                 tr(style='padding-left: 18px')
                                                     td
                                                         +table-index-item-edit('new', '-1', 'item.indexType == "SORTED"', 'itemIndex')