From dbb4efbbe49f59fd13e7a820fc3dbbf66400b20e Mon Sep 17 00:00:00 2001 From: Alex Eng Date: Thu, 25 Jun 2015 15:12:32 +1000 Subject: [PATCH] Add entityType, sourceType, entityId and automatedEntry to HTextFlowTarget and HTextFlowTargetHistory --- .../main/java/org/zanata/model/Activity.java | 6 +- .../main/java/org/zanata/model/HDocument.java | 2 +- .../org/zanata/model/HProjectIteration.java | 2 +- .../org/zanata/model/HTextFlowTarget.java | 33 ++++++- .../zanata/model/HTextFlowTargetHistory.java | 28 +++++- .../org/zanata/model/IsEntityWithType.java | 2 +- .../model/type/TranslationEntityType.java | 40 ++++++++ .../model/type/TranslationSourceType.java | 95 +++++++++++++++++++ .../model/type/TranslationSourceTypeType.java | 68 +++++++++++++ .../TranslationSourceTypeTypeDescriptor.java | 74 +++++++++++++++ .../service/impl/ActivityServiceImpl.java | 8 +- .../db/changelogs/db.changelog-3.8.xml | 53 +++++++++++ .../src/main/resources/db/db.changelog.xml | 2 + .../org/zanata/dao/TextFlowTargetDAOTest.java | 83 ++++++++++++++++ 14 files changed, 481 insertions(+), 15 deletions(-) create mode 100644 zanata-model/src/main/java/org/zanata/model/type/TranslationEntityType.java create mode 100644 zanata-model/src/main/java/org/zanata/model/type/TranslationSourceType.java create mode 100644 zanata-model/src/main/java/org/zanata/model/type/TranslationSourceTypeType.java create mode 100644 zanata-model/src/main/java/org/zanata/model/type/TranslationSourceTypeTypeDescriptor.java create mode 100644 zanata-war/src/main/resources/db/changelogs/db.changelog-3.8.xml create mode 100644 zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java diff --git a/zanata-model/src/main/java/org/zanata/model/Activity.java b/zanata-model/src/main/java/org/zanata/model/Activity.java index 69139616ed..72cf0d7b86 100644 --- a/zanata-model/src/main/java/org/zanata/model/Activity.java +++ b/zanata-model/src/main/java/org/zanata/model/Activity.java @@ -100,9 +100,9 @@ public class Activity extends ModelEntityBase implements Serializable { public Activity(HPerson actor, IsEntityWithType context, IsEntityWithType target, ActivityType activityType, int wordCount) { this.actor = actor; - this.contextType = context.getEntityType(); + this.contextType = context.getType(); this.contextId = context.getId(); - this.lastTargetType = target.getEntityType(); + this.lastTargetType = target.getType(); this.lastTargetId = target.getId(); this.activityType = activityType; this.wordCount = wordCount; @@ -113,7 +113,7 @@ public void updateActivity(Date currentTime, IsEntityWithType target, this.endOffsetMillis = currentTime.getTime() - approxTime.getTime(); this.wordCount += wordCount; this.eventCount++; - this.lastTargetType = target.getEntityType(); + this.lastTargetType = target.getType(); this.lastTargetId = target.getId(); } diff --git a/zanata-model/src/main/java/org/zanata/model/HDocument.java b/zanata-model/src/main/java/org/zanata/model/HDocument.java index af3a3ddfa1..9fcb1f9408 100644 --- a/zanata-model/src/main/java/org/zanata/model/HDocument.java +++ b/zanata-model/src/main/java/org/zanata/model/HDocument.java @@ -303,7 +303,7 @@ public HRawDocument getRawDocument() { @Override @Transient - public EntityType getEntityType() { + public EntityType getType() { return EntityType.HDocument; } diff --git a/zanata-model/src/main/java/org/zanata/model/HProjectIteration.java b/zanata-model/src/main/java/org/zanata/model/HProjectIteration.java index 96f8a67bc6..565bf0a719 100644 --- a/zanata-model/src/main/java/org/zanata/model/HProjectIteration.java +++ b/zanata-model/src/main/java/org/zanata/model/HProjectIteration.java @@ -164,7 +164,7 @@ public Iterator iterator() { @Override @Transient - public EntityType getEntityType() { + public EntityType getType() { return EntityType.HProjectIteration; } diff --git a/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java b/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java index 1afc57a5e8..e30b280e96 100644 --- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java +++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java @@ -32,6 +32,8 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; @@ -53,6 +55,8 @@ import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.NaturalId; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; import org.hibernate.search.annotations.Analyze; import org.hibernate.search.annotations.AnalyzerDiscriminator; import org.hibernate.search.annotations.Field; @@ -69,6 +73,8 @@ import org.zanata.hibernate.search.StringListBridge; import org.zanata.hibernate.search.TextContainerAnalyzerDiscriminator; import org.zanata.model.type.EntityType; +import org.zanata.model.type.TranslationEntityType; +import org.zanata.model.type.TranslationSourceType; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; @@ -85,6 +91,7 @@ @Entity @EntityListeners({ HTextFlowTarget.EntityListener.class }) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) +@TypeDef(name = "sourceType", typeClass = TranslationSourceType.class) @Indexed @Setter @NoArgsConstructor @@ -121,6 +128,20 @@ public class HTextFlowTarget extends ModelEntityBase implements HasContents, @Getter private String revisionComment; + @Getter + private TranslationEntityType entityType; + + @Getter + private Long entityId; + + @Getter + @Type(type = "sourceType") + private TranslationSourceType sourceType; + + @Getter + @Setter(AccessLevel.PRIVATE) + private Boolean automatedEntry; + private boolean revisionCommentSet = false; // Only for internal use (persistence transient) @@ -425,7 +446,7 @@ protected boolean logPersistence() { @Override @Transient - public EntityType getEntityType() { + public EntityType getType() { return EntityType.HTexFlowTarget; } @@ -434,7 +455,17 @@ public static class EntityListener { private void preUpdate(HTextFlowTarget tft) { // insert history if this has changed from its initial state if (tft.initialState != null && tft.initialState.hasChanged(tft)) { + if (tft.initialState.getSourceType() == null) { + tft.initialState.setSourceType(TranslationSourceType.UNKNOWN); + } + tft.initialState.setAutomatedEntry(tft.initialState + .getSourceType().isAutomatedEntry()); + tft.getHistory().put(tft.oldVersionNum, tft.initialState); + if (tft.getSourceType() == null) { + tft.setSourceType(TranslationSourceType.UNKNOWN); + } + tft.setAutomatedEntry(tft.getSourceType().isAutomatedEntry()); if (!tft.isRevisionCommentSet()) { tft.setRevisionComment(null); } diff --git a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetHistory.java b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetHistory.java index 35e8c28ffb..605a8e0abf 100644 --- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetHistory.java +++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetHistory.java @@ -37,13 +37,17 @@ import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; +import javax.validation.constraints.NotNull; import org.hibernate.annotations.AccessType; import org.hibernate.annotations.Immutable; import org.hibernate.annotations.IndexColumn; import org.hibernate.annotations.NaturalId; import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; import org.zanata.common.ContentState; +import org.zanata.model.type.TranslationEntityType; +import org.zanata.model.type.TranslationSourceType; import com.google.common.base.Objects; import lombok.Getter; @@ -76,6 +80,7 @@ name = HTextFlowTargetHistory.QUERY_MATCHING_HISTORY + 6, query = "select count(*) from HTextFlowTargetHistory t where t.textFlowTarget = :tft and size(t.contents) = :contentCount " + "and contents[0] = :content0 and contents[1] = :content1 and contents[2] = :content2 and contents[3] = :content3 and contents[4] = :content4 and contents[5] = :content5") }) +@TypeDef(name = "sourceType", typeClass = TranslationSourceType.class) public class HTextFlowTargetHistory extends HTextContainer implements Serializable, ITextFlowTargetHistory { static final String QUERY_MATCHING_HISTORY = @@ -107,6 +112,24 @@ public static String getQueryNameMatchingHistory(int size) { private HPerson reviewer; + @Getter + @Setter + @NotNull + private TranslationEntityType entityType; + + @Getter + @Setter + private Long entityId; + + @Getter + @Setter + @Type(type = "sourceType") + private TranslationSourceType sourceType; + + @Getter + @Setter + private Boolean automatedEntry; + @Getter @Setter private String revisionComment; @@ -125,7 +148,10 @@ public HTextFlowTargetHistory(HTextFlowTarget target) { this.reviewer = target.getReviewer(); this.setContents(target.getContents()); this.revisionComment = target.getRevisionComment(); - + this.automatedEntry = target.getAutomatedEntry(); + this.sourceType = target.getSourceType(); + this.entityId = target.getEntityId(); + this.entityType = target.getEntityType(); } @Id diff --git a/zanata-model/src/main/java/org/zanata/model/IsEntityWithType.java b/zanata-model/src/main/java/org/zanata/model/IsEntityWithType.java index 9f728e7a71..cdd7608b9e 100644 --- a/zanata-model/src/main/java/org/zanata/model/IsEntityWithType.java +++ b/zanata-model/src/main/java/org/zanata/model/IsEntityWithType.java @@ -28,5 +28,5 @@ public interface IsEntityWithType { Long getId(); - EntityType getEntityType(); + EntityType getType(); } diff --git a/zanata-model/src/main/java/org/zanata/model/type/TranslationEntityType.java b/zanata-model/src/main/java/org/zanata/model/type/TranslationEntityType.java new file mode 100644 index 0000000000..32dbfb6790 --- /dev/null +++ b/zanata-model/src/main/java/org/zanata/model/type/TranslationEntityType.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015, 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.model.type; + +import lombok.Getter; + +/** + * @author Alex Eng aeng@redhat.com + */ +public enum TranslationEntityType { + TMX("Translation memory"), + TFT("HTextFlowTarget"), + MT("Machine translation"); + + @Getter + private final String desc; + + private TranslationEntityType(String desc) { + this.desc = desc; + } +} diff --git a/zanata-model/src/main/java/org/zanata/model/type/TranslationSourceType.java b/zanata-model/src/main/java/org/zanata/model/type/TranslationSourceType.java new file mode 100644 index 0000000000..1496538610 --- /dev/null +++ b/zanata-model/src/main/java/org/zanata/model/type/TranslationSourceType.java @@ -0,0 +1,95 @@ +/* + * Copyright 2015, 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.model.type; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +import com.google.common.collect.Lists; +import lombok.Getter; + +/** + * @author Alex Eng aeng@redhat.com + */ +public enum TranslationSourceType { + COPY_TRANS("CT"), + COPY_VERSION("CV"), + MERGE_VERSION("MV"), + TM_MERGE("TM"), + GWT_EDITOR_ENTRY("GWT"), + JS_EDITOR_ENTRY("JS"), + API_UPLOAD("API"), + WEB_UPLOAD("WEB"), + MACHINE_TRANS("MT"), + UNKNOWN("UNK"); + + public static final Collection AUTOMATED_ENTRIES; + + static { + AUTOMATED_ENTRIES = Collections.unmodifiableCollection(new HashSet( + Arrays.asList(TranslationSourceType.COPY_TRANS, + TranslationSourceType.COPY_VERSION, + TranslationSourceType.MERGE_VERSION, + TranslationSourceType.TM_MERGE))); + } + + @Getter + private final String abbr; + + private TranslationSourceType(String abbr) { + this.abbr = abbr; + } + + public static TranslationSourceType getValueOf(String abbr) { + switch (abbr) { + case "CT": + return TranslationSourceType.COPY_TRANS; + case "CV": + return TranslationSourceType.COPY_VERSION; + case "MV": + return TranslationSourceType.MERGE_VERSION; + case "TM": + return TranslationSourceType.TM_MERGE; + case "GWT": + return TranslationSourceType.GWT_EDITOR_ENTRY; + case "JS": + return TranslationSourceType.JS_EDITOR_ENTRY; + case "API": + return TranslationSourceType.API_UPLOAD; + case "WEB": + return TranslationSourceType.WEB_UPLOAD; + case "MT": + return TranslationSourceType.MACHINE_TRANS; + case "UNKNOWN": + return TranslationSourceType.UNKNOWN; + default: + throw new IllegalArgumentException(String.valueOf(abbr)); + } + } + + public boolean isAutomatedEntry() { + return AUTOMATED_ENTRIES.contains(this); + } +} diff --git a/zanata-model/src/main/java/org/zanata/model/type/TranslationSourceTypeType.java b/zanata-model/src/main/java/org/zanata/model/type/TranslationSourceTypeType.java new file mode 100644 index 0000000000..78bb8228ab --- /dev/null +++ b/zanata-model/src/main/java/org/zanata/model/type/TranslationSourceTypeType.java @@ -0,0 +1,68 @@ +/* + * Copyright 2015, 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.model.type; + +import org.hibernate.MappingException; +import org.hibernate.dialect.Dialect; +import org.hibernate.type.AbstractSingleColumnStandardBasicType; +import org.hibernate.type.DiscriminatorType; +import org.hibernate.type.StringType; +import org.zanata.common.EntityStatus; + + +public class TranslationSourceTypeType extends AbstractSingleColumnStandardBasicType + implements DiscriminatorType { + + public TranslationSourceTypeType() { + super(StringType.INSTANCE.getSqlTypeDescriptor(), + TranslationSourceTypeTypeDescriptor.INSTANCE); + } + + @Override + public String toString(TranslationSourceType value) { + return String.valueOf((value).getAbbr()); + } + + @Override + public String getName() { + return "sourceType"; + } + + @Override + public String objectToSQLString(TranslationSourceType value, Dialect dialect) + throws Exception { + return "\'" + toString(value) + "\'"; + } + + public TranslationSourceType stringToObject(String xml) throws Exception { + if (xml.length() < 1) { + throw new MappingException( + "multiple or zero characters found parsing string"); + } + return TranslationSourceType.getValueOf(xml); + } + + public TranslationSourceType fromStringValue(String xml) { + return TranslationSourceType.getValueOf(xml); + } + +} diff --git a/zanata-model/src/main/java/org/zanata/model/type/TranslationSourceTypeTypeDescriptor.java b/zanata-model/src/main/java/org/zanata/model/type/TranslationSourceTypeTypeDescriptor.java new file mode 100644 index 0000000000..c60b1835e0 --- /dev/null +++ b/zanata-model/src/main/java/org/zanata/model/type/TranslationSourceTypeTypeDescriptor.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015, 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.model.type; + +import org.hibernate.type.descriptor.WrapperOptions; +import org.hibernate.type.descriptor.java.AbstractTypeDescriptor; +import org.zanata.common.ContentType; + +public class TranslationSourceTypeTypeDescriptor extends + AbstractTypeDescriptor { + private static final long serialVersionUID = 1L; + public static final TranslationSourceTypeTypeDescriptor INSTANCE = + new TranslationSourceTypeTypeDescriptor(); + + public TranslationSourceTypeTypeDescriptor() { + super(TranslationSourceType.class); + } + + @Override + public TranslationSourceType fromString(String string) { + if (string == null) { + return null; + } else { + return TranslationSourceType.getValueOf(string); + } + } + + @Override + public String toString(TranslationSourceType value) { + return value.toString(); + } + + @Override + public X + unwrap(TranslationSourceType value, Class type, WrapperOptions options) { + if (value == null) { + return null; + } + if (String.class.isAssignableFrom(type)) { + return (X) value.toString(); + } + throw unknownUnwrap(type); + } + + @Override + public TranslationSourceType wrap(X value, WrapperOptions options) { + if (value == null) { + return null; + } + if (String.class.isInstance(value)) { + return TranslationSourceType.getValueOf((String) value); + } + throw unknownWrap(value.getClass()); + } +} diff --git a/zanata-war/src/main/java/org/zanata/service/impl/ActivityServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/ActivityServiceImpl.java index 2fc2a4019e..4c84b82740 100644 --- a/zanata-war/src/main/java/org/zanata/service/impl/ActivityServiceImpl.java +++ b/zanata-war/src/main/java/org/zanata/service/impl/ActivityServiceImpl.java @@ -54,12 +54,6 @@ import org.zanata.model.IsEntityWithType; import org.zanata.model.type.EntityType; import org.zanata.service.ActivityService; -import org.zanata.util.DateUtil; -import org.zanata.util.StatisticsUtil; - -import com.google.common.collect.Lists; - -import com.google.common.collect.Lists; /** * @author Alex Eng aeng@redhat.com @@ -156,7 +150,7 @@ private void logActivityAlreadyLocked(long actorId, if (context != null && activityType != null) { Date currentActionTime = new Date(); Activity activity = - findActivity(actorId, context.getEntityType(), + findActivity(actorId, context.getType(), context.getId(), activityType, currentActionTime); if (activity != null) { activity.updateActivity(currentActionTime, target, wordCount); diff --git a/zanata-war/src/main/resources/db/changelogs/db.changelog-3.8.xml b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.8.xml new file mode 100644 index 0000000000..4f4b53c1de --- /dev/null +++ b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.8.xml @@ -0,0 +1,53 @@ + + + + + Add entityType, entityId, sourceType and automatedEntry to HTextFlowTarget + + + + + + + + + + + + + + + + + + + + + + + Add entityType, entityId, sourceType and automatedEntry to HTextFlowTargetHistory + + + + + + + + + + + + + + + + + + + + + + diff --git a/zanata-war/src/main/resources/db/db.changelog.xml b/zanata-war/src/main/resources/db/db.changelog.xml index 1d49801c8e..4ded2d897f 100644 --- a/zanata-war/src/main/resources/db/db.changelog.xml +++ b/zanata-war/src/main/resources/db/db.changelog.xml @@ -39,6 +39,8 @@ file="changelogs/db.changelog-3.6.xml" /> +