001/*
002 *  Copyright 2012 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.time.ZonedDateTime;
019import java.util.Collection;
020import java.util.Locale;
021import java.util.Optional;
022
023import javax.jcr.Node;
024import javax.jcr.Property;
025import javax.jcr.PropertyType;
026import javax.jcr.RepositoryException;
027import javax.jcr.Session;
028
029import org.ametys.cms.contenttype.ContentType;
030import org.ametys.cms.data.holder.ModifiableIndexableDataHolder;
031import org.ametys.cms.data.holder.impl.DefaultModifiableModelAwareDataHolder;
032import org.ametys.cms.repository.Content;
033import org.ametys.core.user.UserIdentity;
034import org.ametys.plugins.repository.AmetysObject;
035import org.ametys.plugins.repository.AmetysRepositoryException;
036import org.ametys.plugins.repository.RepositoryConstants;
037import org.ametys.plugins.repository.data.repositorydata.ModifiableRepositoryData;
038import org.ametys.plugins.repository.data.repositorydata.impl.JCRRepositoryData;
039import org.ametys.plugins.repository.tag.TaggableAmetysObjectHelper;
040import org.ametys.web.repository.content.SharedContent;
041import org.ametys.web.repository.site.Site;
042
043/**
044 * Default {@link SharedContent} implementation, backed by a JCR node.
045 * @param <F> the actual type of factory.
046 */
047public class DefaultSharedContent<F extends DefaultSharedContentFactory> extends DefaultWebContent<F> implements SharedContent
048{
049    
050    /** The initial content property. */
051    public static final String INITIAL_CONTENT_PROPERTY = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":initial-content";
052    
053    /**
054     * Creates a {@link DefaultSharedContent}.
055     * @param node the node backing this {@link AmetysObject}
056     * @param parentPath the parentPath in the Ametys hierarchy
057     * @param factory the DefaultSharedContentFactory which created the AmetysObject.
058     */
059    public DefaultSharedContent(Node node, String parentPath, F factory)
060    {
061        super(node, parentPath, factory);
062    }
063    
064    @Override
065    public Content getInitialContent() throws AmetysRepositoryException
066    {
067        Session session = null;
068        try
069        {
070            Content content = null;
071            
072            // The difficulty is that we have to switch to 'default' workspace, 
073            // because the property does not exists in 'live',
074            // because it could reference a non existing node
075            session = getNode().getSession().getRepository().login("default");
076            Node defaultWorkspaceNode = session.getNodeByIdentifier(getNode().getIdentifier());
077            
078            if (defaultWorkspaceNode.hasProperty(INITIAL_CONTENT_PROPERTY))
079            {
080                Property contentProp = defaultWorkspaceNode.getProperty(INITIAL_CONTENT_PROPERTY);
081                if (contentProp.getType() == PropertyType.REFERENCE)
082                {
083                    String contentNodeId = contentProp.getValue().getString();
084                    Node contentNode = getNode().getSession().getNodeByIdentifier(contentNodeId);
085                    content = _getFactory().resolveAmetysObject(contentNode);
086                }
087            }
088            return content;
089        }
090        catch (RepositoryException e)
091        {
092            throw new AmetysRepositoryException("Unable to resolve the initial content of shared content " + toString(), e);
093        }
094        finally
095        {
096            if (session != null)
097            {
098                session.logout();
099            }
100        }
101    }
102    
103    @Override
104    public Site getSite()
105    {
106        return getParent().getParent();
107    }
108    
109    @Override
110    public String getSiteName()
111    {
112        return getSite().getName();
113    }
114    
115    @Override
116    public void setSiteName(String siteName)
117    {
118        // TODO CMS-9336 this metadata should be stored as internal using data holders
119        ModifiableRepositoryData repositoryData = new JCRRepositoryData(getNode());
120        repositoryData.setValue(METADATA_SITE, siteName);
121    }
122    
123    /**
124     * Set the title.
125     * @param title the title.
126     * @throws AmetysRepositoryException if an error occurs.
127     */
128    @Deprecated
129    public void setTitle(String title) throws AmetysRepositoryException
130    {
131        _getFactory().getModifiableContentHelper().setTitle(this, title);
132    }
133    
134    /**
135     * Set the title from the given locale
136     * @param title the title.
137     * @param locale The locale
138     * @throws AmetysRepositoryException if an error occurs.
139     */
140    public void setTitle(String title, Locale locale) throws AmetysRepositoryException
141    {
142        _getFactory().getModifiableContentHelper().setTitle(this, title, locale);
143    }
144    
145    /**
146     * Set the login of the creator.
147     * @param user the creator.
148     * @throws AmetysRepositoryException if an error occurs.
149     */
150    public void setCreator(UserIdentity user) throws AmetysRepositoryException
151    {
152        _getFactory().getModifiableContentHelper().setCreator(this, user);
153    }
154    
155    /**
156     * Set the creation date.
157     * @param creationDate the creation date.
158     * @throws AmetysRepositoryException if an error occurs.
159     */
160    public void setCreationDate(ZonedDateTime creationDate) throws AmetysRepositoryException
161    {
162        _getFactory().getModifiableContentHelper().setCreationDate(this, creationDate);
163    }
164    
165    /**
166     * Set the login of the last contributor.
167     * @param user the last contributor.
168     * @throws AmetysRepositoryException if an error occurs.
169     */
170    public void setLastContributor(UserIdentity user)
171    {
172        _getFactory().getModifiableContentHelper().setLastContributor(this, user);
173    }
174    
175    /**
176     * Set the last modification date.
177     * @param lastModified the last modification date.
178     * @throws AmetysRepositoryException if an error occurs.
179     */
180    public void setLastModified(ZonedDateTime lastModified) throws AmetysRepositoryException
181    {
182        _getFactory().getModifiableContentHelper().setLastModified(this, lastModified);
183    }
184    
185    /**
186     * Set the first validation date
187     * @param validationDate the validation date.
188     * @throws AmetysRepositoryException if an error occurs.
189     */
190    public void setFirstValidationDate(ZonedDateTime validationDate) throws AmetysRepositoryException
191    {
192        _getFactory().getModifiableContentHelper().setFirstValidationDate(this, validationDate);
193    }
194    
195    /**
196     * Set the last validation date
197     * @param validationDate the validation date.
198     * @throws AmetysRepositoryException if an error occurs.
199     */
200    public void setLastValidationDate(ZonedDateTime validationDate) throws AmetysRepositoryException
201    {
202        _getFactory().getModifiableContentHelper().setLastValidationDate(this, validationDate);
203    }
204    
205    /**
206     * Set the last validation date resulting from a major modification
207     * @param validationDate the validation date.
208     * @throws AmetysRepositoryException if an error occurs.
209     */
210    public void setLastMajorValidationDate(ZonedDateTime validationDate) throws AmetysRepositoryException
211    {
212        _getFactory().getModifiableContentHelper().setLastMajorValidationDate(this, validationDate);
213    }
214    
215    @Override
216    public ModifiableIndexableDataHolder getDataHolder()
217    {
218        // It is necessary to instantiate the repository data because of locks:
219        // when the content is locked, the lock token is released to be taken by anyone
220        // in repository data there is a lock checked boolean that need to be reset in order to take the token
221        // this boolean is only reset at instantiation
222        ModifiableRepositoryData repositoryData = new JCRRepositoryData(getNode());
223        Collection<ContentType> contentTypes = _getFactory().getContentHelper().getContentTypes(this);
224        return new DefaultModifiableModelAwareDataHolder(repositoryData, Optional.empty(), Optional.of(this), contentTypes);
225    }
226    
227    @Override
228    public void tag(String tag) throws AmetysRepositoryException
229    {
230        TaggableAmetysObjectHelper.tag(this, tag);
231    }
232    
233    @Override
234    public void untag(String tag) throws AmetysRepositoryException
235    {
236        TaggableAmetysObjectHelper.untag(this, tag);
237    }
238    
239}