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 */ 016package org.ametys.plugins.workspaces.calendars; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.LinkedList; 021import java.util.List; 022import java.util.Map; 023import java.util.Objects; 024import java.util.UUID; 025 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.commons.lang3.BooleanUtils; 029import org.apache.commons.lang3.StringUtils; 030import org.apache.commons.lang3.Strings; 031import org.apache.jackrabbit.util.Text; 032 033import org.ametys.cms.fo.ForceDefaultRepositoryWorkspaceCallableDecorator; 034import org.ametys.core.observation.Event; 035import org.ametys.core.right.RightManager.RightResult; 036import org.ametys.core.ui.Callable; 037import org.ametys.core.user.UserIdentity; 038import org.ametys.plugins.explorer.ModifiableExplorerNode; 039import org.ametys.plugins.explorer.ObservationConstants; 040import org.ametys.plugins.explorer.resources.jcr.JCRResourcesCollection; 041import org.ametys.plugins.repository.AmetysObjectIterable; 042import org.ametys.plugins.repository.AmetysObjectIterator; 043import org.ametys.plugins.repository.ModifiableTraversableAmetysObject; 044import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject; 045import org.ametys.plugins.repository.query.QueryHelper; 046import org.ametys.plugins.repository.query.expression.Expression; 047import org.ametys.plugins.repository.query.expression.Expression.Operator; 048import org.ametys.plugins.repository.query.expression.StringExpression; 049import org.ametys.plugins.workspaces.calendars.Calendar.CalendarVisibility; 050import org.ametys.plugins.workspaces.calendars.events.CalendarEvent; 051import org.ametys.plugins.workspaces.calendars.events.CalendarEventJSONHelper; 052import org.ametys.plugins.workspaces.calendars.jcr.JCRCalendar; 053import org.ametys.plugins.workspaces.calendars.jcr.JCRCalendarFactory; 054import org.ametys.plugins.workspaces.calendars.task.TaskCalendar; 055import org.ametys.plugins.workspaces.project.objects.Project; 056import org.ametys.plugins.workspaces.tasks.TasksWorkspaceModule; 057import org.ametys.plugins.workspaces.tasks.WorkspaceTaskDAO; 058 059/** 060 * Calendar DAO 061 */ 062public class CalendarDAO extends AbstractCalendarDAO 063{ 064 /** Avalon Role */ 065 public static final String ROLE = CalendarDAO.class.getName(); 066 067 /** The tasks list JSON helper */ 068 protected CalendarEventJSONHelper _calendarEventJSONHelper; 069 070 /** The task DAO */ 071 protected WorkspaceTaskDAO _taskDAO; 072 073 @Override 074 public void service(ServiceManager manager) throws ServiceException 075 { 076 super.service(manager); 077 _calendarEventJSONHelper = (CalendarEventJSONHelper) manager.lookup(CalendarEventJSONHelper.ROLE); 078 _taskDAO = (WorkspaceTaskDAO) manager.lookup(WorkspaceTaskDAO.ROLE); 079 } 080 081 /** 082 * Get calendar info 083 * @param calendar The calendar 084 * @param recursive True to get data for sub calendars 085 * @param includeEvents True to also include child events 086 * @param useICSFormat true to use ICS Format for dates 087 * @return the calendar data in a map 088 */ 089 public Map<String, Object> getCalendarData(Calendar calendar, boolean recursive, boolean includeEvents, boolean useICSFormat) 090 { 091 Map<String, Object> result = new HashMap<>(); 092 093 result.put("id", calendar.getId()); 094 result.put("title", Text.unescapeIllegalJcrChars(calendar.getName())); 095 result.put("description", calendar.getDescription()); 096 result.put("templateDesc", calendar.getTemplateDescription()); 097 result.put("color", calendar.getColor()); 098 result.put("visibility", calendar.getVisibility().name().toLowerCase()); 099 result.put("public", calendar.getVisibility() == CalendarVisibility.PUBLIC); 100 101 if (calendar instanceof WorkflowAwareCalendar calendarWA) 102 { 103 result.put("workflowName", calendarWA.getWorkflowName()); 104 } 105 106 result.put("isTaskCalendar", calendar instanceof TaskCalendar); 107 result.put("isTaskCalendarDisabled", calendar instanceof TaskCalendar cal && cal.isDisabled()); 108 109 if (recursive) 110 { 111 List<Map<String, Object>> calendarList = new LinkedList<>(); 112 result.put("calendars", calendarList); 113 for (Calendar child : calendar.getChildCalendars()) 114 { 115 calendarList.add(getCalendarData(child, recursive, includeEvents, useICSFormat)); 116 } 117 } 118 119 if (includeEvents) 120 { 121 List<Map<String, Object>> eventList = new LinkedList<>(); 122 result.put("events", eventList); 123 124 for (CalendarEvent event : calendar.getAllEvents()) 125 { 126 eventList.add(_calendarEventJSONHelper.eventAsJson(event, useICSFormat)); 127 } 128 } 129 130 result.put("rights", _extractCalendarRightData(calendar)); 131 result.put("token", getCalendarIcsToken(calendar, true)); 132 133 134 return result; 135 } 136 137 /** 138 * Get calendar info 139 * @param calendar The calendar 140 * @return the calendar data in a map 141 */ 142 public Map<String, Object> getCalendarProperties(Calendar calendar) 143 { 144 return getCalendarData(calendar, false, false, false); 145 } 146 /** 147 * Add a calendar 148 * @param inputName The desired name for the calendar 149 * @param color The calendar color 150 * @param isPublic true if the calendar is public 151 * @return The result map with id, parentId and name keys 152 */ 153 @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 154 public Map<String, Object> addCalendar(String inputName, String color, boolean isPublic) 155 { 156 String rootId = _getCalendarRoot(true).getId(); 157 return addCalendar(rootId, inputName, StringUtils.EMPTY, StringUtils.EMPTY, color, isPublic ? CalendarVisibility.PUBLIC.name() : CalendarVisibility.PRIVATE.name(), "calendar-default", false); 158 } 159 160 /** 161 * Add a calendar 162 * @param id The identifier of the parent in which the calendar will be added 163 * @param inputName The desired name for the calendar 164 * @param description The calendar description 165 * @param templateDesc The calendar template description 166 * @param color The calendar color 167 * @param visibility The calendar visibility 168 * @param workflowName The calendar workflow name 169 * @param renameIfExists True to rename if existing 170 * @return The result map with id, parentId and name keys 171 */ 172 public Map<String, Object> addCalendar(String id, String inputName, String description, String templateDesc, String color, String visibility, String workflowName, Boolean renameIfExists) 173 { 174 return addCalendar(_resolver.resolveById(id), inputName, description, templateDesc, color, visibility, workflowName, renameIfExists, true, true); 175 } 176 177 /** 178 * Add a calendar 179 * @param parent The parent in which the calendar will be added 180 * @param inputName The desired name for the calendar 181 * @param description The calendar description 182 * @param templateDesc The calendar template description 183 * @param color The calendar color 184 * @param visibility The calendar visibility 185 * @param workflowName The calendar workflow name 186 * @param renameIfExists True to rename if existing 187 * @param checkRights true to check if the current user have enough rights to create the calendar 188 * @param notify True to notify the calendar creation 189 * @return The result map with id, parentId and name keys 190 */ 191 public Map<String, Object> addCalendar(ModifiableTraversableAmetysObject parent, String inputName, String description, String templateDesc, String color, String visibility, String workflowName, Boolean renameIfExists, Boolean checkRights, boolean notify) 192 { 193 String originalName = Text.escapeIllegalJcrChars(inputName); 194 195 // Check user right 196 if (checkRights) 197 { 198 _checkUserRights(parent, RIGHTS_CALENDAR_ADD); 199 } 200 201 if (BooleanUtils.isNotTrue(renameIfExists) && parent.hasChild(originalName)) 202 { 203 getLogger().warn("Cannot create the calendar with name '" + originalName + "', an object with same name already exists."); 204 return Map.of("message", "already-exist"); 205 } 206 207 if (!_explorerResourcesDAO.checkLock(parent)) 208 { 209 getLogger().warn("User '" + _currentUserProvider.getUser() + "' try to modify the object '" + parent.getName() + "' but it is locked by another user"); 210 return Map.of("message", "locked"); 211 } 212 213 int index = 2; 214 String name = originalName; 215 while (parent.hasChild(name)) 216 { 217 name = originalName + " (" + index + ")"; 218 index++; 219 } 220 221 JCRCalendar calendar = parent.createChild(name, JCRCalendarFactory.CALENDAR_NODETYPE); 222 calendar.setWorkflowName(workflowName); 223 calendar.setDescription(description); 224 calendar.setTemplateDescription(templateDesc); 225 calendar.setColor(color); 226 calendar.setVisibility(StringUtils.isNotEmpty(visibility) ? CalendarVisibility.valueOf(visibility.toUpperCase()) : CalendarVisibility.PRIVATE); 227 parent.saveChanges(); 228 229 // Notify listeners 230 Map<String, Object> eventParams = new HashMap<>(); 231 eventParams.put(ObservationConstants.ARGS_ID, calendar.getId()); 232 eventParams.put(ObservationConstants.ARGS_PARENT_ID, parent.getId()); 233 eventParams.put(ObservationConstants.ARGS_NAME, name); 234 eventParams.put(ObservationConstants.ARGS_PATH, calendar.getPath()); 235 236 if (notify) 237 { 238 _observationManager.notify(new Event(org.ametys.plugins.workspaces.calendars.ObservationConstants.EVENT_CALENDAR_CREATED, _currentUserProvider.getUser(), eventParams)); 239 } 240 241 return getCalendarProperties(calendar); 242 } 243 244 /** 245 * Edit a calendar 246 * @param id The identifier of the calendar 247 * @param inputName The new name 248 * @param templateDesc The new calendar template description 249 * @param color The calendar color 250 * @param isPublic true if the calendar is public 251 * @return The result map with id and name keys 252 */ 253 @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 254 public Map<String, Object> editCalendar(String id, String inputName, String templateDesc, String color, boolean isPublic) 255 { 256 CalendarVisibility visibility = isPublic ? CalendarVisibility.PUBLIC : CalendarVisibility.PRIVATE; 257 258 assert id != null; 259 String rename = Text.escapeIllegalJcrChars(inputName); 260 261 JCRCalendar calendar = _resolver.resolveById(id); 262 263 _checkUserRights(calendar, RIGHTS_CALENDAR_EDIT); 264 265 String name = calendar.getName(); 266 ModifiableTraversableAmetysObject parent = calendar.getParent(); 267 268 if (!Strings.CS.equals(rename, name) && parent.hasChild(rename)) 269 { 270 getLogger().warn("Cannot edit the calendar with the new name '" + inputName + "', an object with same name already exists."); 271 return Map.of("message", "already-exist"); 272 } 273 274 if (!_explorerResourcesDAO.checkLock(calendar)) 275 { 276 getLogger().warn("User '" + _currentUserProvider.getUser() + "' try to modify calendar '" + calendar.getName() + "' but it is locked by another user"); 277 return Map.of("message", "locked"); 278 } 279 280 if (!Strings.CS.equals(name, rename)) 281 { 282 int index = 2; 283 name = Text.escapeIllegalJcrChars(rename); 284 while (parent.hasChild(name)) 285 { 286 name = rename + " (" + index + ")"; 287 index++; 288 } 289 calendar.rename(name); 290 } 291 292 calendar.setTemplateDescription(templateDesc); 293 calendar.setColor(color); 294 calendar.setVisibility(visibility); 295 296 parent.saveChanges(); 297 298 // Notify listeners 299 Map<String, Object> eventParams = new HashMap<>(); 300 eventParams.put(ObservationConstants.ARGS_ID, calendar.getId()); 301 eventParams.put(ObservationConstants.ARGS_PARENT_ID, parent.getId()); 302 eventParams.put(ObservationConstants.ARGS_NAME, name); 303 eventParams.put(ObservationConstants.ARGS_PATH, calendar.getPath()); 304 305 _observationManager.notify(new Event(org.ametys.plugins.workspaces.calendars.ObservationConstants.EVENT_CALENDAR_UPDATED, _currentUserProvider.getUser(), eventParams)); 306 307 return getCalendarProperties(calendar); 308 } 309 310 /** 311 * Edit the task calendar 312 * @param inputName the input name 313 * @param color the color 314 * @param isPublic <code>true</code> if the calendar is public 315 * @param disabled <code>true</code> if the calendar is disabled 316 * @return the calendar properties 317 * @throws IllegalAccessException if a right error occurred 318 */ 319 @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 320 public Map<String, Object> editTaskCalendar(String inputName, String color, boolean isPublic, boolean disabled) throws IllegalAccessException 321 { 322 Project project = _workspaceHelper.getProjectFromRequest(); 323 TaskCalendar taskCalendar = getTaskCalendar(project, false); 324 325 // Check user right 326 _checkUserRights(_getCalendarRoot(project, false), RIGHTS_CALENDAR_EDIT); 327 328 if (taskCalendar != null) 329 { 330 taskCalendar.rename(inputName); 331 taskCalendar.setColor(color); 332 taskCalendar.setVisibility(isPublic ? CalendarVisibility.PUBLIC : CalendarVisibility.PRIVATE); 333 taskCalendar.disable(disabled); 334 } 335 return getCalendarProperties(taskCalendar); 336 } 337 338 /** 339 * Delete a calendar 340 * @param id The id of the calendar 341 * @return The result map with id, parent id and message keys 342 */ 343 @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 344 public Map<String, Object> deleteCalendar(String id) 345 { 346 Map<String, Object> result = new HashMap<>(); 347 348 assert id != null; 349 350 JCRCalendar calendar = _resolver.resolveById(id); 351 352 _checkUserRights(calendar, RIGHTS_CALENDAR_DELETE); 353 354 if (!_explorerResourcesDAO.checkLock(calendar)) 355 { 356 getLogger().warn("User '" + _currentUserProvider.getUser() + "' try to delete calendar'" + calendar.getName() + "' but it is locked by another user"); 357 result.put("message", "locked"); 358 return result; 359 } 360 361 ModifiableExplorerNode parent = calendar.getParent(); 362 String parentId = parent.getId(); 363 String name = calendar.getName(); 364 String path = calendar.getPath(); 365 366 calendar.remove(); 367 parent.saveChanges(); 368 369 // Notify listeners 370 Map<String, Object> eventParams = new HashMap<>(); 371 eventParams.put(ObservationConstants.ARGS_ID, id); 372 eventParams.put(ObservationConstants.ARGS_PARENT_ID, parentId); 373 eventParams.put(ObservationConstants.ARGS_NAME, name); 374 eventParams.put(ObservationConstants.ARGS_PATH, path); 375 376 _observationManager.notify(new Event(org.ametys.plugins.workspaces.calendars.ObservationConstants.EVENT_CALENDAR_DELETED, _currentUserProvider.getUser(), eventParams)); 377 378 result.put("id", id); 379 result.put("parentId", parentId); 380 381 return result; 382 } 383 384 /** 385 * Get or create the calendar ICS token 386 * @param calendar The calendar 387 * @param createIfNotExisting Create the token if none exists for the given calendar 388 * @return The token 389 */ 390 public String getCalendarIcsToken(Calendar calendar, boolean createIfNotExisting) 391 { 392 String token = calendar.getIcsUrlToken(); 393 394 if (createIfNotExisting && token == null && calendar instanceof JCRCalendar) 395 { 396 token = UUID.randomUUID().toString(); 397 ((JCRCalendar) calendar).setIcsUrlToken(token); 398 ((JCRCalendar) calendar).saveChanges(); 399 } 400 401 return token; 402 } 403 404 /** 405 * Retrieve the calendar for the matching ICS token 406 * @param token The ICS token 407 * @return The calendar, or null if not found 408 */ 409 public Calendar getCalendarFromIcsToken(String token) 410 { 411 if (StringUtils.isEmpty(token)) 412 { 413 return null; 414 } 415 416 Expression expr = new StringExpression(JCRCalendar.CALENDAR_ICS_TOKEN, Operator.EQ, token); 417 String calendarsQuery = QueryHelper.getXPathQuery(null, JCRCalendarFactory.CALENDAR_NODETYPE, expr); 418 AmetysObjectIterable<JCRCalendar> calendars = _resolver.query(calendarsQuery); 419 AmetysObjectIterator<JCRCalendar> calendarsIterator = calendars.iterator(); 420 421 if (calendarsIterator.getSize() > 0) 422 { 423 return calendarsIterator.next(); 424 } 425 426 // Don't find a token in default calendars, so check in the task calendars 427 return _projectManager.getProjects() 428 .stream() 429 .map(p -> this.getTaskCalendar(p, true)) 430 .filter(Objects::nonNull) 431 .filter(c -> c.getIcsUrlToken().equals(token)) 432 .findFirst() 433 .orElse(null); 434 } 435 436 /** 437 * Internal method to extract the data concerning the right of the current user for a calendar 438 * @param calendar The calendar 439 * @return The map of right data. Keys are the rights id, and values indicates whether the current user has the right or not. 440 */ 441 protected Map<String, Object> _extractCalendarRightData(Calendar calendar) 442 { 443 Map<String, Object> rightsData = new HashMap<>(); 444 445 UserIdentity user = _currentUserProvider.getUser(); 446 boolean isTaskCalendar = calendar instanceof TaskCalendar; 447 448 // Add 449 rightsData.put("add-event", !isTaskCalendar && _rightManager.hasRight(user, RIGHTS_EVENT_ADD, calendar) == RightResult.RIGHT_ALLOW); 450 451 // edit - delete 452 rightsData.put("edit", !isTaskCalendar && _rightManager.hasRight(user, RIGHTS_CALENDAR_EDIT, calendar) == RightResult.RIGHT_ALLOW); 453 rightsData.put("delete", !isTaskCalendar && _rightManager.hasRight(user, RIGHTS_CALENDAR_DELETE, calendar) == RightResult.RIGHT_ALLOW); 454 455 return rightsData; 456 } 457 458 /** 459 * Get the data of every available calendar for the current project 460 * @return the list of calendars 461 */ 462 @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 463 public List<Map<String, Object>> getCalendars() 464 { 465 Project project = _workspaceHelper.getProjectFromRequest(); 466 467 _checkReadAccess(project, CalendarWorkspaceModule.CALENDAR_MODULE_ID); 468 469 List<Map<String, Object>> calendarsData = new ArrayList<>(); 470 CalendarWorkspaceModule calendarModule = (CalendarWorkspaceModule) _workspaceModuleEP.getModule(CalendarWorkspaceModule.CALENDAR_MODULE_ID); 471 472 for (Calendar calendar : calendarModule.getCalendars(project, true)) 473 { 474 if (calendarModule.canView(calendar)) 475 { 476 calendarsData.add(this.getCalendarProperties(calendar)); 477 } 478 } 479 480 return calendarsData; 481 } 482 483 /** 484 * Get the colors of calendars 485 * @return colors 486 */ 487 @Callable (rights = Callable.NO_CHECK_REQUIRED, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 488 public Map<String, CalendarColorsComponent.CalendarColor> getColors() 489 { 490 return _calendarColors.getColors(); 491 } 492 493 /** 494 * Get user rights on root calendar of current project 495 * @return the user rights 496 */ 497 @Callable (rights = Callable.NO_CHECK_REQUIRED, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 498 public Map<String, Object> getUserRights() 499 { 500 Map<String, Object> results = new HashMap<>(); 501 ModifiableTraversableAmetysObject calendarRoot = _getCalendarRoot(false); 502 503 UserIdentity user = _currentUserProvider.getUser(); 504 results.put("canCreateCalendar", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_CALENDAR_ADD, calendarRoot) == RightResult.RIGHT_ALLOW); 505 results.put("canEditCalendar", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_CALENDAR_EDIT, calendarRoot) == RightResult.RIGHT_ALLOW); 506 results.put("canRemoveCalendar", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_CALENDAR_DELETE, calendarRoot) == RightResult.RIGHT_ALLOW); 507 results.put("canCreateEvent", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_EVENT_ADD, calendarRoot) == RightResult.RIGHT_ALLOW); 508 results.put("canEditEvent", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_EVENT_EDIT, calendarRoot) == RightResult.RIGHT_ALLOW); 509 results.put("canRemoveAnyEvent", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_EVENT_DELETE, calendarRoot) == RightResult.RIGHT_ALLOW); 510 results.put("canRemoveSelfEvent", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_EVENT_DELETE_OWN, calendarRoot) == RightResult.RIGHT_ALLOW); 511 results.put("canHandleResource", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_HANDLE_RESOURCE, calendarRoot) == RightResult.RIGHT_ALLOW); 512 results.put("canBookResource", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_BOOK_RESOURCE, calendarRoot) == RightResult.RIGHT_ALLOW); 513 results.put("sharePrivateCalendar", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_EVENT_EDIT, calendarRoot) == RightResult.RIGHT_ALLOW); 514 results.put("canExportICSLink", calendarRoot != null && _rightManager.hasRight(user, RIGHTS_EXPORT_ICS_LINK, calendarRoot) == RightResult.RIGHT_ALLOW); 515 516 return results; 517 } 518 519 /** 520 * Get the calendar root 521 * @param createIfNotExist true to create root if not exist yet 522 * @return the calendar root 523 */ 524 protected ModifiableTraversableAmetysObject _getCalendarRoot(boolean createIfNotExist) 525 { 526 return _getCalendarRoot(_workspaceHelper.getProjectFromRequest(), createIfNotExist); 527 } 528 529 /** 530 * Get the calendar root form the project 531 * @param project the project 532 * @param createIfNotExist true to create root if not exist yet 533 * @return the calendar root 534 */ 535 protected ModifiableTraversableAmetysObject _getCalendarRoot(Project project, boolean createIfNotExist) 536 { 537 CalendarWorkspaceModule calendarModule = (CalendarWorkspaceModule) _workspaceModuleEP.getModule(CalendarWorkspaceModule.CALENDAR_MODULE_ID); 538 return calendarModule.getCalendarsRoot(project, createIfNotExist); 539 } 540 541 /** 542 * Get the data of calendar used to store resources 543 * @return the calendar used to store resources 544 */ 545 @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 546 public Map<String, Object> getResourceCalendar() 547 { 548 Project project = _workspaceHelper.getProjectFromRequest(); 549 _checkReadAccess(project, CalendarWorkspaceModule.CALENDAR_MODULE_ID); 550 551 CalendarWorkspaceModule calendarModule = (CalendarWorkspaceModule) _workspaceModuleEP.getModule(CalendarWorkspaceModule.CALENDAR_MODULE_ID); 552 Calendar calendar = calendarModule.getResourceCalendar(project); 553 554 return this.getCalendarProperties(calendar); 555 } 556 557 /** 558 * Get the task calendar 559 * @param project the project 560 * @param onlyIfEnabled <code>true</code> to return the task calendar only if it is enabled 561 * @return the task calendar 562 */ 563 public TaskCalendar getTaskCalendar(Project project, boolean onlyIfEnabled) 564 { 565 if (_projectManager.isModuleActivated(project, TasksWorkspaceModule.TASK_MODULE_ID) && _projectManager.isModuleActivated(project, CalendarWorkspaceModule.CALENDAR_MODULE_ID)) 566 { 567 JCRResourcesCollection root = (JCRResourcesCollection) _getCalendarRoot(project, false); 568 TaskCalendar calendar = new TaskCalendar(project, root, _taskDAO); 569 return !onlyIfEnabled || !calendar.isDisabled() ? calendar : null; 570 } 571 572 return null; 573 } 574 575 /** 576 * <code>true</code> if the current user has read access on the task calendar 577 * @param project the project 578 * @return <code>true</code> if the current user has read access on the task calendar 579 */ 580 public boolean hasTaskCalendarReadAccess(Project project) 581 { 582 TasksWorkspaceModule taskModule = (TasksWorkspaceModule) _workspaceModuleEP.getModule(TasksWorkspaceModule.TASK_MODULE_ID); 583 DefaultTraversableAmetysObject tasksRoot = taskModule.getTasksRoot(project, false); 584 if (tasksRoot == null) 585 { 586 return false; 587 } 588 return _rightManager.currentUserHasReadAccess(tasksRoot); 589 } 590}