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