Package org.zanata.service.impl

Source Code of org.zanata.service.impl.TranslationStateCacheImpl$DocumentLocaleKey

/*
* Copyright 2010, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.zanata.service.impl;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import net.sf.ehcache.CacheManager;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.zanata.cache.CacheWrapper;
import org.zanata.cache.EhcacheWrapper;
import org.zanata.common.LocaleId;
import org.zanata.dao.DocumentDAO;
import org.zanata.dao.LocaleDAO;
import org.zanata.dao.TextFlowDAO;
import org.zanata.dao.TextFlowTargetDAO;
import org.zanata.events.TextFlowTargetStateEvent;
import org.zanata.model.HDocument;
import org.zanata.model.HLocale;
import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
import org.zanata.service.TranslationStateCache;
import org.zanata.service.ValidationFactoryProvider;
import org.zanata.ui.model.statistic.WordStatistic;
import org.zanata.util.ServiceLocator;
import org.zanata.webtrans.shared.model.DocumentId;
import org.zanata.webtrans.shared.model.DocumentStatus;
import org.zanata.webtrans.shared.model.ValidationAction;
import org.zanata.webtrans.shared.model.ValidationId;

import com.google.common.cache.CacheLoader;

/**
* Default Implementation of the Translation State Cache.
*
* @author Carlos Munoz <a
*         href="mailto:camunoz@redhat.com">camunoz@redhat.com</a>
*/
@Name("translationStateCacheImpl")
// TODO split into APPLICATION and STATELESS beans
@Scope(ScopeType.APPLICATION)
@AutoCreate
public class TranslationStateCacheImpl implements TranslationStateCache {
    private static final String BASE = TranslationStateCacheImpl.class.getName();

    private static final String DOC_STATISTIC_CACHE_NAME = BASE
            + ".documentStatisticCache";

    private static final String DOC_STATUS_CACHE_NAME = BASE
            + ".docStatusCache";

    private static final String TFT_VALIDATION_CACHE_NAME = BASE
            + ".targetValidationCache";

    private CacheManager cacheManager;

    private CacheWrapper<DocumentLocaleKey, WordStatistic> documentStatisticCache;
    private CacheLoader<DocumentLocaleKey, WordStatistic> documentStatisticLoader;

    private CacheWrapper<DocumentLocaleKey, DocumentStatus> docStatusCache;
    private CacheLoader<DocumentLocaleKey, DocumentStatus> docStatusLoader;

    private CacheWrapper<Long, Map<ValidationId, Boolean>> targetValidationCache;
    private CacheLoader<Long, Map<ValidationId, Boolean>> targetValidationLoader;

    @In
    private ServiceLocator serviceLocator;

    // constructor for Seam
    public TranslationStateCacheImpl() {
        this(new DocumentStatisticLoader(), new HTextFlowTargetIdLoader(),
                new HTextFlowTargetValidationLoader());
    }

    // Constructor for testing
    public TranslationStateCacheImpl(
        CacheLoader<DocumentLocaleKey, WordStatistic> documentStatisticLoader,
        CacheLoader<DocumentLocaleKey, DocumentStatus> docStatsLoader,
        CacheLoader<Long, Map<ValidationId, Boolean>> targetValidationLoader) {
        this.documentStatisticLoader = documentStatisticLoader;
        this.docStatusLoader = docStatsLoader;
        this.targetValidationLoader = targetValidationLoader;
    }

    @Create
    public void create() {
        cacheManager = CacheManager.create();
        documentStatisticCache =
                EhcacheWrapper.create(DOC_STATISTIC_CACHE_NAME,
                        cacheManager, documentStatisticLoader);

        docStatusCache =
                EhcacheWrapper.create(DOC_STATUS_CACHE_NAME, cacheManager,
                        docStatusLoader);
        targetValidationCache =
                EhcacheWrapper.create(TFT_VALIDATION_CACHE_NAME, cacheManager,
                        targetValidationLoader);
    }

    @Destroy
    public void destroy() {
        cacheManager.shutdown();
    }

    @Override
    public WordStatistic getDocumentStatistics(Long documentId,
            LocaleId localeId) {
        return documentStatisticCache.getWithLoader(new DocumentLocaleKey(
                documentId, localeId));
    }

    @Override
    public void clearDocumentStatistics(Long documentId) {
        LocaleDAO localeDAO = serviceLocator.getInstance(LocaleDAO.class);
        for (HLocale locale : localeDAO.findAll()) {
            DocumentLocaleKey key =
                    new DocumentLocaleKey(documentId, locale.getLocaleId());
            documentStatisticCache.remove(key);
        }
    }

    @Override
    public void clearDocumentStatistics(Long documentId, LocaleId localeId) {
        documentStatisticCache.remove(new DocumentLocaleKey(documentId,
                localeId));
    }

    public DocumentStatus getDocumentStatus(Long documentId, LocaleId localeId) {
        return docStatusCache.getWithLoader(new DocumentLocaleKey(
                documentId, localeId));
    }

    @Override
    public Boolean textFlowTargetHasWarningOrError(Long targetId,
            ValidationId validationId) {
        Map<ValidationId, Boolean> cacheEntry =
                targetValidationCache.getWithLoader(targetId);
        synchronized (cacheEntry) {
            if (!cacheEntry.containsKey(validationId)) {
                Boolean result = loadTargetValidation(targetId, validationId);
                cacheEntry.put(validationId, result);
            }
            return cacheEntry.get(validationId);
        }
    }

    @Override
    public void textFlowStateUpdated(TextFlowTargetStateEvent event) {
        DocumentLocaleKey key =
                new DocumentLocaleKey(event.getDocumentId(),
                        event.getLocaleId());

        WordStatistic stats = documentStatisticCache.get(key);

        if (stats != null) {
            HTextFlow textFlow = getTextFlowDAO().findById(
                    event.getTextFlowId());

            stats.decrement(event.getPreviousState(),
                    textFlow.getWordCount().intValue());
            stats.increment(event.getNewState(),
                    textFlow.getWordCount().intValue());
            documentStatisticCache.put(key, stats);
        }

        // update document status information
        updateDocStatusCache(key, event.getTextFlowTargetId());

        // invalidate target validation
        targetValidationCache.remove(event.getTextFlowTargetId());
    }

    private void updateDocStatusCache(DocumentLocaleKey key,
            Long updatedTargetId) {
        DocumentStatus documentStatus = docStatusCache.get(key);
        if(documentStatus != null) {
            HTextFlowTarget target =
                getTextFlowTargetDAO().findById(updatedTargetId, false);
            updateDocumentStatus(getDocumentDAO(), documentStatus,
                key.getDocumentId(), target);
        }
    }

    private Boolean loadTargetValidation(Long textFlowTargetId,
            ValidationId validationId) {
        HTextFlowTarget tft =
                getTextFlowTargetDAO().findById(textFlowTargetId, false);
        if (tft != null) {
            ValidationAction action =
                    ValidationFactoryProvider.getFactoryInstance()
                            .getValidationAction(validationId);
            List<String> errorList =
                    action.validate(tft.getTextFlow().getContents().get(0), tft
                            .getContents().get(0));
            return !errorList.isEmpty();
        }
        return null;
    }

    DocumentDAO getDocumentDAO() {
        return serviceLocator.getInstance(DocumentDAO.class);
    }

    TextFlowTargetDAO getTextFlowTargetDAO() {
        return serviceLocator.getInstance(TextFlowTargetDAO.class);
    }

    TextFlowDAO getTextFlowDAO() {
        return serviceLocator.getInstance(TextFlowDAO.class);
    }

    private static class DocumentStatisticLoader extends
            CacheLoader<DocumentLocaleKey, WordStatistic> {

        private DocumentDAO getDocumentDAO() {
            return ServiceLocator.instance().getInstance(DocumentDAO.class);
        }

        @Override
        public WordStatistic load(DocumentLocaleKey key) throws Exception {
            WordStatistic wordStatistic = getDocumentDAO().getWordStatistics(
                    key.getDocumentId(), key.getLocaleId());
            return wordStatistic;
        }
    }

    private static class HTextFlowTargetIdLoader extends
            CacheLoader<DocumentLocaleKey, DocumentStatus> {
        DocumentDAO getDocumentDAO() {
            return ServiceLocator.instance().getInstance(DocumentDAO.class);
        }

        @Override
        public DocumentStatus load(DocumentLocaleKey key) throws Exception {
            DocumentDAO documentDAO = getDocumentDAO();
            HTextFlowTarget target =
                    documentDAO.getLastTranslatedTarget(key.getDocumentId(),
                            key.getLocaleId());
            DocumentStatus documentStatus = new DocumentStatus();

            return updateDocumentStatus(documentDAO, documentStatus,
                    key.getDocumentId(), target);
        }
    }

    private static class HTextFlowTargetValidationLoader extends
            CacheLoader<Long, Map<ValidationId, Boolean>> {
        @Override
        public Map<ValidationId, Boolean> load(Long key) throws Exception {
            return new HashMap<ValidationId, Boolean>();
        }
    }

    private static DocumentStatus updateDocumentStatus(DocumentDAO documentDAO,
            DocumentStatus documentStatus, Long documentId,
            HTextFlowTarget target) {

        Date lastTranslatedDate = null;
        String lastTranslatedBy = "";

        if (target != null) {
            lastTranslatedDate = target.getLastChanged();

            if (target.getLastModifiedBy() != null) {
                lastTranslatedBy =
                        target.getLastModifiedBy().getAccount().getUsername();
            }
        }
        HDocument document = documentDAO.findById(documentId, false);
        documentStatus.update(
                new DocumentId(document.getId(), document.getDocId()),
                lastTranslatedDate, lastTranslatedBy);
        return documentStatus;
    }

    @AllArgsConstructor
    @EqualsAndHashCode
    @Getter
    public static final class DocumentLocaleKey implements Serializable {
        private Long documentId;
        private LocaleId localeId;
    }
}
TOP

Related Classes of org.zanata.service.impl.TranslationStateCacheImpl$DocumentLocaleKey

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.