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