org.nuxeo.ecm.platform.filemanager.service.extension.CSVZipImporter.java Source code

Java tutorial

Introduction

Here is the source code for org.nuxeo.ecm.platform.filemanager.service.extension.CSVZipImporter.java

Source

/*
 * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
 *
 * 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.
 *
 * Contributors:
 *     Nuxeo - initial API and implementation
 *
 */

package org.nuxeo.ecm.platform.filemanager.service.extension;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.common.utils.IdUtils;
import org.nuxeo.common.utils.Path;
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.Blobs;
import org.nuxeo.ecm.core.api.CloseableFile;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.PathRef;
import org.nuxeo.ecm.core.schema.DocumentType;
import org.nuxeo.ecm.core.schema.TypeConstants;
import org.nuxeo.ecm.core.schema.types.Field;
import org.nuxeo.ecm.core.schema.types.SimpleTypeImpl;
import org.nuxeo.ecm.core.schema.types.Type;
import org.nuxeo.ecm.core.schema.types.primitives.DateType;
import org.nuxeo.ecm.core.schema.types.primitives.IntegerType;
import org.nuxeo.ecm.core.schema.types.primitives.LongType;
import org.nuxeo.ecm.core.schema.types.primitives.StringType;
import org.nuxeo.ecm.platform.types.TypeManager;

public class CSVZipImporter extends AbstractFileImporter {

    private static final long serialVersionUID = 1L;

    private static final String MARKER = "meta-data.csv";

    private static final Log log = LogFactory.getLog(CSVZipImporter.class);

    public static ZipFile getArchiveFileIfValid(File file) throws IOException {
        ZipFile zip;

        try {
            zip = new ZipFile(file);
        } catch (ZipException e) {
            log.debug("file is not a zipfile ! ", e);
            return null;
        } catch (IOException e) {
            log.debug("can not open zipfile ! ", e);
            return null;
        }

        ZipEntry marker = zip.getEntry(MARKER);

        if (marker == null) {
            zip.close();
            return null;
        } else {
            return zip;
        }
    }

    @Override
    public DocumentModel create(CoreSession documentManager, Blob content, String path, boolean overwrite,
            String filename, TypeManager typeService) throws IOException {
        ZipFile zip = null;
        try (CloseableFile source = content.getCloseableFile()) {
            zip = getArchiveFileIfValid(source.getFile());
            if (zip == null) {
                return null;
            }

            DocumentModel container = documentManager.getDocument(new PathRef(path));

            ZipEntry index = zip.getEntry(MARKER);
            try (Reader reader = new InputStreamReader(zip.getInputStream(index));
                    CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT.withHeader());) {

                Map<String, Integer> header = csvParser.getHeaderMap();
                for (CSVRecord csvRecord : csvParser) {
                    String type = null;
                    String id = null;
                    Map<String, String> stringValues = new HashMap<>();
                    for (String headerValue : header.keySet()) {
                        String lineValue = csvRecord.get(headerValue);
                        if ("type".equalsIgnoreCase(headerValue)) {
                            type = lineValue;
                        } else if ("id".equalsIgnoreCase(headerValue)) {
                            id = lineValue;
                        } else {
                            stringValues.put(headerValue, lineValue);
                        }
                    }

                    boolean updateDoc = false;
                    // get doc for update
                    DocumentModel targetDoc = null;
                    if (id != null) {
                        // update ?
                        String targetPath = new Path(path).append(id).toString();
                        if (documentManager.exists(new PathRef(targetPath))) {
                            targetDoc = documentManager.getDocument(new PathRef(targetPath));
                            updateDoc = true;
                        }
                    }

                    // create doc if needed
                    if (targetDoc == null) {
                        if (type == null) {
                            log.error("Can not create doc without a type, skipping line");
                            continue;
                        }

                        if (id == null) {
                            id = IdUtils.generateStringId();
                        }
                        targetDoc = documentManager.createDocumentModel(path, id, type);
                    }

                    // update doc properties
                    DocumentType targetDocType = targetDoc.getDocumentType();
                    for (String fname : stringValues.keySet()) {

                        String stringValue = stringValues.get(fname);
                        Field field = null;
                        boolean usePrefix = false;
                        String schemaName = null;
                        String fieldName = null;

                        if (fname.contains(":")) {
                            if (targetDocType.hasField(fname)) {
                                field = targetDocType.getField(fname);
                                usePrefix = true;
                            }
                        } else if (fname.contains(".")) {
                            String[] parts = fname.split("\\.");
                            schemaName = parts[0];
                            fieldName = parts[1];
                            if (targetDocType.hasSchema(schemaName)) {
                                field = targetDocType.getField(fieldName);
                                usePrefix = false;
                            }
                        } else {
                            if (targetDocType.hasField(fname)) {
                                field = targetDocType.getField(fname);
                                usePrefix = false;
                                schemaName = field.getDeclaringType().getSchemaName();
                            }
                        }

                        if (field != null) {
                            Serializable fieldValue = getFieldValue(field, stringValue, zip);

                            if (fieldValue != null) {
                                if (usePrefix) {
                                    targetDoc.setPropertyValue(fname, fieldValue);
                                } else {
                                    targetDoc.setProperty(schemaName, fieldName, fieldValue);
                                }
                            }
                        }
                    }
                    if (updateDoc) {
                        documentManager.saveDocument(targetDoc);
                    } else {
                        documentManager.createDocument(targetDoc);
                    }
                }
            }
            return container;
        } finally {
            IOUtils.closeQuietly(zip);
        }
    }

    protected Serializable getFieldValue(Field field, String stringValue, ZipFile zip) {
        Serializable fieldValue = null;
        Type type = field.getType();
        if (type.isSimpleType()) {
            if (type instanceof SimpleTypeImpl) {
                // consider super type instead
                type = type.getSuperType();
            }
            if (type instanceof StringType) {
                fieldValue = stringValue;
            } else if (type instanceof IntegerType) {
                fieldValue = Integer.parseInt(stringValue);
            } else if (type instanceof LongType) {
                fieldValue = Long.parseLong(stringValue);
            } else if (type instanceof DateType) {
                try {
                    Date date;
                    if (stringValue.length() == 10) {
                        date = new SimpleDateFormat("dd/MM/yyyy").parse(stringValue);
                    } else if (stringValue.length() == 8) {
                        date = new SimpleDateFormat("dd/MM/yy").parse(stringValue);
                    } else {
                        log.warn("Unknown date format :" + stringValue);
                        return null;
                    }
                    fieldValue = date;
                } catch (ParseException e) {
                    log.error("Error during date parsing", e);
                }
            } else {
                log.warn(String.format("Unsupported field type '%s'", type));
                return null;
            }
        } else if (type.isComplexType()) {
            if (TypeConstants.CONTENT.equals(field.getName().getLocalName())) {
                ZipEntry blobIndex = zip.getEntry(stringValue);
                if (blobIndex != null) {
                    Blob blob;
                    try {
                        blob = Blobs.createBlob(zip.getInputStream(blobIndex));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                    blob.setFilename(stringValue);
                    fieldValue = (Serializable) blob;
                }
            }
        }

        return fieldValue;
    }

}