001/*
002 *  Copyright 2022 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.cms.tag.jcr;
017
018import java.util.Map;
019
020import javax.jcr.Node;
021import javax.jcr.PathNotFoundException;
022import javax.jcr.RepositoryException;
023
024import org.apache.commons.lang.StringUtils;
025
026import org.ametys.cms.color.AbstractColorsComponent;
027import org.ametys.cms.tag.ColorableTag;
028import org.ametys.plugins.repository.AmetysObject;
029import org.ametys.plugins.repository.AmetysRepositoryException;
030import org.ametys.plugins.repository.RepositoryConstants;
031
032/**
033 * {@link JCRTag} for storing color tag informations.
034 * @param <T> the tag factory
035 */
036public abstract class AbstractColorableJCRTag<T extends AbstractColorableCMSTagFactory> extends JCRTag
037{
038    /** Constants for color metadata. */
039    private static final String __PROPERTY_COLOR = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":color";
040    
041    /**
042     * Creates a {@link ColorableTag}.
043     * @param node the node backing this {@link AmetysObject}.
044     * @param parentPath the parent path in the Ametys hierarchy.
045     * @param factory the factory which creates the AmetysObject.
046     */
047    public AbstractColorableJCRTag (Node node, String parentPath, T factory)
048    {
049        super(node, parentPath, factory);
050    }
051    
052    /**
053     * Retrieves the color type.
054     * @return the color type.
055     * @throws AmetysRepositoryException if an error occurs.
056     */
057    public String getColor() throws AmetysRepositoryException
058    {
059        try
060        {
061            return getNode().getProperty(__PROPERTY_COLOR).getString();
062        }
063        catch (PathNotFoundException e)
064        {
065            return null;
066        }
067        catch (RepositoryException e)
068        {
069            throw new AmetysRepositoryException("Unable to get color property", e);
070        }
071    }
072    
073    /**
074     * Set the color type.
075     * @param color the color type.
076     * @throws AmetysRepositoryException if an error occurs.
077     */
078    public void setColor(String color) throws AmetysRepositoryException
079    {
080        try
081        {
082            getNode().setProperty(__PROPERTY_COLOR, color);
083        }
084        catch (RepositoryException e)
085        {
086            throw new AmetysRepositoryException("Unable to set color property", e);
087        }
088    }
089    
090    @Override
091    public Map<String, Object> toJSON()
092    {
093        Map<String, Object> infos = super.toJSON();
094        AbstractColorableCMSTagFactory factory = (AbstractColorableCMSTagFactory) _getFactory();
095        infos.put("color", _getColor(factory));
096        infos.put("isColorable", true);
097        infos.put("class", factory.getColorsComponent().getColorCSSClassPrefix());
098        
099        return infos;
100    }
101    
102    private String _getColor(AbstractColorableCMSTagFactory factory)
103    {
104        AbstractColorsComponent colorsComponent = factory.getColorsComponent();
105        String color = getColor();
106        Map<String, Map<String, String>> colors = colorsComponent.getColors();
107        if (StringUtils.isNotEmpty(color) && colors.containsKey(color))
108        {
109            return color;
110        }
111        else
112        {
113            color = _getParentColor(getParent());
114            return StringUtils.isNotBlank(color) ? color : colorsComponent.getDefaultKey();
115        }
116    }
117    
118    private String _getParentColor(AmetysObject parentTag)
119    {
120        if (parentTag == null || !(parentTag instanceof AbstractColorableJCRTag))
121        {
122            return null;
123        }
124        
125        String color = ((AbstractColorableJCRTag) parentTag).getColor();
126        return StringUtils.isNotBlank(color) ? color : _getParentColor(parentTag.getParent());
127    }
128}