001/*
002 *  Copyright 2010 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.web.repository.content.jcr;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.Set;
021
022import javax.jcr.Node;
023import javax.jcr.PropertyIterator;
024import javax.jcr.RepositoryException;
025
026import org.ametys.cms.repository.DefaultContent;
027import org.ametys.cms.repository.DefaultWorkflowAwareContent;
028import org.ametys.cms.repository.ModifiableContent;
029import org.ametys.plugins.explorer.resources.ResourceCollection;
030import org.ametys.plugins.repository.AmetysObject;
031import org.ametys.plugins.repository.AmetysObjectIterable;
032import org.ametys.plugins.repository.AmetysRepositoryException;
033import org.ametys.plugins.repository.ModifiableTraversableAmetysObject;
034import org.ametys.plugins.repository.RepositoryIntegrityViolationException;
035import org.ametys.plugins.repository.UnknownAmetysObjectException;
036import org.ametys.plugins.repository.jcr.NodeTypeHelper;
037import org.ametys.plugins.repository.tag.TagAwareAmetysObject;
038import org.ametys.plugins.repository.version.VersionableAmetysObject;
039import org.ametys.runtime.model.type.ModelItemTypeConstants;
040import org.ametys.web.repository.content.ModifiableWebContent;
041import org.ametys.web.repository.content.WebContent;
042import org.ametys.web.repository.page.Page;
043import org.ametys.web.repository.page.ZoneItem;
044import org.ametys.web.repository.site.Site;
045
046/**
047 * {@link DefaultContent} which is {@link TagAwareAmetysObject}.
048 * @param <F> the actual type of factory.
049 */
050public class DefaultWebContent<F extends DefaultWebContentFactory> extends DefaultContent<F> implements WebContent
051{
052    /**
053     * Creates a {@link DefaultWebContent}.
054     * @param node the node backing this {@link DefaultWebContent}.
055     * @param parentPath the parent path in the Ametys hierarchy.
056     * @param factory the {@link DefaultWebContentFactory} which creates the AmetysObject.
057     */
058    public DefaultWebContent(Node node, String parentPath, F factory)
059    {
060        super(node, parentPath, factory);
061    }
062
063    @Override
064    public ModifiableContent copyTo(ModifiableTraversableAmetysObject parent, String name) throws AmetysRepositoryException
065    {
066        return copyTo(parent, name, 0, false);
067    }
068    
069    /**
070     * Copy the current {@link DefaultWorkflowAwareContent} to the given object. Be careful, this method save changes, but do not create a new version (checkpoint)
071     * @param parent The parent of the new object. Can not be null.
072     * @param name Name of the new object. Can be null. If null, the new name will be get from the copied object.
073     * @param initWorkflowActionId The initial workflow action id
074     * @param checkpoint true to check the content in if it is versionable
075     * @return the created object
076     * @throws AmetysRepositoryException if an error occurs.
077     */
078    public ModifiableContent copyTo(ModifiableTraversableAmetysObject parent, String name, int initWorkflowActionId, boolean checkpoint) throws AmetysRepositoryException
079    {
080        ModifiableContent cContent = super.copyTo(parent, name, 0, false, false);
081        
082        if (cContent instanceof ModifiableWebContent modifiableContent)
083        {
084            modifiableContent.setSiteName(getSiteName());
085            
086            // Copy tags
087            Set<String> tags = getTags();
088            for (String tag : tags)
089            {
090                modifiableContent.tag(tag);
091            }
092            
093            cContent.saveChanges();
094            
095            // Create a new version
096            if (checkpoint && modifiableContent instanceof VersionableAmetysObject versionableContent)
097            {
098                versionableContent.checkpoint();
099            }
100        }
101        
102        return cContent;
103    }
104
105    @Override
106    public Collection<Page> getReferencingPages()
107    {
108        ArrayList<Page> pages = new ArrayList<>();
109        try
110        {
111            PropertyIterator itReferences = getNode().getReferences();
112            
113            while (itReferences.hasNext())
114            {
115                Node refererNode = itReferences.nextProperty().getParent();
116                
117                if (NodeTypeHelper.isNodeType(refererNode, "ametys:zoneItem"))
118                {
119                    // /page/ametys-internal:zones/default/ametys-internal:zoneItems/ametys:zoneItem
120                    Node pageNode = refererNode.getParent().getParent().getParent().getParent();
121                    Page page = _getFactory().resolveAmetysObject(pageNode);
122                    pages.add(page);
123                }
124            }
125        }
126        catch (RepositoryException e)
127        {
128            throw new AmetysRepositoryException("Unable to resolve references for content " + getId(), e);
129        }
130        
131        return pages;
132    }
133    
134    @Override
135    public Collection<ZoneItem> getReferencingZoneItems()
136    {
137        ArrayList<ZoneItem> zoneItems = new ArrayList<>();
138        try
139        {
140            PropertyIterator itReferences = getNode().getReferences();
141            
142            while (itReferences.hasNext())
143            {
144                Node refererNode = itReferences.nextProperty().getParent();
145                
146                if (NodeTypeHelper.isNodeType(refererNode, "ametys:zoneItem"))
147                {
148                    ZoneItem zoneItem = _getFactory().resolveAmetysObject(refererNode);
149                    zoneItems.add(zoneItem);
150                }
151            }
152        }
153        catch (RepositoryException e)
154        {
155            throw new AmetysRepositoryException("Unable to resolve references for content " + getId(), e);
156        }
157        
158        return zoneItems;
159    }
160    
161    @Override
162    public ResourceCollection getRootAttachments() throws AmetysRepositoryException
163    {
164        ResourceCollection attachments = null;
165        
166        if (hasChild(ATTACHMENTS_NODE_NAME))
167        {
168            attachments = getChild(ATTACHMENTS_NODE_NAME);
169        }
170        
171        return attachments;
172    }
173    
174    @Override
175    public Site getSite()
176    {
177        return _getFactory().getSite(getSiteName());
178    }
179    
180    @Override
181    public String getSiteName()
182    {
183        return getInternalDataHolder().getValueOfType(METADATA_SITE, ModelItemTypeConstants.STRING_TYPE_ID);
184    }
185    
186    @Override
187    public boolean hasChild(String name) throws AmetysRepositoryException
188    {
189        return _getFactory().hasChild(this, name);
190    }
191    
192    @SuppressWarnings("unchecked")
193    @Override
194    public <A extends AmetysObject> A createChild(String name, String type) throws AmetysRepositoryException, RepositoryIntegrityViolationException
195    {
196        return (A) _getFactory().createChild(this, name, type);
197    }
198    
199    @SuppressWarnings("unchecked")
200    @Override
201    public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException
202    {
203        return (A) _getFactory().getChild(this, path);
204    }
205    
206    @Override
207    public <A extends AmetysObject> AmetysObjectIterable<A> getChildren() throws AmetysRepositoryException
208    {
209        return _getFactory().getChildren(this);
210    }
211    
212    public String getPrivacyLevel()
213    {
214        return getUnversionedDataHolder().getValueOrDefault(PROPERTY_PRIVACY, getSite().getValueOrDefault("content-privacy"));
215    }
216}