private void signalCopiedTranslation( HTextFlowTarget target, ContentState previousState, Long wordCount) { /* * Using a direct method call instead of an event because it's easier to * read. Since these events are being called synchronously (as opposed * to an 'after Transaction' events), there is no big performance gain * and makes the code easier to read and navigate. */ // TODO how was this not causing duplicate events? Is this bypassing TranslationServiceImpl? // FIXME other observers may not be notified HDocument document = target.getTextFlow().getDocument(); DocumentLocaleKey key = new DocumentLocaleKey(document.getId(), target.getLocaleId()); Map<ContentState, Long> contentStates = Maps.newHashMap(); DocStatsEvent.updateContentStateDeltas( contentStates, target.getState(), previousState, wordCount); DocStatsEvent docEvent = new DocStatsEvent( key, document.getProjectIteration().getId(), contentStates, target.getId()); versionStateCacheImpl.docStatsUpdated(docEvent); }
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(); }