You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2016/11/09 08:38:50 UTC

[36/50] [abbrv] ignite git commit: Web console beta-5.

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/on-focus-out.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/on-focus-out.directive.js b/modules/web-console/frontend/app/directives/on-focus-out.directive.js
new file mode 100644
index 0000000..2e6bfc6
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/on-focus-out.directive.js
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+export default ['$timeout', '$parse', ($timeout, $parse) => {
+    return ($scope, $element, $attrs) => {
+        const handlerCheckFocusOut = (FocusClick) => {
+            if ($element.find(FocusClick.target).length)
+                return;
+
+            $parse($attrs.igniteOnFocusOut)($scope);
+
+            $timeout();
+        };
+
+        window.addEventListener('click', handlerCheckFocusOut, true);
+        window.addEventListener('focusin', handlerCheckFocusOut, true);
+
+        $scope.$on('$destroy', () => {
+            window.removeEventListener('click', handlerCheckFocusOut, true);
+            window.removeEventListener('focusin', handlerCheckFocusOut, true);
+        });
+    };
+}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/restore-input-focus.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/restore-input-focus.directive.js b/modules/web-console/frontend/app/directives/restore-input-focus.directive.js
new file mode 100644
index 0000000..32e6622
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/restore-input-focus.directive.js
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+export default [() => {
+    return ($scope, $element) => {
+        $element.on('click', () => {
+            $element.siblings('.input-tip').find('input').focus();
+        });
+    };
+}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.controller.js b/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.controller.js
index f869e65..7e7a0e4 100644
--- a/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.controller.js
+++ b/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.controller.js
@@ -15,18 +15,78 @@
  * limitations under the License.
  */
 
-const SERVER_CFG = 'ServerConfigurationFactory';
-const CLIENT_CFG = 'ClientConfigurationFactory';
-
-export default ['$scope', 'GeneratorJava', function($scope, generator) {
+export default ['$scope', 'JavaTransformer', function($scope, java) {
     const ctrl = this;
 
     delete ctrl.data;
 
-    // Set default generator
-    ctrl.generator = (cluster) => {
-        const type = $scope.cfg ? CLIENT_CFG : SERVER_CFG;
+    const client = ctrl.client === 'true';
+
+    // Setup generator.
+    switch (ctrl.generator) {
+        case 'igniteConfiguration':
+            const clsName = client ? 'ClientConfigurationFactory' : 'ServerConfigurationFactory';
+
+            ctrl.generate = (cluster) => java.cluster(cluster, 'config', clsName, client);
+
+            break;
+        case 'clusterCaches':
+            ctrl.generate = (cluster, caches) => {
+                const clusterCaches = _.reduce(caches, (acc, cache) => {
+                    if (_.includes(cluster.caches, cache.value))
+                        acc.push(cache.cache);
+
+                    return acc;
+                }, []);
+
+                const cfg = java.generator.clusterGeneral(cluster);
+
+                java.generator.clusterCaches(cluster, clusterCaches, null, false, cfg);
+
+                return java.toSection(cfg);
+            };
+
+            break;
+        case 'cacheStore':
+        case 'cacheQuery':
+            ctrl.generate = (cache, domains) => {
+                const cacheDomains = _.reduce(domains, (acc, domain) => {
+                    if (_.includes(cache.domains, domain.value))
+                        acc.push(domain.meta);
+
+                    return acc;
+                }, []);
+
+                return java[ctrl.generator](cache, cacheDomains);
+            };
+
+            break;
+        case 'cacheNodeFilter':
+            ctrl.generate = (cache, igfss) => {
+                const cacheIgfss = _.reduce(igfss, (acc, igfs) => {
+                    acc.push(igfs.igfs);
+
+                    return acc;
+                }, []);
+
+                return java.cacheNodeFilter(cache, cacheIgfss);
+            };
+
+            break;
+        case 'igfss':
+            ctrl.generate = (cluster, igfss) => {
+                const clusterIgfss = _.reduce(igfss, (acc, igfs) => {
+                    if (_.includes(cluster.igfss, igfs.value))
+                        acc.push(igfs.igfs);
+
+                    return acc;
+                }, []);
+
+                return java.clusterIgfss(clusterIgfss);
+            };
 
-        return generator.cluster(cluster, 'config', type, $scope.cfg);
-    };
+            break;
+        default:
+            ctrl.generate = (master, detail) => java[ctrl.generator](master, detail);
+    }
 }];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.directive.js b/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.directive.js
index fbb1431..c21bff7 100644
--- a/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.directive.js
+++ b/modules/web-console/frontend/app/directives/ui-ace-java/ui-ace-java.directive.js
@@ -18,7 +18,7 @@
 import templateUrl from './ui-ace-java.jade';
 import controller from './ui-ace-java.controller';
 
-export default ['igniteUiAceJava', ['GeneratorJava', (generator) => {
+export default ['igniteUiAceJava', [() => {
     const link = (scope, $el, attrs, [ctrl, igniteUiAceTabs, formCtrl, ngModelCtrl]) => {
         if (formCtrl && ngModelCtrl)
             formCtrl.$removeControl(ngModelCtrl);
@@ -34,96 +34,12 @@ export default ['igniteUiAceJava', ['GeneratorJava', (generator) => {
         if (igniteUiAceTabs && igniteUiAceTabs.onChange)
             scope.onChange = igniteUiAceTabs.onChange;
 
-        const render = (data) => {
-            delete ctrl.data;
-
-            if (!data)
-                return;
-
-            return ctrl.generator(scope.master);
-        };
-
-        // Setup generator.
-        if (scope.generator) {
-            const method = scope.generator;
-
-            switch (method) {
-                case 'clusterCaches':
-                    ctrl.generator = (cluster) => {
-                        const caches = _.reduce(scope.detail, (acc, cache) => {
-                            if (_.includes(cluster.caches, cache.value))
-                                acc.push(cache.cache);
-
-                            return acc;
-                        }, []);
-
-                        return generator.clusterCaches(caches, null, true, generator.clusterGeneral(cluster)).asString();
-                    };
-
-                    break;
-
-                case 'igfss':
-                    ctrl.generator = (cluster) => {
-                        const igfss = _.reduce(scope.detail, (acc, igfs) => {
-                            if (_.includes(cluster.igfss, igfs.value))
-                                acc.push(igfs.igfs);
-
-                            return acc;
-                        }, []);
-
-                        return generator.igfss(igfss, 'cfg').asString();
-                    };
-
-                    break;
-
-                case 'cacheStore':
-                case 'cacheQuery':
-                    ctrl.generator = (cache) => {
-                        const domains = _.reduce(scope.detail, (acc, domain) => {
-                            if (_.includes(cache.domains, domain.value))
-                                acc.push(domain.meta);
-
-                            return acc;
-                        }, []);
-
-                        return generator[method](cache, domains).asString();
-                    };
-
-                    break;
-
-                case 'cacheNodeFilter':
-                    ctrl.generator = (cache) => {
-                        const igfss = _.reduce(scope.detail, (acc, igfs) => {
-                            acc.push(igfs.igfs);
-
-                            return acc;
-                        }, []);
-
-                        return generator.cacheNodeFilter(cache, igfss).asString();
-                    };
-
-                    break;
-
-                default:
-                    ctrl.generator = (data) => generator[method](data).asString();
-            }
-        }
-
-        if (!_.isUndefined(attrs.clusterCfg)) {
-            scope.$watch('cfg', (cfg) => {
-                if (!_.isUndefined(cfg))
-                    return;
-
-                scope.cfg = {};
-            });
-
-            scope.$watch('cfg', (data) => ctrl.data = render(data), true);
-        }
-
         const noDeepWatch = !(typeof attrs.noDeepWatch !== 'undefined');
 
         // Setup watchers.
-        scope.$watch('master', (data) => ctrl.data = render(data), noDeepWatch);
+        scope.$watch('master', () => {
+            ctrl.data = _.isNil(scope.master) ? null : ctrl.generate(scope.master, scope.detail).asString();
+        }, noDeepWatch);
     };
 
     return {
@@ -131,12 +47,12 @@ export default ['igniteUiAceJava', ['GeneratorJava', (generator) => {
         restrict: 'E',
         scope: {
             master: '=',
-            detail: '=',
-            generator: '@',
-            cfg: '=?clusterCfg'
+            detail: '='
         },
         bindToController: {
-            data: '=?ngModel'
+            data: '=?ngModel',
+            generator: '@',
+            client: '@'
         },
         link,
         templateUrl,

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js b/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js
index bc185b3..4e11874 100644
--- a/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js
+++ b/modules/web-console/frontend/app/directives/ui-ace-pojos/ui-ace-pojos.controller.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-export default ['$scope', 'JavaTypes', 'GeneratorJava', function($scope, JavaTypes, generator) {
+export default ['$scope', 'JavaTypes', 'JavaTransformer', function($scope, JavaTypes, generator) {
     const ctrl = this;
 
     // Watchers definition.

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-pom/ui-ace-pom.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-pom/ui-ace-pom.controller.js b/modules/web-console/frontend/app/directives/ui-ace-pom/ui-ace-pom.controller.js
index 82afeac..2bf78c3 100644
--- a/modules/web-console/frontend/app/directives/ui-ace-pom/ui-ace-pom.controller.js
+++ b/modules/web-console/frontend/app/directives/ui-ace-pom/ui-ace-pom.controller.js
@@ -25,7 +25,7 @@ export default ['$scope', 'GeneratorPom', 'IgniteVersion', function($scope, pom,
         if (!value)
             return;
 
-        ctrl.data = pom.generate($scope.cluster, Version.ignite).asString();
+        ctrl.data = pom.generate($scope.cluster, Version.productVersion().ignite).asString();
     };
 
     // Setup watchers.

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.controller.js b/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.controller.js
new file mode 100644
index 0000000..e600773
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.controller.js
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const SERVER_CFG = 'ServerConfigurationFactory';
+const CLIENT_CFG = 'ClientConfigurationFactory';
+
+export default ['$scope', 'IgniteSharpTransformer', function($scope, generator) {
+    const ctrl = this;
+
+    delete ctrl.data;
+
+    // Set default generator
+    ctrl.generator = (cluster) => {
+        const type = $scope.cfg ? CLIENT_CFG : SERVER_CFG;
+
+        return generator.cluster(cluster, 'config', type, $scope.cfg);
+    };
+}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.directive.js b/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.directive.js
new file mode 100644
index 0000000..5d9ad79
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.directive.js
@@ -0,0 +1,133 @@
+/*
+ * 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 templateUrl from './ui-ace-sharp.jade';
+import controller from './ui-ace-sharp.controller';
+
+export default ['igniteUiAceSharp', ['IgniteSharpTransformer', (generator) => {
+    const link = (scope, $el, attrs, [ctrl, igniteUiAceTabs, formCtrl, ngModelCtrl]) => {
+        if (formCtrl && ngModelCtrl)
+            formCtrl.$removeControl(ngModelCtrl);
+
+        if (igniteUiAceTabs && igniteUiAceTabs.onLoad) {
+            scope.onLoad = (editor) => {
+                igniteUiAceTabs.onLoad(editor);
+
+                scope.$watch('master', () => editor.attractAttention = false);
+            };
+        }
+
+        if (igniteUiAceTabs && igniteUiAceTabs.onChange)
+            scope.onChange = igniteUiAceTabs.onChange;
+
+        const render = (data) => {
+            delete ctrl.data;
+
+            if (!data)
+                return;
+
+            return ctrl.generator(scope.master);
+        };
+
+        // Setup generator.
+        if (scope.generator) {
+            const method = scope.generator;
+
+            switch (method) {
+                case 'clusterCaches':
+                    ctrl.generator = (cluster) => {
+                        const caches = _.reduce(scope.detail, (acc, cache) => {
+                            if (_.includes(cluster.caches, cache.value))
+                                acc.push(cache.cache);
+
+                            return acc;
+                        }, []);
+
+                        return generator.clusterCaches(cluster, caches, null, true).asString();
+                    };
+
+                    break;
+
+                case 'igfss':
+                    ctrl.generator = (cluster) => {
+                        const igfss = _.reduce(scope.detail, (acc, igfs) => {
+                            if (_.includes(cluster.igfss, igfs.value))
+                                acc.push(igfs.igfs);
+
+                            return acc;
+                        }, []);
+
+                        return generator.igfss(igfss, 'cfg').asString();
+                    };
+
+                    break;
+
+                case 'cacheStore':
+                    ctrl.generator = (cache) => {
+                        const domains = _.reduce(scope.detail, (acc, domain) => {
+                            if (_.includes(cache.domains, domain.value))
+                                acc.push(domain.meta);
+
+                            return acc;
+                        }, []);
+
+                        return generator.cacheStore(cache, domains).asString();
+                    };
+
+                    break;
+
+                default:
+                    ctrl.generator = (data) => generator[method](data).asString();
+            }
+        }
+
+        if (!_.isUndefined(attrs.clusterCfg)) {
+            scope.$watch('cfg', (cfg) => {
+                if (!_.isUndefined(cfg))
+                    return;
+
+                scope.cfg = {};
+            });
+
+            scope.$watch('cfg', (data) => ctrl.data = render(data), true);
+        }
+
+        const noDeepWatch = !(typeof attrs.noDeepWatch !== 'undefined');
+
+        // Setup watchers.
+        scope.$watch('master', (data) => ctrl.data = render(data), noDeepWatch);
+    };
+
+    return {
+        priority: 1,
+        restrict: 'E',
+        scope: {
+            master: '=',
+            detail: '=',
+            generator: '@',
+            cfg: '=?clusterCfg'
+        },
+        bindToController: {
+            data: '=?ngModel'
+        },
+        link,
+        templateUrl,
+        controller,
+        controllerAs: 'ctrl',
+        require: ['igniteUiAceSharp', '?^igniteUiAceTabs', '?^form', '?ngModel']
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.jade b/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.jade
new file mode 100644
index 0000000..d3f9e44
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/ui-ace-sharp/ui-ace-sharp.jade
@@ -0,0 +1,22 @@
+//-
+    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.
+
+div(ng-if='ctrl.data' 
+    ignite-ace='{onLoad: onLoad, \
+             onChange: onChange, \
+             renderOptions: renderOptions, \
+             mode: "csharp"}'
+    ng-model='ctrl.data')

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.controller.js b/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.controller.js
new file mode 100644
index 0000000..50b71cb
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.controller.js
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+export default ['$scope', 'SpringTransformer', function($scope, spring) {
+    const ctrl = this;
+
+    delete ctrl.data;
+
+    // Setup generator.
+    switch (ctrl.generator) {
+        case 'igniteConfiguration':
+            ctrl.generate = (cluster) => spring.cluster(cluster, ctrl.client === 'true');
+
+            break;
+        case 'clusterCaches':
+            ctrl.generate = (cluster, caches) => {
+                const clusterCaches = _.reduce(caches, (acc, cache) => {
+                    if (_.includes(cluster.caches, cache.value))
+                        acc.push(cache.cache);
+
+                    return acc;
+                }, []);
+
+                const cfg = spring.generator.clusterGeneral(cluster);
+
+                spring.generator.clusterCaches(cluster, clusterCaches, null, false, cfg);
+
+                return spring.toSection(cfg);
+            };
+
+            break;
+        case 'cacheStore':
+        case 'cacheQuery':
+            ctrl.generate = (cache, domains) => {
+                const cacheDomains = _.reduce(domains, (acc, domain) => {
+                    if (_.includes(cache.domains, domain.value))
+                        acc.push(domain.meta);
+
+                    return acc;
+                }, []);
+
+                return spring[ctrl.generator](cache, cacheDomains);
+            };
+
+            break;
+        case 'cacheNodeFilter':
+            ctrl.generate = (cache, igfss) => {
+                const cacheIgfss = _.reduce(igfss, (acc, igfs) => {
+                    acc.push(igfs.igfs);
+
+                    return acc;
+                }, []);
+
+                return spring.cacheNodeFilter(cache, cacheIgfss);
+            };
+
+            break;
+        case 'igfss':
+            ctrl.generate = (cluster, igfss) => {
+                const clusterIgfss = _.reduce(igfss, (acc, igfs) => {
+                    if (_.includes(cluster.igfss, igfs.value))
+                        acc.push(igfs.igfs);
+
+                    return acc;
+                }, []);
+
+                return spring.clusterIgfss(clusterIgfss);
+            };
+
+            break;
+        default:
+            ctrl.generate = (master, detail) => spring[ctrl.generator](master, detail);
+    }
+}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.directive.js b/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.directive.js
new file mode 100644
index 0000000..42d25b6
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.directive.js
@@ -0,0 +1,66 @@
+/*
+ * 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';
+
+import templateUrl from './ui-ace-spring.jade';
+import controller from './ui-ace-spring.controller';
+
+export default ['igniteUiAceSpring', [() => {
+    const link = (scope, $el, attrs, [ctrl, igniteUiAceTabs, formCtrl, ngModelCtrl]) => {
+        if (formCtrl && ngModelCtrl)
+            formCtrl.$removeControl(ngModelCtrl);
+
+        if (igniteUiAceTabs && igniteUiAceTabs.onLoad) {
+            scope.onLoad = (editor) => {
+                igniteUiAceTabs.onLoad(editor);
+
+                // Disable highlight in model switch.
+                scope.$watch('master', () => editor.attractAttention = false);
+            };
+        }
+
+        if (igniteUiAceTabs && igniteUiAceTabs.onChange)
+            scope.onChange = igniteUiAceTabs.onChange;
+
+        const noDeepWatch = !(typeof attrs.noDeepWatch !== 'undefined');
+
+        // Setup watchers.
+        scope.$watch('master', () => {
+            ctrl.data = _.isNil(scope.master) ? null : ctrl.generate(scope.master, scope.detail).asString();
+        }, noDeepWatch);
+    };
+
+    return {
+        priority: 1,
+        restrict: 'E',
+        scope: {
+            master: '=',
+            detail: '='
+        },
+        bindToController: {
+            data: '=?ngModel',
+            generator: '@',
+            client: '@'
+        },
+        link,
+        templateUrl,
+        controller,
+        controllerAs: 'ctrl',
+        require: ['igniteUiAceSpring', '?^igniteUiAceTabs', '?^form', '?ngModel']
+    };
+}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.jade b/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.jade
new file mode 100644
index 0000000..0dd627a
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/ui-ace-spring/ui-ace-spring.jade
@@ -0,0 +1,17 @@
+//-
+    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.
+
+div(ng-if='ctrl.data' ignite-ace='{onLoad: onLoad, onChange: onChange, mode: "xml"}' ng-model='ctrl.data')

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.controller.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.controller.js b/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.controller.js
deleted file mode 100644
index 3233757..0000000
--- a/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.controller.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-
-export default ['$scope', 'GeneratorXml', function($scope, generator) {
-    const ctrl = this;
-
-    delete ctrl.data;
-
-    // Set default generator
-    ctrl.generator = (cluster) => {
-        return generator.cluster(cluster, $scope.cfg);
-    };
-}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.directive.js b/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.directive.js
deleted file mode 100644
index 3bd834f..0000000
--- a/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.directive.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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 templateUrl from './ui-ace-xml.jade';
-import controller from './ui-ace-xml.controller';
-
-export default ['igniteUiAceXml', ['GeneratorXml', (generator) => {
-    const link = (scope, $el, attrs, [ctrl, igniteUiAceTabs, formCtrl, ngModelCtrl]) => {
-        if (formCtrl && ngModelCtrl)
-            formCtrl.$removeControl(ngModelCtrl);
-
-        if (igniteUiAceTabs && igniteUiAceTabs.onLoad) {
-            scope.onLoad = (editor) => {
-                igniteUiAceTabs.onLoad(editor);
-
-                scope.$watch('master', () => editor.attractAttention = false);
-            };
-        }
-
-        if (igniteUiAceTabs && igniteUiAceTabs.onChange)
-            scope.onChange = igniteUiAceTabs.onChange;
-
-        const render = (data) => {
-            delete ctrl.data;
-
-            if (!data)
-                return;
-
-            return ctrl.generator(scope.master);
-        };
-
-        // Setup generator.
-        if (scope.generator) {
-            const method = scope.generator;
-
-            switch (method) {
-                case 'clusterCaches':
-                    ctrl.generator = (cluster) => {
-                        const caches = _.reduce(scope.detail, (acc, cache) => {
-                            if (_.includes(cluster.caches, cache.value))
-                                acc.push(cache.cache);
-
-                            return acc;
-                        }, []);
-
-                        return generator.clusterCaches(caches, null, true, generator.clusterGeneral(cluster)).asString();
-                    };
-
-                    break;
-
-                case 'igfss':
-                    ctrl.generator = (cluster) => {
-                        const igfss = _.reduce(scope.detail, (acc, igfs) => {
-                            if (_.includes(cluster.igfss, igfs.value))
-                                acc.push(igfs.igfs);
-
-                            return acc;
-                        }, []);
-
-                        return generator.igfss(igfss).asString();
-                    };
-
-                    break;
-
-                case 'cacheStore':
-                case 'cacheQuery':
-                    ctrl.generator = (cache) => {
-                        const domains = _.reduce(scope.detail, (acc, domain) => {
-                            if (_.includes(cache.domains, domain.value))
-                                acc.push(domain.meta);
-
-                            return acc;
-                        }, []);
-
-                        return generator[method](cache, domains).asString();
-                    };
-
-                    break;
-
-                case 'cacheNodeFilter':
-                    ctrl.generator = (cache) => {
-                        const igfss = _.reduce(scope.detail, (acc, igfs) => {
-                            acc.push(igfs.igfs);
-
-                            return acc;
-                        }, []);
-
-                        return generator.cacheNodeFilter(cache, igfss).asString();
-                    };
-
-                    break;
-
-                default:
-                    ctrl.generator = (data) => generator[method](data).asString();
-            }
-        }
-
-        if (!_.isUndefined(attrs.clusterCfg)) {
-            scope.$watch('cfg', (cfg) => {
-                if (!_.isUndefined(cfg))
-                    return;
-
-                scope.cfg = {};
-            });
-
-            scope.$watch('cfg', (data) => ctrl.data = render(data), true);
-        }
-
-        const noDeepWatch = !(typeof attrs.noDeepWatch !== 'undefined');
-
-        // Setup watchers.
-        scope.$watch('master', (data) => ctrl.data = render(data), noDeepWatch);
-    };
-
-    return {
-        priority: 1,
-        restrict: 'E',
-        scope: {
-            master: '=',
-            detail: '=',
-            generator: '@',
-            cfg: '=?clusterCfg'
-        },
-        bindToController: {
-            data: '=?ngModel'
-        },
-        link,
-        templateUrl,
-        controller,
-        controllerAs: 'ctrl',
-        require: ['igniteUiAceXml', '?^igniteUiAceTabs', '?^form', '?ngModel']
-    };
-}]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.jade b/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.jade
deleted file mode 100644
index 0dd627a..0000000
--- a/modules/web-console/frontend/app/directives/ui-ace-xml/ui-ace-xml.jade
+++ /dev/null
@@ -1,17 +0,0 @@
-//-
-    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.
-
-div(ng-if='ctrl.data' ignite-ace='{onLoad: onLoad, onChange: onChange, mode: "xml"}' ng-model='ctrl.data')

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade b/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade
new file mode 100644
index 0000000..8f1487e
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.jade
@@ -0,0 +1,33 @@
+//-
+    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.
+
+mixin ui-grid-settings()
+    .ui-grid-settings
+        i.fa.fa-bars(data-animation='am-flip-x' bs-dropdown='' aria-haspopup='true' aria-expanded='expanded' data-auto-close='1' data-trigger='click')
+        ul.select.dropdown-menu(role='menu')
+            li(ng-repeat='item in paragraph.gridOptions.categories|filter:{selectable:true}')
+                a(ng-click='paragraph.toggleColumns(item, !item.visible)')
+                    i.fa.fa-check-square-o.pull-left(ng-if='item.visible')
+                    i.fa.fa-square-o.pull-left(ng-if='!item.visible')
+                    span {{::item.name}}
+            li.divider
+            li
+                a(ng-click='paragraph.selectAllColumns()') Select all
+            li
+                a(ng-click='paragraph.clearAllColumns()') Clear all
+            li.divider
+            li
+                a(ng-click='$hide()') Close

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss b/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss
new file mode 100644
index 0000000..6517a60
--- /dev/null
+++ b/modules/web-console/frontend/app/directives/ui-grid-settings/ui-grid-settings.scss
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+.ui-grid-settings {
+    ul.select.dropdown-menu > li > a {
+        padding-top: 0;
+        padding-bottom: 0;
+    }
+
+    ul.select.dropdown-menu > li > a > i {
+        position: relative;
+        line-height: 26px;
+        width: 14px;
+        margin-left: 0;
+        color: inherit;
+    }
+
+    ul.select.dropdown-menu > li > a > span {
+        line-height: 26px;
+        padding-left: 5px;
+        padding-right: 8px;
+        cursor: pointer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/filters/default-name.filter.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/filters/default-name.filter.js b/modules/web-console/frontend/app/filters/default-name.filter.js
new file mode 100644
index 0000000..687ff84
--- /dev/null
+++ b/modules/web-console/frontend/app/filters/default-name.filter.js
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+// Filter that will check name and return `<default>` if needed.
+export default [() => {
+    return (name, html) => _.isEmpty(name) ? (html ? '&lt;default&gt;' : '<default>') : name;
+}];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/filters/hasPojo.filter.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/filters/hasPojo.filter.js b/modules/web-console/frontend/app/filters/hasPojo.filter.js
index a179423..ee50051 100644
--- a/modules/web-console/frontend/app/filters/hasPojo.filter.js
+++ b/modules/web-console/frontend/app/filters/hasPojo.filter.js
@@ -15,4 +15,7 @@
  * limitations under the License.
  */
 
-export default ['hasPojo', [() => ({caches} = []) => _.find(caches, (cache) => cache.domains && cache.domains.length)]];
+// Filter that return 'true' if caches has at least one domain with 'generatePojo' flag.
+export default ['hasPojo', [() => ({caches} = []) =>
+    _.find(caches, (cache) => cache.domains && cache.domains.length &&
+        cache.domains.find((domain) => domain.generatePojo))]];

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/helpers/jade/form/form-field-feedback.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/form/form-field-feedback.jade b/modules/web-console/frontend/app/helpers/jade/form/form-field-feedback.jade
index bf012db..ac1f080 100644
--- a/modules/web-console/frontend/app/helpers/jade/form/form-field-feedback.jade
+++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-feedback.jade
@@ -21,9 +21,12 @@ mixin form-field-feedback(name, error, message)
 
     i.fa.fa-exclamation-triangle.form-field-feedback(
         ng-if='!#{__pristine} && #{__error}'
+        name='{{ #{name} }}'
+
         bs-tooltip
         data-title=message
+
         ignite-error=error
         ignite-error-message=message
-        name='{{ #{name} }}'
+        ignite-restore-input-focus
     )

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/helpers/jade/mixins.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/helpers/jade/mixins.jade b/modules/web-console/frontend/app/helpers/jade/mixins.jade
index 4979c12..9d46883 100644
--- a/modules/web-console/frontend/app/helpers/jade/mixins.jade
+++ b/modules/web-console/frontend/app/helpers/jade/mixins.jade
@@ -97,28 +97,30 @@ mixin ipaddress-port-range-feedback(name)
 mixin uuid-feedback(name)
     +form-field-feedback(name, 'uuid', 'Invalid node ID!')
 
-//- Mixin for checkbox.
-mixin checkbox(lbl, model, name, tip)
-    +form-field-checkbox(lbl, model, name, false, false, tip)
-
 //- Function that convert enabled state to corresponding disabled state.
 -var enabledToDisabled = function (enabled) {
 -    return (enabled === false || enabled === true) ? !enabled : '!(' + enabled + ')';
 -}
 
+//- Mixin for checkbox.
+mixin checkbox(lbl, model, name, tip)
+    +form-field-checkbox(lbl, model, name, false, false, tip)
+
 //- Mixin for checkbox with enabled condition.
 mixin checkbox-enabled(lbl, model, name, enabled, tip)
     +form-field-checkbox(lbl, model, name, enabledToDisabled(enabled), false, tip)
 
-//- Mixin for java name field with enabled condition.
-mixin java-class(lbl, model, name, enabled, required, tip)
+//- Mixin for Java class name field with auto focus condition.
+mixin java-class-autofocus-placholder(lbl, model, name, enabled, required, autofocus, placeholder, tip, validationActive)
     -var errLbl = lbl.substring(0, lbl.length - 1)
 
-    +ignite-form-field-text(lbl, model, name, enabledToDisabled(enabled), required, 'Enter fully qualified class name', tip)(
+    +ignite-form-field-text(lbl, model, name, enabledToDisabled(enabled), required, placeholder, tip)(
         data-java-identifier='true'
         data-java-package-specified='true'
         data-java-keywords='true'
         data-java-built-in-class='true'
+        data-ignite-form-field-input-autofocus=autofocus
+        data-validation-active=validationActive ? '{{ #{validationActive} }}' : '"always"'
     )
         if  block
             block
@@ -128,14 +130,27 @@ mixin java-class(lbl, model, name, enabled, required, tip)
         +form-field-feedback(name, 'javaPackageSpecified', errLbl + ' does not have package specified!')
         +form-field-feedback(name, 'javaIdentifier', errLbl + ' is invalid Java identifier!')
 
+//- Mixin for Java class name field with auto focus condition.
+mixin java-class-autofocus(lbl, model, name, enabled, required, autofocus, tip, validationActive)
+    +java-class-autofocus-placholder(lbl, model, name, enabled, required, autofocus, 'Enter fully qualified class name', tip, validationActive)
+        if  block
+            block
+
+//- Mixin for Java class name field.
+mixin java-class(lbl, model, name, enabled, required, tip, validationActive)
+    +java-class-autofocus(lbl, model, name, enabled, required, 'false', tip, validationActive)
+        if  block
+            block
+
 //- Mixin for text field with enabled condition with options.
-mixin java-class-typeahead(lbl, model, name, options, enabled, required, placeholder, tip)
+mixin java-class-typeahead(lbl, model, name, options, enabled, required, placeholder, tip, validationActive)
     -var errLbl = lbl.substring(0, lbl.length - 1)
 
     +form-field-datalist(lbl, model, name, enabledToDisabled(enabled), required, placeholder, options, tip)(
         data-java-identifier='true'
         data-java-package-specified='allow-built-in'
         data-java-keywords='true'
+        data-validation-active=validationActive ? '{{ #{validationActive} }}' : '"always"'
     )
         +form-field-feedback(name, 'javaKeywords', errLbl + ' could not contains reserved Java keyword!')
         +form-field-feedback(name, 'javaPackageSpecified', errLbl + ' does not have package specified!')
@@ -234,22 +249,21 @@ mixin table-text-field(name, model, items, valid, save, placeholder, newItem)
     -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
-    if block
-        block
+    div(ignite-on-focus-out=onBlur)
+        if block
+            block
+
+        .input-tip
+            +ignite-form-field-input(name, model, false, 'true', placeholder)(
+                data-ignite-unique=items
+                data-ignite-form-field-input-autofocus='true'
 
-    .input-tip
-        +ignite-form-field-input(name, model, false, 'true', placeholder)(
-            data-ignite-unique=items
-            data-ignite-form-field-input-autofocus='true'
-            ng-blur=onBlur
-            ignite-on-enter=onEnter
-            ignite-on-escape=onEscape
-        )
+                ignite-on-enter=onEnter
+                ignite-on-escape=onEscape
+            )
 
 //- Mixin for table java class field.
 mixin table-java-class-field(lbl, name, model, items, valid, save, newItem)
-    -var errLbl = lbl.substring(0, lbl.length - 1)
-
     -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)'
     -var onEnter = valid + ' && (' + save + '); ' + valid + ' && ' + resetOnEnter + ';'
 
@@ -258,31 +272,28 @@ mixin table-java-class-field(lbl, name, model, items, valid, save, newItem)
     -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
-    if block
-        block
-
-    +form-field-feedback(name, 'javaBuiltInClass', errLbl + ' should not be the Java built-in class!')
-    +form-field-feedback(name, 'javaKeywords', errLbl + ' could not contains reserved Java keyword!')
-    +form-field-feedback(name, 'javaPackageSpecified', errLbl + ' does not have package specified!')
-    +form-field-feedback(name, 'javaIdentifier', errLbl + ' is invalid Java identifier!')
+    div(ignite-on-focus-out=onBlur)
+        +form-field-feedback(name, 'javaBuiltInClass', lbl + ' should not be the Java built-in class!')
+        +form-field-feedback(name, 'javaKeywords', lbl + ' could not contains reserved Java keyword!')
+        +form-field-feedback(name, 'javaPackageSpecified', lbl + ' does not have package specified!')
+        +form-field-feedback(name, 'javaIdentifier', lbl + ' is invalid Java identifier!')
 
-    if block
-        block
+        if block
+            block
 
-    .input-tip
-        +ignite-form-field-input(name, model, 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'
+        .input-tip
+            +ignite-form-field-input(name, model, 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'
 
-            data-ignite-unique=items
-            data-ignite-form-field-input-autofocus='true'
+                data-ignite-unique=items
+                data-ignite-form-field-input-autofocus='true'
 
-            ng-blur=onBlur
-            ignite-on-enter=onEnter
-            ignite-on-escape=onEscape
-        )
+                ignite-on-enter=onEnter
+                ignite-on-escape=onEscape
+            )
 
 //- Mixin for table java package field.
 mixin table-java-package-field(name, model, items, valid, save, newItem)
@@ -294,24 +305,24 @@ mixin table-java-package-field(name, model, items, valid, save, newItem)
     -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
-    +form-field-feedback(name, 'javaKeywords', 'Package name could not contains reserved Java keyword!')
-    +form-field-feedback(name, 'javaPackageName', 'Package name is invalid!')
+    div(ignite-on-focus-out=onBlur)
+        +form-field-feedback(name, 'javaKeywords', 'Package name could not contains reserved Java keyword!')
+        +form-field-feedback(name, 'javaPackageName', 'Package name is invalid!')
 
-    if block
-        block
+        if block
+            block
 
-    .input-tip
-        +ignite-form-field-input(name, model, false, 'true', 'Enter package name')(
-            data-java-keywords='true'
-            data-java-package-name='package-only'
+        .input-tip
+            +ignite-form-field-input(name, model, false, 'true', 'Enter package name')(
+                data-java-keywords='true'
+                data-java-package-name='package-only'
 
-            data-ignite-unique=items
-            data-ignite-form-field-input-autofocus='true'
+                data-ignite-unique=items
+                data-ignite-form-field-input-autofocus='true'
 
-            ng-blur=onBlur
-            ignite-on-enter=onEnter
-            ignite-on-escape=onEscape
-        )
+                ignite-on-enter=onEnter
+                ignite-on-escape=onEscape
+            )
 
 
 //- Mixin for table address field.
@@ -324,24 +335,26 @@ mixin table-address-field(name, model, items, valid, save, newItem, portRange)
     -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
-    +ipaddress-feedback(name)
-    +ipaddress-port-feedback(name)
-    +ipaddress-port-range-feedback(name)
-
-    if block
-        block
-
-    .input-tip
-        +ignite-form-field-input(name, model, false, 'true', 'IP address:port')(
-            data-ipaddress='true'
-            data-ipaddress-with-port='true'
-            data-ipaddress-with-port-range=portRange ? 'true' : null
-            data-ignite-unique=items
-            data-ignite-form-field-input-autofocus='true'
-            ng-blur=onBlur
-            ignite-on-enter=onEnter
-            ignite-on-escape=onEscape
-        )
+    div(ignite-on-focus-out=onBlur)
+        +ipaddress-feedback(name)
+        +ipaddress-port-feedback(name)
+        +ipaddress-port-range-feedback(name)
+        +form-field-feedback(name, 'required', 'IP address:port could not be empty!')
+
+        if block
+            block
+
+        .input-tip
+            +ignite-form-field-input(name, model, false, 'true', 'IP address:port')(
+                data-ipaddress='true'
+                data-ipaddress-with-port='true'
+                data-ipaddress-with-port-range=portRange ? 'true' : null
+                data-ignite-unique=items
+                data-ignite-form-field-input-autofocus='true'
+
+                ignite-on-enter=onEnter
+                ignite-on-escape=onEscape
+            )
 
 //- Mixin for table UUID field.
 mixin table-uuid-field(name, model, items, valid, save, newItem)
@@ -353,18 +366,19 @@ mixin table-uuid-field(name, model, items, valid, save, newItem)
     -var resetOnBlur = newItem ? '!stopblur && (group.add = [])' : 'field.edit = false'
     -var onBlur = valid + ' && ( ' + save + '); ' + resetOnBlur + ';'
 
-    if block
-        block
+    div(ignite-on-focus-out=onBlur)
+        if block
+            block
+
+        .input-tip
+            +ignite-form-field-input(name, model, false, 'true', 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')(
+                data-uuid='true'
+                data-ignite-unique=items
+                data-ignite-form-field-input-autofocus='true'
 
-    .input-tip
-        +ignite-form-field-input(name, model, false, 'true', 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')(
-            data-uuid='true'
-            data-ignite-unique=items
-            data-ignite-form-field-input-autofocus='true'
-            ng-blur=onBlur
-            ignite-on-enter=onEnter
-            ignite-on-escape=onEscape
-        )
+                ignite-on-enter=onEnter
+                ignite-on-escape=onEscape
+            )
 
 //- Mixin for table save button.
    "||" used instead of "&&" to workaround escaping of "&&" to "&amp;&amp;"
@@ -424,7 +438,7 @@ mixin evictionPolicy(model, name, enabled, required, tip)
         a.customize(ng-hide='__.expanded' ng-click='__.expanded = true') Show settings
         .panel-details(ng-if='__.expanded')
             .details-row
-                +number('Batch size', policy + '.batchSize', name + '+ "batchSize"', enabled, '1', '0',
+                +number('Batch size', policy + '.batchSize', name + '+ "batchSize"', enabled, '1', '1',
                     'Number of entries to remove on shrink')
             .details-row
                 +number('Max memory size', policy + '.maxMemorySize', name + '+ "maxMemorySize"', enabled, '0', '0',
@@ -443,18 +457,35 @@ mixin caches(model, tip)
     +dropdown-multiple('<span>Caches:</span>' + '<a ui-sref="base.configuration.caches({linkId: linkId()})"> (add)</a>',
         model + '.caches', '"caches"', true, 'Choose caches', 'No caches configured', 'caches', tip)
 
+//- Mixin for XML, Java, .Net preview.
+mixin preview(master, generator, detail)
+    ignite-ui-ace-tabs
+        .preview-panel(ng-init='mode = "spring"')
+            .preview-legend
+                a(ng-class='{active: mode === "spring"}' ng-click='mode = "spring"') Spring
+                a(ng-class='{active: mode === "java"}' ng-click='mode = "java"') Java
+                a(ng-class='{active: mode === "csharp"}' ng-click='mode = "csharp"') C#
+                //a(ng-class='{active: mode === "app.config"}' ng-click='mode = "app.config"') app.config
+            .preview-content(ng-switch='mode')
+                ignite-ui-ace-spring(ng-switch-when="spring" data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
+                ignite-ui-ace-java(ng-switch-when="java" data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
+                ignite-ui-ace-sharp(ng-switch-when="csharp" data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
+            .preview-content-empty(ng-if='!data')
+                label All Defaults
+
 //- Mixin for XML and Java preview.
 mixin preview-xml-java(master, generator, detail)
     ignite-ui-ace-tabs
-        .preview-panel
+        .preview-panel(ng-init='mode = "spring"')
             .preview-legend
-                a(ng-class='{active: !mode, inactive: mode}' ng-click='mode = false') XML
-                | &nbsp;
-                a(ng-class='{active: mode, inactive: !mode}' ng-click='mode = true') Java
-            .preview-content(ng-if='mode')
-                ignite-ui-ace-java(data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
-            .preview-content(ng-if='!mode')
-                ignite-ui-ace-xml(data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
+                a(ng-class='{active: mode === "spring"}' ng-click='mode = "spring"') Spring
+                a(ng-class='{active: mode === "java"}' ng-click='mode = "java"') Java
+                //a(ng-class='{active: mode === "csharp"}' ng-click='mode = "csharp"') C#
+                //a(ng-class='{active: mode === "app.config"}' ng-click='mode = "app.config"') app.config
+            .preview-content(ng-switch='mode')
+                ignite-ui-ace-spring(ng-switch-when="spring" data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
+                ignite-ui-ace-java(ng-switch-when="java" data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
+                //ignite-ui-ace-sharp(ng-switch-when="csharp" data-master=master data-generator=generator ng-model='$parent.data' data-detail=detail)
             .preview-content-empty(ng-if='!data')
                 label All Defaults
 
@@ -503,7 +534,7 @@ mixin table-pair-edit(tbl, prefix, keyPlaceholder, valPlaceholder, keyJavaBuiltI
 
 //- Mixin for DB dialect.
 mixin dialect(lbl, model, name, required, tipTitle, genericDialectName, placeholder)
-    +dropdown(lbl, model, name, required, placeholder, '[\
+    +dropdown-required(lbl, model, name, 'true', required, placeholder, '[\
                 {value: "Generic", label: "' + genericDialectName + '"},\
                 {value: "Oracle", label: "Oracle"},\
                 {value: "DB2", label: "IBM DB2"},\

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/modules/agent/agent.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/agent/agent.module.js b/modules/web-console/frontend/app/modules/agent/agent.module.js
index 22ced13..d6fc863 100644
--- a/modules/web-console/frontend/app/modules/agent/agent.module.js
+++ b/modules/web-console/frontend/app/modules/agent/agent.module.js
@@ -277,12 +277,13 @@ class IgniteAgentMonitor {
      * @param {String} nid Node id.
      * @param {String} cacheName Cache name.
      * @param {String} [query] Query if null then scan query.
+     * @param {Boolean} nonCollocatedJoins Flag whether to execute non collocated joins.
      * @param {Boolean} local Flag whether to execute query locally.
      * @param {int} pageSize
      * @returns {Promise}
      */
-    query(nid, cacheName, query, local, pageSize) {
-        return this._rest('node:query', nid, maskNull(cacheName), maskNull(query), local, pageSize)
+    query(nid, cacheName, query, nonCollocatedJoins, local, pageSize) {
+        return this._rest('node:query', nid, maskNull(cacheName), maskNull(query), nonCollocatedJoins, local, pageSize)
             .then(({result}) => {
                 if (_.isEmpty(result.key))
                     return result.value;
@@ -295,11 +296,12 @@ class IgniteAgentMonitor {
      * @param {String} nid Node id.
      * @param {String} cacheName Cache name.
      * @param {String} [query] Query if null then scan query.
+     * @param {Boolean} nonCollocatedJoins Flag whether to execute non collocated joins.
      * @param {Boolean} local Flag whether to execute query locally.
      * @returns {Promise}
      */
-    queryGetAll(nid, cacheName, query, local) {
-        return this._rest('node:query:getAll', nid, maskNull(cacheName), maskNull(query), local);
+    queryGetAll(nid, cacheName, query, nonCollocatedJoins, local) {
+        return this._rest('node:query:getAll', nid, maskNull(cacheName), maskNull(query), nonCollocatedJoins, local);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/modules/configuration/Version.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/Version.service.js b/modules/web-console/frontend/app/modules/configuration/Version.service.js
index c36a98b..06efdda 100644
--- a/modules/web-console/frontend/app/modules/configuration/Version.service.js
+++ b/modules/web-console/frontend/app/modules/configuration/Version.service.js
@@ -16,10 +16,80 @@
  */
 
 /**
- * Utility service for version.
+ * Utility service for version parsing and comparing
  */
-export default () => {
-    return {
-        ignite: '1.7.0'
-    };
-};
+const VERSION_MATCHER = /(\d+)\.(\d+)\.(\d+)([-.]([^0123456789][^-]+)(-SNAPSHOT)?)?(-(\d+))?(-([\da-f]+))?/i;
+
+const numberComparator = (a, b) => a > b ? 1 : a < b ? -1 : 0;
+
+export default class Version {
+    /**
+     * Tries to parse product version from it's string representation.
+     *
+     * @param {String} ver - String representation of version.
+     * @returns {{major: Number, minor: Number, maintenance: Number, stage: String, revTs: Number, revHash: String}} - Object that contains product version fields.
+     */
+    parse(ver) {
+        // Development or built from source ZIP.
+        ver = ver.replace(/(-DEV|-n\/a)$/i, '');
+
+        const [, major, minor, maintenance, stage, ...chunks] = ver.match(VERSION_MATCHER);
+
+        return {
+            major: parseInt(major, 10),
+            minor: parseInt(minor, 10),
+            maintenance: parseInt(maintenance, 10),
+            stage: (stage || '').substring(1),
+            revTs: chunks[2] ? parseInt(chunks[3], 10) : 0,
+            revHash: chunks[4] ? chunks[5] : null
+        };
+    }
+
+    /**
+     * Compare to version.
+     * @param a {String} first compared version.
+     * @param b {String} second compared version.
+     * @returns {Number} 1 if a > b, 0 if versions equals, -1 if a < b
+     */
+    compare(a, b) {
+        const pa = this.parse(a);
+        const pb = this.parse(b);
+
+        let res = numberComparator(pa.major, pb.major);
+
+        if (res !== 0)
+            return res;
+
+        res = numberComparator(pa.minor, pb.minor);
+
+        if (res !== 0)
+            return res;
+
+        res = numberComparator(pa.maintenance, pb.maintenance);
+
+        if (res !== 0)
+            return res;
+
+        return numberComparator(pa.revTs, pb.maintenance);
+    }
+
+    /**
+     * Return current product version.
+     * @returns {{ignite: string}}
+     */
+    productVersion() {
+        return {
+            ignite: '1.7.0'
+        };
+    }
+
+    /**
+     * Check if node version is newer or same
+     * @param {String} nodeVer
+     * @param {String} sinceVer
+     * @returns {Boolean}
+     */
+    since(nodeVer, sinceVer) {
+        return this.compare(nodeVer, sinceVer) >= 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/modules/configuration/configuration.module.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/configuration.module.js b/modules/web-console/frontend/app/modules/configuration/configuration.module.js
index dc6fa2f..27f7bef 100644
--- a/modules/web-console/frontend/app/modules/configuration/configuration.module.js
+++ b/modules/web-console/frontend/app/modules/configuration/configuration.module.js
@@ -21,10 +21,22 @@ import igniteEventGroups from './EventGroups.provider';
 import igniteSidebar from './Sidebar.provider';
 import Version from './Version.service';
 
-import GeneratorXml from './generator/Xml.service';
-import GeneratorJava from './generator/Java.service';
+import clusterDefaults from './generator/defaults/cluster.provider';
+import clusterPlatformDefaults from './generator/defaults/cluster.platform.provider';
+import cacheDefaults from './generator/defaults/cache.provider';
+import cachePlatformDefaults from './generator/defaults/cache.platform.provider';
+import igfsDefaults from './generator/defaults/igfs.provider';
+
+import ConfigurationGenerator from './generator/ConfigurationGenerator';
+import PlatformGenerator from './generator/PlatformGenerator';
+
+import SpringTransformer from './generator/SpringTransformer.service';
+import JavaTransformer from './generator/JavaTransformer.service';
+import SharpTransformer from './generator/SharpTransformer.service';
 import GeneratorDocker from './generator/Docker.service';
 import GeneratorPom from './generator/Pom.service';
+import GeneratorProperties from './generator/Properties.service';
+import GeneratorReadme from './generator/Readme.service';
 
 import igniteSidebarDirective from './sidebar.directive';
 
@@ -33,11 +45,21 @@ angular
 .module('ignite-console.configuration', [
 
 ])
+.provider('igniteClusterDefaults', clusterDefaults)
+.provider('igniteClusterPlatformDefaults', clusterPlatformDefaults)
+.provider('igniteCacheDefaults', cacheDefaults)
+.provider('igniteCachePlatformDefaults', cachePlatformDefaults)
+.provider('igniteIgfsDefaults', igfsDefaults)
 .provider(...igniteEventGroups)
 .provider(...igniteSidebar)
 .directive(...igniteSidebarDirective)
 .service('IgniteVersion', Version)
-.service(...GeneratorXml)
-.service(...GeneratorJava)
+.service('IgniteConfigurationGenerator', ConfigurationGenerator)
+.service('IgnitePlatformGenerator', PlatformGenerator)
+.service('SpringTransformer', SpringTransformer)
+.service('JavaTransformer', JavaTransformer)
+.service('IgniteSharpTransformer', SharpTransformer)
+.service('IgnitePropertiesGenerator', GeneratorProperties)
+.service('IgniteReadmeGenerator', GeneratorReadme)
 .service(...GeneratorDocker)
 .service(...GeneratorPom);

http://git-wip-us.apache.org/repos/asf/ignite/blob/087f6405/modules/web-console/frontend/app/modules/configuration/generator/AbstractTransformer.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/AbstractTransformer.js b/modules/web-console/frontend/app/modules/configuration/generator/AbstractTransformer.js
new file mode 100644
index 0000000..6244a53
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/configuration/generator/AbstractTransformer.js
@@ -0,0 +1,341 @@
+/*
+ * 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 StringBuilder from './StringBuilder';
+
+export default class AbstractTransformer {
+    // Append comment with time stamp.
+    static mainComment(sb, ...lines) {
+        lines.push(sb.generatedBy());
+
+        return this.commentBlock(sb, ...lines);
+    }
+
+    // Append line before and after property.
+    static _emptyLineIfNeeded(sb, props, curIdx) {
+        if (curIdx === props.length - 1)
+            return;
+
+        const cur = props[curIdx];
+
+        // Empty line after.
+        if (_.includes(['MAP', 'COLLECTION', 'ARRAY'], cur.clsName) || (cur.clsName === 'BEAN' && cur.value.isComplex()))
+            return sb.emptyLine();
+
+        const next = props[curIdx + 1];
+
+        // Empty line before.
+        if (_.includes(['MAP', 'COLLECTION', 'ARRAY'], next.clsName) || (next.clsName === 'BEAN' && next.value.isComplex()))
+            return sb.emptyLine();
+    }
+
+    // Generate general section.
+    static clusterGeneral(cluster) {
+        return this.toSection(this.generator.clusterGeneral(cluster));
+    }
+
+    // Generate atomics group.
+    static clusterAtomics(atomics) {
+        return this.toSection(this.generator.clusterAtomics(atomics));
+    }
+
+    // Generate binary group.
+    static clusterBinary(binary) {
+        return this.toSection(this.generator.clusterBinary(binary));
+    }
+
+    // Generate cache key configurations.
+    static clusterCacheKeyConfiguration(keyCfgs) {
+        return this.toSection(this.generator.clusterCacheKeyConfiguration(keyCfgs));
+    }
+
+    // Generate collision group.
+    static clusterCollision(collision) {
+        return this.toSection(this.generator.clusterCollision(collision));
+    }
+
+    // Generate communication group.
+    static clusterCommunication(cluster) {
+        return this.toSection(this.generator.clusterCommunication(cluster));
+    }
+
+    // Generate REST access configuration.
+    static clusterConnector(connector) {
+        return this.toSection(this.generator.clusterConnector(connector));
+    }
+
+    // Generate deployment group.
+    static clusterDeployment(cluster) {
+        return this.toSection(this.generator.clusterDeployment(cluster));
+    }
+
+    // Generate discovery group.
+    static clusterDiscovery(disco) {
+        return this.toSection(this.generator.clusterDiscovery(disco));
+    }
+
+    // Generate events group.
+    static clusterEvents(cluster) {
+        return this.toSection(this.generator.clusterEvents(cluster));
+    }
+
+    // Generate failover group.
+    static clusterFailover(cluster) {
+        return this.toSection(this.generator.clusterFailover(cluster));
+    }
+
+    // Generate cluster IGFSs group.
+    static clusterIgfss(igfss) {
+        return this.toSection(this.generator.clusterIgfss(igfss));
+    }
+
+    // Generate load balancing SPI group.
+    static clusterLoadBalancing(cluster) {
+        return this.toSection(this.generator.clusterLoadBalancing(cluster));
+    }
+
+    // Generate logger group.
+    static clusterLogger(cluster) {
+        return this.toSection(this.generator.clusterLogger(cluster));
+    }
+
+    // Generate marshaller group.
+    static clusterMarshaller(cluster) {
+        return this.toSection(this.generator.clusterMarshaller(cluster));
+    }
+
+    // Generate metrics group.
+    static clusterMetrics(cluster) {
+        return this.toSection(this.generator.clusterMetrics(cluster));
+    }
+
+    // Generate ODBC group.
+    static clusterODBC(odbc) {
+        return this.toSection(this.generator.clusterODBC(odbc));
+    }
+
+    // Generate ssl group.
+    static clusterSsl(cluster) {
+        return this.toSection(this.generator.clusterSsl(cluster));
+    }
+
+    // Generate swap group.
+    static clusterSwap(cluster) {
+        return this.toSection(this.generator.clusterSwap(cluster));
+    }
+
+    // Generate time group.
+    static clusterTime(cluster) {
+        return this.toSection(this.generator.clusterTime(cluster));
+    }
+
+    // Generate thread pools group.
+    static clusterPools(cluster) {
+        return this.toSection(this.generator.clusterPools(cluster));
+    }
+
+    // Generate transactions group.
+    static clusterTransactions(transactionConfiguration) {
+        return this.toSection(this.generator.clusterTransactions(transactionConfiguration));
+    }
+
+    // Generate user attributes group.
+    static clusterUserAttributes(cluster) {
+        return this.toSection(this.generator.clusterUserAttributes(cluster));
+    }
+
+    // Generate IGFS general group.
+    static igfsGeneral(igfs) {
+        return this.toSection(this.generator.igfsGeneral(igfs));
+    }
+
+    // Generate IGFS secondary file system group.
+    static igfsSecondFS(igfs) {
+        return this.toSection(this.generator.igfsSecondFS(igfs));
+    }
+
+    // Generate IGFS IPC group.
+    static igfsIPC(igfs) {
+        return this.toSection(this.generator.igfsIPC(igfs));
+    }
+
+    // Generate IGFS fragmentizer group.
+    static igfsFragmentizer(igfs) {
+        return this.toSection(this.generator.igfsFragmentizer(igfs));
+    }
+
+    // Generate IGFS Dual mode group.
+    static igfsDualMode(igfs) {
+        return this.toSection(this.generator.igfsDualMode(igfs));
+    }
+
+    // Generate IGFS miscellaneous group.
+    static igfsMisc(igfs) {
+        return this.toSection(this.generator.igfsMisc(igfs));
+    }
+
+    // Generate cache general group.
+    static cacheGeneral(cache) {
+        return this.toSection(this.generator.cacheGeneral(cache));
+    }
+
+    // Generate cache memory group.
+    static cacheMemory(cache) {
+        return this.toSection(this.generator.cacheMemory(cache));
+    }
+
+    // Generate cache queries & Indexing group.
+    static cacheQuery(cache, domains) {
+        return this.toSection(this.generator.cacheQuery(cache, domains));
+    }
+
+    // Generate cache store group.
+    static cacheStore(cache, domains) {
+        return this.toSection(this.generator.cacheStore(cache, domains));
+    }
+
+    // Generate cache concurrency control group.
+    static cacheConcurrency(cache) {
+        return this.toSection(this.generator.cacheConcurrency(cache));
+    }
+
+    // Generate cache node filter group.
+    static cacheNodeFilter(cache, igfss) {
+        return this.toSection(this.generator.cacheNodeFilter(cache, igfss));
+    }
+
+    // Generate cache rebalance group.
+    static cacheRebalance(cache) {
+        return this.toSection(this.generator.cacheRebalance(cache));
+    }
+
+    // Generate server near cache group.
+    static cacheNearServer(cache) {
+        return this.toSection(this.generator.cacheNearServer(cache));
+    }
+
+    // Generate client near cache group.
+    static cacheNearClient(cache) {
+        return this.toSection(this.generator.cacheNearClient(cache));
+    }
+
+    // Generate cache statistics group.
+    static cacheStatistics(cache) {
+        return this.toSection(this.generator.cacheStatistics(cache));
+    }
+
+    // Generate caches configs.
+    static clusterCaches(cluster, caches, igfss, client) {
+        return this.toSection(this.generator.clusterCaches(cluster, caches, igfss, client));
+    }
+
+    // Generate caches configs.
+    static clusterCheckpoint(cluster, caches) {
+        return this.toSection(this.generator.clusterCheckpoint(cluster, caches));
+    }
+
+    // Generate domain model for general group.
+    static domainModelGeneral(domain) {
+        return this.toSection(this.generator.domainModelGeneral(domain));
+    }
+
+    // Generate domain model for query group.
+    static domainModelQuery(domain) {
+        return this.toSection(this.generator.domainModelQuery(domain));
+    }
+
+    // Generate domain model for store group.
+    static domainStore(domain) {
+        return this.toSection(this.generator.domainStore(domain));
+    }
+
+    /**
+     * Check if configuration contains properties.
+     *
+     * @param {Bean} bean
+     * @returns {Boolean}
+     */
+    static hasProperties(bean) {
+        const searchProps = (prop) => {
+            switch (prop.clsName) {
+                case 'BEAN':
+                    if (this.hasProperties(prop.value))
+                        return true;
+
+                    break;
+                case 'ARRAY':
+                case 'COLLECTION':
+                    if (_.find(prop.items, (item) => this.hasProperties(item)))
+                        return true;
+
+                    break;
+                case 'DATA_SOURCE':
+                case 'PROPERTY':
+                case 'PROPERTY_CHAR':
+                    return true;
+                default:
+            }
+
+            return false;
+        };
+
+        return _.isObject(bean) && (!!_.find(bean.arguments, searchProps) || !!_.find(bean.properties, searchProps));
+    }
+
+    /**
+     * Collect datasource beans.
+     *
+     * @param {Bean} bean
+     */
+    static collectDataSources(bean) {
+        const dataSources = _.reduce(bean.properties, (acc, prop) => {
+            switch (prop.clsName.toUpperCase()) {
+                case 'ARRAY':
+                    if (this._isBean(prop.typeClsName))
+                        _.forEach(prop.items, (item) => acc.push(...this.collectDataSources(item)));
+
+                    break;
+                case 'BEAN':
+                    acc.push(...this.collectDataSources(prop.value));
+
+                    break;
+                case 'DATA_SOURCE':
+                    acc.push(prop.value);
+
+                    break;
+                default:
+            }
+
+            return acc;
+        }, []);
+
+        return _.uniqBy(dataSources, (ds) => ds.id);
+    }
+
+    /**
+     * Transform to section.
+     *
+     * @param cfg
+     * @param sb
+     * @return {StringBuilder}
+     */
+    static toSection(cfg, sb = new StringBuilder()) {
+        this._setProperties(sb, cfg);
+
+        return sb;
+    }
+}