Package org.zanata.rest.service

Source Code of org.zanata.rest.service.TranslationMemoryResourceService

/*
* Copyright 2013, 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.rest.service;

import java.io.InputStream;
import java.util.concurrent.Future;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;

import lombok.extern.slf4j.Slf4j;

import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.TransactionPropagationType;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.security.Restrict;
import org.zanata.async.Async;
import org.zanata.async.AsyncTaskHandle;
import org.zanata.async.AsyncTaskResult;
import org.zanata.async.ContainsAsyncMethods;
import org.zanata.common.LocaleId;
import org.zanata.dao.TextFlowStreamingDAO;
import org.zanata.dao.TransMemoryDAO;
import org.zanata.dao.TransMemoryStreamingDAO;
import org.zanata.exception.EntityMissingException;
import org.zanata.exception.ZanataServiceException;
import org.zanata.lock.Lock;
import org.zanata.model.HProject;
import org.zanata.model.HProjectIteration;
import org.zanata.model.HTextFlow;
import org.zanata.model.ITextFlow;
import org.zanata.model.tm.TransMemory;
import org.zanata.model.tm.TransMemoryUnit;
import org.zanata.service.LocaleService;
import org.zanata.service.LockManagerService;
import org.zanata.tmx.TMXParser;
import org.zanata.util.CloseableIterator;

import com.google.common.base.Optional;

@Name("translationMemoryResource")
@Path(TranslationMemoryResource.SERVICE_PATH)
@Transactional(TransactionPropagationType.SUPPORTS)
@Slf4j
@ContainsAsyncMethods
@ParametersAreNonnullByDefault
// TODO options to export obsolete docs and textflows to TMX?
public class TranslationMemoryResourceService implements
        TranslationMemoryResource {

    @In
    private LocaleService localeServiceImpl;
    @In
    private LockManagerService lockManagerServiceImpl;
    @In
    private RestSlugValidator restSlugValidator;
    @In
    private TextFlowStreamingDAO textFlowStreamDAO;
    @In
    private TransMemoryStreamingDAO transMemoryStreamingDAO;
    @In
    private TransMemoryDAO transMemoryDAO;
    @In
    private TMXParser tmxParser;

    @Override
    @Restrict("#{s:hasRole('admin')}")
    public Response getAllTranslationMemory(@Nullable LocaleId locale) {
        log.debug("exporting TMX for all projects, locale {}", locale);
        if (locale != null) {
            localeServiceImpl.validateSourceLocale(locale);
            // TODO findTextFlowsByLocale
        }
        String filename = makeTMXFilename(null, null, locale);
        CloseableIterator<HTextFlow> iter = textFlowStreamDAO.findTextFlows();
        return buildTMX("getAllTranslationMemory", iter, locale, filename);
    }

    @Override
    public Response getProjectTranslationMemory(@Nonnull String projectSlug,
            @Nullable LocaleId locale) {
        log.debug("exporting TMX for project {}, locale {}", projectSlug,
                locale);
        HProject hProject =
                restSlugValidator.retrieveAndCheckProject(projectSlug, false);
        if (locale != null) {
            restSlugValidator.validateTargetLocale(locale, projectSlug);
            // TODO findTextFlowsByProjectAndLocale
        }
        String filename = makeTMXFilename(projectSlug, null, locale);
        CloseableIterator<HTextFlow> iter =
                textFlowStreamDAO.findTextFlowsByProject(hProject);
        return buildTMX("getProjectTranslationMemory-" + filename, iter,
                locale, filename);
    }

    @Override
    public Response getProjectIterationTranslationMemory(
            @Nonnull String projectSlug, @Nonnull String iterationSlug,
            @Nullable LocaleId locale) {
        log.debug("exporting TMX for project {}, iteration {}, locale {}",
                projectSlug, iterationSlug, locale);
        HProjectIteration hProjectIteration =
                restSlugValidator.retrieveAndCheckIteration(projectSlug,
                        iterationSlug, false);
        if (locale != null) {
            restSlugValidator.validateTargetLocale(locale, projectSlug,
                    iterationSlug);
            // TODO findTextFlowsByProjectIterationAndLocale
        }
        String filename = makeTMXFilename(projectSlug, iterationSlug, locale);
        CloseableIterator<HTextFlow> iter =
                textFlowStreamDAO
                        .findTextFlowsByProjectIteration(hProjectIteration);
        return buildTMX("getProjectIterationTranslationMemory-" + filename,
                iter, locale, filename);
    }

    @Override
    @Restrict("#{s:hasRole('admin')}")
    public Response getTranslationMemory(@Nonnull String slug) {
        log.debug("exporting TMX for translation memory {}", slug);
        TransMemory tm = getTM(transMemoryDAO.getBySlug(slug), slug);
        String filename = makeTMXFilename(slug);
        CloseableIterator<TransMemoryUnit> iter =
                transMemoryStreamingDAO.findTransUnitsByTM(tm);
        return buildTMX("getTranslationMemory-" + filename, tm, iter, filename);
    }

    @Override
    @Restrict("#{s:hasRole('admin')}")
    public Response updateTranslationMemory(String slug, InputStream input)
            throws Exception {
        Lock tmLock = lockTM(slug);
        try {
            Optional<TransMemory> tm = transMemoryDAO.getBySlug(slug);
            tmxParser.parseAndSaveTMX(input, getTM(tm, slug));
            return Response.ok().build();
        } finally {
            lockManagerServiceImpl.release(tmLock);
        }
    }

    private TransMemory getTM(Optional<TransMemory> tm, String slug) {
        if (!tm.isPresent()) {
            throw new EntityMissingException("Translation memory '" + slug
                    + "' was not found.");
        }
        return tm.get();
    }

    @Restrict("#{s:hasRole('admin')}")
    public Object deleteTranslationMemory(String slug)
            throws EntityMissingException {
        Lock tmLock = lockTM(slug);
        try {
            Optional<TransMemory> transMemory = transMemoryDAO.getBySlug(slug);
            if (transMemory.isPresent()) {
                transMemoryDAO.makeTransient(transMemory.get());
                return "Translation memory '" + slug + "' deleted";
            } else {
                throw new EntityMissingException(slug);
            }
        } finally {
            lockManagerServiceImpl.release(tmLock);
        }
    }

    @Override
    @Restrict("#{s:hasRole('admin')}")
    public Object deleteTranslationUnits(String slug) {
        return deleteTranslationUnitsUnguarded(slug);
    }

    /**
     * Deletes without checking security permissions (useful for background
     * processes which do the check ahead of time).
     *
     * @param slug
     * @return
     */
    public Object deleteTranslationUnitsUnguarded(String slug) {
        Lock tmLock = lockTM(slug);
        try {
            int numDeleted = transMemoryDAO.deleteTransMemoryContents(slug);
            return numDeleted + " translation units deleted";
        } finally {
            lockManagerServiceImpl.release(tmLock);
        }
    }

    /**
     * Deletes without checking security permissions and asynchronously.
     *
     * @param slug
     * @return
     */
    @Async
    public Future<Object> deleteTranslationUnitsUnguardedAsync(String slug,
            AsyncTaskHandle handle) {
        // TODO the handle is not being used for progress tracking in the
        // current implementation
        return AsyncTaskResult
                .taskResult(deleteTranslationUnitsUnguarded(slug));
    }

    private Lock lockTM(String slug) {
        Lock tmLock = new Lock("tm", slug);
        String owner = lockManagerServiceImpl.attainLockOrReturnOwner(tmLock);
        if (owner != null) {
            throw new ZanataServiceException("Translation Memory '" + slug
                    + "' is locked by user: " + owner, 503);
        }
        return tmLock;
    }

    private Response buildTMX(String jobName,
            @Nonnull CloseableIterator<? extends ITextFlow> iter,
            @Nullable LocaleId locale, @Nonnull String filename) {
        TMXStreamingOutput<HTextFlow> output =
                new TMXStreamingOutput(jobName, iter,
                        new TranslationsTMXExportStrategy(locale));
        return okResponse(filename, output);
    }

    private Response buildTMX(String jobName, TransMemory tm,
            CloseableIterator<TransMemoryUnit> iter, String filename) {
        TMXStreamingOutput<TransMemoryUnit> output =
                new TMXStreamingOutput<TransMemoryUnit>(jobName, iter,
                        new TransMemoryTMXExportStrategy(tm));
        return okResponse(filename, output);
    }

    private Response okResponse(String filename, StreamingOutput output) {
        return Response
                .ok()
                .header("Content-Disposition",
                        "attachment; filename=\"" + filename + "\"")
                .type(PREFERRED_MEDIA_TYPE).entity(output).build();
    }

    private static @Nonnull
    String makeTMXFilename(@Nullable String projectSlug,
            @Nullable String iterationSlug, @Nullable LocaleId locale) {
        String p = projectSlug != null ? projectSlug : "allProjects";
        String i = iterationSlug != null ? iterationSlug : "allVersions";
        String l = locale != null ? locale.getId() : "allLocales";
        return "zanata-" + p + "-" + i + "-" + l + ".tmx";
    }

    private static @Nonnull
    String makeTMXFilename(@Nullable String tmSlug) {
        return "zanata-" + tmSlug + ".tmx";
    }

}
TOP

Related Classes of org.zanata.rest.service.TranslationMemoryResourceService

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.