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.ModifiableContent;
028import org.ametys.cms.repository.TagAwareAmetysObject;
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.JCRAmetysObject;
037import org.ametys.plugins.repository.jcr.NodeTypeHelper;
038import org.ametys.web.repository.content.ModifiableWebContent;
039import org.ametys.web.repository.content.WebContent;
040import org.ametys.web.repository.page.Page;
041import org.ametys.web.repository.page.ZoneItem;
042import org.ametys.web.repository.site.Site;
043
044/**
045 * {@link DefaultContent} which is {@link TagAwareAmetysObject}.
046 * @param <F> the actual type of factory.
047 */
048public class DefaultWebContent<F extends DefaultWebContentFactory> extends DefaultContent<F> implements WebContent
049{
050    
051    /** Constants for site Metadata. */
052    public static final String METADATA_SITE = "site";
053    
054    /**
055     * Creates a {@link DefaultWebContent}.
056     * @param node the node backing this {@link DefaultWebContent}.
057     * @param parentPath the parent path in the Ametys hierarchy.
058     * @param factory the {@link DefaultWebContentFactory} which creates the AmetysObject.
059     */
060    public DefaultWebContent(Node node, String parentPath, F factory)
061    {
062        super(node, parentPath, factory);
063    }
064
065    @Override
066    public ModifiableContent copyTo(ModifiableTraversableAmetysObject parent, String name) throws AmetysRepositoryException
067    {
068        ModifiableContent cContent = super.copyTo(parent, name);
069        
070        try
071        {
072            if (cContent instanceof ModifiableWebContent)
073            {
074                ((ModifiableWebContent) cContent).setSiteName(getSiteName());
075                
076                // Copy tags
077                Set<String> tags = getTags();
078                for (String tag : tags)
079                {
080                    ((ModifiableWebContent) cContent).tag(tag);
081                }
082                
083                // Copy attachments
084                ResourceCollection rootAttachments = getRootAttachments();
085                
086                AmetysObjectIterable<AmetysObject> attachments = rootAttachments.getChildren();
087                
088                if (rootAttachments instanceof JCRAmetysObject && cContent instanceof JCRAmetysObject)
089                {
090                    // As root attachments node is auto-created it can not be copied manually : copy the children of root attachments.
091                    ResourceCollection cRootAttachments = ((ModifiableWebContent) cContent).getRootAttachments();
092                    Node cResourcesNode = ((JCRAmetysObject) cRootAttachments).getNode();
093                    
094                    for (AmetysObject attachment : attachments)
095                    {
096                        if (attachment instanceof JCRAmetysObject)
097                        {
098                            Node resourceNode = ((JCRAmetysObject) attachment).getNode();
099                            getNode().getSession().getWorkspace().copy(resourceNode.getPath(), cResourcesNode.getPath() + "/" + resourceNode.getName());
100                        }
101                    }
102                }
103                
104                cContent.saveChanges();
105            }
106        }
107        catch (RepositoryException e)
108        {
109            throw new AmetysRepositoryException(e);
110        }
111        
112        return cContent;
113    }
114    
115    @Override
116    public Collection<Page> getReferencingPages()
117    {
118        ArrayList<Page> pages = new ArrayList<>();
119        try
120        {
121            PropertyIterator itReferences = getNode().getReferences();
122            
123            while (itReferences.hasNext())
124            {
125                Node refererNode = itReferences.nextProperty().getParent();
126                
127                if (NodeTypeHelper.isNodeType(refererNode, "ametys:zoneItem"))
128                {
129                    // /page/ametys-internal:zones/default/ametys-internal:zoneItems/ametys:zoneItem
130                    Node pageNode = refererNode.getParent().getParent().getParent().getParent();
131                    Page page = _getFactory().resolveAmetysObject(pageNode);
132                    pages.add(page);
133                }
134            }
135        }
136        catch (RepositoryException e)
137        {
138            throw new AmetysRepositoryException("Unable to resolve references for content " + getId(), e);
139        }
140        
141        return pages;
142    }
143    
144    @Override
145    public Collection<ZoneItem> getReferencingZoneItems()
146    {
147        ArrayList<ZoneItem> zoneItems = new ArrayList<>();
148        try
149        {
150            PropertyIterator itReferences = getNode().getReferences();
151            
152            while (itReferences.hasNext())
153            {
154                Node refererNode = itReferences.nextProperty().getParent();
155                
156                if (NodeTypeHelper.isNodeType(refererNode, "ametys:zoneItem"))
157                {
158                    ZoneItem zoneItem = _getFactory().resolveAmetysObject(refererNode);
159                    zoneItems.add(zoneItem);
160                }
161            }
162        }
163        catch (RepositoryException e)
164        {
165            throw new AmetysRepositoryException("Unable to resolve references for content " + getId(), e);
166        }
167        
168        return zoneItems;
169    }
170    
171    @Override
172    public ResourceCollection getRootAttachments() throws AmetysRepositoryException
173    {
174        ResourceCollection attachments = null;
175        
176        if (hasChild(ATTACHMENTS_NODE_NAME))
177        {
178            attachments = getChild(ATTACHMENTS_NODE_NAME);
179        }
180        
181        return attachments;
182    }
183    
184    @Override
185    public Site getSite()
186    {
187        return _getFactory().getSite(getSiteName());
188    }
189    
190    @Override
191    public String getSiteName()
192    {
193        return getMetadataHolder().getString(METADATA_SITE);
194    }
195    
196    @Override
197    public boolean hasChild(String name) throws AmetysRepositoryException
198    {
199        return _getFactory().hasChild(this, name);
200    }
201    
202    @SuppressWarnings("unchecked")
203    @Override
204    public <A extends AmetysObject> A createChild(String name, String type) throws AmetysRepositoryException, RepositoryIntegrityViolationException
205    {
206        return (A) _getFactory().createChild(this, name, type);
207    }
208    
209    @SuppressWarnings("unchecked")
210    @Override
211    public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException
212    {
213        return (A) _getFactory().getChild(this, path);
214    }
215    
216    @Override
217    public <A extends AmetysObject> AmetysObjectIterable<A> getChildren() throws AmetysRepositoryException
218    {
219        return _getFactory().getChildren(this);
220    }
221    
222}