001/* 002 * Copyright 2018 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.plugins.ugc.page; 017 018import java.util.ArrayList; 019import java.util.Collections; 020import java.util.Locale; 021import java.util.Map; 022import java.util.Set; 023 024import org.ametys.cms.repository.Content; 025import org.ametys.plugins.explorer.resources.ResourceCollection; 026import org.ametys.plugins.repository.AmetysObject; 027import org.ametys.plugins.repository.AmetysObjectIterable; 028import org.ametys.plugins.repository.AmetysObjectResolver; 029import org.ametys.plugins.repository.AmetysRepositoryException; 030import org.ametys.plugins.repository.CollectionIterable; 031import org.ametys.plugins.repository.UnknownAmetysObjectException; 032import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder; 033import org.ametys.plugins.repository.data.holder.ModelLessDataHolder; 034import org.ametys.plugins.repository.data.holder.impl.DefaultModelLessDataHolder; 035import org.ametys.plugins.repository.data.repositorydata.RepositoryData; 036import org.ametys.plugins.repository.data.repositorydata.impl.MemoryRepositoryData; 037import org.ametys.plugins.repository.data.type.RepositoryModelItemType; 038import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint; 039import org.ametys.web.repository.page.Page; 040import org.ametys.web.repository.page.UnknownZoneException; 041import org.ametys.web.repository.page.Zone; 042import org.ametys.web.repository.site.Site; 043import org.ametys.web.repository.sitemap.Sitemap; 044import org.ametys.web.service.ServiceExtensionPoint; 045import org.ametys.web.skin.Skin; 046import org.ametys.web.skin.SkinsManager; 047 048/** 049 * Page representing an UGC page. 050 */ 051public class UGCPage implements Page 052{ 053 private static final String __UGC_PAGE_TEMPLATE = "ugc-page"; 054 055 private Page _root; 056 private String _title; 057 private AmetysObjectResolver _resolver; 058 private UGCPageHandler _ugcPageHandler; 059 private SkinsManager _skinsManager; 060 private String _path; 061 private Content _ugcContent; 062 private AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> _pageDataTypeExtensionPoint; 063 private AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> _zoneDataTypeExtensionPoint; 064 private ServiceExtensionPoint _serviceExtensionPoint; 065 private AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> _zoneItemDataTypeExtensionPoint; 066 067 /** 068 * Constructor. 069 * @param root the root page. 070 * @param syncContent the synchronized content 071 * @param path the path 072 * @param resolver the {@link AmetysObjectResolver}. 073 * @param ugcPageHandler the ugc page handler 074 * @param skinsManager the skins manager 075 * @param pageDataTypeExtensionPoint the extension point with available data types for pages 076 * @param zoneDataTypeExtensionPoint the extension point with available data types for zones 077 * @param serviceExtensionPoint the service extension point 078 * @param zoneItemDataTypeExtensionPoint the extension point with available data types for zone items 079 */ 080 public UGCPage(Page root, Content syncContent, String path, AmetysObjectResolver resolver, UGCPageHandler ugcPageHandler, SkinsManager skinsManager, AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> pageDataTypeExtensionPoint, AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> zoneDataTypeExtensionPoint, ServiceExtensionPoint serviceExtensionPoint, AbstractThreadSafeComponentExtensionPoint<RepositoryModelItemType> zoneItemDataTypeExtensionPoint) 081 { 082 _root = root; 083 _path = path; 084 _resolver = resolver; 085 _ugcPageHandler = ugcPageHandler; 086 _skinsManager = skinsManager; 087 _ugcContent = syncContent; 088 _title = _ugcContent.getTitle(new Locale(root.getSitemapName())); 089 090 _pageDataTypeExtensionPoint = pageDataTypeExtensionPoint; 091 _zoneDataTypeExtensionPoint = zoneDataTypeExtensionPoint; 092 _serviceExtensionPoint = serviceExtensionPoint; 093 _zoneItemDataTypeExtensionPoint = zoneItemDataTypeExtensionPoint; 094 } 095 096 /** 097 * Returns the associated UGC {@link Content}. 098 * @return the associated UGC {@link Content}. 099 */ 100 public Content getUgcContent() 101 { 102 return _ugcContent; 103 } 104 105 public int getDepth() throws AmetysRepositoryException 106 { 107 return _root.getDepth() + (_path.equals("_root") ? 1 : 2); 108 } 109 110 public Set<String> getReferers() throws AmetysRepositoryException 111 { 112 return null; 113 } 114 115 public ResourceCollection getRootAttachments() throws AmetysRepositoryException 116 { 117 return null; 118 } 119 120 public String getTemplate() throws AmetysRepositoryException 121 { 122 Skin skin = _skinsManager.getSkin(getSite().getSkinId()); 123 124 if (skin.getTemplate(__UGC_PAGE_TEMPLATE) != null) 125 { 126 return __UGC_PAGE_TEMPLATE; 127 } 128 129 return "page"; 130 } 131 132 public String getTitle() throws AmetysRepositoryException 133 { 134 return _title; 135 } 136 137 public String getLongTitle() throws AmetysRepositoryException 138 { 139 return _title; 140 } 141 142 public PageType getType() throws AmetysRepositoryException 143 { 144 return PageType.CONTAINER; 145 } 146 147 public String getURL() throws AmetysRepositoryException 148 { 149 throw new UnsupportedOperationException("#getURL is not supported on virtual ugc pages"); 150 } 151 152 public LinkType getURLType() throws AmetysRepositoryException 153 { 154 throw new UnsupportedOperationException("#getURLType is not supported on virtual ugc pages"); 155 } 156 157 public Zone getZone(String name) throws UnknownZoneException, AmetysRepositoryException 158 { 159 if (!"default".equals(name)) 160 { 161 throw new IllegalArgumentException("Only the zone named 'default' is actually supported on virtual ugc pages."); 162 } 163 164 return new UGCZone(this, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint); 165 } 166 167 public AmetysObjectIterable< ? extends Zone> getZones() throws AmetysRepositoryException 168 { 169 ArrayList<Zone> zones = new ArrayList<>(); 170 zones.add(new UGCZone(this, _zoneDataTypeExtensionPoint, _zoneItemDataTypeExtensionPoint)); 171 return new CollectionIterable<>(zones); 172 } 173 174 public boolean hasZone(String name) throws AmetysRepositoryException 175 { 176 return "default".equals(name); 177 } 178 179 public AmetysObjectIterable<? extends Page> getChildrenPages() throws AmetysRepositoryException 180 { 181 ArrayList<Page> children = new ArrayList<>(); 182 return new CollectionIterable<>(children); 183 } 184 185 public String getPathInSitemap() throws AmetysRepositoryException 186 { 187 if (_path.equals("_root")) 188 { 189 return _root.getPathInSitemap() + "/" + getName(); 190 } 191 else 192 { 193 return _root.getPathInSitemap() + "/" + _path + "/" + getName(); 194 } 195 } 196 197 public Site getSite() throws AmetysRepositoryException 198 { 199 return _root.getSite(); 200 } 201 202 public String getSiteName() throws AmetysRepositoryException 203 { 204 return _root.getSiteName(); 205 } 206 207 public Sitemap getSitemap() throws AmetysRepositoryException 208 { 209 return _root.getSitemap(); 210 } 211 212 public String getSitemapName() throws AmetysRepositoryException 213 { 214 return _root.getSitemapName(); 215 } 216 217 public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException 218 { 219 if (path.isEmpty()) 220 { 221 throw new AmetysRepositoryException("path must be non empty"); 222 } 223 224 return null; 225 } 226 227 @SuppressWarnings("unchecked") 228 public AmetysObjectIterable<? extends AmetysObject> getChildren() throws AmetysRepositoryException 229 { 230 return getChildrenPages(); 231 } 232 233 public boolean hasChild(String name) throws AmetysRepositoryException 234 { 235 return false; 236 } 237 238 public String getId() throws AmetysRepositoryException 239 { 240 return _ugcPageHandler.computePageId(_path, _root, _ugcContent); 241 } 242 243 public String getName() throws AmetysRepositoryException 244 { 245 return _ugcContent.getName(); 246 } 247 248 @SuppressWarnings("unchecked") 249 public Page getParent() throws AmetysRepositoryException 250 { 251 if (!_path.equals("_root")) 252 { 253 String name = _path; 254 Map<String, Map<String, String>> transitionalPageName = _ugcPageHandler.getTransitionalPage(_root); 255 Map<String, String> attributes = transitionalPageName.get(name); 256 String title = attributes.get(UGCPageHandler.ATTRIBUTE_TRANSITIONAL_PAGE_TITLE); 257 String metadataValue = attributes.get(UGCPageHandler.ATTRIBUTE_TRANSITIONAL_PAGE_METADATA_VALUE); 258 return new UGCTransitionalPage(_root, title, metadataValue, name, _resolver, _ugcPageHandler, _skinsManager, _pageDataTypeExtensionPoint, _zoneDataTypeExtensionPoint, _serviceExtensionPoint, _zoneItemDataTypeExtensionPoint); 259 } 260 else 261 { 262 return _root; 263 } 264 } 265 266 public String getParentPath() throws AmetysRepositoryException 267 { 268 if (!_path.equals("_root")) 269 { 270 return _root.getPath() + "/" + _path; 271 } 272 else 273 { 274 return _root.getPath(); 275 } 276 } 277 278 public String getPath() throws AmetysRepositoryException 279 { 280 return getParentPath() + "/" + getName(); 281 } 282 283 public ModelLessDataHolder getDataHolder() 284 { 285 RepositoryData repositoryData = new MemoryRepositoryData(getName()); 286 return new DefaultModelLessDataHolder(_pageDataTypeExtensionPoint, repositoryData); 287 } 288 289 public Set<String> getTags() throws AmetysRepositoryException 290 { 291 return Collections.emptySet(); 292 } 293 294 public AmetysObjectIterable< ? extends Page> getChildrenPages(boolean includeInvisiblePage) throws AmetysRepositoryException 295 { 296 ArrayList<Page> children = new ArrayList<>(); 297 return new CollectionIterable<>(children); 298 } 299 300 public boolean isVisible() throws AmetysRepositoryException 301 { 302 return true; 303 } 304 305 public Page getChildPageAt(int index) throws UnknownAmetysObjectException, AmetysRepositoryException 306 { 307 throw new UnknownAmetysObjectException("There is no child for ugc page"); 308 } 309 310 public ModelAwareDataHolder getTemplateParametersHolder() throws AmetysRepositoryException 311 { 312 return null; 313 } 314}