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}