Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Merge pull request #253 from zanata/rhbz1023258
Browse files Browse the repository at this point in the history
rhbz1023258 - Copy trans refactor and bug-fix.
  • Loading branch information
seanf committed Nov 13, 2013
2 parents 0264873 + 33577c7 commit b27f6da
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 256 deletions.
Expand Up @@ -343,10 +343,8 @@ public void setContents(String... contents) {
this.setContents(Arrays.asList(contents));
}

// TODO use orphanRemoval=true: requires JPA 2.0
@OneToOne(optional = true, fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "comment_id")
public HSimpleComment getComment() {
return comment;
Expand Down
Expand Up @@ -77,12 +77,15 @@
public class ViewAllStatusAction implements Serializable {
private static final long serialVersionUID = 1L;

private static final PeriodFormatterBuilder PERIOD_FORMATTER_BUILDER =
// Period Formatters are thread safe and immutableaccording to joda time
// docs
private static final PeriodFormatter COPY_TRANS_TIME_REMAINING_FORMATTER =
new PeriodFormatterBuilder().appendDays()
.appendSuffix(" day", " days").appendSeparator(", ")
.appendHours().appendSuffix(" hour", " hours")
.appendSeparator(", ").appendMinutes()
.appendSuffix(" min", " mins");
.appendSuffix(" min", " mins")
.toFormatter();

@Logger
private Log log;
Expand Down Expand Up @@ -342,8 +345,7 @@ public boolean isCopyTransRunning() {
}

@Restrict("#{s:hasPermission(viewAllStatusAction.projectIteration, 'copy-trans')}")
public
void cancelCopyTrans() {
public void cancelCopyTrans() {
if (isCopyTransRunning()) {
copyTransManager.cancelCopyTrans(getProjectIteration());
}
Expand Down Expand Up @@ -464,16 +466,13 @@ public CopyTransTaskHandle getCopyTransProcessHandle() {
}

private String formatTimePeriod(long durationInMillis) {
PeriodFormatter formatter = PERIOD_FORMATTER_BUILDER.toFormatter();
CopyTransTaskHandle handle =
copyTransManager
.getCopyTransProcessHandle(getProjectIteration());
Period period = new Period(durationInMillis);

if (period.toStandardMinutes().getMinutes() <= 0) {
return "less than a minute"; // TODO Localize
} else {
return formatter.print(period.normalizedStandard());
return COPY_TRANS_TIME_REMAINING_FORMATTER
.print(period.normalizedStandard());
}
}

Expand Down
74 changes: 31 additions & 43 deletions zanata-war/src/main/java/org/zanata/dao/TextFlowTargetDAO.java
Expand Up @@ -2,14 +2,12 @@

import java.util.List;

import javax.persistence.EntityManager;

import com.google.common.base.Optional;
import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.zanata.common.ContentState;
Expand All @@ -25,9 +23,6 @@
@Scope(ScopeType.STATELESS)
public class TextFlowTargetDAO extends AbstractDAOImpl<HTextFlowTarget, Long> {

@In
private EntityManager entityManager;

public TextFlowTargetDAO() {
super(HTextFlowTarget.class);
}
Expand Down Expand Up @@ -179,35 +174,30 @@ public List<HTextFlowTarget> findTranslations(HDocument document,
}

/**
* Finds matching translations for a given document and locale.
*
* Finds the best matching translations for a single text flow and a locale.
* Other parameters (context, document id, and project) can also influence
* what the best match is.
* A matching translation is one where the source text is exactly the
* same as the translation within the document and in the same locale.
*
* @param document
* The document for which to find equivalent translations.
* @param locale
* The locale. Only translations for this locale are fetched.
* @param checkContext
* Whether to check the text flow's context for matches.
* @param checkDocument
* Whether to check the text flow's document for matches.
* @param checkProject
* Whether to check the text flow's project for matches.
* @param requireTranslationReview
* whether document belongs to a reviewable project iteration
* @return A scrollable result set (in case there is a large result set).
* Position 0 of the result set is the matching translation
* (HTextFlowTarget), position 1 is the HTextFlow in the document
* that it matches against.
* @param textFlow The text flow for which to find a matching translation.
* @param locale The locale in which to find matches.
* @param checkContext Whether to check for a matching context
* @param checkDocument Whether to check for a matching document id
* @param checkProject Whether to check for a matching project
* @return The single best possible match found in the system for the
* given text flow.
*/
public ScrollableResults findMatchingTranslations(HDocument document,
HLocale locale, boolean checkContext, boolean checkDocument,
boolean checkProject, boolean requireTranslationReview) {
public Optional<HTextFlowTarget> findBestMatchingTranslation(
HTextFlow textFlow, HLocale locale, boolean checkContext,
boolean checkDocument, boolean checkProject) {

StringBuilder queryStr =
new StringBuilder(
"select textFlow, max(match.id) "
"select match "
+ "from HTextFlowTarget match, HTextFlow textFlow "
+ "where "
+ "textFlow.document = :document "
+ "textFlow.id = :textFlowId "
+ "and textFlow.contentHash = match.textFlow.contentHash "
+ "and match.locale = :locale "
+
Expand All @@ -216,12 +206,7 @@ public ScrollableResults findMatchingTranslations(HDocument document,
// project
"and match.state in (:approvedState, :translatedState) "
+
// Do not fetch results for already approved
// text flow targets
"and (match.locale not in indices(textFlow.targets) "
+ "or :finalState != (select t.state from HTextFlowTarget t where t.textFlow = textFlow and t.locale = :locale) ) "
+
// Do not reuse its own translations
// Do not reuse its own translation
"and match.textFlow != textFlow "
+
// Do not reuse matches from obsolete entities
Expand All @@ -238,22 +223,25 @@ public ScrollableResults findMatchingTranslations(HDocument document,
if (checkProject) {
queryStr.append("and match.textFlow.document.projectIteration.project = textFlow.document.projectIteration.project ");
}
queryStr.append("group by textFlow");
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");

Query q = getSession().createQuery(queryStr.toString());

q.setParameter("document", document).setParameter("locale", locale)
q.setParameter("textFlowId", textFlow.getId())
.setParameter("locale", locale)
.setParameter("approvedState", ContentState.Approved)
.setParameter("translatedState", ContentState.Translated)
.setParameter("obsoleteEntityStatus", EntityStatus.OBSOLETE);
if (requireTranslationReview) {
q.setParameter("finalState", ContentState.Approved);
} else {
q.setParameter("finalState", ContentState.Translated);
}
q.setCacheable(false); // don't try to cache scrollable results
q.setComment("TextFlowTargetDAO.findMatchingTranslations");
return q.scroll();
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.<HTextFlowTarget> absent()
: Optional.of((HTextFlowTarget) results.get(0));
}

/**
Expand Down

0 comments on commit b27f6da

Please sign in to comment.