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.HashMap; 019import java.util.List; 020import java.util.Map; 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.repositorydata.impl.JCRRepositoryData; 040import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject; 041import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata; 042import org.ametys.runtime.model.View; 043import org.ametys.runtime.model.exception.BadItemTypeException; 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.SitemapElement; 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 SitemapElement getSitemapElement() 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 copiableZoneItem) 112 { 113 copiableZoneItem.copyTo((ModifiableTraversableAmetysObject) cZone, (String) 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 @Override 131 public ModifiableCompositeMetadata getMetadataHolder() 132 { 133 __LOGGER.warn("The getMetadataHolder method of DefaultZone is deprecated. Use the getDataHolder instead. StackTrace: ", new Exception()); 134 return super.getMetadataHolder(); 135 } 136 137 public ModifiableModelAwareDataHolder getZoneParametersHolder() throws AmetysRepositoryException 138 { 139 JCRRepositoryData zoneRepositoryData = new JCRRepositoryData(getNode()); 140 141 // Get the zone Id 142 String zoneId = getName(); 143 144 // Get the template Id 145 SitemapElement sitemapElement = getSitemapElement(); 146 String templateId = sitemapElement.getTemplate(); 147 148 // Get the skin Id 149 String skinId = sitemapElement.getSite().getSkinId(); 150 151 ViewParametersManager viewParametersManager = _getFactory().getViewParametersManager(); 152 Optional<ViewParametersModel> zoneViewParameters = viewParametersManager.getZoneViewParametersModel(skinId, templateId, zoneId); 153 if (zoneViewParameters.isEmpty()) 154 { 155 zoneViewParameters = Optional.of(new ViewParametersModel("zone-no-param", new View(), MapUtils.EMPTY_SORTED_MAP)); 156 } 157 return viewParametersManager.getParametersHolder(zoneRepositoryData, zoneViewParameters.get()); 158 } 159 160 @Override 161 public void dataToSAX(ContentHandler contentHandler, DataContext context) throws SAXException, UnknownTypeException, NotUniqueTypeException, BadItemTypeException 162 { 163 for (String dataName : getDataNames()) 164 { 165 DataContext newContext = context.cloneContext().addSegmentToDataPath(dataName); 166 dataToSAX(contentHandler, dataName, newContext); 167 } 168 } 169 170 @Override 171 public void dataToSAX(ContentHandler contentHandler, String dataPath, DataContext context) throws SAXException, UnknownTypeException, NotUniqueTypeException, BadItemTypeException 172 { 173 // Do not generate SAX events for view parameters 174 if (!ViewParametersManager.VIEW_PARAMETERS_COMPOSITE_NAME.equals(dataPath)) 175 { 176 super.dataToSAX(contentHandler, dataPath, context); 177 } 178 } 179 180 @Override 181 public Map<String, Object> dataToJSON(DataContext context) throws UnknownTypeException, NotUniqueTypeException, BadItemTypeException 182 { 183 Map<String, Object> result = new HashMap<>(); 184 for (String dataName : getDataNames()) 185 { 186 DataContext newContext = context.cloneContext().addSegmentToDataPath(dataName); 187 result.put(dataName, dataToJSON(dataName, newContext)); 188 } 189 190 return result; 191 } 192 193 @Override 194 public Object dataToJSON(String dataPath, DataContext context) throws UnknownTypeException, NotUniqueTypeException, BadItemTypeException 195 { 196 // Do not convert view parameters 197 return !ViewParametersManager.VIEW_PARAMETERS_COMPOSITE_NAME.equals(dataPath) 198 ? super.dataToJSON(dataPath, context) 199 : null; 200 } 201}