Package org.zanata.rest.service

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

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

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;

import lombok.extern.slf4j.Slf4j;

import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.security.Restrict;
import org.zanata.ApplicationConfiguration;
import org.zanata.common.LocaleId;
import org.zanata.common.MergeType;
import org.zanata.dao.DocumentDAO;
import org.zanata.dao.ProjectDAO;
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.dao.TextFlowTargetDAO;
import org.zanata.model.HDocument;
import org.zanata.model.HLocale;
import org.zanata.model.HProjectIteration;
import org.zanata.model.HTextFlowTarget;
import org.zanata.rest.dto.resource.TranslationsResource;
import org.zanata.security.ZanataIdentity;
import org.zanata.service.CopyTransService;
import org.zanata.service.LocaleService;
import org.zanata.service.TranslationService;

import com.google.common.base.Optional;

/**
* This service allows clients to push and pull both source documents and
* translations.
*/
@Name("translatedDocResourceService")
@Path(TranslatedDocResource.SERVICE_PATH)
@Slf4j
@Transactional
public class TranslatedDocResourceService implements TranslatedDocResource {

    // security actions
    // private static final String ACTION_IMPORT_TEMPLATE = "import-template";
    // private static final String ACTION_IMPORT_TRANSLATION =
    // "import-translation";

    /** Project Identifier. */
    @PathParam("projectSlug")
    private String projectSlug;

    /** Project Iteration identifier. */
    @PathParam("iterationSlug")
    private String iterationSlug;

    /** (This parameter is optional and is currently not used) */
    @HeaderParam("Content-Type")
    @Context
    private MediaType requestContentType;

    @Context
    private HttpHeaders headers;

    @Context
    private Request request;

    @Context
    private UriInfo uri;

    @In
    private ZanataIdentity identity;

    @In
    private ApplicationConfiguration applicationConfiguration;

    @In
    private ProjectIterationDAO projectIterationDAO;

    @In
    private ProjectDAO projectDAO;

    @In
    private DocumentDAO documentDAO;

    @In
    private TextFlowTargetDAO textFlowTargetDAO;

    @In
    private ResourceUtils resourceUtils;

    @In
    private ETagUtils eTagUtils;

    @In
    private CopyTransService copyTransServiceImpl;
    @In
    private RestSlugValidator restSlugValidator;

    @In
    private TranslationService translationServiceImpl;

    @In
    private LocaleService localeServiceImpl;

    @Override
    public Response getTranslations(String idNoSlash, LocaleId locale,
            Set<String> extensions, boolean skeletons, String eTag) {
        log.debug("start to get translation");
        String id = URIHelper.convertFromDocumentURIId(idNoSlash);
        HProjectIteration hProjectIteration =
                restSlugValidator.retrieveAndCheckIteration(projectSlug,
                        iterationSlug, false);
        HLocale hLocale =
                restSlugValidator.validateTargetLocale(locale, projectSlug,
                        iterationSlug);

        ResourceUtils.validateExtensions(extensions);

        // Check Etag header
        EntityTag generatedEtag =
                eTagUtils.generateETagForTranslatedDocument(hProjectIteration,
                        id, hLocale);
        List<String> requestedEtagHeaders =
                headers.getRequestHeader(HttpHeaders.IF_NONE_MATCH);
        if (requestedEtagHeaders != null && !requestedEtagHeaders.isEmpty()) {
            if (requestedEtagHeaders.get(0).equals(generatedEtag.getValue())) {
                return Response.notModified(generatedEtag).build();
            }
        }

        ResponseBuilder response = request.evaluatePreconditions(generatedEtag);
        if (response != null) {
            return response.build();
        }

        HDocument document =
                documentDAO.getByDocIdAndIteration(hProjectIteration, id);
        if (document == null || document.isObsolete()) {
            return Response.status(Status.NOT_FOUND).build();
        }

        TranslationsResource translationResource = new TranslationsResource();
        // TODO avoid queries for better cacheability
        List<HTextFlowTarget> hTargets =
                textFlowTargetDAO.findTranslations(document, hLocale);
        boolean foundData =
                resourceUtils.transferToTranslationsResource(
                        translationResource, document, hLocale, extensions,
                        hTargets, Optional.<String> absent());

        if (!foundData && !skeletons) {
            return Response.status(Status.NOT_FOUND).build();
        }

        // TODO lastChanged
        return Response.ok().entity(translationResource).tag(generatedEtag)
                .build();
    }

    @Override
    @Restrict("#{s:hasPermission(translatedDocResourceService.securedIteration.project, 'modify-translation')}")
    public
            Response deleteTranslations(String idNoSlash, LocaleId locale) {
        String id = URIHelper.convertFromDocumentURIId(idNoSlash);
        HProjectIteration hProjectIteration =
                restSlugValidator.retrieveAndCheckIteration(projectSlug,
                        iterationSlug, true);
        HLocale hLocale =
                restSlugValidator.validateTargetLocale(locale, projectSlug,
                        iterationSlug);

        EntityTag etag =
                eTagUtils.generateETagForTranslatedDocument(hProjectIteration,
                        id, hLocale);

        ResponseBuilder response = request.evaluatePreconditions(etag);
        if (response != null) {
            return response.build();
        }

        HDocument document =
                documentDAO.getByDocIdAndIteration(hProjectIteration, id);
        if (document == null || document.isObsolete()) {
            return Response.status(Status.NOT_FOUND).build();
        }
        List<HTextFlowTarget> targets =
                textFlowTargetDAO.findAllTranslations(document, locale);

        for (HTextFlowTarget target : targets) {
            target.clear();
        }

        // we also need to delete the extensions here
        document.getPoTargetHeaders().remove(hLocale);
        textFlowTargetDAO.flush();

        return Response.ok().build();

    }

    @Override
    public Response putTranslations(String idNoSlash, LocaleId locale,
            TranslationsResource messageBody, Set<String> extensions,
            String merge) {
        // check security (cannot be on @Restrict as it refers to method
        // parameters)
        identity.checkPermission("modify-translation", this.localeServiceImpl
                .getByLocaleId(locale), this.getSecuredIteration().getProject());

        log.debug("start put translations");
        MergeType mergeType;
        try {
            mergeType = MergeType.valueOf(merge.toUpperCase());
        } catch (IllegalArgumentException e) {
            return Response.status(Status.BAD_REQUEST)
                    .entity("bad merge type " + merge).build();
        }
        String id = URIHelper.convertFromDocumentURIId(idNoSlash);

        HProjectIteration hProjectIteration =
                projectIterationDAO.getBySlug(projectSlug, iterationSlug);
        HLocale hLocale =
                restSlugValidator.validateTargetLocale(locale, projectSlug,
                        iterationSlug);

        EntityTag etag =
                eTagUtils.generateETagForTranslatedDocument(hProjectIteration,
                        id, hLocale);

        ResponseBuilder response = request.evaluatePreconditions(etag);
        if (response != null) {
            return response.build();
        }

        // Translate
        List<String> warnings =
                this.translationServiceImpl.translateAllInDoc(projectSlug,
                        iterationSlug, id, locale, messageBody, extensions,
                        mergeType);

        // Regenerate etag in case it has changed
        etag =
                eTagUtils.generateETagForTranslatedDocument(hProjectIteration,
                        id, hLocale);

        log.debug("successful put translation");
        // TODO lastChanged
        StringBuilder sb = new StringBuilder();
        for (String warning : warnings) {
            sb.append("warning: ").append(warning).append('\n');
        }
        return Response.ok(sb.toString()).tag(etag).build();
    }

    // public for Seam's benefit (and the @Restrict in deleteTranslations)
    public HProjectIteration getSecuredIteration() {
        return restSlugValidator.retrieveAndCheckIteration(projectSlug,
                iterationSlug, false);
    }

}
TOP

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

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.