001/* 002 * Copyright 2011 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.blog.repository; 017 018import java.util.ArrayList; 019import java.util.Collections; 020import java.util.NoSuchElementException; 021import java.util.Set; 022import java.util.SortedSet; 023import java.util.TreeSet; 024 025import org.ametys.core.util.I18nUtils; 026import org.ametys.plugins.blog.BlogCacheManager; 027import org.ametys.plugins.explorer.resources.ResourceCollection; 028import org.ametys.plugins.repository.AmetysObject; 029import org.ametys.plugins.repository.AmetysObjectIterable; 030import org.ametys.plugins.repository.AmetysObjectIterator; 031import org.ametys.plugins.repository.AmetysObjectResolver; 032import org.ametys.plugins.repository.AmetysRepositoryException; 033import org.ametys.plugins.repository.CollectionIterable; 034import org.ametys.plugins.repository.EmptyIterable; 035import org.ametys.plugins.repository.UnknownAmetysObjectException; 036import org.ametys.plugins.repository.metadata.CompositeMetadata; 037import org.ametys.web.repository.page.Page; 038import org.ametys.web.repository.page.PagesContainer; 039import org.ametys.web.repository.page.UnknownZoneException; 040import org.ametys.web.repository.page.Zone; 041import org.ametys.web.repository.site.Site; 042import org.ametys.web.repository.sitemap.Sitemap; 043import org.ametys.web.site.SiteConfigurationExtensionPoint; 044import org.ametys.web.skin.SkinsManager; 045 046/** 047 * Virtual page representing the Post list by year page. 048 */ 049public class VirtualYearsPage implements Page 050{ 051 052 /** The page name. */ 053 public static final String NAME = "years"; 054 055 private AmetysObjectResolver _resolver; 056 private BlogCacheManager _cacheManager; 057 private I18nUtils _i18nUtils; 058 private String _i18nCatalogue; 059 private SiteConfigurationExtensionPoint _siteConf; 060 private PagesContainer _root; 061 private String _title; 062 private SkinsManager _skinsManager; 063 064 /** 065 * Constructor. 066 * @param resolver the {@link AmetysObjectResolver}. 067 * @param cacheManager the {@link BlogCacheManager}. 068 * @param skinsManager the {@link SkinsManager}. 069 * @param i18nCache the i18n utils 070 * @param i18nCatalogue the i18n catalogue. 071 * @param siteConf the site configuration 072 * @param root the blog root page. 073 * @param title the page's title. 074 */ 075 public VirtualYearsPage(AmetysObjectResolver resolver, BlogCacheManager cacheManager, SkinsManager skinsManager, I18nUtils i18nCache, String i18nCatalogue, SiteConfigurationExtensionPoint siteConf, String title, PagesContainer root) 076 { 077 _resolver = resolver; 078 _cacheManager = cacheManager; 079 _skinsManager = skinsManager; 080 _i18nUtils = i18nCache; 081 _i18nCatalogue = i18nCatalogue; 082 _siteConf = siteConf; 083 _root = root; 084 _title = title; 085 } 086 087 @Override 088 public int getDepth() throws AmetysRepositoryException 089 { 090 int depth = 0; 091 if (_root instanceof Page) 092 { 093 depth = ((Page) _root).getDepth(); 094 } 095 096 return depth + 1; 097 } 098 099 @Override 100 public Set<String> getReferers() throws AmetysRepositoryException 101 { 102 return null; 103 } 104 105 @Override 106 public ResourceCollection getRootAttachments() throws AmetysRepositoryException 107 { 108 return null; 109 } 110 111 @Override 112 public String getTemplate() throws AmetysRepositoryException 113 { 114 return null; 115 } 116 117 @Override 118 public String getTitle() throws AmetysRepositoryException 119 { 120 return _title; 121 } 122 123 @Override 124 public String getLongTitle() throws AmetysRepositoryException 125 { 126 return _title; 127 } 128 129 @Override 130 public PageType getType() throws AmetysRepositoryException 131 { 132 return PageType.NODE; 133 } 134 135 @Override 136 public String getURL() throws AmetysRepositoryException 137 { 138 throw new UnsupportedOperationException("getURL not supported on virtual blog pages"); 139 } 140 141 @Override 142 public LinkType getURLType() throws AmetysRepositoryException 143 { 144 throw new UnsupportedOperationException("getURLType not supported on virtual blog pages"); 145 } 146 147 @Override 148 public Zone getZone(String name) throws UnknownZoneException, AmetysRepositoryException 149 { 150 throw new UnknownZoneException("There is no zone on the blog years page."); 151 } 152 153 @Override 154 public AmetysObjectIterable< ? extends Zone> getZones() throws AmetysRepositoryException 155 { 156 return new EmptyIterable<>(); 157 } 158 159 @Override 160 public boolean hasZone(String name) throws AmetysRepositoryException 161 { 162 return false; 163 } 164 165 @Override 166 public AmetysObjectIterable<? extends Page> getChildrenPages() throws AmetysRepositoryException 167 { 168 ArrayList<Page> children = new ArrayList<>(); 169 170 SortedSet<Integer> years = new TreeSet<>(Collections.reverseOrder()); 171 years.addAll(_cacheManager.getYears(getSiteName(), getSitemapName())); 172 173 for (Integer year : years) 174 { 175 VirtualYearPage page = new VirtualYearPage(_resolver, _cacheManager, _skinsManager, _i18nUtils, _i18nCatalogue, _siteConf, year, Integer.toString(year), _root); 176 177 children.add(page); 178 } 179 180 return new CollectionIterable<>(children); 181 } 182 183 @Override 184 public AmetysObjectIterable< ? extends Page> getChildrenPages(boolean includeInvisiblePages) throws AmetysRepositoryException 185 { 186 return getChildrenPages(); 187 } 188 189 @Override 190 public Page getChildPageAt(int index) throws UnknownAmetysObjectException, AmetysRepositoryException 191 { 192 if (index < 0) 193 { 194 throw new AmetysRepositoryException("Child page index cannot be negative"); 195 } 196 197 AmetysObjectIterable< ? extends Page> childPages = getChildrenPages(); 198 AmetysObjectIterator< ? extends Page> it = childPages.iterator(); 199 200 try 201 { 202 it.skip(index); 203 return it.next(); 204 } 205 catch (NoSuchElementException e) 206 { 207 throw new UnknownAmetysObjectException("There's no child page at index " + index + " for page " + this.getId()); 208 } 209 } 210 211 @Override 212 public String getPathInSitemap() throws AmetysRepositoryException 213 { 214 StringBuilder path = new StringBuilder(_root.getPathInSitemap()); 215 if (path.length() > 0) 216 { 217 path.append('/'); 218 } 219 path.append(NAME); 220 221 return path.toString(); 222 } 223 224 @Override 225 public Site getSite() throws AmetysRepositoryException 226 { 227 return _root.getSite(); 228 } 229 230 @Override 231 public String getSiteName() throws AmetysRepositoryException 232 { 233 return _root.getSiteName(); 234 } 235 236 @Override 237 public Sitemap getSitemap() throws AmetysRepositoryException 238 { 239 return _root.getSitemap(); 240 } 241 242 @Override 243 public String getSitemapName() throws AmetysRepositoryException 244 { 245 return _root.getSitemapName(); 246 } 247 248 @SuppressWarnings("unchecked") 249 @Override 250 public <A extends AmetysObject> A getChild(String path) throws AmetysRepositoryException, UnknownAmetysObjectException 251 { 252 if (path.isEmpty()) 253 { 254 throw new AmetysRepositoryException("Path must be non empty"); 255 } 256 257 int slashPos = path.indexOf('/'); 258 259 String childName = slashPos == -1 ? path : path.substring(0, slashPos); 260 261 int year; 262 try 263 { 264 year = Integer.parseInt(childName); 265 } 266 catch (NumberFormatException e) 267 { 268 throw new AmetysRepositoryException(childName + " is not a valid year.", e); 269 } 270 271 VirtualYearPage page = new VirtualYearPage(_resolver, _cacheManager, _skinsManager, _i18nUtils, _i18nCatalogue, _siteConf, year, childName, _root); 272 273 if (slashPos == -1) 274 { 275 return (A) page; 276 } 277 else 278 { 279 return (A) page.getChild(path.substring(slashPos + 1)); 280 } 281 } 282 283 @SuppressWarnings("unchecked") 284 @Override 285 public AmetysObjectIterable<? extends AmetysObject> getChildren() throws AmetysRepositoryException 286 { 287 return getChildrenPages(); 288 } 289 290 @Override 291 public boolean hasChild(String name) throws AmetysRepositoryException 292 { 293 try 294 { 295 int year = Integer.parseInt(name); 296 297 return _cacheManager.hasYear(getSiteName(), getSitemapName(), year); 298 } 299 catch (NumberFormatException e) 300 { 301 // Ignore. 302 } 303 304 return false; 305 } 306 307 @Override 308 public String getId() throws AmetysRepositoryException 309 { 310 return "blog-category://" + NAME + "?rootId=" + _root.getId(); 311 } 312 313 @Override 314 public String getName() throws AmetysRepositoryException 315 { 316 return NAME; 317 } 318 319 @SuppressWarnings("unchecked") 320 @Override 321 public PagesContainer getParent() throws AmetysRepositoryException 322 { 323 return _root; 324 } 325 326 @Override 327 public String getParentPath() throws AmetysRepositoryException 328 { 329 return _root.getPath(); 330 } 331 332 @Override 333 public String getPath() throws AmetysRepositoryException 334 { 335 StringBuilder buff = new StringBuilder(getParentPath()); 336 if (!getParentPath().isEmpty()) 337 { 338 buff.append('/'); 339 } 340 buff.append(NAME); 341 342 return buff.toString(); 343 } 344 345 @Override 346 public CompositeMetadata getMetadataHolder() 347 { 348 return new StaticCompositeMetadata(); 349 } 350 351 @Override 352 public Set<String> getTags() throws AmetysRepositoryException 353 { 354 return Collections.emptySet(); 355 } 356 357 @Override 358 public boolean isVisible() throws AmetysRepositoryException 359 { 360 return true; 361 } 362}