Package org.jahia.services.categories.jcr

Source Code of org.jahia.services.categories.jcr.JCRCategoryProvider

/**
* This file is part of Jahia, next-generation open source CMS:
* Jahia's next-generation, open source CMS stems from a widely acknowledged vision
* of enterprise application convergence - web, search, document, social and portal -
* unified by the simplicity of web content management.
*
* For more information, please visit http://www.jahia.com.
*
* Copyright (C) 2002-2011 Jahia Solutions Group SA. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* As a special exception to the terms and conditions of version 2.0 of
* the GPL (or any later version), you may redistribute this Program in connection
* with Free/Libre and Open Source Software ("FLOSS") applications as described
* in Jahia's FLOSS exception. You should have received a copy of the text
* describing the FLOSS exception, and it is also available here:
* http://www.jahia.com/license
*
* Commercial and Supported Versions of the program (dual licensing):
* alternatively, commercial and supported versions of the program may be used
* in accordance with the terms and conditions contained in a separate
* written agreement between you and Jahia Solutions Group SA.
*
* If you are unsure which license is appropriate for your use,
* please contact the sales department at sales@jahia.com.
*/

package org.jahia.services.categories.jcr;

import org.jahia.services.content.JCRContentUtils;
import org.jahia.services.sites.JahiaSitesBaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jahia.api.Constants;
import org.jahia.exceptions.JahiaException;
import org.jahia.services.categories.Category;
import org.jahia.services.categories.CategoryBean;
import org.jahia.services.content.JCRNodeWrapper;
import org.jahia.services.content.JCRSessionWrapper;
import org.jahia.services.content.JCRSessionFactory;
import org.jahia.services.usermanager.JahiaUser;

import javax.jcr.*;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import java.util.*;

/**
* This is the manager/provider class to create/get/remove categories within Jahia's JCR.
*
* @author Benjamin Papez
*
*/
public class JCRCategoryProvider {
    private transient static Logger logger = LoggerFactory
            .getLogger(JCRCategoryProvider.class);
    private transient JCRSessionFactory sessionFactory;
    private static JCRCategoryProvider mCategoryProvider;

    /**
     * Create an new instance of the Category provider if the instance do not exist, or return the existing instance.
     *
     * @return Return the instance of the Category provider.
     */
    public static JCRCategoryProvider getInstance() {
        if (mCategoryProvider == null) {
            mCategoryProvider = new JCRCategoryProvider();
        }
        return mCategoryProvider;
    }

    /**
     * Setting the JCR store service (done via Spring)
     * @param sessionFactory
     */
    public void setSessionFactory(JCRSessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    /**
     * Returns the folder node (of nt:folder type) holding all root categories
     * @return categories' root folder JCR node
     */
    public Node getCategoriesRoot() {
        JCRNodeWrapper rootNodeWrapper = null;
        try {
            JCRSessionWrapper jcrSessionWrapper = sessionFactory
                    .getCurrentUserSession();
            rootNodeWrapper = jcrSessionWrapper.getNode(JCRContentUtils.getSystemSitePath()+"/categories");
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return rootNodeWrapper;
    }

    /**
     * Get all root categories accessible by the given user
     * @param user accessing the repository
     * @return list of root categories (Category facade objects)
     */
    public List<Category> getRootCategories(JahiaUser user) {
        JCRNodeWrapper rootNodeWrapper = null;
        List<Category> rootCategories = new ArrayList<Category>();
        try {
            rootNodeWrapper = (JCRNodeWrapper) getCategoriesRoot();
            for (NodeIterator it = rootNodeWrapper.getNodes(); it.hasNext();) {
                JCRNodeWrapper rootCategoryNode = (JCRNodeWrapper) it.nextNode();
                if (rootCategoryNode.isNodeType(Constants.JAHIANT_CATEGORY)) {
                    rootCategories.add(new Category(
                            createCategoryBeanFromNode(rootCategoryNode)));
                }
            }
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return rootCategories;
    }

    /**
     * This is the method that creates a new category in the system, with all the specified attributes.
     * @param key of category to be created
     * @param parentCategory
     * @return newly created category (Category facade object)
     * @throws JahiaException
     */
    public Category createCategory(String key, Category parentCategory) throws JahiaException {
        Category newCategory = null;
        try {
            JCRSessionWrapper jcrSessionWrapper = sessionFactory
                    .getCurrentUserSession();
            JCRNodeWrapper parentNodeWrapper = getParentNode(parentCategory,
                    jcrSessionWrapper);
            jcrSessionWrapper.checkout(parentNodeWrapper);
            final JCRNodeWrapper wrapper = parentNodeWrapper.addNode(key,
                    Constants.JAHIANT_CATEGORY);
            jcrSessionWrapper.save();
            newCategory = new Category(createCategoryBeanFromNode(wrapper));
        } catch (ItemExistsException e) {
            throw new JahiaException("Category " + key
                    + " already exists", "Category " + key
                    + " already exists", JahiaException.DATA_ERROR,
                    JahiaException.ERROR_SEVERITY);           
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return newCategory;
    }

    /**
     * Get category by its ID
     * @param categoryUUID
     * @return category having the given UUID
     */
    public Category getCategoryByUUID(String categoryUUID) {
        Category categoryByUUID = null;
        try {
            JCRSessionWrapper session = sessionFactory
                    .getCurrentUserSession();
            Node categoryNode = session.getNodeByUUID(categoryUUID);
            categoryByUUID = new Category(
                    createCategoryBeanFromNode(categoryNode));
        } catch (PathNotFoundException e) {
            logger.debug(e.getMessage(), e);
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return categoryByUUID;
    }


    /**
     * Get category by path
     * @param categoryPath
     * @return
     */
    public Category getCategoryByPath(String categoryPath) {
        Category categoryByUUID = null;
        try {
            JCRSessionWrapper session = sessionFactory
                    .getCurrentUserSession();
            Node categoryNode = session.getNode(categoryPath);
            categoryByUUID = new Category(
                    createCategoryBeanFromNode(categoryNode));
        } catch (PathNotFoundException e) {
            logger.debug(e.getMessage(), e);
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return categoryByUUID;
    }

    /**
     * Get child category within a parent category (or null for root) by its key
     * @param categoryKey
     * @param parentCategory
     * @return the category matching the key
     */
    public Category getCategoryByKey(String categoryKey, Category parentCategory) {
        Category newCategory = null;
        try {
            JCRSessionWrapper jcrSessionWrapper = sessionFactory
                    .getCurrentUserSession();
            JCRNodeWrapper parentNodeWrapper = null;
            if (parentCategory != null) {
                parentNodeWrapper = (JCRNodeWrapper) ((JCRCategory) parentCategory
                        .getJahiaCategory()).getCategoryNode();
            }
            if (parentNodeWrapper == null) {
                parentNodeWrapper = (JCRNodeWrapper) getCategoriesRoot();
            }
            final JCRNodeWrapper wrapper = (JCRNodeWrapper) parentNodeWrapper
                    .getNode(categoryKey);
            newCategory = new Category(createCategoryBeanFromNode(wrapper));
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return newCategory;

    }

    /**
     * Find categories by its key anywhere in the tree
     * @param categoryKey
     * @return list of categories matching the key
     */
    public List<Category> findCategoryByKey(String categoryKey) {
        final List<Category> result = new ArrayList<Category>();
        try {
            Session session = sessionFactory.getCurrentUserSession();
            if (session.getWorkspace().getQueryManager() != null) {
        StringBuilder query = new StringBuilder("SELECT * FROM ["
                + Constants.JAHIANT_CATEGORY + "] as cat WHERE cat.[" + Constants.NODENAME
                + "] = '");
                query.append(categoryKey);
                query.append("' ");
                if (logger.isDebugEnabled()) {
                    logger.debug(query.toString());
                }
                Query q = session.getWorkspace().getQueryManager().createQuery(
                        query.toString(), Query.JCR_SQL2);
                QueryResult qr = q.execute();
                NodeIterator ni = qr.getNodes();
                while (ni.hasNext()) {
                    Node categoryNode = ni.nextNode();
                    result.add(new Category(
                            createCategoryBeanFromNode(categoryNode)));
                }
            }
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * Find categories by its key prefix anywhere in the tree
     * @param categoryKey
     * @return list of categories matching the key
     */   
    public List<Category> findCategoriesStartingByKey(String categoryKey) {
        final List<Category> result = new ArrayList<Category>();
        try {
            Session session = sessionFactory.getCurrentUserSession();
            if (session.getWorkspace().getQueryManager() != null) {
              StringBuilder query = new StringBuilder("SELECT * FROM ["
                        + Constants.JAHIANT_CATEGORY
                        + "] as cat WHERE cat.[" + Constants.NODENAME + "] LIKE '");
                query.append(categoryKey);
                query.append("%' ");
                query.append(" ORDER BY cat.[" + Constants.NODENAME+"]");
                if (logger.isDebugEnabled()) {
                    logger.debug(query.toString());
                }
                Query q = session.getWorkspace().getQueryManager().createQuery(
                        query.toString(), Query.JCR_SQL2);
                QueryResult qr = q.execute();
                NodeIterator ni = qr.getNodes();
                while (ni.hasNext()) {
                    Node categoryNode = ni.nextNode();
                    result.add(new Category(
                            createCategoryBeanFromNode(categoryNode)));
                }
            }
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * Find categories by its title prefix and language anywhere in the tree
     * @param titlePrefix
     * @param language
     * @return list of categories matching the title prefix and langauge
     */
    public List<Category> findCategoriesStartingByTitle(String titlePrefix,
            String language) {
        throw new UnsupportedOperationException("not yet implemented");
    }
   
    /**
     * Find categories containing term in title and language anywhere in the tree
     * @param title
     * @param language
     * @return list of categories matching the title term and language
     */
    public List<Category> findCategoriesContainingTitleString(String title,
            String language) {
        throw new UnsupportedOperationException("not yet implemented");
    }

    /**
     * Get the category title in all languages. The key in the map is the language code and the value is the title.
     * @param category
     * @return a Map with language code keys and title values
     * @throws JahiaException
     */
    public Map<String, String> getTitlesForCategory(Category category)
            throws JahiaException {
        Map<String, String> result = new HashMap<String, String>();
        try {
            Session session = sessionFactory.getCurrentUserSession();
            Node categoryNode = session.getNodeByIdentifier(category
                    .getJahiaCategory().getId());
            for (NodeIterator it = categoryNode
                    .getNodes("j:translation*"); it.hasNext();) {
                Node subNode = (Node) it.next();
                String languageCode = subNode.getProperty(
                        Constants.JCR_LANGUAGE).getString();
                String title = null;
                try {
                    title = subNode.getProperty(
                            Constants.JCR_TITLE)
                            .getString();
                } catch (PathNotFoundException ex) {
                    logger.debug(ex.getMessage(), ex);
                }
                result.put(languageCode, title);
            }
        } catch (RepositoryException e) {
            logger.warn(e.getMessage(), e);
        }
        return result;
    }

    /**
     * Get the category title in the specified language
     * @param category
     * @param locale
     * @return category title in the specified language
     * @throws JahiaException
     */
    public String getTitleForCategory(Category category, Locale locale)
            throws JahiaException {
        String title = null;
        try {
            Session session = sessionFactory.getCurrentUserSession(null, locale);
            Node categoryNode = session.getNodeByIdentifier(category
                    .getJahiaCategory().getId());
            Property titleProperty = categoryNode
                    .getProperty(Constants.JCR_TITLE);
            if (titleProperty != null) {
                title = titleProperty.getString();
            }
        } catch (PathNotFoundException e) {
            logger.debug(e.getMessage(), e);           
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return title;
    }

    /**
     * Set category title in specified language
     * @param category
     * @param locale
     * @param title
     * @throws JahiaException
     */
    public void setTitleForCategory(Category category, Locale locale,
            String title) throws JahiaException {
        try {
            JCRSessionWrapper session = sessionFactory.getCurrentUserSession(null, locale);
            Node categoryNode = session.getNodeByIdentifier(category
                    .getJahiaCategory().getId());
            session.checkout(categoryNode);
            categoryNode.setProperty(Constants.JCR_TITLE, title);
            session.save();
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
    }

    /**
     * Remove category title for specified language
     * @param category
     * @param locale
     * @throws JahiaException
     */
    public void removeTitleForCategory(Category category, Locale locale)
            throws JahiaException {
        try {
            JCRSessionWrapper session = sessionFactory.getCurrentUserSession(null, locale);
            Node categoryNode = session.getNodeByIdentifier(category
                    .getJahiaCategory().getId());
            session.checkout(categoryNode);
            categoryNode.getProperty(Constants.JCR_TITLE).remove();
            session.save();
        } catch (PathNotFoundException e) {
            logger.debug(e.getMessage(), e);           
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
    }

    /**
     * Remove the category from the repository
     * @param categoryBean
     * @throws JahiaException
     */
    public void removeCategory(CategoryBean categoryBean) throws JahiaException {
        try {
            JCRSessionWrapper jcrSessionWrapper = sessionFactory
                    .getCurrentUserSession();
            Node node = null;
            if (categoryBean.getId() == null) {
                List<Category> categories = findCategoryByKey(categoryBean.getKey());
                if (categories.size() == 1) {
                    node = ((JCRCategory) categories.get(0).getJahiaCategory())
                            .getCategoryNode();
                } else {
                    String msg = "Category "
                            + categoryBean.getKey()
                            + (categories.size() == 0 ? "not found"
                                    : " exists multiple times and could not be deleted");
                    throw new JahiaException(msg, msg,
                            JahiaException.DATA_ERROR,
                            JahiaException.ERROR_SEVERITY);                      
                }
            } else {
                node = jcrSessionWrapper.getNodeByUUID(categoryBean.getId());
            }
            if (node != null) {
                if (!node.getParent().isCheckedOut()) {
                    jcrSessionWrapper.checkout(node.getParent());
                }
                node.remove();
                jcrSessionWrapper.save();
            }
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
    }

    private CategoryBean createCategoryBeanFromNode(Node categoryNode) {
        CategoryBean categoryBean = new JCRCategory(categoryNode);
        return categoryBean;
    }

    /**
     * Find category by property name and value (not supported yet, as properties are dropped and will be replaced by category references)
     * @param propName
     * @param propValue
     * @param user
     * @return
     */
    public List<Category> findCategoriesByPropNameAndValue(String propName,
            String propValue, JahiaUser user) {
        throw new UnsupportedOperationException("not yet implemented");
    }

    /**
     * Remove properties from category (not supported yet, as properties are dropped and will be replaced by category references)
     * @param categoryId
     */
    public void removeProperties(String categoryId) {
        logger.error("method nor supported yet");
    }

    /**
     * Get properties from category (not supported yet, as properties are dropped and will be replaced by category references)
     * @param categoryId
     * @return
     */
    public Properties getProperties(String categoryId) {
        logger.error("method nor supported yet");       
        return null;
    }

    /**
     * Set properties (not supported yet, as properties are dropped and will be replaced by category references)
     * @param categoryId
     * @param properties
     */
    public void setProperties(String categoryId, Properties properties) {
        logger.error("method nor supported yet");
    }

    /**
     * Get all child categories from a parent category a user is able to see
     * @param parentCategory
     * @param user
     * @return all child category objects of a parent, which a user can see
     * @throws JahiaException
     */
    public List<Category> getCategoryChildCategories(Category parentCategory, JahiaUser user)
            throws JahiaException {
        List<Category> rootCategories = new ArrayList<Category>();
        try {
            JCRSessionWrapper jcrSessionWrapper = sessionFactory
                    .getCurrentUserSession();
            JCRNodeWrapper parentNodeWrapper = getParentNode(parentCategory,
                    jcrSessionWrapper);
            for (NodeIterator iterator = parentNodeWrapper.getNodes(); iterator.hasNext();) {
                JCRNodeWrapper rootCategoryNode = (JCRNodeWrapper) iterator.nextNode();
                if (rootCategoryNode.isNodeType(Constants.JAHIANT_CATEGORY)) {
                    rootCategories.add(new Category(
                            createCategoryBeanFromNode(rootCategoryNode)));
                }
            }
        } catch (RepositoryException e) {
            logger.error(e.getMessage(), e);
        }
        return rootCategories;
    }

    private JCRNodeWrapper getParentNode(Category parentCategory,
            JCRSessionWrapper jcrSessionWrapper) throws RepositoryException {
        JCRNodeWrapper parentNodeWrapper = null;
        if (parentCategory != null) {
            parentNodeWrapper = (JCRNodeWrapper) ((JCRCategory) parentCategory
                    .getJahiaCategory()).getCategoryNode();
        }
        if (parentNodeWrapper == null) {
            parentNodeWrapper = (JCRNodeWrapper) getCategoriesRoot();
        }
        return parentNodeWrapper;
    }
}
TOP

Related Classes of org.jahia.services.categories.jcr.JCRCategoryProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.