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.page.jcr; 017 018import java.util.List; 019 020import javax.jcr.Node; 021import javax.jcr.RepositoryException; 022 023import org.ametys.cms.repository.Content; 024import org.ametys.cms.repository.DefaultContent; 025import org.ametys.plugins.repository.AmetysObject; 026import org.ametys.plugins.repository.AmetysRepositoryException; 027import org.ametys.plugins.repository.CopiableAmetysObject; 028import org.ametys.plugins.repository.ModifiableTraversableAmetysObject; 029import org.ametys.plugins.repository.RepositoryConstants; 030import org.ametys.plugins.repository.RepositoryIntegrityViolationException; 031import org.ametys.plugins.repository.jcr.JCRAmetysObject; 032import org.ametys.plugins.repository.jcr.SimpleAmetysObject; 033import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata; 034import org.ametys.web.repository.content.WebContent; 035import org.ametys.web.repository.page.ModifiableZone; 036import org.ametys.web.repository.page.ModifiableZoneItem; 037import org.ametys.web.repository.page.Zone; 038import org.ametys.web.repository.page.ZoneItem; 039 040/** 041 * implementation of an {@link ZoneItem}. 042 */ 043public class DefaultZoneItem extends SimpleAmetysObject<DefaultZoneItemFactory> implements ModifiableZoneItem, CopiableAmetysObject 044{ 045 /** Constant for title metadata. */ 046 public static final String METADATA_TYPE = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":type"; 047 /** Constant for service metadata. */ 048 public static final String METADATA_SERVICE = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":service"; 049 /** Constant for service metadata. */ 050 public static final String METADATA_SERVICE_PARAM = "service_parameters"; 051 /** Constant for content metadata. */ 052 public static final String METADATA_CONTENT = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":content"; 053 /** Constant for "metadata set name" metadata. */ 054 public static final String METADATA_METADATASET_NAME = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":metadataSetName"; 055 056 /** 057 * Creates a {@link DefaultZoneItem}. 058 * 059 * @param node the node backing this {@link AmetysObject}. 060 * @param parentPath the parent path in the Ametys hierarchy. 061 * @param factory the {@link DefaultZoneItemFactory} which creates the AmetysObject. 062 */ 063 public DefaultZoneItem(Node node, String parentPath, DefaultZoneItemFactory factory) 064 { 065 super(node, parentPath, factory); 066 } 067 068 @Override 069 public ZoneType getType() throws AmetysRepositoryException 070 { 071 try 072 { 073 return ZoneType.valueOf(getNode().getProperty(METADATA_TYPE).getString()); 074 } 075 catch (RepositoryException e) 076 { 077 throw new AmetysRepositoryException("Unable to get type property", e); 078 } 079 } 080 081 @Override 082 public void setType(ZoneType type) throws AmetysRepositoryException 083 { 084 try 085 { 086 getNode().setProperty(METADATA_TYPE, type.name()); 087 } 088 catch (RepositoryException e) 089 { 090 throw new AmetysRepositoryException("Unable to set type property", e); 091 } 092 } 093 094 @Override 095 public <C extends Content> C getContent() throws AmetysRepositoryException 096 { 097 try 098 { 099 return _getFactory().<C>resolveAmetysObject(getNode().getProperty(METADATA_CONTENT).getNode()); 100 } 101 catch (RepositoryException e) 102 { 103 throw new AmetysRepositoryException("Unable to get content property", e); 104 } 105 } 106 107 @Override 108 public <C extends Content> void setContent(C content) throws AmetysRepositoryException 109 { 110 try 111 { 112 // FIXME stop using getNode that is JCR but use AmetysObject API... if it seems cool to you 113 getNode().setProperty(METADATA_CONTENT, ((JCRAmetysObject) content).getNode()); 114 } 115 catch (RepositoryException e) 116 { 117 throw new AmetysRepositoryException("Unable to set content property", e); 118 } 119 } 120 121 @Override 122 public String getMetadataSetName() throws AmetysRepositoryException 123 { 124 try 125 { 126 if (getNode().hasProperty(METADATA_METADATASET_NAME)) 127 { 128 return getNode().getProperty(METADATA_METADATASET_NAME).getString(); 129 } 130 return null; 131 } 132 catch (RepositoryException e) 133 { 134 throw new AmetysRepositoryException("Unable to get metadata set name property.", e); 135 } 136 } 137 138 @Override 139 public void setMetadataSetName(String metadataSetName) throws AmetysRepositoryException 140 { 141 try 142 { 143 getNode().setProperty(METADATA_METADATASET_NAME, metadataSetName); 144 } 145 catch (RepositoryException e) 146 { 147 throw new AmetysRepositoryException("Unable to set metadata set name property.", e); 148 } 149 } 150 151 @Override 152 public String getServiceId() throws AmetysRepositoryException 153 { 154 try 155 { 156 return getNode().getProperty(METADATA_SERVICE).getString(); 157 } 158 catch (RepositoryException e) 159 { 160 throw new AmetysRepositoryException("Unable to get service property", e); 161 } 162 } 163 164 @Override 165 public ModifiableCompositeMetadata getServiceParameters() throws AmetysRepositoryException 166 { 167 return getMetadataHolder().getCompositeMetadata(METADATA_SERVICE_PARAM, true); 168 } 169 170 @Override 171 public void setServiceId(String serviceId) throws AmetysRepositoryException 172 { 173 try 174 { 175 getNode().setProperty(METADATA_SERVICE, serviceId); 176 } 177 catch (RepositoryException e) 178 { 179 throw new AmetysRepositoryException("Unable to set service property", e); 180 } 181 } 182 183 @Override 184 public ModifiableZoneItem copyTo(ModifiableTraversableAmetysObject parent, String name, List<String> restrictTo) throws AmetysRepositoryException 185 { 186 return copyTo (parent, name); 187 } 188 189 @Override 190 public ModifiableZoneItem copyTo(ModifiableTraversableAmetysObject parent, String name) throws AmetysRepositoryException 191 { 192 if (parent instanceof DefaultZone) 193 { 194 ModifiableZone parentZone = (ModifiableZone) parent; 195 ModifiableZoneItem cZoneItem = parentZone.addZoneItem(); 196 197 ZoneType type = getType(); 198 cZoneItem.setType(type); 199 200 if (ZoneType.SERVICE.equals(type)) 201 { 202 cZoneItem.setServiceId(getServiceId()); 203 // Copy services parameters 204 getMetadataHolder().copyTo(cZoneItem.getMetadataHolder()); 205 } 206 else 207 { 208 Content content = getContent(); 209 if (content instanceof WebContent) 210 { 211 WebContent webContent = (WebContent) content; 212 if (getZone().getPage().getSiteName().equals(webContent.getSiteName())) 213 { 214 if (webContent instanceof DefaultContent) 215 { 216 Content cContent = ((DefaultContent) webContent).copyTo(webContent.getSite().getRootContents(), null); 217 cZoneItem.setContent(cContent); 218 219 // Update references to AmetysObject in RichText 220 _getFactory().getCopySiteComponent().updateLinksInRichText(getZone().getPage(), cZoneItem.getZone().getPage(), content, cContent); 221 } 222 } 223 else 224 { 225 // Copy reference 226 cZoneItem.setContent(getContent()); 227 } 228 } 229 else 230 { 231 // Copy reference 232 cZoneItem.setContent(getContent()); 233 } 234 235 String metadataSetName = getMetadataSetName(); 236 if (metadataSetName != null) 237 { 238 cZoneItem.setMetadataSetName(metadataSetName); 239 } 240 } 241 242 return cZoneItem; 243 } 244 else 245 { 246 throw new AmetysRepositoryException("Can not copy a zone item " + getId() + " of type DefaultZoneItem to something that is not a DefaultZone " + parent.getId()); 247 } 248 } 249 250 @Override 251 public boolean canMoveTo(AmetysObject newParent) throws AmetysRepositoryException 252 { 253 return newParent instanceof DefaultZone; 254 } 255 256 @Override 257 public void moveTo(AmetysObject newParent, boolean renameIfExist) throws AmetysRepositoryException, RepositoryIntegrityViolationException 258 { 259 if (!canMoveTo(newParent)) 260 { 261 throw new AmetysRepositoryException("Can not move a zone item " + getId() + " of type DefaultZoneItem to something that is not a DefaultZone " + newParent.getId()); 262 } 263 264 Node node = getNode(); 265 266 try 267 { 268 DefaultZone newParentZone = (DefaultZone) newParent; 269 270 // Move node 271 node.getSession().move(node.getPath(), newParentZone.getNode().getPath() + "/" + DefaultZone.ZONEITEMS_NODE_NAME + "/" + node.getName()); 272 } 273 catch (RepositoryException e) 274 { 275 throw new AmetysRepositoryException("Can not move DefaultZoneItem " + getId() + " to DefaultZone " + newParent.getId(), e); 276 } 277 } 278 279 @Override 280 public void orderBefore(AmetysObject siblingObject) throws AmetysRepositoryException 281 { 282 if (siblingObject != null && !(siblingObject instanceof JCRAmetysObject)) 283 { 284 throw new AmetysRepositoryException(String.format("Unable to order zone item '%s' before sibling '%s' (sibling is not a JCRAmetysObject)", this.getId(), siblingObject.getId())); 285 } 286 287 Node node = getNode(); 288 Node siblingNode = siblingObject != null ? ((JCRAmetysObject) siblingObject).getNode() : null; 289 290 try 291 { 292 node.getParent().orderBefore(node.getName() + "[" + node.getIndex() + "]", siblingNode != null ? siblingNode.getName() + "[" + siblingNode.getIndex() + "]" : null); 293 } 294 catch (RepositoryException e) 295 { 296 throw new AmetysRepositoryException(String.format("Unable to order zone item '%s' before sibling '%s'", this.getId(), siblingObject != null ? siblingObject.getId() : ""), e); 297 } 298 } 299 300 @Override 301 public Zone getZone() 302 { 303 return getParent().getParent(); 304 } 305}