org.betaconceptframework.astroboa.engine.jcr.renderer.ContentObjectFolderRenderer.java Source code

Java tutorial

Introduction

Here is the source code for org.betaconceptframework.astroboa.engine.jcr.renderer.ContentObjectFolderRenderer.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.renderer;

import java.util.Locale;

import javax.jcr.AccessDeniedException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.util.ISO9075;
import org.betaconceptframework.astroboa.api.model.ContentObjectFolder;
import org.betaconceptframework.astroboa.api.model.ContentObjectFolder.Type;
import org.betaconceptframework.astroboa.api.model.definition.ContentObjectTypeDefinition;
import org.betaconceptframework.astroboa.engine.jcr.dao.ContentDefinitionDao;
import org.betaconceptframework.astroboa.engine.jcr.query.CmsQueryHandler;
import org.betaconceptframework.astroboa.engine.jcr.query.CmsQueryResult;
import org.betaconceptframework.astroboa.engine.jcr.util.CmsRepositoryEntityUtils;
import org.betaconceptframework.astroboa.model.impl.ContentObjectFolderImpl;
import org.betaconceptframework.astroboa.model.impl.item.CmsBuiltInItem;
import org.betaconceptframework.astroboa.model.impl.query.xpath.XPathUtils;
import org.betaconceptframework.astroboa.util.CmsConstants;
import org.betaconceptframework.astroboa.util.CmsUtils;
import org.betaconceptframework.astroboa.util.TreeDepth;
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 ContentObjectFolderRenderer {

    @Autowired
    private ContentDefinitionDao contentDefinitionDao;
    @Autowired
    private CmsRepositoryEntityUtils cmsRepositoryEntityUtils;

    @Autowired
    private CmsQueryHandler cmsQueryHandler;

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

    public ContentObjectFolder render(Session session, Node contentObjectFolderNode, int depth,
            boolean renderContentObjectIds, String locale) throws Exception {

        ContentObjectFolder contentObjectFolder = new ContentObjectFolderImpl();

        contentObjectFolder.setId(contentObjectFolderNode.getIdentifier());
        contentObjectFolder.setType(renderType(contentObjectFolderNode));
        ((ContentObjectFolderImpl) contentObjectFolder)
                .setFullPath(getFullPath(contentObjectFolderNode, contentObjectFolder.getType()));

        final String name = contentObjectFolderNode.getName();
        if (contentObjectFolder.getType() == ContentObjectFolder.Type.CONTENT_TYPE) {
            //Extract type from node name
            String typeName = StringUtils.remove(name, CmsConstants.TYPE_FOLDER);

            contentObjectFolder.setName(typeName);

            //Search for definition for this type and get localized label
            ContentObjectTypeDefinition typeDefinition = contentDefinitionDao
                    .getContentObjectTypeDefinition(typeName);

            if (typeDefinition == null) {
                logger.warn("Unable to render localized label for content object folder {} for type {}", name,
                        typeName);
                contentObjectFolder.setLocalizedLabelForCurrentLocale(name);
            } else {
                if (StringUtils.isBlank(locale)) {
                    locale = Locale.ENGLISH.toString();
                }

                contentObjectFolder.setLocalizedLabelForCurrentLocale(
                        typeDefinition.getDisplayName().getLocalizedLabelForLocale(locale));
            }
        } else {
            String label = name;

            if ((contentObjectFolder.getType() == ContentObjectFolder.Type.DAY
                    || contentObjectFolder.getType() == ContentObjectFolder.Type.HOUR
                    || contentObjectFolder.getType() == ContentObjectFolder.Type.MINUTE
                    || contentObjectFolder.getType() == ContentObjectFolder.Type.SECOND) && label != null
                    && label.length() == 1) {
                label = "0" + label;
            }

            contentObjectFolder.setLocalizedLabelForCurrentLocale(name);
            contentObjectFolder.setName(name);
        }

        final int nextDepth = CmsUtils.getNextDepth(depth);

        if (contentObjectFolder.getType() == ContentObjectFolder.Type.CONTENT_TYPE
                || contentObjectFolder.getType() == ContentObjectFolder.Type.YEAR
                || contentObjectFolder.getType() == ContentObjectFolder.Type.MONTH
                || contentObjectFolder.getType() == ContentObjectFolder.Type.HOUR
                || contentObjectFolder.getType() == ContentObjectFolder.Type.MINUTE) {

            contentObjectFolder.setNumberOfContentObjects(0);

            if (depth != TreeDepth.ZERO.asInt()) {
                //Render children
                NodeIterator subFolders = contentObjectFolderNode.getNodes();
                while (subFolders.hasNext()) {
                    Node subFolderNode = subFolders.nextNode();

                    if (getFolderType(subFolderNode) != null)
                        contentObjectFolder.addSubFolder(
                                render(session, subFolderNode, nextDepth, renderContentObjectIds, locale));
                }
            }
        } else if (contentObjectFolder.getType() == ContentObjectFolder.Type.DAY
                || contentObjectFolder.getType() == ContentObjectFolder.Type.SECOND) {

            //Backwards compatibility. DAY may contain content object nodes as well thus we need to make a query in order
            //to retrieve all content object child nodes

            //Perform a query to load all nodes representing content object nodes
            String contentObjectFolderPathCriterion = ISO9075.encodePath(contentObjectFolderNode.getPath())
                    .replaceFirst("/", "");

            String contentObjectNodeQuery = XPathUtils.createXPathSelect(contentObjectFolderPathCriterion, null,
                    CmsBuiltInItem.StructuredContentObject, true);

            //If we do not want to render content object ids then we are only interested in their number
            int limit = renderContentObjectIds ? -1 : 0;

            CmsQueryResult contentObjectNodes = cmsQueryHandler.getNodesFromXPathQuery(session,
                    contentObjectNodeQuery, 0, limit);

            contentObjectFolder.setNumberOfContentObjects(contentObjectNodes.getTotalRowCount());

            if (renderContentObjectIds) {
                //Iterate over the nodes in order to retrieve content object ids
                NodeIterator childNodes = contentObjectNodes.getNodeIterator();
                while (childNodes.hasNext()) {

                    Node childNode = childNodes.nextNode();
                    contentObjectFolder.addContentObjectId(cmsRepositoryEntityUtils.getCmsIdentifier(childNode));
                }
            }

            //Finally, if folder is a DAY folder and depth is > 0
            //then load its subfolders
            if (contentObjectFolder.getType() == ContentObjectFolder.Type.DAY && depth != TreeDepth.ZERO.asInt()) {

                //We need to make a query to distinguish nodes, as DAY folder node may have content object nodes (version 2.x.x)
                //or hour folder nodes (version 3.x.x). In cases where both type of nodes exists then repository has been migrated from version 
                //2.x.x to 3.x.x
                String hourFolderNodeQuery = XPathUtils.createXPathSelect(contentObjectFolderPathCriterion, null,
                        CmsBuiltInItem.GenericHourFolder, true);

                CmsQueryResult hourFolderNodes = cmsQueryHandler.getNodesFromXPathQuery(session,
                        hourFolderNodeQuery, 0, -1);

                NodeIterator subFolderNodes = hourFolderNodes.getNodeIterator();

                while (subFolderNodes.hasNext()) {
                    contentObjectFolder.addSubFolder(
                            render(session, subFolderNodes.nextNode(), nextDepth, renderContentObjectIds, locale));
                }
            }

        }

        return contentObjectFolder;

    }

    private String getFullPath(Node contentObjectFolderNode, Type type) throws RepositoryException {

        if (type == null) {
            return "";
        }

        switch (type) {
        case CONTENT_TYPE:
        case YEAR:
            return contentObjectFolderNode.getName();
        case MONTH:
        case DAY:
        case HOUR:
        case MINUTE:
        case SECOND:
            //locate contentTypeFolder folder
            Node contentTypeFolder = contentObjectFolderNode.getParent();

            while (contentTypeFolder != null
                    && !contentTypeFolder.isNodeType(CmsBuiltInItem.GenericContentTypeFolder.getJcrName())) {
                contentTypeFolder = contentTypeFolder.getParent();
            }

            if (contentTypeFolder == null) {
                return contentObjectFolderNode.getName();
            }

            String path = StringUtils.remove(contentObjectFolderNode.getPath(), contentTypeFolder.getPath());

            if (path != null && path.startsWith("/")) {
                return StringUtils.removeStart(path, "/");
            }

            return path;

        default:
            break;
        }

        if (Type.MONTH == type) {
            return getMonthName(contentObjectFolderNode) + "/" + contentObjectFolderNode.getName();
        } else if (Type.DAY == type) {
            return getDayPath(contentObjectFolderNode) + "/" + getMonthName(contentObjectFolderNode) + "/"
                    + contentObjectFolderNode.getName();
        } else if (Type.HOUR == type) {
            return getHourPath(contentObjectFolderNode) + "/" + getDayPath(contentObjectFolderNode) + "/"
                    + getMonthName(contentObjectFolderNode) + "/" + contentObjectFolderNode.getName();
        } else if (Type.MINUTE == type) {
            return getMinutePath(contentObjectFolderNode) + "/" + getHourPath(contentObjectFolderNode) + "/"
                    + getDayPath(contentObjectFolderNode) + "/" + getMonthName(contentObjectFolderNode) + "/"
                    + contentObjectFolderNode.getName();
        } else if (Type.SECOND == type) {
            return contentObjectFolderNode.getParent().getParent().getParent().getParent().getParent().getName()
                    + "/" + getMinutePath(contentObjectFolderNode) + "/" + getHourPath(contentObjectFolderNode)
                    + "/" + getDayPath(contentObjectFolderNode) + "/" + getMonthName(contentObjectFolderNode) + "/"
                    + contentObjectFolderNode.getName();
        }

        // Type.YEAR == type || Type.CONTENT_TYPE == type
        return contentObjectFolderNode.getName();
    }

    private String getMinutePath(Node contentObjectFolderNode)
            throws RepositoryException, ItemNotFoundException, AccessDeniedException {
        return contentObjectFolderNode.getParent().getParent().getParent().getParent().getName();
    }

    private String getHourPath(Node contentObjectFolderNode)
            throws RepositoryException, ItemNotFoundException, AccessDeniedException {
        return contentObjectFolderNode.getParent().getParent().getParent().getName();
    }

    private String getDayPath(Node contentObjectFolderNode)
            throws RepositoryException, ItemNotFoundException, AccessDeniedException {
        return contentObjectFolderNode.getParent().getParent().getName();
    }

    private String getMonthName(Node contentObjectFolderNode)
            throws RepositoryException, ItemNotFoundException, AccessDeniedException {
        return contentObjectFolderNode.getParent().getName();
    }

    private Type getFolderType(Node folderNode) throws RepositoryException {

        if (folderNode.isNodeType(CmsBuiltInItem.GenericContentTypeFolder.getJcrName())) {
            return ContentObjectFolder.Type.CONTENT_TYPE;
        } else if (folderNode.isNodeType(CmsBuiltInItem.GenericYearFolder.getJcrName())) {
            return ContentObjectFolder.Type.YEAR;
        } else if (folderNode.isNodeType(CmsBuiltInItem.GenericMonthFolder.getJcrName())) {
            return ContentObjectFolder.Type.MONTH;
        } else if (folderNode.isNodeType(CmsBuiltInItem.GenericDayFolder.getJcrName())) {
            return ContentObjectFolder.Type.DAY;
        } else if (folderNode.isNodeType(CmsBuiltInItem.GenericHourFolder.getJcrName())) {
            return ContentObjectFolder.Type.HOUR;
        } else if (folderNode.isNodeType(CmsBuiltInItem.GenericMinuteFolder.getJcrName())) {
            return ContentObjectFolder.Type.MINUTE;
        } else if (folderNode.isNodeType(CmsBuiltInItem.GenericSecondFolder.getJcrName())) {
            return ContentObjectFolder.Type.SECOND;
        } else
            return null;
    }

    private Type renderType(Node folderNode) throws Exception {

        Type folderType = getFolderType(folderNode);
        if (folderType == null)
            throw new Exception("Unknown content object folder type " + folderNode.getPath());
        else
            return folderType;
    }
}