fr.acxio.tools.agia.cmis.CmisWriter.java Source code

Java tutorial

Introduction

Here is the source code for fr.acxio.tools.agia.cmis.CmisWriter.java

Source

package fr.acxio.tools.agia.cmis;

/*
 * Copyright 2014 Acxio
 * 
 * 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.
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.alfresco.webservice.util.ISO9075;
import org.alfresco.webservice.util.Constants;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.chemistry.opencmis.client.api.OperationContext;
import org.apache.chemistry.opencmis.commons.PropertyIds;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.chemistry.opencmis.commons.enums.VersioningState;
import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamWriter;

import fr.acxio.tools.agia.alfresco.domain.Document;
import fr.acxio.tools.agia.alfresco.domain.Folder;
import fr.acxio.tools.agia.alfresco.domain.Node;
import fr.acxio.tools.agia.alfresco.domain.NodeList;
import fr.acxio.tools.agia.alfresco.domain.Property;

public class CmisWriter implements ItemStreamWriter<NodeList> {

    private CmisService cmisService;
    private OperationContext operationContext;
    private Set<String> existingPaths = new HashSet<String>();

    public void setCmisService(CmisService sCmisService) {
        cmisService = sCmisService;
    }

    public void setOperationContext(OperationContext sOperationContext) {
        operationContext = sOperationContext;
    }

    @Override
    public void open(ExecutionContext sExecutionContext) throws ItemStreamException {
        cmisService.startSession();
    }

    @Override
    public void update(ExecutionContext sExecutionContext) throws ItemStreamException {
        // TODO Auto-generated method stub

    }

    @Override
    public void close() throws ItemStreamException {
        cmisService.endSession();
        existingPaths.clear();
    }

    @Override
    public void write(List<? extends NodeList> sItems) throws Exception {
        if (!sItems.isEmpty()) {
            String aCurrentNodePath;

            for (NodeList aNodeList : sItems) {
                for (Node aNode : aNodeList) {
                    aCurrentNodePath = ISO9075.decode(aNode.getPath().replaceAll("[^:/]*:", "")); // Strip
                                                                                                  // namespaces

                    if (!existingPaths.contains(aCurrentNodePath)) {
                        createOrUpdateNode(aCurrentNodePath, aNode);
                        existingPaths.add(aCurrentNodePath);
                    }
                }
            }
        }
    }

    private void createOrUpdateNode(String sCurrentNodePath, Node sNode) throws IOException {
        CmisObject aExistingObject = null;
        try {
            aExistingObject = cmisService.getSession().getObjectByPath(sCurrentNodePath, operationContext);
        } catch (CmisObjectNotFoundException e) {
            aExistingObject = null;
        }

        if (aExistingObject != null) {
            updateNode(aExistingObject, sCurrentNodePath, sNode);
        } else {
            createNewNode(sCurrentNodePath, sNode);
        }
    }

    private void updateNode(CmisObject sExistingObject, String sCurrentNodePath, Node sNode) throws IOException {
        Map<String, Object> aProperties = getProperties(sNode);
        if (sNode instanceof Document) {
            sExistingObject.updateProperties(aProperties);
            ContentStream contentStream = createStreamForNode((Document) sNode);
            ((org.apache.chemistry.opencmis.client.api.Document) sExistingObject).setContentStream(contentStream,
                    true);

            ((ContentStreamImpl) contentStream).getStream().close();
        }
    }

    private void createNewNode(String sCurrentNodePath, Node sNode) throws IOException {
        org.apache.chemistry.opencmis.client.api.Folder aParent = getParent(sCurrentNodePath);
        Map<String, Object> aProperties = getProperties(sNode);
        if (sNode instanceof Document) {
            ContentStream contentStream = createStreamForNode((Document) sNode);
            aParent.createDocument(aProperties, contentStream, VersioningState.MAJOR);

            ((ContentStreamImpl) contentStream).getStream().close();
        } else if (sNode instanceof Folder) {
            aParent.createFolder(aProperties);
        }
    }

    private org.apache.chemistry.opencmis.client.api.Folder getParent(String sNodePath) {
        String aParentPath = sNodePath.substring(0, sNodePath.lastIndexOf("/"));
        org.apache.chemistry.opencmis.client.api.Folder aParent = (org.apache.chemistry.opencmis.client.api.Folder) cmisService
                .getSession().getObjectByPath(aParentPath, operationContext);
        if (aParent == null) {
            aParent = cmisService.getSession().getRootFolder();
        }
        return aParent;
    }

    private Map<String, Object> getProperties(Node sNode) {
        Map<String, Object> aResult = new HashMap<String, Object>();
        List<Property> aProperties = sNode.getProperties();

        String aNodeType = (sNode.getType() == null)
                ? ((sNode instanceof Document) ? "cmis:document" : "cmis:folder")
                : sNode.getType().toString();
        if (Constants.TYPE_CONTENT.equals(aNodeType)) {
            aNodeType = "cmis:document";
        } else if (Constants.TYPE_FOLDER.equals(aNodeType)) {
            aNodeType = "cmis:folder";
        } else {
            aNodeType = sNode.getType().getLocalName();
        }
        aResult.put(PropertyIds.OBJECT_TYPE_ID, aNodeType);

        List<String> aPropValues;
        String aPropName;
        for (Property aProperty : aProperties) {
            aPropValues = aProperty.getValues();
            aPropName = aProperty.getName().getShortName();
            if (Constants.PROP_NAME.equals(aProperty.getName().toString())) {
                aPropName = "cmis:name";
            }
            if (aPropValues.size() > 1) {
                aResult.put(aPropName, scanValues(aPropValues));
            } else if (aPropValues.size() == 1) {
                aResult.put(aPropName, scanValue(aPropValues.get(0)));
            }
        }
        return aResult;
    }

    private ContentStream createStreamForNode(Document sDocument) throws IOException {
        ContentStream aResult = null;
        if ((sDocument.getContentPath() != null) && (sDocument.getContentPath().length() > 0)) {
            File aFile = new File(sDocument.getContentPath());
            if (aFile.exists() && aFile.isFile()) {
                FileInputStream aInputStream = new FileInputStream(aFile);
                aResult = new ContentStreamImpl(aFile.getName(), BigInteger.valueOf(aFile.length()),
                        sDocument.getMimeType(), aInputStream);
            } else {
                throw new IOException("Cannot find content file: " + sDocument.getContentPath());
            }
        }
        return aResult;
    }

    private Object scanValue(String sValue) {
        Object aResult = sValue;
        if (sValue.startsWith("%")) {
            String aFormatString = sValue.substring(1, sValue.indexOf("%", 1));
            String aValue = sValue.substring(2 + aFormatString.length());
            if ("B".equals(aFormatString)) {
                aResult = Boolean.valueOf(aValue);
            } else if ("D".equals(aFormatString)) {
                aResult = Long.valueOf(aValue);
            } else if ("F".equals(aFormatString)) {
                aResult = Double.valueOf(aValue);
            } else if (aFormatString.startsWith("T")) {
                DateTimeFormatter aFormatter = DateTimeFormat.forPattern(aFormatString.substring(1));
                aResult = aFormatter.parseDateTime(aValue).toDate();
            }
        }
        return aResult;
    }

    private List<Object> scanValues(List<String> sValues) {
        List<Object> aResult = null;
        if (sValues != null) {
            aResult = new ArrayList<Object>(sValues.size());
            for (String aValue : sValues) {
                aResult.add(scanValue(aValue));
            }
        }
        return aResult;
    }
}