diff --git a/zanata-model/src/main/java/org/zanata/model/HTextFlow.java b/zanata-model/src/main/java/org/zanata/model/HTextFlow.java index dab1585e3d..6705e1d2c8 100644 --- a/zanata-model/src/main/java/org/zanata/model/HTextFlow.java +++ b/zanata-model/src/main/java/org/zanata/model/HTextFlow.java @@ -48,6 +48,7 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import com.google.common.annotations.VisibleForTesting; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.Setter; @@ -155,7 +156,8 @@ public Long getId() { return id; } - protected void setId(Long id) { + @VisibleForTesting + public void setId(Long id) { this.id = id; } diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetDAO.java index 4ce4ca7fa1..18265696bb 100644 --- a/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetDAO.java +++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetDAO.java @@ -202,54 +202,58 @@ public Optional searchBestMatchTransMemory( StringBuilder queryStr = new StringBuilder( - "select match " - + "from HTextFlowTarget match, HTextFlow textFlow " - + "where " - + "textFlow.id = :textFlowId " - + "and textFlow.contentHash = match.textFlow.contentHash " - + "and match.locale.localeId = :targetLocaleId " + "select match\n" + + "from HTextFlowTarget match\n" + + "where match.textFlow.contentHash = :contentHash\n" + + "and match.locale.localeId = :targetLocaleId\n" + // It's fine to reuse translation in Translated // state even if it came from a reviewable // project - "and match.state in (:approvedState, :translatedState) " + "and match.state in (:approvedState, :translatedState)\n" + // Do not reuse its own translation - "and match.textFlow != textFlow " + "and match.textFlow.id != :textFlowId\n" + // Do not reuse matches from obsolete entities // (iteration, project) // Obsolete document translations ARE reused - "and match.textFlow.document.projectIteration.status != :obsoleteEntityStatus " - + "and match.textFlow.document.projectIteration.project.status != :obsoleteEntityStatus "); + "and match.textFlow.document.projectIteration.status != :obsoleteEntityStatus\n" + + "and match.textFlow.document.projectIteration.project.status != :obsoleteEntityStatus\n" + ); if (checkContext) { - queryStr.append("and match.textFlow.resId = textFlow.resId "); + queryStr.append("and match.textFlow.resId = :resId\n"); } if (checkDocument) { - queryStr.append("and match.textFlow.document.docId = textFlow.document.docId "); + queryStr.append("and match.textFlow.document.docId = :docId\n"); } if (checkProject) { - queryStr.append("and match.textFlow.document.projectIteration.project = textFlow.document.projectIteration.project "); + queryStr.append("and match.textFlow.document.projectIteration.project.id = :projectId\n"); } - queryStr.append("order by (case when match.textFlow.resId = textFlow.resId then 0 else 1 end)," - + "(case when match.textFlow.document.docId = textFlow.document.docId then 0 else 1 end)," - + "(case when match.textFlow.document.projectIteration.project = textFlow.document.projectIteration.project then 0 else 1 end)," - + "match.lastChanged desc"); + queryStr.append("order by\n" + + " (case when match.textFlow.resId = :resId then 0 else 1 end),\n" + + " (case when match.textFlow.document.docId\n" + + " = :docId then 0 else 1 end),\n" + + " (case when match.textFlow.document.projectIteration.project.id\n" + + " = :projectId then 0 else 1 end),\n" + + " match.lastChanged desc\n"); Query q = getSession().createQuery(queryStr.toString()); - q.setParameter("textFlowId", textFlow.getId()) - .setParameter("targetLocaleId", targetLocaleId) - .setParameter("approvedState", ContentState.Approved) - .setParameter("translatedState", ContentState.Translated) - .setParameter("obsoleteEntityStatus", EntityStatus.OBSOLETE); + q.setParameter("textFlowId", textFlow.getId()); + q.setParameter("contentHash", textFlow.getContentHash()); + q.setParameter("resId", textFlow.getResId()); + q.setParameter("docId", textFlow.getDocument().getDocId()); + q.setParameter("projectId", textFlow.getDocument().getProjectIteration().getProject().getId()); + q.setParameter("targetLocaleId", targetLocaleId); + q.setParameter("approvedState", ContentState.Approved); + q.setParameter("translatedState", ContentState.Translated); + q.setParameter("obsoleteEntityStatus", EntityStatus.OBSOLETE); q.setCacheable(false); // don't try to cache scrollable results q.setComment("TextFlowTargetDAO.findMatchingTranslations"); q.setMaxResults(1); // Get the first one (should be the best match // because of the order by clause) - List results = q.list(); - return results.isEmpty() ? Optional. absent() - : Optional.of((HTextFlowTarget) results.get(0)); + return Optional.fromNullable((HTextFlowTarget) q.uniqueResult()); } /** diff --git a/zanata-war/src/main/java/org/zanata/service/impl/TranslationMemoryServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/TranslationMemoryServiceImpl.java index f54d528e03..b17114b74f 100644 --- a/zanata-war/src/main/java/org/zanata/service/impl/TranslationMemoryServiceImpl.java +++ b/zanata-war/src/main/java/org/zanata/service/impl/TranslationMemoryServiceImpl.java @@ -76,6 +76,8 @@ import static com.google.common.collect.Collections2.filter; import lombok.extern.slf4j.Slf4j; +import javax.annotation.Nullable; + /** * @author Alex Eng aeng@redhat.com */ @@ -456,7 +458,7 @@ public int hashCode() { private List getSearchResult(TransMemoryQuery query, LocaleId sourceLocale, LocaleId targetLocale, - final Integer maxResult, Class... entities) + final @Nullable Integer maxResult, Class... entities) throws ParseException { String queryText = null; String[] multiQueryText = null; @@ -522,8 +524,7 @@ private List getSearchResult(TransMemoryQuery query, ftQuery.setSort(lastChangedSort); if (maxResult != null) { - return (List) ftQuery.setMaxResults(maxResult) - .getResultList(); + ftQuery.setMaxResults(maxResult); } return (List) ftQuery.getResultList(); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransMemoryQuery.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransMemoryQuery.java index 40f826ad05..d93d3f63a0 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransMemoryQuery.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransMemoryQuery.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.List; +import lombok.ToString; import org.zanata.webtrans.shared.rpc.HasSearchType.SearchType; import com.google.gwt.user.client.rpc.IsSerializable; @@ -33,6 +34,7 @@ * href="mailto:sflaniga@redhat.com">sflaniga@redhat.com * */ +@ToString public class TransMemoryQuery implements IsSerializable { private SearchType searchType; private List queries; @@ -144,6 +146,7 @@ public int hashCode() { return result; } + @ToString public static class Condition implements IsSerializable { private boolean isCheck; private String value;