org.jbpm.integration.cmis.impl.OpenCMISPlaceholderResolverStrategy.java Source code

Java tutorial

Introduction

Here is the source code for org.jbpm.integration.cmis.impl.OpenCMISPlaceholderResolverStrategy.java

Source

/*
 * Copyright 2014 JBoss Inc
 *
 * 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 org.jbpm.integration.cmis.impl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;

import org.apache.chemistry.opencmis.client.api.Folder;
import org.apache.chemistry.opencmis.client.api.Session;
import org.apache.chemistry.opencmis.commons.data.ContentStream;
import org.apache.commons.io.IOUtils;
import org.drools.core.common.DroolsObjectInputStream;
import org.jbpm.document.Document;
import org.jbpm.integration.cmis.UpdateMode;
import org.kie.api.marshalling.ObjectMarshallingStrategy;

/**
 * ObjectMarshallingStrategy implementation for storing and retrieving data from CMIS compatible systems.
 * It will act only on variables that are of type <code>Document</code>
 * It allows to specify connection details to the repository
 * <ul>
 *    <li>user</li>
 *    <li>password</li>
 *    <li>url</li>
 *    <li>repository</li>
 * </ul>
 * and uses ATOM binding to connect and interact with CMIS. On top of that update mode can also be selected - override,
 *  new major version, new minor version on update. By default override mode is used if none is specified. 
 * <br/>
 * Interaction with CMIS can be done with one of the following ways:
 * <ul>
 *    <li>create new document based on variable - to do so Document variable should have null objectId and must have content</li>
 *    <li>update document based on variable - to do so Document variable must have objectId set and must have content</li>
 *    <li>read document from CMIS - to do so Document variable must have only objectId set and other fields left empty</li>
 * </ul>
 * Every time a document is updated it might get new objectId and thus it will be set upon such operations.
 *
 * @see Document
 */
public class OpenCMISPlaceholderResolverStrategy extends OpenCMISSupport implements ObjectMarshallingStrategy {

    private String user;
    private String password;
    private String url;
    private String repository;
    private String contentUrl;
    private UpdateMode mode = UpdateMode.OVERRIDE;

    public OpenCMISPlaceholderResolverStrategy(String user, String password, String url, String repository) {
        this.user = user;
        this.password = password;
        this.url = url;
        this.repository = repository;
    }

    public OpenCMISPlaceholderResolverStrategy(String user, String password, String url, String repository,
            UpdateMode mode) {
        this.user = user;
        this.password = password;
        this.url = url;
        this.repository = repository;
        this.mode = mode;
    }

    public OpenCMISPlaceholderResolverStrategy(String user, String password, String url, String repository,
            String contentUrl) {
        this.user = user;
        this.password = password;
        this.url = url;
        this.repository = repository;
        this.contentUrl = contentUrl;
    }

    public OpenCMISPlaceholderResolverStrategy(String user, String password, String url, String repository,
            String contentUrl, UpdateMode mode) {
        this.user = user;
        this.password = password;
        this.url = url;
        this.repository = repository;
        this.contentUrl = contentUrl;
        this.mode = mode;
    }

    public boolean accept(Object object) {
        if (object instanceof Document) {
            return true;
        }
        return false;
    }

    public byte[] marshal(Context context, ObjectOutputStream os, Object object) throws IOException {
        Document document = (Document) object;
        Session session = getRepositorySession(user, password, url, repository);
        try {
            if (document.getContent() != null) {
                String type = getType(document);
                if (document.getIdentifier() == null || document.getIdentifier().isEmpty()) {
                    String location = getLocation(document);

                    Folder parent = findFolderForPath(session, location);
                    if (parent == null) {
                        parent = createFolder(session, null, location);
                    }
                    org.apache.chemistry.opencmis.client.api.Document doc = createDocument(session, parent,
                            document.getName(), type, document.getContent());
                    document.setIdentifier(doc.getId());
                    document.addAttribute("updated", "true");
                } else {
                    if (document.getContent() != null && "true".equals(document.getAttribute("updated"))) {
                        org.apache.chemistry.opencmis.client.api.Document doc = updateDocument(session,
                                document.getIdentifier(), type, document.getContent(), mode);

                        document.setIdentifier(doc.getId());
                        document.addAttribute("updated", "false");
                    }
                }
            }
            ByteArrayOutputStream buff = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(buff);
            oos.writeUTF(document.getIdentifier());
            oos.writeUTF(object.getClass().getCanonicalName());
            oos.close();
            return buff.toByteArray();
        } finally {
            session.clear();
        }
    }

    public Object unmarshal(Context context, ObjectInputStream ois, byte[] object, ClassLoader classloader)
            throws IOException, ClassNotFoundException {
        DroolsObjectInputStream is = new DroolsObjectInputStream(new ByteArrayInputStream(object), classloader);
        String objectId = is.readUTF();
        String canonicalName = is.readUTF();
        Session session = getRepositorySession(user, password, url, repository);
        try {
            org.apache.chemistry.opencmis.client.api.Document doc = (org.apache.chemistry.opencmis.client.api.Document) findObjectForId(
                    session, objectId);
            Document document = (Document) Class.forName(canonicalName).newInstance();
            document.setAttributes(new HashMap<String, String>());

            document.setIdentifier(objectId);
            document.setName(doc.getName());
            document.setLastModified(doc.getLastModificationDate().getTime());
            document.setSize(doc.getContentStreamLength());
            document.addAttribute("location", getFolderName(doc.getParents()) + getPathAsString(doc.getPaths()));
            if (doc.getContentStream() != null && contentUrl == null) {
                ContentStream stream = doc.getContentStream();
                document.setContent(IOUtils.toByteArray(stream.getStream()));
                document.addAttribute("updated", "false");
                document.addAttribute("type", stream.getMimeType());
            } else {
                document.setLink(contentUrl + document.getIdentifier());
            }
            return document;
        } catch (Exception e) {
            throw new RuntimeException("Cannot read document from CMIS", e);
        } finally {
            is.close();
            session.clear();
        }
    }

    public Context createContext() {
        return null;
    }

    /*
     * for backward compatibility with previous serialization mechanism - before protobuf was used
     * (non-Javadoc)
     * @see org.kie.api.marshalling.ObjectMarshallingStrategy#write(java.io.ObjectOutputStream, java.lang.Object)
     * @see org.kie.api.marshalling.ObjectMarshallingStrategy#read(java.io.ObjectOutputStream)
     */

    public void write(ObjectOutputStream os, Object object) throws IOException {
        Document document = (Document) object;
        Session session = getRepositorySession(user, password, url, repository);
        try {
            if (document.getContent() != null) {
                String type = document.getAttribute("type");
                if (document.getIdentifier() == null) {
                    String location = document.getAttribute("location");

                    Folder parent = findFolderForPath(session, location);
                    if (parent == null) {
                        parent = createFolder(session, null, location);
                    }
                    org.apache.chemistry.opencmis.client.api.Document doc = createDocument(session, parent,
                            document.getName(), type, document.getContent());
                    document.setIdentifier(doc.getId());
                    document.addAttribute("updated", "false");
                } else {
                    if (document.getContent() != null && "true".equals(document.getAttribute("updated"))) {
                        org.apache.chemistry.opencmis.client.api.Document doc = updateDocument(session,
                                document.getIdentifier(), type, document.getContent(), mode);

                        document.setIdentifier(doc.getId());
                        document.addAttribute("updated", "false");
                    }
                }
            }
            ByteArrayOutputStream buff = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(buff);
            oos.writeUTF(document.getIdentifier());
            oos.writeUTF(object.getClass().getCanonicalName());
            oos.close();
        } finally {
            session.clear();
        }
    }

    public Object read(ObjectInputStream os) throws IOException, ClassNotFoundException {
        String objectId = os.readUTF();
        String canonicalName = os.readUTF();
        Session session = getRepositorySession(user, password, url, repository);
        try {
            org.apache.chemistry.opencmis.client.api.Document doc = (org.apache.chemistry.opencmis.client.api.Document) findObjectForId(
                    session, objectId);
            Document document = (Document) Class.forName(canonicalName).newInstance();

            document.setIdentifier(objectId);
            document.setName(doc.getName());
            document.addAttribute("location", getFolderName(doc.getParents()) + getPathAsString(doc.getPaths()));
            if (doc.getContentStream() != null) {
                ContentStream stream = doc.getContentStream();
                document.setContent(IOUtils.toByteArray(stream.getStream()));
                document.addAttribute("updated", "false");
                document.addAttribute("type", stream.getMimeType());
            }
            return document;
        } catch (Exception e) {
            throw new RuntimeException("Cannot read document from CMIS", e);
        } finally {
            session.clear();
        }
    }

}