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