public boolean hasMoreActivities() {
    int loadedActivitiesCount = (activityPageIndex + 1) * ACTIVITY_COUNT_PER_LOAD;
    int totalActivitiesCount =
        activityServiceImpl.getActivityCountByActor(authenticatedAccount.getPerson().getId());

    return ((loadedActivitiesCount < totalActivitiesCount)
        && (loadedActivitiesCount < MAX_ACTIVITIES_COUNT_PER_PAGE));
  }
 public List<Activity> getActivities() {
   if (authenticatedAccount != null) {
     int count = (activityPageIndex + 1) * ACTIVITY_COUNT_PER_LOAD;
     return activityServiceImpl.findLatestActivities(
         authenticatedAccount.getPerson().getId(), 0, count);
   }
   return Collections.emptyList();
 }
  @Override
  @Transactional
  public HDocument saveDocument(
      String projectSlug,
      String iterationSlug,
      Resource sourceDoc,
      Set<String> extensions,
      boolean copyTrans) {
    // Only active iterations allow the addition of a document
    HProjectIteration hProjectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);

    // Check permission
    identity.checkPermission(hProjectIteration, "import-template");

    String docId = sourceDoc.getName();

    HDocument document = documentDAO.getByDocIdAndIteration(hProjectIteration, docId);
    HLocale hLocale = this.localeServiceImpl.validateSourceLocale(sourceDoc.getLang());

    boolean changed = false;
    int nextDocRev;
    if (document == null) { // must be a create operation
      nextDocRev = 1;
      changed = true;
      // TODO check that entity name matches id parameter
      document = new HDocument(sourceDoc.getName(), sourceDoc.getContentType(), hLocale);
      document.setProjectIteration(hProjectIteration);
      hProjectIteration.getDocuments().put(docId, document);
      document = documentDAO.makePersistent(document);
    } else if (document.isObsolete()) { // must also be a create operation
      nextDocRev = document.getRevision() + 1;
      changed = true;
      document.setObsolete(false);
      // not sure if this is needed
      hProjectIteration.getDocuments().put(docId, document);
    } else { // must be an update operation
      nextDocRev = document.getRevision() + 1;
    }

    changed |=
        resourceUtils.transferFromResource(sourceDoc, document, extensions, hLocale, nextDocRev);
    documentDAO.flush();

    long actorId = authenticatedAccount.getPerson().getId();
    if (changed) {
      documentUploadedEvent.fireAfterSuccess(
          new DocumentUploadedEvent(actorId, document.getId(), true, hLocale.getLocaleId()));
      clearStatsCacheForUpdatedDocument(document);
    }

    if (copyTrans && nextDocRev == 1) {
      copyTranslations(document);
    }

    return document;
  }
  public static boolean isUserCoordinatorOfLanguage(HLocale lang) {
    HAccount authenticatedAccount = getAuthenticatedAccount();
    PersonDAO personDAO = (PersonDAO) Component.getInstance(PersonDAO.class);

    if (authenticatedAccount != null) {
      return personDAO.isUserInLanguageTeamWithRoles(
          authenticatedAccount.getPerson(), lang, null, null, true);
    }

    return false; // No authenticated user
  }
 @Restrict("#{s:hasPermission(versionGroupMaintainerManageAction.group,'update')}")
 public String addMaintainers(String account) {
   HAccount a = accountDAO.getByUsername(account);
   if (a == null) {
     FacesMessages.instance().add("This account does not exist.");
     return "failure";
   } else if (a.isEnabled()) {
     HIterationGroup iterationGroup = versionGroupServiceImpl.getBySlug(this.slug);
     Set<HPerson> personList = iterationGroup.getMaintainers();
     personList.add(a.getPerson());
     versionGroupServiceImpl.makePersistent(iterationGroup);
     versionGroupServiceImpl.flush();
     log.debug("add {0} into maintainers", account);
     return "success";
   } else {
     FacesMessages.instance().add("This account is disabled.");
     return "failure";
   }
 }
 // TODO should we fire an event when username/name/email is changed (rare)?
 private void cacheUserDetails() {
   if (cachedUsername == null) {
     cachedUsername = getCredentials().getUsername();
   }
   if (cachedPersonName == null) {
     HAccount account = accountDAO.getByUsername(cachedUsername);
     if (account != null) {
       HPerson person = account.getPerson();
       if (person != null) {
         cachedPersonName = person.getName();
         cachedPersonEmail = person.getEmail();
       } else {
         cachedPersonEmail = null;
       }
     } else {
       cachedPersonEmail = null;
     }
   }
 }
  public Integer runCopyTrans(
      HLocale targetLocale,
      HCopyTransOptions options,
      HDocument document,
      boolean requireTranslationReview,
      List<HTextFlow> copyTargets) {
    int numCopied = 0;
    boolean checkContext = false, checkProject = false, checkDocument = false;

    // Only outright reject copies if the options say so
    if (options.getDocIdMismatchAction() == HCopyTransOptions.ConditionRuleAction.REJECT) {
      checkDocument = true;
    }
    if (options.getProjectMismatchAction() == HCopyTransOptions.ConditionRuleAction.REJECT) {
      checkProject = true;
    }
    if (options.getContextMismatchAction() == HCopyTransOptions.ConditionRuleAction.REJECT) {
      checkContext = true;
    }

    Long actorId = authenticatedAccount.getPerson().getId();
    for (HTextFlow textFlow : copyTargets) {
      if (shouldFindMatch(textFlow, targetLocale, requireTranslationReview)) {

        Optional<HTextFlowTarget> bestMatch =
            translationFinder.searchBestMatchTransMemory(
                textFlow,
                targetLocale.getLocaleId(),
                document.getLocale().getLocaleId(),
                checkContext,
                checkDocument,
                checkProject);
        if (bestMatch.isPresent()) {
          numCopied++;

          saveCopyTransMatch(actorId, bestMatch.get(), textFlow, options, requireTranslationReview);
        }
      }
    }
    return numCopied;
  }
  private Integer mergeTranslations(
      final Long sourceVersionId,
      final Long targetVersionId,
      final int batchStart,
      final int batchLength,
      final boolean useNewerTranslation,
      final List<HLocale> supportedLocales)
      throws Exception {

    final Stopwatch stopwatch = Stopwatch.createUnstarted();
    stopwatch.start();

    List<HTextFlow[]> matches =
        textFlowDAO.getSourceByMatchedContext(
            sourceVersionId, targetVersionId, batchStart, batchLength);

    Multimap<DocumentLocaleKey, TextFlowTargetStateChange> eventMap = HashMultimap.create();

    Map<DocumentLocaleKey, Map<ContentState, Long>> docStatsMap = Maps.newHashMap();

    Map<DocumentLocaleKey, Long> lastUpdatedTargetId = Maps.newHashMap();
    ;

    for (HTextFlow[] results : matches) {
      HTextFlow sourceTf = results[0];
      HTextFlow targetTf = results[1];
      boolean foundChange = false;
      Map<Long, ContentState> localeContentStateMap = Maps.newHashMap();

      for (HLocale hLocale : supportedLocales) {
        HTextFlowTarget sourceTft = sourceTf.getTargets().get(hLocale.getId());
        // only process translated state
        if (sourceTft == null || !sourceTft.getState().isTranslated()) {
          continue;
        }

        HTextFlowTarget targetTft = targetTf.getTargets().get(hLocale.getId());
        if (targetTft == null) {
          targetTft = new HTextFlowTarget(targetTf, hLocale);
          targetTft.setVersionNum(0);
          targetTf.getTargets().put(hLocale.getId(), targetTft);
        }

        if (MergeTranslationsServiceImpl.shouldMerge(sourceTft, targetTft, useNewerTranslation)) {
          foundChange = true;

          ContentState oldState = targetTft.getState();
          localeContentStateMap.put(hLocale.getId(), oldState);
          mergeTextFlowTarget(sourceTft, targetTft);
        }
      }
      if (foundChange) {
        translationStateCacheImpl.clearDocumentStatistics(targetTf.getDocument().getId());
        textFlowDAO.makePersistent(targetTf);
        textFlowDAO.flush();

        for (Map.Entry<Long, ContentState> entry : localeContentStateMap.entrySet()) {
          HTextFlowTarget updatedTarget = targetTf.getTargets().get(entry.getKey());

          DocumentLocaleKey key =
              new DocumentLocaleKey(
                  targetTf.getDocument().getId(), updatedTarget.getLocale().getLocaleId());

          eventMap.put(
              key,
              new TextFlowTargetStateEvent.TextFlowTargetStateChange(
                  targetTf.getId(),
                  updatedTarget.getId(),
                  updatedTarget.getState(),
                  entry.getValue()));

          lastUpdatedTargetId.put(key, updatedTarget.getId());

          Map<ContentState, Long> contentStateDeltas =
              docStatsMap.get(key) == null ? Maps.newHashMap() : docStatsMap.get(key);

          DocStatsEvent.updateContentStateDeltas(
              contentStateDeltas,
              updatedTarget.getState(),
              entry.getValue(),
              targetTf.getWordCount());

          docStatsMap.put(key, contentStateDeltas);
        }
      }
    }
    Long actorId = authenticatedAccount.getPerson().getId();
    for (Map.Entry<DocumentLocaleKey, Collection<TextFlowTargetStateChange>> entry :
        eventMap.asMap().entrySet()) {
      TextFlowTargetStateEvent tftUpdatedEvent =
          new TextFlowTargetStateEvent(
              entry.getKey(), targetVersionId, actorId, ImmutableList.copyOf(entry.getValue()));
      textFlowTargetStateEvent.fire(tftUpdatedEvent);
    }
    for (Map.Entry<DocumentLocaleKey, Map<ContentState, Long>> entry : docStatsMap.entrySet()) {
      DocStatsEvent docEvent =
          new DocStatsEvent(
              entry.getKey(),
              targetVersionId,
              entry.getValue(),
              lastUpdatedTargetId.get(entry.getKey()));
      docStatsEvent.fire(docEvent);
    }
    stopwatch.stop();
    log.info(
        "Complete merge translations of {} in {}",
        matches.size() * supportedLocales.size(),
        stopwatch);
    return matches.size() * supportedLocales.size();
  }