diff --git a/pom.xml b/pom.xml index 736301d68a..72d7079998 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ org.zanata zanata-parent - 10 + 13-SNAPSHOT ../parent diff --git a/zanata-model/pom.xml b/zanata-model/pom.xml index 8bc34ee7e2..0fd93e0fa2 100644 --- a/zanata-model/pom.xml +++ b/zanata-model/pom.xml @@ -249,6 +249,10 @@ validation-api + + com.google.code.findbugs + jsr305 + 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 8959531fa4..44d6cbefdc 100644 --- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java +++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java @@ -23,7 +23,6 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -57,13 +56,10 @@ import org.hibernate.search.annotations.AnalyzerDiscriminator; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.FieldBridge; -import org.hibernate.search.annotations.Index; import org.hibernate.search.annotations.Indexed; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.Parameter; import org.hibernate.validator.constraints.NotEmpty; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.zanata.common.ContentState; import org.zanata.common.HasContents; import org.zanata.common.LocaleId; @@ -74,6 +70,7 @@ import org.zanata.hibernate.search.TextContainerAnalyzerDiscriminator; import com.google.common.base.Objects; +import com.google.common.collect.Lists; /** * Represents a flow of translated text that should be processed as a @@ -114,6 +111,8 @@ public class HTextFlowTarget extends ModelEntityBase implements HasContents, Has private Map history; + private List reviewComments; + // Only for internal use (persistence transient) @Setter(AccessLevel.PRIVATE) private Integer oldVersionNum; @@ -388,6 +387,23 @@ public Map getHistory() return history; } + @OneToMany(cascade = { CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST }, mappedBy = "textFlowTarget") + public List getReviewComments() + { + if (reviewComments == null) + { + reviewComments = Lists.newArrayList(); + } + return reviewComments; + } + + public HTextFlowTargetReviewComment addReviewComment(String comment, HPerson commenter) + { + HTextFlowTargetReviewComment reviewComment = new HTextFlowTargetReviewComment(this, comment, commenter); + getReviewComments().add(reviewComment); + return reviewComment; + } + @PreUpdate private void preUpdate() { diff --git a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java new file mode 100644 index 0000000000..9f68b2ab68 --- /dev/null +++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java @@ -0,0 +1,107 @@ +/* + * 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.model; + +import java.util.List; +import javax.persistence.Access; +import javax.persistence.AccessType; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Transient; +import javax.validation.constraints.NotNull; + +import org.hibernate.annotations.BatchSize; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.hibernate.annotations.Immutable; +import org.hibernate.annotations.NaturalId; +import org.hibernate.annotations.Type; +import org.hibernate.search.annotations.IndexedEmbedded; +import org.zanata.common.ContentState; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +@Entity +@Immutable +@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) +@BatchSize(size = 20) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Access(AccessType.FIELD) +public class HTextFlowTargetReviewComment extends ModelEntityBase +{ + private static final long serialVersionUID = 1413384329431214946L; + + @Getter + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "commenter_id", nullable = false) + private HPerson commenter; + + @NotNull + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "target_id") + @IndexedEmbedded + @Getter + private HTextFlowTarget textFlowTarget; + + @NotNull + @Type(type = "text") + @Getter + private String comment; + + @Setter(AccessLevel.PROTECTED) + @Getter + @NotNull + private Integer targetVersion; + + private transient String commenterName; + + public HTextFlowTargetReviewComment(HTextFlowTarget target, String comment, HPerson commenter) + { + this.textFlowTarget = target; + this.comment = comment; + this.commenter = commenter; + commenterName = commenter.getName(); + targetVersion = target.getVersionNum(); + } + + @Transient + public String getCommenterName() + { + if (commenterName == null) + { + commenterName = getCommenter().getName(); + } + return commenterName; + } + +} diff --git a/zanata-war/pom.xml b/zanata-war/pom.xml index 0040c975a8..6f08beaa64 100644 --- a/zanata-war/pom.xml +++ b/zanata-war/pom.xml @@ -1320,6 +1320,10 @@ com.google.guava guava-gwt + + com.google.code.findbugs + annotations + com.google.code.findbugs jsr305 diff --git a/zanata-war/src/main/java/org/zanata/ApplicationConfiguration.java b/zanata-war/src/main/java/org/zanata/ApplicationConfiguration.java index bc93fb22e2..1cadd2bcbf 100644 --- a/zanata-war/src/main/java/org/zanata/ApplicationConfiguration.java +++ b/zanata-war/src/main/java/org/zanata/ApplicationConfiguration.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Set; + import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Level; @@ -47,7 +48,6 @@ import org.zanata.config.JndiBackedConfig; import org.zanata.log4j.ZanataHTMLLayout; import org.zanata.log4j.ZanataSMTPAppender; -import org.zanata.model.HApplicationConfiguration; import org.zanata.security.AuthenticationType; @Name("applicationConfiguration") @@ -63,22 +63,6 @@ public class ApplicationConfiguration implements Serializable private static final String EMAIL_APPENDER_NAME = "zanata.log.appender.email"; public static final String EVENT_CONFIGURATION_CHANGED = "zanata.configuration.changed"; - - - private static final String[] allConfigKeys = new String[] - { - HApplicationConfiguration.KEY_ADMIN_EMAIL, - HApplicationConfiguration.KEY_DOMAIN, - HApplicationConfiguration.KEY_EMAIL_FROM_ADDRESS, - HApplicationConfiguration.KEY_EMAIL_LOG_EVENTS, - HApplicationConfiguration.KEY_EMAIL_LOG_LEVEL, - HApplicationConfiguration.KEY_HELP_CONTENT, - HApplicationConfiguration.KEY_HOME_CONTENT, - HApplicationConfiguration.KEY_HOST, - HApplicationConfiguration.KEY_LOG_DESTINATION_EMAIL, - HApplicationConfiguration.KEY_REGISTER - }; - private DatabaseBackedConfig databaseBackedConfig; private JndiBackedConfig jndiBackedConfig; @@ -97,7 +81,6 @@ public class ApplicationConfiguration implements Serializable public void load() { log.info("Reloading configuration"); - Map configValues = new HashMap(); databaseBackedConfig = (DatabaseBackedConfig)Component.getInstance(DatabaseBackedConfig.class); jndiBackedConfig = (JndiBackedConfig)Component.getInstance(JndiBackedConfig.class); diff --git a/zanata-war/src/main/java/org/zanata/action/CopyTransManager.java b/zanata-war/src/main/java/org/zanata/action/CopyTransManager.java index 2ba07d06fb..6364f59522 100644 --- a/zanata-war/src/main/java/org/zanata/action/CopyTransManager.java +++ b/zanata-war/src/main/java/org/zanata/action/CopyTransManager.java @@ -69,19 +69,30 @@ public class CopyTransManager implements Serializable Collections.synchronizedMap( new HashMap() ); // Collection of recently cancelled copy trans processes (discards the oldest ones) + // TODO deprecated, switch to CacheBuilder private Map recentlyCancelled = new MapMaker() .softValues() .expiration(1, TimeUnit.HOURS) // keep them for an hour .makeMap(); +// CacheBuilder.newBuilder() +// .softValues() +// .expireAfterWrite(1, TimeUnit.HOURS) // keep them for an hour +// .build().asMap(); // Collection of recently completed copy trans processes (discards the olders ones) + // TODO deprecated, switch to CacheBuilder private Map recentlyFinished = new MapMaker() .softValues() .expiration(1, TimeUnit.HOURS) // keep them for an hour .makeMap(); +// CacheBuilder.newBuilder() +// .softValues() +// .expireAfterWrite(1, TimeUnit.HOURS) // keep them for an hour +// .build().asMap(); + @In private ProcessManagerService processManagerServiceImpl; diff --git a/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java b/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java index 2f1e91d9c1..15c19461c0 100644 --- a/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java +++ b/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java @@ -60,7 +60,6 @@ import org.zanata.rest.dto.stats.TranslationStatistics; import org.zanata.rest.dto.stats.TranslationStatistics.StatUnit; import org.zanata.rest.service.StatisticsResource; -import org.zanata.seam.scope.FlashScopeBean; import org.zanata.security.ZanataIdentity; import org.zanata.service.CopyTransService; import org.zanata.service.LocaleService; @@ -106,9 +105,6 @@ public class ViewAllStatusAction implements Serializable @In CopyTransManager copyTransManager; - @In - FlashScopeBean flashScope; - private String iterationSlug; private String projectSlug; diff --git a/zanata-war/src/main/java/org/zanata/config/DatabaseBackedConfig.java b/zanata-war/src/main/java/org/zanata/config/DatabaseBackedConfig.java index c12b13ee3c..3236d602c8 100644 --- a/zanata-war/src/main/java/org/zanata/config/DatabaseBackedConfig.java +++ b/zanata-war/src/main/java/org/zanata/config/DatabaseBackedConfig.java @@ -20,6 +20,7 @@ */ package org.zanata.config; +import java.io.Serializable; import java.util.HashMap; import java.util.Map; @@ -40,9 +41,11 @@ @Name("databaseBackedConfig") @Scope(ScopeType.APPLICATION) @AutoCreate -public class DatabaseBackedConfig +public class DatabaseBackedConfig implements Serializable { + private static final long serialVersionUID = 1L; + @In private ApplicationConfigurationDAO applicationConfigurationDAO; diff --git a/zanata-war/src/main/java/org/zanata/config/JndiBackedConfig.java b/zanata-war/src/main/java/org/zanata/config/JndiBackedConfig.java index ca0e639827..8ff7525532 100644 --- a/zanata-war/src/main/java/org/zanata/config/JndiBackedConfig.java +++ b/zanata-war/src/main/java/org/zanata/config/JndiBackedConfig.java @@ -20,10 +20,12 @@ */ package org.zanata.config; +import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; + import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameClassPair; @@ -45,9 +47,10 @@ @Name("jndiBackedConfig") @Scope(ScopeType.APPLICATION) @AutoCreate -public class JndiBackedConfig +public class JndiBackedConfig implements Serializable { - + private static final long serialVersionUID = 1L; + private static final String KEY_AUTH_POLICY = "java:global/zanata/security/auth-policy-names/"; private static final String KEY_ADMIN_USERS = "java:global/zanata/security/admin-users"; private static final String KEY_DEFAULT_FROM_ADDRESS = "java:global/zanata/email/default-from-address"; diff --git a/zanata-war/src/main/java/org/zanata/dao/AbstractDAOImpl.java b/zanata-war/src/main/java/org/zanata/dao/AbstractDAOImpl.java index 6798d492b0..73daf732b1 100644 --- a/zanata-war/src/main/java/org/zanata/dao/AbstractDAOImpl.java +++ b/zanata-war/src/main/java/org/zanata/dao/AbstractDAOImpl.java @@ -13,9 +13,10 @@ /** * Based on code from http://community.jboss.org/wiki/GenericDataAccessObjects */ -public abstract class AbstractDAOImpl implements GenericDAO +public abstract class AbstractDAOImpl implements GenericDAO, Serializable { - + private static final long serialVersionUID = 1L; + private Class persistentClass; private Session session; diff --git a/zanata-war/src/main/java/org/zanata/dao/ApplicationConfigurationDAO.java b/zanata-war/src/main/java/org/zanata/dao/ApplicationConfigurationDAO.java index 58c4ceb488..7be8370431 100644 --- a/zanata-war/src/main/java/org/zanata/dao/ApplicationConfigurationDAO.java +++ b/zanata-war/src/main/java/org/zanata/dao/ApplicationConfigurationDAO.java @@ -1,9 +1,7 @@ package org.zanata.dao; -import org.hibernate.Criteria; import org.hibernate.Session; -import org.hibernate.criterion.Restrictions; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.AutoCreate; import org.jboss.seam.annotations.Name; diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetReviewCommentsDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetReviewCommentsDAO.java new file mode 100644 index 0000000000..26a7f65bdd --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetReviewCommentsDAO.java @@ -0,0 +1,67 @@ +/* + * 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.dao; + +import java.util.List; + +import org.hibernate.Query; +import org.hibernate.Session; +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.AutoCreate; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.zanata.common.LocaleId; +import org.zanata.model.HTextFlowTargetReviewComment; +import org.zanata.webtrans.shared.model.TransUnitId; + +/** + * + * @author Patrick Huang pahuang@redhat.com + */ +@Name("textFlowTargetReviewCommentsDAO") +@AutoCreate +@Scope(ScopeType.STATELESS) +public class TextFlowTargetReviewCommentsDAO extends AbstractDAOImpl +{ + @SuppressWarnings("unused") + public TextFlowTargetReviewCommentsDAO() + { + super(HTextFlowTargetReviewComment.class); + } + + @SuppressWarnings("unused") + public TextFlowTargetReviewCommentsDAO(Session session) + { + super(HTextFlowTargetReviewComment.class, session); + } + + + public List getReviewComments(TransUnitId textFlowId, LocaleId localeId) + { + Query query = getSession().createQuery("select c from HTextFlowTargetReviewComment c join fetch c.commenter where c.textFlowTarget.textFlow.id = :textFlowId and c.textFlowTarget.locale.localeId = :localeId"); + query.setParameter("textFlowId", textFlowId.getValue()); + query.setParameter("localeId", localeId); + query.setComment("TextFlowTargetReviewCommentsDAO.getReviewComments"); + query.setCacheable(true); + return query.list(); + } +} diff --git a/zanata-war/src/main/java/org/zanata/service/impl/ProcessManagerServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/ProcessManagerServiceImpl.java index a21a81f795..6b4945f712 100644 --- a/zanata-war/src/main/java/org/zanata/service/impl/ProcessManagerServiceImpl.java +++ b/zanata-war/src/main/java/org/zanata/service/impl/ProcessManagerServiceImpl.java @@ -144,7 +144,7 @@ public void clearInactive() /** * Internal class to detect when a process is complete. */ - private final class DefaultProcessListener implements RunnableProcessListener, Serializable + private final class DefaultProcessListener implements RunnableProcessListener { private static final long serialVersionUID = 1L; diff --git a/zanata-war/src/main/java/org/zanata/service/impl/ValidationServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/ValidationServiceImpl.java index c818fcfea4..1f4eaa0cd8 100644 --- a/zanata-war/src/main/java/org/zanata/service/impl/ValidationServiceImpl.java +++ b/zanata-war/src/main/java/org/zanata/service/impl/ValidationServiceImpl.java @@ -257,18 +257,14 @@ public List filterHasErrorTexFlow(List textFlows, List result.size() ? result.size() : toIndex; + startIndex = startIndex > toIndex ? toIndex - maxSize : startIndex; + startIndex = startIndex < 0 ? 0 : startIndex; return result.subList(startIndex, toIndex); } - private void validateIndexes(int startIndex, int toIndex, int actualResultSize, int expectedResultSize) - { - toIndex = toIndex > actualResultSize ? actualResultSize : toIndex; - startIndex = startIndex > toIndex ? toIndex - expectedResultSize : startIndex; - startIndex = startIndex < 0 ? 0 : startIndex; - } - private boolean textFlowTargetHasError(Long textFlowId, List validationIds, LocaleId localeId) { HTextFlowTarget target = textFlowTargetDAO.getTextFlowTarget(textFlowId, localeId); diff --git a/zanata-war/src/main/java/org/zanata/util/DateUtil.java b/zanata-war/src/main/java/org/zanata/util/DateUtil.java index ee0150f12f..b13c8b4a06 100644 --- a/zanata-war/src/main/java/org/zanata/util/DateUtil.java +++ b/zanata-war/src/main/java/org/zanata/util/DateUtil.java @@ -3,24 +3,23 @@ */ package org.zanata.util; -import java.text.SimpleDateFormat; import java.util.Date; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + /** * * @author Alex Eng aeng@redhat.com * */ -// FIXME SimpleDateFormat is not thread safe; we should use JODA public class DateUtil { private final static String DATE_TIME_SHORT_PATTERN = "dd/MM/yy HH:mm"; private final static String TIME_SHORT_PATTERN = "hh:mm:ss"; - private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(DATE_TIME_SHORT_PATTERN); - private final static SimpleDateFormat TIME_FORMAT = new SimpleDateFormat(TIME_SHORT_PATTERN); - /** * Format date to dd/MM/yy hh:mm a * @param date @@ -30,7 +29,8 @@ public static String formatShortDate(Date date) { if(date != null) { - return DATE_FORMAT.format(date); + DateTimeFormatter fmt = DateTimeFormat.forPattern(DATE_TIME_SHORT_PATTERN); + return fmt.print(new DateTime(date)); } return null; } @@ -44,7 +44,8 @@ public static String formatTime(Date date) { if(date != null) { - return TIME_FORMAT.format(date); + DateTimeFormatter fmt = DateTimeFormat.forPattern(TIME_SHORT_PATTERN); + return fmt.print(new DateTime(date)); } return null; } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/events/ReviewCommentEvent.java b/zanata-war/src/main/java/org/zanata/webtrans/client/events/ReviewCommentEvent.java new file mode 100644 index 0000000000..13decb51bd --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/events/ReviewCommentEvent.java @@ -0,0 +1,52 @@ +/* + * 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.webtrans.client.events; + +import org.zanata.webtrans.shared.model.TransUnitId; +import com.google.gwt.event.shared.GwtEvent; + +public class ReviewCommentEvent extends GwtEvent +{ + public static Type TYPE = new Type(); + + private TransUnitId transUnitId; + + public ReviewCommentEvent(TransUnitId transUnitId) + { + this.transUnitId = transUnitId; + } + + public TransUnitId getTransUnitId() + { + return transUnitId; + } + + public Type getAssociatedType() + { + return TYPE; + } + + protected void dispatch(ReviewCommentEventHandler handler) + { + handler.onShowReviewComment(this); + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/events/ReviewCommentEventHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/client/events/ReviewCommentEventHandler.java new file mode 100644 index 0000000000..2b0da52031 --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/events/ReviewCommentEventHandler.java @@ -0,0 +1,29 @@ +/* + * 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.webtrans.client.events; + +import com.google.gwt.event.shared.EventHandler; + +public interface ReviewCommentEventHandler extends EventHandler +{ + void onShowReviewComment(ReviewCommentEvent event); +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/history/HistoryToken.java b/zanata-war/src/main/java/org/zanata/webtrans/client/history/HistoryToken.java index ca4edaab70..b65a7ce8ff 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/history/HistoryToken.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/history/HistoryToken.java @@ -264,12 +264,12 @@ public void setFilterTranslated(boolean filterTranslated) { this.filterTranslated = filterTranslated; } - + public void setFilterApproved(boolean filterApproved) { this.filterApproved = filterApproved; } - + public void setFilterRejected(boolean filterRejected) { this.filterRejected = filterRejected; diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/DocumentListPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/DocumentListPresenter.java index 4244b663cb..43c373f9ef 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/DocumentListPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/DocumentListPresenter.java @@ -344,8 +344,8 @@ public void onSuccess(GetDocumentStatsResult result) Integer row = pageRows.get(entry.getKey()); if (row != null) { - display.updateStats(row.intValue(), docInfo.getStats()); - display.updateLastTranslated(row.intValue(), docInfo.getLastTranslated()); + display.updateStats(row, docInfo.getStats()); + display.updateLastTranslated(row, docInfo.getLastTranslated()); } eventBus.fireEvent(new DocumentStatsUpdatedEvent(entry.getKey(), docInfo.getStats())); eventBus.fireEvent(new ProjectStatsUpdatedEvent(docInfo.getStats())); @@ -462,7 +462,6 @@ public void onDocumentSelected(DocumentSelectionEvent event) public void onTransUnitUpdated(TransUnitUpdatedEvent event) { TransUnitUpdateInfo updateInfo = event.getUpdateInfo(); - Log.info("********** updated Info:" + updateInfo); // update stats for containing document DocumentInfo updatedDoc = getDocumentInfo(updateInfo.getDocumentId()); ContainerTranslationStatistics currentStats = updatedDoc.getStats(); @@ -476,26 +475,14 @@ public void onTransUnitUpdated(TransUnitUpdatedEvent event) Integer row = pageRows.get(updatedDoc.getId()); if (row != null) { - display.updateStats(row.intValue(), updatedDoc.getStats()); + display.updateStats(row, updatedDoc.getStats()); AuditInfo lastTranslated = new AuditInfo(event.getUpdateInfo().getTransUnit().getLastModifiedTime(), event.getUpdateInfo().getTransUnit().getLastModifiedBy()); - display.updateLastTranslated(row.intValue(), lastTranslated); + display.updateLastTranslated(row, lastTranslated); } eventBus.fireEvent(new DocumentStatsUpdatedEvent(updatedDoc.getId(), currentStats)); } } - private static void logStatistics(String msg, TranslationStatistics statistics) - { - String string = com.google.common.base.Objects.toStringHelper(statistics). - add("unit", statistics.getUnit()). - add("approved", statistics.getApproved()). - add("draft", statistics.getDraft()). - add("new", statistics.getUntranslated()). -// add("locale", statistics.getLocale()). - toString(); - Log.info(msg + " statistics: " + string); - } - private void updateLastTranslatedInfo(DocumentInfo doc, TransUnit updatedTransUnit) { doc.setLastTranslated(new AuditInfo(updatedTransUnit.getLastModifiedTime(), updatedTransUnit.getLastModifiedBy())); @@ -510,10 +497,8 @@ private void adjustStats(ContainerTranslationStatistics stats, TransUnitUpdateIn TranslationStatistics msgStatistic = stats.getStats(localeId.getId(), StatUnit.MESSAGE); TranslationStatistics wordStatistic = stats.getStats(localeId.getId(), StatUnit.WORD); - logStatistics("before adjust", msgStatistic); msgStatistic.decrement(updateInfo.getPreviousState(), 1); msgStatistic.increment(updateInfo.getTransUnit().getStatus(), 1); - logStatistics("after adjust", msgStatistic); wordStatistic.decrement(updateInfo.getPreviousState(), updateInfo.getSourceWordCount()); wordStatistic.increment(updateInfo.getTransUnit().getStatus(), updateInfo.getSourceWordCount()); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentDataProvider.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentDataProvider.java new file mode 100644 index 0000000000..87cd023aa4 --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentDataProvider.java @@ -0,0 +1,51 @@ +/* + * 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.webtrans.client.presenter; + +import org.zanata.webtrans.client.view.ReviewCommentDisplay; +import org.zanata.webtrans.shared.model.ReviewComment; +import com.google.gwt.view.client.ListDataProvider; +import com.google.inject.Singleton; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +@Singleton +public class ReviewCommentDataProvider extends ListDataProvider +{ + public ReviewCommentDataProvider() + { + super(ReviewCommentDisplay.COMMENT_PROVIDES_KEY); + } + + public void setLoading(boolean loading) + { + if (loading) + { + updateRowCount(0, false); + } + else + { + updateRowCount(getList().size(), true); + } + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenter.java new file mode 100644 index 0000000000..251342c8e5 --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenter.java @@ -0,0 +1,119 @@ +/* + * 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.webtrans.client.presenter; + +import org.zanata.webtrans.client.events.ReviewCommentEvent; +import org.zanata.webtrans.client.events.ReviewCommentEventHandler; +import org.zanata.webtrans.client.rpc.AbstractAsyncCallback; +import org.zanata.webtrans.client.rpc.CachingDispatchAsync; +import org.zanata.webtrans.client.service.GetTransUnitActionContextHolder; +import org.zanata.webtrans.client.service.NavigationService; +import org.zanata.webtrans.client.view.ReviewCommentDisplay; +import org.zanata.webtrans.shared.model.TransUnit; +import org.zanata.webtrans.shared.model.TransUnitId; +import org.zanata.webtrans.shared.rpc.AddReviewCommentAction; +import org.zanata.webtrans.shared.rpc.AddReviewCommentResult; +import org.zanata.webtrans.shared.rpc.GetReviewCommentsAction; +import org.zanata.webtrans.shared.rpc.GetReviewCommentsResult; +import com.allen_sauer.gwt.log.client.Log; +import com.google.inject.Inject; +import com.google.inject.Singleton; + +import net.customware.gwt.presenter.client.EventBus; +import net.customware.gwt.presenter.client.widget.WidgetPresenter; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +@Singleton +public class ReviewCommentPresenter extends WidgetPresenter implements ReviewCommentDisplay.Listener, ReviewCommentEventHandler +{ + private final ReviewCommentDisplay display; + private final CachingDispatchAsync dispatcher; + private final ReviewCommentDataProvider dataProvider; + private final GetTransUnitActionContextHolder contextHolder; + private final NavigationService navigationService; + private TransUnitId transUnitId; + + @Inject + public ReviewCommentPresenter(ReviewCommentDisplay display, EventBus eventBus, CachingDispatchAsync dispatcher, ReviewCommentDataProvider dataProvider, GetTransUnitActionContextHolder contextHolder, NavigationService navigationService) + { + super(display, eventBus); + this.display = display; + this.dispatcher = dispatcher; + this.dataProvider = dataProvider; + this.contextHolder = contextHolder; + this.navigationService = navigationService; + + display.setListener(this); + display.setDataProvider(dataProvider); + } + + @Override + protected void onBind() + { + eventBus.addHandler(ReviewCommentEvent.TYPE, this); + } + + @Override + public void onShowReviewComment(ReviewCommentEvent event) + { + this.transUnitId = event.getTransUnitId(); + Integer currentTargetVersion = navigationService.getByIdOrNull(transUnitId).getVerNum(); + display.setCurrentTargetVersion(currentTargetVersion); + dataProvider.setLoading(true); + dispatcher.execute(new GetReviewCommentsAction(transUnitId), new AbstractAsyncCallback() + { + @Override + public void onSuccess(GetReviewCommentsResult result) + { + dataProvider.setList(result.getComments()); + dataProvider.setLoading(false); + } + }); + display.center(); + } + + @Override + public void addComment(String content) + { + dispatcher.execute(new AddReviewCommentAction(transUnitId, content, contextHolder.getContext().getDocument().getId()), new AbstractAsyncCallback() + { + @Override + public void onSuccess(AddReviewCommentResult result) + { + dataProvider.getList().add(result.getComment()); + display.clearInput(); + } + }); + } + + @Override + protected void onUnbind() + { + } + + @Override + protected void onRevealDisplay() + { + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/SearchResultsPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/SearchResultsPresenter.java index d70be96836..ba661fa1c6 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/SearchResultsPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/SearchResultsPresenter.java @@ -335,7 +335,7 @@ public void onTransUnitUpdated(final TransUnitUpdatedEvent event) } Log.debug("found matching TU for TU update, id: " + updateInfo.getTransUnit().getId().getId()); - if (replaceInfo.getReplaceState() == ReplacementState.Replaced && replaceInfo.getTransUnit().getVerNum() != updateInfo.getTransUnit().getVerNum()) + if (replaceInfo.getReplaceState() == ReplacementState.Replaced && !(replaceInfo.getTransUnit().getVerNum().equals(updateInfo.getTransUnit().getVerNum()))) { // can't undo after additional update setReplaceState(replaceInfo, ReplacementState.NotReplaced); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TargetContentsPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TargetContentsPresenter.java index 9bf0a592b6..02ac63e867 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TargetContentsPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TargetContentsPresenter.java @@ -89,6 +89,7 @@ public class TargetContentsPresenter implements private final TableEditorMessages messages; private final SourceContentsPresenter sourceContentsPresenter; private final TranslationHistoryPresenter historyPresenter; + private final ReviewCommentPresenter reviewCommentPresenter; private final Provider displayProvider; private final EditorTranslators editorTranslators; private final EditorKeyShortcuts editorKeyShortcuts; @@ -115,7 +116,8 @@ public TargetContentsPresenter(Provider displayProvider, EditorKeyShortcuts editorKeyShortcuts, TranslationHistoryPresenter historyPresenter, UserOptionsService userOptionsService, - SaveAsApprovedConfirmationDisplay saveAsApprovedConfirmation) + SaveAsApprovedConfirmationDisplay saveAsApprovedConfirmation, + ReviewCommentPresenter reviewCommentPresenter) // @formatter:on { this.displayProvider = displayProvider; @@ -126,6 +128,7 @@ public TargetContentsPresenter(Provider displayProvider, this.sourceContentsPresenter = sourceContentsPresenter; this.editorKeyShortcuts = editorKeyShortcuts; this.historyPresenter = historyPresenter; + this.reviewCommentPresenter = reviewCommentPresenter; this.historyPresenter.setCurrentValueHolder(this); this.userOptionsService = userOptionsService; this.saveAsApprovedConfirmation = saveAsApprovedConfirmation; @@ -145,6 +148,7 @@ private void bindEventHandlers() eventBus.addHandler(CopyDataToEditorEvent.getType(), this); eventBus.addHandler(TransUnitEditEvent.getType(), this); eventBus.addHandler(WorkspaceContextUpdateEvent.getType(), this); + reviewCommentPresenter.bind(); } public void savePendingChangesIfApplicable() @@ -687,6 +691,16 @@ public void rejectTranslation(TransUnitId id) saveCurrent(ContentState.Rejected); } + + public void updateCommentCount(TransUnitId id, int commentsCount) + { + Optional displayOptional = Finds.findDisplayById(displayList, id); + if (displayOptional.isPresent()) + { + displayOptional.get().updateCommentIndicator(commentsCount); + } + } + /** * For testing only * @param currentTransUnitId current trans unit id diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransUnitsTablePresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransUnitsTablePresenter.java index 591248dba3..028f893d45 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransUnitsTablePresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransUnitsTablePresenter.java @@ -289,7 +289,14 @@ public void refreshRow(TransUnit updatedTransUnit, EditorClientId editorClientId translationHistoryPresenter.displayEntries(latest, Collections. emptyList()); } } - targetContentsPresenter.updateRow(updatedTransUnit); + if (updateType == TransUnitUpdated.UpdateType.AddComment) + { + targetContentsPresenter.updateCommentCount(updatedTransUnit.getId(), updatedTransUnit.getCommentsCount()); + } + else + { + targetContentsPresenter.updateRow(updatedTransUnit); + } } // update type is web editor save or web editor save fuzzy and coming from diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/TableEditorMessages.java b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/TableEditorMessages.java index e45a9e80a1..9579fd1756 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/TableEditorMessages.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/TableEditorMessages.java @@ -112,4 +112,7 @@ public interface TableEditorMessages extends Messages @DefaultMessage("Reject translation") String reviewReject(); + + @DefaultMessage("Comment") + String comment(); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/WebTransMessages.java b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/WebTransMessages.java index 4e73a3fbc6..23aa5a51f2 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/WebTransMessages.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/WebTransMessages.java @@ -542,4 +542,6 @@ public interface WebTransMessages extends Messages @DefaultMessage("Download document with extension {0}") String downloadFileTitle(String key); + @DefaultMessage("Comment") + String reviewComment(); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/EditorButtonsWidget.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/EditorButtonsWidget.java index 4d86a7f05f..f932a819cd 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/EditorButtonsWidget.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/EditorButtonsWidget.java @@ -1,5 +1,7 @@ package org.zanata.webtrans.client.ui; +import org.zanata.common.ContentState; +import org.zanata.webtrans.client.events.ReviewCommentEvent; import org.zanata.webtrans.client.view.TargetContentsDisplay; import org.zanata.webtrans.shared.model.TransUnitId; import com.google.gwt.core.client.GWT; @@ -13,9 +15,12 @@ import com.google.gwt.user.client.ui.InlineLabel; import com.google.gwt.user.client.ui.SimplePanel; +import net.customware.gwt.presenter.client.EventBus; + public class EditorButtonsWidget extends Composite { private static EditorButtonsWidgetUiBinder ourUiBinder = GWT.create(EditorButtonsWidgetUiBinder.class); + private final EventBus eventBus; @UiField HTMLPanel buttons; @@ -35,12 +40,15 @@ public class EditorButtonsWidget extends Composite InlineLabel acceptIcon; @UiField InlineLabel rejectIcon; + @UiField + InlineLabel commentIcon; private TargetContentsDisplay.Listener listener; private TransUnitId id; - public EditorButtonsWidget() + public EditorButtonsWidget(EventBus eventBus) { + this.eventBus = eventBus; initWidget(ourUiBinder.createAndBindUi(this)); setDisplayReviewButtons(listener != null && listener.canReviewTranslation()); setDisplayModifyTranslationButtons(listener != null && listener.canModifyTranslation()); @@ -121,6 +129,12 @@ public void onReject(ClickEvent event) event.stopPropagation(); } + @UiHandler("commentIcon") + public void onCommentClick(ClickEvent event) + { + eventBus.fireEvent(new ReviewCommentEvent(id)); + } + public void setListener(TargetContentsDisplay.Listener listener) { this.listener = listener; @@ -128,9 +142,15 @@ public void setListener(TargetContentsDisplay.Listener listener) setDisplayModifyTranslationButtons(listener.canModifyTranslation()); } - public void setId(TransUnitId id) + public void setIdAndState(TransUnitId id, ContentState state) { this.id = id; + enableComment(state.isTranslated() || state.isRejectedOrFuzzy()); + } + + private void enableComment(boolean enable) + { + commentIcon.setVisible(enable); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/EditorButtonsWidget.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/EditorButtonsWidget.ui.xml index 8ce0c6255f..ea44f13fc0 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/EditorButtonsWidget.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/EditorButtonsWidget.ui.xml @@ -21,6 +21,7 @@ + \ No newline at end of file diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentDisplay.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentDisplay.java new file mode 100644 index 0000000000..0c8b33108a --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentDisplay.java @@ -0,0 +1,57 @@ +/* + * 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.webtrans.client.view; + +import org.zanata.webtrans.shared.model.ReviewComment; +import com.google.gwt.view.client.ListDataProvider; +import com.google.gwt.view.client.ProvidesKey; +import com.google.inject.ImplementedBy; + +import net.customware.gwt.presenter.client.widget.WidgetDisplay; + +@ImplementedBy(ReviewCommentView.class) +public interface ReviewCommentDisplay extends WidgetDisplay +{ + static final ProvidesKey COMMENT_PROVIDES_KEY = new ProvidesKey() + { + @Override + public Object getKey(ReviewComment item) + { + return item.getId(); + } + }; + + void setDataProvider(ListDataProvider dataProvider); + + void setListener(Listener listener); + + void center(); + + void clearInput(); + + void setCurrentTargetVersion(Integer targetVersion); + + interface Listener + { + void addComment(String comment); + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.java new file mode 100644 index 0000000000..ea5f04e7db --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.java @@ -0,0 +1,213 @@ +/* + * 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.webtrans.client.view; + +import org.zanata.webtrans.client.resources.WebTransMessages; +import org.zanata.webtrans.client.ui.CellTableResources; +import org.zanata.webtrans.client.ui.DialogBoxCloseButton; +import org.zanata.webtrans.client.util.DateUtil; +import org.zanata.webtrans.shared.model.ReviewComment; +import com.google.common.base.Objects; +import com.google.gwt.cell.client.Cell; +import com.google.gwt.cell.client.TextCell; +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.resources.client.CssResource; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.user.cellview.client.CellTable; +import com.google.gwt.user.cellview.client.Column; +import com.google.gwt.user.cellview.client.SimplePager; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTMLPanel; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; +import com.google.gwt.view.client.ListDataProvider; +import com.google.inject.Singleton; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +@Singleton +public class ReviewCommentView extends DialogBox implements ReviewCommentDisplay +{ + private static final CellTableResources CELL_TABLE_RESOURCES = GWT.create(CellTableResources.class); + private static AddReviewCommentViewUiBinder ourUiBinder = GWT.create(AddReviewCommentViewUiBinder.class); + + @UiField(provided = true) + DialogBoxCloseButton closeButton; + @UiField + WebTransMessages messages; + @UiField + VerticalPanel commentsContainer; + @UiField + Styles style; + + private final CellTable commentTable; + private Listener listener; + private TextBox commentInputBox; + private Integer currentTargetVersion; + + public ReviewCommentView() + { + super(true, true); + closeButton = new DialogBoxCloseButton(this); + HTMLPanel root = ourUiBinder.createAndBindUi(this); + setGlassEnabled(true); + + commentTable = setUpTable(); + + SimplePager simplePager = new SimplePager(); + simplePager.setDisplay(commentTable); + + commentsContainer.add(commentTable); + commentsContainer.add(simplePager); + commentsContainer.add(createCommentInput()); + + setWidget(root); + } + + private Widget createCommentInput() + { + FlowPanel panel = new FlowPanel(); + commentInputBox = new TextBox(); + panel.add(commentInputBox); + Button addButton = new Button(messages.reviewComment(), new ClickHandler() + { + @Override + public void onClick(ClickEvent event) + { + listener.addComment(commentInputBox.getValue()); + } + }); + panel.add(addButton); + return panel; + } + + private CellTable setUpTable() + { + CellTable table = new CellTable(15, CELL_TABLE_RESOURCES, COMMENT_PROVIDES_KEY); + table.setEmptyTableWidget(new Label(messages.noContent())); + table.setLoadingIndicator(new Label(messages.loading())); + + Column commentColumn = createCommentColumn(); + Column commenterColumn = createCommenterColumn(); + Column commentedDateColumn = createCommentedDateColumn(); + + table.addColumn(commenterColumn, messages.modifiedBy()); + table.setColumnWidth(commenterColumn, 10, Style.Unit.PCT); + + table.addColumn(commentedDateColumn, messages.modifiedDate()); + table.setColumnWidth(commentedDateColumn, 20, Style.Unit.PCT); + + table.addColumn(commentColumn, messages.reviewComment()); + table.setColumnWidth(commentColumn, 70, Style.Unit.PCT); + + return table; + } + + private Column createCommentColumn() + { + return new Column(new TextCell()) + { + @Override + public String getValue(ReviewComment object) + { + return object.getComment(); + } + + @Override + public String getCellStyleNames(Cell.Context context, ReviewComment object) + { + if (!Objects.equal(object.getTargetVersion(), currentTargetVersion)) + { + return style.obsoleteComment(); + } + return super.getCellStyleNames(context, object); + } + }; + } + + private static Column createCommenterColumn() + { + return new Column(new TextCell()) + { + @Override + public String getValue(ReviewComment item) + { + return item.getCommenterName(); + } + }; + } + + private static Column createCommentedDateColumn() + { + return new Column(new TextCell()) + { + @Override + public String getValue(ReviewComment item) + { + return DateUtil.formatShortDate(item.getCreationDate()); + } + }; + } + + @Override + public void clearInput() + { + commentInputBox.setText(""); + } + + @Override + public void setCurrentTargetVersion(Integer targetVersion) + { + this.currentTargetVersion = targetVersion; + } + + @Override + public void setDataProvider(ListDataProvider dataProvider) + { + dataProvider.addDataDisplay(commentTable); + } + + @Override + public void setListener(Listener listener) + { + this.listener = listener; + } + + interface AddReviewCommentViewUiBinder extends UiBinder + { + } + + interface Styles extends CssResource + { + + String obsoleteComment(); + } +} \ No newline at end of file diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.ui.xml new file mode 100644 index 0000000000..29fb1c892b --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.ui.xml @@ -0,0 +1,40 @@ + + + + + + .obsoleteComment + { + font-style: italic; + text-decoration: line-through; + } + + + + + + + + + \ No newline at end of file diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsDisplay.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsDisplay.java index 6eb203659b..eec4764ae3 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsDisplay.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsDisplay.java @@ -70,6 +70,8 @@ public interface TargetContentsDisplay extends WidgetDisplay, HasTransUnitId, Ha void setEnableSpellCheck(boolean spellCheckEnabled); + void updateCommentIndicator(int commentsCount); + interface Listener { void validate(ToggleEditor editor); @@ -103,6 +105,7 @@ interface Listener void acceptTranslation(TransUnitId id); void rejectTranslation(TransUnitId id); + } enum EditingState diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsView.java index 1e4b48a91f..b3e798c179 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsView.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsView.java @@ -24,7 +24,7 @@ import java.util.List; import org.zanata.common.ContentState; -import org.zanata.webtrans.client.resources.TableEditorMessages; +import org.zanata.webtrans.client.events.ReviewCommentEvent; import org.zanata.webtrans.client.ui.Editor; import org.zanata.webtrans.client.ui.EditorButtonsWidget; import org.zanata.webtrans.client.ui.ToggleEditor; @@ -33,8 +33,6 @@ import org.zanata.webtrans.client.util.ContentStateToStyleUtil; import org.zanata.webtrans.shared.model.TransUnit; import org.zanata.webtrans.shared.model.TransUnitId; -import org.zanata.webtrans.shared.model.UserWorkspaceContext; - import com.google.common.base.Objects; import com.google.common.collect.Lists; import com.google.gwt.core.client.GWT; @@ -45,19 +43,19 @@ import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Grid; -import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.HorizontalPanel; -import com.google.gwt.user.client.ui.InlineLabel; import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.google.inject.Inject; import com.google.inject.Provider; +import net.customware.gwt.presenter.client.EventBus; + public class TargetContentsView extends Composite implements TargetContentsDisplay { private static final int COLUMNS = 1; private static Binder binder = GWT.create(Binder.class); + private final EventBus eventBus; @UiField Grid editorGrid; @@ -70,8 +68,10 @@ public class TargetContentsView extends Composite implements TargetContentsDispl @UiField Label savingIndicator; - @UiField + @UiField(provided = true) EditorButtonsWidget buttons; + @UiField + Label commentIndicator; private HorizontalPanel rootPanel; private ArrayList editors; @@ -81,8 +81,10 @@ public class TargetContentsView extends Composite implements TargetContentsDispl private TransUnit cachedValue; @Inject - public TargetContentsView(Provider validationMessagePanelViewProvider) + public TargetContentsView(Provider validationMessagePanelViewProvider, EventBus eventBus) { + this.eventBus = eventBus; + buttons = new EditorButtonsWidget(eventBus); validationPanel = validationMessagePanelViewProvider.get(); rootPanel = binder.createAndBindUi(this); editorGrid.addStyleName("TableEditorCell-Target-Table"); @@ -91,6 +93,12 @@ public TargetContentsView(Provider validationMessage editors = Lists.newArrayList(); } + @UiHandler("commentIndicator") + public void commentIndicatorClicked(ClickEvent event) + { + eventBus.fireEvent(new ReviewCommentEvent(getId())); + } + @Override public void showButtons(boolean displayButtons) { @@ -120,8 +128,8 @@ public void addUndo(final UndoLink undoLink) @Override public void setValueAndCreateNewEditors(TransUnit transUnit) { - cachedValue = transUnit; - buttons.setId(cachedValue.getId()); + setCachedTU(transUnit); + updateCommentIndicator(transUnit.getCommentsCount()); editors.clear(); List cachedTargets = cachedValue.getTargets(); @@ -139,35 +147,19 @@ public void setValueAndCreateNewEditors(TransUnit transUnit) editors.add(editor); rowIndex++; } - editorGrid.setStyleName(resolveStyleName(cachedValue.getStatus())); editingState = EditingState.SAVED; } private static String resolveStyleName(ContentState status) { - // TODO consolidate and simplify all the state styling. See also SearchResultsDocumentTable, TranslationHistoryView return ContentStateToStyleUtil.stateToStyle(status, "TableEditorRow "); -// String state = ""; -// switch (status) -// { -// case Approved: -// state = " Approved"; -// break; -// case NeedReview: -// state = " Fuzzy"; -// break; -// case New: -// state = " New"; -// break; -// case Translated: -// state = " Translated"; -// break; -// case Rejected: -// state = " Rejected"; -// break; -// } -// styles += state + "StateDecoration"; -// return styles; + } + + @Override + public void updateCommentIndicator(int commentsCount) + { + commentIndicator.setVisible(commentsCount > 0); + commentIndicator.setText(String.valueOf(commentsCount)); } @Override @@ -204,8 +196,14 @@ public EditingState getEditingState() @Override public void updateCachedTargetsAndVersion(List targets, Integer verNum, ContentState status) { - cachedValue = TransUnit.Builder.from(cachedValue).setTargets(targets).setVerNum(verNum).setStatus(status).build(); + setCachedTU(TransUnit.Builder.from(cachedValue).setTargets(targets).setVerNum(verNum).setStatus(status).build()); + } + + private void setCachedTU(TransUnit newTransUnit) + { + cachedValue = newTransUnit; editorGrid.setStyleName(resolveStyleName(cachedValue.getStatus())); + buttons.setIdAndState(cachedValue.getId(), cachedValue.getStatus()); } @Override @@ -327,6 +325,8 @@ interface Styles extends CssResource String unsaved(); String saving(); + + String commentIndicator(); } interface Binder extends UiBinder diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsView.ui.xml index fa68c64917..d13619b1b6 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsView.ui.xml @@ -33,12 +33,28 @@ background-color: #ff4500; } + .commentIndicator { + position: absolute; + right: 5px; + font-size: smaller; + color: #ffffff; + z-index: 1; + background-color: #ff0000; + border-radius: 10px; + border: thick double #ffffff; + padding-left: 2px; + padding-right: 2px; + box-shadow: 2px 2px 2px #888; + cursor: pointer; + } + + diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterDisplay.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterDisplay.java index fc210b83f6..399bf1feb6 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterDisplay.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterDisplay.java @@ -21,7 +21,7 @@ public interface TransFilterDisplay extends WidgetDisplay, SearchFieldListener void setNeedReviewFilter(boolean filterByNeedReview); void setUntranslatedFilter(boolean filterByUntranslated); - + void setApprovedFilter(boolean filterByApproved); void setRejectedFilter(boolean filterByRejected); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterView.java index dafd8695a5..94f671e670 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterView.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterView.java @@ -27,15 +27,14 @@ import com.allen_sauer.gwt.log.client.Log; import com.google.common.base.Strings; import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.SelectElement; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.Widget; import com.google.inject.Inject; @@ -52,11 +51,10 @@ public class TransFilterView extends Composite implements TransFilterDisplay Styles style; @UiField - CheckBox translatedChk, fuzzyChk, untranslatedChk, approvedChk, rejectedChk, hasErrorChk; - - @UiField - CheckBox incompleteChk, completeChk; - + CheckBox parentIncompleteChk, untranslatedChk, fuzzyChk, rejectedChk, + parentCompleteChk, translatedChk, approvedChk, + hasErrorChk; + private String hintMessage; private boolean focused = false; @@ -116,39 +114,45 @@ public void setSearchTerm(String searchTerm) } @Override - public void setTranslatedFilter(boolean filterByTranslated) + public void setUntranslatedFilter(boolean filterByUntranslated) { - translatedChk.setValue(filterByTranslated); + updateChildCheckbox(untranslatedChk, filterByUntranslated); } @Override public void setNeedReviewFilter(boolean filterByNeedReview) { - fuzzyChk.setValue(filterByNeedReview); + updateChildCheckbox(fuzzyChk, filterByNeedReview); } @Override - public void setUntranslatedFilter(boolean filterByUntranslated) + public void setTranslatedFilter(boolean filterByTranslated) { - untranslatedChk.setValue(filterByUntranslated); + updateChildCheckbox(translatedChk, filterByTranslated); } - + @Override public void setApprovedFilter(boolean filterByApproved) { - approvedChk.setValue(filterByApproved); + updateChildCheckbox(approvedChk, filterByApproved); } - + @Override public void setRejectedFilter(boolean filterByRejected) { - rejectedChk.setValue(filterByRejected); + updateChildCheckbox(rejectedChk, filterByRejected); } @Override public void setHasErrorFilter(boolean filterByHasError) { - hasErrorChk.setValue(filterByHasError); + updateChildCheckbox(hasErrorChk, filterByHasError); + } + + private void updateChildCheckbox(CheckBox checkbox, boolean value) + { + checkbox.setValue(value); + updateParentCheckboxes(); } @Override @@ -198,53 +202,49 @@ public void onSearchFieldCancel() @UiHandler({"translatedChk", "fuzzyChk", "untranslatedChk", "approvedChk", "rejectedChk", "hasErrorChk"}) public void onFilterOptionsChanged(ValueChangeEvent event) { - toggleCompleteChk(); - toggleIncompleteChk(); - - listener.messageFilterOptionChanged(translatedChk.getValue(), fuzzyChk.getValue(), untranslatedChk.getValue(), approvedChk.getValue(), rejectedChk.getValue(), hasErrorChk.getValue()); + updateParentCheckboxes(); + listener.messageFilterOptionChanged(translatedChk.getValue(), fuzzyChk.getValue(), + untranslatedChk.getValue(), approvedChk.getValue(), rejectedChk.getValue(), hasErrorChk.getValue()); } - - public void toggleCompleteChk() + + private void updateParentCheckboxes() { - if(translatedChk.getValue() == approvedChk.getValue()) - { - if(approvedChk.getValue() == true) - { - completeChk.setValue(true); - } - else - { - completeChk.setValue(false); - } - } - else - { - //Should be indeterminate states if all checkboxes has different states, but GWT checkbox doesn't support it - completeChk.setValue(false); - } + updateParentCheckboxToMatchChildren(parentIncompleteChk, untranslatedChk, fuzzyChk, rejectedChk); + updateParentCheckboxToMatchChildren(parentCompleteChk, translatedChk, approvedChk); } - - public void toggleIncompleteChk() + + private void updateParentCheckboxToMatchChildren(CheckBox parent, CheckBox... children) { - if(untranslatedChk.getValue() == fuzzyChk.getValue() && fuzzyChk.getValue() == rejectedChk.getValue() && rejectedChk.getValue()) + boolean allChecked = allHaveValue(true, children); + boolean noneChecked = allHaveValue(false, children); + boolean partiallyChecked = !(allChecked || noneChecked); + + parent.setValue(allChecked); + setPartiallyChecked(parent, partiallyChecked); + } + + private static boolean allHaveValue(boolean checkValue, CheckBox... checkboxes) + { + for (CheckBox checkbox : checkboxes) { - if(rejectedChk.getValue() == true) - { - incompleteChk.setValue(true); - } - else + if (checkbox.getValue() != checkValue) { - incompleteChk.setValue(false); + return false; } } - else - { - //Should be indeterminate states if all checkboxes has different states - incompleteChk.setValue(false); - } + return true; } - - @UiHandler("incompleteChk") + + private static void setPartiallyChecked(CheckBox checkbox, boolean partiallyChecked) + { + setElementIndeterminate(checkbox.getElement(), partiallyChecked); + } + + private static native void setElementIndeterminate(Element elem, boolean indeterminate)/*-{ + elem.getElementsByTagName('input')[0].indeterminate = indeterminate; + }-*/; + + @UiHandler("parentIncompleteChk") public void onIncompleteChkChanged(ValueChangeEvent event) { untranslatedChk.setValue(event.getValue()); @@ -253,7 +253,7 @@ public void onIncompleteChkChanged(ValueChangeEvent event) onFilterOptionsChanged(event); } - @UiHandler("completeChk") + @UiHandler("parentCompleteChk") public void onCompleteChkChanged(ValueChangeEvent event) { translatedChk.setValue(event.getValue()); @@ -264,9 +264,9 @@ public void onCompleteChkChanged(ValueChangeEvent event) @Override public void setOptionsState(ConfigurationState state) { - translatedChk.setValue(state.isFilterByTranslated()); - fuzzyChk.setValue(state.isFilterByNeedReview()); untranslatedChk.setValue(state.isFilterByUntranslated()); + fuzzyChk.setValue(state.isFilterByNeedReview()); + translatedChk.setValue(state.isFilterByTranslated()); approvedChk.setValue(state.isFilterByApproved()); rejectedChk.setValue(state.isFilterByRejected()); hasErrorChk.setValue(state.isFilterByHasError()); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterView.ui.xml index befb8ae31a..de9d674c98 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterView.ui.xml @@ -75,7 +75,7 @@ } .drop-down { - position:relative: + position:relative; } .drop-down:hover { @@ -145,7 +145,7 @@
  • - Incomplete + Incomplete
    • @@ -161,7 +161,7 @@
    • - Complete + Complete
      • diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandler.java new file mode 100644 index 0000000000..6d2551b3df --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandler.java @@ -0,0 +1,110 @@ +/* + * 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.webtrans.server.rpc; + +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.security.management.JpaIdentityStore; +import org.zanata.dao.TextFlowTargetDAO; +import org.zanata.model.HAccount; +import org.zanata.model.HLocale; +import org.zanata.model.HTextFlow; +import org.zanata.model.HTextFlowTarget; +import org.zanata.model.HTextFlowTargetReviewComment; +import org.zanata.service.SecurityService; +import org.zanata.webtrans.server.ActionHandlerFor; +import org.zanata.webtrans.server.TranslationWorkspace; +import org.zanata.webtrans.shared.model.ReviewComment; +import org.zanata.webtrans.shared.model.ReviewCommentId; +import org.zanata.webtrans.shared.model.TransUnit; +import org.zanata.webtrans.shared.model.TransUnitUpdateInfo; +import org.zanata.webtrans.shared.rpc.AddReviewCommentAction; +import org.zanata.webtrans.shared.rpc.AddReviewCommentResult; +import org.zanata.webtrans.shared.rpc.TransUnitUpdated; + +import lombok.extern.slf4j.Slf4j; +import net.customware.gwt.dispatch.server.ExecutionContext; +import net.customware.gwt.dispatch.shared.ActionException; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +@Name("webtrans.gwt.AddReviewCommentHandler") +@Scope(ScopeType.STATELESS) +@ActionHandlerFor(AddReviewCommentAction.class) +@Slf4j +public class AddReviewCommentHandler extends AbstractActionHandler +{ + @In + private SecurityService securityServiceImpl; + + @In + private TextFlowTargetDAO textFlowTargetDAO; + + @In(value = JpaIdentityStore.AUTHENTICATED_USER) + private HAccount authenticatedAccount; + + @In + TransUnitTransformer transUnitTransformer; + + @Override + public AddReviewCommentResult execute(AddReviewCommentAction action, ExecutionContext context) throws ActionException + { + SecurityService.SecurityCheckResult securityCheckResult = securityServiceImpl.checkPermission(action, SecurityService.TranslationAction.MODIFY); + HLocale hLocale = securityCheckResult.getLocale(); + TranslationWorkspace workspace = securityCheckResult.getWorkspace(); + + HTextFlowTarget hTextFlowTarget = textFlowTargetDAO.getTextFlowTarget(action.getTransUnitId().getValue(), hLocale.getLocaleId()); + if (hTextFlowTarget == null || hTextFlowTarget.getState().isUntranslated()) + { + throw new ActionException("comment on untranslated message is pointless!"); + } + HTextFlowTargetReviewComment hComment = hTextFlowTarget.addReviewComment(action.getContent(), authenticatedAccount.getPerson()); + textFlowTargetDAO.makePersistent(hTextFlowTarget); + textFlowTargetDAO.flush(); + + publishTransUnitUpdatedEvent(action, hLocale, hTextFlowTarget, workspace); + + return new AddReviewCommentResult(toDTO(hComment)); + } + + private void publishTransUnitUpdatedEvent(AddReviewCommentAction action, HLocale hLocale, HTextFlowTarget hTextFlowTarget, TranslationWorkspace workspace) + { + HTextFlow textFlow = hTextFlowTarget.getTextFlow(); + TransUnit transUnit = transUnitTransformer.transform(textFlow, hTextFlowTarget, hLocale); + TransUnitUpdated transUnitUpdated = new TransUnitUpdated(new TransUnitUpdateInfo(true, false, action.getDocumentId(), transUnit, textFlow.getWordCount().intValue(), transUnit.getVerNum(), transUnit.getStatus()), action.getEditorClientId(), TransUnitUpdated.UpdateType.AddComment); + workspace.publish(transUnitUpdated); + } + + private static ReviewComment toDTO(HTextFlowTargetReviewComment hComment) + { + return new ReviewComment(new ReviewCommentId(hComment.getId()), hComment.getComment(), hComment.getCommenterName(), hComment.getCreationDate(), hComment.getTargetVersion()); + } + + @Override + public void rollback(AddReviewCommentAction action, AddReviewCommentResult result, ExecutionContext context) throws ActionException + { + + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetReviewCommentsHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetReviewCommentsHandler.java new file mode 100644 index 0000000000..735979a1e2 --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetReviewCommentsHandler.java @@ -0,0 +1,76 @@ +/* + * 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.webtrans.server.rpc; + +import java.util.List; + +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.zanata.dao.TextFlowTargetReviewCommentsDAO; +import org.zanata.model.HTextFlowTargetReviewComment; +import org.zanata.webtrans.server.ActionHandlerFor; +import org.zanata.webtrans.shared.model.ReviewComment; +import org.zanata.webtrans.shared.model.ReviewCommentId; +import org.zanata.webtrans.shared.rpc.GetReviewCommentsAction; +import org.zanata.webtrans.shared.rpc.GetReviewCommentsResult; +import com.google.common.base.Function; +import com.google.common.collect.Lists; + +import net.customware.gwt.dispatch.server.ExecutionContext; +import net.customware.gwt.dispatch.shared.ActionException; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +@Name("webtrans.gwt.GetReviewCommentsHandler") +@Scope(ScopeType.STATELESS) +@ActionHandlerFor(GetReviewCommentsAction.class) +public class GetReviewCommentsHandler extends AbstractActionHandler +{ + @In + private TextFlowTargetReviewCommentsDAO textFlowTargetReviewCommentsDAO; + + @Override + public GetReviewCommentsResult execute(GetReviewCommentsAction action, ExecutionContext context) throws ActionException + { + List hComments = textFlowTargetReviewCommentsDAO.getReviewComments(action.getTransUnitId(), action.getWorkspaceId().getLocaleId()); + + List comments = Lists.transform(hComments, new Function() + { + @Override + public ReviewComment apply(HTextFlowTargetReviewComment input) + { + return new ReviewComment(new ReviewCommentId(input.getId()), input.getComment(), input.getCommenterName(), input.getCreationDate(), input.getTargetVersion()); + } + }); + // we re-wrap the list because gwt rpc doesn't like other list implementation + return new GetReviewCommentsResult(Lists.newArrayList(comments)); + } + + @Override + public void rollback(GetReviewCommentsAction action, GetReviewCommentsResult result, ExecutionContext context) throws ActionException + { + + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandler.java index 0f3ef5bc79..d2e20551e4 100755 --- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandler.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandler.java @@ -123,11 +123,13 @@ private List getTextFlows(GetTransUnitList action, HLocale hLocale, i log.debug("Fetch TransUnits:*"); if (!hasValidationFilter(action)) { + // TODO debt: this should use a left join to fetch target (and possibly comments) textFlows = textFlowDAO.getTextFlowsByDocumentId(action.getDocumentId(), offset, action.getCount()); } // has validation filter else { + // TODO debt: this is not scalable. But we may not have other choice for validation filter. Maybe use scrollable result will help? textFlows = textFlowDAO.getAllTextFlowsByDocumentId(action.getDocumentId()); textFlows = validationServiceImpl.filterHasErrorTexFlow(textFlows, action.getValidationIds(), hLocale.getLocaleId(), offset, action.getCount()); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/TransUnitTransformer.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/TransUnitTransformer.java index 00854784a6..dcce8ec97f 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/TransUnitTransformer.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/TransUnitTransformer.java @@ -21,6 +21,8 @@ package org.zanata.webtrans.server.rpc; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.AutoCreate; @@ -31,8 +33,12 @@ import org.zanata.model.HSimpleComment; import org.zanata.model.HTextFlow; import org.zanata.model.HTextFlowTarget; +import org.zanata.model.HTextFlowTargetReviewComment; import org.zanata.rest.service.ResourceUtils; +import org.zanata.webtrans.shared.model.ReviewCommentId; import org.zanata.webtrans.shared.model.TransUnit; +import com.google.common.base.Function; +import com.google.common.collect.Lists; @Name("transUnitTransformer") @Scope(ScopeType.STATELESS) @@ -46,17 +52,17 @@ public class TransUnitTransformer public TransUnit transform(HTextFlow hTextFlow, HLocale hLocale) { + // TODO debt: we iterate over a collection of text flow and call this + // method, if target is not eagerly loaded it will cause hibernate n+1. + // We may want to have a method as transform(Collection + // hTextFlows, HLocale hLocale) and use query internally or change caller + // code to always eager load targets. HTextFlowTarget target = hTextFlow.getTargets().get(hLocale.getId()); return transform(hTextFlow, target, hLocale); } - public TransUnit transform(HTextFlow hTextFlow, HTextFlowTarget target) - { - return transform(hTextFlow, target, target.getLocale()); - } - - private TransUnit transform(HTextFlow hTextFlow, HTextFlowTarget target, HLocale hLocale) + public TransUnit transform(HTextFlow hTextFlow, HTextFlowTarget target, HLocale hLocale) { String msgContext = null; if (hTextFlow.getPotEntryData() != null) @@ -68,7 +74,22 @@ private TransUnit transform(HTextFlow hTextFlow, HTextFlowTarget target, HLocale ArrayList sourceContents = GwtRpcUtil.getSourceContents(hTextFlow); ArrayList targetContents = GwtRpcUtil.getTargetContentsWithPadding(hTextFlow, target, nPlurals); - TransUnit.Builder builder = TransUnit.Builder.newTransUnitBuilder().setId(hTextFlow.getId()).setResId(hTextFlow.getResId()).setLocaleId(hLocale.getLocaleId()).setPlural(hTextFlow.isPlural()).setSources(sourceContents).setSourceComment(commentToString(hTextFlow.getComment())).setTargets(targetContents).setTargetContent(target == null ? null : commentToString(target.getComment())).setMsgContext(msgContext).setRowIndex(hTextFlow.getPos()).setVerNum(target == null ? NULL_TARGET_VERSION_NUM : target.getVersionNum()); + // @formatter:off + TransUnit.Builder builder = TransUnit.Builder.newTransUnitBuilder() + .setId(hTextFlow.getId()) + .setResId(hTextFlow.getResId()) + .setLocaleId(hLocale.getLocaleId()) + .setPlural(hTextFlow.isPlural()) + .setSources(sourceContents) + .setSourceComment(commentToString(hTextFlow.getComment())) + .setTargets(targetContents) + .setTargetComment(target == null ? null : commentToString(target.getComment())) + .setMsgContext(msgContext) + .setRowIndex(hTextFlow.getPos()) + .setVerNum(target == null ? NULL_TARGET_VERSION_NUM : target.getVersionNum()) + .setCommentsCount(getCommentCount(target)) + ; + // @formatter:on if (target != null) { @@ -82,6 +103,17 @@ private TransUnit transform(HTextFlow hTextFlow, HTextFlowTarget target, HLocale return builder.build(); } + private static int getCommentCount(HTextFlowTarget target) + { + if (target == null) + { + return 0; + } + // TODO pahuang this will cause extra database call for each target. See above transform(HTextFlow, HLocale). + return target.getReviewComments().size(); + } + + private static String commentToString(HSimpleComment comment) { return comment == null ? null : comment.getComment(); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ReviewComment.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ReviewComment.java new file mode 100644 index 0000000000..582c9286b6 --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ReviewComment.java @@ -0,0 +1,113 @@ +package org.zanata.webtrans.shared.model; + +import java.util.Date; +import java.util.List; + +import org.zanata.common.ContentState; +import com.google.gwt.user.client.rpc.IsSerializable; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +public class ReviewComment implements IsSerializable +{ + private ReviewCommentId id; + private String comment; + private List targetContents; + private String commenterName; + private Date creationDate; + private ContentState targetState; + private Integer targetVersion; + + @SuppressWarnings("unused") + public ReviewComment() + { + } + + public ReviewComment(ReviewCommentId id, String comment, String commenterName, Date creationDate, Integer targetVersion) + { + this.id = id; + this.comment = comment; + this.commenterName = commenterName; + this.creationDate = creationDate; + this.targetVersion = targetVersion; + } + + public ReviewComment attachMetaInfo(List targetContents, ContentState targetState) + { + this.targetContents = targetContents; + this.targetState = targetState; + return this; + } + + public ReviewCommentId getId() + { + return id; + } + + public String getComment() + { + return comment; + } + + public List getTargetContents() + { + return targetContents; + } + + public String getCommenterName() + { + return commenterName; + } + + public Date getCreationDate() + { + return creationDate; + } + + public ContentState getTargetState() + { + return targetState; + } + + public Integer getTargetVersion() + { + return targetVersion; + } + + // setters to make gwt serialization happy + void setId(ReviewCommentId id) + { + this.id = id; + } + + void setComment(String comment) + { + this.comment = comment; + } + + void setTargetContents(List targetContents) + { + this.targetContents = targetContents; + } + + void setCommenterName(String commenterName) + { + this.commenterName = commenterName; + } + + void setCreationDate(Date creationDate) + { + this.creationDate = creationDate; + } + + void setTargetState(ContentState targetState) + { + this.targetState = targetState; + } + + void setTargetVersion(Integer targetVersion) + { + this.targetVersion = targetVersion; + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ReviewCommentId.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ReviewCommentId.java new file mode 100644 index 0000000000..6bcc140cfa --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ReviewCommentId.java @@ -0,0 +1,80 @@ +/* + * 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.webtrans.shared.model; + +import java.io.Serializable; + +import com.google.gwt.user.client.rpc.IsSerializable; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +public class ReviewCommentId implements Identifier, IsSerializable, Serializable +{ + private static final long serialVersionUID = 1L; + + private Long id; + + public ReviewCommentId(Long id) + { + this.id = id; + } + + @SuppressWarnings("unused") + public ReviewCommentId() + { + } + + @Override + public Long getValue() + { + return id; + } + + public Long getId() + { + return id; + } + + void setId(Long id) + { + this.id = id; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ReviewCommentId that = (ReviewCommentId) o; + + return id.equals(that.id); + + } + + @Override + public int hashCode() + { + return id.hashCode(); + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransUnit.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransUnit.java index dcd7dc388a..afbb5ae79c 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransUnit.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransUnit.java @@ -32,6 +32,7 @@ public class TransUnit implements IsSerializable, HasTransUnitId private int rowIndex; private int verNum; private String targetComment; + private int commentsCount; // for GWT @SuppressWarnings("unused") @@ -55,6 +56,7 @@ private TransUnit(Builder builder) this.rowIndex = builder.rowIndex; this.verNum = builder.verNum; this.targetComment = builder.targetComment; + this.commentsCount = builder.commentsCount; } @Override @@ -189,6 +191,16 @@ void setTargetComment(String targetComment) this.targetComment = targetComment; } + public int getCommentsCount() + { + return commentsCount; + } + + void setCommentsCount(int commentsCount) + { + this.commentsCount = commentsCount; + } + public String debugString() { return Objects.toStringHelper(this). @@ -224,6 +236,7 @@ public static class Builder private int rowIndex; private int verNum = -1; // to fail check if not set before build private String targetComment; + private int commentsCount; private Builder(TransUnit transUnit) { @@ -240,6 +253,7 @@ private Builder(TransUnit transUnit) this.lastModifiedTime = transUnit.lastModifiedTime; this.rowIndex = transUnit.rowIndex; this.verNum = transUnit.verNum; + this.commentsCount = transUnit.commentsCount; } private Builder() @@ -271,9 +285,9 @@ public static Builder from(TransUnit transUnit) return new Builder(transUnit); } - private static List nullToEmpty(List contents) + private static List nullToEmpty(List contents) { - return contents == null ? Lists.newArrayList() : contents; + return contents == null ? Lists.newArrayList() : contents; } public Builder setStatus(ContentState status) @@ -378,10 +392,16 @@ public Builder setVerNum(int verNum) return this; } - public Builder setTargetContent(String targetComment) + public Builder setTargetComment(String targetComment) { this.targetComment = targetComment; return this; } + + public Builder setCommentsCount(int commentsCount) + { + this.commentsCount = commentsCount; + return this; + } } } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/AddReviewCommentAction.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/AddReviewCommentAction.java new file mode 100644 index 0000000000..3bc93aa2da --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/AddReviewCommentAction.java @@ -0,0 +1,64 @@ +/* + * 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.webtrans.shared.rpc; + +import org.zanata.webtrans.shared.model.DocumentId; +import org.zanata.webtrans.shared.model.TransUnitId; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +public class AddReviewCommentAction extends AbstractWorkspaceAction +{ + private static final long serialVersionUID = 1L; + + private String content; + private DocumentId documentId; + private TransUnitId transUnitId; + + @SuppressWarnings("unused") + public AddReviewCommentAction() + { + } + + public AddReviewCommentAction(TransUnitId transUnitId, String content, DocumentId id) + { + this.transUnitId = transUnitId; + this.content = content; + documentId = id; + } + + public String getContent() + { + return content; + } + + public TransUnitId getTransUnitId() + { + return transUnitId; + } + + public DocumentId getDocumentId() + { + return documentId; + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/AddReviewCommentResult.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/AddReviewCommentResult.java new file mode 100644 index 0000000000..7b0f0c9df2 --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/AddReviewCommentResult.java @@ -0,0 +1,49 @@ +/* + * 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.webtrans.shared.rpc; + +import org.zanata.webtrans.shared.model.ReviewComment; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +public class AddReviewCommentResult implements DispatchResult +{ + private static final long serialVersionUID = 1L; + + private ReviewComment comment; + + @SuppressWarnings("unused") + public AddReviewCommentResult() + { + } + + public AddReviewCommentResult(ReviewComment comment) + { + this.comment = comment; + } + + public ReviewComment getComment() + { + return comment; + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetReviewCommentsAction.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetReviewCommentsAction.java new file mode 100644 index 0000000000..d9928b9590 --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetReviewCommentsAction.java @@ -0,0 +1,48 @@ +/* + * 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.webtrans.shared.rpc; + +import org.zanata.webtrans.shared.model.TransUnitId; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +public class GetReviewCommentsAction extends AbstractWorkspaceAction +{ + private static final long serialVersionUID = 1L; + private TransUnitId transUnitId; + + @SuppressWarnings("unused") + public GetReviewCommentsAction() + { + } + + public GetReviewCommentsAction(TransUnitId transUnitId) + { + this.transUnitId = transUnitId; + } + + public TransUnitId getTransUnitId() + { + return transUnitId; + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetReviewCommentsResult.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetReviewCommentsResult.java new file mode 100644 index 0000000000..81e565617f --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetReviewCommentsResult.java @@ -0,0 +1,50 @@ +/* + * 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.webtrans.shared.rpc; + +import java.util.List; + +import org.zanata.webtrans.shared.model.ReviewComment; + +/** + * @author Patrick Huang pahuang@redhat.com + */ +public class GetReviewCommentsResult implements DispatchResult +{ + private static final long serialVersionUID = 1L; + private List comments; + + @SuppressWarnings("unused") + public GetReviewCommentsResult() + { + } + + public GetReviewCommentsResult(List comments) + { + this.comments = comments; + } + + public List getComments() + { + return comments; + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/TransUnitUpdated.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/TransUnitUpdated.java index 10d6e92c94..54a5c8400f 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/TransUnitUpdated.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/TransUnitUpdated.java @@ -31,7 +31,7 @@ public class TransUnitUpdated implements SessionEventData, HasTransUnitUpdatedDa public enum UpdateType { - WebEditorSave, WebEditorSaveFuzzy, ReplaceText, TMMerge, Revert + WebEditorSave, WebEditorSaveFuzzy, ReplaceText, TMMerge, AddComment, Revert // TODO add types for updates through REST, copytrans, etc. } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/validation/action/TabValidation.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/validation/action/TabValidation.java index 2f66e03c87..7269f956fe 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/shared/validation/action/TabValidation.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/validation/action/TabValidation.java @@ -44,6 +44,7 @@ public TabValidation(ValidationId id) @Override public void doValidate(ArrayList errorList, String source, String target) { + @edu.umd.cs.findbugs.annotations.SuppressWarnings("GBU_GUAVA_BETA_CLASS_USAGE") CharMatcher tabs = CharMatcher.is('\t'); int sourceTabs = tabs.countIn(source); int targetTabs = tabs.countIn(target); diff --git a/zanata-war/src/main/resources/db/changelogs/db.changelog-3.1.xml b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.1.xml index 459583110e..4efeabca9e 100644 --- a/zanata-war/src/main/resources/db/changelogs/db.changelog-3.1.xml +++ b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.1.xml @@ -1,12 +1,48 @@ - - - + + + + Add HTextFlowTargetReviewComment table to support user comments. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Add a flag indicating when a member of a Language team (locale) is a team reviewer. @@ -15,7 +51,7 @@ - + Add a flag indicating when a member of a Language team (locale) is a team translator. @@ -24,12 +60,13 @@ - + Make current locale members and coordinator as translator update HLocale_Member set isTranslator = 1; - - - + + + + \ No newline at end of file diff --git a/zanata-war/src/main/webapp-jboss/WEB-INF/classes/META-INF/persistence.xml b/zanata-war/src/main/webapp-jboss/WEB-INF/classes/META-INF/persistence.xml index f3fa99291d..d9fc91bb53 100644 --- a/zanata-war/src/main/webapp-jboss/WEB-INF/classes/META-INF/persistence.xml +++ b/zanata-war/src/main/webapp-jboss/WEB-INF/classes/META-INF/persistence.xml @@ -8,41 +8,42 @@ org.hibernate.ejb.HibernatePersistence java:jboss/datasources/${ds.jndi.name} META-INF/orm.xml - - org.zanata.model.HAccountActivationKey - org.zanata.model.HAccount - org.zanata.model.HAccountResetPasswordKey - org.zanata.model.HAccountRole - org.zanata.model.HApplicationConfiguration - org.zanata.model.HasSimpleComment - org.zanata.model.HCopyTransOptions - org.zanata.model.HDocumentHistory - org.zanata.model.HDocument - org.zanata.model.HDocumentUpload - org.zanata.model.HDocumentUploadPart - org.zanata.model.HAccountOption - org.zanata.model.HProject - org.zanata.model.HLocale - org.zanata.model.HLocaleMember - org.zanata.model.HPerson - org.zanata.model.HPersonEmailValidationKey - org.zanata.model.HProjectIteration - org.zanata.model.HRawDocument - org.zanata.model.HRoleAssignmentRule - org.zanata.model.HSimpleComment - org.zanata.model.HTextFlowHistory - org.zanata.model.HTextFlow - org.zanata.model.HTextFlowTargetHistory - org.zanata.model.HTextFlowTarget - org.zanata.model.HGlossaryEntry - org.zanata.model.HGlossaryTerm - org.zanata.model.HTermComment - org.zanata.model.HIterationGroup - org.zanata.model.po.HPoHeader - org.zanata.model.po.HPoTargetHeader - org.zanata.model.po.HPotEntryData - org.zanata.model.security.HCredentials - org.zanata.model.security.HOpenIdCredentials + + org.zanata.model.HAccount + org.zanata.model.HAccountActivationKey + org.zanata.model.HAccountOption + org.zanata.model.HAccountResetPasswordKey + org.zanata.model.HAccountRole + org.zanata.model.HApplicationConfiguration + org.zanata.model.HasSimpleComment + org.zanata.model.HCopyTransOptions + org.zanata.model.HDocument + org.zanata.model.HDocumentHistory + org.zanata.model.HDocumentUpload + org.zanata.model.HDocumentUploadPart + org.zanata.model.HGlossaryEntry + org.zanata.model.HGlossaryTerm + org.zanata.model.HIterationGroup + org.zanata.model.HLocale + org.zanata.model.HLocaleMember + org.zanata.model.HPerson + org.zanata.model.HPersonEmailValidationKey + org.zanata.model.HProject + org.zanata.model.HProjectIteration + org.zanata.model.HRawDocument + org.zanata.model.HRoleAssignmentRule + org.zanata.model.HSimpleComment + org.zanata.model.HTermComment + org.zanata.model.HTextFlowHistory + org.zanata.model.HTextFlow + org.zanata.model.HTextFlowTarget + org.zanata.model.HTextFlowTargetHistory + org.zanata.model.HTextFlowTargetReviewComment + org.zanata.model.po.HPoHeader + org.zanata.model.po.HPoTargetHeader + org.zanata.model.po.HPotEntryData + org.zanata.model.security.HCredentials + org.zanata.model.security.HOpenIdCredentials - org.zanata.model.HAccountActivationKey - org.zanata.model.HAccount - org.zanata.model.HAccountResetPasswordKey - org.zanata.model.HAccountRole - org.zanata.model.HApplicationConfiguration - org.zanata.model.HasSimpleComment + org.zanata.model.HAccount + org.zanata.model.HAccountActivationKey + org.zanata.model.HAccountOption + org.zanata.model.HAccountResetPasswordKey + org.zanata.model.HAccountRole + org.zanata.model.HApplicationConfiguration + org.zanata.model.HasSimpleComment org.zanata.model.HCopyTransOptions - org.zanata.model.HDocumentHistory - org.zanata.model.HDocument + org.zanata.model.HDocument + org.zanata.model.HDocumentHistory org.zanata.model.HDocumentUpload org.zanata.model.HDocumentUploadPart - org.zanata.model.HAccountOption - org.zanata.model.HProject - org.zanata.model.HLocale - org.zanata.model.HLocaleMember - org.zanata.model.HPerson - org.zanata.model.HPersonEmailValidationKey - org.zanata.model.HProjectIteration + org.zanata.model.HGlossaryEntry + org.zanata.model.HGlossaryTerm + org.zanata.model.HIterationGroup + org.zanata.model.HLocale + org.zanata.model.HLocaleMember + org.zanata.model.HPerson + org.zanata.model.HPersonEmailValidationKey + org.zanata.model.HProject + org.zanata.model.HProjectIteration org.zanata.model.HRawDocument org.zanata.model.HRoleAssignmentRule - org.zanata.model.HSimpleComment - org.zanata.model.HTextFlowHistory - org.zanata.model.HTextFlow - org.zanata.model.HTextFlowTargetHistory - org.zanata.model.HTextFlowTarget - org.zanata.model.HGlossaryEntry - org.zanata.model.HGlossaryTerm - org.zanata.model.HTermComment - org.zanata.model.HIterationGroup - org.zanata.model.po.HPoHeader - org.zanata.model.po.HPoTargetHeader - org.zanata.model.po.HPotEntryData + org.zanata.model.HSimpleComment + org.zanata.model.HTermComment + org.zanata.model.HTextFlowHistory + org.zanata.model.HTextFlow + org.zanata.model.HTextFlowTarget + org.zanata.model.HTextFlowTargetHistory + org.zanata.model.HTextFlowTargetReviewComment + org.zanata.model.po.HPoHeader + org.zanata.model.po.HPoTargetHeader + org.zanata.model.po.HPotEntryData org.zanata.model.security.HCredentials org.zanata.model.security.HOpenIdCredentials diff --git a/zanata-war/src/test/resources/arquillian/persistence.xml b/zanata-war/src/test/resources/arquillian/persistence.xml index ef4fd1fcfe..61c6db512c 100755 --- a/zanata-war/src/test/resources/arquillian/persistence.xml +++ b/zanata-war/src/test/resources/arquillian/persistence.xml @@ -21,35 +21,36 @@ META-INF/orm.xml - org.zanata.model.HAccountActivationKey - org.zanata.model.HAccount - org.zanata.model.HAccountResetPasswordKey - org.zanata.model.HAccountRole - org.zanata.model.HApplicationConfiguration - org.zanata.model.HasSimpleComment + org.zanata.model.HAccount + org.zanata.model.HAccountActivationKey + org.zanata.model.HAccountOption + org.zanata.model.HAccountResetPasswordKey + org.zanata.model.HAccountRole + org.zanata.model.HApplicationConfiguration + org.zanata.model.HasSimpleComment org.zanata.model.HCopyTransOptions - org.zanata.model.HDocumentHistory - org.zanata.model.HDocument + org.zanata.model.HDocument + org.zanata.model.HDocumentHistory org.zanata.model.HDocumentUpload org.zanata.model.HDocumentUploadPart - org.zanata.model.HAccountOption - org.zanata.model.HProject + org.zanata.model.HGlossaryEntry + org.zanata.model.HGlossaryTerm + org.zanata.model.HIterationGroup org.zanata.model.HLocale - org.zanata.model.HLocaleMember - org.zanata.model.HPerson - org.zanata.model.HPersonEmailValidationKey - org.zanata.model.HProjectIteration + org.zanata.model.HLocaleMember + org.zanata.model.HPerson + org.zanata.model.HPersonEmailValidationKey + org.zanata.model.HProject + org.zanata.model.HProjectIteration org.zanata.model.HRawDocument org.zanata.model.HRoleAssignmentRule org.zanata.model.HSimpleComment - org.zanata.model.HTextFlowHistory - org.zanata.model.HTextFlow - org.zanata.model.HTextFlowTargetHistory - org.zanata.model.HTextFlowTarget - org.zanata.model.HGlossaryEntry - org.zanata.model.HGlossaryTerm org.zanata.model.HTermComment - org.zanata.model.HIterationGroup + org.zanata.model.HTextFlowHistory + org.zanata.model.HTextFlow + org.zanata.model.HTextFlowTarget + org.zanata.model.HTextFlowTargetHistory + org.zanata.model.HTextFlowTargetReviewComment org.zanata.model.po.HPoHeader org.zanata.model.po.HPoTargetHeader org.zanata.model.po.HPotEntryData diff --git a/zanata-war/src/test/resources/org/zanata/test/model/ClearAllTables.dbunit.xml b/zanata-war/src/test/resources/org/zanata/test/model/ClearAllTables.dbunit.xml index 01f39eca69..ef65b9ca68 100644 --- a/zanata-war/src/test/resources/org/zanata/test/model/ClearAllTables.dbunit.xml +++ b/zanata-war/src/test/resources/org/zanata/test/model/ClearAllTables.dbunit.xml @@ -31,4 +31,5 @@ + diff --git a/zanata-war/src/test/resources/org/zanata/test/model/TextFlowTestData.dbunit.xml b/zanata-war/src/test/resources/org/zanata/test/model/TextFlowTestData.dbunit.xml index 0a26f5dd59..35b2835e00 100644 --- a/zanata-war/src/test/resources/org/zanata/test/model/TextFlowTestData.dbunit.xml +++ b/zanata-war/src/test/resources/org/zanata/test/model/TextFlowTestData.dbunit.xml @@ -221,6 +221,17 @@ content0="mssgTrans4" /> + + diff --git a/zanata-war/src/test/resources/performance/GetTransUnitListTest.dbunit.xml b/zanata-war/src/test/resources/performance/GetTransUnitListTest.dbunit.xml index 5461564455..ae0ba11ad8 100644 --- a/zanata-war/src/test/resources/performance/GetTransUnitListTest.dbunit.xml +++ b/zanata-war/src/test/resources/performance/GetTransUnitListTest.dbunit.xml @@ -58,4 +58,7 @@ sdf adf + + +