/*
 * 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.examples.datagrid.store;

import org.apache.ignite.*;
import org.apache.ignite.cache.*;
import org.apache.ignite.cache.store.*;
import org.apache.ignite.configuration.*;
import org.apache.ignite.examples.datagrid.store.dummy.*;
import org.apache.ignite.examples.datagrid.store.hibernate.*;
import org.apache.ignite.examples.datagrid.store.jdbc.*;
import org.apache.ignite.examples.datagrid.store.model.*;
import org.apache.ignite.internal.util.typedef.*;
import org.apache.ignite.spi.discovery.tcp.*;
import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.*;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;

import javax.cache.configuration.*;
import java.sql.*;
import java.util.*;

import static org.apache.ignite.cache.CacheAtomicityMode.*;

/**
 * Starts up an empty node with example cache and store configuration.
 */
public class CacheNodeWithStoreStartup {
    /** Use org.apache.ignite.examples.datagrid.store.dummy.CacheDummyPersonStore to run example. */
    public static final String DUMMY = "DUMMY";

    /** Use org.apache.ignite.examples.datagrid.store.jdbc.CacheJdbcPersonStore to run example. */
    public static final String SIMPLE_JDBC = "SIMPLE_JDBC";

    /** Use org.apache.ignite.examples.datagrid.store.hibernate.CacheHibernatePersonStore to run example. */
    public static final String HIBERNATE = "HIBERNATE";

    /** Use org.apache.ignite.examples.datagrid.store.jdbc.CacheJdbcPojoPersonStore to run example. */
    public static final String AUTO = "AUTO";

    /** Store to use. */
    public static final String STORE = DUMMY;

    /**
     * Start up an empty node with specified cache configuration.
     *
     * @param args Command line arguments, none required.
     * @throws IgniteException If example execution failed.
     */
    public static void main(String[] args) throws IgniteException {
        Ignition.start(configure());
    }

    /**
     * Configure ignite.
     *
     * @return Ignite configuration.
     * @throws IgniteException If failed.
     */
    public static IgniteConfiguration configure() throws IgniteException {
        IgniteConfiguration cfg = new IgniteConfiguration();

        cfg.setLocalHost("127.0.0.1");

        // Discovery SPI.
        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();

        TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();

        ipFinder.setAddresses(Arrays.asList("127.0.0.1:47500..47509"));

        discoSpi.setIpFinder(ipFinder);

        CacheConfiguration<Long, Person> cacheCfg = new CacheConfiguration<>();

        // Set atomicity as transaction, since we are showing transactions in example.
        cacheCfg.setAtomicityMode(TRANSACTIONAL);

        CacheStore<Long, Person> store;

        switch (STORE) {
            case DUMMY:
                store = new CacheDummyPersonStore();
                break;

            case SIMPLE_JDBC:
                store = new CacheJdbcPersonStore();
                break;

            case HIBERNATE:
                store = new CacheHibernatePersonStore();
                break;

            default:
                store = new CacheJdbcPojoPersonStore();
                cacheCfg.setTypeMetadata(typeMetadata());
                break;
        }

        cacheCfg.setCacheStoreFactory(new FactoryBuilder.SingletonFactory<>(store));
        cacheCfg.setReadThrough(true);
        cacheCfg.setWriteThrough(true);

        cfg.setDiscoverySpi(discoSpi);
        cfg.setCacheConfiguration(cacheCfg);

        return cfg;
    }

    /**
     * @return Type mapping description.
     */
    private static Collection<CacheTypeMetadata> typeMetadata() {
        CacheTypeMetadata tm = new CacheTypeMetadata();

        tm.setDatabaseTable("PERSON");

        tm.setKeyType("java.lang.Long");
        tm.setValueType("org.apache.ignite.examples.datagrid.store.model.Person");

        tm.setKeyFields(F.asList(new CacheTypeFieldMetadata("ID", Types.BIGINT, "id", Long.class)));

        tm.setValueFields(F.asList(
            new CacheTypeFieldMetadata("ID", Types.BIGINT, "id", long.class),
            new CacheTypeFieldMetadata("FIRST_NAME", Types.VARCHAR, "firstName", String.class),
            new CacheTypeFieldMetadata("LAST_NAME", Types.VARCHAR, "lastName", String.class)
        ));

        return F.asList(tm);
    }
}

@@ -3520,24 +3520,209 @@
 ACTIONAL);%0A%0A
+        cacheCfg.setCacheStoreFactory(new Factory%3CCacheStore%3C? super Long, ? super Person%3E%3E() %7B%0A            @Override public CacheStore%3C? super Long, ? super Person%3E create() %7B%0A        
         Cach
@@ -3750,16 +3750,24 @@
 store;%0A%0A
+        
         
@@ -3791,24 +3791,32 @@
             
+    
+    
 case DUMMY:%0A
@@ -3815,16 +3815,24 @@
  DUMMY:%0A
+        
         
@@ -3868,32 +3868,40 @@
 yPersonStore();%0A
+        
                 
@@ -3916,24 +3916,32 @@
             
+        
 case SIMPLE_
@@ -3946,16 +3946,24 @@
 E_JDBC:%0A
+        
         
@@ -4018,32 +4018,40 @@
             
+   
+     
 break;%0A%0A
             
@@ -4030,32 +4030,40 @@
         break;%0A%0A
+        
             case
@@ -4082,32 +4082,40 @@
                 
+       
+ 
 store = new Cach
@@ -4147,32 +4147,40 @@
                 
+        
 break;%0A%0A        
@@ -4183,16 +4183,24 @@
         
+ 
+       
 default:
@@ -4220,225 +4220,402 @@
     
-store = new CacheJdbcPojoPersonStore();%0A                cacheCfg.setTypeMetadata(typeMetadata());%0A                break;%0A        %7D%0A%0A        cacheCfg.setCacheStoreFactory(new FactoryBuilder.SingletonFactory%3C%3E(store
+        if (!STORE.equals(AUTO))%0A                            throw new IllegalStateException(%22Unexpected store configured: %22 + STORE);%0A%0A                        store = new CacheJdbcPojoPersonStore();%0A                        break;%0A                %7D%0A%0A                return store;%0A            %7D%0A        %7D);%0A%0A        if (STORE.equals(AUTO))%0A            cacheCfg.setTypeMetadata(typeMetadata(
 ));%0A
+%0A
     

fix for ignite-507