001/* 002 * Copyright 2015 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 */ 016 017package org.ametys.odf.catalog; 018 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.LinkedList; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025 026import org.apache.avalon.framework.component.Component; 027import org.apache.avalon.framework.context.Context; 028import org.apache.avalon.framework.context.ContextException; 029import org.apache.avalon.framework.context.Contextualizable; 030import org.apache.avalon.framework.service.ServiceException; 031import org.apache.avalon.framework.service.ServiceManager; 032import org.apache.avalon.framework.service.Serviceable; 033import org.apache.cocoon.ProcessingException; 034import org.apache.commons.lang.StringUtils; 035 036import org.ametys.core.ui.Callable; 037import org.ametys.core.user.CurrentUserProvider; 038import org.ametys.core.user.User; 039import org.ametys.core.user.UserIdentity; 040import org.ametys.core.user.UserManager; 041import org.ametys.odf.ProgramItem; 042import org.ametys.odf.export.pdf.GeneratePDFEngine; 043import org.ametys.odf.program.Program; 044import org.ametys.plugins.repository.AmetysObjectIterable; 045import org.ametys.plugins.repository.AmetysObjectIterator; 046import org.ametys.plugins.repository.AmetysObjectResolver; 047import org.ametys.plugins.repository.UnknownAmetysObjectException; 048import org.ametys.runtime.i18n.I18nizableText; 049 050/** 051 * DAO for manipulating catalogs. 052 * 053 */ 054public class CatalogDAO implements Serviceable, Component, Contextualizable 055{ 056 /** The Avalon role */ 057 public static final String ROLE = CatalogDAO.class.getName(); 058 059 /** The catalog manager */ 060 protected CatalogsManager _catalogsManager; 061 062 /** The ametys object resolver */ 063 protected AmetysObjectResolver _resolver; 064 065 /** The current user provider */ 066 protected CurrentUserProvider _currentUserProvider; 067 068 /** The users manager */ 069 protected UserManager _userManager; 070 071 /** The avalon context. */ 072 protected Context _context; 073 074 /** The manager */ 075 protected ServiceManager _manager; 076 077 @Override 078 public void contextualize(Context context) throws ContextException 079 { 080 _context = context; 081 } 082 083 @Override 084 public void service(ServiceManager manager) throws ServiceException 085 { 086 _catalogsManager = (CatalogsManager) manager.lookup(CatalogsManager.ROLE); 087 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 088 _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE); 089 _userManager = (UserManager) manager.lookup(UserManager.ROLE); 090 _manager = manager; 091 } 092 093 /** 094 * Creates a new ODF catalog. 095 * @param title The title of the catalog 096 * @param name The code of the catalog 097 * @param catalogNameToCopy The catalog name to copy or null 098 * @return The id and the title of the created catalog, or an error 099 * @throws ProcessingException if creation failed 100 */ 101 @Callable 102 public Map<String, String> createCatalog (String title, String name, String catalogNameToCopy) throws ProcessingException 103 { 104 Map<String, String> result = new HashMap<>(); 105 106 // FIXME CMS-5758 FilterNameHelper.filterName do not authorized name with number (so name is computed from JS) 107 108 Catalog catalog = _catalogsManager.getCatalog(name); 109 if (catalog != null) 110 { 111 result.put("message", "already-exist"); 112 return result; 113 } 114 115 Catalog newCatalog = _catalogsManager.createCatalog(name, title); 116 117 if (StringUtils.isNotEmpty(catalogNameToCopy)) 118 { 119 Catalog catalogToCopy = _catalogsManager.getCatalog(catalogNameToCopy); 120 121 if (catalogToCopy == null) 122 { 123 result.put("message", "not-found"); 124 return result; 125 } 126 127 _catalogsManager.copyCatalog(newCatalog, catalogToCopy); 128 } 129 130 newCatalog.saveChanges(); 131 132 result.put("id", newCatalog.getId()); 133 result.put("title", newCatalog.getTitle()); 134 135 return result; 136 } 137 138 /** 139 * Edits an ODF catalog. 140 * @param id The id of the catalog to edit 141 * @param title The title of the catalog 142 * @return The id and the title of the edited catalog, or an error 143 */ 144 @Callable 145 public Map<String, String> editCatalog (String id, String title) 146 { 147 Map<String, String> result = new HashMap<>(); 148 149 try 150 { 151 Catalog catalog = _resolver.resolveById(id); 152 153 catalog.setTitle(title); 154 catalog.saveChanges(); 155 156 result.put("id", catalog.getId()); 157 } 158 catch (UnknownAmetysObjectException e) 159 { 160 result.put("message", "not-found"); 161 } 162 163 return result; 164 } 165 166 /** 167 * Set a catalog as default catalog 168 * @param id The id of catalog 169 * @return The id and the title of the edited catalog, or an error 170 */ 171 @Callable 172 public synchronized Map<String, String> setDefaultCatalog(String id) 173 { 174 Map<String, String> result = new HashMap<>(); 175 176 try 177 { 178 Catalog catalog = _resolver.resolveById(id); 179 180 Catalog defaultCatalog = _catalogsManager.getDefaultCatalog(); 181 if (defaultCatalog != null) 182 { 183 defaultCatalog.setDefault(false); 184 defaultCatalog.saveChanges(); 185 } 186 catalog.setDefault(true); 187 catalog.saveChanges(); 188 189 _catalogsManager.updateDefaultCatalog(); 190 191 result.put("id", catalog.getId()); 192 } 193 catch (UnknownAmetysObjectException e) 194 { 195 result.put("message", "not-found"); 196 } 197 198 return result; 199 } 200 201 /** 202 * Removes an ODF catalog. 203 * @param id The id of the catalog to remove 204 * @return The id of the deleted catalog, or an error 205 */ 206 @Callable 207 public Map<String, Object> removeCatalog (String id) 208 { 209 Map<String, Object> result = new HashMap<>(); 210 211 result.put("id", id); 212 213 Catalog catalog = _resolver.resolveById(id); 214 215 AmetysObjectIterable<ProgramItem> programItems = _catalogsManager.getProgramItems(catalog.getName()); 216 AmetysObjectIterator<ProgramItem> it = programItems.iterator(); 217 218 if (it.hasNext()) 219 { 220 // Still referenced 221 result.put("error", new I18nizableText("plugin.odf", "PLUGINS_ODF_CATALOG_CATALOGACTIONS_DELETE_ERROR_STILL_REFERENCED")); 222 } 223 else 224 { 225 _catalogsManager.deleteCatalog(catalog.getId()); 226 } 227 228 return result; 229 } 230 231 /** 232 * Gets the properties of a catalog. 233 * @param id The catalog id 234 * @return The properties of the catalog in a map 235 */ 236 @Callable 237 public Map<String, Object> getCatalogProperties(String id) 238 { 239 Catalog catalog = _resolver.resolveById(id); 240 return getCatalogProperties(catalog); 241 } 242 243 /** 244 * Gets the properties of a set of catalogs. 245 * @param ids The catalogs' id 246 * @return The properties of the catalogs 247 */ 248 @Callable 249 public Map<String, Object> getCatalogsProperties(List<String> ids) 250 { 251 Map<String, Object> result = new HashMap<>(); 252 253 List<Map<String, Object>> catalogs = new LinkedList<>(); 254 Set<String> unknownCatalogs = new HashSet<>(); 255 256 for (String id : ids) 257 { 258 try 259 { 260 Catalog catalog = _resolver.resolveById(id); 261 catalogs.add(getCatalogProperties(catalog)); 262 } 263 catch (UnknownAmetysObjectException e) 264 { 265 unknownCatalogs.add(id); 266 } 267 } 268 269 result.put("catalogs", catalogs); 270 result.put("unknownCatalogs", unknownCatalogs); 271 272 return result; 273 } 274 275 /** 276 * Generates the PDF of this catalog. 277 * @param name The name (code) of the catalog to export 278 * @param contextualParameters the contextual parameters 279 * @return An empty map, or an error 280 */ 281 @Callable 282 public Map<String, Object> generatePDF(String name, Map<String, Object> contextualParameters) 283 { 284 Map<String, Object> result = new HashMap<>(); 285 286 if (GeneratePDFEngine.isRunning()) 287 { 288 result.put("message", "already-running"); 289 } 290 else 291 { 292 GeneratePDFEngine generatePDFEngine = new GeneratePDFEngine(); 293 294 UserIdentity identity = _currentUserProvider.getUser(); 295 User currentUser = _userManager.getUser(identity.getPopulationId(), identity.getLogin()); 296 297 generatePDFEngine.setContextualParameters(contextualParameters); 298 generatePDFEngine.setCatalog(name); 299 generatePDFEngine.setIssuer(currentUser); 300 301 try 302 { 303 // Initialize and configure the engine. 304 generatePDFEngine.initialize(_manager, _context); 305 306 // Create the thread, mark it as daemon and start it. 307 Thread engineThread = new Thread(generatePDFEngine, "GeneratePDFEngine"); 308 engineThread.setDaemon(true); 309 engineThread.start(); 310 } 311 catch (Exception e) 312 { 313 throw new RuntimeException("Unable to initialize the generate pdf engine", e); 314 } 315 } 316 317 return result; 318 } 319 320 /** 321 * Get the properties of a catalog as a Map 322 * @param catalog The catalog 323 * @return The properties into a map object 324 */ 325 public Map<String, Object> getCatalogProperties(Catalog catalog) 326 { 327 Map<String, Object> result = new HashMap<>(); 328 329 result.put("id", catalog.getId()); 330 result.put("title", catalog.getTitle()); 331 result.put("isDefault", catalog.isDefault()); 332 result.put("code", catalog.getName()); 333 334 AmetysObjectIterable<Program> programs = _catalogsManager.getPrograms(catalog.getName()); 335 result.put("nbPrograms", programs.getSize()); 336 337 return result; 338 } 339}