de.ks.idnadrev.expimp.xls.XlsxImporter.java Source code

Java tutorial

Introduction

Here is the source code for de.ks.idnadrev.expimp.xls.XlsxImporter.java

Source

/*
 * Copyright [2014] [Christian Loehnert, krampenschiesser@gmail.com]
 * Licensed 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 de.ks.idnadrev.expimp.xls;

import com.google.common.util.concurrent.MoreExecutors;
import de.ks.idnadrev.expimp.DependencyGraph;
import de.ks.idnadrev.expimp.xls.result.XlsxImportResultCollector;
import de.ks.idnadrev.expimp.xls.result.XlsxImportSheetResult;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.enterprise.inject.spi.CDI;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

public class XlsxImporter {
    private static final Logger log = LoggerFactory.getLogger(XlsxImporter.class);

    protected XlsxImportResultCollector resultCollector;
    protected final ExecutorService executorService;
    protected DependencyGraph dependencyGraph;
    protected boolean throwOnError = false;

    protected XlsImportCfg importCfg = new XlsImportCfg().replaceExisting();

    public XlsxImporter() {
        this(MoreExecutors.newDirectExecutorService());
    }

    public XlsxImporter(ExecutorService executorService) {
        this.executorService = executorService;
        dependencyGraph = CDI.current().select(DependencyGraph.class).get();
    }

    public XlsxImporter setImportCfg(XlsImportCfg importCfg) {
        this.importCfg = importCfg;
        return this;
    }

    public XlsImportCfg getImportCfg() {
        return importCfg;
    }

    public XlsxImportResultCollector importFromFile(File file) {
        resultCollector = new XlsxImportResultCollector();
        checkFile(file);
        OPCPackage pkg = openPackage(file);
        try {
            XSSFReader reader = new XSSFReader(pkg);
            SharedStringsTable sharedStringsTable = reader.getSharedStringsTable();//used by ms office to store all string values
            log.info("Importing from {}", file);

            Map<Integer, Collection<SingleSheetImport>> importStages = new HashMap<>();

            XSSFReader.SheetIterator iterator = (XSSFReader.SheetIterator) reader.getSheetsData();
            while (iterator.hasNext()) {
                InputStream sheetStream = iterator.next();

                String sheetName = iterator.getSheetName();
                final XlsxImportSheetResult result = resultCollector.getSheetResult(sheetName);

                Class<?> class2Import;
                try {
                    class2Import = getClass().getClassLoader().loadClass(sheetName);
                } catch (ClassNotFoundException e) {
                    log.info("Could not load class to import {} will skip sheet.", sheetName);
                    result.generalError("Could not load class to import " + sheetName + " will skip sheet.", e);
                    continue;
                }

                if (class2Import != null) {
                    if (importCfg.getIgnored().contains(class2Import)) {
                        continue;
                    }
                    int stage = dependencyGraph.getStage(class2Import);
                    importStages.putIfAbsent(stage, new LinkedList<>());
                    SingleSheetImport singleSheetImport = new SingleSheetImport(class2Import, sheetStream,
                            dependencyGraph, reader, result, importCfg);
                    importStages.get(stage).add(singleSheetImport);
                }
            }

            importStages.entrySet().forEach(stage -> {
                try {
                    executorService.invokeAll(stage.getValue());

                    List<List<Future<?>>> collect = stage.getValue().stream()//
                            .map(sheet -> sheet.getRunAfterImport().stream()
                                    .map((Runnable r) -> executorService.submit(r))
                                    .collect(Collectors.<Future<?>>toList()))//
                            .collect(Collectors.<List<Future<?>>>toList());

                    for (List<Future<?>> futureList : collect) {
                        futureList.forEach(future -> {
                            try {
                                future.get();
                            } catch (ExecutionException e) {
                                if (throwOnError) {
                                    log.error("Could not run after sheet ", e);
                                    throw new RuntimeException(e);
                                }
                            } catch (InterruptedException e) {
                                //
                            }
                        });
                    }
                } catch (InterruptedException e1) {
                    //
                }
            });

        } catch (OpenXML4JException | IOException e) {
            resultCollector.generalError("Could not read " + file, e);
            if (throwOnError) {
                log.error("Could not read {}", file, e);
                throw new RuntimeException(e);
            }
        } finally {
            try {
                pkg.close();
            } catch (IOException e) {
                resultCollector.generalError("Could not close package " + pkg, e);
                if (throwOnError) {
                    log.error("Could not close package {}", pkg, e);
                }
            }
        }
        return resultCollector;
    }

    protected OPCPackage openPackage(File file) {
        OPCPackage pkg = null;
        try {
            pkg = OPCPackage.open(file);
        } catch (InvalidFormatException e) {
            log.error("Could not create opc package for file {}", file, e);
            throw new RuntimeException(e);
        }
        return pkg;
    }

    private void checkFile(File file) {
        if (file == null) {
            throw new NullPointerException("File must not be null");
        }
        if (!file.exists()) {
            throw new IllegalArgumentException("File " + file + " has to exist");
        }
    }

    public boolean isThrowOnError() {
        return throwOnError;
    }

    public void setThrowOnError(boolean throwOnError) {
        this.throwOnError = throwOnError;
    }
}