/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.camel.component.cmis; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.camel.Exchange; import org.apache.camel.Message; import org.apache.camel.NoSuchHeaderException; import org.apache.camel.RuntimeExchangeException; import org.apache.camel.impl.DefaultProducer; import org.apache.camel.util.ExchangeHelper; import org.apache.camel.util.MessageHelper; import org.apache.chemistry.opencmis.client.api.CmisObject; import org.apache.chemistry.opencmis.client.api.Document; import org.apache.chemistry.opencmis.client.api.Folder; 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.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The CMIS producer. */ public class CMISProducer extends DefaultProducer { private static final Logger LOG = LoggerFactory.getLogger(CMISProducer.class); private final CMISSessionFacadeFactory sessionFacadeFactory; private CMISSessionFacade sessionFacade; public CMISProducer(CMISEndpoint endpoint, CMISSessionFacadeFactory sessionFacadeFactory) { super(endpoint); this.sessionFacadeFactory = sessionFacadeFactory; this.sessionFacade = null; } @Override public CMISEndpoint getEndpoint() { return (CMISEndpoint) super.getEndpoint(); } public void process(Exchange exchange) throws Exception { CmisObject cmisObject = createNode(exchange); LOG.debug("Created node with id: {}", cmisObject.getId()); // copy the header of in message to the out message exchange.getOut().copyFrom(exchange.getIn()); exchange.getOut().setBody(cmisObject.getId()); } private Map<String, Object> filterTypeProperties(Map<String, Object> properties) throws Exception { Map<String, Object> result = new HashMap<>(properties.size()); String objectTypeName = CamelCMISConstants.CMIS_DOCUMENT; if (properties.containsKey(PropertyIds.OBJECT_TYPE_ID)) { objectTypeName = (String) properties.get(PropertyIds.OBJECT_TYPE_ID); } Set<String> types = new HashSet<>(); types.addAll(getSessionFacade().getPropertiesFor(objectTypeName)); if (getSessionFacade().supportsSecondaries() && properties.containsKey(PropertyIds.SECONDARY_OBJECT_TYPE_IDS)) { @SuppressWarnings("unchecked") Collection<String> secondaryTypes = (Collection<String>) properties.get(PropertyIds.SECONDARY_OBJECT_TYPE_IDS); for (String secondaryType : secondaryTypes) { types.addAll(getSessionFacade().getPropertiesFor(secondaryType)); } } for (Map.Entry<String, Object> entry : properties.entrySet()) { if (types.contains(entry.getKey())) { result.put(entry.getKey(), entry.getValue()); } } return result; } private CmisObject createNode(Exchange exchange) throws Exception { validateRequiredHeader(exchange, PropertyIds.NAME); Message message = exchange.getIn(); String parentFolderPath = parentFolderPathFor(message); Folder parentFolder = getFolderOnPath(exchange, parentFolderPath); Map<String, Object> cmisProperties = filterTypeProperties(message.getHeaders()); if (isDocument(exchange)) { String fileName = message.getHeader(PropertyIds.NAME, String.class); String mimeType = getMimeType(message); byte[] buf = getBodyData(message); ContentStream contentStream = getSessionFacade().createContentStream(fileName, buf, mimeType); return storeDocument(parentFolder, cmisProperties, contentStream); } else if (isFolder(message)) { return storeFolder(parentFolder, cmisProperties); } else { // other types return storeDocument(parentFolder, cmisProperties, null); } } private Folder getFolderOnPath(Exchange exchange, String path) throws Exception { try { return (Folder) getSessionFacade().getObjectByPath(path); } catch (CmisObjectNotFoundException e) { throw new RuntimeExchangeException("Path not found " + path, exchange, e); } } private String parentFolderPathFor(Message message) throws Exception { String customPath = message.getHeader(CamelCMISConstants.CMIS_FOLDER_PATH, String.class); if (customPath != null) { return customPath; } if (isFolder(message)) { String path = (String) message.getHeader(PropertyIds.PATH); String name = (String) message.getHeader(PropertyIds.NAME); if (path != null && path.length() > name.length()) { return path.substring(0, path.length() - name.length()); } } return "/"; } private boolean isFolder(Message message) throws Exception { String baseTypeId = message.getHeader(PropertyIds.OBJECT_TYPE_ID, String.class); if (baseTypeId != null) { return CamelCMISConstants.CMIS_FOLDER.equals(getSessionFacade().getCMISTypeFor(baseTypeId)); } return message.getBody() == null; } private Folder storeFolder(Folder parentFolder, Map<String, Object> cmisProperties) throws Exception { if (!cmisProperties.containsKey(PropertyIds.OBJECT_TYPE_ID)) { cmisProperties.put(PropertyIds.OBJECT_TYPE_ID, CamelCMISConstants.CMIS_FOLDER); } LOG.debug("Creating folder with properties: {}", cmisProperties); return parentFolder.createFolder(cmisProperties); } private Document storeDocument(Folder parentFolder, Map<String, Object> cmisProperties, ContentStream contentStream) throws Exception { if (!cmisProperties.containsKey(PropertyIds.OBJECT_TYPE_ID)) { cmisProperties.put(PropertyIds.OBJECT_TYPE_ID, CamelCMISConstants.CMIS_DOCUMENT); } VersioningState versioningState = VersioningState.NONE; if (getSessionFacade().isObjectTypeVersionable((String) cmisProperties.get(PropertyIds.OBJECT_TYPE_ID))) { versioningState = VersioningState.MAJOR; } LOG.debug("Creating document with properties: {}", cmisProperties); return parentFolder.createDocument(cmisProperties, contentStream, versioningState); } private void validateRequiredHeader(Exchange exchange, String name) throws NoSuchHeaderException { ExchangeHelper.getMandatoryHeader(exchange, name, String.class); } private boolean isDocument(Exchange exchange) throws Exception { String baseTypeId = exchange.getIn().getHeader(PropertyIds.OBJECT_TYPE_ID, String.class); if (baseTypeId != null) { return CamelCMISConstants.CMIS_DOCUMENT.equals(getSessionFacade().getCMISTypeFor(baseTypeId)); } return exchange.getIn().getBody() != null; } private byte[] getBodyData(Message message) { return message.getBody(byte[].class); } private String getMimeType(Message message) throws NoSuchHeaderException { String mimeType = message.getHeader(PropertyIds.CONTENT_STREAM_MIME_TYPE, String.class); if (mimeType == null) { mimeType = MessageHelper.getContentType(message); } return mimeType; } private CMISSessionFacade getSessionFacade() throws Exception { if (sessionFacade == null) { sessionFacade = sessionFacadeFactory.create(getEndpoint()); sessionFacade.initSession(); } return sessionFacade; } }