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