001/*
002 *  Copyright 2014 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.io.IOException;
019import java.util.ArrayList;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023
024import javax.jcr.RepositoryException;
025
026import org.apache.avalon.framework.parameters.Parameters;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.cocoon.ProcessingException;
030import org.apache.cocoon.acting.ServiceableAction;
031import org.apache.cocoon.environment.ObjectModelHelper;
032import org.apache.cocoon.environment.Redirector;
033import org.apache.cocoon.environment.Request;
034import org.apache.cocoon.environment.SourceResolver;
035import org.apache.commons.lang.StringUtils;
036import org.xml.sax.SAXException;
037
038import org.ametys.cms.tag.AbstractTagProviderExtensionPoint;
039import org.ametys.cms.tag.Tag;
040import org.ametys.core.cocoon.JSonReader;
041import org.ametys.plugins.repository.AmetysObject;
042import org.ametys.plugins.repository.AmetysObjectIterable;
043import org.ametys.plugins.repository.AmetysObjectResolver;
044import org.ametys.plugins.repository.TraversableAmetysObject;
045
046/**
047 * This action returns the JCR sub-tags of a given JCR node.
048 */
049public class GetJCRTagsAction extends ServiceableAction
050{
051    /** The tag provider extension point */
052    protected AbstractTagProviderExtensionPoint<? extends Tag> _tagProviderExtPt;
053
054    /** The Ametys object resolver */
055    protected AmetysObjectResolver _resolver;
056
057    /** The service manager */
058    protected ServiceManager _serviceManager;
059    
060    @Override
061    public void service(ServiceManager serviceManager) throws ServiceException
062    {
063        super.service(serviceManager);
064        _serviceManager = serviceManager;
065        _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
066    }
067
068    @SuppressWarnings("unchecked")
069    @Override
070    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws IOException, SAXException, ProcessingException
071    {
072        Map<String, Object> jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT);
073        
074        String parentId = (String) jsParameters.get("node");
075        String tagProviderId = (String) jsParameters.get("tagProviderId");
076        String tagProviderEPId = (String) jsParameters.get("tagProviderEPId");
077        
078        Map<String, Object> contextualParameters = (Map<String, Object>) jsParameters.get("contextualParameters");
079
080        try
081        {
082            _tagProviderExtPt = (AbstractTagProviderExtensionPoint<? extends Tag>) _serviceManager.lookup(tagProviderEPId);
083        }
084        catch (ServiceException e1)
085        {
086            throw new IllegalArgumentException("Can't have a tag provider extension point with id " + tagProviderEPId, e1);
087        }
088        
089        List<Map<String, Object>> tags = new ArrayList<>();
090
091        try
092        {
093            if (StringUtils.isEmpty(parentId) || parentId.startsWith(_tagProviderExtPt.getTagsNodeName() + "://"))
094            {
095                AbstractJCRTagProvider<? extends Tag> provider = (AbstractJCRTagProvider< ? extends Tag>) _tagProviderExtPt.getExtension(tagProviderId); 
096
097                TraversableAmetysObject rootNode = provider.getRootNode(contextualParameters);
098
099                try (AmetysObjectIterable<AmetysObject> it = rootNode.getChildren())
100                {
101                    for (AmetysObject object : it)
102                    {
103                        if (object instanceof JCRTag)
104                        {
105                            tags.add(((JCRTag) object).toJSON());
106                        }
107                    }
108                }
109            }
110            else
111            {
112                JCRTag jcrTag = _resolver.resolveById(parentId);
113
114                try (AmetysObjectIterable< ? > objects = jcrTag.getChildren())
115                {
116                    for (AmetysObject object : objects)
117                    {
118                        if (object instanceof JCRTag)
119                        {
120                            tags.add(((JCRTag) object).toJSON());
121                        }
122                    }
123                }
124            }
125        }
126        catch (RepositoryException e)
127        {
128            getLogger().error("Unable to get JCR tag root node", e);
129        }
130
131        Map<String, Object> result = new HashMap<>();
132        result.put("children", tags);
133
134        Request request = ObjectModelHelper.getRequest(objectModel);
135        request.setAttribute(JSonReader.OBJECT_TO_READ, result);
136
137        return EMPTY_MAP;
138    }
139}