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.io.IOException; 019import java.util.List; 020import java.util.Locale; 021import java.util.Optional; 022 023import javax.jcr.Node; 024 025import org.apache.commons.collections4.MapUtils; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028import org.xml.sax.ContentHandler; 029import org.xml.sax.SAXException; 030 031import org.ametys.plugins.repository.AmetysObject; 032import org.ametys.plugins.repository.AmetysObjectIterable; 033import org.ametys.plugins.repository.AmetysRepositoryException; 034import org.ametys.plugins.repository.CopiableAmetysObject; 035import org.ametys.plugins.repository.ModifiableTraversableAmetysObject; 036import org.ametys.plugins.repository.RepositoryConstants; 037import org.ametys.plugins.repository.TraversableAmetysObject; 038import org.ametys.plugins.repository.data.holder.ModifiableModelAwareDataHolder; 039import org.ametys.plugins.repository.data.holder.ModifiableModelLessDataHolder; 040import org.ametys.plugins.repository.data.holder.impl.DefaultModifiableModelLessDataHolder; 041import org.ametys.plugins.repository.data.repositorydata.ModifiableRepositoryData; 042import org.ametys.plugins.repository.data.repositorydata.impl.JCRRepositoryData; 043import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject; 044import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata; 045import org.ametys.runtime.model.View; 046import org.ametys.runtime.model.exception.NotUniqueTypeException; 047import org.ametys.runtime.model.exception.UnknownTypeException; 048import org.ametys.web.parameters.view.ViewParametersModel; 049import org.ametys.web.parameters.view.ViewParametersManager; 050import org.ametys.web.repository.page.ModifiablePage; 051import org.ametys.web.repository.page.ModifiableZone; 052import org.ametys.web.repository.page.ModifiableZoneItem; 053import org.ametys.web.repository.page.Page; 054import org.ametys.web.repository.page.Zone; 055 056/** 057 * JCR implementation of an {@link Zone}. 058 */ 059public class DefaultZone extends DefaultTraversableAmetysObject<DefaultZoneFactory> implements ModifiableZone, CopiableAmetysObject 060{ 061 /** Constant for zone items node name */ 062 public static final String ZONEITEMS_NODE_NAME = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":zoneItems"; 063 /** Constant for zone item node name */ 064 public static final String ZONEITEM_NODE_NAME = RepositoryConstants.NAMESPACE_PREFIX + ":" + ZONEITEM_DATA_NAME; 065 /** Constant for zone items node type */ 066 public static final String ZONEITEM_NODETYPE_NAME = RepositoryConstants.NAMESPACE_PREFIX + ":zoneItem"; 067 068 private static final Logger __LOGGER = LoggerFactory.getLogger(DefaultZone.class); 069 070 /** 071 * Creates a {@link DefaultZone}. 072 * 073 * @param node the node backing this {@link AmetysObject}. 074 * @param parentPath the parent path in the Ametys hierarchy. 075 * @param factory the {@link DefaultZoneFactory} which creates the AmetysObject. 076 */ 077 public DefaultZone(Node node, String parentPath, DefaultZoneFactory factory) 078 { 079 super(node, parentPath, factory); 080 } 081 082 @Override 083 public AmetysObjectIterable<ModifiableZoneItem> getZoneItems() throws AmetysRepositoryException 084 { 085 return ((TraversableAmetysObject) getChild(ZONEITEMS_NODE_NAME)).getChildren(); 086 } 087 088 @Override 089 public ModifiableZoneItem addZoneItem() throws AmetysRepositoryException 090 { 091 return ((ModifiableTraversableAmetysObject) getChild(ZONEITEMS_NODE_NAME)).createChild(ZONEITEM_NODE_NAME, ZONEITEM_NODETYPE_NAME); 092 } 093 094 @Override 095 public Page getPage() 096 { 097 return getParent().getParent(); 098 } 099 100 @Override 101 public ModifiableZone copyTo(ModifiableTraversableAmetysObject parent, String name) throws AmetysRepositoryException 102 { 103 if (parent instanceof ModifiablePage) 104 { 105 ModifiableZone cZone = ((ModifiablePage) parent).createZone(getName()); 106 107 // Copy view parameters 108 getZoneParametersHolder().copyTo(cZone.getZoneParametersHolder()); 109 110 for (ModifiableZoneItem zoneItem : getZoneItems()) 111 { 112 if (zoneItem instanceof CopiableAmetysObject) 113 { 114 ((CopiableAmetysObject) zoneItem).copyTo((ModifiableTraversableAmetysObject) cZone, null); 115 } 116 } 117 return cZone; 118 } 119 else 120 { 121 throw new AmetysRepositoryException("Can not copy zone " + getId() + " of type DefaultZone to something that is not a ModifiablePage " + parent.getId()); 122 } 123 } 124 125 @Override 126 public AmetysObject copyTo(ModifiableTraversableAmetysObject parent, String name, List<String> restrictTo) throws AmetysRepositoryException 127 { 128 return copyTo(parent, name); 129 } 130 131 public ModifiableModelLessDataHolder getDataHolder() 132 { 133 ModifiableRepositoryData repositoryData = new JCRRepositoryData(getNode()); 134 return new DefaultModifiableModelLessDataHolder(_getFactory().getPageDataTypeExtensionPoint(), repositoryData); 135 } 136 137 @Override 138 public ModifiableCompositeMetadata getMetadataHolder() 139 { 140 __LOGGER.warn("The getMetadataHolder method of DefaultZone is deprecated. Use the getDataHolder instead. StackTrace: ", new Exception()); 141 return super.getMetadataHolder(); 142 } 143 144 public ModifiableModelAwareDataHolder getZoneParametersHolder() throws AmetysRepositoryException 145 { 146 JCRRepositoryData zoneItemRepositoryData = new JCRRepositoryData(getNode()); 147 148 // Get the zone Id 149 String zoneId = getName(); 150 151 // Get the template Id 152 Page page = getPage(); 153 String templateId = page.getTemplate(); 154 155 // Get the skin Id 156 String skinId = page.getSite().getSkinId(); 157 158 ViewParametersManager viewParametersManager = _getFactory().getViewParametersManager(); 159 Optional<ViewParametersModel> zoneViewParameters = viewParametersManager.getZoneViewParametersModel(skinId, templateId, zoneId); 160 if (zoneViewParameters.isEmpty()) 161 { 162 zoneViewParameters = Optional.of(new ViewParametersModel("zone-no-param", new View(), MapUtils.EMPTY_SORTED_MAP)); 163 } 164 return viewParametersManager.getParametersHolder(zoneItemRepositoryData, zoneViewParameters.get()); 165 } 166 167 /* 168 * The default implementation is overridden here to not use the getDataHolder()#dataToSAX implementation 169 * Each #dataToSAX method calls the next one and the implementation that has to change is the last one. 170 * If the getDataHolder() is used for one, the next ones will be called with the default implementation 171 */ 172 public void dataToSAX(ContentHandler contentHandler, Locale locale) throws SAXException, IOException, UnknownTypeException, NotUniqueTypeException 173 { 174 for (String name : getDataNames()) 175 { 176 dataToSAX(contentHandler, name, locale); 177 } 178 } 179 180 public void dataToSAX(ContentHandler contentHandler, String dataPath, Locale locale) throws SAXException, IOException 181 { 182 if (!ViewParametersManager.VIEW_PARAMETERS_COMPOSITE_NAME.equals(dataPath)) 183 { 184 ModifiableZone.super.dataToSAX(contentHandler, dataPath, locale); 185 } 186 } 187}