// Path: spring-data-solr-demo-common/src/main/java/org/tuxdevelop/spring/data/solr/demo/domain/StarbucksStore.java
// @Data
// @AllArgsConstructor
// @NoArgsConstructor
// @SolrDocument
// @XmlRootElement
// public class StarbucksStore {
// 
//     @Id
//     @Field("id")
//     private String id;
//     @Field("name")
//     private String name;
//     @Field("zipCode")
//     private String zipCode;
//     @Field("city")
//     private String city;
//     @Field("street")
//     private String street;
//     @Field("products")
//     private Collection<String> products;
//     @Field("services")
//     private Collection<String> services;
//     @JsonIgnore
//     @Field("location")
//     private Point location;
// 
// }
// 
// Path: spring-data-solr-demo-common/src/main/java/org/tuxdevelop/spring/data/solr/demo/repository/StarbucksStoreRepository.java
// public interface StarbucksStoreRepository extends SolrCrudRepository<StarbucksStore, String>, StarbucksStoreCrudOperations {
// 
//     /**
//      * find stores by name
//      *
//      * @param name the name of store
//      * @return a collection of stores, where the input match
//      */
//     Collection<StarbucksStore> findByName(@Param("name") final String name);
// 
// 
//     /**
//      * find all stores whoch provides the given products
//      *
//      * @param products products query parameter
//      * @return a collection of stores, where the input match
//      */
//     Collection<StarbucksStore> findByProductsIn(@Param("products") final Collection<String> products);
//     
//     /**
//      * find all stores which provides the given products and are next to a geo point and given distance
//      *
//      * @param products products query parameter
//      * @param point    geo location
//      * @param distance radius distance to the geo point
//      * @return a collection of stores, where the input match
//      */
//     Collection<StarbucksStore> findByProductsInAndLocationNear(@Param("products") final Collection<String> products, @Param
//             ("point") final Point point, final @Param("distance") Distance distance);
// 
//     /**
//      * find stores by name
//      *
//      * @param name the name of store
//      * @return a collection of stores, where the input match
//      */
//     @Query("name:?0")
//     Collection<StarbucksStore> findByNameQuery(@Param("name") final String name);
// 
//     /**
//      * find stores by name
//      *
//      * @param name the name of store
//      * @return a collection of stores, where the input match
//      */
//     @Query(value = "*:*", filters = {"name:=?0"})
//     Collection<StarbucksStore> findByNameFilterQuery(@Param("name") final String name);
// 
//     /**
//      * find all stores which are next to a geo point and given distance
//      *
//      * @param point    geo location
//      * @param distance radius distance to the geo point
//      * @return a collection of stores, where the input match
//      */
//     Collection<StarbucksStore> findByLocationNear(@Param("point") final Point point, @Param("distance") final Distance distance);
// 
//     /**
//      * find all stores of a give zip code
//      *
//      * @param zipCode query parameter
//      * @param page    input page
//      * @return a facet of the products of stores, where the input matches
//      */
//     @Query(value = "zipCode:?0")
//     @Facet(fields = {"products"})
//     FacetPage<StarbucksStore> findByZipCodeFacetOnProducts(@Param("zipCode") final String zipCode, final Pageable page);
// 
//     /**
//      * find all stores
//      *
//      * @param page input page
//      * @return a facet of the products of stores, where the input matches
//      */
//     @Query(value = "*:*")
//     @Facet(fields = {"products"})
//     FacetPage<StarbucksStore> findByFacetOnProducts(final Pageable page);
// 
//     /**
//      * find all stores which provides the given products
//      *
//      * @param products query param
//      * @param page     input page
//      * @return a facet of the names of stores, where the input matches
//      */
//     @Query(value = "*:*", filters = "products:?0")
//     @Facet(fields = {"name"})
//     FacetPage<StarbucksStore> findFacetOnName(@Param("products") final List<String> products, final Pageable page);
// }


import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.separator.DefaultRecordSeparatorPolicy;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.geo.Point;
import org.springframework.data.solr.UncategorizedSolrException;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.tuxdevelop.spring.data.solr.demo.domain.StarbucksStore;
import org.tuxdevelop.spring.data.solr.demo.repository.StarbucksStoreRepository;
import java.util.*;

    @Autowired
    private StarbucksStoreRepository starbucksStoreRepository;

    public void importStarbucks() throws Exception {
        final List<List<StarbucksStore>> stores = importStores();
        for (List<StarbucksStore> starbucksStoreList : stores) {
            try {
                starbucksStoreRepository.save(starbucksStoreList);
            } catch (UncategorizedSolrException e) {
                log.error(e.getMessage());
            }
        }

    }

    private List<List<StarbucksStore>> importStores() throws Exception {
        final ClassPathResource resource = new ClassPathResource("starbucks.csv");
        final Scanner scanner = new Scanner(resource.getInputStream());
        final String line = scanner.nextLine();
        scanner.close();

        final FlatFileItemReader<StarbucksStore> itemReader = new FlatFileItemReader<StarbucksStore>();
        itemReader.setResource(resource);

        // DelimitedLineTokenizer defaults to comma as its delimiter
        final DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        tokenizer.setNames(line.split(","));
        tokenizer.setStrict(false);

// Path: spring-data-solr-demo-common/src/main/java/org/tuxdevelop/spring/data/solr/demo/domain/StarbucksStore.java
// @Data
// @AllArgsConstructor
// @NoArgsConstructor
// @SolrDocument
// @XmlRootElement
// public class StarbucksStore {
// 
//     @Id
//     @Field("id")
//     private String id;
//     @Field("name")
//     private String name;
//     @Field("zipCode")
//     private String zipCode;
//     @Field("city")
//     private String city;
//     @Field("street")
//     private String street;
//     @Field("products")
//     private Collection<String> products;
//     @Field("services")
//     private Collection<String> services;
//     @JsonIgnore
//     @Field("location")
//     private Point location;
// 
// }
// 
// Path: spring-data-solr-demo-common/src/main/java/org/tuxdevelop/spring/data/solr/demo/repository/StarbucksStoreRepository.java
// public interface StarbucksStoreRepository extends SolrCrudRepository<StarbucksStore, String>, StarbucksStoreCrudOperations {
// 
//     /**
//      * find stores by name
//      *
//      * @param name the name of store
//      * @return a collection of stores, where the input match
//      */
//     Collection<StarbucksStore> findByName(@Param("name") final String name);
// 
// 
//     /**
//      * find all stores whoch provides the given products
//      *
//      * @param products products query parameter
//      * @return a collection of stores, where the input match
//      */
//     Collection<StarbucksStore> findByProductsIn(@Param("products") final Collection<String> products);
//     
//     /**
//      * find all stores which provides the given products and are next to a geo point and given distance
//      *
//      * @param products products query parameter
//      * @param point    geo location
//      * @param distance radius distance to the geo point
//      * @return a collection of stores, where the input match
//      */
//     Collection<StarbucksStore> findByProductsInAndLocationNear(@Param("products") final Collection<String> products, @Param
//             ("point") final Point point, final @Param("distance") Distance distance);
// 
//     /**
//      * find stores by name
//      *
//      * @param name the name of store
//      * @return a collection of stores, where the input match
//      */
//     @Query("name:?0")
//     Collection<StarbucksStore> findByNameQuery(@Param("name") final String name);
// 
//     /**
//      * find stores by name
//      *
//      * @param name the name of store
//      * @return a collection of stores, where the input match
//      */
//     @Query(value = "*:*", filters = {"name:=?0"})
//     Collection<StarbucksStore> findByNameFilterQuery(@Param("name") final String name);
// 
//     /**
//      * find all stores which are next to a geo point and given distance
//      *
//      * @param point    geo location
//      * @param distance radius distance to the geo point
//      * @return a collection of stores, where the input match
//      */
//     Collection<StarbucksStore> findByLocationNear(@Param("point") final Point point, @Param("distance") final Distance distance);
// 
//     /**
//      * find all stores of a give zip code
//      *
//      * @param zipCode query parameter
//      * @param page    input page
//      * @return a facet of the products of stores, where the input matches
//      */
//     @Query(value = "zipCode:?0")
//     @Facet(fields = {"products"})
//     FacetPage<StarbucksStore> findByZipCodeFacetOnProducts(@Param("zipCode") final String zipCode, final Pageable page);
// 
//     /**
//      * find all stores
//      *
//      * @param page input page
//      * @return a facet of the products of stores, where the input matches
//      */
//     @Query(value = "*:*")
//     @Facet(fields = {"products"})
//     FacetPage<StarbucksStore> findByFacetOnProducts(final Pageable page);
// 
//     /**
//      * find all stores which provides the given products
//      *
//      * @param products query param
//      * @param page     input page
//      * @return a facet of the names of stores, where the input matches
//      */
//     @Query(value = "*:*", filters = "products:?0")
//     @Facet(fields = {"name"})
//     FacetPage<StarbucksStore> findFacetOnName(@Param("products") final List<String> products, final Pageable page);
// }


// Path: spring-data-solr-demo-common/src/main/java/org/tuxdevelop/spring/data/solr/demo/util/SolrInitializer.java
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.separator.DefaultRecordSeparatorPolicy;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.geo.Point;
import org.springframework.data.solr.UncategorizedSolrException;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.tuxdevelop.spring.data.solr.demo.domain.StarbucksStore;
import org.tuxdevelop.spring.data.solr.demo.repository.StarbucksStoreRepository;
import java.util.*;


    @Autowired
    private StarbucksStoreRepository starbucksStoreRepository;

    public void importStarbucks() throws Exception {
        final List<List<StarbucksStore>> stores = importStores();
        for (List<StarbucksStore> starbucksStoreList : stores) {
            try {
                starbucksStoreRepository.save(starbucksStoreList);
            } catch (UncategorizedSolrException e) {
                log.error(e.getMessage());
            }
        }

    }

    private List<List<StarbucksStore>> importStores() throws Exception {
        final ClassPathResource resource = new ClassPathResource("starbucks.csv");
        final Scanner scanner = new Scanner(resource.getInputStream());
        final String line = scanner.nextLine();
        scanner.close();

        final FlatFileItemReader<StarbucksStore> itemReader = new FlatFileItemReader<StarbucksStore>();
        itemReader.setResource(resource);

        // DelimitedLineTokenizer defaults to comma as its delimiter
        final DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        tokenizer.setNames(line.split(","));
        tokenizer.setStrict(false);

        final DefaultLineMapper<StarbucksStore> lineMapper = new DefaultLineMapper<StarbucksStore>();