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.plugins.newsletter.category; 017 018import java.util.ArrayList; 019import java.util.Arrays; 020import java.util.Collection; 021import java.util.List; 022 023import org.apache.avalon.framework.configuration.Configurable; 024import org.apache.avalon.framework.configuration.Configuration; 025import org.apache.avalon.framework.configuration.ConfigurationException; 026import org.apache.avalon.framework.logger.LogEnabled; 027import org.apache.avalon.framework.logger.Logger; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.avalon.framework.service.Serviceable; 031 032import org.ametys.cms.repository.Content; 033import org.ametys.cms.repository.ContentTypeExpression; 034import org.ametys.plugins.repository.AmetysObjectIterable; 035import org.ametys.plugins.repository.AmetysObjectResolver; 036import org.ametys.plugins.repository.UnknownAmetysObjectException; 037import org.ametys.plugins.repository.query.expression.AndExpression; 038import org.ametys.plugins.repository.query.expression.Expression; 039import org.ametys.plugins.repository.query.expression.Expression.Operator; 040import org.ametys.plugins.repository.query.expression.StringExpression; 041import org.ametys.runtime.i18n.I18nizableText; 042import org.ametys.runtime.plugin.component.PluginAware; 043import org.ametys.web.repository.page.ModifiablePage; 044import org.ametys.web.repository.page.Page; 045import org.ametys.web.repository.page.PageQueryHelper; 046import org.ametys.web.repository.page.jcr.DefaultPage; 047import org.ametys.web.tags.TagExpression; 048 049/** 050 * This class provides newsletter categories from the site map 051 * 052 */ 053public class SitemapCategoryProvider implements LogEnabled, CategoryProvider, Serviceable, Configurable, PluginAware 054{ 055 /** The root id */ 056 public static final String TAG_NAME = "NEWSLETTER_CATEGORY"; 057 /** The metadata name for newsletter template */ 058 public static final String METADATA_TEMPLATE = "newsletterTemplate"; 059 /** The metadata name for automatic newsletter ids. */ 060 public static final String METADATA_AUTOMATIC_IDS = "newsletterAutomaticIds"; 061 /** The metadata name for newsletter template */ 062 public static final String CATEGORY_PREFIX_ID = "category_"; 063 064 /** The id */ 065 protected String _id; 066 /** The label */ 067 protected I18nizableText _label; 068 /** The description */ 069 protected I18nizableText _description; 070 /** The plugin name */ 071 protected String _pluginName; 072 /** The feature name */ 073 protected String _featureName; 074 075 /** The Logger */ 076 protected Logger _logger; 077 078 private AmetysObjectResolver _resolver; 079 080 @Override 081 public void service(ServiceManager serviceManager) throws ServiceException 082 { 083 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 084 } 085 086 @Override 087 public void configure(Configuration configuration) throws ConfigurationException 088 { 089 _label = configureLabel(configuration); 090 _description = configureDescription(configuration); 091 } 092 093 public void enableLogging(Logger logger) 094 { 095 _logger = logger; 096 } 097 098 @Override 099 public boolean isWritable() 100 { 101 return false; 102 } 103 104 @Override 105 public List<Category> getCategories(String siteName, String lang) 106 { 107 TagExpression expr = new TagExpression(Operator.EQ, TAG_NAME); 108 String xpathQuery = PageQueryHelper.getPageXPathQuery(siteName, lang, "", expr, null); 109 110 List<Category> categories = new ArrayList<>(); 111 112 AmetysObjectIterable<DefaultPage> pages = _resolver.query(xpathQuery); 113 for (DefaultPage page : pages) 114 { 115 Category category = new Category(CATEGORY_PREFIX_ID + page.getId(), page.getName(), _id, new I18nizableText(page.getTitle()), null, page.getMetadataHolder().getString(METADATA_TEMPLATE, null), siteName, lang); 116 categories.add(category); 117 } 118 119 return categories; 120 } 121 122 @Override 123 public Collection<Category> getAllCategories(String siteName, String lang) 124 { 125 return getCategories(siteName, lang); 126 } 127 128 @Override 129 public List<Category> getCategories(String categoryID) 130 { 131 return new ArrayList<>(); 132 } 133 134 @Override 135 public boolean hasCategory(String categoryID) 136 { 137 if (categoryID.startsWith(CATEGORY_PREFIX_ID)) 138 { 139 String pageID = categoryID.substring(CATEGORY_PREFIX_ID.length()); 140 try 141 { 142 DefaultPage page = _resolver.resolveById(pageID); 143 if (page != null) 144 { 145 return page.getTags().contains(TAG_NAME); 146 } 147 } 148 catch (UnknownAmetysObjectException e) 149 { 150 // Page does not exist anymore 151 return false; 152 } 153 } 154 return false; 155 } 156 157 @Override 158 public Category getCategory(String categoryID) 159 { 160 if (categoryID.startsWith("category_")) 161 { 162 String pageID = categoryID.substring(CATEGORY_PREFIX_ID.length()); 163 DefaultPage page = _resolver.resolveById(pageID); 164 if (page != null && page.getTags().contains(TAG_NAME)) 165 { 166 return new Category(CATEGORY_PREFIX_ID + page.getId(), page.getName(), "provider_" + _id, new I18nizableText(page.getTitle()), new I18nizableText(""), page.getMetadataHolder().getString(METADATA_TEMPLATE, null), page.getSiteName(), page.getSitemapName()); 167 } 168 } 169 return null; 170 } 171 172 @Override 173 public void setTemplate(Category category, String templateName) 174 { 175 String categoryID = category.getId(); 176 if (categoryID.startsWith("category_")) 177 { 178 String pageID = categoryID.substring(CATEGORY_PREFIX_ID.length()); 179 ModifiablePage page = _resolver.resolveById(pageID); 180 if (page != null) 181 { 182 page.getMetadataHolder().setMetadata(METADATA_TEMPLATE, templateName); 183 page.saveChanges(); 184 } 185 } 186 } 187 188 @Override 189 public Collection<String> getAutomaticIds(String categoryId) 190 { 191 if (categoryId.startsWith("category_")) 192 { 193 String pageID = categoryId.substring(CATEGORY_PREFIX_ID.length()); 194 Page page = _resolver.resolveById(pageID); 195 if (page != null) 196 { 197 String[] autoIds = page.getMetadataHolder().getStringArray(METADATA_AUTOMATIC_IDS, new String[0]); 198 199 return Arrays.asList(autoIds); 200 } 201 } 202 203 // Either the category ID is not a page category, or the page doesn't exist. 204 throw new IllegalArgumentException("The provided category ID is invalid."); 205 } 206 207 @Override 208 public void setAutomatic(String categoryId, Collection<String> automaticNewsletterIds) 209 { 210 if (categoryId.startsWith("category_")) 211 { 212 String pageID = categoryId.substring(CATEGORY_PREFIX_ID.length()); 213 Page page = _resolver.resolveById(pageID); 214 if (page != null && page instanceof ModifiablePage) 215 { 216 ModifiablePage modifiablePage = (ModifiablePage) page; 217 218 // Convert to array. 219 String[] autoIdsArray = automaticNewsletterIds.toArray(new String[automaticNewsletterIds.size()]); 220 221 modifiablePage.getMetadataHolder().setMetadata(METADATA_AUTOMATIC_IDS, autoIdsArray); 222 modifiablePage.saveChanges(); 223 224 return; 225 } 226 } 227 228 // Either the category ID is not a page category, or the page doesn't exist. 229 throw new IllegalArgumentException("The provided category ID is invalid."); 230 } 231 232 @Override 233 public AmetysObjectIterable<Content> getNewsletters(String categoryID, String siteName, String lang) 234 { 235 Expression cTypeExpr = new ContentTypeExpression(Operator.EQ, "org.ametys.plugins.newsletter.Content.newsletter"); 236 Expression siteExpr = new StringExpression("site", Operator.EQ, siteName); 237 Expression catExpr = new StringExpression("category", Operator.EQ, categoryID); 238 Expression expr = new AndExpression(cTypeExpr, siteExpr, catExpr); 239 240 String xpathQuery = org.ametys.plugins.repository.query.QueryHelper.getXPathQuery(null, "ametys:content", expr); 241 return _resolver.query(xpathQuery); 242 } 243 244 @Override 245 public boolean hasChildren(String categoryID) 246 { 247 return false; 248 } 249 250 @Override 251 public boolean hasNewsletters(String categoryID, String siteName, String lang) 252 { 253 Expression expr = new ContentTypeExpression(Operator.EQ, "org.ametys.plugins.newsletter.Content.newsletter"); 254 Expression siteExpr = new StringExpression("site", Operator.EQ, siteName); 255 expr = new AndExpression(expr, siteExpr); 256 Expression catExpr = new StringExpression("category", Operator.EQ, categoryID); 257 expr = new AndExpression(expr, catExpr); 258 259 String xpathQuery = org.ametys.plugins.repository.query.QueryHelper.getXPathQuery(null, "ametys:content", expr); 260 261 return _resolver.query(xpathQuery).iterator().hasNext(); 262 } 263 264 /** 265 * Configure label from the passed configuration 266 * @param configuration The configuration 267 * @return The label 268 * @throws ConfigurationException If an error occurred 269 */ 270 protected I18nizableText configureLabel (Configuration configuration) throws ConfigurationException 271 { 272 Configuration labelConfiguration = configuration.getChild("label"); 273 274 if (labelConfiguration.getAttributeAsBoolean("i18n", false)) 275 { 276 return new I18nizableText("plugin." + _pluginName, labelConfiguration.getValue("")); 277 } 278 else 279 { 280 return new I18nizableText(labelConfiguration.getValue("")); 281 } 282 } 283 284 /** 285 * Configure description from the passed configuration 286 * @param configuration The configuration 287 * @return The description 288 * @throws ConfigurationException If an error occurred 289 */ 290 protected I18nizableText configureDescription (Configuration configuration) throws ConfigurationException 291 { 292 Configuration descConfiguration = configuration.getChild("description"); 293 294 if (descConfiguration.getAttributeAsBoolean("i18n", false)) 295 { 296 return new I18nizableText("plugin." + _pluginName, descConfiguration.getValue("")); 297 } 298 else 299 { 300 return new I18nizableText(descConfiguration.getValue("")); 301 } 302 } 303 304 public void setPluginInfo(String pluginName, String featureName, String id) 305 { 306 _pluginName = pluginName; 307 _featureName = featureName; 308 _id = id; 309 } 310 311 /** 312 * Get the plugin name 313 * @return the plugin name 314 */ 315 public String getPluginName() 316 { 317 return _pluginName; 318 } 319 320 @Override 321 public I18nizableText getDescription() 322 { 323 return _description; 324 } 325 326 @Override 327 public String getId() 328 { 329 return _id; 330 } 331 332 @Override 333 public I18nizableText getLabel() 334 { 335 return _label; 336 } 337 338 @Override 339 public String getRootId(String siteName, String lang) 340 { 341 return _id; 342 } 343}