http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/PojoCacheStoreMultitreadedSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/PojoCacheStoreMultitreadedSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/PojoCacheStoreMultitreadedSelfTest.java
new file mode 100644
index 0000000..f2688d3
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/PojoCacheStoreMultitreadedSelfTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.store.jdbc;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.*;
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+import org.gridgain.grid.cache.query.*;
+import org.gridgain.grid.util.typedef.*;
+import org.h2.jdbcx.*;
+import org.springframework.beans.*;
+import org.springframework.beans.factory.xml.*;
+import org.springframework.context.support.*;
+import org.springframework.core.io.*;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import static org.gridgain.grid.cache.GridCacheAtomicityMode.*;
+import static org.gridgain.grid.cache.GridCacheMode.*;
+
+/**
+ *
+ */
+public class PojoCacheStoreMultitreadedSelfTest extends 
AbstractCacheStoreMultithreadedSelfTest<JdbcPojoCacheStore> {
+    /** {@inheritDoc} */
+    @Override protected JdbcPojoCacheStore store() throws Exception {
+        JdbcPojoCacheStore store = new JdbcPojoCacheStore();
+
+        store.setDataSource(JdbcConnectionPool.create(DFLT_CONN_URL, "sa", 
""));
+
+        UrlResource metaUrl;
+
+        try {
+            metaUrl = new UrlResource(new 
File("modules/core/src/test/config/store/auto/all.xml").toURI().toURL());
+        }
+        catch (MalformedURLException e) {
+            throw new IgniteCheckedException("Failed to resolve metadata path 
[err=" + e.getMessage() + ']', e);
+        }
+
+        try {
+            GenericApplicationContext springCtx = new 
GenericApplicationContext();
+
+            new 
XmlBeanDefinitionReader(springCtx).loadBeanDefinitions(metaUrl);
+
+            springCtx.refresh();
+
+            Collection<GridCacheQueryTypeMetadata> typeMetadata =
+                
springCtx.getBeansOfType(GridCacheQueryTypeMetadata.class).values();
+
+            store.setTypeMetadata(typeMetadata);
+        }
+        catch (BeansException e) {
+            if (X.hasCause(e, ClassNotFoundException.class))
+                throw new IgniteCheckedException("Failed to instantiate Spring 
XML application context " +
+                    "(make sure all classes used in Spring configuration are 
present at CLASSPATH) " +
+                    "[springUrl=" + metaUrl + ']', e);
+            else
+                throw new IgniteCheckedException("Failed to instantiate Spring 
XML application context [springUrl=" +
+                    metaUrl + ", err=" + e.getMessage() + ']', e);
+        }
+
+        return store;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) 
throws Exception {
+        IgniteConfiguration c = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi disco = new TcpDiscoverySpi();
+
+        disco.setIpFinder(IP_FINDER);
+
+        c.setDiscoverySpi(disco);
+
+        CacheConfiguration cc = defaultCacheConfiguration();
+
+        cc.setCacheMode(PARTITIONED);
+        cc.setAtomicityMode(ATOMIC);
+        cc.setSwapEnabled(false);
+        cc.setWriteBehindEnabled(false);
+
+        // TODO: IGNITE-32 FIXME cc.setStore(store);
+
+        c.setCacheConfiguration(cc);
+
+        return c;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/PojoCacheStoreSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/PojoCacheStoreSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/PojoCacheStoreSelfTest.java
new file mode 100644
index 0000000..fa77385
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/PojoCacheStoreSelfTest.java
@@ -0,0 +1,551 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.store.jdbc;
+
+import org.apache.ignite.*;
+import org.apache.ignite.cache.store.jdbc.model.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.transactions.*;
+import org.gridgain.grid.cache.query.*;
+import org.gridgain.grid.util.typedef.*;
+import org.gridgain.grid.util.typedef.internal.*;
+import 
org.gridgain.testframework.junits.cache.GridAbstractCacheStoreSelfTest.*;
+import org.gridgain.testframework.junits.common.*;
+import org.h2.jdbcx.*;
+import org.jetbrains.annotations.*;
+import org.springframework.beans.*;
+import org.springframework.beans.factory.xml.*;
+import org.springframework.context.support.*;
+import org.springframework.core.io.*;
+
+import java.io.*;
+import java.net.*;
+import java.sql.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * Class for {@code PojoCacheStore} tests.
+ */
+public class PojoCacheStoreSelfTest extends GridCommonAbstractTest {
+    /** Default connection URL (value is 
<tt>jdbc:h2:mem:jdbcCacheStore;DB_CLOSE_DELAY=-1</tt>). */
+    protected static final String DFLT_CONN_URL = 
"jdbc:h2:mem:autoCacheStore;DB_CLOSE_DELAY=-1";
+
+    /** Organization count. */
+    protected static final int ORGANIZATION_CNT = 1000;
+
+    /** Person count. */
+    protected static final int PERSON_CNT = 100000;
+
+    /** */
+    protected final JdbcPojoCacheStore store;
+
+    /**
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings({"AbstractMethodCallInConstructor", 
"OverriddenMethodCallDuringObjectConstruction"})
+    public PojoCacheStoreSelfTest() throws Exception {
+        super(false);
+
+        store = store();
+
+        inject(store);
+    }
+
+    /**
+     * @return Store.
+     */
+    protected JdbcPojoCacheStore store() throws IgniteCheckedException {
+        JdbcPojoCacheStore store = new JdbcPojoCacheStore();
+
+        store.setDataSource(JdbcConnectionPool.create(DFLT_CONN_URL, "sa", 
""));
+
+        UrlResource metaUrl;
+
+        try {
+            metaUrl = new UrlResource(new 
File("modules/core/src/test/config/store/auto/all.xml").toURI().toURL());
+        }
+        catch (MalformedURLException e) {
+            throw new IgniteCheckedException("Failed to resolve metadata path 
[err=" + e.getMessage() + ']', e);
+        }
+
+        try {
+            GenericApplicationContext springCtx = new 
GenericApplicationContext();
+
+            new 
XmlBeanDefinitionReader(springCtx).loadBeanDefinitions(metaUrl);
+
+            springCtx.refresh();
+
+            Collection<GridCacheQueryTypeMetadata> typeMetadata =
+                
springCtx.getBeansOfType(GridCacheQueryTypeMetadata.class).values();
+
+            store.setTypeMetadata(typeMetadata);
+        }
+        catch (BeansException e) {
+            if (X.hasCause(e, ClassNotFoundException.class))
+                throw new IgniteCheckedException("Failed to instantiate Spring 
XML application context " +
+                    "(make sure all classes used in Spring configuration are 
present at CLASSPATH) " +
+                    "[springUrl=" + metaUrl + ']', e);
+            else
+                throw new IgniteCheckedException("Failed to instantiate Spring 
XML application context [springUrl=" +
+                    metaUrl + ", err=" + e.getMessage() + ']', e);
+        }
+
+        return store;
+    }
+
+    /**
+     * @param store Store.
+     * @throws Exception If failed.
+     */
+    protected void inject(JdbcCacheStore store) throws Exception {
+        getTestResources().inject(store);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testLoadCache() throws Exception {
+        Connection conn = DriverManager.getConnection(DFLT_CONN_URL, "sa", "");
+
+        Statement stmt = conn.createStatement();
+
+        PreparedStatement orgStmt = conn.prepareStatement("INSERT INTO 
Organization(id, name, city) VALUES (?, ?, ?)");
+
+        for (int i = 0; i < ORGANIZATION_CNT; i++) {
+            orgStmt.setInt(1, i);
+            orgStmt.setString(2, "name" + i);
+            orgStmt.setString(3, "city" + i % 10);
+
+            orgStmt.addBatch();
+        }
+
+        orgStmt.executeBatch();
+
+        conn.commit();
+
+        PreparedStatement prnStmt = conn.prepareStatement("INSERT INTO 
Person(id, org_id, name) VALUES (?, ?, ?)");
+
+        for (int i = 0; i < PERSON_CNT; i++) {
+            prnStmt.setInt(1, i);
+            prnStmt.setInt(2, i % 100);
+            prnStmt.setString(3, "name" + i);
+
+            prnStmt.addBatch();
+        }
+
+        prnStmt.executeBatch();
+
+        conn.commit();
+
+        U.closeQuiet(stmt);
+
+        U.closeQuiet(conn);
+
+        final Collection<OrganizationKey> orgKeys = new 
ArrayList<>(ORGANIZATION_CNT);
+        final Collection<PersonKey> prnKeys = new ArrayList<>(PERSON_CNT);
+
+        IgniteBiInClosure<Object, Object> c = new CI2<Object, Object>() {
+            @Override public void apply(Object k, Object v) {
+                if (k instanceof OrganizationKey && v instanceof Organization)
+                    orgKeys.add((OrganizationKey)k);
+                else if (k instanceof PersonKey && v instanceof Person)
+                    prnKeys.add((PersonKey)k);
+            }
+        };
+
+        store.loadCache(c);
+
+        assertEquals(ORGANIZATION_CNT, orgKeys.size());
+        assertEquals(PERSON_CNT, prnKeys.size());
+
+        store.removeAll(null, orgKeys);
+        store.removeAll(null, prnKeys);
+
+        orgKeys.clear();
+        prnKeys.clear();
+
+        store.loadCache(c);
+
+        assertTrue(orgKeys.isEmpty());
+        assertTrue(prnKeys.isEmpty());
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testStore() throws Exception {
+        // Create dummy transaction
+        IgniteTx tx = new DummyTx();
+
+        OrganizationKey k1 = new OrganizationKey(1);
+        Organization v1 = new Organization(1, "Name1", "City1");
+
+        OrganizationKey k2 = new OrganizationKey(2);
+        Organization v2 = new Organization(2, "Name2", "City2");
+
+        store.put(tx, k1, v1);
+        store.put(tx, k2, v2);
+
+        store.txEnd(tx, true);
+
+        assertEquals(v1, store.load(null, k1));
+        assertEquals(v2, store.load(null, k2));
+
+        OrganizationKey k3 = new OrganizationKey(3);
+
+        assertNull(store.load(tx, k3));
+
+        store.remove(tx, k1);
+
+        store.txEnd(tx, true);
+
+        assertNull(store.load(tx, k1));
+        assertEquals(v2, store.load(tx, k2));
+        assertNull(store.load(null, k3));
+    }
+
+    /**
+     * @throws IgniteCheckedException if failed.
+     */
+    public void testRollback() throws IgniteCheckedException {
+        IgniteTx tx = new DummyTx();
+
+        OrganizationKey k1 = new OrganizationKey(1);
+        Organization v1 = new Organization(1, "Name1", "City1");
+
+        // Put.
+        store.put(tx, k1, v1);
+
+        store.txEnd(tx, false); // Rollback.
+
+        tx = new DummyTx();
+
+        assertNull(store.load(tx, k1));
+
+        OrganizationKey k2 = new OrganizationKey(2);
+        Organization v2 = new Organization(2, "Name2", "City2");
+
+        // Put all.
+        assertNull(store.load(tx, k2));
+
+        store.putAll(tx, Collections.singletonMap(k2, v2));
+
+        store.txEnd(tx, false); // Rollback.
+
+        tx = new DummyTx();
+
+        assertNull(store.load(tx, k2));
+
+        OrganizationKey k3 = new OrganizationKey(3);
+        Organization v3 = new Organization(3, "Name3", "City3");
+
+        store.putAll(tx, Collections.singletonMap(k3, v3));
+
+        store.txEnd(tx, true); // Commit.
+
+        tx = new DummyTx();
+
+        assertEquals(v3, store.load(tx, k3));
+
+        OrganizationKey k4 = new OrganizationKey(4);
+        Organization v4 = new Organization(4, "Name4", "City4");
+
+        store.put(tx, k4, v4);
+
+        store.txEnd(tx, false); // Rollback.
+
+        tx = new DummyTx();
+
+        assertNull(store.load(tx, k4));
+
+        assertEquals(v3, store.load(tx, k3));
+
+        // Remove.
+        store.remove(tx, k3);
+
+        store.txEnd(tx, false); // Rollback.
+
+        tx = new DummyTx();
+
+        assertEquals(v3, store.load(tx, k3));
+
+        // Remove all.
+        store.removeAll(tx, Arrays.asList(k3));
+
+        store.txEnd(tx, false); // Rollback.
+
+        tx = new DummyTx();
+
+        assertEquals(v3, store.load(tx, k3));
+    }
+
+    /**
+     * @throws IgniteCheckedException if failed.
+     */
+    public void testAllOpsWithTXNoCommit() throws IgniteCheckedException {
+        doTestAllOps(new DummyTx(), false);
+    }
+
+    /**
+     * @throws IgniteCheckedException if failed.
+     */
+    public void testAllOpsWithTXCommit() throws IgniteCheckedException {
+        doTestAllOps(new DummyTx(), true);
+    }
+
+    /**
+     * @throws IgniteCheckedException if failed.
+     */
+    public void testAllOpsWithoutTX() throws IgniteCheckedException {
+        doTestAllOps(null, false);
+    }
+
+    /**
+     * @param tx Transaction.
+     * @param commit Commit.
+     * @throws IgniteCheckedException If failed.
+     */
+    private void doTestAllOps(@Nullable IgniteTx tx, boolean commit) throws 
IgniteCheckedException {
+        try {
+            final OrganizationKey k1 = new OrganizationKey(1);
+            final Organization v1 = new Organization(1, "Name1", "City1");
+
+            store.put(tx, k1, v1);
+
+            if (tx != null && commit) {
+                store.txEnd(tx, true);
+
+                tx = new DummyTx();
+            }
+
+            if (tx == null || commit)
+                assertEquals(v1, store.load(tx, k1));
+
+            Map<OrganizationKey, Organization> m = new HashMap<>();
+
+            final OrganizationKey k2 = new OrganizationKey(2);
+            final Organization v2 = new Organization(2, "Name2", "City2");
+
+            final OrganizationKey k3 = new OrganizationKey(3);
+            final Organization v3 = new Organization(3, "Name3", "City3");
+
+            m.put(k2, v2);
+            m.put(k3, v3);
+
+            store.putAll(tx, m);
+
+            if (tx != null && commit) {
+                store.txEnd(tx, true);
+
+                tx = new DummyTx();
+            }
+
+            final AtomicInteger cntr = new AtomicInteger();
+
+            final OrganizationKey no_such_key = new OrganizationKey(4);
+
+            if (tx == null || commit) {
+                store.loadAll(tx, Arrays.asList(k1, k2, k3, no_such_key), new 
CI2<Object, Object>() {
+                    @Override public void apply(Object o, Object o1) {
+                        if (k1.equals(o))
+                            assertEquals(v1, o1);
+
+                        if (k2.equals(o))
+                            assertEquals(v2, o1);
+
+                        if (k3.equals(o))
+                            assertEquals(v3, o1);
+
+                        if (no_such_key.equals(o))
+                            fail();
+
+                        cntr.incrementAndGet();
+                    }
+                });
+
+                assertEquals(3, cntr.get());
+            }
+
+            store.removeAll(tx, Arrays.asList(k2, k3));
+
+            if (tx != null && commit) {
+                store.txEnd(tx, true);
+
+                tx = new DummyTx();
+            }
+
+            if (tx == null || commit) {
+                assertNull(store.load(tx, k2));
+                assertNull(store.load(tx, k3));
+                assertEquals(v1, store.load(tx, k1));
+            }
+
+            store.remove(tx, k1);
+
+            if (tx != null && commit) {
+                store.txEnd(tx, true);
+
+                tx = new DummyTx();
+            }
+
+            if (tx == null || commit)
+                assertNull(store.load(tx, k1));
+        }
+        finally {
+            if (tx != null)
+                store.txEnd(tx, false);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSimpleMultithreading() throws Exception {
+        final Random rnd = new Random();
+
+        final Queue<OrganizationKey> queue = new LinkedBlockingQueue<>();
+
+        multithreaded(new Callable<Object>() {
+            @Nullable @Override public Object call() throws Exception {
+                for (int i = 0; i < 1000; i++) {
+                    IgniteTx tx = rnd.nextBoolean() ? new DummyTx() : null;
+
+                    int op = rnd.nextInt(10);
+
+                    boolean queueEmpty = false;
+
+                    if (op < 4) { // Load.
+                        OrganizationKey key = queue.poll();
+
+                        if (key == null)
+                            queueEmpty = true;
+                        else {
+                            if (rnd.nextBoolean())
+                                assertNotNull(store.load(tx, key));
+                            else {
+                                final AtomicInteger cntr = new AtomicInteger();
+
+                                store.loadAll(tx, Collections.singleton(key), 
new CI2<Object, Object>() {
+                                    @Override public void apply(Object o, 
Object o1) {
+                                        cntr.incrementAndGet();
+
+                                        assertNotNull(o);
+                                        assertNotNull(o1);
+
+                                        OrganizationKey key = 
(OrganizationKey)o;
+                                        Organization val = (Organization)o1;
+
+                                        
assertTrue(key.getId().equals(val.getId()));
+                                    }
+                                });
+
+                                assertEquals(1, cntr.get());
+                            }
+
+                            if (tx != null)
+                                store.txEnd(tx, true);
+
+                            queue.add(key);
+                        }
+                    }
+                    else if (op < 6) { // Remove.
+                        OrganizationKey key = queue.poll();
+
+                        if (key == null)
+                            queueEmpty = true;
+                        else {
+                            if (rnd.nextBoolean())
+                                store.remove(tx, key);
+                            else
+                                store.removeAll(tx, 
Collections.singleton(key));
+
+                            if (tx != null)
+                                store.txEnd(tx, true);
+                        }
+                    }
+                    else { // Update.
+                        OrganizationKey key = queue.poll();
+
+                        if (key == null)
+                            queueEmpty = true;
+                        else {
+                            Organization val =
+                                new Organization(key.getId(), "Name" + 
key.getId(), "City" + key.getId());
+
+                            if (rnd.nextBoolean())
+                                store.put(tx, key, val);
+                            else
+                                store.putAll(tx, Collections.singletonMap(key, 
val));
+
+                            if (tx != null)
+                                store.txEnd(tx, true);
+
+                            queue.add(key);
+                        }
+                    }
+
+                    if (queueEmpty) { // Add.
+                        OrganizationKey key = new 
OrganizationKey(rnd.nextInt());
+                        Organization val = new Organization(key.getId(), 
"Name" + key.getId(), "City" + key.getId());
+
+                        if (rnd.nextBoolean())
+                            store.put(tx, key, val);
+                        else
+                            store.putAll(tx, Collections.singletonMap(key, 
val));
+
+                        if (tx != null)
+                            store.txEnd(tx, true);
+
+                        queue.add(key);
+                    }
+                }
+
+                return null;
+            }
+        }, 37);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        Class.forName("org.h2.Driver");
+        Connection conn = DriverManager.getConnection(DFLT_CONN_URL, "sa", "");
+
+        Statement stmt = conn.createStatement();
+
+        stmt.executeUpdate("DROP TABLE IF EXISTS Organization");
+        stmt.executeUpdate("DROP TABLE IF EXISTS Person");
+
+        stmt.executeUpdate("CREATE TABLE Organization (id integer PRIMARY KEY, 
name varchar(50), city varchar(50))");
+        stmt.executeUpdate("CREATE TABLE Person (id integer PRIMARY KEY, 
org_id integer, name varchar(50))");
+
+        stmt.executeUpdate("CREATE INDEX Org_Name_IDX On Organization (name)");
+        stmt.executeUpdate("CREATE INDEX Org_Name_City_IDX On Organization 
(name, city)");
+        stmt.executeUpdate("CREATE INDEX Person_Name_IDX1 On Person (name)");
+        stmt.executeUpdate("CREATE INDEX Person_Name_IDX2 On Person (name 
desc)");
+
+        conn.commit();
+
+        U.closeQuiet(stmt);
+
+        U.closeQuiet(conn);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Organization.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Organization.java
 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Organization.java
new file mode 100644
index 0000000..92a58d3
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Organization.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.store.jdbc.model;
+
+import java.io.*;
+
+/**
+ * Organization definition.
+ *
+ * Code generated by Apache Ignite Schema Load utility.
+ */
+public class Organization implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Value for id. */
+    private Integer id;
+
+    /** Value for name. */
+    private String name;
+
+    /** Value for city. */
+    private String city;
+
+    /**
+     * Empty constructor.
+     */
+    public Organization() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     */
+    public Organization(
+        Integer id,
+        String name,
+        String city
+    ) {
+        this.id = id;
+        this.name = name;
+        this.city = city;
+    }
+
+    /**
+     * Gets id.
+     *
+     * @return Value for id.
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * Sets id.
+     *
+     * @param id New value for id.
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets name.
+     *
+     * @return Value for name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets name.
+     *
+     * @param name New value for name.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Gets city.
+     *
+     * @return Value for city.
+     */
+    public String getCity() {
+        return city;
+    }
+
+    /**
+     * Sets city.
+     *
+     * @param city New value for city.
+     */
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (!(o instanceof Organization))
+            return false;
+
+        Organization that = (Organization)o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null)
+            return false;
+
+        if (name != null ? !name.equals(that.name) : that.name != null)
+            return false;
+
+        if (city != null ? !city.equals(that.city) : that.city != null)
+            return false;
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = id != null ? id.hashCode() : 0;
+
+        res = 31 * res + (name != null ? name.hashCode() : 0);
+        res = 31 * res + (city != null ? city.hashCode() : 0);
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "Organization [id=" + id +
+            ", name=" + name +
+            ", city=" + city +
+            "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/OrganizationKey.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/OrganizationKey.java
 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/OrganizationKey.java
new file mode 100644
index 0000000..7b48aed
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/OrganizationKey.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.store.jdbc.model;
+
+import java.io.*;
+
+/**
+ * OrganizationKey definition.
+ *
+ * Code generated by Apache Ignite Schema Load utility.
+ */
+public class OrganizationKey implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Value for id. */
+    private Integer id;
+
+    /**
+     * Empty constructor.
+     */
+    public OrganizationKey() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     */
+    public OrganizationKey(
+        Integer id
+    ) {
+        this.id = id;
+    }
+
+    /**
+     * Gets id.
+     *
+     * @return Value for id.
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * Sets id.
+     *
+     * @param id New value for id.
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (!(o instanceof OrganizationKey))
+            return false;
+
+        OrganizationKey that = (OrganizationKey)o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null)
+            return false;
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = id != null ? id.hashCode() : 0;
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "OrganizationKey [id=" + id +
+            "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Person.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Person.java
 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Person.java
new file mode 100644
index 0000000..6d8c1d2
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/Person.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.store.jdbc.model;
+
+import java.io.*;
+
+/**
+ * Person definition.
+ *
+ * Code generated by Apache Ignite Schema Load utility.
+ */
+public class Person implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Value for id. */
+    private Integer id;
+
+    /** Value for orgId. */
+    private Integer orgId;
+
+    /** Value for name. */
+    private String name;
+
+    /**
+     * Empty constructor.
+     */
+    public Person() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     */
+    public Person(
+        Integer id,
+        Integer orgId,
+        String name
+    ) {
+        this.id = id;
+        this.orgId = orgId;
+        this.name = name;
+    }
+
+    /**
+     * Gets id.
+     *
+     * @return Value for id.
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * Sets id.
+     *
+     * @param id New value for id.
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /**
+     * Gets orgId.
+     *
+     * @return Value for orgId.
+     */
+    public Integer getOrgId() {
+        return orgId;
+    }
+
+    /**
+     * Sets orgId.
+     *
+     * @param orgId New value for orgId.
+     */
+    public void setOrgId(Integer orgId) {
+        this.orgId = orgId;
+    }
+
+    /**
+     * Gets name.
+     *
+     * @return Value for name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets name.
+     *
+     * @param name New value for name.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (!(o instanceof Person))
+            return false;
+
+        Person that = (Person)o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null)
+            return false;
+
+        if (orgId != null ? !orgId.equals(that.orgId) : that.orgId != null)
+            return false;
+
+        if (name != null ? !name.equals(that.name) : that.name != null)
+            return false;
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = id != null ? id.hashCode() : 0;
+
+        res = 31 * res + (orgId != null ? orgId.hashCode() : 0);
+        res = 31 * res + (name != null ? name.hashCode() : 0);
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "Person [id=" + id +
+            ", orgId=" + orgId +
+            ", name=" + name +
+            "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/PersonKey.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/PersonKey.java
 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/PersonKey.java
new file mode 100644
index 0000000..068041b
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/PersonKey.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.cache.store.jdbc.model;
+
+import java.io.*;
+
+/**
+ * PersonKey definition.
+ *
+ * Code generated by Apache Ignite Schema Load utility.
+ */
+public class PersonKey implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Value for id. */
+    private Integer id;
+
+    /**
+     * Empty constructor.
+     */
+    public PersonKey() {
+        // No-op.
+    }
+
+    /**
+     * Full constructor.
+     */
+    public PersonKey(
+        Integer id
+    ) {
+        this.id = id;
+    }
+
+    /**
+     * Gets id.
+     *
+     * @return Value for id.
+     */
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * Sets id.
+     *
+     * @param id New value for id.
+     */
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (!(o instanceof PersonKey))
+            return false;
+
+        PersonKey that = (PersonKey)o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null)
+            return false;
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = id != null ? id.hashCode() : 0;
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return "PersonKey [id=" + id +
+            "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/package.html
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/package.html
 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/package.html
new file mode 100644
index 0000000..d10c624
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/cache/store/jdbc/model/package.html
@@ -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.
+  -->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd";>
+<html>
+<body>
+    <!-- Package description. -->
+    Contains store tests model classes.
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/pom.xml
----------------------------------------------------------------------
diff --git a/modules/schema-load/pom.xml b/modules/schema-load/pom.xml
new file mode 100644
index 0000000..88eee8e
--- /dev/null
+++ b/modules/schema-load/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+  -->
+
+<!--
+    POM file.
+-->
+<project
+    xmlns="http://maven.apache.org/POM/4.0.0";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite</artifactId>
+        <version>${ignite.version}</version>
+        <relativePath>../..</relativePath>
+    </parent>
+
+    <artifactId>ignite-schema-load</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <version>${ignite.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/java</directory>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </resource>
+        </resources>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            
<mainClass>org.apache.ignite.schema.ui.SchemaLoadApp</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>jfxrt.jar</id>
+            <activation>
+                <property>
+                    <name>java.vendor</name>
+                    <value>Oracle Corporation</value>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>javafx</groupId>
+                    <artifactId>jfxrt</artifactId>
+                    <version>${java.version}</version>
+                    <scope>system</scope>
+                    <systemPath>${java.home}/lib/jfxrt.jar</systemPath>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/data_connection_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/data_connection_48x48.png 
b/modules/schema-load/src/main/java/media/data_connection_48x48.png
new file mode 100644
index 0000000..475f219
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/data_connection_48x48.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/error_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/error_48x48.png 
b/modules/schema-load/src/main/java/media/error_48x48.png
new file mode 100644
index 0000000..e341b8a
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/error_48x48.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/ignite_128x128.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/ignite_128x128.png 
b/modules/schema-load/src/main/java/media/ignite_128x128.png
new file mode 100644
index 0000000..d99a83c
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/ignite_128x128.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/ignite_16x16.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/ignite_16x16.png 
b/modules/schema-load/src/main/java/media/ignite_16x16.png
new file mode 100644
index 0000000..3e07d33
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/ignite_16x16.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/ignite_24x24.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/ignite_24x24.png 
b/modules/schema-load/src/main/java/media/ignite_24x24.png
new file mode 100644
index 0000000..8da5c97
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/ignite_24x24.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/ignite_32x32.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/ignite_32x32.png 
b/modules/schema-load/src/main/java/media/ignite_32x32.png
new file mode 100644
index 0000000..c6c6819
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/ignite_32x32.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/ignite_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/ignite_48x48.png 
b/modules/schema-load/src/main/java/media/ignite_48x48.png
new file mode 100644
index 0000000..5b684cc
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/ignite_48x48.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/ignite_64x64.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/ignite_64x64.png 
b/modules/schema-load/src/main/java/media/ignite_64x64.png
new file mode 100644
index 0000000..c1d348b
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/ignite_64x64.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/information_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/information_48x48.png 
b/modules/schema-load/src/main/java/media/information_48x48.png
new file mode 100644
index 0000000..8712a1b
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/information_48x48.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/navigate_down_24x24.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/navigate_down_24x24.png 
b/modules/schema-load/src/main/java/media/navigate_down_24x24.png
new file mode 100644
index 0000000..a06dc3b
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/navigate_down_24x24.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/navigate_up_24x24.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/navigate_up_24x24.png 
b/modules/schema-load/src/main/java/media/navigate_up_24x24.png
new file mode 100644
index 0000000..e2fad4c
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/navigate_up_24x24.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/question_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/question_48x48.png 
b/modules/schema-load/src/main/java/media/question_48x48.png
new file mode 100644
index 0000000..84683f9
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/question_48x48.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/sign_warning_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/sign_warning_48x48.png 
b/modules/schema-load/src/main/java/media/sign_warning_48x48.png
new file mode 100644
index 0000000..5e7cccd
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/sign_warning_48x48.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/style.css
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/style.css 
b/modules/schema-load/src/main/java/media/style.css
new file mode 100644
index 0000000..99f3d68
--- /dev/null
+++ b/modules/schema-load/src/main/java/media/style.css
@@ -0,0 +1,58 @@
+.root {
+    -fx-background-color: eeeeee;
+}
+
+.button {
+    -fx-font-size: 14;
+    -fx-focus-color: gray;
+}
+
+.label {
+    -fx-font-size: 14;
+}
+
+.check-box {
+    -fx-font-size: 14;
+    -fx-focus-color: gray;
+}
+
+.text-field {
+    -fx-font-size: 14;
+    -fx-background-color: -fx-text-box-border, -fx-control-inner-background, 
-fx-control-inner-background;
+    -fx-background-radius: 0, 0, 0, 0;
+}
+
+.text-field:focused {
+    -fx-background-color: -fx-text-box-border, -fx-control-inner-background, 
-fx-control-inner-background;
+    -fx-background-radius: 0, 0, 0, 0;
+}
+
+.tree-view {
+    -fx-focus-color: gray;
+}
+
+.table-view {
+    -fx-focus-color: gray;
+}
+
+.tooltip {
+    -fx-background-radius: 0 0 0 0;
+}
+
+.page-corner {
+    -fx-shape: " ";
+}
+
+.progress-indicator {
+    -fx-progress-color: gray
+}
+
+.split-pane {
+    -fx-background-color: -fx-box-border, eeeeee;
+}
+
+#banner {
+   -fx-font-size: 20px;
+   -fx-font-weight: bold;
+   -fx-background-color: white
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/media/text_tree_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-load/src/main/java/media/text_tree_48x48.png 
b/modules/schema-load/src/main/java/media/text_tree_48x48.png
new file mode 100644
index 0000000..6ca9e65
Binary files /dev/null and 
b/modules/schema-load/src/main/java/media/text_tree_48x48.png differ

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/PojoGenerator.java
----------------------------------------------------------------------
diff --git 
a/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/PojoGenerator.java
 
b/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/PojoGenerator.java
new file mode 100644
index 0000000..fadb3a3
--- /dev/null
+++ 
b/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/PojoGenerator.java
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.generator;
+
+import org.apache.ignite.schema.ui.*;
+import org.gridgain.grid.cache.query.*;
+
+import java.io.*;
+import java.util.*;
+
+import static org.apache.ignite.schema.ui.MessageBox.Result.*;
+
+/**
+ * POJO generator for key and value classes.
+ */
+public class PojoGenerator {
+    /** */
+    private static final String TAB = "    ";
+    /** */
+    private static final String TAB2 = TAB + TAB;
+    /** */
+    private static final String TAB3 = TAB + TAB + TAB;
+
+    /**
+     * Add line to source code without indent.
+     *
+     * @param src Source code.
+     * @param line Code line.
+     */
+    private static void add0(Collection<String> src, String line) {
+        src.add(line);
+    }
+
+    /**
+     * Add line to source code with one indent.
+     *
+     * @param src Source code.
+     * @param line Code line.
+     */
+    private static void add1(Collection<String> src, String line) {
+        src.add(TAB + line);
+    }
+
+    /**
+     * Add line to source code with two indents.
+     *
+     * @param src Source code.
+     * @param line Code line.
+     */
+    private static void add2(Collection<String> src, String line) {
+        src.add(TAB2 + line);
+    }
+
+    /**
+     * Add line to source code with three indents.
+     *
+     * @param src Source code.
+     * @param line Code line.
+     */
+    private static void add3(Collection<String> src, String line) {
+        src.add(TAB3 + line);
+    }
+
+    /**
+     * @param str Source string.
+     * @return String with first letters in upper case.
+     */
+    private static String capitalizeFirst(String str) {
+        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
+    }
+
+    /**
+     * Generate java class code.
+     *
+     * @param pkg Package name.
+     * @param type Type name.
+     * @param descs Type descriptors.
+     * @param constructor If {@code true} then generate empty and full 
constructors.
+     * @param askOverwrite Callback to ask user to confirm file overwrite.
+     * @throws IOException If failed to write generated code into file.
+     */
+    private static void generateCode(String pkg, String type, 
Collection<GridCacheQueryTypeDescriptor> descs,
+        File pkgFolder, boolean constructor, ConfirmCallable askOverwrite) 
throws IOException {
+        File out = new File(pkgFolder, type + ".java");
+
+        if (out.exists()) {
+            MessageBox.Result choice = askOverwrite.confirm(out.getName());
+
+            if (CANCEL == choice)
+                throw new IllegalStateException("POJO generation was 
canceled!");
+
+            if (NO == choice || NO_TO_ALL == choice)
+                return;
+        }
+
+        Collection<String> src = new ArrayList<>(256);
+
+        add0(src, "/*");
+        add0(src, " * Licensed to the Apache Software Foundation (ASF) under 
one or more");
+        add0(src, " * contributor license agreements.  See the NOTICE file 
distributed with");
+        add0(src, " * this work for additional information regarding copyright 
ownership.");
+        add0(src, " * The ASF licenses this file to You under the Apache 
License, Version 2.0");
+        add0(src, " * (the \"License\"); you may not use this file except in 
compliance with");
+        add0(src, " * the License.  You may obtain a copy of the License at");
+        add0(src, " *");
+        add0(src, " *      http://www.apache.org/licenses/LICENSE-2.0";);
+        add0(src, " *");
+        add0(src, " * Unless required by applicable law or agreed to in 
writing, software");
+        add0(src, " * distributed under the License is distributed on an \"AS 
IS\" BASIS,");
+        add0(src, " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.");
+        add0(src, " * See the License for the specific language governing 
permissions and");
+        add0(src, " * limitations under the License.");
+        add0(src, " */");
+
+        add0(src, "");
+
+        add0(src, "package " + pkg + ";");
+
+        add0(src, "");
+
+        add0(src, "import java.io.*;");
+
+        add0(src, "");
+
+        add0(src, "/**");
+        add0(src, " * " + type + " definition.");
+        add0(src, " *");
+        add0(src, " * Code generated by Apache Ignite Schema Load utility.");
+        add0(src, " */");
+        add0(src, "public class " + type + " implements Serializable {");
+
+        add1(src, "/** */");
+        add1(src, "private static final long serialVersionUID = 0L;");
+
+        add0(src, "");
+
+        // Fields.
+        for (GridCacheQueryTypeDescriptor desc : descs) {
+            String fldName = desc.getJavaName();
+
+            add1(src, "/** Value for " + fldName + ". */");
+            add1(src, "private " + desc.getJavaType().getSimpleName() + " " + 
fldName + ";");
+            add0(src, "");
+        }
+
+        // Constructors.
+        if (constructor) {
+            add1(src, "/**");
+            add1(src, " * Empty constructor.");
+            add1(src, " */");
+            add1(src, "public " + type + "() {");
+            add2(src, "// No-op.");
+            add1(src, "}");
+
+            add0(src, "");
+
+            add1(src, "/**");
+            add1(src, " * Full constructor.");
+            add1(src, " */");
+            add1(src, "public " + type + "(");
+
+            Iterator<GridCacheQueryTypeDescriptor> it = descs.iterator();
+
+            while (it.hasNext()) {
+                GridCacheQueryTypeDescriptor desc = it.next();
+
+                add2(src, desc.getJavaType().getSimpleName() + " " + 
desc.getJavaName() + (it.hasNext() ? "," : ""));
+            }
+            add1(src, ") {");
+
+            for (GridCacheQueryTypeDescriptor desc : descs)
+                add2(src, String.format("this.%1$s = %1$s;", 
desc.getJavaName()));
+
+            add1(src, "}");
+
+            add0(src, "");
+        }
+
+        // Methods.
+        for (GridCacheQueryTypeDescriptor desc : descs) {
+            String fldName = desc.getJavaName();
+
+            String fldType = desc.getJavaType().getSimpleName();
+
+            String mtdName = capitalizeFirst(fldName);
+
+            add1(src, "/**");
+            add1(src, " * Gets " + fldName + ".");
+            add1(src, " *");
+            add1(src, " * @return Value for " + fldName + ".");
+            add1(src, " */");
+            add1(src, "public " + fldType + " get" + mtdName + "() {");
+            add2(src, "return " + fldName + ";");
+            add1(src, "}");
+
+            add0(src, "");
+
+            add1(src, "/**");
+            add1(src, " * Sets " + fldName + ".");
+            add1(src, " *");
+            add1(src, " * @param " + fldName + " New value for " + fldName + 
".");
+            add1(src, " */");
+            add1(src, "public void set" + mtdName + "(" + fldType + " " + 
fldName + ") {");
+            add2(src, "this." + fldName + " = " + fldName + ";");
+            add1(src, "}");
+
+            add0(src, "");
+        }
+
+        add1(src, "/** {@inheritDoc} */");
+        add1(src, "@Override public boolean equals(Object o) {");
+        add2(src, "if (this == o)");
+        add3(src, "return true;");
+
+        add0(src, "");
+
+        add2(src, "if (!(o instanceof " + type + "))");
+        add3(src, "return false;");
+
+        add0(src, "");
+
+        add2(src, String.format("%1$s that = (%1$s)o;", type));
+
+        for (GridCacheQueryTypeDescriptor desc : descs) {
+            add0(src, "");
+            add2(src, String.format("if (%1$s != null ? 
!%1$s.equals(that.%1$s) : that.%1$s != null)",
+                desc.getJavaName()));
+            add3(src, "return false;");
+        }
+
+        add0(src, "");
+        add2(src, "return true;");
+        add1(src, "}");
+
+        add0(src, "");
+
+        add1(src, "/** {@inheritDoc} */");
+        add1(src, "@Override public int hashCode() {");
+
+        Iterator<GridCacheQueryTypeDescriptor> it = descs.iterator();
+
+        add2(src, String.format("int res = %1$s != null ? %1$s.hashCode() : 
0;", it.next().getJavaName()));
+
+        if (it.hasNext()) {
+            add0(src, "");
+
+            while (it.hasNext())
+                add2(src, String.format("res = 31 * res + (%1$s != null ? 
%1$s.hashCode() : 0);",
+                    it.next().getJavaName()));
+        }
+
+        add0(src, "");
+        add2(src, "return res;");
+        add1(src, "}");
+
+        add0(src, "");
+
+        add1(src, "/** {@inheritDoc} */");
+        add1(src, "@Override public String toString() {");
+
+        it = descs.iterator();
+
+        add2(src, String.format("return \"%1$s [%2$s=\" + %2$s +", type, 
it.next().getJavaName()));
+
+        while (it.hasNext())
+            add3(src, String.format("\", %1$s=\" + %1$s +", 
it.next().getJavaName()));
+
+        add3(src, "\"]\";");
+        add1(src, "}");
+
+        add0(src, "}");
+
+        try (Writer writer = new BufferedWriter(new FileWriter(out))) {
+            for (String line : src)
+                writer.write(line + '\n');
+        }
+    }
+
+    /**
+     * Generate source code for type by its metadata.
+     *
+     * @param meta Type metadata.
+     * @param outFolder Output folder.
+     * @param pkg Types package.
+     * @param constructor If {@code true} then generate empty and full 
constructors.
+     * @param askOverwrite Callback to ask user to confirm file overwrite.
+     * @throws IOException If failed to write generated code into file.
+     */
+    public static void generate(GridCacheQueryTypeMetadata meta, String 
outFolder, String pkg, boolean constructor,
+        ConfirmCallable askOverwrite)
+        throws IOException {
+        File pkgFolder = new File(outFolder, pkg.replace('.', 
File.separatorChar));
+
+        if (!pkgFolder.exists() && !pkgFolder.mkdirs())
+            throw new IOException("Failed to create folders for package: " + 
pkg);
+
+        generateCode(pkg, meta.getKeyType(), meta.getKeyDescriptors(), 
pkgFolder, constructor, askOverwrite);
+
+        generateCode(pkg, meta.getType(), meta.getValueDescriptors(), 
pkgFolder, constructor, askOverwrite);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/XmlGenerator.java
----------------------------------------------------------------------
diff --git 
a/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/XmlGenerator.java
 
b/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/XmlGenerator.java
new file mode 100644
index 0000000..a038bd9
--- /dev/null
+++ 
b/modules/schema-load/src/main/java/org/apache/ignite/schema/generator/XmlGenerator.java
@@ -0,0 +1,320 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.generator;
+
+import org.apache.ignite.lang.*;
+import org.apache.ignite.schema.ui.*;
+import org.gridgain.grid.cache.query.*;
+import org.gridgain.grid.util.typedef.*;
+import org.w3c.dom.*;
+
+import javax.xml.parsers.*;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.*;
+import javax.xml.transform.stream.*;
+import java.io.*;
+import java.util.*;
+
+import static org.apache.ignite.schema.ui.MessageBox.Result.*;
+
+/**
+ * Generator of XML files for type metadata.
+ */
+public class XmlGenerator {
+    /**
+     * Add bean to XML document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param clazz Bean class.
+     */
+    private static Element addBean(Document doc, Node parent, Class<?> clazz) {
+        Element elem = doc.createElement("bean");
+
+        elem.setAttribute("class", clazz.getName());
+
+        parent.appendChild(elem);
+
+        return elem;
+    }
+
+    /**
+     * Add element to XML document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param tagName XML tag name.
+     * @param attr1 Name for first attr.
+     * @param val1 Value for first attribute.
+     * @param attr2 Name for second attr.
+     * @param val2 Value for second attribute.
+     */
+    private static Element addElement(Document doc, Node parent, String 
tagName,
+        String attr1, String val1, String attr2, String val2) {
+        Element elem = doc.createElement(tagName);
+
+        if (attr1 != null)
+            elem.setAttribute(attr1, val1);
+
+        if (attr2 != null)
+            elem.setAttribute(attr2, val2);
+
+        parent.appendChild(elem);
+
+        return elem;
+    }
+
+    /**
+     * Add element to XML document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param tagName XML tag name.
+     */
+    private static Element addElement(Document doc, Node parent, String 
tagName) {
+        return addElement(doc, parent, tagName, null, null, null, null);
+    }
+
+    /**
+     * Add element to XML document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param tagName XML tag name.
+     */
+    private static Element addElement(Document doc, Node parent, String 
tagName, String attrName, String attrVal) {
+        return addElement(doc, parent, tagName, attrName, attrVal, null, null);
+    }
+
+    /**
+     * Add &quot;property&quot; element to XML document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param name Value for &quot;name&quot; attribute
+     * @param val Value for &quot;value&quot; attribute
+     */
+    private static Element addProperty(Document doc, Node parent, String name, 
String val) {
+        String valAttr = val != null ? "value" : null;
+
+        return addElement(doc, parent, "property", "name", name, valAttr, val);
+    }
+
+    /**
+     * Add fields to xml document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param name Property name.
+     * @param fields Map with fields.
+     */
+    private static void addFields(Document doc, Node parent, String name, 
Map<String, Class<?>> fields) {
+        if (!fields.isEmpty()) {
+            Element prop = addProperty(doc, parent, name, null);
+
+            Element map = addElement(doc, prop, "map");
+
+            for (Map.Entry<String, Class<?>> item : fields.entrySet())
+                addElement(doc, map, "entry", "key", item.getKey(), "value", 
item.getValue().getName());
+        }
+    }
+
+    /**
+     * Add type descriptors to XML document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param name Property name.
+     * @param descs Map with type descriptors.
+     */
+    private static void addTypeDescriptors(Document doc, Node parent, String 
name,
+        Collection<GridCacheQueryTypeDescriptor> descs) {
+        if (!descs.isEmpty()) {
+            Element prop = addProperty(doc, parent, name, null);
+
+            Element list = addElement(doc, prop, "list");
+
+            for (GridCacheQueryTypeDescriptor desc : descs) {
+                Element item = addBean(doc, list, 
GridCacheQueryTypeDescriptor.class);
+
+                addProperty(doc, item, "javaName", desc.getJavaName());
+                addProperty(doc, item, "javaType", 
desc.getJavaType().getName());
+                addProperty(doc, item, "dbName", desc.getDbName());
+                addProperty(doc, item, "dbType", 
String.valueOf(desc.getDbType()));
+            }
+        }
+    }
+
+    /**
+     * Add text fields to xml document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param textFields Collection with text fields.
+     */
+    private static void addTextFields(Document doc, Node parent, 
Collection<String> textFields) {
+        if (!textFields.isEmpty()) {
+            Element prop = addProperty(doc, parent, "textFields", null);
+
+            Element list = addElement(doc, prop, "list");
+
+            for (String textField : textFields)
+                addElement(doc, list, "value").setNodeValue(textField);
+        }
+    }
+
+    /**
+     * Add indexes to xml document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param groups Map with indexes.
+     */
+    private static void addGroups(Document doc, Node parent,
+        Map<String, LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>>> 
groups) {
+        if (!F.isEmpty(groups)) {
+            Element prop = addProperty(doc, parent, "groups", null);
+
+            Element map = addElement(doc, prop, "map");
+
+            for (Map.Entry<String, LinkedHashMap<String, 
IgniteBiTuple<Class<?>, Boolean>>> group : groups.entrySet()) {
+                Element entry1 = addElement(doc, map, "entry", "key", 
group.getKey());
+
+                Element val1 = addElement(doc, entry1, "map");
+
+                LinkedHashMap<String, IgniteBiTuple<Class<?>, Boolean>> fields 
= group.getValue();
+
+                for (Map.Entry<String, IgniteBiTuple<Class<?>, Boolean>> field 
: fields.entrySet()) {
+                    Element entry2 = addElement(doc, val1, "entry", "key", 
field.getKey());
+
+                    Element val2 = addBean(doc, entry2, IgniteBiTuple.class);
+
+                    IgniteBiTuple<Class<?>, Boolean> tuple = field.getValue();
+
+                    Class<?> clazz = tuple.get1();
+
+                    assert clazz != null;
+
+                    addElement(doc, val2, "constructor-arg", null, null, 
"value", clazz.getName());
+                    addElement(doc, val2, "constructor-arg", null, null, 
"value", String.valueOf(tuple.get2()));
+                }
+            }
+        }
+    }
+
+    /**
+     * Add element with type metadata to XML document.
+     *
+     * @param doc XML document.
+     * @param parent Parent XML node.
+     * @param pkg Package fo types.
+     * @param meta Meta.
+     */
+    private static void addTypeMetadata(Document doc, Node parent, String pkg, 
GridCacheQueryTypeMetadata meta) {
+        Element bean = addBean(doc, parent, GridCacheQueryTypeMetadata.class);
+
+        addProperty(doc, bean, "type", pkg + "." + meta.getType());
+
+        addProperty(doc, bean, "keyType", pkg + "." + meta.getKeyType());
+
+        addProperty(doc, bean, "schema", meta.getSchema());
+
+        addProperty(doc, bean, "tableName", meta.getTableName());
+
+        addTypeDescriptors(doc, bean, "keyDescriptors", 
meta.getKeyDescriptors());
+
+        addTypeDescriptors(doc, bean, "valueDescriptors", 
meta.getValueDescriptors());
+
+        addFields(doc, bean, "queryFields", meta.getQueryFields());
+
+        addFields(doc, bean, "ascendingFields", meta.getAscendingFields());
+
+        addFields(doc, bean, "descendingFields", meta.getDescendingFields());
+
+        addTextFields(doc, bean, meta.getTextFields());
+
+        addGroups(doc, bean, meta.getGroups());
+    }
+
+    /**
+     * Transform metadata into xml.
+     *
+     * @param pkg Package fo types.
+     * @param meta Metadata to transform.
+     * @param out File to output result.
+     * @param askOverwrite Callback to ask user to confirm file overwrite.
+     */
+    public static void transform(String pkg, GridCacheQueryTypeMetadata meta, 
File out, ConfirmCallable askOverwrite) {
+        transform(pkg, Collections.singleton(meta), out, askOverwrite);
+    }
+
+    /**
+     * Transform metadata into xml.
+     *
+     * @param pkg Package fo types.
+     * @param meta Metadata to transform.
+     * @param out File to output result.
+     * @param askOverwrite Callback to ask user to confirm file overwrite.
+     */
+    public static void transform(String pkg, 
Collection<GridCacheQueryTypeMetadata> meta, File out,
+        ConfirmCallable askOverwrite) {
+        try {
+            if (out.exists()) {
+                MessageBox.Result choice = askOverwrite.confirm(out.getName());
+
+                if (CANCEL == choice)
+                    throw new IllegalStateException("XML generation was 
canceled!");
+
+                if (NO == choice || NO_TO_ALL == choice)
+                    return;
+            }
+
+            DocumentBuilderFactory docFactory = 
DocumentBuilderFactory.newInstance();
+
+            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+
+            Document doc = docBuilder.newDocument();
+            doc.setXmlStandalone(true);
+
+            Element beans = addElement(doc, doc, "beans");
+            beans.setAttribute("xmlns", 
"http://www.springframework.org/schema/beans";);
+            beans.setAttribute("xmlns:xsi", 
"http://www.w3.org/2001/XMLSchema-instance";);
+            beans.setAttribute("xmlns:util", 
"http://www.springframework.org/schema/util";);
+            beans.setAttribute("xsi:schemaLocation",
+                "http://www.springframework.org/schema/beans " +
+                    
"http://www.springframework.org/schema/beans/spring-beans.xsd " +
+                    "http://www.springframework.org/schema/util " +
+                    
"http://www.springframework.org/schema/util/spring-util.xsd";);
+
+            for (GridCacheQueryTypeMetadata item : meta)
+                addTypeMetadata(doc, beans, pkg, item);
+
+            TransformerFactory transformerFactory = 
TransformerFactory.newInstance();
+
+            Transformer transformer = transformerFactory.newTransformer();
+
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount";, "4");
+
+            transformer.transform(new DOMSource(doc), new StreamResult(out));
+        }
+        catch (ParserConfigurationException | TransformerException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/ConfirmCallable.java
----------------------------------------------------------------------
diff --git 
a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/ConfirmCallable.java
 
b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/ConfirmCallable.java
new file mode 100644
index 0000000..3990496
--- /dev/null
+++ 
b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/ConfirmCallable.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.ui;
+
+import javafx.application.*;
+import javafx.stage.*;
+
+import java.util.concurrent.*;
+
+import static org.apache.ignite.schema.ui.MessageBox.Result.*;
+
+/**
+ * Callable to ask user for confirmation from non EDT thread.
+ */
+public class ConfirmCallable implements Callable<MessageBox.Result> {
+    /** Owner window. */
+    private final Stage owner;
+
+    /** Message template. */
+    private final String template;
+
+    /** Message to show in confirmation dialog. */
+    private String msg;
+
+    /** User choice. */
+    private MessageBox.Result choice = NO;
+
+    /**
+     * @param owner Owner window.
+     * @param template Message template.
+     */
+    public ConfirmCallable(Stage owner, String template) {
+        this.owner = owner;
+        this.template = template;
+    }
+
+    /** {@inheritDoc} */
+    @Override public MessageBox.Result call() throws Exception {
+        choice = MessageBox.confirmRememberChoiceDialog(owner, 
String.format(template, msg));
+
+        return choice;
+    }
+
+    /**
+     * Execute confirmation in EDT thread.
+     *
+     * @return Confirm result.
+     */
+    public MessageBox.Result confirm(String msg) {
+        this.msg = msg;
+
+        if (choice == YES_TO_ALL || choice == NO_TO_ALL)
+            return choice;
+
+        FutureTask<MessageBox.Result> fut = new FutureTask<>(this);
+
+        Platform.runLater(fut);
+
+        try {
+            return fut.get();
+        }
+        catch (Exception ignored) {
+            return NO;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/410f9e5e/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/Controls.java
----------------------------------------------------------------------
diff --git 
a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/Controls.java 
b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/Controls.java
new file mode 100644
index 0000000..039b478
--- /dev/null
+++ 
b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/Controls.java
@@ -0,0 +1,377 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.ui;
+
+import javafx.event.*;
+import javafx.geometry.*;
+import javafx.scene.*;
+import javafx.scene.control.*;
+import javafx.scene.control.cell.*;
+import javafx.scene.image.*;
+import javafx.scene.layout.*;
+import javafx.scene.text.*;
+
+/**
+ * Utility class to create controls.
+ */
+public class Controls {
+    /** */
+    public static final Insets DFLT_PADDING = new Insets(10, 10, 10, 10);
+
+    /**
+     * Create scene with predefined style.
+     *
+     * @param root The root node of the scene graph.
+     * @return New {@code Scene} instance.
+     */
+    public static Scene scene(Parent root) {
+        Scene scene = new Scene(root);
+
+        scene.getStylesheets().add("media/style.css");
+
+        return scene;
+    }
+
+    /**
+     * Create grid pane with default padding.
+     *
+     * @param top Top padding
+     * @param right Right padding.
+     * @param bottom Bottom padding.
+     * @param left Left padding.
+     * @return New {@code GridPaneEx} instance.
+     */
+    public static GridPaneEx paneEx(double top, double right, double bottom, 
double left) {
+        GridPaneEx paneEx = new GridPaneEx();
+
+        paneEx.setPadding(new Insets(top, right, bottom, left));
+
+        return paneEx;
+    }
+
+    /**
+     * Create new {@code HBox} with default padding.
+     *
+     * @param spacing Amount of horizontal space between each child.
+     * @param dfltPadding If {@code true} than set default padding for pane.
+     * @return New {@code HBox} instance.
+     */
+    public static HBox hBox(int spacing, boolean dfltPadding) {
+        HBox hb = new HBox(spacing);
+
+        if (dfltPadding)
+            hb.setPadding(DFLT_PADDING);
+
+        return hb;
+    }
+
+    /**
+     * Create new {@code HBox} with default padding and add controls.
+     *
+     * @param spacing Amount of horizontal space between each child.
+     * @param dfltPadding If {@code true} than set default padding for pane.
+     * @param controls Controls to add.
+     * @return New {@code HBox} instance.
+     */
+    public static HBox hBox(int spacing, boolean dfltPadding, Node... 
controls) {
+        HBox hb = hBox(spacing, dfltPadding);
+
+        hb.getChildren().addAll(controls);
+
+        return hb;
+    }
+
+    /**
+     * Create new {@code VBox} with default padding.
+     *
+     * @param spacing Amount of horizontal space between each child.
+     * @return New {@code VBox} instance.
+     */
+    public static VBox vBox(int spacing) {
+        VBox vb = new VBox(spacing);
+
+        vb.setPadding(DFLT_PADDING);
+
+        return vb;
+    }
+
+    /**
+     * Create new {@code VBox} with default padding and add controls.
+     *
+     * @param spacing Amount of horizontal space between each child.
+     * @param controls Controls to add.
+     * @return New {@code VBox} instance.
+     */
+    public static VBox vBox(int spacing, Node... controls) {
+        VBox vb = vBox(spacing);
+
+        vb.getChildren().addAll(controls);
+
+        return vb;
+    }
+
+    /**
+     * Create stack pane.
+     *
+     * @param controls Controls to add.
+     * @return New {@code StackPane} instance.
+     */
+    public static StackPane stackPane(Node... controls) {
+        StackPane sp = new StackPane();
+
+        sp.getChildren().addAll(controls);
+
+        return sp;
+    }
+
+    /**
+     * Create border pane.
+     *
+     * @param top Optional top control.
+     * @param center Optional center control.
+     * @param bottom Optional bottom control.
+     * @param left Optional left control.
+     * @param right Optional right control.
+     * @return New {@code BorderPane} instance.
+     */
+    public static BorderPane borderPane(Node top, Node center, Node bottom, 
Node left, Node right) {
+        BorderPane bp = new BorderPane();
+
+        bp.setTop(top);
+        bp.setCenter(center);
+        bp.setBottom(bottom);
+        bp.setLeft(left);
+        bp.setRight(right);
+
+        return bp;
+    }
+
+    /**
+     * Sets control tooltip if needed.
+     *
+     * @param ctrl Target control.
+     * @param tip Tooltip text.
+     * @return Control itself for method chaining.
+     */
+    public static <T extends Control> T tooltip(T ctrl, String tip) {
+        if (!tip.isEmpty())
+            ctrl.setTooltip(new Tooltip(tip));
+
+        return ctrl;
+    }
+
+    /**
+     * Create button with text only.
+     *
+     * @param text Button text.
+     * @param tip Tooltip text.
+     * @param onAct Button action.
+     * @return New {@code Button} instance.
+     */
+    public static Button button(String text, String tip, 
EventHandler<ActionEvent> onAct) {
+        Button btn = new Button(text);
+
+        btn.setOnAction(onAct);
+
+        tooltip(btn, tip);
+
+        return btn;
+    }
+
+    /**
+     * Create button with icon only.
+     *
+     * @param icon Button icon.
+     * @param tip Tooltip text.
+     * @param onAct Button action.
+     * @return New {@code Button} instance.
+     */
+    public static Button button(ImageView icon, String tip, 
EventHandler<ActionEvent> onAct) {
+        Button btn = new Button();
+
+        btn.setGraphic(icon);
+        btn.setOnAction(onAct);
+
+        tooltip(btn, tip);
+
+        return btn;
+    }
+
+    /**
+     * Create pane with buttons.
+     *
+     * @param alignment Alignment of buttons.
+     * @param dfltPadding If {@code true} than set default padding for pane.
+     * @param btns Buttons that will be added to pane.
+     * @return New {@code HBox} instance with buttons.
+     */
+    public static Pane buttonsPane(Pos alignment, boolean dfltPadding, 
Button... btns) {
+        HBox hb = hBox(10, dfltPadding, btns);
+
+        hb.setAlignment(alignment);
+
+        return hb;
+    }
+
+    /**
+     * Create checkbox.
+     *
+     * @param text Checkbox text.
+     * @param tip Tooltip tex.
+     * @param sel Checkbox selected state.
+     * @return New {@code Checkbox} instance.
+     */
+    public static CheckBox checkBox(String text, String tip, boolean sel) {
+        CheckBox ch = new CheckBox(text);
+
+        ch.setSelected(sel);
+
+        tooltip(ch, tip);
+
+        return ch;
+    }
+
+    /**
+     * Create text field.
+     *
+     * @param tip Tooltip text.
+     * @return New {@code TextField} instance.
+     */
+    public static TextField textField(String tip) {
+        TextField tf = new TextField();
+
+        tooltip(tf, tip);
+
+        return tf;
+    }
+
+    /**
+     * Create static text.
+     *
+     * @param text Text to show.
+     * @param wrap Text wrapping width.
+     * @return New {@code Text} instance.
+     */
+    public static Text text(String text, int wrap) {
+        Text t = new Text(text);
+
+        t.setFont(new Font(14));
+
+        if (wrap > 0)
+            t.setWrappingWidth(wrap);
+
+        return t;
+    }
+
+    /**
+     * Create password field.
+     *
+     * @param tip Tooltip text.
+     * @return New {@code PasswordField} instance.
+     */
+    public static PasswordField passwordField(String tip) {
+        PasswordField pf = new PasswordField();
+
+        tooltip(pf, tip);
+
+        return pf;
+    }
+
+    /**
+     * Create split pane for provided nodes.
+     *
+     * @param node1 First node.
+     * @param node2 Second node.
+     * @param pos Initial divider position.
+     * @return New {@code SplitPane} instance.
+     */
+    public static SplitPane splitPane(Node node1, Node node2, double pos) {
+        SplitPane sp = new SplitPane();
+
+        sp.setOrientation(Orientation.VERTICAL);
+        sp.getItems().addAll(node1, node2);
+        sp.setDividerPosition(0, pos);
+
+        return sp;
+    }
+
+    /**
+     * Create table column.
+     *
+     * @param colName Column name to display.
+     * @param propName Property name column is bound to.
+     * @param tip Column tooltip text.
+     * @param minWidth The minimum width column is permitted to be resized to.
+     * @param maxWidth The maximum width column is permitted to be resized to.
+     * @return New {@code TableColumn} instance.
+     */
+    public static <S, T> TableColumn<S, T> tableColumn(String colName, String 
propName, String tip,
+        int minWidth, int maxWidth) {
+        TableColumn<S, T> col = new TableColumn<>();
+
+        col.setGraphic(tooltip(new Label(colName), tip));
+
+        col.setSortable(false);
+
+        if (minWidth > 0)
+            col.setMinWidth(minWidth);
+
+        if (maxWidth > 0)
+            col.setMaxWidth(maxWidth);
+
+        col.setCellValueFactory(new PropertyValueFactory<S, T>(propName));
+
+        return col;
+    }
+
+    /**
+     * Create progress indicator.
+     *
+     * @param sz Indicator diameter.
+     * @return New {@code ProgressIndicator} instance.
+     */
+    public static ProgressIndicator progressIndicator(int sz) {
+        ProgressIndicator pi = new ProgressIndicator();
+
+        pi.setMaxWidth(sz);
+        pi.setMaxHeight(sz);
+
+        return pi;
+    }
+
+    /**
+     * Create image view.
+     *
+     * @param imgFileName Image filename.
+     * @return New {@code ImageView} instance.
+     */
+    public static ImageView imageView(String imgFileName, int sz) {
+        return new ImageView(image(imgFileName, sz));
+    }
+
+    /**
+     * Gets image by its filename.
+     *
+     * @param imgFileName Image filename.
+     * @return Loaded image.
+     */
+    public static Image image(String imgFileName, int sz) {
+        return new Image(Controls.class.getClassLoader()
+            .getResourceAsStream(String.format("media/%1$s_%2$dx%2$d.png", 
imgFileName, sz)));
+    }
+}

Reply via email to