private void onCommentChanged(GwtConversation conversation, Comment comment, Map properties) {
   conversation.getProject().updateHomepage(comment.getParent(), false);
   if (comment.isPublished() && properties.containsKey("published")) {
     subscriptionService.notifySubscribers(
         comment.getParent(),
         "New comment posted by " + comment.getAuthorLabel(),
         conversation.getProject(),
         null);
   }
 }
 @Override
 public void onPublishRelease(GwtConversation conversation, String releaseId) {
   Project project = conversation.getProject();
   Release release = (Release) getDaoService().getEntityById(releaseId);
   if (!release.isProject(project)) throw new PermissionDeniedException();
   release.release(project, conversation.getSession().getUser(), webApplication);
 }
 private void onTaskChanged(GwtConversation conversation, Task task, Map properties) {
   // update sprint day snapshot after change
   conversation
       .getProject()
       .getCurrentSprint()
       .getDaySnapshot(Date.today())
       .updateWithCurrentSprint();
   Requirement requirement = task.getRequirement();
   if (requirement.isInCurrentSprint()) {
     User currentUser = conversation.getSession().getUser();
     if (task.isClosed() && properties.containsKey("remainingWork")) {
       String event = currentUser.getName() + " closed " + task.getReferenceAndLabel();
       if (requirement.isTasksClosed()) {
         event += ", all tasks closed in " + requirement.getReferenceAndLabel();
       }
       postProjectEvent(conversation, event, task);
     } else if (task.isOwnerSet() && properties.containsKey("ownerId")) {
       postProjectEvent(
           conversation, currentUser.getName() + " claimed " + task.getReferenceAndLabel(), task);
     }
     if (!task.isOwnerSet() && properties.containsKey("ownerId")) {
       postProjectEvent(
           conversation,
           currentUser.getName() + " unclaimed " + task.getReferenceAndLabel(),
           task);
     }
     if (!task.isClosed() && requirement.isRejectDateSet()) {
       requirement.setRejectDate(null);
       sendToClients(conversation, requirement);
     }
   }
 }
 @Override
 public void onRequestReleaseIssues(GwtConversation conversation, String releaseId) {
   assertProjectSelected(conversation);
   Project project = conversation.getProject();
   Release release = releaseDao.getById(releaseId);
   if (!release.isProject(project)) throw new PermissionDeniedException();
   conversation.sendToClient(release.getIssues());
 }
 @Override
 public void onSearch(GwtConversation conversation, String text) {
   Project project = conversation.getProject();
   if (project == null) return;
   List<AEntity> foundEntities = project.search(text);
   log.debug("Found entities for search", "\"" + text + "\"", "->", foundEntities);
   conversation.sendToClient(foundEntities);
 }
 @Override
 public void onRequestRequirementEstimationVotes(
     GwtConversation conversation, String requirementId) {
   assertProjectSelected(conversation);
   Project project = conversation.getProject();
   Requirement requirement = requirementDao.getById(requirementId);
   if (!requirement.isProject(project)) throw new PermissionDeniedException();
   conversation.sendToClient(requirement.getEstimationVotes());
 }
 @Override
 public void onCloseProject(GwtConversation conversation) {
   Project project = conversation.getProject();
   if (project != null && conversation.getSession().getGwtConversations().size() < 2) {
     ProjectUserConfig config = project.getUserConfig(conversation.getSession().getUser());
     config.reset();
     sendToClients(conversation, config);
   }
   conversation.clearRemoteEntities();
   conversation.setProject(null);
 }
 @Override
 public void onActivateRequirementEstimationVoting(
     GwtConversation conversation, String requirementId) {
   Requirement requirement = requirementDao.getById(requirementId);
   if (requirement == null || !requirement.isProject(conversation.getProject()))
     throw new PermissionDeniedException();
   requirement.initializeEstimationVotes();
   requirement.setWorkEstimationVotingActive(true);
   requirement.setWorkEstimationVotingShowoff(false);
   sendToClients(conversation, requirement);
   sendToClients(conversation, requirement.getEstimationVotes());
 }
 @Override
 public void onRequestHistory(GwtConversation conversation) {
   assertProjectSelected(conversation);
   Project project = conversation.getProject();
   Set<SprintReport> reports = project.getSprintReports();
   Set<AEntity> entities = new HashSet<AEntity>();
   entities.addAll(reports);
   for (SprintReport report : reports) {
     entities.addAll(getAssociatedEntities(report));
   }
   conversation.sendToClient(entities);
 }
Exemple #10
0
  private void postProjectEvent(GwtConversation conversation, String message, AEntity subject) {
    assertProjectSelected(conversation);
    Project project = conversation.getProject();
    webApplication.postProjectEvent(project, message, subject);

    try {
      sendProjectEventEmails(
          message, subject, project, conversation.getSession().getUser().getEmail());
    } catch (Throwable ex) {
      log.error("Sending project event notification emails failed.", ex);
    }
  }
Exemple #11
0
  @Override
  public void onRequestEntityByReference(GwtConversation conversation, String reference) {
    assertProjectSelected(conversation);
    Project project = conversation.getProject();

    AEntity entity = project.getEntityByReference(reference);
    if (entity == null) {
      log.info("Requested entity not found:", reference);
    } else {
      conversation.sendToClient(entity);
      conversation.sendToClient(getAssociatedEntities(entity));
    }
  }
Exemple #12
0
  @Override
  public void onDeleteEntity(GwtConversation conversation, String entityId) {
    AEntity entity = getDaoService().getEntityById(entityId);
    User user = conversation.getSession().getUser();
    if (!Auth.isDeletable(entity, user)) throw new PermissionDeniedException();

    if (entity instanceof File) {
      File file = (File) entity;
      file.deleteFile();
    }

    if (entity instanceof Task) {
      // update sprint day snapshot before delete
      conversation
          .getProject()
          .getCurrentSprint()
          .getDaySnapshot(Date.today())
          .updateWithCurrentSprint();
    }

    ADao dao = getDaoService().getDao(entity);
    dao.deleteEntity(entity);

    if (entity instanceof Task) onTaskDeleted(conversation, (Task) entity);

    Project project = conversation.getProject();
    if (project != null) {
      for (GwtConversation c : webApplication.getConversationsByProject(project, conversation)) {
        c.getNextData().addDeletedEntity(entityId);
      }
    }

    if (user != null && project != null) {
      ProjectUserConfig config = project.getUserConfig(user);
      config.touch();
      sendToClients(conversation, config);
    }
  }
Exemple #13
0
 @Override
 public void onRequestForum(GwtConversation conversation, boolean all) {
   Project project = conversation.getProject();
   Set<AEntity> parents = new HashSet<AEntity>();
   for (Subject subject : project.getSubjects()) {
     if (subject.getComments().isEmpty()) parents.add(subject);
   }
   for (Comment comment : project.getLatestComments()) {
     AEntity parent = comment.getParent();
     if (!all
         && !conversation.isAvailableOnClient(parent)
         && comment.getDateAndTime().getPeriodToNow().abs().toDays() > 7) continue;
     conversation.sendToClient(comment);
     parents.add(parent);
   }
   conversation.sendToClient(parents);
 }
Exemple #14
0
 private void onTaskDeleted(GwtConversation conversation, Task task) {
   // update sprint day snapshot after delete
   conversation
       .getProject()
       .getCurrentSprint()
       .getDaySnapshot(Date.today())
       .updateWithCurrentSprint();
   Requirement requirement = task.getRequirement();
   if (requirement.isInCurrentSprint()) {
     if (task.isOwnerSet()) {
       postProjectEvent(
           conversation,
           conversation.getSession().getUser().getName()
               + " deleted "
               + task.getReferenceAndLabel(),
           task);
     }
   }
 }
Exemple #15
0
  @Override
  public void onPullStoryToSprint(GwtConversation conversation, String storyId) {
    assertProjectSelected(conversation);
    Requirement story = requirementDao.getById(storyId);
    Project project = conversation.getProject();
    Sprint sprint = project.getCurrentSprint();
    User currentUser = conversation.getSession().getUser();

    sprint.pullRequirement(story, currentUser);

    postProjectEvent(
        conversation,
        currentUser.getName() + " pulled " + story.getReferenceAndLabel() + " to current sprint",
        story);

    sendToClients(conversation, sprint);
    sendToClients(conversation, story);
    sendToClients(conversation, story.getTasksInSprint());
  }
Exemple #16
0
 @Override
 public void onSwitchToNextSprint(GwtConversation conversation) {
   assertProjectSelected(conversation);
   Project project = conversation.getProject();
   Sprint oldSprint = project.getCurrentSprint();
   for (Requirement requirement : oldSprint.getRequirements()) {
     if (!requirement.isClosed()) {
       requirement.setDirty(true);
       sendToClients(conversation, requirement);
     }
   }
   Sprint newSprint = project.switchToNextSprint();
   postProjectEvent(
       conversation, conversation.getSession().getUser() + " switched to next sprint ", newSprint);
   sendToClients(conversation, project.getSprints());
   sendToClients(conversation, project.getSprintReports());
   sendToClients(conversation, project.getRequirements());
   sendToClients(conversation, project.getTasks()); // TODO optimize: no history tasks
   sendToClients(conversation, oldSprint.getReleases());
   sendToClients(conversation, project);
 }
Exemple #17
0
 @Override
 public void onConvertIssueToStory(GwtConversation conversation, String issueId) {
   Issue issue = issueDao.getById(issueId);
   Requirement story = requirementDao.postRequirement(issue);
   issue.appendToStatement("Created Story " + story.getReference() + " in Product Backlog.");
   issue.setCloseDate(Date.today());
   sendToClients(conversation, story);
   sendToClients(conversation, issue);
   User currentUser = conversation.getSession().getUser();
   postProjectEvent(
       conversation,
       currentUser.getName()
           + " created "
           + story.getReference()
           + " from "
           + issue.getReferenceAndLabel(),
       issue);
   changeDao.postChange(issue, currentUser, "storyId", null, story.getId());
   changeDao.postChange(story, currentUser, "issueId", null, issue.getId());
   subscriptionService.copySubscribers(issue, story);
   subscriptionService.notifySubscribers(
       story, "Story created from " + issue, conversation.getProject(), null);
 }
Exemple #18
0
 @Override
 public void onSendIssueReplyEmail(
     GwtConversation conversation,
     String issueId,
     String from,
     String to,
     String subject,
     String text) {
   assertProjectSelected(conversation);
   Issue issue = issueDao.getById(issueId);
   if (Str.isEmail(from)) {
     emailSender.sendEmail(conversation.getProject(), to, subject, text);
   } else {
     emailSender.sendEmail(from, to, subject, text);
   }
   User user = conversation.getSession().getUser();
   postProjectEvent(
       conversation,
       user.getName() + " emailed a response to " + issue.getReferenceAndLabel(),
       issue);
   Change change = changeDao.postChange(issue, user, "@reply", null, text);
   conversation.sendToClient(change);
 }
Exemple #19
0
 private void assertProjectSelected(GwtConversation conversation) {
   if (conversation.getProject() == null) throw new RuntimeException("No project selected.");
 }
Exemple #20
0
  @Override
  public void onCreateEntity(GwtConversation conversation, String type, Map properties) {
    String id = (String) properties.get("id");
    if (id == null) throw new NullPointerException("id == null");

    ADao dao = getDaoService().getDaoByName(type);
    AEntity entity = dao.newEntityInstance(id);
    entity.updateProperties(properties);
    User currentUser = conversation.getSession().getUser();
    Project currentProject = conversation.getProject();

    if (entity instanceof Numbered) {
      ((Numbered) entity).updateNumber();
    }

    if (entity instanceof Project) {
      Project project = (Project) entity;
      project.addParticipant(currentUser);
      project.addAdmin(currentUser);
      project.addProductOwner(currentUser);
      project.addScrumMaster(currentUser);
      project.addTeamMember(currentUser);
    }

    if (entity instanceof Comment) {
      Comment comment = (Comment) entity;
      comment.setDateAndTime(DateAndTime.now());
      postProjectEvent(
          conversation,
          comment.getAuthor().getName() + " commented on " + comment.getParent(),
          comment.getParent());
      currentProject.updateHomepage(comment.getParent(), true);
    }

    if (entity instanceof ChatMessage) {
      ChatMessage chatMessage = (ChatMessage) entity;
      chatMessage.setDateAndTime(DateAndTime.now());
    }

    if (entity instanceof Impediment) {
      Impediment impediment = (Impediment) entity;
      impediment.setDate(Date.today());
    }

    if (entity instanceof Issue) {
      Issue issue = (Issue) entity;
      issue.setDate(DateAndTime.now());
      issue.setCreator(currentUser);
    }

    if (entity instanceof Task) {
      Task task = (Task) entity;
      Requirement requirement = task.getRequirement();
      requirement.setRejectDate(null);
      requirement.setClosed(false);
      sendToClients(conversation, requirement);
    }

    if (entity instanceof BlogEntry) {
      BlogEntry blogEntry = (BlogEntry) entity;
      blogEntry.setDateAndTime(DateAndTime.now());
      blogEntry.addAuthor(currentUser);
    }

    if (entity instanceof Change) {
      Change change = (Change) entity;
      change.setDateAndTime(DateAndTime.now());
      change.setUser(currentUser);
    }

    if (!(entity instanceof Transient)) dao.saveEntity(entity);

    sendToClients(conversation, entity);

    if (entity instanceof Requirement) {
      Requirement requirement = (Requirement) entity;
      Requirement epic = requirement.getEpic();
      String value = null;
      if (epic != null) {
        value = epic.getReferenceAndLabel();
        Change change =
            changeDao.postChange(epic, currentUser, "@split", null, requirement.getReference());
        conversation.sendToClient(change);
      }
      Change change = changeDao.postChange(requirement, currentUser, "@created", null, value);
      conversation.sendToClient(change);
    }

    if (entity instanceof Task
        || entity instanceof Wikipage
        || entity instanceof Risk
        || entity instanceof Impediment
        || entity instanceof Issue
        || entity instanceof BlogEntry) {
      Change change = changeDao.postChange(entity, currentUser, "@created", null, null);
      conversation.sendToClient(change);
    }

    if (currentUser != null && currentProject != null) {
      ProjectUserConfig config = currentProject.getUserConfig(currentUser);
      config.touch();
      sendToClients(conversation, config);
    }
  }
Exemple #21
0
  @Override
  public void onChangeProperties(GwtConversation conversation, String entityId, Map properties) {
    AEntity entity = getDaoService().getEntityById(entityId);
    User currentUser = conversation.getSession().getUser();
    if (!Auth.isEditable(entity, currentUser)) throw new PermissionDeniedException();

    Sprint previousRequirementSprint =
        entity instanceof Requirement ? ((Requirement) entity).getSprint() : null;

    if (entity instanceof Requirement) {
      postChangeIfChanged(conversation, entity, properties, currentUser, "label");
      postChangeIfChanged(conversation, entity, properties, currentUser, "description");
      postChangeIfChanged(conversation, entity, properties, currentUser, "testDescription");
      postChangeIfChanged(conversation, entity, properties, currentUser, "sprintId");
      postChangeIfChanged(conversation, entity, properties, currentUser, "closed");
      postChangeIfChanged(conversation, entity, properties, currentUser, "issueId");
    }
    Project project = conversation.getProject();
    if (entity instanceof Task) {
      // update sprint day snapshot before change
      if (project.isCurrentSprintSet())
        project.getCurrentSprint().getDaySnapshot(Date.today()).updateWithCurrentSprint();
      postChangeIfChanged(conversation, entity, properties, currentUser, "label");
      postChangeIfChanged(conversation, entity, properties, currentUser, "description");
    }
    if (entity instanceof Wikipage) {
      postChangeIfChanged(conversation, entity, properties, currentUser, "text");
    }
    if (entity instanceof Risk) {
      postChangeIfChanged(conversation, entity, properties, currentUser, "description");
      postChangeIfChanged(conversation, entity, properties, currentUser, "probability");
      postChangeIfChanged(conversation, entity, properties, currentUser, "impact");
      postChangeIfChanged(conversation, entity, properties, currentUser, "probabilityMitigation");
      postChangeIfChanged(conversation, entity, properties, currentUser, "impactMitigation");
    }
    if (entity instanceof Impediment) {
      postChangeIfChanged(conversation, entity, properties, currentUser, "description");
      postChangeIfChanged(conversation, entity, properties, currentUser, "solution");
      postChangeIfChanged(conversation, entity, properties, currentUser, "closed");
    }
    if (entity instanceof Issue) {
      postChangeIfChanged(conversation, entity, properties, currentUser, "description");
      postChangeIfChanged(conversation, entity, properties, currentUser, "statement");
      postChangeIfChanged(conversation, entity, properties, currentUser, "closeDate");
      postChangeIfChanged(conversation, entity, properties, currentUser, "storyId");
    }
    if (entity instanceof BlogEntry) {
      postChangeIfChanged(conversation, entity, properties, currentUser, "text");
    }

    entity.updateProperties(properties);

    if (entity instanceof Task) onTaskChanged(conversation, (Task) entity, properties);
    if (entity instanceof Requirement)
      onRequirementChanged(
          conversation, (Requirement) entity, properties, previousRequirementSprint);
    if (entity instanceof Impediment)
      onImpedimentChanged(conversation, (Impediment) entity, properties);
    if (entity instanceof Issue) onIssueChanged(conversation, (Issue) entity, properties);
    if (entity instanceof BlogEntry)
      onBlogEntryChanged(conversation, (BlogEntry) entity, properties);
    if (entity instanceof Comment) onCommentChanged(conversation, (Comment) entity, properties);
    if (entity instanceof SystemConfig)
      onSystemConfigChanged(conversation, (SystemConfig) entity, properties);
    if (entity instanceof Wikipage) onWikipageChanged(conversation, (Wikipage) entity, properties);

    Project currentProject = project;
    if (currentUser != null && currentProject != null) {
      ProjectUserConfig config = currentProject.getUserConfig(currentUser);
      config.touch();
      sendToClients(conversation, config);
    }

    conversation.clearRemoteEntitiesByType(Change.class);
    sendToClients(conversation, entity);
  }
Exemple #22
0
 @Override
 public void onUpdateProjectHomepage(GwtConversation conversation) {
   assertProjectSelected(conversation);
   Project project = conversation.getProject();
   project.updateHomepage();
 }
Exemple #23
0
 @Override
 public void onRequestClosedIssues(GwtConversation conversation) {
   assertProjectSelected(conversation);
   Project project = conversation.getProject();
   conversation.sendToClient(project.getClosedIssues());
 }
Exemple #24
0
  private void onRequirementChanged(
      GwtConversation conversation,
      Requirement requirement,
      Map properties,
      Sprint previousRequirementSprint) {
    Project currentProject = conversation.getProject();
    Sprint sprint = requirement.getSprint();
    boolean inCurrentSprint = sprint != null && currentProject.isCurrentSprint(sprint);
    User currentUser = conversation.getSession().getUser();

    if (properties.containsKey("description")
        || properties.containsKey("testDescription")
        || properties.containsKey("qualitysIds")) {
      requirement.setDirty(true);
      conversation.sendToClient(requirement);
    }

    if (properties.containsKey("rejectDate") && requirement.isRejectDateSet()) {
      postProjectEvent(
          conversation,
          currentUser.getName() + " rejected " + requirement.getReferenceAndLabel(),
          requirement);
    }

    if (properties.containsKey("accepted") && requirement.isRejectDateSet()) {
      postProjectEvent(
          conversation,
          currentUser.getName() + " accepted " + requirement.getReferenceAndLabel(),
          requirement);
    }

    if (sprint != previousRequirementSprint) {
      if (properties.containsKey("sprintId")) {
        if (inCurrentSprint) {
          postProjectEvent(
              conversation,
              currentUser.getName()
                  + " pulled "
                  + requirement.getReferenceAndLabel()
                  + " to current sprint",
              requirement);
          subscriptionService.notifySubscribers(
              requirement, "Story pulled to current Sprint", conversation.getProject(), null);
        } else {
          postProjectEvent(
              conversation,
              currentUser.getName()
                  + " kicked "
                  + requirement.getReferenceAndLabel()
                  + " from current sprint",
              requirement);
          subscriptionService.notifySubscribers(
              requirement, "Story kicked from current Sprint", conversation.getProject(), null);
        }
      }
    }

    if (properties.containsKey("estimatedWork")) {
      requirement.initializeEstimationVotes();
      requirement.setDirty(false);
      requirement.setWorkEstimationVotingShowoff(false);
      requirement.setWorkEstimationVotingActive(false);
      conversation.sendToClient(requirement);
    }

    requirement.getProject().getCurrentSprintSnapshot().update();
  }
Exemple #25
0
 @Override
 public void onTouchLastActivity(GwtConversation conversation) {
   Project project = conversation.getProject();
   if (project == null) return;
   project.getUserConfig(conversation.getSession().getUser()).touch();
 }
Exemple #26
0
  private void onIssueChanged(GwtConversation conversation, Issue issue, Map properties) {
    User currentUser = conversation.getSession().getUser();

    if (properties.containsKey("closeDate")) {
      if (issue.isClosed()) {
        issue.setCloseDate(Date.today());
        postProjectEvent(
            conversation, currentUser.getName() + " closed " + issue.getReferenceAndLabel(), issue);
        subscriptionService.notifySubscribers(
            issue, "Issue closed", conversation.getProject(), null);
      } else {
        postProjectEvent(
            conversation,
            currentUser.getName() + " reopened " + issue.getReferenceAndLabel(),
            issue);
        subscriptionService.notifySubscribers(
            issue, "Issue reopened", conversation.getProject(), null);
      }
    }

    if (properties.containsKey("ownerId") && issue.isOwnerSet()) {
      if (!issue.isFixed()) {
        postProjectEvent(
            conversation,
            currentUser.getName() + " claimed " + issue.getReferenceAndLabel(),
            issue);
      }

      Release nextRelease = issue.getProject().getNextRelease();
      if (nextRelease != null && issue.isFixReleasesEmpty()) {
        issue.setFixReleases(Collections.singleton(nextRelease));
      }
    }

    if (properties.containsKey("fixDate")) {
      if (issue.isFixed()) {
        postProjectEvent(
            conversation, currentUser.getName() + " fixed " + issue.getReferenceAndLabel(), issue);
      } else {
        postProjectEvent(
            conversation,
            currentUser.getName() + " rejected fix for " + issue.getReferenceAndLabel(),
            issue);
      }
    }

    if (properties.containsKey("urgent")) {
      if (issue.isBug()) {
        Release currentRelease = issue.getProject().getCurrentRelease();
        if (issue.isAffectedReleasesEmpty() && currentRelease != null) {
          issue.setAffectedReleases(Collections.singleton(currentRelease));
        }
      }
    }

    if (properties.containsKey("acceptDate")) {
      if (issue.isIdea() || issue.isBug()) {
        postProjectEvent(
            conversation,
            currentUser.getName() + " accepted " + issue.getReferenceAndLabel(),
            issue);
        subscriptionService.notifySubscribers(
            issue, "Issue accepted", conversation.getProject(), null);
      }
    }

    issue.getProject().updateHomepage(issue, false);
  }