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, contentTypes, Optional.empty(), Optional.empty(), Optional.of(this)); 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}