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 088 AmetysObjectIterable<AmetysObject> attachments = rootAttachments.getChildren(); 089 090 if (rootAttachments instanceof JCRAmetysObject && cContent instanceof JCRAmetysObject) 091 { 092 // As root attachments node is auto-created it can not be copied manually : copy the children of root attachments. 093 ResourceCollection cRootAttachments = ((ModifiableWebContent) cContent).getRootAttachments(); 094 Node cResourcesNode = ((JCRAmetysObject) cRootAttachments).getNode(); 095 096 for (AmetysObject attachment : attachments) 097 { 098 if (attachment instanceof JCRAmetysObject) 099 { 100 Node resourceNode = ((JCRAmetysObject) attachment).getNode(); 101 getNode().getSession().getWorkspace().copy(resourceNode.getPath(), cResourcesNode.getPath() + "/" + resourceNode.getName()); 102 } 103 } 104 } 105 106 cContent.saveChanges(); 107 } 108 } 109 catch (RepositoryException e) 110 { 111 throw new AmetysRepositoryException(e); 112 } 113 114 return cContent; 115 } 116 117 @Override 118 public Collection<Page> getReferencingPages() 119 { 120 ArrayList<Page> pages = new ArrayList<>(); 121 try 122 { 123 PropertyIterator itReferences = getNode().getReferences(); 124 125 while (itReferences.hasNext()) 126 { 127 Node refererNode = itReferences.nextProperty().getParent(); 128 129 if (NodeTypeHelper.isNodeType(refererNode, "ametys:zoneItem")) 130 { 131 // /page/ametys-internal:zones/default/ametys-internal:zoneItems/ametys:zoneItem 132 Node pageNode = refererNode.getParent().getParent().getParent().getParent(); 133 Page page = _getFactory().resolveAmetysObject(pageNode); 134 pages.add(page); 135 } 136 } 137 } 138 catch (RepositoryException e) 139 { 140 throw new AmetysRepositoryException("Unable to resolve references for content " + getId(), e); 141 } 142 143 return pages; 144 } 145 146 @Override 147 public Collection<ZoneItem> getReferencingZoneItems() 148 { 149 ArrayList<ZoneItem> zoneItems = new ArrayList<>(); 150 try 151 { 152 PropertyIterator itReferences = getNode().getReferences(); 153 154 while (itReferences.hasNext()) 155 { 156 Node refererNode = itReferences.nextProperty().getParent(); 157 158 if (NodeTypeHelper.isNodeType(refererNode, "ametys:zoneItem")) 159 { 160 ZoneItem zoneItem = _getFactory().resolveAmetysObject(refererNode); 161 zoneItems.add(zoneItem); 162 } 163 } 164 } 165 catch (RepositoryException e) 166 { 167 throw new AmetysRepositoryException("Unable to resolve references for content " + getId(), e); 168 } 169 170 return zoneItems; 171 } 172 173 @Override 174 public ResourceCollection getRootAttachments() throws AmetysRepositoryException 175 { 176 ResourceCollection attachments = null; 177 178 if (hasChild(ATTACHMENTS_NODE_NAME)) 179 { 180 attachments = getChild(ATTACHMENTS_NODE_NAME); 181 } 182 183 return attachments; 184 } 185 186 @Override 187 public Site getSite() 188 { 189 return _getFactory().getSite(getSiteName()); 190 } 191 192 @Override 193 public String getSiteName() 194 { 195 // TODO CMS-9336 this metadata should be stored as internal using data holders 196 ModifiableRepositoryData repositoryData = new JCRRepositoryData(getNode()); 197 return repositoryData.getString(METADATA_SITE); 198 } 199 200 @Override 201 public boolean hasChild(String name) throws AmetysRepositoryException 202 { 203 return _getFactory().hasChild(this, name); 204 } 205 206 @SuppressWarnings("unchecked") 207 @Override 208 public <A extends AmetysObject> A createChild(String name, String type) throws AmetysRepositoryException, RepositoryIntegrityViolationException 209 { 210 return (A) _getFactory().createChild(this, name, type); 211 } 212 213 @SuppressWarnings("unchecked") 214 @Override 215 public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException 216 { 217 return (A) _getFactory().getChild(this, path); 218 } 219 220 @Override 221 public <A extends AmetysObject> AmetysObjectIterable<A> getChildren() throws AmetysRepositoryException 222 { 223 return _getFactory().getChildren(this); 224 } 225 226}