org.betaconceptframework.astroboa.engine.jcr.util.BinaryChannelUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.betaconceptframework.astroboa.engine.jcr.util.BinaryChannelUtils.java

Source

/*
 * Copyright (C) 2005-2012 BetaCONCEPT Limited
 *
 * This file is part of Astroboa.
 *
 * Astroboa is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Astroboa is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Astroboa.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.betaconceptframework.astroboa.engine.jcr.util;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.ValueFactory;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.betaconceptframework.astroboa.api.model.BinaryChannel;
import org.betaconceptframework.astroboa.api.model.ValueType;
import org.betaconceptframework.astroboa.api.model.exception.CmsException;
import org.betaconceptframework.astroboa.context.AstroboaClientContextHolder;
import org.betaconceptframework.astroboa.context.RepositoryContext;
import org.betaconceptframework.astroboa.model.impl.BinaryChannelImpl;
import org.betaconceptframework.astroboa.model.impl.SaveMode;
import org.betaconceptframework.astroboa.model.impl.item.CmsBuiltInItem;
import org.betaconceptframework.astroboa.model.impl.item.JcrBuiltInItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 
 * @author Gregory Chomatas (gchomatas@betaconcept.com)
 * @author Savvas Triantafyllou (striantafyllou@betaconcept.com)
 *
 */
public class BinaryChannelUtils {

    private final Logger logger = LoggerFactory.getLogger(BinaryChannelUtils.class);

    @Autowired
    private CmsRepositoryEntityUtils cmsRepositoryEntityUtils;

    private final static Pattern Astroboa_Resource_Api_Pattern = Pattern.compile("http://.*?/resource-api/.*");

    public void populateBinaryChannelToNode(BinaryChannel binaryChannel, Node binaryParentNode, Session session,
            SaveMode saveMode, Context context, boolean binaryContentIsNew) throws Exception {
        if (binaryChannel == null) {
            throw new CmsException("No BinaryChannel to populate");
        }

        if (binaryParentNode == null) {
            throw new CmsException("No parent node of binary channel is provided");
        }

        final String name = binaryChannel.getName();
        if (name == null) {
            throw new CmsException("BinaryChannel name not found");
        }

        try {
            Node binaryChannelNode;
            if (binaryChannel.getId() != null) {
                binaryChannelNode = context.retrieveNodeForBinaryChannel(binaryChannel.getId());

                if (binaryChannelNode == null) {
                    //User has specified an id for binary channel
                    binaryChannelNode = createNewBinaryChannelNode(binaryChannel, binaryParentNode, name, true);
                }

                //Check that binaryChannelNode has the proper parent
                if (!binaryChannelNode.getParent().getIdentifier().equals(binaryParentNode.getIdentifier())) {
                    throw new CmsException("Binary channel node " + binaryChannelNode.getPath()
                            + " does not belong to parent node " + binaryParentNode.getPath());
                }
            } else {
                binaryChannelNode = createNewBinaryChannelNode(binaryChannel, binaryParentNode, name, false);
            }

            //Get content from external location if necessary
            loadContentFromExternalLocation(context, binaryChannel);

            populateNodeWithBinary(saveMode, binaryChannel, binaryChannelNode, session, binaryContentIsNew);

        } catch (RepositoryException e) {
            throw new CmsException(e);
        }
    }

    public void loadContentFromExternalLocation(Context context, BinaryChannel binaryChannel) {

        String externalLocationOfTheContent = ((BinaryChannelImpl) binaryChannel).getExternalLocationOfTheContent();

        if (!binaryChannel.isNewContentLoaded() && StringUtils.isNotBlank(externalLocationOfTheContent)) {

            //Check context first
            byte[] content = context.getBinaryContentForKey(externalLocationOfTheContent);

            //try to download
            if (content == null) {
                InputStream inputStream = null;
                try {
                    URL urlResource = new URL(externalLocationOfTheContent);

                    if (Astroboa_Resource_Api_Pattern.matcher(externalLocationOfTheContent).matches()
                            && context.getImportConfiguration() != null
                            && context.getImportConfiguration()
                                    .credentialsOfUserWhoHasAccessToBinaryContent() != null
                            && context.getImportConfiguration().credentialsOfUserWhoHasAccessToBinaryContent()
                                    .getUsername() != null
                            && context.getImportConfiguration().credentialsOfUserWhoHasAccessToBinaryContent()
                                    .getPassword() != null) {

                        String username = context.getImportConfiguration()
                                .credentialsOfUserWhoHasAccessToBinaryContent().getUsername();
                        String password = context.getImportConfiguration()
                                .credentialsOfUserWhoHasAccessToBinaryContent().getPassword();

                        URLConnection uc = urlResource.openConnection();
                        uc.setRequestProperty("Authorization", "Basic "
                                + new String(Base64.encodeBase64(((username + ":" + password).getBytes()))));
                        inputStream = (InputStream) uc.getInputStream();

                    } else {
                        inputStream = urlResource.openStream();
                    }

                    binaryChannel.setContent(IOUtils.toByteArray(inputStream));

                } catch (Throwable e) {
                    //Log exception but continue with unmarshaling
                    //BinaryChannle will be created without content
                    logger.warn("Invalid external location " + externalLocationOfTheContent
                            + " of the content for binary channel " + binaryChannel.getName(), e);
                } finally {
                    if (inputStream != null) {
                        IOUtils.closeQuietly(inputStream);
                    }
                }
            } else {
                binaryChannel.setContent(content);
            }
        }
    }

    private Node createNewBinaryChannelNode(BinaryChannel binaryChannel, Node binaryParentNode, final String name,
            boolean useProvidedId) throws RepositoryException {

        Node binaryChannelNode = JcrNodeUtils.addBinaryChannelNode(binaryParentNode, name);

        cmsRepositoryEntityUtils.createCmsIdentifier(binaryChannelNode, binaryChannel, useProvidedId);

        return binaryChannelNode;
    }

    private void populateNodeWithBinary(SaveMode saveMode, BinaryChannel binaryChannel, Node binaryChannelNode,
            Session session, boolean binaryContentIsNew) throws Exception {

        ValueFactory valueFactory = session.getValueFactory();

        JcrNodeUtils.addSimpleProperty(saveMode, binaryChannelNode, CmsBuiltInItem.SourceFileName,
                binaryChannel.getSourceFilename(), valueFactory, ValueType.String);

        JcrNodeUtils.addSimpleProperty(saveMode, binaryChannelNode, CmsBuiltInItem.Name, binaryChannel.getName(),
                valueFactory, ValueType.String);

        JcrNodeUtils.addSimpleProperty(saveMode, binaryChannelNode, CmsBuiltInItem.Size, binaryChannel.getSize(),
                valueFactory, ValueType.Long);

        populateBinaryData(saveMode, binaryChannel, binaryChannelNode, session, binaryContentIsNew);

    }

    private void populateBinaryData(SaveMode saveMode, BinaryChannel binaryChannel, Node binaryChannelNode,
            Session session, boolean binaryContentIsNew) throws Exception {

        ValueFactory valueFactory = session.getValueFactory();

        JcrNodeUtils.addSimpleProperty(saveMode, binaryChannelNode, JcrBuiltInItem.JcrEncoding,
                binaryChannel.getEncoding(), valueFactory, ValueType.String);

        JcrNodeUtils.addSimpleProperty(saveMode, binaryChannelNode, JcrBuiltInItem.JcrMimeType,
                binaryChannel.getMimeType(), valueFactory, ValueType.String);

        //Update binary data only if value is new
        if (binaryContentIsNew) {
            JcrNodeUtils.addBinaryProperty(saveMode, binaryChannelNode, JcrBuiltInItem.JcrData,
                    binaryChannel.getContent(), valueFactory);
        }

        JcrNodeUtils.addSimpleProperty(saveMode, binaryChannelNode, JcrBuiltInItem.JcrLastModified,
                binaryChannel.getModified(), valueFactory, ValueType.Date);
    }

    public void deleteBinaryChannelNode(Node contentNode, String binaryChannelName) throws RepositoryException {
        if (contentNode != null && contentNode.hasNode(binaryChannelName)) {
            NodeIterator binaryDataNodes = contentNode.getNodes(binaryChannelName);

            while (binaryDataNodes.hasNext()) {
                Node nextNode = binaryDataNodes.nextNode();
                nextNode.remove();
            }
        }
    }

    public Map<String, Node> partitionBinaryChannelNodeWithTheSameNamePerId(Node contentObjectNode,
            String binaryChannelName) throws RepositoryException {
        Map<String, Node> binaryChannelNodes = new HashMap<String, Node>();
        if (contentObjectNode != null && contentObjectNode.hasNodes()) {
            NodeIterator contentObjectChildNodes = contentObjectNode.getNodes(binaryChannelName);
            while (contentObjectChildNodes.hasNext()) {
                Node child = contentObjectChildNodes.nextNode();
                if (child.isNodeType(CmsBuiltInItem.BinaryChannel.getJcrName())
                        && child.hasProperty(CmsBuiltInItem.CmsIdentifier.getJcrName()))
                    binaryChannelNodes.put(cmsRepositoryEntityUtils.getCmsIdentifier(child), child);
            }
        }

        return binaryChannelNodes;
    }

    public void addRepositoryIdToBinaryChannel(String binaryChannelNameOrPath, BinaryChannel binaryChannel)
            throws RepositoryException {
        RepositoryContext repositoryContext = AstroboaClientContextHolder.getRepositoryContextForActiveClient();
        if (repositoryContext == null || repositoryContext.getCmsRepository() == null
                || StringUtils.isBlank(repositoryContext.getCmsRepository().getId())) {
            logger.warn("Could not find connected repostiory id while creating path for binary channel "
                    + binaryChannelNameOrPath);
        } else {
            ((BinaryChannelImpl) binaryChannel).setRepositoryId(repositoryContext.getCmsRepository().getId());
        }
    }
}