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.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.runtime.model.type.DataContext; 049import org.ametys.web.parameters.view.ViewParametersManager; 050import org.ametys.web.parameters.view.ViewParametersModel; 051import org.ametys.web.repository.page.ModifiablePage; 052import org.ametys.web.repository.page.ModifiableZone; 053import org.ametys.web.repository.page.ModifiableZoneItem; 054import org.ametys.web.repository.page.SitemapElement; 055import org.ametys.web.repository.page.Zone; 056 057/** 058 * JCR implementation of an {@link Zone}. 059 */ 060public class DefaultZone extends DefaultTraversableAmetysObject<DefaultZoneFactory> implements ModifiableZone, CopiableAmetysObject 061{ 062 /** Constant for zone items node name */ 063 public static final String ZONEITEMS_NODE_NAME = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":zoneItems"; 064 /** Constant for zone item node name */ 065 public static final String ZONEITEM_NODE_NAME = RepositoryConstants.NAMESPACE_PREFIX + ":" + ZONEITEM_DATA_NAME; 066 /** Constant for zone items node type */ 067 public static final String ZONEITEM_NODETYPE_NAME = RepositoryConstants.NAMESPACE_PREFIX + ":zoneItem"; 068 069 private static final Logger __LOGGER = LoggerFactory.getLogger(DefaultZone.class); 070 071 /** 072 * Creates a {@link DefaultZone}. 073 * 074 * @param node the node backing this {@link AmetysObject}. 075 * @param parentPath the parent path in the Ametys hierarchy. 076 * @param factory the {@link DefaultZoneFactory} which creates the AmetysObject. 077 */ 078 public DefaultZone(Node node, String parentPath, DefaultZoneFactory factory) 079 { 080 super(node, parentPath, factory); 081 } 082 083 @Override 084 public AmetysObjectIterable<ModifiableZoneItem> getZoneItems() throws AmetysRepositoryException 085 { 086 return ((TraversableAmetysObject) getChild(ZONEITEMS_NODE_NAME)).getChildren(); 087 } 088 089 @Override 090 public ModifiableZoneItem addZoneItem() throws AmetysRepositoryException 091 { 092 return ((ModifiableTraversableAmetysObject) getChild(ZONEITEMS_NODE_NAME)).createChild(ZONEITEM_NODE_NAME, ZONEITEM_NODETYPE_NAME); 093 } 094 095 @Override 096 public SitemapElement getSitemapElement() 097 { 098 return getParent().getParent(); 099 } 100 101 @Override 102 public ModifiableZone copyTo(ModifiableTraversableAmetysObject parent, String name) throws AmetysRepositoryException 103 { 104 if (parent instanceof ModifiablePage) 105 { 106 ModifiableZone cZone = ((ModifiablePage) parent).createZone(getName()); 107 108 // Copy view parameters 109 getZoneParametersHolder().copyTo(cZone.getZoneParametersHolder()); 110 111 for (ModifiableZoneItem zoneItem : getZoneItems()) 112 { 113 if (zoneItem instanceof CopiableAmetysObject) 114 { 115 ((CopiableAmetysObject) zoneItem).copyTo((ModifiableTraversableAmetysObject) cZone, null); 116 } 117 } 118 return cZone; 119 } 120 else 121 { 122 throw new AmetysRepositoryException("Can not copy zone " + getId() + " of type DefaultZone to something that is not a ModifiablePage " + parent.getId()); 123 } 124 } 125 126 @Override 127 public AmetysObject copyTo(ModifiableTraversableAmetysObject parent, String name, List<String> restrictTo) throws AmetysRepositoryException 128 { 129 return copyTo(parent, name); 130 } 131 132 public ModifiableModelLessDataHolder getDataHolder() 133 { 134 ModifiableRepositoryData repositoryData = new JCRRepositoryData(getNode()); 135 return new DefaultModifiableModelLessDataHolder(_getFactory().getPageDataTypeExtensionPoint(), repositoryData); 136 } 137 138 @Override 139 public ModifiableCompositeMetadata getMetadataHolder() 140 { 141 __LOGGER.warn("The getMetadataHolder method of DefaultZone is deprecated. Use the getDataHolder instead. StackTrace: ", new Exception()); 142 return super.getMetadataHolder(); 143 } 144 145 public ModifiableModelAwareDataHolder getZoneParametersHolder() throws AmetysRepositoryException 146 { 147 JCRRepositoryData zoneRepositoryData = new JCRRepositoryData(getNode()); 148 149 // Get the zone Id 150 String zoneId = getName(); 151 152 // Get the template Id 153 SitemapElement sitemapElement = getSitemapElement(); 154 String templateId = sitemapElement.getTemplate(); 155 156 // Get the skin Id 157 String skinId = sitemapElement.getSite().getSkinId(); 158 159 ViewParametersManager viewParametersManager = _getFactory().getViewParametersManager(); 160 Optional<ViewParametersModel> zoneViewParameters = viewParametersManager.getZoneViewParametersModel(skinId, templateId, zoneId); 161 if (zoneViewParameters.isEmpty()) 162 { 163 zoneViewParameters = Optional.of(new ViewParametersModel("zone-no-param", new View(), MapUtils.EMPTY_SORTED_MAP)); 164 } 165 return viewParametersManager.getParametersHolder(zoneRepositoryData, zoneViewParameters.get()); 166 } 167 168 public void dataToSAX(ContentHandler contentHandler, DataContext context) throws SAXException, UnknownTypeException, NotUniqueTypeException 169 { 170 for (String dataName : getDataNames()) 171 { 172 DataContext newContext = context.cloneContext().addSegmentToDataPath(dataName); 173 dataToSAX(contentHandler, dataName, newContext); 174 } 175 } 176 177 public void dataToSAX(ContentHandler contentHandler, String dataPath, DataContext context) throws SAXException 178 { 179 // Do not generate SAX events for view parameters 180 if (!ViewParametersManager.VIEW_PARAMETERS_COMPOSITE_NAME.equals(dataPath)) 181 { 182 ModifiableZone.super.dataToSAX(contentHandler, dataPath, context); 183 } 184 } 185 186 public Map<String, Object> dataToJSON(DataContext context) throws UnknownTypeException, NotUniqueTypeException 187 { 188 Map<String, Object> result = new HashMap<>(); 189 for (String dataName : getDataNames()) 190 { 191 DataContext newContext = context.cloneContext().addSegmentToDataPath(dataName); 192 result.put(dataName, dataToJSON(dataName, newContext)); 193 } 194 195 return result; 196 } 197 198 public Object dataToJSON(String dataPath, DataContext context) 199 { 200 // Do not convert view parameters 201 return !ViewParametersManager.VIEW_PARAMETERS_COMPOSITE_NAME.equals(dataPath) 202 ? ModifiableZone.super.dataToJSON(dataPath, context) 203 : null; 204 } 205}