From 4f1dfe35bed84a2c80d163ed5d6e2f707d3b429b Mon Sep 17 00:00:00 2001
From: Sean Flanigan
Date: Tue, 2 Jul 2013 15:19:55 +1000
Subject: [PATCH 001/184] Always enable WrappedConnectionProvider, but disabled
for MySQL connections
This allows zanata.war to be run against H2 for testing purposes
(functional tests), but still check for potential problems with MySQL
streaming ResultSets.
---
.../zanata/database}/ConnectionWrapper.java | 2 +-
.../zanata/database}/ResultSetWrapper.java | 2 +-
.../zanata/database}/StatementWrapper.java | 2 +-
.../StreamingResultSetSQLException.java | 2 +-
.../database}/WrappedConnectionProvider.java | 17 ++-
.../WEB-INF/classes/META-INF/persistence.xml | 4 +-
.../org/zanata/dao/TextFlowStreamDAOTest.java | 97 -------------
.../WrappedConnectionProviderTest.java | 128 ++++++++++++++++++
.../test/resources/META-INF/persistence.xml | 2 +-
.../test/resources/arquillian/persistence.xml | 2 +
10 files changed, 152 insertions(+), 106 deletions(-)
rename zanata-war/src/{test/java/org/zanata/jdbc => main/java/org/zanata/database}/ConnectionWrapper.java (99%)
rename zanata-war/src/{test/java/org/zanata/jdbc => main/java/org/zanata/database}/ResultSetWrapper.java (99%)
rename zanata-war/src/{test/java/org/zanata/jdbc => main/java/org/zanata/database}/StatementWrapper.java (99%)
rename zanata-war/src/{test/java/org/zanata/jdbc => main/java/org/zanata/database}/StreamingResultSetSQLException.java (98%)
rename zanata-war/src/{test/java/org/zanata/dao => main/java/org/zanata/database}/WrappedConnectionProvider.java (81%)
create mode 100644 zanata-war/src/test/java/org/zanata/database/WrappedConnectionProviderTest.java
diff --git a/zanata-war/src/test/java/org/zanata/jdbc/ConnectionWrapper.java b/zanata-war/src/main/java/org/zanata/database/ConnectionWrapper.java
similarity index 99%
rename from zanata-war/src/test/java/org/zanata/jdbc/ConnectionWrapper.java
rename to zanata-war/src/main/java/org/zanata/database/ConnectionWrapper.java
index f4f9909195..fb7dc47159 100644
--- a/zanata-war/src/test/java/org/zanata/jdbc/ConnectionWrapper.java
+++ b/zanata-war/src/main/java/org/zanata/database/ConnectionWrapper.java
@@ -19,7 +19,7 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-package org.zanata.jdbc;
+package org.zanata.database;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
diff --git a/zanata-war/src/test/java/org/zanata/jdbc/ResultSetWrapper.java b/zanata-war/src/main/java/org/zanata/database/ResultSetWrapper.java
similarity index 99%
rename from zanata-war/src/test/java/org/zanata/jdbc/ResultSetWrapper.java
rename to zanata-war/src/main/java/org/zanata/database/ResultSetWrapper.java
index 5122b0f3d7..34f94dbad5 100644
--- a/zanata-war/src/test/java/org/zanata/jdbc/ResultSetWrapper.java
+++ b/zanata-war/src/main/java/org/zanata/database/ResultSetWrapper.java
@@ -19,7 +19,7 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-package org.zanata.jdbc;
+package org.zanata.database;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
diff --git a/zanata-war/src/test/java/org/zanata/jdbc/StatementWrapper.java b/zanata-war/src/main/java/org/zanata/database/StatementWrapper.java
similarity index 99%
rename from zanata-war/src/test/java/org/zanata/jdbc/StatementWrapper.java
rename to zanata-war/src/main/java/org/zanata/database/StatementWrapper.java
index 34e1b08f31..a258a52f37 100644
--- a/zanata-war/src/test/java/org/zanata/jdbc/StatementWrapper.java
+++ b/zanata-war/src/main/java/org/zanata/database/StatementWrapper.java
@@ -19,7 +19,7 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-package org.zanata.jdbc;
+package org.zanata.database;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
diff --git a/zanata-war/src/test/java/org/zanata/jdbc/StreamingResultSetSQLException.java b/zanata-war/src/main/java/org/zanata/database/StreamingResultSetSQLException.java
similarity index 98%
rename from zanata-war/src/test/java/org/zanata/jdbc/StreamingResultSetSQLException.java
rename to zanata-war/src/main/java/org/zanata/database/StreamingResultSetSQLException.java
index 79cd2215be..534b884b46 100644
--- a/zanata-war/src/test/java/org/zanata/jdbc/StreamingResultSetSQLException.java
+++ b/zanata-war/src/main/java/org/zanata/database/StreamingResultSetSQLException.java
@@ -19,7 +19,7 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-package org.zanata.jdbc;
+package org.zanata.database;
import java.sql.SQLException;
diff --git a/zanata-war/src/test/java/org/zanata/dao/WrappedConnectionProvider.java b/zanata-war/src/main/java/org/zanata/database/WrappedConnectionProvider.java
similarity index 81%
rename from zanata-war/src/test/java/org/zanata/dao/WrappedConnectionProvider.java
rename to zanata-war/src/main/java/org/zanata/database/WrappedConnectionProvider.java
index 600d56f248..eeca3a02d4 100644
--- a/zanata-war/src/test/java/org/zanata/dao/WrappedConnectionProvider.java
+++ b/zanata-war/src/main/java/org/zanata/database/WrappedConnectionProvider.java
@@ -19,13 +19,13 @@
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-package org.zanata.dao;
+package org.zanata.database;
import java.sql.Connection;
+import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
-import org.zanata.jdbc.ConnectionWrapper;
/**
* This class wraps JDBC Connections/Statements/ResultSets to detect
@@ -38,11 +38,22 @@
*/
public class WrappedConnectionProvider extends DriverManagerConnectionProviderImpl
{
+ private static final long serialVersionUID = 1L;
+
@Override
public Connection getConnection() throws SQLException
{
Connection connection = super.getConnection();
- return ConnectionWrapper.wrap(connection);
+ DatabaseMetaData metaData = connection.getMetaData();
+ String databaseName = metaData.getDatabaseProductName();
+ if ("MySQL".equals(databaseName))
+ {
+ return connection;
+ }
+ else
+ {
+ return ConnectionWrapper.wrap(connection);
+ }
}
}
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 0f1d2d31c9..40b00951e2 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
@@ -57,7 +57,9 @@
-
+
+
+
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowStreamDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowStreamDAOTest.java
index 3b4aae6fee..3f6e0a55bd 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowStreamDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowStreamDAOTest.java
@@ -2,36 +2,21 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Iterator;
-
import lombok.Cleanup;
-import lombok.extern.slf4j.Slf4j;
import org.dbunit.operation.DatabaseOperation;
import org.hamcrest.Matchers;
-import org.hibernate.JDBCException;
-import org.hibernate.Query;
-import org.hibernate.ScrollMode;
-import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.ejb.HibernateEntityManagerFactory;
-import org.hibernate.jdbc.Work;
-import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.zanata.ZanataDbunitJpaTest;
-import org.zanata.jdbc.StreamingResultSetSQLException;
import org.zanata.model.HProject;
import org.zanata.model.HProjectIteration;
import org.zanata.model.HTextFlow;
import org.zanata.util.CloseableIterator;
@Test(groups = { "jpa-tests" })
-@Slf4j
public class TextFlowStreamDAOTest extends ZanataDbunitJpaTest
{
@@ -58,88 +43,6 @@ public void setup()
projectIterDao = new ProjectIterationDAO(session);
}
- @Test
- public void testWrapperWithNestedExecute() throws Exception
- {
- @Cleanup
- ScrollableResults scroll1 = streamQuery("from HTextFlow");
- try
- {
- session.doWork(new Work()
- {
- @Override
- public void execute(Connection connection) throws SQLException
- {
- Statement statement = connection.createStatement();
- statement.executeUpdate("delete from HTextFlow where 0=1");
- }
- });
- Assert.fail("Failed to detect concurrent ResultSet - is WrappedConnectionProvider enabled?");
- }
- catch (JDBCException e)
- {
- if (!(e.getSQLException() instanceof StreamingResultSetSQLException))
- {
- throw e;
- }
- }
- }
-
- @Test
- public void testWrapperWithNestedStreaming() throws Exception
- {
- @Cleanup
- ScrollableResults scroll1 = streamQuery("from HTextFlow");
- try
- {
- @Cleanup
- ScrollableResults scroll2 = streamQuery("from HTextFlowTarget");
- Assert.fail("Failed to detect concurrent ResultSet - is WrappedConnectionProvider enabled?");
- }
- catch (JDBCException e)
- {
- if (!(e.getSQLException() instanceof StreamingResultSetSQLException))
- {
- throw e;
- }
- }
- }
-
- @Test
- public void testWrapperWithNestedResults() throws Exception
- {
- @Cleanup
- ScrollableResults scroll1 = streamQuery("from HTextFlow");
- try
- {
- @Cleanup
- ScrollableResults scroll2 = scrollQuery("from HTextFlowTarget");
- Assert.fail("Failed to detect concurrent ResultSet - is WrappedConnectionProvider enabled?");
- }
- catch (JDBCException e)
- {
- if (!(e.getSQLException() instanceof StreamingResultSetSQLException))
- {
- throw e;
- }
- }
- }
-
- private ScrollableResults streamQuery(String queryString)
- {
- Query q = session.createQuery(queryString);
- q.setFetchSize(Integer.MIN_VALUE);
- ScrollableResults scroll = q.scroll(ScrollMode.FORWARD_ONLY);
- return scroll;
- }
-
- private ScrollableResults scrollQuery(String queryString)
- {
- Query q = session.createQuery(queryString);
- ScrollableResults scroll = q.scroll();
- return scroll;
- }
-
@Test
public void findAllTextFlows() throws Exception
{
diff --git a/zanata-war/src/test/java/org/zanata/database/WrappedConnectionProviderTest.java b/zanata-war/src/test/java/org/zanata/database/WrappedConnectionProviderTest.java
new file mode 100644
index 0000000000..68ad7363d1
--- /dev/null
+++ b/zanata-war/src/test/java/org/zanata/database/WrappedConnectionProviderTest.java
@@ -0,0 +1,128 @@
+package org.zanata.database;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import lombok.Cleanup;
+
+import org.dbunit.operation.DatabaseOperation;
+import org.hibernate.JDBCException;
+import org.hibernate.Query;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Session;
+import org.hibernate.jdbc.Work;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.zanata.ZanataDbunitJpaTest;
+
+@Test(groups = { "jpa-tests" })
+public class WrappedConnectionProviderTest extends ZanataDbunitJpaTest
+{
+
+ private Session session;
+
+ @Override
+ protected void prepareDBUnitOperations()
+ {
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/ProjectsData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/TextFlowTestData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/LocalesData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/AccountData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
+ }
+
+ @BeforeMethod(firstTimeOnly = true)
+ public void setup()
+ {
+ session = getSession();
+ }
+
+ @Test
+ public void testWrapperWithNestedExecute() throws Exception
+ {
+ @Cleanup
+ ScrollableResults scroll1 = streamQuery("from HTextFlow");
+ try
+ {
+ session.doWork(new Work()
+ {
+ @Override
+ public void execute(Connection connection) throws SQLException
+ {
+ Statement statement = connection.createStatement();
+ statement.executeUpdate("delete from HTextFlow where 0=1");
+ }
+ });
+ concurrentResultSetNotDetected();
+ }
+ catch (JDBCException e)
+ {
+ checkExceptionType(e);
+ }
+ }
+
+ @Test
+ public void testWrapperWithNestedStreaming() throws Exception
+ {
+ @Cleanup
+ ScrollableResults scroll1 = streamQuery("from HTextFlow");
+ try
+ {
+ @Cleanup
+ ScrollableResults scroll2 = streamQuery("from HTextFlowTarget");
+ concurrentResultSetNotDetected();
+ }
+ catch (JDBCException e)
+ {
+ checkExceptionType(e);
+ }
+ }
+
+ @Test
+ public void testWrapperWithNestedResults() throws Exception
+ {
+ @Cleanup
+ ScrollableResults scroll1 = streamQuery("from HTextFlow");
+ try
+ {
+ @Cleanup
+ ScrollableResults scroll2 = scrollQuery("from HTextFlowTarget");
+ concurrentResultSetNotDetected();
+ }
+ catch (JDBCException e)
+ {
+ checkExceptionType(e);
+ }
+ }
+
+ private void concurrentResultSetNotDetected()
+ {
+ Assert.fail("Failed to detect concurrent ResultSet - is WrappedConnectionProvider enabled in persistence.xml?");
+ }
+
+ private void checkExceptionType(JDBCException e)
+ {
+ if (!(e.getSQLException() instanceof StreamingResultSetSQLException))
+ {
+ throw e;
+ }
+ }
+
+ private ScrollableResults streamQuery(String queryString)
+ {
+ Query q = session.createQuery(queryString);
+ q.setFetchSize(Integer.MIN_VALUE);
+ ScrollableResults scroll = q.scroll(ScrollMode.FORWARD_ONLY);
+ return scroll;
+ }
+
+ private ScrollableResults scrollQuery(String queryString)
+ {
+ Query q = session.createQuery(queryString);
+ ScrollableResults scroll = q.scroll();
+ return scroll;
+ }
+
+}
diff --git a/zanata-war/src/test/resources/META-INF/persistence.xml b/zanata-war/src/test/resources/META-INF/persistence.xml
index f9205ff03b..c57cff0c2c 100755
--- a/zanata-war/src/test/resources/META-INF/persistence.xml
+++ b/zanata-war/src/test/resources/META-INF/persistence.xml
@@ -60,7 +60,7 @@
-
+
-
+
diff --git a/zanata-war/src/test/resources/META-INF/persistence.xml b/zanata-war/src/test/resources/META-INF/persistence.xml
index c57cff0c2c..b17579c5e2 100755
--- a/zanata-war/src/test/resources/META-INF/persistence.xml
+++ b/zanata-war/src/test/resources/META-INF/persistence.xml
@@ -60,7 +60,7 @@
-
+
diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties
index b20409f350..b5992d6d3b 100644
--- a/zanata-war/src/main/resources/messages.properties
+++ b/zanata-war/src/main/resources/messages.properties
@@ -394,10 +394,12 @@ jsf.JoinLanguageTeam=Join Language Team
jsf.LeaveLanguageTeam=Leave Language Team
jsf.RequestToJoinLanguageTeam=Request To Join Team
jsf.contactLanguageTeamCoordinator=Contact Team Coordinators
-jsf.AddTeamMember=Add Team Member
+jsf.AddTeamMember=Add Team Translator
jsf.FindUsersToAdd=Find Users To Add
jsf.Searching=Searching...
jsf.AlreadyInTeam=Already in Team
+jsf.Reviewer=Reviewer
+jsf.Translator=Translator
@@ -793,7 +795,7 @@ jsf.email.coordinator.ReceivedReason=You are coordinator in '#{sendEmail.locale.
#------ request-to-join-language-team email ------
jsf.email.joinrequest.UserRequestingToJoin=Zanata user '#{sendEmail.fromName}' with id '#{sendEmail.fromLoginName}' is requesting to join the #{sendEmail.locale.localeId.id} (#{sendEmail.locale.retrieveNativeName()}) Language Team.
-jsf.email.joinrequest.AddUserInstructions=You can add #{sendEmail.fromName} to the #{sendEmail.locale.localeId.id} team using the "#{messages['jsf.AddTeamMember']}" action on the language team page and searching for '#{sendEmail.fromLoginName}'.
+jsf.email.joinrequest.AddUserInstructions=You can add #{sendEmail.fromName} to the #{sendEmail.locale.localeId.id} team as translator using the "#{messages['jsf.AddTeamMember']}" action on the language team page and searching for '#{sendEmail.fromLoginName}'.
#------ request-to-join-group email ------
diff --git a/zanata-war/src/main/webapp/language/language.xhtml b/zanata-war/src/main/webapp/language/language.xhtml
index acb682d82a..bddbc385c1 100644
--- a/zanata-war/src/main/webapp/language/language.xhtml
+++ b/zanata-war/src/main/webapp/language/language.xhtml
@@ -44,20 +44,36 @@
#{messages['jsf.Email']}
-
#{member.person.email}
-
+
+
+ #{messages['jsf.Translator']}
+
+
+
+
+
+
+
+ #{messages['jsf.Reviewer']}
+
+
+
+
+
+
#{messages['jsf.Coordinator']}
-
-
-
+
+
#{messages['jsf.Actions']}
@@ -133,6 +149,34 @@
#{messages['jsf.Username']}
#{person.account.username}
+
+
+ #{messages['jsf.Translator']}
+
+
+
+
+
+
+
+ #{messages['jsf.Reviewer']}
+
+
+
+
+
+
+
+ #{messages['jsf.Coordinator']}
+
+
+
+
+
+
#{messages['jsf.Actions']}
Date: Fri, 5 Jul 2013 10:53:52 +1000
Subject: [PATCH 005/184] Fix proxies to implement all interfaces from
superclasses
---
.../zanata/database/ConnectionWrapper.java | 8 ++--
.../java/org/zanata/database/ProxyUtil.java | 46 +++++++++++++++++++
.../org/zanata/database/ResultSetWrapper.java | 6 +--
.../org/zanata/database/StatementWrapper.java | 6 +--
.../WrappedConnectionProviderTest.java | 2 +-
zanata-war/src/test/resources/arquillian.xml | 4 ++
6 files changed, 59 insertions(+), 13 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/database/ProxyUtil.java
diff --git a/zanata-war/src/main/java/org/zanata/database/ConnectionWrapper.java b/zanata-war/src/main/java/org/zanata/database/ConnectionWrapper.java
index 9c4d634b4a..9bb0a10f03 100644
--- a/zanata-war/src/main/java/org/zanata/database/ConnectionWrapper.java
+++ b/zanata-war/src/main/java/org/zanata/database/ConnectionWrapper.java
@@ -29,12 +29,14 @@
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.List;
import java.util.Set;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.ClassUtils;
import org.testng.internal.annotations.Sets;
/**
@@ -43,7 +45,7 @@
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
-public class ConnectionWrapper implements InvocationHandler
+class ConnectionWrapper implements InvocationHandler
{
// For reference, this is what the mysql exception looks like:
// Streaming result set com.mysql.jdbc.RowDataDynamic@1950740 is
@@ -62,9 +64,7 @@ public static Connection wrap(Connection connection)
{
return connection;
}
- ConnectionWrapper h = new ConnectionWrapper(connection);
- ClassLoader cl = h.getClass().getClassLoader();
- return (Connection) Proxy.newProxyInstance(cl, connection.getClass().getInterfaces(), h);
+ return ProxyUtil.newProxy(connection, new ConnectionWrapper(connection));
}
public static Connection wrapUnlessMysql(Connection connection) throws SQLException
diff --git a/zanata-war/src/main/java/org/zanata/database/ProxyUtil.java b/zanata-war/src/main/java/org/zanata/database/ProxyUtil.java
new file mode 100644
index 0000000000..6fedd70200
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/database/ProxyUtil.java
@@ -0,0 +1,46 @@
+/*
+ * 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.database;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.util.List;
+
+import org.apache.commons.lang.ClassUtils;
+
+/**
+ * @author Sean Flanigan sflaniga@redhat.com
+ *
+ */
+class ProxyUtil
+{
+
+ public static T newProxy(T object, InvocationHandler handler)
+ {
+ ClassLoader cl = handler.getClass().getClassLoader();
+ Class> clazz = object.getClass();
+ List> allInterfaces = ClassUtils.getAllInterfaces(clazz);
+ Class>[] interfaces = allInterfaces.toArray(new Class>[0]);
+ return (T) Proxy.newProxyInstance(cl, interfaces, handler);
+ }
+
+}
diff --git a/zanata-war/src/main/java/org/zanata/database/ResultSetWrapper.java b/zanata-war/src/main/java/org/zanata/database/ResultSetWrapper.java
index 34f94dbad5..e16ba1a024 100644
--- a/zanata-war/src/main/java/org/zanata/database/ResultSetWrapper.java
+++ b/zanata-war/src/main/java/org/zanata/database/ResultSetWrapper.java
@@ -37,7 +37,7 @@
*
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
-public class ResultSetWrapper implements InvocationHandler
+class ResultSetWrapper implements InvocationHandler
{
public static ResultSet wrap(ResultSet resultSet, Connection connection, boolean streaming)
{
@@ -45,9 +45,7 @@ public static ResultSet wrap(ResultSet resultSet, Connection connection, boolean
{
return resultSet;
}
- ResultSetWrapper h = new ResultSetWrapper(resultSet, connection, streaming);
- ClassLoader cl = h.getClass().getClassLoader();
- return (ResultSet) Proxy.newProxyInstance(cl, resultSet.getClass().getInterfaces(), h);
+ return ProxyUtil.newProxy(resultSet, new ResultSetWrapper(resultSet, connection, streaming));
}
@Getter
diff --git a/zanata-war/src/main/java/org/zanata/database/StatementWrapper.java b/zanata-war/src/main/java/org/zanata/database/StatementWrapper.java
index a258a52f37..b7898d2633 100644
--- a/zanata-war/src/main/java/org/zanata/database/StatementWrapper.java
+++ b/zanata-war/src/main/java/org/zanata/database/StatementWrapper.java
@@ -37,7 +37,7 @@
*
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
-public class StatementWrapper implements InvocationHandler
+class StatementWrapper implements InvocationHandler
{
public static Statement wrap(Statement statement, Connection connection)
{
@@ -45,9 +45,7 @@ public static Statement wrap(Statement statement, Connection connection)
{
return statement;
}
- StatementWrapper h = new StatementWrapper(statement, connection);
- ClassLoader cl = h.getClass().getClassLoader();
- return (Statement) Proxy.newProxyInstance(cl, statement.getClass().getInterfaces(), h);
+ return ProxyUtil.newProxy(statement, new StatementWrapper(statement, connection));
}
private final Statement statement;
diff --git a/zanata-war/src/test/java/org/zanata/database/WrappedConnectionProviderTest.java b/zanata-war/src/test/java/org/zanata/database/WrappedConnectionProviderTest.java
index 68ad7363d1..de1cc60bb3 100644
--- a/zanata-war/src/test/java/org/zanata/database/WrappedConnectionProviderTest.java
+++ b/zanata-war/src/test/java/org/zanata/database/WrappedConnectionProviderTest.java
@@ -99,7 +99,7 @@ public void testWrapperWithNestedResults() throws Exception
private void concurrentResultSetNotDetected()
{
- Assert.fail("Failed to detect concurrent ResultSet - is WrappedConnectionProvider enabled in persistence.xml?");
+ Assert.fail("Failed to detect concurrent ResultSet - is Wrapped*ConnectionProvider enabled in persistence.xml?");
}
private void checkExceptionType(JDBCException e)
diff --git a/zanata-war/src/test/resources/arquillian.xml b/zanata-war/src/test/resources/arquillian.xml
index e6693ad69b..a7f9ed49c8 100644
--- a/zanata-war/src/test/resources/arquillian.xml
+++ b/zanata-war/src/test/resources/arquillian.xml
@@ -15,7 +15,11 @@
${arquillian.jboss.home}
/usr/lib/jvm/jre-1.6.0-openjdk.x86_64
+
+-->
+ -Xms1536m -Xmx1536m -XX:MaxPermSize=256m -Dorg.jboss.as.logging.per-deployment=false -Djboss.socket.binding.port-offset=100 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8787
+
zanata-standalone.xml
From 9e434add8465c973e29ff2eb2dd47dd97554f3db Mon Sep 17 00:00:00 2001
From: Sean Flanigan
Date: Fri, 5 Jul 2013 10:56:00 +1000
Subject: [PATCH 006/184] Only rebuild Groovy classes on full Eclipse build
---
zanata-war/pom.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/zanata-war/pom.xml b/zanata-war/pom.xml
index db2fd4da63..284be56a0d 100644
--- a/zanata-war/pom.xml
+++ b/zanata-war/pom.xml
@@ -730,7 +730,9 @@
-
+
+ false
+
From 65689d4eaaa6b882b12e1121f18ce2ada45cfa30 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Fri, 5 Jul 2013 11:47:42 +1000
Subject: [PATCH 007/184] map project types to option text in functional tests
---
.../zanata/page/projects/CreateVersionPage.java | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/functional-test/src/main/java/org/zanata/page/projects/CreateVersionPage.java b/functional-test/src/main/java/org/zanata/page/projects/CreateVersionPage.java
index 8e9a4ec002..6c0a602b69 100644
--- a/functional-test/src/main/java/org/zanata/page/projects/CreateVersionPage.java
+++ b/functional-test/src/main/java/org/zanata/page/projects/CreateVersionPage.java
@@ -20,6 +20,9 @@
*/
package org.zanata.page.projects;
+import java.util.HashMap;
+import java.util.Map;
+
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
@@ -40,6 +43,18 @@ public class CreateVersionPage extends AbstractPage
@FindBy(id = "iterationForm:save")
private WebElement saveButton;
+ private static final Map projectTypeOptions = new HashMap();
+ static
+ {
+ projectTypeOptions.put("File", "File. For plain text, LibreOffice, InDesign.");
+ projectTypeOptions.put("Gettext", "Gettext. For gettext software strings.");
+ projectTypeOptions.put("Podir", "Podir. For publican/docbook strings.");
+ projectTypeOptions.put("Properties", "Properties. For Java properties files.");
+ projectTypeOptions.put("Utf8Properties", "Utf8Properties. For UTF8-encoded Java properties.");
+ projectTypeOptions.put("Xliff", "Xliff. For supported XLIFF files.");
+ projectTypeOptions.put("Xml", "Xml. For XML from the Zanata REST API.");
+ }
+
public CreateVersionPage(final WebDriver driver)
{
super(driver);
@@ -53,7 +68,7 @@ public CreateVersionPage inputVersionId(String versionId)
public CreateVersionPage selectProjectType(String projectType)
{
- new Select(projectTypeSelection).selectByVisibleText(projectType);
+ new Select(projectTypeSelection).selectByVisibleText(projectTypeOptions.get(projectType));
return this;
}
From aaf451d1210a9890aeb90d64610e73c145abfeb7 Mon Sep 17 00:00:00 2001
From: Sean Flanigan
Date: Fri, 5 Jul 2013 11:51:23 +1000
Subject: [PATCH 008/184] Clean up poms by removing obsolete sections
---
zanata-model/pom.xml | 32 --------------
zanata-war/pom.xml | 99 +-------------------------------------------
2 files changed, 1 insertion(+), 130 deletions(-)
diff --git a/zanata-model/pom.xml b/zanata-model/pom.xml
index 3cb4adbac7..35be715913 100644
--- a/zanata-model/pom.xml
+++ b/zanata-model/pom.xml
@@ -260,38 +260,6 @@
org.zanata.ZanataMySQL5InnoDBDialect
com.mysql.jdbc.Driver
-
-
-
- org.codehaus.mojo
- hibernate3-maven-plugin
- 2.2
-
-
-
- hbm2ddl
- jpaconfiguration
-
-
-
- zanataDatabase
- schema.ddl
- false
- true
- false
- true
-
-
-
-
- mysql
- mysql-connector-java
- 5.1.9
-
-
-
-
-
diff --git a/zanata-war/pom.xml b/zanata-war/pom.xml
index 284be56a0d..0040c975a8 100644
--- a/zanata-war/pom.xml
+++ b/zanata-war/pom.xml
@@ -489,53 +489,6 @@
-
- org.codehaus.mojo
- hibernate3-maven-plugin
- 2.2
-
-
-
- hbm2ddl
- jpaconfiguration
-
-
-
- false
- false
- false
- false
- schema.ddl
- zanataTestDatasourcePU
-
-
-
-
-
-
- com.h2database
- h2
- 1.3.170
-
-
-
-
-
+ only two permutations, and to compile in draft mode -->
chromefirefox
org.zanata.webtrans.ApplicationChromeFirefox
@@ -924,56 +877,6 @@
-
- eclipse
-
- zanata-dev
-
-
- src/main/resources-dev
- false
-
-
-
-
-
- org.apache.maven.plugins
- maven-eclipse-plugin
- 2.9
-
- 2.0
-
-
-
- com.google.gdt.eclipse.core.webAppProjectValidator
-
-
- com.google.gwt.eclipse.core.gwtProjectValidator
-
-
-
-
- com.google.gwt.eclipse.core.gwtNature
- com.google.gdt.eclipse.core.webAppNature
-
-
-
- org.eclipse.jdt.launching.JRE_CONTAINER
- com.google.gwt.eclipse.core.GWT_CONTAINER
-
-
-
- com.google.gwt:gwt-servlet
- com.google.gwt:gwt-user
-
-
-
-
-
-
-
-
-
it-coverage
/usr/lib/jvm/jre-1.6.0-openjdk.x86_64
+ -Xms1536m -Xmx1536m -XX:MaxPermSize=256m -Dorg.jboss.as.logging.per-deployment=false -Djboss.socket.binding.port-offset=100 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8787
-->
- -Xms1536m -Xmx1536m -XX:MaxPermSize=256m -Dorg.jboss.as.logging.per-deployment=false -Djboss.socket.binding.port-offset=100 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8787
+ -Xms1536m -Xmx1536m -XX:MaxPermSize=256m -Dorg.jboss.as.logging.per-deployment=false -Djboss.socket.binding.port-offset=100
zanata-standalone.xml
From 887708a9e3520f628bb3354a7aa9f999926c5d7f Mon Sep 17 00:00:00 2001
From: David Mason
Date: Fri, 5 Jul 2013 13:08:04 +1000
Subject: [PATCH 016/184] remove unused imports, injections and annotations
---
.../webtrans/server/rpc/GetDocumentListHandler.java | 8 --------
.../webtrans/server/rpc/GetGlossaryDetailsHandler.java | 1 -
.../webtrans/server/rpc/GetTransMemoryDetailsHandler.java | 1 -
.../zanata/webtrans/server/rpc/GetTransMemoryHandler.java | 4 ----
.../webtrans/server/rpc/GetTranslatorListHandler.java | 2 --
.../webtrans/server/rpc/GetValidationRulesHandler.java | 3 ---
.../zanata/webtrans/server/rpc/ReplaceTextHandler.java | 2 --
.../server/rpc/RevertTransUnitUpdatesHandler.java | 2 --
.../webtrans/server/rpc/RunDocValidationHandler.java | 4 ----
.../webtrans/server/rpc/UpdateGlossaryTermHandler.java | 3 ---
.../webtrans/server/rpc/UpdateTransUnitHandler.java | 2 --
11 files changed, 32 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetDocumentListHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetDocumentListHandler.java
index 207690794a..5979668846 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetDocumentListHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetDocumentListHandler.java
@@ -14,13 +14,11 @@
import org.jboss.seam.annotations.Scope;
import org.zanata.common.ProjectType;
import org.zanata.dao.DocumentDAO;
-import org.zanata.dao.TextFlowTargetDAO;
import org.zanata.model.HDocument;
import org.zanata.model.HPerson;
import org.zanata.model.HProjectIteration;
import org.zanata.security.ZanataIdentity;
import org.zanata.service.TranslationFileService;
-import org.zanata.service.TranslationStateCache;
import org.zanata.webtrans.server.ActionHandlerFor;
import org.zanata.webtrans.shared.model.AuditInfo;
import org.zanata.webtrans.shared.model.DocumentId;
@@ -40,14 +38,8 @@ public class GetDocumentListHandler extends AbstractActionHandler
{
- @In
- private ZanataIdentity identity;
@In
private ValidationService validationServiceImpl;
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ReplaceTextHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ReplaceTextHandler.java
index 389f726b7a..63d3e4a9c5 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ReplaceTextHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ReplaceTextHandler.java
@@ -28,8 +28,6 @@
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.zanata.service.SecurityService;
import org.zanata.webtrans.server.ActionHandlerFor;
import org.zanata.webtrans.shared.model.TransUnitUpdateRequest;
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/RevertTransUnitUpdatesHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/RevertTransUnitUpdatesHandler.java
index 52aaea2e4e..d4a47ef200 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/RevertTransUnitUpdatesHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/RevertTransUnitUpdatesHandler.java
@@ -22,7 +22,6 @@
import java.util.List;
-import lombok.extern.slf4j.Slf4j;
import net.customware.gwt.dispatch.server.ExecutionContext;
import net.customware.gwt.dispatch.shared.ActionException;
@@ -54,7 +53,6 @@
@Name("webtrans.gwt.RevertTransUnitUpdatesHandler")
@Scope(ScopeType.STATELESS)
@ActionHandlerFor(RevertTransUnitUpdates.class)
-@Slf4j
public class RevertTransUnitUpdatesHandler extends AbstractActionHandler
{
@In
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/RunDocValidationHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/RunDocValidationHandler.java
index 764256bfcb..d1211c6ae1 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/RunDocValidationHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/RunDocValidationHandler.java
@@ -10,7 +10,6 @@
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
-import org.zanata.dao.LocaleDAO;
import org.zanata.service.ValidationService;
import org.zanata.webtrans.server.ActionHandlerFor;
import org.zanata.webtrans.shared.model.DocumentId;
@@ -25,9 +24,6 @@ public class RunDocValidationHandler extends AbstractActionHandler
{
@In
From 943d32bb4e86b98451a7977c5707a0d014fd798d Mon Sep 17 00:00:00 2001
From: David Mason
Date: Fri, 5 Jul 2013 15:22:18 +1000
Subject: [PATCH 017/184] Extract builder and states class from
FilterConstraints
---
.../main/java/org/zanata/dao/TextFlowDAO.java | 16 +-
.../java/org/zanata/search/ActiveStates.java | 146 +++++++
.../search/FilterConstraintToQuery.java | 8 +-
.../org/zanata/search/FilterConstraints.java | 367 ++++++------------
.../impl/TextFlowSearchServiceImpl.java | 10 +-
.../rpc/GetProjectTransUnitListsHandler.java | 15 +-
.../server/rpc/GetTransUnitListHandler.java | 15 +-
.../rpc/GetTransUnitsNavigationService.java | 14 +-
.../webtrans/shared/rpc/GetTransUnitList.java | 1 +
.../shared/rpc/GetTransUnitsNavigation.java | 2 +
.../java/org/zanata/dao/TextFlowDAOTest.java | 70 ++--
.../search/FilterConstraintToQueryTest.java | 54 ++-
.../impl/TextFlowSearchServiceImplTest.java | 6 +-
13 files changed, 399 insertions(+), 325 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/search/ActiveStates.java
diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
index 41fce047e3..467e2c6f6f 100644
--- a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
@@ -41,6 +41,7 @@
import org.zanata.model.HDocument;
import org.zanata.model.HLocale;
import org.zanata.model.HTextFlow;
+import org.zanata.search.ActiveStates;
import org.zanata.search.FilterConstraintToQuery;
import org.zanata.search.FilterConstraints;
import org.zanata.webtrans.shared.model.DocumentId;
@@ -70,7 +71,6 @@ public TextFlowDAO(Session session)
super(HTextFlow.class, session);
}
- @SuppressWarnings("unchecked")
public OpenBitSet findIdsWithTranslations(LocaleId locale)
{
Query q = getSession().getNamedQuery(HTextFlow.QUERY_TRANSLATED_TEXTFLOWIDS);
@@ -169,11 +169,11 @@ public List getNavigationByDocumentId(Long documentId, HLocale hLocal
* @param alias HTextFlowTarget alias
* @return '1' if accept all status or a SQL condition clause with target content state conditions in parentheses '()' joined by 'or'
*/
- protected static String buildContentStateCondition(FilterConstraints filterConstraints, String alias)
+ protected static String buildContentStateCondition(FilterConstraints constraints, String alias)
{
-
- if (filterConstraints.isTranslatedIncluded() == filterConstraints.isFuzzyIncluded()
- && filterConstraints.isTranslatedIncluded() == filterConstraints.isNewIncluded())
+
+ ActiveStates includedStates = constraints.getIncludedStates();
+ if (includedStates.hasAllStates() || includedStates.hasNoStates())
{
return "1";
}
@@ -181,17 +181,17 @@ protected static String buildContentStateCondition(FilterConstraints filterConst
builder.append("(");
List conditions = Lists.newArrayList();
final String column = alias + ".state";
- if (filterConstraints.isTranslatedIncluded())
+ if (constraints.getIncludedStates().isTranslatedOn())
{
conditions.add(column + "=2"); // Translated
conditions.add(column + "=3"); // Approved
}
- if (filterConstraints.isFuzzyIncluded())
+ if (constraints.getIncludedStates().isFuzzyOn())
{
conditions.add(column + "=1"); // Fuzzy
conditions.add(column + "=4"); // Rejected
}
- if (filterConstraints.isNewIncluded())
+ if (constraints.getIncludedStates().isNewOn())
{
conditions.add(column + "=0 or " + column + " is null");
}
diff --git a/zanata-war/src/main/java/org/zanata/search/ActiveStates.java b/zanata-war/src/main/java/org/zanata/search/ActiveStates.java
new file mode 100644
index 0000000000..eeabfa61bb
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/search/ActiveStates.java
@@ -0,0 +1,146 @@
+package org.zanata.search;
+
+import java.util.List;
+
+import org.zanata.common.ContentState;
+
+import com.google.common.collect.Lists;
+
+import lombok.Getter;
+import lombok.AllArgsConstructor;
+import lombok.ToString;
+
+@ToString
+@AllArgsConstructor
+@Getter
+public class ActiveStates
+{
+ private boolean newOn;
+ private boolean fuzzyOn;
+ private boolean translatedOn;
+ private boolean approvedOn;
+ private boolean rejectedOn;
+
+ /**
+ * @return a Builder with all states on by default
+ */
+ public static Builder builder()
+ {
+ return new Builder();
+ }
+
+ public boolean hasAllStates()
+ {
+ return newOn && fuzzyOn && translatedOn && approvedOn && rejectedOn;
+ }
+
+ public boolean hasNoStates()
+ {
+ return !(newOn || fuzzyOn || translatedOn || approvedOn || rejectedOn);
+ }
+
+ public List asList()
+ {
+ List result = Lists.newArrayList();
+ if (newOn)
+ {
+ result.add(ContentState.New);
+ }
+ if (fuzzyOn)
+ {
+ result.add(ContentState.NeedReview);
+ }
+ if (translatedOn)
+ {
+ result.add(ContentState.Translated);
+ }
+ if (approvedOn)
+ {
+ result.add(ContentState.Approved);
+ }
+ if (rejectedOn)
+ {
+ result.add(ContentState.Rejected);
+ }
+ return result;
+ }
+
+ public static class Builder
+ {
+ private boolean newOn;
+ private boolean fuzzyOn;
+ private boolean translatedOn;
+ private boolean approvedOn;
+ private boolean rejectedOn;
+
+ public Builder()
+ {
+ allOn();
+ }
+
+ public ActiveStates build()
+ {
+ return new ActiveStates(newOn, fuzzyOn, translatedOn, approvedOn, rejectedOn);
+ }
+
+ public Builder allOn()
+ {
+ this.newOn = true;
+ this.fuzzyOn = true;
+ this.translatedOn = true;
+ this.approvedOn = true;
+ this.rejectedOn = true;
+ return this;
+ }
+
+ public Builder allOff()
+ {
+ this.newOn = false;
+ this.fuzzyOn = false;
+ this.translatedOn = false;
+ this.approvedOn = false;
+ this.rejectedOn = false;
+ return this;
+ }
+
+ public Builder fromStates(ActiveStates states)
+ {
+ this.newOn = states.newOn;
+ this.fuzzyOn = states.fuzzyOn;
+ this.translatedOn = states.translatedOn;
+ this.approvedOn = states.approvedOn;
+ this.rejectedOn = states.rejectedOn;
+ return this;
+ }
+
+ public Builder setNewOn(boolean on)
+ {
+ newOn = on;
+ return this;
+ }
+
+ public Builder setFuzzyOn(boolean on)
+ {
+ fuzzyOn = on;
+ return this;
+ }
+
+ public Builder setTranslatedOn(boolean on)
+ {
+ translatedOn = on;
+ return this;
+ }
+
+ public Builder setApprovedOn(boolean on)
+ {
+ approvedOn = on;
+ return this;
+ }
+
+ public Builder setRejectedOn(boolean on)
+ {
+ rejectedOn = on;
+ return this;
+ }
+ }
+}
diff --git a/zanata-war/src/main/java/org/zanata/search/FilterConstraintToQuery.java b/zanata-war/src/main/java/org/zanata/search/FilterConstraintToQuery.java
index 3d12655843..a6cf05e406 100644
--- a/zanata-war/src/main/java/org/zanata/search/FilterConstraintToQuery.java
+++ b/zanata-war/src/main/java/org/zanata/search/FilterConstraintToQuery.java
@@ -140,7 +140,7 @@ private Criterion contentsCriterion(String alias)
protected String buildStateCondition()
{
- if (constraints.isAllStateIncluded())
+ if (constraints.getIncludedStates().hasAllStates())
{
return null;
}
@@ -148,7 +148,7 @@ protected String buildStateCondition()
String stateInListWhereClause = and(textFlowAndLocaleRestriction.toString(), String.format("state in (%s)", STATE_LIST_PLACEHOLDER));
String stateInListCondition = QueryBuilder.exists().from("HTextFlowTarget").where(stateInListWhereClause).toQueryString();
- if (constraints.isNewIncluded())
+ if (constraints.getIncludedStates().isNewOn())
{
String nullTargetCondition = String.format("%s not in indices(tf.targets)", LOCALE_PLACEHOLDER);
if (hasSearch && constraints.isSearchInSource())
@@ -175,9 +175,9 @@ public Query setQueryParameters(Query textFlowQuery, HLocale hLocale)
{
textFlowQuery.setParameter(SEARCH_NAMED_PARAM, searchString);
}
- if (!constraints.isAllStateIncluded())
+ if (!constraints.getIncludedStates().hasAllStates())
{
- textFlowQuery.setParameterList(STATE_LIST_NAMED_PARAM, constraints.getContentStateAsList());
+ textFlowQuery.setParameterList(STATE_LIST_NAMED_PARAM, constraints.getIncludedStates().asList());
}
return textFlowQuery;
}
diff --git a/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java b/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
index f456ea79b1..9e53cfc2f2 100644
--- a/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
+++ b/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
@@ -20,305 +20,192 @@
*/
package org.zanata.search;
-//TODO could make a hierarchy of filter constraints, which could be consumed
-//by a hierarchy of filters. For the moment there aren't enough uses to
-//justify this. May want to add document(someDocument) to these constraints
+//TODO May want to add document(someDocument) to these constraints
//so that only one search method is needed on the interface.
-import java.util.List;
+import lombok.Getter;
-import org.zanata.common.ContentState;
import com.google.common.base.Objects;
-import com.google.common.collect.Lists;
/**
* Specifies a set of constraints to be applied by a filter.
*
* @author David Mason, damason@redhat.com
*/
+@Getter
public class FilterConstraints
{
private String searchString;
-
private boolean isCaseSensitive;
-
private boolean searchInSource;
private boolean searchInTarget;
+ private ActiveStates includedStates;
- private boolean newIncluded;
- private boolean fuzzyIncluded;
- private boolean translatedIncluded;
- private boolean approvedIncluded;
- private boolean rejectedIncluded;
-
- //TODO rhbz953734 - need to consider other content state??
- private FilterConstraints(String searchString, boolean caseSensitive, boolean searchInSource, boolean searchInTarget, boolean newIncluded, boolean fuzzyIncluded, boolean translatedIncluded, boolean approvedIncluded, boolean rejectedIncluded)
+ private FilterConstraints(String searchString, boolean caseSensitive,
+ boolean searchInSource, boolean searchInTarget,
+ ActiveStates includedStates)
{
this.searchString = searchString;
this.isCaseSensitive = caseSensitive;
this.searchInSource = searchInSource;
this.searchInTarget = searchInTarget;
- this.newIncluded = newIncluded;
- this.fuzzyIncluded = fuzzyIncluded;
- this.translatedIncluded = translatedIncluded;
- this.approvedIncluded = approvedIncluded;
- this.rejectedIncluded = rejectedIncluded;
- }
-
- /**
- * Create a chainable filter constraints that specifies a case-insensitive
- * search in both source and target, including all content states.
- *
- * Use chainable methods to alter these constraints
- *
- * @param searchString the string to search for in source and target
- * @return the new {@link FilterConstraints}
- */
- public static FilterConstraints filterBy(String searchString)
- {
- return new FilterConstraints(searchString, false, true, true, true, true, true, true, true);
+ this.includedStates = includedStates;
}
- public static FilterConstraints keepAll()
- {
- return new FilterConstraints("", false, true, true, true, true, true, true, true);
- }
-
- public static FilterConstraints keepNone()
+ public static Builder builder()
{
- return new FilterConstraints("", false, false, false, false, false, false, false, false);
+ return new Builder();
}
-
- //chainable setters
- // TODO use builder instead
-
- /**
- * Specify that search string does not require the same case as content to be considered a match
- *
- * @return this object for chaining
- */
- public FilterConstraints ignoreCase()
- {
- isCaseSensitive = false;
- return this;
- }
-
- /**
- * Specify that search string must have the same case as content to be considered a match
- *
- * @return this object for chaining
- */
- public FilterConstraints matchCase()
- {
- isCaseSensitive = true;
- return this;
- }
-
- /**
- * Specify search case-sensitivity
- *
- * @param caseSensitive true if the search string must have the same case as content to be considered a match
- * @return this object for chaining
- */
- public FilterConstraints caseSensitive(boolean caseSensitive)
- {
- this.isCaseSensitive = caseSensitive;
- return this;
- }
-
- /**
- * Return text flows that match the search string in their target content
- *
- * @return this object for chaining
- */
- public FilterConstraints filterTarget()
- {
- searchInTarget = true;
- return this;
- }
-
- /**
- * Do not search for the search string in the target
- *
- * @return this object for chaining
- */
- public FilterConstraints ignoreTarget()
+ @Override
+ public String toString()
{
- searchInTarget = false;
- return this;
+ // @formatter:off
+ return Objects.toStringHelper(this).
+ add("searchString", searchString).
+ add("isCaseSensitive", isCaseSensitive).
+ add("searchInSource", searchInSource).
+ add("searchInTarget", searchInTarget).
+ add("includedStates", includedStates).
+ toString();
+ // @formatter:on
}
- /**
- * Return text flows that match the search string in their source content
- *
- * @return this object for chaining
- */
- public FilterConstraints filterSource()
+ public static class Builder
{
- searchInSource = true;
- return this;
- }
+ private String searchString;
+ private boolean caseSensitive;
+ private boolean searchInSource;
+ private boolean searchInTarget;
+ private ActiveStates.Builder states;
- /**
- * Do not search for the search string in the source
- *
- * @return this object for chaining
- */
- public FilterConstraints ignoreSource()
- {
- searchInSource = false;
- return this;
- }
+ public Builder()
+ {
+ states = ActiveStates.builder();
+ setKeepAll();
+ }
- /**
- * Do not return any text flows with New targets
- *
- * @return this object for chaining
- */
- public FilterConstraints excludeNew()
- {
- newIncluded = false;
- return this;
- }
+ public FilterConstraints build()
+ {
+ return new FilterConstraints(searchString, caseSensitive,
+ searchInSource, searchInTarget, states.build());
+ }
- /**
- * Do not return any text flows with Fuzzy targets
- *
- * @return this object for chaining
- */
- public FilterConstraints excludeFuzzy()
- {
- fuzzyIncluded = false;
- return this;
- }
+ public Builder keepAll()
+ {
+ setKeepAll();
+ return this;
+ }
- /**
- * Do not return any text flows with Translated targets
- *
- * @return this object for chaining
- */
- public FilterConstraints excludeTranslated()
- {
- translatedIncluded = false;
- return this;
- }
-
- public FilterConstraints excludeApproved()
- {
- approvedIncluded = false;
- return this;
- }
-
- public FilterConstraints excludeRejected()
- {
- rejectedIncluded = false;
- return this;
- }
+ private void setKeepAll()
+ {
+ searchString = "";
+ caseSensitive = false;
+ searchInSource = true;
+ searchInTarget = true;
+ states.allOn();
+ }
+ public Builder keepNone()
+ {
+ searchString = "";
+ caseSensitive = false;
+ searchInSource = false;
+ searchInTarget = false;
+ states.allOff();
+ return this;
+ }
- //getters
+ public Builder filterBy(String searchString)
+ {
+ this.searchString = searchString;
+ return this;
+ }
- public String getSearchString()
- {
- return searchString;
- }
+ public Builder caseSensitive(boolean caseSensitive)
+ {
+ this.caseSensitive = caseSensitive;
+ return this;
+ }
- public boolean isCaseSensitive()
- {
- return this.isCaseSensitive;
- }
+ public Builder checkInSource(boolean check)
+ {
+ searchInSource = check;
+ return this;
+ }
- public boolean isSearchInSource()
- {
- return searchInSource;
- }
+ public Builder checkInTarget(boolean check)
+ {
+ searchInTarget = check;
+ return this;
+ }
- public boolean isSearchInTarget()
- {
- return searchInTarget;
- }
+ public Builder includeStates(ActiveStates states)
+ {
+ this.states.fromStates(states);
+ return this;
+ }
- public boolean isNewIncluded()
- {
- return newIncluded;
- }
+ public Builder includeNew()
+ {
+ states.setNewOn(true);
+ return this;
+ }
- public boolean isFuzzyIncluded()
- {
- return fuzzyIncluded;
- }
+ public Builder excludeNew()
+ {
+ states.setNewOn(false);
+ return this;
+ }
- public boolean isTranslatedIncluded()
- {
- return translatedIncluded;
- }
-
- public boolean isApprovedIncluded()
- {
- return approvedIncluded;
- }
-
- public boolean isRejectedIncluded()
- {
- return rejectedIncluded;
- }
+ public Builder includeFuzzy()
+ {
+ states.setFuzzyOn(true);
+ return this;
+ }
- public FilterConstraints filterByStatus(boolean newState, boolean fuzzyState, boolean translatedState, boolean approvedState, boolean rejectedState)
- {
- if (translatedState == fuzzyState && translatedState == newState && translatedState == approvedState && translatedState == rejectedState)
+ public Builder excludeFuzzy()
{
- return new FilterConstraints(searchString, isCaseSensitive, isSearchInSource(), isSearchInTarget(), true, true, true, true, true);
+ states.setFuzzyOn(false);
+ return this;
}
- return new FilterConstraints(searchString, isCaseSensitive, isSearchInSource(), isSearchInTarget(), newState, fuzzyState, translatedState, approvedState, rejectedState);
- }
- public boolean isAllStateIncluded()
- {
- return translatedIncluded && fuzzyIncluded && newIncluded && approvedIncluded && rejectedIncluded;
- }
+ public Builder includeTranslated()
+ {
+ states.setTranslatedOn(true);
+ return this;
+ }
- public List getContentStateAsList()
- {
- List result = Lists.newArrayList();
- if (translatedIncluded)
+ public Builder excludeTranslated()
{
- result.add(ContentState.Translated);
+ states.setTranslatedOn(false);
+ return this;
}
- if (fuzzyIncluded)
+
+ public Builder includeApproved()
{
- result.add(ContentState.NeedReview);
+ states.setApprovedOn(true);
+ return this;
}
- if (newIncluded)
+
+ public Builder excludeApproved()
{
- result.add(ContentState.New);
+ states.setApprovedOn(false);
+ return this;
}
- if (approvedIncluded)
+
+ public Builder includeRejected()
{
- result.add(ContentState.Approved);
+ states.setRejectedOn(true);
+ return this;
}
- if (rejectedIncluded)
+
+ public Builder excludeRejected()
{
- result.add(ContentState.Rejected);
+ states.setRejectedOn(false);
+ return this;
}
- return result;
- }
- @Override
- public String toString()
- {
- // @formatter:off
- return Objects.toStringHelper(this).
- add("searchString", searchString).
- add("isCaseSensitive", isCaseSensitive).
- add("searchInSource", searchInSource).
- add("searchInTarget", searchInTarget).
- add("newIncluded", newIncluded).
- add("fuzzyIncluded", fuzzyIncluded).
- add("translatedIncluded", translatedIncluded).
- add("approvedIncluded", approvedIncluded).
- add("rejectedIncluded", rejectedIncluded).
- toString();
- // @formatter:on
}
+
}
diff --git a/zanata-war/src/main/java/org/zanata/service/impl/TextFlowSearchServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/TextFlowSearchServiceImpl.java
index 1bad576876..e31a97de91 100644
--- a/zanata-war/src/main/java/org/zanata/service/impl/TextFlowSearchServiceImpl.java
+++ b/zanata-war/src/main/java/org/zanata/service/impl/TextFlowSearchServiceImpl.java
@@ -57,6 +57,7 @@
import org.zanata.model.HProjectIteration;
import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
+import org.zanata.search.ActiveStates;
import org.zanata.search.FilterConstraintToQuery;
import org.zanata.search.FilterConstraints;
import org.zanata.service.LocaleService;
@@ -139,7 +140,8 @@ private List findTextFlowsByDocumentPaths(WorkspaceId workspace, List
return Collections.emptyList();
}
- if (!constraints.isNewIncluded() && !constraints.isFuzzyIncluded() && !constraints.isTranslatedIncluded())
+ ActiveStates includedStates = constraints.getIncludedStates();
+ if (!includedStates.isNewOn() && !includedStates.isFuzzyOn() && !includedStates.isTranslatedOn())
{
// including nothing
return Collections.emptyList();
@@ -298,19 +300,19 @@ private List findTextFlowsWithHibernateSearch(String projectSlug, Str
}
targetQuery.add(localeQuery, Occur.MUST);
- if (!constraints.isTranslatedIncluded())
+ if (!constraints.getIncludedStates().isTranslatedOn())
{
TermQuery approvedStateQuery = new TermQuery(new Term(IndexFieldLabels.CONTENT_STATE_FIELD, ContentState.Approved.toString()));
targetQuery.add(approvedStateQuery, Occur.MUST_NOT);
}
- if (!constraints.isFuzzyIncluded())
+ if (!constraints.getIncludedStates().isFuzzyOn())
{
TermQuery approvedStateQuery = new TermQuery(new Term(IndexFieldLabels.CONTENT_STATE_FIELD, ContentState.NeedReview.toString()));
targetQuery.add(approvedStateQuery, Occur.MUST_NOT);
}
- if (!constraints.isNewIncluded())
+ if (!constraints.getIncludedStates().isNewOn())
{
TermQuery approvedStateQuery = new TermQuery(new Term(IndexFieldLabels.CONTENT_STATE_FIELD, ContentState.New.toString()));
targetQuery.add(approvedStateQuery, Occur.MUST_NOT);
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetProjectTransUnitListsHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetProjectTransUnitListsHandler.java
index 62c1ebde64..549176c1f1 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetProjectTransUnitListsHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetProjectTransUnitListsHandler.java
@@ -96,15 +96,12 @@ public GetProjectTransUnitListsResult execute(GetProjectTransUnitLists action, E
return new GetProjectTransUnitListsResult(action, docPaths, matchingTUs);
}
- FilterConstraints filterConstraints = FilterConstraints.filterBy(action.getSearchString()).caseSensitive(action.isCaseSensitive());
- if (!action.isSearchInSource())
- {
- filterConstraints.ignoreSource();
- }
- if (!action.isSearchInTarget())
- {
- filterConstraints.ignoreTarget();
- }
+ FilterConstraints filterConstraints = FilterConstraints.builder()
+ .filterBy(action.getSearchString())
+ .caseSensitive(action.isCaseSensitive())
+ .checkInSource(action.isSearchInSource())
+ .checkInTarget(action.isSearchInTarget())
+ .build();
List matchingFlows = textFlowSearchServiceImpl.findTextFlows(action.getWorkspaceId(), action.getDocumentPaths(), filterConstraints);
log.info("Returned {} results for search", matchingFlows.size());
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..e7404d99fa 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
@@ -35,6 +35,7 @@
import org.zanata.exception.ZanataServiceException;
import org.zanata.model.HLocale;
import org.zanata.model.HTextFlow;
+import org.zanata.search.ActiveStates;
import org.zanata.search.FilterConstraints;
import org.zanata.security.ZanataIdentity;
import org.zanata.service.LocaleService;
@@ -136,9 +137,17 @@ private List getTextFlows(GetTransUnitList action, HLocale hLocale, i
else
{
// @formatter:off
- FilterConstraints constraints = FilterConstraints
- .filterBy(action.getPhrase()).ignoreCase().filterSource().filterTarget()
- .filterByStatus(action.isFilterUntranslated(), action.isFilterNeedReview(), action.isFilterTranslated(), action.isFilterApproved(), action.isFilterRejected());
+ FilterConstraints constraints = FilterConstraints.builder()
+ .filterBy(action.getPhrase())
+ .caseSensitive(false).checkInSource(true).checkInTarget(true)
+ .includeStates(ActiveStates.builder()
+ .setNewOn(action.isFilterUntranslated())
+ .setFuzzyOn(action.isFilterNeedReview())
+ .setTranslatedOn(action.isFilterTranslated())
+ .setApprovedOn(action.isFilterApproved())
+ .setRejectedOn(action.isFilterRejected())
+ .build())
+ .build();
// @formatter:on
log.debug("Fetch TransUnits filtered by status and/or search: {}", constraints);
if (!hasValidationFilter(action))
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java
index c53d85535a..556476bc9b 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java
@@ -35,6 +35,7 @@
import org.zanata.model.HLocale;
import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
+import org.zanata.search.ActiveStates;
import org.zanata.search.FilterConstraints;
import org.zanata.webtrans.shared.model.TransUnitId;
import org.zanata.webtrans.shared.rpc.GetTransUnitsNavigation;
@@ -53,7 +54,18 @@ public class GetTransUnitsNavigationService
protected GetTransUnitsNavigationResult getNavigationIndexes(GetTransUnitsNavigation action, HLocale hLocale)
{
- FilterConstraints filterConstraints = FilterConstraints.filterBy(action.getPhrase()).filterSource().filterTarget().filterByStatus(action.isNewState(), action.isFuzzyState(), action.isTranslatedState(), action.isApprovedState(), action.isRejectedState());
+ FilterConstraints filterConstraints = FilterConstraints.builder()
+ .filterBy(action.getPhrase())
+ .checkInSource(true).checkInTarget(true)
+ .includeStates(ActiveStates.builder()
+ .setNewOn(action.isNewState())
+ .setFuzzyOn(action.isFuzzyState())
+ .setTranslatedOn(action.isTranslatedState())
+ .setApprovedOn(action.isApprovedState())
+ .setRejectedOn(action.isRejectedState())
+ .build())
+ .build();
+
List idIndexList = new ArrayList();
Map transIdStateMap = new HashMap();
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
index e6c7d76e8e..f5578f6f98 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
@@ -16,6 +16,7 @@ public class GetTransUnitList extends AbstractWorkspaceAction validationIds;
private TransUnitId targetTransUnitId;
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
index 05410230a8..7c050a7f2d 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
@@ -28,6 +28,8 @@ public class GetTransUnitsNavigation
{
private Long id;
private String phrase;
+
+ // FIXME use state object
private boolean isFuzzyState, isNewState, isTranslatedState, isApprovedState, isRejectedState;
@SuppressWarnings("unused")
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index 018457f69e..7a53849be8 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -67,26 +67,27 @@ private void printTestData()
}
+ // FIXME looks like this test does not take more recently added states into account
+ // should ensure all states are in test data and check test logic
@Test
public void canGetAllUntranslatedTextFlowForADocument() {
HLocale deLocale = getEm().find(HLocale.class, 3L);
log.info("locale: {}", deLocale);
- FilterConstraints untranslated = FilterConstraints.keepAll().excludeFuzzy().excludeTranslated();
+ FilterConstraints untranslated = FilterConstraints.builder().keepAll().excludeFuzzy().excludeTranslated().build();
List result = dao.getTextFlowByDocumentIdWithConstraints(new DocumentId(1L, ""), deLocale, untranslated, 0, 10);
assertThat(result.size(), is(0));
HLocale frLocale = getEm().find(HLocale.class, 6L);
result = dao.getTextFlowByDocumentIdWithConstraints(new DocumentId(1L, ""), frLocale, untranslated, 0, 10);
assertThat(result.size(), is(1));
-
}
@Test
public void canGetTextFlowWithNullTarget() {
HLocale deLocale = getEm().find(HLocale.class, 3L);
- FilterConstraints untranslated = FilterConstraints.keepAll().excludeFuzzy().excludeTranslated();
+ FilterConstraints untranslated = FilterConstraints.builder().keepAll().excludeFuzzy().excludeTranslated().build();
List result = dao.getTextFlowByDocumentIdWithConstraints(new DocumentId(4L, ""), deLocale, untranslated, 0, 10);
assertThat(result, Matchers.hasSize(1));
}
@@ -100,55 +101,60 @@ public void canGetTextFlowsByStatus() {
DocumentId documentId1 = new DocumentId(1L, ""); // esLocale fuzzy,
// frLocale new, deLocale
// approved
- List result = dao.getTextFlowByDocumentIdWithConstraints(documentId1, esLocale, FilterConstraints.keepAll().excludeTranslated().excludeNew(), 0, 10);
+ List result = dao.getTextFlowByDocumentIdWithConstraints(documentId1, esLocale,
+ FilterConstraints.builder().keepAll().excludeTranslated().excludeNew().build(), 0, 10);
assertThat(result, Matchers.hasSize(1));
- result = dao.getTextFlowByDocumentIdWithConstraints(documentId1, frLocale, FilterConstraints.keepAll().excludeFuzzy(), 0, 10);
+ result = dao.getTextFlowByDocumentIdWithConstraints(documentId1, frLocale,
+ FilterConstraints.builder().keepAll().excludeFuzzy().build(), 0, 10);
assertThat(result, Matchers.hasSize(1));
- result = dao.getTextFlowByDocumentIdWithConstraints(documentId1, deLocale, FilterConstraints.keepAll().excludeFuzzy().excludeNew(), 0, 10);
+ result = dao.getTextFlowByDocumentIdWithConstraints(documentId1, deLocale,
+ FilterConstraints.builder().keepAll().excludeFuzzy().excludeNew().build(), 0, 10);
assertThat(result, Matchers.hasSize(1));
HLocale enUSLocale = getEm().find(HLocale.class, 4L);
DocumentId documentId2 = new DocumentId(2L, ""); // all 3 text flows has
// en-US fuzzy target
- result = dao.getTextFlowByDocumentIdWithConstraints(documentId2, enUSLocale, FilterConstraints.keepAll().excludeTranslated().excludeFuzzy(), 0, 10);
+ result = dao.getTextFlowByDocumentIdWithConstraints(documentId2, enUSLocale,
+ FilterConstraints.builder().keepAll().excludeTranslated().excludeFuzzy().build(), 0, 10);
assertThat(result, Matchers.empty());
- result = dao.getTextFlowByDocumentIdWithConstraints(documentId2, enUSLocale, FilterConstraints.keepAll().excludeNew(), 0, 10);
+ result = dao.getTextFlowByDocumentIdWithConstraints(documentId2, enUSLocale,
+ FilterConstraints.builder().keepAll().excludeNew().build(), 0, 10);
assertThat(result, Matchers.hasSize(3));
}
+ // TODO this should be split into 8 tests
@Test
public void canBuildContentStateQuery()
{
// accept all
- assertThat(TextFlowDAO.buildContentStateCondition(FilterConstraints.keepAll(), "tft"), Matchers.equalTo("1"));
- assertThat(TextFlowDAO.buildContentStateCondition(FilterConstraints.keepNone(), "tft"), Matchers.equalTo("1"));
+ assertThat(TextFlowDAO.buildContentStateCondition(FilterConstraints.builder().keepAll().build(), "tft"), Matchers.equalTo("1"));
+ assertThat(TextFlowDAO.buildContentStateCondition(FilterConstraints.builder().keepNone().build(), "tft"), Matchers.equalTo("1"));
// single status filter
- FilterConstraints filterConstraints = FilterConstraints.keepNone();
-
- filterConstraints = filterConstraints.filterByStatus(false, false, true, false, false);
- assertThat(TextFlowDAO.buildContentStateCondition(filterConstraints, "tft"), Matchers.equalTo("(tft.state=2 or tft.state=3)"));
-
- filterConstraints = filterConstraints.filterByStatus(false, true, false, false, false);
- assertThat(TextFlowDAO.buildContentStateCondition(filterConstraints, "tft"), Matchers.equalTo("(tft.state=1 or tft.state=4)"));
-
- filterConstraints = filterConstraints.filterByStatus(true, false, false, false, false);
- assertThat(TextFlowDAO.buildContentStateCondition(filterConstraints, "tft"), Matchers.equalTo("(tft.state=0 or tft.state is null)"));
+ FilterConstraints.Builder constraints = FilterConstraints.builder();
+
+ constraints.keepNone().includeTranslated();
+ assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=2 or tft.state=3)"));
+
+ constraints.keepNone().includeFuzzy();
+ assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=1 or tft.state=4)"));
+
+ constraints.keepNone().includeNew();
+ assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=0 or tft.state is null)"));
// two status
-
- filterConstraints = filterConstraints.filterByStatus(true, false, true, false, false);
- assertThat(TextFlowDAO.buildContentStateCondition(filterConstraints, "tft"), Matchers.equalTo("(tft.state=2 or tft.state=3 or tft.state=0 or tft.state is null)"));
-
- filterConstraints = filterConstraints.filterByStatus(false, true, true, false, false);
- assertThat(TextFlowDAO.buildContentStateCondition(filterConstraints, "tft"), Matchers.equalTo("(tft.state=2 or tft.state=3 or tft.state=1 or tft.state=4)"));
-
- filterConstraints = filterConstraints.filterByStatus(true, true, false, false, false);
- assertThat(TextFlowDAO.buildContentStateCondition(filterConstraints, "tft"), Matchers.equalTo("(tft.state=1 or tft.state=4 or tft.state=0 or tft.state is null)"));
+ constraints.keepNone().includeNew().includeTranslated();
+ assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=2 or tft.state=3 or tft.state=0 or tft.state is null)"));
+
+ constraints.keepNone().includeFuzzy().includeApproved();
+ assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=2 or tft.state=3 or tft.state=1 or tft.state=4)"));
+
+ constraints.keepNone().includeNew().includeFuzzy();
+ assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=1 or tft.state=4 or tft.state=0 or tft.state is null)"));
}
@Test
@@ -169,7 +175,10 @@ public void testGetTextFlowByDocumentIdWithConstraint()
{
HLocale deLocale = getEm().find(HLocale.class, 3L);
- List result = dao.getTextFlowByDocumentIdWithConstraints(new DocumentId(new Long(4), ""), deLocale, FilterConstraints.filterBy("mssg").excludeTranslated().excludeFuzzy(), 0, 10);
+ List result = dao.getTextFlowByDocumentIdWithConstraints(
+ new DocumentId(new Long(4), ""), deLocale,
+ FilterConstraints.builder().filterBy("mssg").excludeTranslated().excludeFuzzy().build(),
+ 0, 10);
assertThat(result, Matchers.hasSize(1));
}
@@ -181,6 +190,5 @@ public void queryTest1()
"where (exists (from HTextFlowTarget where textFlow = tf and content0 like '%mssg%'))";
Query query = getSession().createQuery(queryString);
List result = query.list();
-
}
}
diff --git a/zanata-war/src/test/java/org/zanata/search/FilterConstraintToQueryTest.java b/zanata-war/src/test/java/org/zanata/search/FilterConstraintToQueryTest.java
index a4c9b2a4a1..04108706ff 100644
--- a/zanata-war/src/test/java/org/zanata/search/FilterConstraintToQueryTest.java
+++ b/zanata-war/src/test/java/org/zanata/search/FilterConstraintToQueryTest.java
@@ -48,7 +48,8 @@ public void beforeMethod()
@Test
public void testBuildSearchConditionWithNothingToSearch()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.keepAll(), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().keepAll().build(), documentId);
String result = constraintToQuery.buildSearchCondition();
@@ -58,7 +59,8 @@ public void testBuildSearchConditionWithNothingToSearch()
@Test
public void testBuildSearchConditionInSource()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.filterBy("FiLe").ignoreTarget().filterSource(), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().filterBy("FiLe").checkInTarget(false).checkInSource(true).build(), documentId);
String result = constraintToQuery.buildSearchCondition();
@@ -68,7 +70,8 @@ public void testBuildSearchConditionInSource()
@Test
public void testBuildSearchConditionInTarget()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.filterBy("FiLe").ignoreSource().filterTarget(), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().filterBy("FiLe").checkInSource(false).checkInTarget(true).build(), documentId);
String result = constraintToQuery.buildSearchCondition();
@@ -79,7 +82,8 @@ public void testBuildSearchConditionInTarget()
@Test
public void testBuildSearchConditionInBoth()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.filterBy("FiLe"), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().filterBy("FiLe").build(), documentId);
String result = constraintToQuery.buildSearchCondition();
@@ -89,7 +93,8 @@ public void testBuildSearchConditionInBoth()
@Test
public void testCaseSensitiveSearch()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.filterBy("FiLe").caseSensitive(true), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().filterBy("FiLe").caseSensitive(true).build(), documentId);
String result = constraintToQuery.buildSearchCondition();
@@ -99,7 +104,8 @@ public void testCaseSensitiveSearch()
@Test
public void testBuildStateConditionWithAllState()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.keepAll(), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().keepAll().build(), documentId);
String result = constraintToQuery.buildSearchCondition();
@@ -109,7 +115,8 @@ public void testBuildStateConditionWithAllState()
@Test
public void testBuildStateConditionWithoutUntranslatedState()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.keepAll().excludeNew(), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().keepAll().excludeNew().build(), documentId);
String result = constraintToQuery.buildStateCondition();
@@ -119,7 +126,8 @@ public void testBuildStateConditionWithoutUntranslatedState()
@Test
public void testBuildStateConditionWithUntranslatedStateButNoSearch()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.keepAll().excludeTranslated(), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().keepAll().excludeTranslated().build(), documentId);
String result = constraintToQuery.buildStateCondition();
@@ -136,7 +144,8 @@ public void testBuildStateConditionWithUntranslatedStateButNoSearch()
@Test
public void testBuildStateConditionWithUntranslatedStateAndSearch()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.filterBy("blah").excludeTranslated(), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().filterBy("blah").excludeTranslated().build(), documentId);
String result = constraintToQuery.buildStateCondition();
@@ -154,7 +163,8 @@ public void testBuildStateConditionWithUntranslatedStateAndSearch()
@Test
public void testToHQLWithNoCondition()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.keepAll(), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().keepAll().build(), documentId);
String result = constraintToQuery.toHQL();
@@ -164,7 +174,8 @@ public void testToHQLWithNoCondition()
@Test
public void testToHQLWithNoConditionForMultipleDocuments()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInMultipleDocuments(FilterConstraints.keepAll(), Lists.newArrayList(1L));
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInMultipleDocuments(
+ FilterConstraints.builder().keepAll().build(), Lists.newArrayList(1L));
String result = constraintToQuery.toHQL();
@@ -174,7 +185,8 @@ public void testToHQLWithNoConditionForMultipleDocuments()
@Test
public void testToHQLWithSearchAndStateCondition()
{
- FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(FilterConstraints.filterBy("FiLe").excludeTranslated(), documentId);
+ FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(
+ FilterConstraints.builder().filterBy("FiLe").excludeTranslated().build(), documentId);
String result = constraintToQuery.toHQL();
log.info("hql: {}", result);
@@ -201,7 +213,7 @@ public void testToHQLWithSearchAndStateCondition()
@Test
public void testSetParametersForQuery()
{
- FilterConstraints constraints = FilterConstraints.filterBy("file").excludeTranslated();
+ FilterConstraints constraints = FilterConstraints.builder().filterBy("file").excludeTranslated().build();
FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(constraints, documentId);
constraintToQuery.setQueryParameters(query, hLocale);
@@ -209,14 +221,14 @@ public void testSetParametersForQuery()
verify(query).setParameter(FilterConstraintToQuery.DOC_ID_NAMED_PARAM, documentId.getId());
verify(query).setParameter(FilterConstraintToQuery.LOCALE_NAMED_PARAM, hLocale.getId());
verify(query).setParameter(FilterConstraintToQuery.SEARCH_NAMED_PARAM, "%file%");
- verify(query).setParameterList(FilterConstraintToQuery.STATE_LIST_NAMED_PARAM, constraints.getContentStateAsList());
+ verify(query).setParameterList(FilterConstraintToQuery.STATE_LIST_NAMED_PARAM, constraints.getIncludedStates().asList());
verifyNoMoreInteractions(query);
}
@Test
public void testSetParametersForQueryWithMultipleDocuments()
{
- FilterConstraints constraints = FilterConstraints.filterBy("file").excludeTranslated();
+ FilterConstraints constraints = FilterConstraints.builder().filterBy("file").excludeTranslated().build();
List docIdList = Lists.newArrayList(1L, 2L);
FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInMultipleDocuments(constraints, docIdList);
@@ -225,28 +237,28 @@ public void testSetParametersForQueryWithMultipleDocuments()
verify(query).setParameterList(FilterConstraintToQuery.DOC_IDS_LIST_NAMED_PARAM, docIdList);
verify(query).setParameter(FilterConstraintToQuery.LOCALE_NAMED_PARAM, hLocale.getId());
verify(query).setParameter(FilterConstraintToQuery.SEARCH_NAMED_PARAM, "%file%");
- verify(query).setParameterList(FilterConstraintToQuery.STATE_LIST_NAMED_PARAM, constraints.getContentStateAsList());
+ verify(query).setParameterList(FilterConstraintToQuery.STATE_LIST_NAMED_PARAM, constraints.getIncludedStates().asList());
verifyNoMoreInteractions(query);
}
@Test
public void testSetParametersForQueryWithNoSearch()
{
- FilterConstraints constraints = FilterConstraints.keepAll().excludeTranslated();
+ FilterConstraints constraints = FilterConstraints.builder().keepAll().excludeTranslated().build();
FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(constraints, documentId);
constraintToQuery.setQueryParameters(query, hLocale);
verify(query).setParameter(FilterConstraintToQuery.DOC_ID_NAMED_PARAM, documentId.getId());
verify(query).setParameter(FilterConstraintToQuery.LOCALE_NAMED_PARAM, hLocale.getId());
- verify(query).setParameterList(FilterConstraintToQuery.STATE_LIST_NAMED_PARAM, constraints.getContentStateAsList());
+ verify(query).setParameterList(FilterConstraintToQuery.STATE_LIST_NAMED_PARAM, constraints.getIncludedStates().asList());
verifyNoMoreInteractions(query);
}
@Test
public void testSetParametersForQueryWithNoStateFilter()
{
- FilterConstraints constraints = FilterConstraints.filterBy("FiLe");
+ FilterConstraints constraints = FilterConstraints.builder().filterBy("FiLe").build();
FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(constraints, documentId);
constraintToQuery.setQueryParameters(query, hLocale);
@@ -260,7 +272,7 @@ public void testSetParametersForQueryWithNoStateFilter()
@Test
public void testSetParametersForQueryWithSearchCaseSensitive()
{
- FilterConstraints constraints = FilterConstraints.filterBy("FiLe").caseSensitive(true);
+ FilterConstraints constraints = FilterConstraints.builder().filterBy("FiLe").caseSensitive(true).build();
FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(constraints, documentId);
constraintToQuery.setQueryParameters(query, hLocale);
@@ -274,7 +286,7 @@ public void testSetParametersForQueryWithSearchCaseSensitive()
@Test
public void testSetParametersForQueryWithSearchTermAsPercent()
{
- FilterConstraints constraints = FilterConstraints.filterBy("% blah blah %").caseSensitive(true);
+ FilterConstraints constraints = FilterConstraints.builder().filterBy("% blah blah %").caseSensitive(true).build();
FilterConstraintToQuery constraintToQuery = FilterConstraintToQuery.filterInSingleDocument(constraints, documentId);
constraintToQuery.setQueryParameters(query, hLocale);
diff --git a/zanata-war/src/test/java/org/zanata/service/impl/TextFlowSearchServiceImplTest.java b/zanata-war/src/test/java/org/zanata/service/impl/TextFlowSearchServiceImplTest.java
index 0dfea64cc1..0df0720280 100644
--- a/zanata-war/src/test/java/org/zanata/service/impl/TextFlowSearchServiceImplTest.java
+++ b/zanata-war/src/test/java/org/zanata/service/impl/TextFlowSearchServiceImplTest.java
@@ -24,16 +24,13 @@
import org.zanata.service.TextFlowSearchService;
import org.zanata.webtrans.shared.model.WorkspaceId;
-import lombok.extern.slf4j.Slf4j;
import static org.hamcrest.MatcherAssert.*;
import static org.mockito.Mockito.*;
-import static org.mockito.Mockito.when;
/**
* @author Patrick Huang pahuang@redhat.com
*/
@Test(groups = { "jpa-tests" })
-@Slf4j
public class TextFlowSearchServiceImplTest extends ZanataDbunitJpaTest
{
private TextFlowSearchService service;
@@ -69,7 +66,8 @@ public void beforeMethod()
@Test
public void testFindTextFlows() throws Exception
{
- List result = service.findTextFlows(workspaceId, FilterConstraints.filterBy("file"));
+ List result = service.findTextFlows(workspaceId,
+ FilterConstraints.builder().filterBy("file").build());
assertThat(result.size(), Matchers.equalTo(7));
}
From dd5806758b5a20725c035f1ab0051b8c32ad5837 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Fri, 5 Jul 2013 16:40:50 +1000
Subject: [PATCH 018/184] Use ActiveStates in search and navigation actions
---
.../server/rpc/GetTransUnitListHandler.java | 13 +---
.../rpc/GetTransUnitsNavigationService.java | 9 +--
.../webtrans/shared/rpc/GetTransUnitList.java | 60 ++++++++++---------
.../shared/rpc/GetTransUnitsNavigation.java | 57 +++++++-----------
4 files changed, 55 insertions(+), 84 deletions(-)
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 e7404d99fa..fe76eb80dd 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
@@ -88,7 +88,7 @@ public GetTransUnitListResult execute(GetTransUnitList action, ExecutionContext
GetTransUnitsNavigationResult navigationResult = null;
if (action.isNeedReloadIndex())
{
- GetTransUnitsNavigation getTransUnitsNavigation = new GetTransUnitsNavigation(action.getDocumentId().getId(), action.getPhrase(), action.isFilterUntranslated(), action.isFilterNeedReview(), action.isFilterTranslated(), action.isFilterApproved(), action.isFilterRejected());
+ GetTransUnitsNavigation getTransUnitsNavigation = new GetTransUnitsNavigation(action.getDocumentId().getId(), action.getPhrase(), action.getFilterStates());
log.debug("get trans unit navigation action: {}", getTransUnitsNavigation);
navigationResult = getTransUnitsNavigationService.getNavigationIndexes(getTransUnitsNavigation, hLocale);
@@ -117,16 +117,13 @@ public GetTransUnitListResult execute(GetTransUnitList action, ExecutionContext
private List getTextFlows(GetTransUnitList action, HLocale hLocale, int offset)
{
List textFlows;
- // no status and phrase filter
if (!hasStatusAndPhaseFilter(action))
{
- // no validation filter
log.debug("Fetch TransUnits:*");
if (!hasValidationFilter(action))
{
textFlows = textFlowDAO.getTextFlowsByDocumentId(action.getDocumentId(), offset, action.getCount());
}
- // has validation filter
else
{
textFlows = textFlowDAO.getAllTextFlowsByDocumentId(action.getDocumentId());
@@ -140,13 +137,7 @@ private List getTextFlows(GetTransUnitList action, HLocale hLocale, i
FilterConstraints constraints = FilterConstraints.builder()
.filterBy(action.getPhrase())
.caseSensitive(false).checkInSource(true).checkInTarget(true)
- .includeStates(ActiveStates.builder()
- .setNewOn(action.isFilterUntranslated())
- .setFuzzyOn(action.isFilterNeedReview())
- .setTranslatedOn(action.isFilterTranslated())
- .setApprovedOn(action.isFilterApproved())
- .setRejectedOn(action.isFilterRejected())
- .build())
+ .includeStates(action.getFilterStates())
.build();
// @formatter:on
log.debug("Fetch TransUnits filtered by status and/or search: {}", constraints);
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java
index 556476bc9b..f92cfb2608 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java
@@ -35,7 +35,6 @@
import org.zanata.model.HLocale;
import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
-import org.zanata.search.ActiveStates;
import org.zanata.search.FilterConstraints;
import org.zanata.webtrans.shared.model.TransUnitId;
import org.zanata.webtrans.shared.rpc.GetTransUnitsNavigation;
@@ -57,13 +56,7 @@ protected GetTransUnitsNavigationResult getNavigationIndexes(GetTransUnitsNaviga
FilterConstraints filterConstraints = FilterConstraints.builder()
.filterBy(action.getPhrase())
.checkInSource(true).checkInTarget(true)
- .includeStates(ActiveStates.builder()
- .setNewOn(action.isNewState())
- .setFuzzyOn(action.isFuzzyState())
- .setTranslatedOn(action.isTranslatedState())
- .setApprovedOn(action.isApprovedState())
- .setRejectedOn(action.isRejectedState())
- .build())
+ .includeStates(action.getActiveStates())
.build();
List idIndexList = new ArrayList();
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
index f5578f6f98..16a477ac60 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
@@ -2,6 +2,7 @@
import java.util.List;
+import org.zanata.search.ActiveStates;
import org.zanata.webtrans.client.service.GetTransUnitActionContext;
import org.zanata.webtrans.shared.model.DocumentId;
import org.zanata.webtrans.shared.model.TransUnitId;
@@ -16,37 +17,37 @@ public class GetTransUnitList extends AbstractWorkspaceAction validationIds;
private TransUnitId targetTransUnitId;
private boolean needReloadIndex = false;
- @SuppressWarnings("unused")
private GetTransUnitList()
{
}
- private GetTransUnitList(DocumentId id, int offset, int count, String phrase, boolean filterTranslated, boolean filterNeedReview, boolean filterUntranslated, boolean filterApproved, boolean filterRejected, boolean filterHasError, TransUnitId targetTransUnitId, List validationIds)
+ private GetTransUnitList(GetTransUnitActionContext context)
{
- this.documentId = id;
- this.offset = offset;
- this.count = count;
- this.phrase = phrase;
- this.filterTranslated = filterTranslated;
- this.filterNeedReview = filterNeedReview;
- this.filterUntranslated = filterUntranslated;
- this.filterApproved = filterApproved;
- this.filterRejected = filterRejected;
- this.filterHasError = filterHasError;
- this.targetTransUnitId = targetTransUnitId;
- this.validationIds = validationIds;
-
+ documentId = context.getDocument().getId();
+ offset = context.getOffset();
+ count = context.getCount();
+ phrase = context.getFindMessage();
+ filterStates = ActiveStates.builder()
+ .setNewOn(context.isFilterUntranslated())
+ .setFuzzyOn(context.isFilterNeedReview())
+ .setTranslatedOn(context.isFilterTranslated())
+ .setApprovedOn(context.isFilterApproved())
+ .setRejectedOn(context.isFilterRejected())
+ .build();
+ filterHasError = context.isFilterHasError();
+ targetTransUnitId = context.getTargetTransUnitId();
+ validationIds = context.getValidationIds();
}
public static GetTransUnitList newAction(GetTransUnitActionContext context)
{
- return new GetTransUnitList(context.getDocument().getId(), context.getOffset(), context.getCount(), context.getFindMessage(), context.isFilterTranslated(), context.isFilterNeedReview(), context.isFilterUntranslated(), context.isFilterApproved(), context.isFilterRejected(), context.isFilterHasError(), context.getTargetTransUnitId(), context.getValidationIds());
+ return new GetTransUnitList(context);
}
public boolean isNeedReloadIndex()
@@ -80,29 +81,34 @@ public String getPhrase()
return this.phrase;
}
+ public ActiveStates getFilterStates()
+ {
+ return filterStates;
+ }
+
public boolean isFilterTranslated()
{
- return filterTranslated;
+ return filterStates.isTranslatedOn();
}
public boolean isFilterNeedReview()
{
- return filterNeedReview;
+ return filterStates.isFuzzyOn();
}
public boolean isFilterUntranslated()
{
- return filterUntranslated;
+ return filterStates.isNewOn();
}
public boolean isFilterApproved()
{
- return filterApproved;
+ return filterStates.isApprovedOn();
}
public boolean isFilterRejected()
{
- return filterRejected;
+ return filterStates.isRejectedOn();
}
public boolean isFilterHasError()
@@ -123,7 +129,7 @@ public List getValidationIds()
public boolean isAcceptAllStatus()
{
//all filter options are checked or unchecked
- return filterNeedReview == filterTranslated && filterNeedReview == filterUntranslated && filterNeedReview == filterHasError && filterApproved == filterNeedReview && filterRejected == filterNeedReview;
+ return filterStates.hasNoStates() && !filterHasError || filterStates.hasAllStates() && filterHasError;
}
@Override
@@ -135,11 +141,7 @@ public String toString()
add("count", count).
add("documentId", documentId).
add("phrase", phrase).
- add("filterTranslated", filterTranslated).
- add("filterNeedReview", filterNeedReview).
- add("filterUntranslated", filterUntranslated).
- add("filterApproved", filterApproved).
- add("filterRejected", filterRejected).
+ add("filterStates", filterStates).
add("filterHasError", filterHasError).
add("targetTransUnitId", targetTransUnitId).
add("needReloadIndex", needReloadIndex).
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
index 7c050a7f2d..1ca50389b7 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
@@ -21,6 +21,7 @@
package org.zanata.webtrans.shared.rpc;
+import org.zanata.search.ActiveStates;
import org.zanata.webtrans.client.service.GetTransUnitActionContext;
import com.google.common.base.Objects;
@@ -29,28 +30,36 @@ public class GetTransUnitsNavigation
private Long id;
private String phrase;
- // FIXME use state object
- private boolean isFuzzyState, isNewState, isTranslatedState, isApprovedState, isRejectedState;
+ private ActiveStates activeStates;
@SuppressWarnings("unused")
private GetTransUnitsNavigation()
{
}
- public GetTransUnitsNavigation(Long id, String phrase, boolean isNewState, boolean isFuzzyState, boolean isTranslatedState, boolean isApprovedState, boolean isRejectedState)
+ public GetTransUnitsNavigation(Long id, String phrase, ActiveStates activeStates)
{
this.id = id;
this.phrase = phrase;
- this.isNewState = isNewState;
- this.isFuzzyState = isFuzzyState;
- this.isTranslatedState = isTranslatedState;
- this.isApprovedState = isApprovedState;
- this.isRejectedState = isRejectedState;
+ this.activeStates = activeStates;
+ }
+
+ public GetTransUnitsNavigation(GetTransUnitActionContext context)
+ {
+ this(context.getDocument().getId().getId(),
+ context.getFindMessage(),
+ ActiveStates.builder()
+ .setNewOn(context.isFilterUntranslated())
+ .setFuzzyOn(context.isFilterNeedReview())
+ .setTranslatedOn(context.isFilterTranslated())
+ .setApprovedOn(context.isFilterApproved())
+ .setRejectedOn(context.isFilterRejected())
+ .build());
}
public static GetTransUnitsNavigation newAction(GetTransUnitActionContext context)
{
- return new GetTransUnitsNavigation(context.getDocument().getId().getId(), context.getFindMessage(), context.isFilterUntranslated(), context.isFilterNeedReview(), context.isFilterTranslated(), context.isFilterApproved(), context.isFilterRejected());
+ return new GetTransUnitsNavigation(context);
}
public Long getId()
@@ -63,29 +72,9 @@ public String getPhrase()
return this.phrase;
}
- public boolean isFuzzyState()
- {
- return isFuzzyState;
- }
-
- public boolean isNewState()
- {
- return isNewState;
- }
-
- public boolean isTranslatedState()
- {
- return isTranslatedState;
- }
-
- public boolean isApprovedState()
- {
- return isApprovedState;
- }
-
- public boolean isRejectedState()
+ public ActiveStates getActiveStates()
{
- return isRejectedState;
+ return activeStates;
}
@Override
@@ -95,11 +84,7 @@ public String toString()
return Objects.toStringHelper(this).
add("id", id).
add("phrase", phrase).
- add("isFuzzyState", isFuzzyState).
- add("isNewState", isNewState).
- add("isTranslatedState", isTranslatedState).
- add("isApprovedState", isApprovedState).
- add("isRejectedState", isRejectedState).
+ add("activeStates", activeStates).
toString();
// @formatter:on
}
From 2abfe51676dc9b155feb95aee5cbd9fcf367f420 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Fri, 5 Jul 2013 17:32:13 +1000
Subject: [PATCH 019/184] set client version in test
---
functional-test/sample-projects/glossary/pom.xml | 1 +
functional-test/sample-projects/plural/pom.xml | 3 ++-
pom.xml | 2 +-
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/functional-test/sample-projects/glossary/pom.xml b/functional-test/sample-projects/glossary/pom.xml
index 29aa8355a8..89ec996721 100644
--- a/functional-test/sample-projects/glossary/pom.xml
+++ b/functional-test/sample-projects/glossary/pom.xml
@@ -13,6 +13,7 @@
org.zanata
zanata-maven-plugin
+ ${zanata.client.version}
diff --git a/functional-test/sample-projects/plural/pom.xml b/functional-test/sample-projects/plural/pom.xml
index 242001acd0..772d895300 100644
--- a/functional-test/sample-projects/plural/pom.xml
+++ b/functional-test/sample-projects/plural/pom.xml
@@ -9,7 +9,8 @@
org.zanata
zanata-maven-plugin
-
+ ${zanata.client.version}
+
pot
.
diff --git a/pom.xml b/pom.xml
index 80c1c1065e..736301d68a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,7 +35,7 @@
3.0.1-SNAPSHOT
3.0.1-SNAPSHOT
- 3.0.0
+ 3.0.1-SNAPSHOT
3.0.0
4.3.2.Final
From 29ea2e5dfe7a041aac139acd41955f96be47c75f Mon Sep 17 00:00:00 2001
From: David Mason
Date: Mon, 8 Jul 2013 10:25:39 +1000
Subject: [PATCH 020/184] split TextFlowDAOTest.canBuildContentStateQuery()
into more atomic tests
---
.../java/org/zanata/dao/TextFlowDAOTest.java | 81 ++++++++++++++-----
1 file changed, 60 insertions(+), 21 deletions(-)
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index 7a53849be8..ab5fb456be 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -126,35 +126,74 @@ public void canGetTextFlowsByStatus() {
assertThat(result, Matchers.hasSize(3));
}
- // TODO this should be split into 8 tests
+
@Test
- public void canBuildContentStateQuery()
+ public void canBuildAcceptAllQuery()
{
- // accept all
- assertThat(TextFlowDAO.buildContentStateCondition(FilterConstraints.builder().keepAll().build(), "tft"), Matchers.equalTo("1"));
- assertThat(TextFlowDAO.buildContentStateCondition(FilterConstraints.builder().keepNone().build(), "tft"), Matchers.equalTo("1"));
-
- // single status filter
- FilterConstraints.Builder constraints = FilterConstraints.builder();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(
+ FilterConstraints.builder().keepAll().build(), "tft");
+ assertThat("Conditional that accepts all should be '1'", contentStateCondition, is("1"));
+ }
- constraints.keepNone().includeTranslated();
- assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=2 or tft.state=3)"));
+ @Test
+ public void canBuildAcceptAllQueryWhenNoStatesSelected()
+ {
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(
+ FilterConstraints.builder().keepNone().build(), "tft");
+ assertThat("Conditional that accepts all should be '1'", contentStateCondition, is("1"));
+ }
- constraints.keepNone().includeFuzzy();
- assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=1 or tft.state=4)"));
+ @Test
+ public void canBuildNewOnlyConditional()
+ {
+ FilterConstraints constraints = FilterConstraints.builder()
+ .keepNone().includeNew().build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
+ assertThat(contentStateCondition, is("(tft.state=0 or tft.state is null)"));
+ }
- constraints.keepNone().includeNew();
- assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=0 or tft.state is null)"));
+ @Test
+ public void canBuildFuzzyOnlyConditional()
+ {
+ FilterConstraints constraints = FilterConstraints.builder()
+ .keepNone().includeFuzzy().build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
+ assertThat(contentStateCondition, is("(tft.state=1 or tft.state=4)"));
+ }
- // two status
- constraints.keepNone().includeNew().includeTranslated();
- assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=2 or tft.state=3 or tft.state=0 or tft.state is null)"));
+ @Test
+ public void canBuildTranslatedOnlyConditional()
+ {
+ FilterConstraints constraints = FilterConstraints.builder()
+ .keepNone().includeTranslated().build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
+ assertThat(contentStateCondition, is("(tft.state=2 or tft.state=3)"));
+ }
- constraints.keepNone().includeFuzzy().includeApproved();
- assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=2 or tft.state=3 or tft.state=1 or tft.state=4)"));
+ @Test
+ public void canBuildContentStateQuery()
+ {
+ FilterConstraints constraints = FilterConstraints.builder()
+ .keepNone().includeNew().includeFuzzy().build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
+ assertThat(contentStateCondition, is("(tft.state=1 or tft.state=4 or tft.state=0 or tft.state is null)"));
+ }
+ @Test
+ public void canBuildNewAndTranslatedConditional()
+ {
+ FilterConstraints constraints = FilterConstraints.builder()
+ .keepNone().includeNew().includeTranslated().build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
+ assertThat(contentStateCondition, is("(tft.state=2 or tft.state=3 or tft.state=0 or tft.state is null)"));
+ }
- constraints.keepNone().includeNew().includeFuzzy();
- assertThat(TextFlowDAO.buildContentStateCondition(constraints.build(), "tft"), Matchers.equalTo("(tft.state=1 or tft.state=4 or tft.state=0 or tft.state is null)"));
+ @Test
+ public void canBuildFuzzyAndTranslatedConditional()
+ {
+ FilterConstraints constraints = FilterConstraints.builder()
+ .keepNone().includeFuzzy().includeTranslated().build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
+ assertThat(contentStateCondition, is("(tft.state=2 or tft.state=3 or tft.state=1 or tft.state=4)"));
}
@Test
From 60ae8a847380d0386a3ab2d42523a0fd578df654 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Mon, 8 Jul 2013 11:28:23 +1000
Subject: [PATCH 021/184] split TextFlowDAOTest.canGetTextFlowsByStatus into
more atomic tests
---
.../java/org/zanata/dao/TextFlowDAOTest.java | 84 ++++++++++++++-----
1 file changed, 64 insertions(+), 20 deletions(-)
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index ab5fb456be..4e4ea60561 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -93,37 +93,79 @@ public void canGetTextFlowWithNullTarget() {
}
@Test
- public void canGetTextFlowsByStatus() {
- HLocale esLocale = getEm().find(HLocale.class, 5L);
+ public void canGetTextFlowsByStatusNotNew()
+ {
+ HLocale enUSLocale = getEm().find(HLocale.class, 4L);
+ // all 3 text flows are fuzzy for en-US in this document
+ DocumentId documentId2 = new DocumentId(2L, "");
+ List result = dao.getTextFlowByDocumentIdWithConstraints(documentId2, enUSLocale,
+ FilterConstraints.builder().keepAll().excludeNew().build(), 0, 10);
+
+ assertThat(result, Matchers.hasSize(3));
+ }
+
+ @Test
+ public void canGetTextFlowsByStatusNotFuzzy()
+ {
+ // frLocale new in this document
+ DocumentId documentId = new DocumentId(1L, "");
HLocale frLocale = getEm().find(HLocale.class, 6L);
- HLocale deLocale = getEm().find(HLocale.class, 3L);
+ FilterConstraints notFuzzy = FilterConstraints.builder().keepAll().excludeFuzzy().build();
- DocumentId documentId1 = new DocumentId(1L, ""); // esLocale fuzzy,
- // frLocale new, deLocale
- // approved
- List result = dao.getTextFlowByDocumentIdWithConstraints(documentId1, esLocale,
- FilterConstraints.builder().keepAll().excludeTranslated().excludeNew().build(), 0, 10);
+ List result = dao.getTextFlowByDocumentIdWithConstraints(documentId, frLocale,
+ notFuzzy, 0, 10);
assertThat(result, Matchers.hasSize(1));
+ }
- result = dao.getTextFlowByDocumentIdWithConstraints(documentId1, frLocale,
- FilterConstraints.builder().keepAll().excludeFuzzy().build(), 0, 10);
+ @Test
+ public void canGetTextFlowsByStatusNotTranslatedNotNew()
+ {
+ // esLocale fuzzy in this document
+ DocumentId documentId = new DocumentId(1L, "");
+ HLocale esLocale = getEm().find(HLocale.class, 5L);
+ FilterConstraints notNewOrTranslated = FilterConstraints.builder().keepAll().excludeTranslated().excludeNew().build();
+
+ List result = dao.getTextFlowByDocumentIdWithConstraints(documentId, esLocale,
+ notNewOrTranslated, 0, 10);
assertThat(result, Matchers.hasSize(1));
+ }
- result = dao.getTextFlowByDocumentIdWithConstraints(documentId1, deLocale,
- FilterConstraints.builder().keepAll().excludeFuzzy().excludeNew().build(), 0, 10);
+ @Test
+ public void canGetTextFlowsByStatusNotFuzzyNotNew()
+ {
+ // deLocale approved in this document
+ DocumentId documentId = new DocumentId(1L, "");
+ HLocale deLocale = getEm().find(HLocale.class, 3L);
+ FilterConstraints notNewOrFuzzy =
+ FilterConstraints.builder().keepAll().excludeFuzzy().excludeNew().build();
+
+ List result = dao.getTextFlowByDocumentIdWithConstraints(documentId, deLocale,
+ notNewOrFuzzy, 0, 10);
assertThat(result, Matchers.hasSize(1));
+ }
+ @Test
+ public void canGetTextFlowsByStatusNotFuzzyNotTranslated()
+ {
HLocale enUSLocale = getEm().find(HLocale.class, 4L);
- DocumentId documentId2 = new DocumentId(2L, ""); // all 3 text flows has
- // en-US fuzzy target
-
- result = dao.getTextFlowByDocumentIdWithConstraints(documentId2, enUSLocale,
- FilterConstraints.builder().keepAll().excludeTranslated().excludeFuzzy().build(), 0, 10);
+ // all 3 text flows are fuzzy for en-US in this document
+ DocumentId documentId2 = new DocumentId(2L, "");
+ FilterConstraints notFuzzyOrTranslated =
+ FilterConstraints.builder().keepAll().excludeTranslated().excludeFuzzy().build();
+ List result = dao.getTextFlowByDocumentIdWithConstraints(documentId2, enUSLocale,
+ notFuzzyOrTranslated, 0, 10);
assertThat(result, Matchers.empty());
+ }
- result = dao.getTextFlowByDocumentIdWithConstraints(documentId2, enUSLocale,
- FilterConstraints.builder().keepAll().excludeNew().build(), 0, 10);
- assertThat(result, Matchers.hasSize(3));
+ @Test
+ public void thisBreaksForSomeReason() {
+ // fails regardless of using different documentId, locale or constraints
+ DocumentId id = new DocumentId(1L, "");
+ HLocale locale = getEm().find(HLocale.class, 3L);
+ FilterConstraints constraints = FilterConstraints.builder().build();
+
+ dao.getTextFlowByDocumentIdWithConstraints(id, locale, constraints, 0, 10);
+ dao.getTextFlowByDocumentIdWithConstraints(id, locale, constraints, 0, 10);
}
@@ -222,6 +264,8 @@ public void testGetTextFlowByDocumentIdWithConstraint()
assertThat(result, Matchers.hasSize(1));
}
+ // What is this testing? I can't tell if it is ensuring that no exception is thrown,
+ // or if it is just half-written and useless.
@Test
public void queryTest1()
{
From af83b0e9be5a9241a041df2eef3f9bf3cff9fca6 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Mon, 8 Jul 2013 12:39:49 +1000
Subject: [PATCH 022/184] Work in progress: enhanced reviewer implementation:
https://bugzilla.redhat.com/show_bug.cgi?id=981067
---
zanata-war/src/main/resources/messages.properties | 2 +-
zanata-war/src/main/webapp/language/language.xhtml | 11 ++++-------
.../src/main/webapp/language/request_to_join.xhtml | 13 ++++++++++++-
3 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties
index b4b4834fd0..5b32c99ed7 100644
--- a/zanata-war/src/main/resources/messages.properties
+++ b/zanata-war/src/main/resources/messages.properties
@@ -400,7 +400,7 @@ jsf.Loading=Loading...
jsf.AlreadyInTeam=Already in Team
jsf.Reviewer=Reviewer
jsf.Translator=Translator
-
+jsf.JoinAs=I want to join '#{sendEmail.locale.localeId.id}' language team as :
#------ [home] > Help ------
diff --git a/zanata-war/src/main/webapp/language/language.xhtml b/zanata-war/src/main/webapp/language/language.xhtml
index e144700d9f..9ccf18358e 100644
--- a/zanata-war/src/main/webapp/language/language.xhtml
+++ b/zanata-war/src/main/webapp/language/language.xhtml
@@ -108,7 +108,7 @@
-
+
@@ -169,20 +169,17 @@
#{messages['jsf.Translator']}
-
-
+
#{messages['jsf.Reviewer']}
-
-
+
#{messages['jsf.Coordinator']}
-
-
+
diff --git a/zanata-war/src/main/webapp/language/request_to_join.xhtml b/zanata-war/src/main/webapp/language/request_to_join.xhtml
index 28124df285..8de875335c 100644
--- a/zanata-war/src/main/webapp/language/request_to_join.xhtml
+++ b/zanata-war/src/main/webapp/language/request_to_join.xhtml
@@ -42,7 +42,18 @@
#{messages['jsf.email.joinrequest.AdditionalInfoMessage']}
-
+
+ #{messages['jsf.JoinAs']}
+
+ #{messages['jsf.Translator']}
+
+
+
+ #{messages['jsf.Reviewer']}
+
+
+ #{messages['jsf.Coordinator']}
+
Date: Mon, 8 Jul 2013 13:30:50 +1000
Subject: [PATCH 023/184] Revert FilterConstraints includeStates(ActiveStates)
to old behaviour
Old behaviour was to flip all states to on in the case that they
were all off. The change should only be temporary since it is
surprising - some changes to the code for the editor are necessary
before this can be made more sensible.
---
.../java/org/zanata/search/FilterConstraints.java | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java b/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
index 9e53cfc2f2..8f52112a8f 100644
--- a/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
+++ b/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
@@ -142,7 +142,18 @@ public Builder checkInTarget(boolean check)
public Builder includeStates(ActiveStates states)
{
- this.states.fromStates(states);
+ //FIXME this behaviour is too surprising.
+ // It exists because the editor UI should show all states when either
+ // all or none of the states are checked. This logic should just happen
+ // in the editor backend *before* sending a request to the server.
+ if (states.hasNoStates())
+ {
+ this.states.allOn();
+ }
+ else
+ {
+ this.states.fromStates(states);
+ }
return this;
}
From 1cbcf3bc6cbc3dbbe66e37dd7607da8e4420e9a0 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Mon, 8 Jul 2013 13:58:29 +1000
Subject: [PATCH 024/184] disable mysterious breaking test in TextFlowDAOTest
---
zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index 4e4ea60561..456bf710ba 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -157,7 +157,7 @@ public void canGetTextFlowsByStatusNotFuzzyNotTranslated()
assertThat(result, Matchers.empty());
}
- @Test
+ @Test(enabled = false)
public void thisBreaksForSomeReason() {
// fails regardless of using different documentId, locale or constraints
DocumentId id = new DocumentId(1L, "");
From ba6eb0096e7f71ee9152165de9f8041a30cc99ca Mon Sep 17 00:00:00 2001
From: David Mason
Date: Mon, 8 Jul 2013 14:54:31 +1000
Subject: [PATCH 025/184] protect some wrapped builder calls from automatic
formatting
---
.../webtrans/server/rpc/GetProjectTransUnitListsHandler.java | 2 ++
.../webtrans/server/rpc/GetTransUnitsNavigationService.java | 2 ++
.../java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java | 2 ++
3 files changed, 6 insertions(+)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetProjectTransUnitListsHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetProjectTransUnitListsHandler.java
index 549176c1f1..22ac725a4f 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetProjectTransUnitListsHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetProjectTransUnitListsHandler.java
@@ -96,12 +96,14 @@ public GetProjectTransUnitListsResult execute(GetProjectTransUnitLists action, E
return new GetProjectTransUnitListsResult(action, docPaths, matchingTUs);
}
+ // @formatter:off
FilterConstraints filterConstraints = FilterConstraints.builder()
.filterBy(action.getSearchString())
.caseSensitive(action.isCaseSensitive())
.checkInSource(action.isSearchInSource())
.checkInTarget(action.isSearchInTarget())
.build();
+ // @formatter:on
List matchingFlows = textFlowSearchServiceImpl.findTextFlows(action.getWorkspaceId(), action.getDocumentPaths(), filterConstraints);
log.info("Returned {} results for search", matchingFlows.size());
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java
index f92cfb2608..5ef402be2b 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransUnitsNavigationService.java
@@ -53,11 +53,13 @@ public class GetTransUnitsNavigationService
protected GetTransUnitsNavigationResult getNavigationIndexes(GetTransUnitsNavigation action, HLocale hLocale)
{
+ // @formatter:off
FilterConstraints filterConstraints = FilterConstraints.builder()
.filterBy(action.getPhrase())
.checkInSource(true).checkInTarget(true)
.includeStates(action.getActiveStates())
.build();
+ // @formatter:on
List idIndexList = new ArrayList();
Map transIdStateMap = new HashMap();
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
index 16a477ac60..8d543385ba 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
@@ -33,6 +33,7 @@ private GetTransUnitList(GetTransUnitActionContext context)
offset = context.getOffset();
count = context.getCount();
phrase = context.getFindMessage();
+ // @formatter :off
filterStates = ActiveStates.builder()
.setNewOn(context.isFilterUntranslated())
.setFuzzyOn(context.isFilterNeedReview())
@@ -40,6 +41,7 @@ private GetTransUnitList(GetTransUnitActionContext context)
.setApprovedOn(context.isFilterApproved())
.setRejectedOn(context.isFilterRejected())
.build();
+ // @formatter :on
filterHasError = context.isFilterHasError();
targetTransUnitId = context.getTargetTransUnitId();
validationIds = context.getValidationIds();
From f6eda7ba4c17c442871a469148d702af47cf031a Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Mon, 8 Jul 2013 16:31:36 +1000
Subject: [PATCH 026/184] Implemented email request to join language team with
roles
---
.../org/zanata/action/LanguageJoinAction.java | 87 +++++++++++++++++++
.../java/org/zanata/service/EmailService.java | 2 +-
.../src/main/resources/messages.properties | 6 +-
...l => email_request_to_join_language.xhtml} | 27 +++++-
.../webapp/language/request_to_join.xhtml | 39 ++++-----
.../src/main/webapp/resources/css/zanata.css | 12 +++
6 files changed, 148 insertions(+), 25 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/action/LanguageJoinAction.java
rename zanata-war/src/main/webapp/WEB-INF/facelets/email/{email_request_to_join.xhtml => email_request_to_join_language.xhtml} (67%)
diff --git a/zanata-war/src/main/java/org/zanata/action/LanguageJoinAction.java b/zanata-war/src/main/java/org/zanata/action/LanguageJoinAction.java
new file mode 100644
index 0000000000..251e61697c
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/action/LanguageJoinAction.java
@@ -0,0 +1,87 @@
+/*
+ * 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.action;
+
+import java.io.Serializable;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import org.apache.commons.lang.StringUtils;
+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.util.ZanataMessages;
+
+/**
+ * @author Alex Eng aeng@redhat.com
+ */
+
+@Name("languageJoinAction")
+@Scope(ScopeType.PAGE)
+public class LanguageJoinAction implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ @In
+ private ZanataMessages zanataMessages;
+
+ private String roleMessage;
+
+ @Getter
+ @Setter
+ private boolean joinAsTranslator;
+
+ @Getter
+ @Setter
+ private boolean joinAsReviewer;
+
+ @Getter
+ @Setter
+ private boolean joinAsCoordinator;
+
+
+ public boolean hasRoleRequest()
+ {
+ return joinAsTranslator || joinAsReviewer || joinAsCoordinator;
+ }
+
+
+ public String getRoleMessage()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(zanataMessages.getMessage("jsf.email.joinrequest.Subject"));
+
+ if(joinAsTranslator || joinAsReviewer || joinAsCoordinator)
+ {
+ sb.append(" as");
+ sb.append( joinAsTranslator ? " (Translator) " : "");
+ sb.append( joinAsReviewer ? " (Reviewer) " : "");
+ sb.append( joinAsCoordinator ? " (Coordinator) " : "");
+ }
+ roleMessage = sb.toString();
+
+ return roleMessage;
+ }
+
+}
diff --git a/zanata-war/src/main/java/org/zanata/service/EmailService.java b/zanata-war/src/main/java/org/zanata/service/EmailService.java
index 21ff38f6d0..5b5eac8745 100644
--- a/zanata-war/src/main/java/org/zanata/service/EmailService.java
+++ b/zanata-war/src/main/java/org/zanata/service/EmailService.java
@@ -32,7 +32,7 @@ public interface EmailService
{
public static final String ADMIN_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_admin.xhtml";
public static final String COORDINATOR_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_coordinator.xhtml";
- public static final String REQUEST_TO_JOIN_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_to_join.xhtml";
+ public static final String REQUEST_TO_JOIN_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_to_join_language.xhtml";
public static final String REQUEST_TO_JOIN_GROUP_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_to_join_group.xhtml";
public static final String ACTIVATION_ACCOUNT_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/activation.xhtml";
/**
diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties
index 5b32c99ed7..41b00c9414 100644
--- a/zanata-war/src/main/resources/messages.properties
+++ b/zanata-war/src/main/resources/messages.properties
@@ -400,7 +400,7 @@ jsf.Loading=Loading...
jsf.AlreadyInTeam=Already in Team
jsf.Reviewer=Reviewer
jsf.Translator=Translator
-jsf.JoinAs=I want to join '#{sendEmail.locale.localeId.id}' language team as :
+jsf.JoinAs=Request to join '#{sendEmail.locale.localeId.id}' language team as :
#------ [home] > Help ------
@@ -794,9 +794,9 @@ jsf.email.coordinator.ReceivedReason=You are coordinator in '#{sendEmail.locale.
#------ request-to-join-language-team email ------
-jsf.email.joinrequest.UserRequestingToJoin=Zanata user '#{sendEmail.fromName}' with id '#{sendEmail.fromLoginName}' is requesting to join the #{sendEmail.locale.localeId.id} (#{sendEmail.locale.retrieveNativeName()}) Language Team.
+jsf.email.joinrequest.UserRequestingToJoin=Zanata user '#{sendEmail.fromName}' with id '#{sendEmail.fromLoginName}' is requesting to join the #{sendEmail.locale.localeId.id} (#{sendEmail.locale.retrieveNativeName()}) Language Team
jsf.email.joinrequest.AddUserInstructions=You can add #{sendEmail.fromName} to the #{sendEmail.locale.localeId.id} team as translator using the "#{messages['jsf.AddTeamMember']}" action on the language team page and searching for '#{sendEmail.fromLoginName}'.
-
+jsf.email.joinrequest.RoleRequest=with the following role(s):
#------ request-to-join-group email ------
jsf.email.group.maintainer.SentNotification=Your message has been sent to the #{versionGroupJoinAction.group.name} group maintainer
diff --git a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join.xhtml b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
similarity index 67%
rename from zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join.xhtml
rename to zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
index 87f5bd38dc..94f85fea92 100644
--- a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join.xhtml
+++ b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
@@ -15,7 +15,32 @@
#{messages['jsf.email.coordinator.DearCoordinator']}
- #{messages['jsf.email.joinrequest.UserRequestingToJoin']}
+ #{messages['jsf.email.joinrequest.UserRequestingToJoin']}
+
+
+ #{messages['jsf.email.joinrequest.RoleRequest']}
+
+
+
+ #{messages['jsf.Translator']}
+
+
+
+
+
+ #{messages['jsf.Reviewer']}
+
+
+
+
+
+ #{messages['jsf.Coordinator']}
+
+
+
+
+
+
#{messages['jsf.email.joinrequest.UserMessageIntro']}
diff --git a/zanata-war/src/main/webapp/language/request_to_join.xhtml b/zanata-war/src/main/webapp/language/request_to_join.xhtml
index 8de875335c..e833caa19e 100644
--- a/zanata-war/src/main/webapp/language/request_to_join.xhtml
+++ b/zanata-war/src/main/webapp/language/request_to_join.xhtml
@@ -13,10 +13,22 @@
#{messages['jsf.RequestToJoinLanguageTeamTitle']}
-
+
-
+
+ #{messages['jsf.JoinAs']}
+
+ #{messages['jsf.Translator']}
+
+
+ #{messages['jsf.Reviewer']}
+
+
+ #{messages['jsf.Coordinator']}
+
+
+
#{messages['jsf.email.From']}
#{messages['jsf.email.ReplyAddress']} #{messages['jsf.email.ReplyAddress.description']}
-
+
#{messages['jsf.email.Subject']}
-
+
- #{messages['jsf.AdditionalInfo']}
+ #{messages['jsf.AdditionalInfo']}
-
+
#{messages['jsf.email.joinrequest.AdditionalInfoMessage']}
-
- #{messages['jsf.JoinAs']}
-
- #{messages['jsf.Translator']}
-
-
-
- #{messages['jsf.Reviewer']}
-
-
- #{messages['jsf.Coordinator']}
-
-
+
Date: Mon, 8 Jul 2013 18:01:49 +1000
Subject: [PATCH 027/184] Remove 'has error' filter out of 'complete' filtering
option
---
.../webtrans/client/view/TransFilterView.java | 6 +++---
.../webtrans/client/view/TransFilterView.ui.xml | 15 ++++++++++-----
2 files changed, 13 insertions(+), 8 deletions(-)
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 c017da0eb3..dafd8695a5 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
@@ -206,9 +206,9 @@ public void onFilterOptionsChanged(ValueChangeEvent event)
public void toggleCompleteChk()
{
- if(translatedChk.getValue() == approvedChk.getValue() && approvedChk.getValue() == hasErrorChk.getValue())
+ if(translatedChk.getValue() == approvedChk.getValue())
{
- if(hasErrorChk.getValue() == true)
+ if(approvedChk.getValue() == true)
{
completeChk.setValue(true);
}
@@ -258,7 +258,6 @@ public void onCompleteChkChanged(ValueChangeEvent event)
{
translatedChk.setValue(event.getValue());
approvedChk.setValue(event.getValue());
- hasErrorChk.setValue(event.getValue());
onFilterOptionsChanged(event);
}
@@ -270,5 +269,6 @@ public void setOptionsState(ConfigurationState state)
untranslatedChk.setValue(state.isFilterByUntranslated());
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 088887d814..befb8ae31a 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
@@ -43,8 +43,12 @@
.hasError {
border-left:3px solid #FF4500;
+ padding-right:5px;
+ opacity:0.6;
+ transition: .3s;
+ display:inline !important;
}
-
+
.filterListToggle {
font-size:16px;
cursor:pointer;
@@ -109,7 +113,7 @@
-moz-transition: .3s;
}
- .filterList li span:hover {
+ .filterList li span:hover, .hasError:hover {
background-color: #fff;
opacity: 1;
}
@@ -166,11 +170,12 @@
Approved
-
- Has warning
-
+
+
+ Has warning
+
\ No newline at end of file
From eb25d69be61ebb32a856ad50af6cd2117fabee65 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Tue, 9 Jul 2013 09:49:18 +1000
Subject: [PATCH 028/184] Work in progress: enhanced reviewer implementation:
https://bugzilla.redhat.com/show_bug.cgi?id=981067
---
.../org/zanata/action/LanguageJoinAction.java | 87 ----------
.../action/LanguageJoinUpdateRoleAction.java | 149 ++++++++++++++++++
.../org/zanata/action/LanguageTeamAction.java | 4 +-
.../org/zanata/action/SendEmailAction.java | 6 +-
.../java/org/zanata/service/EmailService.java | 3 +-
.../zanata/service/LanguageTeamService.java | 2 +-
.../service/impl/LanguageTeamServiceImpl.java | 2 +-
.../src/main/resources/messages.properties | 7 +-
...equest_to_join_update_role_language.xhtml} | 11 +-
zanata-war/src/main/webapp/WEB-INF/pages.xml | 12 +-
.../src/main/webapp/WEB-INF/urlrewrite.xml | 4 +-
.../src/main/webapp/language/language.xhtml | 15 +-
...html => request_to_join_update_role.xhtml} | 14 +-
13 files changed, 195 insertions(+), 121 deletions(-)
delete mode 100644 zanata-war/src/main/java/org/zanata/action/LanguageJoinAction.java
create mode 100644 zanata-war/src/main/java/org/zanata/action/LanguageJoinUpdateRoleAction.java
rename zanata-war/src/main/webapp/WEB-INF/facelets/email/{email_request_to_join_language.xhtml => email_request_to_join_update_role_language.xhtml} (82%)
rename zanata-war/src/main/webapp/language/{request_to_join.xhtml => request_to_join_update_role.xhtml} (87%)
diff --git a/zanata-war/src/main/java/org/zanata/action/LanguageJoinAction.java b/zanata-war/src/main/java/org/zanata/action/LanguageJoinAction.java
deleted file mode 100644
index 251e61697c..0000000000
--- a/zanata-war/src/main/java/org/zanata/action/LanguageJoinAction.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.action;
-
-import java.io.Serializable;
-
-import lombok.Getter;
-import lombok.Setter;
-
-import org.apache.commons.lang.StringUtils;
-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.util.ZanataMessages;
-
-/**
- * @author Alex Eng aeng@redhat.com
- */
-
-@Name("languageJoinAction")
-@Scope(ScopeType.PAGE)
-public class LanguageJoinAction implements Serializable
-{
- private static final long serialVersionUID = 1L;
-
- @In
- private ZanataMessages zanataMessages;
-
- private String roleMessage;
-
- @Getter
- @Setter
- private boolean joinAsTranslator;
-
- @Getter
- @Setter
- private boolean joinAsReviewer;
-
- @Getter
- @Setter
- private boolean joinAsCoordinator;
-
-
- public boolean hasRoleRequest()
- {
- return joinAsTranslator || joinAsReviewer || joinAsCoordinator;
- }
-
-
- public String getRoleMessage()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.append(zanataMessages.getMessage("jsf.email.joinrequest.Subject"));
-
- if(joinAsTranslator || joinAsReviewer || joinAsCoordinator)
- {
- sb.append(" as");
- sb.append( joinAsTranslator ? " (Translator) " : "");
- sb.append( joinAsReviewer ? " (Reviewer) " : "");
- sb.append( joinAsCoordinator ? " (Coordinator) " : "");
- }
- roleMessage = sb.toString();
-
- return roleMessage;
- }
-
-}
diff --git a/zanata-war/src/main/java/org/zanata/action/LanguageJoinUpdateRoleAction.java b/zanata-war/src/main/java/org/zanata/action/LanguageJoinUpdateRoleAction.java
new file mode 100644
index 0000000000..94e7a566d1
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/action/LanguageJoinUpdateRoleAction.java
@@ -0,0 +1,149 @@
+/*
+ * 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.action;
+
+import java.io.Serializable;
+
+import lombok.Getter;
+import lombok.Setter;
+
+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.model.HAccount;
+import org.zanata.util.ZanataMessages;
+
+/**
+ * @author Alex Eng aeng@redhat.com
+ */
+
+@Name("languageJoinUpdateRoleAction")
+@Scope(ScopeType.PAGE)
+public class LanguageJoinUpdateRoleAction implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ private static final String JOIN_REQUEST = "join";
+
+ private static final String ROLE_REQUEST = "role";
+
+
+ @In
+ private ZanataMessages zanataMessages;
+
+ @In(required = false, value = JpaIdentityStore.AUTHENTICATED_USER)
+ private HAccount authenticatedAccount;
+
+ @Getter
+ @Setter
+ private boolean requestAsTranslator;
+
+ @Getter
+ @Setter
+ private boolean requestAsReviewer;
+
+ @Getter
+ @Setter
+ private boolean requestAsCoordinator;
+
+ @Getter
+ @Setter
+ private String requestType;
+
+ @Setter
+ private String language;
+
+ private String roleMessage;
+
+ private String title;
+
+ private String subject;
+
+
+ public boolean hasRoleRequest()
+ {
+ return requestAsTranslator || requestAsReviewer || requestAsCoordinator;
+ }
+
+
+ public String getSubject()
+ {
+ if(requestType.equals(JOIN_REQUEST))
+ {
+ subject = zanataMessages.getMessage("jsf.email.joinrequest.Subject");
+ }
+ else
+ {
+ subject = zanataMessages.getMessage("jsf.email.rolerequest.Subject");
+ }
+ return subject;
+ }
+
+ public String getTitle()
+ {
+ if(requestType.equals(JOIN_REQUEST))
+ {
+ title = zanataMessages.getMessage("jsf.RequestToJoinLanguageTeamTitle");
+ }
+ else
+ {
+ title = zanataMessages.getMessage("jsf.RequestRoleLanguageTeamTitle");
+ }
+ return title;
+ }
+
+ public String getRoleMessage()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(zanataMessages.getMessage("jsf.email.joinrequest.Subject"));
+
+ if(requestAsTranslator || requestAsReviewer || requestAsCoordinator)
+ {
+ sb.append(" as");
+ if(requestAsTranslator)
+ {
+ sb.append(" (");
+ sb.append(zanataMessages.getMessage("jsf.Translator"));
+ sb.append(" )");
+ }
+
+ if(requestAsReviewer)
+ {
+ sb.append(" (");
+ sb.append(zanataMessages.getMessage("jsf.Reviewer"));
+ sb.append(" )");
+ }
+
+ if(requestAsCoordinator)
+ {
+ sb.append(" (");
+ sb.append(zanataMessages.getMessage("jsf.Coordinator"));
+ sb.append(" )");
+ }
+ }
+ roleMessage = sb.toString();
+ return roleMessage;
+ }
+
+}
diff --git a/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java b/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java
index 63c3471bfb..fa94863cda 100644
--- a/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java
@@ -171,7 +171,7 @@ public void joinTribe()
}
try
{
- languageTeamServiceImpl.joinOrUpdateLanguageTeam(this.language, authenticatedAccount.getPerson().getId(), true, true, true);
+ languageTeamServiceImpl.joinOrUpdateRoleInLanguageTeam(this.language, authenticatedAccount.getPerson().getId(), true, true, true);
Events.instance().raiseEvent("personJoinedTribe");
log.info("{0} joined tribe {1}", authenticatedAccount.getUsername(), this.language);
// FIXME use localizable string
@@ -245,7 +245,7 @@ public void saveTeamTranslator( HLocaleMember member )
private void addTeamMember( final Long personId, boolean isTranslator, boolean isReviewer, boolean isCoordinator )
{
- this.languageTeamServiceImpl.joinOrUpdateLanguageTeam(this.language, personId, isTranslator, isReviewer, isCoordinator);
+ this.languageTeamServiceImpl.joinOrUpdateRoleInLanguageTeam(this.language, personId, isTranslator, isReviewer, isCoordinator);
}
@Restrict("#{s:hasPermission(languageTeamAction.locale, 'manage-language-team')}")
diff --git a/zanata-war/src/main/java/org/zanata/action/SendEmailAction.java b/zanata-war/src/main/java/org/zanata/action/SendEmailAction.java
index 8e42fc1086..dfe29f5424 100644
--- a/zanata-war/src/main/java/org/zanata/action/SendEmailAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/SendEmailAction.java
@@ -60,7 +60,7 @@ public class SendEmailAction implements Serializable
private static final String EMAIL_TYPE_CONTACT_ADMIN = "contact_admin";
private static final String EMAIL_TYPE_CONTACT_COORDINATOR = "contact_coordinator";
- private static final String EMAIL_TYPE_REQUEST_TO_JOIN = "request_to_join_language_team";
+ private static final String EMAIL_TYPE_REQUEST_TO_JOIN_UPDATE_ROLE = "request_to_join_update_role_language";
private static final String EMAIL_TYPE_REQUEST_TO_JOIN_GROUP = "request_to_join_group";
@In
@@ -224,9 +224,9 @@ else if (emailType.equals(EMAIL_TYPE_CONTACT_COORDINATOR))
FacesMessages.instance().add(msg);
return "success";
}
- else if (emailType.equals(EMAIL_TYPE_REQUEST_TO_JOIN))
+ else if (emailType.equals(EMAIL_TYPE_REQUEST_TO_JOIN_UPDATE_ROLE))
{
- String msg = emailServiceImpl.sendToLanguageCoordinators(EmailService.REQUEST_TO_JOIN_EMAIL_TEMPLATE, getCoordinators(), fromName, fromLoginName, replyEmail, subject, message, language);
+ String msg = emailServiceImpl.sendToLanguageCoordinators(EmailService.REQUEST_TO_JOIN_UPDATE_ROLE_EMAIL_TEMPLATE, getCoordinators(), fromName, fromLoginName, replyEmail, subject, message, language);
FacesMessages.instance().add(msg);
return "success";
}
diff --git a/zanata-war/src/main/java/org/zanata/service/EmailService.java b/zanata-war/src/main/java/org/zanata/service/EmailService.java
index 5b5eac8745..c90e3a0c25 100644
--- a/zanata-war/src/main/java/org/zanata/service/EmailService.java
+++ b/zanata-war/src/main/java/org/zanata/service/EmailService.java
@@ -21,7 +21,6 @@
package org.zanata.service;
import java.util.List;
-import java.util.Set;
import org.zanata.model.HPerson;
@@ -32,7 +31,7 @@ public interface EmailService
{
public static final String ADMIN_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_admin.xhtml";
public static final String COORDINATOR_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_coordinator.xhtml";
- public static final String REQUEST_TO_JOIN_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_to_join_language.xhtml";
+ public static final String REQUEST_TO_JOIN_UPDATE_ROLE_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_to_join_update_role_language.xhtml";
public static final String REQUEST_TO_JOIN_GROUP_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_to_join_group.xhtml";
public static final String ACTIVATION_ACCOUNT_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/activation.xhtml";
/**
diff --git a/zanata-war/src/main/java/org/zanata/service/LanguageTeamService.java b/zanata-war/src/main/java/org/zanata/service/LanguageTeamService.java
index 0484325f7e..bcc943d86d 100644
--- a/zanata-war/src/main/java/org/zanata/service/LanguageTeamService.java
+++ b/zanata-war/src/main/java/org/zanata/service/LanguageTeamService.java
@@ -12,7 +12,7 @@ public interface LanguageTeamService
List getLanguageMemberships(String userName);
- void joinOrUpdateLanguageTeam(String locale, Long personId, boolean isTranslator, boolean isReviewer, boolean isCoordinator) throws ZanataServiceException;
+ void joinOrUpdateRoleInLanguageTeam(String locale, Long personId, boolean isTranslator, boolean isReviewer, boolean isCoordinator) throws ZanataServiceException;
boolean leaveLanguageTeam(String locale, Long personId);
}
diff --git a/zanata-war/src/main/java/org/zanata/service/impl/LanguageTeamServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/LanguageTeamServiceImpl.java
index 51dfba622a..2da39ee612 100644
--- a/zanata-war/src/main/java/org/zanata/service/impl/LanguageTeamServiceImpl.java
+++ b/zanata-war/src/main/java/org/zanata/service/impl/LanguageTeamServiceImpl.java
@@ -51,7 +51,7 @@ public List getLanguageMemberships(String userName)
return personDAO.getLanguageMembershipByUsername(userName);
}
- public void joinOrUpdateLanguageTeam(String locale, Long personId, boolean isTranslator, boolean isReviewer, boolean isCoordinator) throws ZanataServiceException
+ public void joinOrUpdateRoleInLanguageTeam(String locale, Long personId, boolean isTranslator, boolean isReviewer, boolean isCoordinator) throws ZanataServiceException
{
LocaleId localeId = new LocaleId(locale);
HPerson currentPerson = personDAO.findById(personId, false);
diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties
index 41b00c9414..b18c538313 100644
--- a/zanata-war/src/main/resources/messages.properties
+++ b/zanata-war/src/main/resources/messages.properties
@@ -393,6 +393,7 @@ jsf.Coordinator=Coordinator
jsf.JoinLanguageTeam=Join Language Team
jsf.LeaveLanguageTeam=Leave Language Team
jsf.RequestToJoinLanguageTeam=Request To Join Team
+jsf.RequestUpdateRoleLanguageTeam=Request Role(s)
jsf.contactLanguageTeamCoordinator=Contact Team Coordinators
jsf.AddTeamMember=Add Team Translator
jsf.FindUsersToAdd=Find Users To Add
@@ -400,7 +401,7 @@ jsf.Loading=Loading...
jsf.AlreadyInTeam=Already in Team
jsf.Reviewer=Reviewer
jsf.Translator=Translator
-jsf.JoinAs=Request to join '#{sendEmail.locale.localeId.id}' language team as :
+jsf.RequestRoleAs=Request role in '#{sendEmail.locale.localeId.id}' language team as :
#------ [home] > Help ------
@@ -723,8 +724,10 @@ jsf.AlreadyInGroup=Already in Group
jsf.email.joingrouprequest.AdditionalInfoMessage=To ensure your request is processed without delay, please provide any additional information that will help the group maintainers to process your request.
!FIXME make key similar to related keys
jsf.RequestToJoinLanguageTeamTitle=Request To Join '#{sendEmail.locale.localeId.id}' Language Team
+jsf.RequestRoleLanguageTeamTitle=Request Role(s) in '#{sendEmail.locale.localeId.id}' Language Team
jsf.email.joinrequest.Subject=User '#{sendEmail.fromLoginName}' wants to join the '#{sendEmail.locale.localeId.id}' language team
-jsf.email.joinrequest.AdditionalInfoMessage=To ensure your request is processed without delay, please provide any additional information that will help the team coordinators identify you and process your request.
+jsf.email.rolerequest.Subject=User '#{sendEmail.fromLoginName}' request for additional role(s) in '#{sendEmail.locale.localeId.id}' language team
+jsf.email.AdditionalInfoMessage=To ensure your request is processed without delay, please provide any additional information that will help the team coordinators identify you and process your request.
jsf.email.ContactCoordinatorTitle=Contact '#{sendEmail.locale.retrieveDisplayName()}' Coordinator
jsf.contactLanguageTeamCoordinatorForLocale=Contact '#{sendEmail.locale.localeId.id} (#{sendEmail.locale.retrieveNativeName()})' Language Team Coordinators
diff --git a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_update_role_language.xhtml
similarity index 82%
rename from zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
rename to zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_update_role_language.xhtml
index 94f85fea92..a481cb9f39 100644
--- a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
+++ b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_update_role_language.xhtml
@@ -11,28 +11,29 @@
-
+
#{messages['jsf.email.coordinator.DearCoordinator']}
+
#{messages['jsf.email.joinrequest.UserRequestingToJoin']}
-
+
#{messages['jsf.email.joinrequest.RoleRequest']}
-
+
#{messages['jsf.Translator']}
-
+
#{messages['jsf.Reviewer']}
-
+
#{messages['jsf.Coordinator']}
diff --git a/zanata-war/src/main/webapp/WEB-INF/pages.xml b/zanata-war/src/main/webapp/WEB-INF/pages.xml
index 9c21c4590c..632ea3effe 100644
--- a/zanata-war/src/main/webapp/WEB-INF/pages.xml
+++ b/zanata-war/src/main/webapp/WEB-INF/pages.xml
@@ -865,13 +865,15 @@
-
+
+
+
-
+
@@ -880,7 +882,7 @@
-
+
@@ -891,9 +893,7 @@
-
-
-
+
diff --git a/zanata-war/src/main/webapp/WEB-INF/urlrewrite.xml b/zanata-war/src/main/webapp/WEB-INF/urlrewrite.xml
index 1578f6b310..5300e45a63 100644
--- a/zanata-war/src/main/webapp/WEB-INF/urlrewrite.xml
+++ b/zanata-war/src/main/webapp/WEB-INF/urlrewrite.xml
@@ -39,7 +39,7 @@
^/language/join/(.+)$
- /language/request_to_join.seam\?emailType=request_to_join_language_team&id=$1
+ /language/request_to_join_update_role.seam\?emailType=request_to_join_update_role_language&id=$1
@@ -312,7 +312,7 @@
$1/language/contact/$2
- ^(/.+)?/language/request_to_join.seam\?emailType=request_to_join_language_team&id=(.+)$
+ ^(/.+)?/language/request_to_join_update_role.seam\?emailType=request_to_join_update_role_language&id=(.+)$
$1/language/join/$2
diff --git a/zanata-war/src/main/webapp/language/language.xhtml b/zanata-war/src/main/webapp/language/language.xhtml
index 9ccf18358e..51c37a7190 100644
--- a/zanata-war/src/main/webapp/language/language.xhtml
+++ b/zanata-war/src/main/webapp/language/language.xhtml
@@ -105,8 +105,16 @@
#{messages['jsf.LeaveLanguageTeam']}
-
-
+
+
+
+
+
+
+
+
@@ -119,7 +127,7 @@
-
+
#{messages['jsf.FindUsersToAdd']}
@@ -184,6 +192,7 @@
+
diff --git a/zanata-war/src/main/webapp/language/request_to_join.xhtml b/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml
similarity index 87%
rename from zanata-war/src/main/webapp/language/request_to_join.xhtml
rename to zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml
index e833caa19e..8d0ce5d596 100644
--- a/zanata-war/src/main/webapp/language/request_to_join.xhtml
+++ b/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml
@@ -11,20 +11,20 @@
- #{messages['jsf.RequestToJoinLanguageTeamTitle']}
+ #{languageJoinUpdateRoleAction.title}
- #{messages['jsf.JoinAs']}
-
+ #{messages['jsf.RequestRoleAs']}
+
#{messages['jsf.Translator']}
-
+
#{messages['jsf.Reviewer']}
-
+
#{messages['jsf.Coordinator']}
@@ -42,7 +42,7 @@
#{messages['jsf.email.Subject']}
-
+
@@ -50,7 +50,7 @@
- #{messages['jsf.email.joinrequest.AdditionalInfoMessage']}
+ #{messages['jsf.email.AdditionalInfoMessage']}
From d06f5984eaa1a956f60726aefe29e670dde50dc2 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 9 Jul 2013 10:01:11 +1000
Subject: [PATCH 029/184] clear database before starting TextFlowDAOTest
---
zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index 456bf710ba..2b9616fead 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -31,6 +31,7 @@ public class TextFlowDAOTest extends ZanataDbunitJpaTest
@Override
protected void prepareDBUnitOperations()
{
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/ClearAllTables.dbunit.xml", DatabaseOperation.DELETE_ALL));
beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/ProjectsData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/TextFlowTestData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/LocalesData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
From 77c573b08fdf29408be5249fa5234caafa5a05cb Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Wed, 10 Jul 2013 09:11:18 +1000
Subject: [PATCH 030/184] Implemented email request to join language team with
roles
---
.../action/LanguageJoinUpdateRoleAction.java | 90 ++++++++++---------
.../org/zanata/action/SendEmailAction.java | 13 ++-
.../java/org/zanata/service/EmailService.java | 3 +-
.../src/main/resources/messages.properties | 16 ++--
.../src/main/resources/messages_ja.properties | 2 +-
.../src/main/resources/messages_uk.properties | 2 +-
.../resources/messages_zh_TW_Hant.properties | 2 +-
.../email/email_request_role_language.xhtml | 57 ++++++++++++
.../email/email_request_to_join_group.xhtml | 2 +-
...l => email_request_to_join_language.xhtml} | 9 +-
zanata-war/src/main/webapp/WEB-INF/pages.xml | 2 +-
.../src/main/webapp/language/language.xhtml | 6 +-
.../request_to_join_update_role.xhtml | 19 ++--
13 files changed, 150 insertions(+), 73 deletions(-)
create mode 100644 zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml
rename zanata-war/src/main/webapp/WEB-INF/facelets/email/{email_request_to_join_update_role_language.xhtml => email_request_to_join_language.xhtml} (93%)
diff --git a/zanata-war/src/main/java/org/zanata/action/LanguageJoinUpdateRoleAction.java b/zanata-war/src/main/java/org/zanata/action/LanguageJoinUpdateRoleAction.java
index 94e7a566d1..3a700d379c 100644
--- a/zanata-war/src/main/java/org/zanata/action/LanguageJoinUpdateRoleAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/LanguageJoinUpdateRoleAction.java
@@ -30,7 +30,11 @@
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.security.management.JpaIdentityStore;
+import org.zanata.annotation.CachedMethodResult;
+import org.zanata.common.LocaleId;
+import org.zanata.dao.LocaleMemberDAO;
import org.zanata.model.HAccount;
+import org.zanata.model.HLocaleMember;
import org.zanata.util.ZanataMessages;
/**
@@ -43,52 +47,51 @@ public class LanguageJoinUpdateRoleAction implements Serializable
{
private static final long serialVersionUID = 1L;
- private static final String JOIN_REQUEST = "join";
-
- private static final String ROLE_REQUEST = "role";
+ private static final String EMAIL_TYPE_REQUEST_JOIN = "request_join_language";
+ private static final String EMAIL_TYPE_REQUEST_ROLE = "request_role_language";
@In
private ZanataMessages zanataMessages;
+ @In
+ private LocaleMemberDAO localeMemberDAO;
+
@In(required = false, value = JpaIdentityStore.AUTHENTICATED_USER)
private HAccount authenticatedAccount;
@Getter
@Setter
- private boolean requestAsTranslator;
+ private Boolean requestAsTranslator;
@Getter
@Setter
- private boolean requestAsReviewer;
+ private Boolean requestAsReviewer;
@Getter
@Setter
- private boolean requestAsCoordinator;
+ private Boolean requestAsCoordinator;
@Getter
@Setter
- private String requestType;
+ private String emailType;
@Setter
+ @Getter
private String language;
- private String roleMessage;
-
private String title;
private String subject;
-
public boolean hasRoleRequest()
{
return requestAsTranslator || requestAsReviewer || requestAsCoordinator;
}
-
public String getSubject()
{
- if(requestType.equals(JOIN_REQUEST))
+ if(emailType.equals(EMAIL_TYPE_REQUEST_JOIN))
{
subject = zanataMessages.getMessage("jsf.email.joinrequest.Subject");
}
@@ -101,7 +104,7 @@ public String getSubject()
public String getTitle()
{
- if(requestType.equals(JOIN_REQUEST))
+ if(emailType.equals(EMAIL_TYPE_REQUEST_JOIN))
{
title = zanataMessages.getMessage("jsf.RequestToJoinLanguageTeamTitle");
}
@@ -112,38 +115,39 @@ public String getTitle()
return title;
}
- public String getRoleMessage()
+ public boolean isTranslator()
{
- StringBuilder sb = new StringBuilder();
-
- sb.append(zanataMessages.getMessage("jsf.email.joinrequest.Subject"));
-
- if(requestAsTranslator || requestAsReviewer || requestAsCoordinator)
+ HLocaleMember member = getLocaleMember();
+ if(member != null)
{
- sb.append(" as");
- if(requestAsTranslator)
- {
- sb.append(" (");
- sb.append(zanataMessages.getMessage("jsf.Translator"));
- sb.append(" )");
- }
-
- if(requestAsReviewer)
- {
- sb.append(" (");
- sb.append(zanataMessages.getMessage("jsf.Reviewer"));
- sb.append(" )");
- }
-
- if(requestAsCoordinator)
- {
- sb.append(" (");
- sb.append(zanataMessages.getMessage("jsf.Coordinator"));
- sb.append(" )");
- }
+ return getLocaleMember().isTranslator();
}
- roleMessage = sb.toString();
- return roleMessage;
+ return false;
+ }
+
+ public boolean isReviewer()
+ {
+ HLocaleMember member = getLocaleMember();
+ if(member != null)
+ {
+ return getLocaleMember().isReviewer();
+ }
+ return false;
+ }
+
+ public boolean isCoordinator()
+ {
+ HLocaleMember member = getLocaleMember();
+ if(member != null)
+ {
+ return getLocaleMember().isCoordinator();
+ }
+ return false;
+ }
+
+ @CachedMethodResult
+ private HLocaleMember getLocaleMember()
+ {
+ return localeMemberDAO.findByPersonAndLocale(authenticatedAccount.getPerson().getId(), new LocaleId(language));
}
-
}
diff --git a/zanata-war/src/main/java/org/zanata/action/SendEmailAction.java b/zanata-war/src/main/java/org/zanata/action/SendEmailAction.java
index dfe29f5424..b596d9cbbf 100644
--- a/zanata-war/src/main/java/org/zanata/action/SendEmailAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/SendEmailAction.java
@@ -60,7 +60,8 @@ public class SendEmailAction implements Serializable
private static final String EMAIL_TYPE_CONTACT_ADMIN = "contact_admin";
private static final String EMAIL_TYPE_CONTACT_COORDINATOR = "contact_coordinator";
- private static final String EMAIL_TYPE_REQUEST_TO_JOIN_UPDATE_ROLE = "request_to_join_update_role_language";
+ private static final String EMAIL_TYPE_REQUEST_JOIN = "request_join_language";
+ private static final String EMAIL_TYPE_REQUEST_ROLE = "request_role_language";
private static final String EMAIL_TYPE_REQUEST_TO_JOIN_GROUP = "request_to_join_group";
@In
@@ -224,9 +225,15 @@ else if (emailType.equals(EMAIL_TYPE_CONTACT_COORDINATOR))
FacesMessages.instance().add(msg);
return "success";
}
- else if (emailType.equals(EMAIL_TYPE_REQUEST_TO_JOIN_UPDATE_ROLE))
+ else if (emailType.equals(EMAIL_TYPE_REQUEST_JOIN))
{
- String msg = emailServiceImpl.sendToLanguageCoordinators(EmailService.REQUEST_TO_JOIN_UPDATE_ROLE_EMAIL_TEMPLATE, getCoordinators(), fromName, fromLoginName, replyEmail, subject, message, language);
+ String msg = emailServiceImpl.sendToLanguageCoordinators(EmailService.REQUEST_TO_JOIN_EMAIL_TEMPLATE, getCoordinators(), fromName, fromLoginName, replyEmail, subject, message, language);
+ FacesMessages.instance().add(msg);
+ return "success";
+ }
+ else if (emailType.equals(EMAIL_TYPE_REQUEST_ROLE))
+ {
+ String msg = emailServiceImpl.sendToLanguageCoordinators(EmailService.REQUEST_ROLE_EMAIL_TEMPLATE, getCoordinators(), fromName, fromLoginName, replyEmail, subject, message, language);
FacesMessages.instance().add(msg);
return "success";
}
diff --git a/zanata-war/src/main/java/org/zanata/service/EmailService.java b/zanata-war/src/main/java/org/zanata/service/EmailService.java
index c90e3a0c25..9ca005f7de 100644
--- a/zanata-war/src/main/java/org/zanata/service/EmailService.java
+++ b/zanata-war/src/main/java/org/zanata/service/EmailService.java
@@ -31,7 +31,8 @@ public interface EmailService
{
public static final String ADMIN_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_admin.xhtml";
public static final String COORDINATOR_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_coordinator.xhtml";
- public static final String REQUEST_TO_JOIN_UPDATE_ROLE_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_to_join_update_role_language.xhtml";
+ public static final String REQUEST_TO_JOIN_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_to_join_language.xhtml";
+ public static final String REQUEST_ROLE_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_role_language.xhtml";
public static final String REQUEST_TO_JOIN_GROUP_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/email_request_to_join_group.xhtml";
public static final String ACTIVATION_ACCOUNT_EMAIL_TEMPLATE = "/WEB-INF/facelets/email/activation.xhtml";
/**
diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties
index b18c538313..61078aa3c8 100644
--- a/zanata-war/src/main/resources/messages.properties
+++ b/zanata-war/src/main/resources/messages.properties
@@ -393,7 +393,7 @@ jsf.Coordinator=Coordinator
jsf.JoinLanguageTeam=Join Language Team
jsf.LeaveLanguageTeam=Leave Language Team
jsf.RequestToJoinLanguageTeam=Request To Join Team
-jsf.RequestUpdateRoleLanguageTeam=Request Role(s)
+jsf.RequestUpdateRoleLanguageTeam=Request role
jsf.contactLanguageTeamCoordinator=Contact Team Coordinators
jsf.AddTeamMember=Add Team Translator
jsf.FindUsersToAdd=Find Users To Add
@@ -724,9 +724,9 @@ jsf.AlreadyInGroup=Already in Group
jsf.email.joingrouprequest.AdditionalInfoMessage=To ensure your request is processed without delay, please provide any additional information that will help the group maintainers to process your request.
!FIXME make key similar to related keys
jsf.RequestToJoinLanguageTeamTitle=Request To Join '#{sendEmail.locale.localeId.id}' Language Team
-jsf.RequestRoleLanguageTeamTitle=Request Role(s) in '#{sendEmail.locale.localeId.id}' Language Team
+jsf.RequestRoleLanguageTeamTitle=Request Role in '#{sendEmail.locale.localeId.id}' Language Team
jsf.email.joinrequest.Subject=User '#{sendEmail.fromLoginName}' wants to join the '#{sendEmail.locale.localeId.id}' language team
-jsf.email.rolerequest.Subject=User '#{sendEmail.fromLoginName}' request for additional role(s) in '#{sendEmail.locale.localeId.id}' language team
+jsf.email.rolerequest.Subject=User '#{sendEmail.fromLoginName}' request for additional role in '#{sendEmail.locale.localeId.id}' language team
jsf.email.AdditionalInfoMessage=To ensure your request is processed without delay, please provide any additional information that will help the team coordinators identify you and process your request.
jsf.email.ContactCoordinatorTitle=Contact '#{sendEmail.locale.retrieveDisplayName()}' Coordinator
jsf.contactLanguageTeamCoordinatorForLocale=Contact '#{sendEmail.locale.localeId.id} (#{sendEmail.locale.retrieveNativeName()})' Language Team Coordinators
@@ -796,16 +796,20 @@ jsf.email.coordinator.ResponseInstructions=You can click the link below to go di
jsf.email.coordinator.ReceivedReason=You are coordinator in '#{sendEmail.locale.retrieveNativeName()}' language team
-#------ request-to-join-language-team email ------
+#------ request-to-join-language email ------
jsf.email.joinrequest.UserRequestingToJoin=Zanata user '#{sendEmail.fromName}' with id '#{sendEmail.fromLoginName}' is requesting to join the #{sendEmail.locale.localeId.id} (#{sendEmail.locale.retrieveNativeName()}) Language Team
jsf.email.joinrequest.AddUserInstructions=You can add #{sendEmail.fromName} to the #{sendEmail.locale.localeId.id} team as translator using the "#{messages['jsf.AddTeamMember']}" action on the language team page and searching for '#{sendEmail.fromLoginName}'.
-jsf.email.joinrequest.RoleRequest=with the following role(s):
+jsf.email.joinrequest.RoleRequest=with the following role:
+
+#------ request-role-language email ------
+jsf.email.rolerequest.UserRequestingRole=Zanata user '#{sendEmail.fromName}' with id '#{sendEmail.fromLoginName}' is requesting the following role in #{sendEmail.locale.localeId.id} (#{sendEmail.locale.retrieveNativeName()}) Language Team:
+jsf.email.rolerequest.AddUserInstructions=You can assign #{sendEmail.fromName} to requested role in #{sendEmail.locale.localeId.id} team on the language team page.
#------ request-to-join-group email ------
jsf.email.group.maintainer.SentNotification=Your message has been sent to the #{versionGroupJoinAction.group.name} group maintainer
jsf.email.maintainer.DearMaintainer=Dear Group Maintainer,
jsf.email.joingrouprequest.RequestingToJoinGroup=Zanata user '#{sendEmail.fromName}' with id '#{sendEmail.fromLoginName}' is requesting his/her project(s) to be added to group '#{versionGroupJoinAction.group.name}'.
-jsf.email.joinrequest.UserMessageIntro=#{sendEmail.fromName} has included the following message with their request:
+jsf.email.UserMessageIntro=#{sendEmail.fromName} has included the following message with their request:
jsf.email.joingrouprequest.ResponseInstructions=Click the link below to go act on the request. Please reply to #{sendEmail.fromName} at #{sendEmail.replyEmail} when you have finished processing their request.
jsf.email.group.maintainer.ReceivedReason=You are maintainer in group '#{versionGroupJoinAction.group.name}'
diff --git a/zanata-war/src/main/resources/messages_ja.properties b/zanata-war/src/main/resources/messages_ja.properties
index f19e991490..aa8515003f 100644
--- a/zanata-war/src/main/resources/messages_ja.properties
+++ b/zanata-war/src/main/resources/messages_ja.properties
@@ -576,7 +576,7 @@ jsf.email.joinrequest.AddUserInstructions=\u8A00\u8A9E\u30C1\u30FC\u30E0\u30DA\u
jsf.email.group.maintainer.SentNotification=\u30E6\u30FC\u30B6\u30FC\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u304C \#{versionGroupJoinAction.group.name} \u30B0\u30EB\u30FC\u30D7\u306E\u30E1\u30F3\u30C6\u30CA\u30FC\u306B\u9001\u4FE1\u3055\u308C\u307E\u3057\u305F
jsf.email.maintainer.DearMaintainer=\u30B0\u30EB\u30FC\u30D7\u30E1\u30F3\u30C6\u30CA\u30FC\u306E\u65B9\u3078
jsf.email.joingrouprequest.RequestingToJoinGroup=\ id \u304C '\#{sendEmail.fromLoginName}' \u306E Zanata \u30E6\u30FC\u30B6\u30FC '\#{sendEmail.fromName}' \u3055\u3093\u304C\u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E \u30B0\u30EB\u30FC\u30D7 '\#{versionGroupJoinAction.group.name}' \u3078\u306E\u53C2\u52A0\u3092\u30EA\u30AF\u30A8\u30B9\u30C8\u3057\u3066\u3044\u307E\u3059\u3002
-jsf.email.joinrequest.UserMessageIntro=\#{sendEmail.fromName} \u3055\u3093\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u306B\u306F\u6B21\u306E\u3088\u3046\u306A\u30E1\u30C3\u30BB\u30FC\u30B8\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\:
+jsf.email.UserMessageIntro=\#{sendEmail.fromName} \u3055\u3093\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u306B\u306F\u6B21\u306E\u3088\u3046\u306A\u30E1\u30C3\u30BB\u30FC\u30B8\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\:
jsf.email.joingrouprequest.ResponseInstructions=\u4EE5\u4E0B\u306E\u30EA\u30F3\u30AF\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u51E6\u7406\u3057\u307E\u3059\u3002 \u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u51E6\u7406\u3092\u5B8C\u4E86\u3057\u305F\u3089 \#{sendEmail.fromName} \u3055\u3093\u5B9B\u3066\u306E\u8FD4\u4FE1\u30E1\u30FC\u30EB\u3092 \#{sendEmail.replyEmail} \u306B\u9001\u4FE1\u3057\u3066\u304F\u3060\u3055\u3044\u3002
jsf.email.group.maintainer.ReceivedReason=\u30E6\u30FC\u30B6\u30FC\u306F\u30B0\u30EB\u30FC\u30D7 '\#{versionGroupJoinAction.group.name}' \u306E\u30E1\u30F3\u30C6\u30CA\u30FC\u3067\u3059
up=\u2191
diff --git a/zanata-war/src/main/resources/messages_uk.properties b/zanata-war/src/main/resources/messages_uk.properties
index b56590b226..4d06658eea 100644
--- a/zanata-war/src/main/resources/messages_uk.properties
+++ b/zanata-war/src/main/resources/messages_uk.properties
@@ -675,7 +675,7 @@ jsf.email.coordinator.ReceivedReason=\u0412\u0438 \u043A\u043E\u043E\u0440\u0434
jsf.email.joinrequest.UserRequestingToJoin=\u041A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447 Zanata '\#{sendEmail.fromName}' \u0437 ID '\#{sendEmail.fromLoginName}' \u043D\u0430\u0434\u0456\u0441\u043B\u0430\u0432 \u0437\u0430\u043F\u0438\u0442 \u043D\u0430 \u0432\u0441\u0442\u0443\u043F \u0434\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0438 \u043F\u0435\u0440\u0435\u043A\u043B\u0430\u0434\u0430\u0447\u0456\u0432 \#{sendEmail.locale.localeId.id} (\#{sendEmail.locale.retrieveNativeName()}).
jsf.email.group.maintainer.SentNotification=\u0412\u0430\u0448\u0435 \u043F\u043E\u0432\u0456\u0434\u043E\u043C\u043B\u0435\u043D\u043D\u044F \u043D\u0430\u0434\u0456\u0441\u043B\u0430\u043D\u043E \u0434\u043E \u043A\u043E\u043E\u0440\u0434\u0438\u043D\u0430\u0442\u043E\u0440\u0430 \u0433\u0440\u0443\u043F\u0438 \#{versionGroupJoinAction.group.name}
jsf.email.maintainer.DearMaintainer=\u0428\u0430\u043D\u043E\u0432\u043D\u0438\u0439 \u043A\u043E\u043E\u0440\u0434\u0438\u043D\u043E\u0440 \u0433\u0440\u0443\u043F\u0438,
-jsf.email.joinrequest.UserMessageIntro=\#{sendEmail.fromName} \u0432\u043A\u043B\u044E\u0447\u0438\u0432 \u043D\u0430\u0441\u0442\u0443\u043F\u043D\u0435 \u043F\u043E\u0432\u0456\u0434\u043E\u043C\u043B\u0435\u043D\u043D\u044F \u0434\u043E \u0441\u0432\u043E\u0433\u043E \u0437\u0430\u043F\u0438\u0442\u0443\:
+jsf.email.UserMessageIntro=\#{sendEmail.fromName} \u0432\u043A\u043B\u044E\u0447\u0438\u0432 \u043D\u0430\u0441\u0442\u0443\u043F\u043D\u0435 \u043F\u043E\u0432\u0456\u0434\u043E\u043C\u043B\u0435\u043D\u043D\u044F \u0434\u043E \u0441\u0432\u043E\u0433\u043E \u0437\u0430\u043F\u0438\u0442\u0443\:
jsf.email.group.maintainer.ReceivedReason=\u0412\u0438 \u043A\u043E\u043E\u0440\u0434\u0438\u043D\u0430\u0442\u043E\u0440 \u0433\u0440\u0443\u043F\u0438 '\#{versionGroupJoinAction.group.name}'
# translation auto-copied from project Zanata, version jsf-pages, document main/resources/messages, author Maks
up=\u2191
diff --git a/zanata-war/src/main/resources/messages_zh_TW_Hant.properties b/zanata-war/src/main/resources/messages_zh_TW_Hant.properties
index fccef3c2bf..2a5e5a09a8 100644
--- a/zanata-war/src/main/resources/messages_zh_TW_Hant.properties
+++ b/zanata-war/src/main/resources/messages_zh_TW_Hant.properties
@@ -563,7 +563,7 @@ jsf.email.joinrequest.AddUserInstructions=\u60A8\u53EF\u85C9\u7531\u4F7F\u7528\u
jsf.email.group.maintainer.SentNotification=\u60A8\u7684\u8A0A\u606F\u5DF2\u50B3\u9001\u7D66 \#{versionGroupJoinAction.group.name} \u7FA4\u7D44\u7684\u7DAD\u8B77\u8005
jsf.email.maintainer.DearMaintainer=\u89AA\u611B\u7684\u7FA4\u7D44\u7DAD\u8B77\u8005\uFF0C
jsf.email.joingrouprequest.RequestingToJoinGroup=Zanata \u4F7F\u7528\u8005 '\#{sendEmail.fromName}'\uFF0CId '\#{sendEmail.fromLoginName}' \u8981\u6C42\u5C07\u4ED6/\u5979\u7684\u5C08\u6848\u52A0\u5165 '\#{versionGroupJoinAction.group.name}' \u7FA4\u7D44\u4E2D\u3002
-jsf.email.joinrequest.UserMessageIntro=\#{sendEmail.fromName} \u5728\u5176\u8ACB\u6C42\u4E2D\u5305\u542B\u4E86\u4E0B\u5217\u8A0A\u606F\uFF1A
+jsf.email.UserMessageIntro=\#{sendEmail.fromName} \u5728\u5176\u8ACB\u6C42\u4E2D\u5305\u542B\u4E86\u4E0B\u5217\u8A0A\u606F\uFF1A
jsf.email.joingrouprequest.ResponseInstructions=\u8ACB\u9EDE\u9078\u4EE5\u4E0B\u9023\u7D50\u4EE5\u8655\u7406\u8ACB\u6C42\u3002\u7576\u60A8\u5B8C\u6210\u8655\u7406\u8ACB\u6C42\u5F8C\uFF0C\u65BC \#{sendEmail.replyEmail} \u56DE\u8986 \#{sendEmail.fromName}\u3002
jsf.email.group.maintainer.ReceivedReason=\u60A8\u662F '\#{versionGroupJoinAction.group.name}' \u7FA4\u7D44\u7684\u7DAD\u8B77\u8005
up=\u2191
diff --git a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml
new file mode 100644
index 0000000000..0b0c1455fc
--- /dev/null
+++ b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+ #{messages['jsf.email.coordinator.DearCoordinator']}
+
+
+ #{messages['jsf.email.rolerequest.UserRequestingRole']}
+
+
+
+ #{messages['jsf.Translator']}
+
+
+
+
+
+ #{messages['jsf.Reviewer']}
+
+
+
+
+
+ #{messages['jsf.Coordinator']}
+
+
+
+
+
+
+ #{messages['jsf.email.UserMessageIntro']}
+
+
+
+
+ #{messages['jsf.email.rolerequest.AddUserInstructions']}
+ #{messages['jsf.email.coordinator.ResponseInstructions']}
+
+
+ #{applicationConfiguration.serverPath}/language/view/#{sendEmail.locale.localeId.id}
+
+
+
+
+
diff --git a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_group.xhtml b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_group.xhtml
index a24777faf4..ea7f1dc10e 100644
--- a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_group.xhtml
+++ b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_group.xhtml
@@ -17,7 +17,7 @@
#{messages['jsf.email.maintainer.DearMaintainer']}
#{messages['jsf.email.joingrouprequest.RequestingToJoinGroup']}
- #{messages['jsf.email.joinrequest.UserMessageIntro']}
+ #{messages['jsf.email.UserMessageIntro']}
diff --git a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_update_role_language.xhtml b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
similarity index 93%
rename from zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_update_role_language.xhtml
rename to zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
index a481cb9f39..6a25ed2a5f 100644
--- a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_update_role_language.xhtml
+++ b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
@@ -15,9 +15,8 @@
#{messages['jsf.email.coordinator.DearCoordinator']}
-
- #{messages['jsf.email.joinrequest.UserRequestingToJoin']}
-
+
+ #{messages['jsf.email.joinrequest.UserRequestingToJoin']}
#{messages['jsf.email.joinrequest.RoleRequest']}
-
+
- #{messages['jsf.email.joinrequest.UserMessageIntro']}
+ #{messages['jsf.email.UserMessageIntro']}
diff --git a/zanata-war/src/main/webapp/WEB-INF/pages.xml b/zanata-war/src/main/webapp/WEB-INF/pages.xml
index 632ea3effe..81fa26b6ad 100644
--- a/zanata-war/src/main/webapp/WEB-INF/pages.xml
+++ b/zanata-war/src/main/webapp/WEB-INF/pages.xml
@@ -867,7 +867,7 @@
-
+
diff --git a/zanata-war/src/main/webapp/language/language.xhtml b/zanata-war/src/main/webapp/language/language.xhtml
index 51c37a7190..abc2f3e001 100644
--- a/zanata-war/src/main/webapp/language/language.xhtml
+++ b/zanata-war/src/main/webapp/language/language.xhtml
@@ -107,14 +107,12 @@
-
-
+
-
-
+
diff --git a/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml b/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml
index 8d0ce5d596..4af227d45f 100644
--- a/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml
+++ b/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml
@@ -18,14 +18,21 @@
#{messages['jsf.RequestRoleAs']}
-
- #{messages['jsf.Translator']}
+
+
+
+ #{messages['jsf.Translator']}
+
-
- #{messages['jsf.Reviewer']}
+
+
+ #{messages['jsf.Reviewer']}
+
-
- #{messages['jsf.Coordinator']}
+
+
+ #{messages['jsf.Coordinator']}
+
From 0bad9feb50c94fe490cecb4c909b104875c57b3d Mon Sep 17 00:00:00 2001
From: Damian Jansen
Date: Fri, 5 Jul 2013 11:54:46 +1000
Subject: [PATCH 031/184] User Registration tests
Currently, successful registration testing is blocked by Captcha validation.
Includes register page, and testcases for field validation on usernames and
email RFC2822 compliance.
Basic validation for password matching and Captcha rejection.
---
.../main/java/org/zanata/page/HomePage.java | 9 +
.../org/zanata/page/account/RegisterPage.java | 127 ++++++++
.../main/java/org/zanata/util/RFC2822.java | 277 ++++++++++++++++++
.../feature/account/RegisterDetailedTest.java | 260 ++++++++++++++++
.../src/main/webapp/account/register.xhtml | 2 +-
5 files changed, 674 insertions(+), 1 deletion(-)
create mode 100644 functional-test/src/main/java/org/zanata/page/account/RegisterPage.java
create mode 100644 functional-test/src/main/java/org/zanata/util/RFC2822.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
diff --git a/functional-test/src/main/java/org/zanata/page/HomePage.java b/functional-test/src/main/java/org/zanata/page/HomePage.java
index 1ac0cb2b6c..b58226ae46 100644
--- a/functional-test/src/main/java/org/zanata/page/HomePage.java
+++ b/functional-test/src/main/java/org/zanata/page/HomePage.java
@@ -26,6 +26,7 @@
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
+import org.zanata.page.account.RegisterPage;
import org.zanata.page.administration.AdministrationPage;
import org.zanata.page.groups.VersionGroupsPage;
import org.zanata.page.projects.ProjectsPage;
@@ -108,4 +109,12 @@ public AdministrationPage goToAdministration()
adminLink.click();
return new AdministrationPage(getDriver());
}
+
+ public RegisterPage goToRegistration()
+ {
+ getDriver().findElement(By.linkText("More")).click();
+ WebElement registerLink = getDriver().findElement(By.id("Register"));
+ registerLink.click();
+ return new RegisterPage(getDriver());
+ }
}
diff --git a/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java b/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java
new file mode 100644
index 0000000000..bc61baa12c
--- /dev/null
+++ b/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java
@@ -0,0 +1,127 @@
+package org.zanata.page.account;
+
+
+import java.util.Map;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.zanata.page.AbstractPage;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@Slf4j
+public class RegisterPage extends AbstractPage
+{
+
+ @FindBy(id = "registerForm:nameField:name")
+ private WebElement nameField;
+
+ @FindBy(id = "registerForm:emailField:email")
+ private WebElement emailField;
+
+ @FindBy(id = "registerForm:usernameField:username")
+ private WebElement usernameField;
+
+ @FindBy(id = "registerForm:passwordField:password")
+ private WebElement passwordField;
+
+ @FindBy(id = "registerForm:passwordConfirmField:passwordConfirm")
+ private WebElement confirmPasswordField;
+
+ @FindBy(id = "registerForm:captcha:verifyCaptcha")
+ private WebElement captchaField;
+
+ @FindBy(id = "registerForm:agreedToTerms:agreedToTerms")
+ private WebElement termsCheckbox;
+
+ @FindBy(id = "registerForm:registerButton")
+ private WebElement registerButton;
+
+ public RegisterPage(WebDriver driver)
+ {
+ super(driver);
+ }
+
+ public RegisterPage enterName(String name)
+ {
+ nameField.sendKeys(name);
+ return new RegisterPage(getDriver());
+ }
+
+ public RegisterPage enterUserName(String userName)
+ {
+ usernameField.sendKeys(userName);
+ return new RegisterPage(getDriver());
+ }
+
+ public RegisterPage enterEmail(String email)
+ {
+ emailField.sendKeys(email);
+ return new RegisterPage(getDriver());
+ }
+
+ public RegisterPage enterPassword(String password)
+ {
+ passwordField.sendKeys(password);
+ return new RegisterPage(getDriver());
+ }
+
+ public RegisterPage enterConfirmPassword(String confirmPassword)
+ {
+ confirmPasswordField.sendKeys(confirmPassword);
+ return new RegisterPage(getDriver());
+ }
+
+ public RegisterPage enterCaptcha(String captcha)
+ {
+ captchaField.sendKeys(captcha);
+ return new RegisterPage(getDriver());
+ }
+
+ public RegisterPage clickTerms()
+ {
+ termsCheckbox.click();
+ return new RegisterPage(getDriver());
+ }
+
+ public AbstractPage register()
+ {
+ registerButton.click();
+ return new AbstractPage(getDriver());
+ }
+
+ public RegisterPage registerFailure()
+ {
+ registerButton.click();
+ return new RegisterPage(getDriver());
+ }
+
+ public RegisterPage clearFields()
+ {
+ nameField.clear();
+ emailField.clear();
+ usernameField.clear();
+ passwordField.clear();
+ confirmPasswordField.clear();
+ captchaField.clear();
+ return new RegisterPage(getDriver());
+ }
+
+ /*
+ Pass in a map of strings, to be entered into the registration fields.
+ Fields: name, email, username, password, confirmpassword, captcha
+ */
+ public RegisterPage setFields(Map fields)
+ {
+ clearFields();
+ enterName(fields.get("name"));
+ enterEmail(fields.get("email"));
+ enterUserName(fields.get("username"));
+ enterPassword(fields.get("password"));
+ enterConfirmPassword(fields.get("confirmpassword"));
+ enterCaptcha(fields.get("captcha"));
+ return new RegisterPage(getDriver());
+ }
+}
diff --git a/functional-test/src/main/java/org/zanata/util/RFC2822.java b/functional-test/src/main/java/org/zanata/util/RFC2822.java
new file mode 100644
index 0000000000..df61e4c886
--- /dev/null
+++ b/functional-test/src/main/java/org/zanata/util/RFC2822.java
@@ -0,0 +1,277 @@
+package org.zanata.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+public class RFC2822 {
+
+ /*
+ * Definitions
+ * localpart: the section of an address preceding the @ symbol
+ * domain: the section of an address following the @ symbol
+ * label: section of domain between the @ symbol or period and the next period or end e.g example in me@example.com
+ * quote / quoting: a section of the localpart contained within quotation marks
+ *
+ * BUG982048
+ * This defect is an list of all items that, valid or invalid, are not correctly recognised by the email validation
+ * in Zanata.
+ *
+ * Untested:
+ * RFC2822, section 3.4.1
+ * The contents of a bracketed domain can have a \ precede a character to escape it,
+ * and the following character must not be 10 (LF) or 13 (CR).
+ * This allows spaces in the domain as long as they are escaped.
+ *
+ * RFC 2821, section 4.5.3.1
+ * The maximum length of a "useful" email address is 255 characters.
+ *
+ * RFC 3696
+ * The maximum allowable length of an email address is 320 characters.
+ */
+
+ public static Map invalidEmailAddresses()
+ {
+ Map invalidEmailAddresses = new HashMap();
+
+ /*
+ * RFC 2822, section 3.4.1
+ * Email addresses consist of a local part, the "@" symbol, and the domain.
+ */
+ invalidEmailAddresses.put("3.4.1 Plain address", "plainaddress");
+ invalidEmailAddresses.put("3.4.1 Missing @", "email.example.com");
+ invalidEmailAddresses.put("3.4.1 Missing localpart", "@example.com");
+ invalidEmailAddresses.put("3.4.1 Missing domain", "email@");
+ invalidEmailAddresses.put("3.4.1 Two @ sign", "email@example@example.com");
+
+ /*
+ * RFC 2822, section 3.4.1
+ * No periods can start or end the local part.
+ * Two periods together is invalid.
+ */
+ invalidEmailAddresses.put("3.4.1 Leading dot", ".email@example.com");
+ invalidEmailAddresses.put("3.4.1 Trailing dot", "email.@example.com");
+ invalidEmailAddresses.put("3.4.1 Multiple dots", "email..email@example.com");
+
+ /*
+ * RFC 2822, section 2.2
+ * All email addresses are in 7-bit US ASCII.
+ */
+ // BUG982048invalidEmailAddresses.put("3.4.1 Non unicode characters", "あいうえお@example.com");
+
+ /*
+ * RFC 2822, section 3.4.1
+ * Unquoted local parts can consist of TEXT
+ * TEXT can contain:
+ * alphabetic
+ * numeric
+ * and symbols !#$%'*+-/=?^_`{|}~
+ */
+ invalidEmailAddresses.put("3.4.1 Invalid unquoted character", "test,user@example.com");
+ invalidEmailAddresses.put("3.4.1 Invalid unquoted character", "test(user@example.com");
+ invalidEmailAddresses.put("3.4.1 Invalid unquoted character", "test)user@example.com");
+
+ /*
+ * RFC 2822, section 3.4.1
+ * The quoted local part starts with a quotation mark, ends with a quotation mark.
+ */
+ invalidEmailAddresses.put("3.4.1 Invalid quoting", "test\"user@example.com");
+
+ /*
+ * RFC 2822, section 4.4
+ * If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
+ * or quoted chunks separated by periods
+ */
+ invalidEmailAddresses.put("3.4.1 Invalid quoting", "\"test\"user@example.com");
+ invalidEmailAddresses.put("4.4 Invalid quoting", "\"test\"quote\"user@example.com");
+
+ /*
+ * RFC 2822, section 3.4.1
+ * The contents of a quoted local part can not contain characters:
+ * 9 (TAB)
+ * 10 (LF)
+ * 13 (CR)
+ * 32 (space)
+ * 34 (")
+ * 91-94 ([, \, ], ^)
+ */
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test,user\"@example.com");
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test\\user\"@example.com");
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test[user\"@example.com");
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test]user\"@example.com");
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test^user\"@example.com");
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test user\"@example.com");
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test\"user\"@example.com");
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "test.\"".concat("\t").concat("\".user@example.com"));
+
+ /*
+ * RFC 2822, section 3.4.1
+ * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
+ */
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "test.\"\\".concat("\r").concat("\".user@example.com"));
+ invalidEmailAddresses.put("3.4.1 Invalid quoted character", "test.\"\\".concat("\n").concat("\".user@example.com"));
+
+ /*
+ * RFC 1035, section 2.3.4
+ * A plain domain consists of labels separated with periods. No period can start or end a domain name.
+ * No two periods in succession can be in a domain name.
+ */
+ invalidEmailAddresses.put("RFC1035-2.3.4 Trailing dot in domain", "email@example.com.");
+ invalidEmailAddresses.put("RFC1035-2.3.4 Leading dot in domain", "email@.example.com");
+ invalidEmailAddresses.put("RFC1035-2.3.4 Multiple dots in domain", "email@example..com");
+
+ /*
+ * RFC 2822, section 3.4.1
+ * Bracketed domains must:
+ * start with [, end with ]
+ * not contain characters 9 (TAB), 10 (LF), 13 (CR), 32 (space), 91-94 ([, \, ], ^)
+ */
+ invalidEmailAddresses.put("3.4.1 Incorrectly quoted domain", "email@[example].com");
+ invalidEmailAddresses.put("3.4.1 Incorrectly quoted domain", "email@[ex^ample.com]");
+ invalidEmailAddresses.put("3.4.1 Incorrectly quoted domain", "email@[exa\\mple].com");
+
+ /*
+ * RFC 1035, section 2.3.4
+ * The maximum length of a label is 63 characters.
+ */
+ // BUG982048 invalidEmailAddresses.put("RFC1035-2.3.4 Domain label too long",
+ // "email@IJUr9P6Y7Fx7rFy4sziQDT0qvSC7XKK6jrD0CNC41jorAKgFYIXLTN5ITJLohy58.com");
+
+ /*
+ * RFC 1035, section 2.3.4
+ * A label may contain hyphens, but no two hyphens in a row.
+ * A label must not start nor end with a hyphen.
+ */
+ // BUG982048 invalidEmailAddresses.put("2.3.4 Leading dash in domain", "email@-example.com");
+ // BUG982048 invalidEmailAddresses.put("2.3.4 Trailing dash in domain", "email@example-.com");
+ // BUG982048 invalidEmailAddresses.put("2.3.4 Multiple dashes in domain", "email@exa--mple.com");
+ invalidEmailAddresses.put("2.3.4 Leading dash in bracketed domain", "email@[-example.com]");
+ invalidEmailAddresses.put("2.3.4 Trailing dash in bracketed domain", "email@[example.com-]");
+ invalidEmailAddresses.put("2.3.4 Multiple dashes in bracketed domain", "email@[exa--mple.com]");
+
+ /*
+ * The contents of a bracketed domain can have a \ precede a character to escape it, and the following character
+ * must not be 10 (LF) or 13 (CR).
+ */
+ invalidEmailAddresses.put("3.4.1 Invalid bracketed domain", "test@[\\".concat("\r").concat("example.com]"));
+ invalidEmailAddresses.put("3.4.1 Invalid bracketed domain", "test@[\\".concat("\n").concat("example.com]"));
+
+ /*
+ * RFC 2821, section 4.5.3.1
+ * The maximum length of the local part is 64 characters.
+ */
+ invalidEmailAddresses.put("RFC2821-4.5.3.1 Max localpart length is 64",
+ "emailuhpealgyxntsh5upl5gqn5a4ruqs7mw6wz21j6dn72amzwozqlyua4jx16rd@example.com");
+
+ /*
+ * RFC 3696, section 2
+ * The top level domain must be all alphabetic.
+ */
+ invalidEmailAddresses.put("RFC3696-2 Encoded html", "Joe Smith ");
+ invalidEmailAddresses.put("RFC3696-2 Following text", "email@example.com (Joe Smith)");
+ // BUG982048 invalidEmailAddresses.put("RFC3696-2 Invalid IP", "email@111.222.333.44444");
+
+ /*
+ * RFC 2821, section 4.5.3.1
+ * The maximum length of a "useful" email address is 255 characters.
+ */
+ /*
+ * BUG982048
+ invalidEmailAddresses.put("4.5.3.1 Max email length is 255",
+ "email@"+
+ "Hk3yhCtbBRw3wCT76tL1ryAdfrIaaDszHqvZqnNrZPlNn3Wd7u."+
+ "RfpxrueSghp9dkGTGwT9s0fyJL850Sned72RD3Mm5PpEh6QJwQ."+
+ "3CeXyEHQEhXNOQdWhYVjGBLzlHz1sJfi4lfn7ighLXcxa5cMAK."+
+ "jFXsG8BVsvkODKktTXJ70bQmDWtWQzuh3oz4twumVArDGEbzS1."+
+ "slyaBcQqVgUdqXTBdbMY7YJxZwrzZQBBGjCl4e.com");
+ */
+ return invalidEmailAddresses;
+ }
+
+ /*
+ * An map of valid emails conforming to RFC2822
+ */
+ public static Map validEmailAddresses()
+ {
+ Map validEmailAddresses = new HashMap();
+
+ /*
+ * RFC 2822, section 3.4.1
+ * Email addresses consist of a local part, the "@" symbol, and the domain.
+ */
+ validEmailAddresses.put("3.4.1 Basic email", "email@example.com");
+
+ /*
+ * RFC 2822, sections 3.4.1 and 4.4
+ * The local part can be unquoted, quoted in its entirety, or quoted on a per-label basis.
+ * The quoted local part starts with a quotation mark, ends with a quotation mark.
+ */
+ // BUG982048 validEmailAddresses.put("3.4.1 Basic quoted email", "\"email\"@example.com");
+
+ /*
+ * RFC 2822, section 3.4.1
+ * TEXT can contain alphabetic, numeric, and these symbols: !#$%'*+-/=?^_`{|}~
+ */
+ validEmailAddresses.put("3.4.1 Allowed special characters in localpart", "email.!#$%'*+-/=?^_`{|}~.dot@example.com");
+
+ /*
+ RFC 2822, section 4.4
+ If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
+ or quoted chunks separated by periods.
+ */
+ // BUG982048 validEmailAddresses.put("4.4 Quoted label with surrounding labels", "dot.\"email\".dot@example.com");
+ // BUG982048 validEmailAddresses.put("4.4 Localpart with empty quote", "dot.\"\".dot@example.com");
+
+ /*
+ * RFC 2822, section 3.4.1
+ * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
+ * This supersedes the previous rule, allowing spaces and quotation marks in the email address as long as they
+ * are escaped.
+ */
+ // BUG982048 validEmailAddresses.put("3.4.1 Quoted email with escaped special characters", "email.\"(),:;<>\\@\\[\\]\\\\\"@example.com");
+ // BUG982048 validEmailAddresses.put("3.4.1 Quoted email with escaped quotes", "email.\"\\\"\"@example.com");
+ // BUG982048 validEmailAddresses.put("3.4.1 Quoted email with space character", "\"special\\ email\"@example.com");
+
+ /*
+ * RFC 2822, section 3.4.1
+ * The domain can be bracketed or plain.
+ */
+ // BUG982048 validEmailAddresses.put("3.4.1 Email with bracketed domain", "email@[example.com]");
+ // BUG982048 validEmailAddresses.put("3.4.1 Bracketed IPv6 domain", "email@[123.45.67.89]");
+ // BUG982048 validEmailAddresses.put("3.4.1 Bracketed IPv6 domain", "email@[IPv6:2001:2d12:c4fe:5afe::1]");
+
+ /*
+ * RFC 1035, section 2.3.4
+ * A plain domain consists of labels separated with periods. No period can start or end a domain name.
+ */
+ validEmailAddresses.put("RFC1035-2.3.4 Localpart with multiple labels", "another.email@example.com");
+ validEmailAddresses.put("RFC1035-2.3.4 Domain with multiple labels", "email@another.example.com");
+
+ /*
+ * RFC 1035, section 2.3.4
+ * The maximum length of a label is 63 characters.
+ */
+ validEmailAddresses.put("RFC1035-2.3.4 Domain label of 63 characters",
+ "email@B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8.com");
+ validEmailAddresses.put("RFC1035-2.3.4 Localpart label of 63 characters",
+ "B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8@example.com");
+
+ /*
+ * RFC 1035, section 2.3.4
+ * A label may contain hyphens, but no two hyphens in a row.
+ */
+ validEmailAddresses.put("RFC1035-2.3.4 Hyphenated domain label", "email@another-example.com");
+ validEmailAddresses.put("RFC1035-2.3.4 Hyphenated localpart label", "my-email@example.com");
+
+ /*
+ * RFC 2821, section 4.5.3.1
+ * The maximum length of the local part is 64 characters.
+ */
+ validEmailAddresses.put("RFC1035-2.3.4 Localpart length of 64 characters",
+ "B3NQyUsDdzODMoymfDdifn6Wztx2wrivm.80LEngHGl182frm6ifCPyv5SntbDg8@example.com");
+
+ return validEmailAddresses;
+ }
+}
\ No newline at end of file
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
new file mode 100644
index 0000000000..2b03712090
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
@@ -0,0 +1,260 @@
+/*
+ * 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.feature.account;
+
+import org.hamcrest.Matchers;
+import org.junit.*;
+import org.zanata.page.HomePage;
+import org.zanata.page.account.RegisterPage;
+import org.zanata.util.ResetDatabaseRule;
+import org.zanata.util.RFC2822;
+import org.zanata.workflow.AbstractWebWorkFlow;
+
+import java.util.*;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@Slf4j
+public class RegisterDetailedTest
+{
+ @ClassRule
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule(ResetDatabaseRule.Config.WithData, ResetDatabaseRule.Config.NoResetAfter);
+
+ Map fields;
+ private HomePage homePage;
+
+ @Before
+ public void before()
+ {
+ // fields contains a set of data that can be successfully registered
+ fields = new HashMap();
+
+ // Conflicting fields - must be set for each test function to avoid "not available" errors
+ fields.put("email", "test@test.com");
+ fields.put("username", "testusername");
+
+ fields.put("name", "test");
+ fields.put("password", "testpassword");
+ fields.put("confirmpassword", "testpassword");
+ fields.put("captcha", "555"); // TODO: Expect captcha error, fix
+ homePage = new AbstractWebWorkFlow().goToHome();
+ }
+
+ @Test
+ @Ignore("Captcha prevents test completion")
+ public void registerSuccessful()
+ {
+ RegisterPage registerPage = homePage.goToRegistration();
+ registerPage = registerPage.setFields(fields);
+ assertThat("No errors are shown", registerPage.getErrors().size(), Matchers.equalTo(0));
+ registerPage.register();
+ }
+
+ @Test
+ public void usernameLengthValidation()
+ {
+ String errorMsg = "size must be between 3 and 20";
+ fields.put("email", "length.test@test.com");
+ RegisterPage registerPage = homePage.goToRegistration();
+
+ fields.put("username", "bo");
+ registerPage = registerPage.setFields(fields);
+ assertThat("Size errors are shown for string too short", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+
+ fields.put("username", "testusername");
+ registerPage = registerPage.setFields(fields);
+ assertThat("Size errors are not shown", registerPage.getErrors(), Matchers.not(Matchers.hasItem(errorMsg)));
+
+ fields.put("username", "12345678901234567890a");
+ registerPage = registerPage.setFields(fields);
+ assertThat("Size errors are shown for string too long", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+ }
+
+ @Test
+ public void usernameCharacterValidation()
+ {
+ String errorMsg = "lowercase letters and digits (regex \"^[a-z\\d_]{3,20}$\")";
+ fields.put("email", "character.test@example.com");
+ for (Map.Entry entry : usernameCharacterValidationData().entrySet())
+ {
+ log.info("Test " + entry.getKey() + ":" + entry.getValue());
+ fields.put("username", entry.getValue());
+ RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ assertThat("Validation errors are shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+ }
+ }
+
+ @Test
+ @Ignore("Captcha prevents test completion")
+ public void usernamePreExisting()
+ {
+ String errorMsg = "This username is not available";
+ fields.put("email", "exists.test@test.com");
+ fields.put("username", "alreadyexists");
+ RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ registerPage.register();
+
+ fields.put("email", "exists2.test@test.com");
+ registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ assertThat("Username not available message is shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+ }
+
+ @Test
+ public void emailValidation()
+ {
+ String errorMsg = "not a well-formed email address";
+ fields.put("username", "emailvalidation");
+ for (Map.Entry entry : RFC2822.invalidEmailAddresses().entrySet())
+ {
+ log.info("Test " + entry.getKey() + ":" + entry.getValue());
+ fields.put("email", entry.getValue());
+ RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ assertThat("Email validation errors are shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+ }
+ }
+
+ @Test
+ public void validEmailAcceptance()
+ {
+ String errorMsg = "not a well-formed email address";
+ fields.put("username", "emailvalidation");
+ for (Map.Entry entry : RFC2822.validEmailAddresses().entrySet())
+ {
+ log.info("Test " + entry.getKey() + ":" + entry.getValue());
+ fields.put("email", entry.getValue());
+ RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ assertThat("Email validation errors are not shown", registerPage.getErrors(),
+ Matchers.not(Matchers.hasItem(errorMsg)));
+ }
+ }
+
+ @Test
+ public void rejectIncorrectCaptcha()
+ {
+ String errorMsg = "incorrect response";
+ fields.put("username", "rejectbadcaptcha");
+ fields.put("email", "rejectbadcaptcha@example.com");
+ fields.put("captcha", "9000");
+
+ RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields).registerFailure();
+ assertThat("The Captcha entry is rejected", registerPage.getErrors(), Matchers.contains(errorMsg));
+ }
+
+ @Test
+ public void passwordsMatch()
+ {
+ String errorMsg = "Passwords do not match";
+ fields.put("username", "passwordsmatch");
+ fields.put("email", "passwordsmatchtest@example.com");
+ fields.put("password", "passwordsmatch");
+ fields.put("confirmpassword", "passwordsdonotmatch");
+
+ RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ assertThat("Passwords fail to match error is shown", registerPage.getErrors(), Matchers.contains(errorMsg));
+ }
+
+ @Test
+ public void requiredFields()
+ {
+ String errorMsg = "value is required";
+ fields.put("name", "");
+ fields.put("username", "");
+ fields.put("email", "");
+ fields.put("password", "");
+ fields.put("confirmpassword", "");
+
+ RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ assertThat("Value is required shows for all fields", registerPage.getErrors(),
+ Matchers.contains(errorMsg, errorMsg, errorMsg, errorMsg, errorMsg));
+ }
+
+ /*
+ Bugs
+ */
+ @Test(expected = AssertionError.class)
+ public void bug981082_inaccurateErrorMessage()
+ {
+ String errorMsg = "size must be between 3 and 20";
+ fields.put("email", "bug981082test@test.com");
+ fields.put("username", "mo");
+
+ RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ assertThat("Size errors are shown for string too short", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+
+ fields.put("username", "johndoeusernamevalidation");
+ registerPage = registerPage.setFields(fields);
+ assertThat("Size errors are shown for string too long", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+ }
+
+ @Test(expected = AssertionError.class)
+ public void bug981498_underscoreRules()
+ {
+ String errorMsg = "lowercase letters and digits (regex \"^[a-z\\d_]{3,20}$\")";
+ fields.put("email", "bug981498test@example.com");
+ fields.put("username", "______");
+ RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ assertThat("A username of all underscores is not valid", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+ }
+
+ /*
+ Returns a hash of invalid characters for a username
+ Hash is String reason for invalid 'character', String character
+ */
+ private LinkedHashMap usernameCharacterValidationData()
+ {
+ LinkedHashMap inputData = new LinkedHashMap(100);
+ inputData.put("Invalid char |", "user|name");
+ inputData.put("Invalid char /", "user/name");
+ inputData.put("Invalid char ", "user\\name");
+ inputData.put("Invalid char +", "user+name");
+ inputData.put("Invalid char *", "user*name");
+ inputData.put("Invalid char |", "user|name");
+ inputData.put("Invalid char (", "user(name");
+ inputData.put("Invalid char )", "user)name");
+ inputData.put("Invalid char $", "user$name");
+ inputData.put("Invalid char [", "user[name");
+ inputData.put("Invalid char ]", "user]name");
+ inputData.put("Invalid char :", "user:name");
+ inputData.put("Invalid char ;", "user;name");
+ inputData.put("Invalid char '", "user'name");
+ inputData.put("Invalid char ,", "user,name");
+ inputData.put("Invalid char ?", "user?name");
+ inputData.put("Invalid char !", "user!name");
+ inputData.put("Invalid char @", "user@name");
+ inputData.put("Invalid char #", "user#name");
+ inputData.put("Invalid char %", "user%name");
+ inputData.put("Invalid char ^", "user^name");
+ inputData.put("Invalid char =", "user=name");
+ inputData.put("Invalid char .", "user.name");
+ inputData.put("Invalid char {", "user{name");
+ inputData.put("Invalid char }", "user}name");
+ // Capital letters are prohibited
+ for (char c = 'A'; c <= 'Z'; c++) {
+ String letter = String.valueOf(c);
+ inputData.put("Invalid capital char ".concat(letter), "user".concat(letter).concat("name"));
+ }
+ return inputData;
+ }
+}
diff --git a/zanata-war/src/main/webapp/account/register.xhtml b/zanata-war/src/main/webapp/account/register.xhtml
index 116417bb8c..eebe55aab7 100644
--- a/zanata-war/src/main/webapp/account/register.xhtml
+++ b/zanata-war/src/main/webapp/account/register.xhtml
@@ -95,7 +95,7 @@
-
+
From 96d8f0598490355aeb518daafd8895fceaa413f8 Mon Sep 17 00:00:00 2001
From: Damian Jansen
Date: Wed, 10 Jul 2013 10:28:32 +1000
Subject: [PATCH 032/184] Better description of the RFC2822 class
The description was lacking / inaccurate.
---
functional-test/src/main/java/org/zanata/util/RFC2822.java | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/functional-test/src/main/java/org/zanata/util/RFC2822.java b/functional-test/src/main/java/org/zanata/util/RFC2822.java
index df61e4c886..d4937a46a6 100644
--- a/functional-test/src/main/java/org/zanata/util/RFC2822.java
+++ b/functional-test/src/main/java/org/zanata/util/RFC2822.java
@@ -9,10 +9,15 @@
public class RFC2822 {
/*
+ * Synopsis:
+ * The functions of this class contain valid and invalid email addresses, as stipulated in the
+ * RFC2822 Internet Message Format standard, or referred to standards.
+ *
* Definitions
* localpart: the section of an address preceding the @ symbol
* domain: the section of an address following the @ symbol
- * label: section of domain between the @ symbol or period and the next period or end e.g example in me@example.com
+ * label: section of localpart or domain between the start, @ symbol, period or end (also referred to as "atom")
+ * e.g. me, myself, example, com in me.myself@example.com
* quote / quoting: a section of the localpart contained within quotation marks
*
* BUG982048
From a034279807e4ed0b1fe4bdddb005800141aa3d3b Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Wed, 10 Jul 2013 10:49:48 +1000
Subject: [PATCH 033/184] Implement rules in workspace for reviewer role:
https://bugzilla.redhat.com/show_bug.cgi?id=981067
---
.../java/org/zanata/action/ProjectHome.java | 8 +-
.../action/ProjectIterationFilesAction.java | 9 +-
.../main/java/org/zanata/dao/PersonDAO.java | 37 ++++++++
.../zanata/security/SecurityFunctions.java | 17 +++-
.../presenter/TargetContentsPresenter.java | 7 ++
.../client/ui/EditorButtonsWidget.java | 9 ++
.../client/view/TargetContentsDisplay.java | 2 +
.../server/rpc/ActivateWorkspaceHandler.java | 4 +-
.../shared/model/UserWorkspaceContext.java | 2 +-
.../src/main/resources/messages.properties | 2 +-
.../src/main/resources/messages_ja.properties | 2 +-
.../src/main/resources/messages_uk.properties | 2 +-
.../resources/messages_zh_TW_Hant.properties | 2 +-
zanata-war/src/main/resources/security.drl | 10 +-
.../email/email_request_role_language.xhtml | 2 +-
.../email_request_to_join_language.xhtml | 2 +-
.../src/main/webapp/iteration/files.xhtml | 92 ++-----------------
.../src/main/webapp/project/project.xhtml | 28 +-----
18 files changed, 110 insertions(+), 127 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/action/ProjectHome.java b/zanata-war/src/main/java/org/zanata/action/ProjectHome.java
index a7d8204213..cac721d515 100644
--- a/zanata-war/src/main/java/org/zanata/action/ProjectHome.java
+++ b/zanata-war/src/main/java/org/zanata/action/ProjectHome.java
@@ -398,9 +398,13 @@ public boolean checkViewObsolete()
return identity != null && identity.hasPermission("HProject", "view-obsolete");
}
- public boolean isUserAllowedToTranslate(String versionSlug, HLocale localeId)
+ public boolean isUserAllowedToTranslateOrReview(String versionSlug, HLocale localeId)
{
- return !StringUtils.isEmpty(versionSlug) && localeId != null && isIterationActive(versionSlug) && identity != null && identity.hasPermission("add-translation", getInstance(), localeId);
+ return !StringUtils.isEmpty(versionSlug)
+ && localeId != null
+ && isIterationActive(versionSlug)
+ && identity != null
+ && (identity.hasPermission("add-translation", getInstance(), localeId) || identity.hasPermission("translation-review", getInstance(), localeId));
}
private boolean isIterationActive(String versionSlug)
diff --git a/zanata-war/src/main/java/org/zanata/action/ProjectIterationFilesAction.java b/zanata-war/src/main/java/org/zanata/action/ProjectIterationFilesAction.java
index 8cfe109c44..155ea79e9a 100644
--- a/zanata-war/src/main/java/org/zanata/action/ProjectIterationFilesAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/ProjectIterationFilesAction.java
@@ -575,6 +575,11 @@ public boolean isUserAllowedToTranslate()
{
return isIterationActive() && identity != null && identity.hasPermission("add-translation", getProjectIteration().getProject(), getLocale());
}
+
+ public boolean isUserAllowedToReview()
+ {
+ return isIterationActive() && identity != null && identity.hasPermission("translation-review", getProjectIteration().getProject(), getLocale());
+ }
public boolean isIterationReadOnly()
{
@@ -645,9 +650,9 @@ public List getTranslationDeniedReasonMessages()
}
// User not member of language team
- if (!personDAO.isMemberOfLanguageTeam(authenticatedAccount.getPerson(), getLocale()))
+ if (!personDAO.isTranslatorOfLanguageTeam(authenticatedAccount.getPerson(), getLocale()))
{
- displayMessages.add(zanataMessages.getMessage("jsf.iteration.files.translateDenied.UserNotInLanguageTeam", getLocale().retrieveDisplayName()));
+ displayMessages.add(zanataMessages.getMessage("jsf.iteration.files.translateDenied.UserNotTranslatorInLanguageTeam", getLocale().retrieveDisplayName()));
}
// User not part of the allowed roles
diff --git a/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java b/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
index c9ad733c32..8d2870cf10 100644
--- a/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
@@ -145,6 +145,43 @@ public boolean isMemberOfLanguageTeam( HPerson person, HLocale language )
return totalCount > 0L;
}
+ /**
+ * Indicates if a Person is a translator of a language team.
+ * @param person The person
+ * @param language The language team
+ * @return True if person is a translator of the language team.
+ */
+ public boolean isTranslatorOfLanguageTeam( HPerson person, HLocale language )
+ {
+ Query q = getSession().createQuery("select count(*) from HLocaleMember " +
+ "where id.person = :person and id.supportedLanguage = :language " +
+ "and translator = true")
+ .setParameter("person", person)
+ .setParameter("language", language);
+ q.setCacheable(false).setComment("PersonDAO.isTranslatorOfLanguageTeam");
+ Long totalCount = (Long) q.uniqueResult();
+ return totalCount > 0L;
+ }
+
+ /**
+ * Indicates if a Person is a reviewer of a language team.
+ * @param person The person
+ * @param language The language team
+ * @return True if person is a reviewer of the language team.
+ */
+ public boolean isReviewerOfLanguageTeam( HPerson person, HLocale language )
+ {
+ Query q = getSession().createQuery("select count(*) from HLocaleMember " +
+ "where id.person = :person and id.supportedLanguage = :language " +
+ "and reviewer = true")
+ .setParameter("person", person)
+ .setParameter("language", language);
+ q.setCacheable(false).setComment("PersonDAO.isReviewerOfLanguageTeam");
+ Long totalCount = (Long) q.uniqueResult();
+ return totalCount > 0L;
+ }
+
+
/**
* Indicates if a Person is a coordinator of a language team.
* @param person The person
diff --git a/zanata-war/src/main/java/org/zanata/security/SecurityFunctions.java b/zanata-war/src/main/java/org/zanata/security/SecurityFunctions.java
index 9ba9378af3..887e8fb4e7 100644
--- a/zanata-war/src/main/java/org/zanata/security/SecurityFunctions.java
+++ b/zanata-war/src/main/java/org/zanata/security/SecurityFunctions.java
@@ -66,14 +66,27 @@ public static boolean isUserAllowedAccess( HProject project )
}
}
- public static boolean isUserMemberOfLanguageTeam( HLocale lang )
+ public static boolean isUserTranslatorOfLanguageTeam( HLocale lang )
{
HAccount authenticatedAccount = getAuthenticatedAccount();
PersonDAO personDAO = (PersonDAO)Component.getInstance(PersonDAO.class);
if( authenticatedAccount != null )
{
- return personDAO.isMemberOfLanguageTeam( authenticatedAccount.getPerson(), lang );
+ return personDAO.isTranslatorOfLanguageTeam( authenticatedAccount.getPerson(), lang );
+ }
+
+ return false; // No authenticated user
+ }
+
+ public static boolean isUserReviewerOfLanguageTeam( HLocale lang )
+ {
+ HAccount authenticatedAccount = getAuthenticatedAccount();
+ PersonDAO personDAO = (PersonDAO)Component.getInstance(PersonDAO.class);
+
+ if( authenticatedAccount != null )
+ {
+ return personDAO.isReviewerOfLanguageTeam( authenticatedAccount.getPerson(), lang );
}
return false; // No authenticated user
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 3c6d51a321..9bf0a592b6 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
@@ -665,6 +665,13 @@ public boolean canReviewTranslation()
WorkspaceRestrictions restrictions = userWorkspaceContext.getWorkspaceRestrictions();
return restrictions.isHasReviewAccess() && restrictions.isProjectRequireReview();
}
+
+ @Override
+ public boolean canModifyTranslation()
+ {
+ WorkspaceRestrictions restrictions = userWorkspaceContext.getWorkspaceRestrictions();
+ return restrictions.isHasWriteAccess();
+ }
@Override
public void acceptTranslation(TransUnitId id)
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 d1f36313ba..6277335db0 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
@@ -43,6 +43,7 @@ public EditorButtonsWidget()
{
initWidget(ourUiBinder.createAndBindUi(this));
displayReviewButtons(listener != null && listener.canReviewTranslation());
+ displayModifyTranslationButtons(listener != null && listener.canModifyTranslation());
}
private void displayReviewButtons(boolean canReview)
@@ -50,6 +51,13 @@ private void displayReviewButtons(boolean canReview)
acceptIcon.setVisible(canReview);
rejectIcon.setVisible(canReview);
}
+
+ private void displayModifyTranslationButtons(boolean canModify)
+ {
+ saveIcon.setVisible(canModify);
+ fuzzyIcon.setVisible(canModify);
+ cancelIcon.setVisible(canModify);
+ }
public void addUndo(final UndoLink undoLink)
{
@@ -117,6 +125,7 @@ public void setListener(TargetContentsDisplay.Listener listener)
{
this.listener = listener;
displayReviewButtons(listener.canReviewTranslation());
+ displayModifyTranslationButtons(listener.canModifyTranslation());
}
public void setId(TransUnitId id)
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 e8ac810cb9..6eb203659b 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
@@ -97,6 +97,8 @@ interface Listener
UserConfigHolder.ConfigurationState getConfigState();
boolean canReviewTranslation();
+
+ boolean canModifyTranslation();
void acceptTranslation(TransUnitId id);
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandler.java
index c3cd0bb451..9048cd4485 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandler.java
@@ -119,7 +119,7 @@ public ActivateWorkspaceResult execute(ActivateWorkspaceAction action, Execution
HProjectIteration projectIteration = projectIterationDAO.getBySlug(workspaceId.getProjectIterationId().getProjectSlug(), workspaceId.getProjectIterationId().getIterationSlug());
boolean isProjectActive = isProjectIterationActive(project.getStatus(), projectIteration.getStatus());
- boolean hasWriteAccess = hasPermission(project, locale);
+ boolean hasWriteAccess = hasWritePermission(project, locale);
boolean hasGlossaryUpdateAccess = hasGlossaryUpdatePermission();
boolean requireReview = projectIteration.getRequireTranslationReview();
boolean hasReviewAccess = hasReviewerPermission(locale, project);
@@ -142,7 +142,7 @@ protected String getHttpSessionId()
return ServletContexts.instance().getRequest().getSession().getId();
}
- private boolean hasPermission(HProject project, HLocale locale)
+ private boolean hasWritePermission(HProject project, HLocale locale)
{
return identity.hasPermission(SecurityService.TranslationAction.MODIFY.action(), project, locale);
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java
index 7e4a71e954..407455e869 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java
@@ -38,7 +38,7 @@ public WorkspaceContext getWorkspaceContext()
public boolean hasReadOnlyAccess()
{
- return (!getWorkspaceRestrictions().isProjectActive() || !getWorkspaceRestrictions().isHasWriteAccess());
+ return (!getWorkspaceRestrictions().isProjectActive() || (!getWorkspaceRestrictions().isHasWriteAccess() && !getWorkspaceRestrictions().isHasReviewAccess()));
}
public WorkspaceRestrictions getWorkspaceRestrictions()
diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties
index 61078aa3c8..5619530858 100644
--- a/zanata-war/src/main/resources/messages.properties
+++ b/zanata-war/src/main/resources/messages.properties
@@ -343,7 +343,7 @@ jsf.iteration.files.translateDenied.NotLoggedIn=You are not logged In.
jsf.iteration.files.translateDenied.VersionIsReadOnly=This project version is Read-Only.
jsf.iteration.files.translateDenied.VersionIsObsolete=This project version is Obsolete.
! {0} is a language name
-jsf.iteration.files.translateDenied.UserNotInLanguageTeam=You are not part of the {0} language team.
+jsf.iteration.files.translateDenied.UserNotTranslatorInLanguageTeam=You are not translator of the {0} language team.
! {0} is a list of user roles
jsf.iteration.files.translateDenied.UserNotInProjectRole=You must be part of these user roles to translate this project: {0}
diff --git a/zanata-war/src/main/resources/messages_ja.properties b/zanata-war/src/main/resources/messages_ja.properties
index aa8515003f..898c170d48 100644
--- a/zanata-war/src/main/resources/messages_ja.properties
+++ b/zanata-war/src/main/resources/messages_ja.properties
@@ -252,7 +252,7 @@ jsf.iteration.files.WhyCantITranslate=\u306A\u305C\u7FFB\u8A33\u3067\u304D\u306A
jsf.iteration.files.translateDenied.NotLoggedIn=\u30E6\u30FC\u30B6\u30FC\u306F\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u3044\u307E\u305B\u3093\u3002
jsf.iteration.files.translateDenied.VersionIsReadOnly=\u3053\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u3067\u3059\u3002
jsf.iteration.files.translateDenied.VersionIsObsolete=\u3053\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u65E7\u7248\u3067\u3059\u3002
-jsf.iteration.files.translateDenied.UserNotInLanguageTeam=\u30E6\u30FC\u30B6\u30FC\u306F {0} \u8A00\u8A9E\u30C1\u30FC\u30E0\u306E\u30E1\u30F3\u30D0\u30FC\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
+jsf.iteration.files.translateDenied.UserNotTranslatorInLanguageTeam=\u30E6\u30FC\u30B6\u30FC\u306F {0} \u8A00\u8A9E\u30C1\u30FC\u30E0\u306E\u30E1\u30F3\u30D0\u30FC\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002
jsf.iteration.files.translateDenied.UserNotInProjectRole=\u3053\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u7FFB\u8A33\u3059\u308B\u306B\u306F\u6B21\u306E\u30E6\u30FC\u30B6\u30FC\u30ED\u30FC\u30EB\u306B\u306A\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\: {0}
jsf.NoGroupExists=\u30B0\u30EB\u30FC\u30D7\u304C\u3042\u308A\u307E\u305B\u3093\u3002
jsf.groups.ShowActiveGroups=\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u30B0\u30EB\u30FC\u30D7\u306E\u8868\u793A
diff --git a/zanata-war/src/main/resources/messages_uk.properties b/zanata-war/src/main/resources/messages_uk.properties
index 4d06658eea..76f2e10585 100644
--- a/zanata-war/src/main/resources/messages_uk.properties
+++ b/zanata-war/src/main/resources/messages_uk.properties
@@ -327,7 +327,7 @@ jsf.iteration.files.translateDenied.NotLoggedIn=\u0412\u0438 \u043D\u0435 \u0443
# translation auto-copied from project Zanata, version jsf-pages, document main/resources/messages, author Maks
jsf.iteration.files.translateDenied.VersionIsReadOnly=\u0426\u044F \u0432\u0435\u0440\u0441\u0456\u044F \u043F\u0440\u043E\u0435\u043A\u0442\u0443 \u0442\u0456\u043B\u044C\u043A\u0438 \u0434\u043B\u044F \u0447\u0438\u0442\u0430\u043D\u043D\u044F.
jsf.iteration.files.translateDenied.VersionIsObsolete=\u0426\u044F \u0432\u0435\u0440\u0441\u0456\u044F \u043F\u0440\u043E\u0435\u043A\u0442\u0443 \u0437\u0430\u0441\u0442\u0430\u0440\u0456\u043B\u0430
-jsf.iteration.files.translateDenied.UserNotInLanguageTeam=\u0412\u0438 \u043D\u0435 \u0454 \u0447\u0430\u0441\u0442\u0438\u043D\u043E\u044E \u043A\u043E\u043C\u0430\u043D\u0434\u0438 \u043F\u0435\u0440\u0435\u043A\u043B\u0430\u0434\u0430\u0447\u0456\u0432 {0} .
+jsf.iteration.files.translateDenied.UserNotTranslatorInLanguageTeam=\u0412\u0438 \u043D\u0435 \u0454 \u0447\u0430\u0441\u0442\u0438\u043D\u043E\u044E \u043A\u043E\u043C\u0430\u043D\u0434\u0438 \u043F\u0435\u0440\u0435\u043A\u043B\u0430\u0434\u0430\u0447\u0456\u0432 {0} .
# translation auto-copied from project Zanata, version jsf-pages, document main/resources/messages, author Maks
jsf.NoGroupExists=\u0413\u0440\u0443\u043F\u0438 \u0432\u0456\u0434\u0441\u0443\u0442\u043D\u0456.
jsf.groups.ShowActiveGroups=\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u0438 \u0430\u043A\u0442\u0438\u0432\u043D\u0456 \u0433\u0440\u0443\u043F\u0438
diff --git a/zanata-war/src/main/resources/messages_zh_TW_Hant.properties b/zanata-war/src/main/resources/messages_zh_TW_Hant.properties
index 2a5e5a09a8..18643751f4 100644
--- a/zanata-war/src/main/resources/messages_zh_TW_Hant.properties
+++ b/zanata-war/src/main/resources/messages_zh_TW_Hant.properties
@@ -243,7 +243,7 @@ jsf.iteration.files.WhyCantITranslate=\u70BA\u4F55\u6211\u7121\u6CD5\u7FFB\u8B6F
jsf.iteration.files.translateDenied.NotLoggedIn=\u60A8\u5C1A\u672A\u767B\u5165\u3002
jsf.iteration.files.translateDenied.VersionIsReadOnly=\u6B64\u5C08\u6848\u7248\u672C\u70BA\u552F\u8B80\u3002
jsf.iteration.files.translateDenied.VersionIsObsolete=\u6B64\u5C08\u6848\u7248\u672C\u5DF2\u904E\u6642\u3002
-jsf.iteration.files.translateDenied.UserNotInLanguageTeam=\u60A8\u5C1A\u672A\u52A0\u5165 {0} \u8A9E\u8A00\u5718\u968A\u3002
+jsf.iteration.files.translateDenied.UserNotTranslatorInLanguageTeam=\u60A8\u5C1A\u672A\u52A0\u5165 {0} \u8A9E\u8A00\u5718\u968A\u3002
jsf.iteration.files.translateDenied.UserNotInProjectRole=\u60A8\u5FC5\u9808\u64C1\u6709\u9019\u4E9B\u4F7F\u7528\u8005\u89D2\u8272\uFF0C\u624D\u80FD\u7FFB\u8B6F\u6B64\u5C08\u6848\uFF1A{0}
jsf.NoGroupExists=\u6C92\u6709\u5B58\u5728\u7684\u7FA4\u7D44\u3002
jsf.groups.ShowActiveGroups=\u986F\u793A\u555F\u7528\u4E2D\u7684\u7FA4\u7D44
diff --git a/zanata-war/src/main/resources/security.drl b/zanata-war/src/main/resources/security.drl
index 1a5463d89f..d2f872165d 100644
--- a/zanata-war/src/main/resources/security.drl
+++ b/zanata-war/src/main/resources/security.drl
@@ -16,7 +16,8 @@ import org.jboss.seam.security.permission.PermissionCheck;
import org.jboss.seam.security.permission.RoleCheck;
import function org.zanata.security.SecurityFunctions.isUserAllowedAccess;
-import function org.zanata.security.SecurityFunctions.isUserMemberOfLanguageTeam;
+import function org.zanata.security.SecurityFunctions.isUserTranslatorOfLanguageTeam;
+import function org.zanata.security.SecurityFunctions.isUserReviewerOfLanguageTeam;
import function org.zanata.security.SecurityFunctions.isUserCoordinatorOfLanguageTeam;
/* admin can do anything */
@@ -191,7 +192,7 @@ when
$project: HProject( eval(isUserAllowedAccess($project)) )
eval(authenticatedPerson != null)
$locale: HLocale(
- eval(isUserMemberOfLanguageTeam($locale))
+ eval(isUserTranslatorOfLanguageTeam($locale))
)
then
check.grant();
@@ -469,16 +470,15 @@ end
******************************************************************************************/
rule ReviewerReviewTranslation
no-loop
- activation-group "permisstions"
+ activation-group "permissions"
when
check: PermissionCheck(action == "translation-review", granted == false)
$project: HProject(
eval( isUserAllowedAccess($project) )
)
$locale: HLocale(
- eval( isUserMemberOfLanguageTeam($locale) )
+ eval( isUserReviewerOfLanguageTeam($locale) )
)
- Role(name == "reviewer")
then
check.grant();
end
diff --git a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml
index 0b0c1455fc..7ccb8e31e7 100644
--- a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml
+++ b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml
@@ -11,7 +11,7 @@
-
+
#{messages['jsf.email.coordinator.DearCoordinator']}
diff --git a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
index 6a25ed2a5f..646128757b 100644
--- a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
+++ b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
@@ -11,7 +11,7 @@
-
+
#{messages['jsf.email.coordinator.DearCoordinator']}
diff --git a/zanata-war/src/main/webapp/iteration/files.xhtml b/zanata-war/src/main/webapp/iteration/files.xhtml
index b9a2b546d9..eb5c02c522 100644
--- a/zanata-war/src/main/webapp/iteration/files.xhtml
+++ b/zanata-war/src/main/webapp/iteration/files.xhtml
@@ -105,7 +105,7 @@
#{messages['jsf.Actions']}
@@ -114,73 +114,24 @@
value="#{request.contextPath}/webtrans/Application.seam?project=#{projectIterationFilesAction.projectSlug}&iteration=#{projectIterationFilesAction.iterationSlug}&localeId=#{projectIterationFilesAction.localeId}&locale=#{locale.language}#view:doc;doc:#{doc.docId}">
-
-
-
- #{messages['jsf.Actions']}
-
-
-
-
-
-
-
-
-
+
#{messages['jsf.Actions']}
-
-
-
-
-
-
-
- #{messages['jsf.Actions']}
-
-
-
-
-
+
+
#{messages['jsf.iteration.files.Download']}
@@ -314,7 +266,7 @@
@@ -322,20 +274,9 @@
#{messages['jsf.Open']}
-
+
-
-
-
-
-
- #{messages['jsf.OpenGWTDevMode']}
-
-
-
@@ -344,19 +285,6 @@
#{messages['jsf.Translate']}
-
-
-
-
-
-
- #{messages['jsf.TranslateGWTDevMode']}
-
-
-
-
-
+
#{messages['jsf.iteration.files.WhyCantITranslate']}
diff --git a/zanata-war/src/main/webapp/project/project.xhtml b/zanata-war/src/main/webapp/project/project.xhtml
index 6411c795fe..b5de9f0908 100644
--- a/zanata-war/src/main/webapp/project/project.xhtml
+++ b/zanata-war/src/main/webapp/project/project.xhtml
@@ -57,7 +57,7 @@
@@ -68,19 +68,7 @@
-
-
-
-
-
- #{language.localeId.id}
-
-
-
-
@@ -90,17 +78,7 @@
-
-
-
-
-
-
- #{language.localeId.id}
-
-
+
From 33e5375531661c64bfdf396606287491bee40e0e Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 10 Jul 2013 13:10:15 +1000
Subject: [PATCH 034/184] Rename ActiveStates to ContentStateGroup, rename
methods and move to gwt shared.
Move to gwt includes a few minor changes to allow gwt-rpc serialization.
---
.../main/java/org/zanata/dao/TextFlowDAO.java | 10 +-
.../java/org/zanata/search/ActiveStates.java | 146 --------------
.../search/FilterConstraintToQuery.java | 2 +-
.../org/zanata/search/FilterConstraints.java | 38 ++--
.../impl/TextFlowSearchServiceImpl.java | 14 +-
.../server/rpc/GetTransUnitListHandler.java | 2 +-
.../shared/model/ContentStateGroup.java | 183 ++++++++++++++++++
.../webtrans/shared/rpc/GetTransUnitList.java | 28 +--
.../shared/rpc/GetTransUnitsNavigation.java | 21 +-
9 files changed, 243 insertions(+), 201 deletions(-)
delete mode 100644 zanata-war/src/main/java/org/zanata/search/ActiveStates.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/model/ContentStateGroup.java
diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
index 467e2c6f6f..8ed888ded6 100644
--- a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
@@ -41,9 +41,9 @@
import org.zanata.model.HDocument;
import org.zanata.model.HLocale;
import org.zanata.model.HTextFlow;
-import org.zanata.search.ActiveStates;
import org.zanata.search.FilterConstraintToQuery;
import org.zanata.search.FilterConstraints;
+import org.zanata.webtrans.shared.model.ContentStateGroup;
import org.zanata.webtrans.shared.model.DocumentId;
import com.google.common.base.Joiner;
@@ -172,7 +172,7 @@ public List getNavigationByDocumentId(Long documentId, HLocale hLocal
protected static String buildContentStateCondition(FilterConstraints constraints, String alias)
{
- ActiveStates includedStates = constraints.getIncludedStates();
+ ContentStateGroup includedStates = constraints.getIncludedStates();
if (includedStates.hasAllStates() || includedStates.hasNoStates())
{
return "1";
@@ -181,17 +181,17 @@ protected static String buildContentStateCondition(FilterConstraints constraints
builder.append("(");
List conditions = Lists.newArrayList();
final String column = alias + ".state";
- if (constraints.getIncludedStates().isTranslatedOn())
+ if (constraints.getIncludedStates().hasTranslated())
{
conditions.add(column + "=2"); // Translated
conditions.add(column + "=3"); // Approved
}
- if (constraints.getIncludedStates().isFuzzyOn())
+ if (constraints.getIncludedStates().hasFuzzy())
{
conditions.add(column + "=1"); // Fuzzy
conditions.add(column + "=4"); // Rejected
}
- if (constraints.getIncludedStates().isNewOn())
+ if (constraints.getIncludedStates().hasNew())
{
conditions.add(column + "=0 or " + column + " is null");
}
diff --git a/zanata-war/src/main/java/org/zanata/search/ActiveStates.java b/zanata-war/src/main/java/org/zanata/search/ActiveStates.java
deleted file mode 100644
index eeabfa61bb..0000000000
--- a/zanata-war/src/main/java/org/zanata/search/ActiveStates.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package org.zanata.search;
-
-import java.util.List;
-
-import org.zanata.common.ContentState;
-
-import com.google.common.collect.Lists;
-
-import lombok.Getter;
-import lombok.AllArgsConstructor;
-import lombok.ToString;
-
-@ToString
-@AllArgsConstructor
-@Getter
-public class ActiveStates
-{
- private boolean newOn;
- private boolean fuzzyOn;
- private boolean translatedOn;
- private boolean approvedOn;
- private boolean rejectedOn;
-
- /**
- * @return a Builder with all states on by default
- */
- public static Builder builder()
- {
- return new Builder();
- }
-
- public boolean hasAllStates()
- {
- return newOn && fuzzyOn && translatedOn && approvedOn && rejectedOn;
- }
-
- public boolean hasNoStates()
- {
- return !(newOn || fuzzyOn || translatedOn || approvedOn || rejectedOn);
- }
-
- public List asList()
- {
- List result = Lists.newArrayList();
- if (newOn)
- {
- result.add(ContentState.New);
- }
- if (fuzzyOn)
- {
- result.add(ContentState.NeedReview);
- }
- if (translatedOn)
- {
- result.add(ContentState.Translated);
- }
- if (approvedOn)
- {
- result.add(ContentState.Approved);
- }
- if (rejectedOn)
- {
- result.add(ContentState.Rejected);
- }
- return result;
- }
-
- public static class Builder
- {
- private boolean newOn;
- private boolean fuzzyOn;
- private boolean translatedOn;
- private boolean approvedOn;
- private boolean rejectedOn;
-
- public Builder()
- {
- allOn();
- }
-
- public ActiveStates build()
- {
- return new ActiveStates(newOn, fuzzyOn, translatedOn, approvedOn, rejectedOn);
- }
-
- public Builder allOn()
- {
- this.newOn = true;
- this.fuzzyOn = true;
- this.translatedOn = true;
- this.approvedOn = true;
- this.rejectedOn = true;
- return this;
- }
-
- public Builder allOff()
- {
- this.newOn = false;
- this.fuzzyOn = false;
- this.translatedOn = false;
- this.approvedOn = false;
- this.rejectedOn = false;
- return this;
- }
-
- public Builder fromStates(ActiveStates states)
- {
- this.newOn = states.newOn;
- this.fuzzyOn = states.fuzzyOn;
- this.translatedOn = states.translatedOn;
- this.approvedOn = states.approvedOn;
- this.rejectedOn = states.rejectedOn;
- return this;
- }
-
- public Builder setNewOn(boolean on)
- {
- newOn = on;
- return this;
- }
-
- public Builder setFuzzyOn(boolean on)
- {
- fuzzyOn = on;
- return this;
- }
-
- public Builder setTranslatedOn(boolean on)
- {
- translatedOn = on;
- return this;
- }
-
- public Builder setApprovedOn(boolean on)
- {
- approvedOn = on;
- return this;
- }
-
- public Builder setRejectedOn(boolean on)
- {
- rejectedOn = on;
- return this;
- }
- }
-}
diff --git a/zanata-war/src/main/java/org/zanata/search/FilterConstraintToQuery.java b/zanata-war/src/main/java/org/zanata/search/FilterConstraintToQuery.java
index a6cf05e406..6f46ff3ca2 100644
--- a/zanata-war/src/main/java/org/zanata/search/FilterConstraintToQuery.java
+++ b/zanata-war/src/main/java/org/zanata/search/FilterConstraintToQuery.java
@@ -148,7 +148,7 @@ protected String buildStateCondition()
String stateInListWhereClause = and(textFlowAndLocaleRestriction.toString(), String.format("state in (%s)", STATE_LIST_PLACEHOLDER));
String stateInListCondition = QueryBuilder.exists().from("HTextFlowTarget").where(stateInListWhereClause).toQueryString();
- if (constraints.getIncludedStates().isNewOn())
+ if (constraints.getIncludedStates().hasNew())
{
String nullTargetCondition = String.format("%s not in indices(tf.targets)", LOCALE_PLACEHOLDER);
if (hasSearch && constraints.isSearchInSource())
diff --git a/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java b/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
index 8f52112a8f..d5803bb1da 100644
--- a/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
+++ b/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
@@ -23,6 +23,8 @@
//TODO May want to add document(someDocument) to these constraints
//so that only one search method is needed on the interface.
+import org.zanata.webtrans.shared.model.ContentStateGroup;
+
import lombok.Getter;
import com.google.common.base.Objects;
@@ -39,11 +41,11 @@ public class FilterConstraints
private boolean isCaseSensitive;
private boolean searchInSource;
private boolean searchInTarget;
- private ActiveStates includedStates;
+ private ContentStateGroup includedStates;
private FilterConstraints(String searchString, boolean caseSensitive,
boolean searchInSource, boolean searchInTarget,
- ActiveStates includedStates)
+ ContentStateGroup includedStates)
{
this.searchString = searchString;
this.isCaseSensitive = caseSensitive;
@@ -77,11 +79,11 @@ public static class Builder
private boolean caseSensitive;
private boolean searchInSource;
private boolean searchInTarget;
- private ActiveStates.Builder states;
+ private ContentStateGroup.Builder states;
public Builder()
{
- states = ActiveStates.builder();
+ states = ContentStateGroup.builder();
setKeepAll();
}
@@ -103,7 +105,7 @@ private void setKeepAll()
caseSensitive = false;
searchInSource = true;
searchInTarget = true;
- states.allOn();
+ states.addAll();
}
public Builder keepNone()
@@ -112,7 +114,7 @@ public Builder keepNone()
caseSensitive = false;
searchInSource = false;
searchInTarget = false;
- states.allOff();
+ states.removeAll();
return this;
}
@@ -140,7 +142,7 @@ public Builder checkInTarget(boolean check)
return this;
}
- public Builder includeStates(ActiveStates states)
+ public Builder includeStates(ContentStateGroup states)
{
//FIXME this behaviour is too surprising.
// It exists because the editor UI should show all states when either
@@ -148,7 +150,7 @@ public Builder includeStates(ActiveStates states)
// in the editor backend *before* sending a request to the server.
if (states.hasNoStates())
{
- this.states.allOn();
+ this.states.addAll();
}
else
{
@@ -159,61 +161,61 @@ public Builder includeStates(ActiveStates states)
public Builder includeNew()
{
- states.setNewOn(true);
+ states.includeNew(true);
return this;
}
public Builder excludeNew()
{
- states.setNewOn(false);
+ states.includeNew(false);
return this;
}
public Builder includeFuzzy()
{
- states.setFuzzyOn(true);
+ states.includeFuzzy(true);
return this;
}
public Builder excludeFuzzy()
{
- states.setFuzzyOn(false);
+ states.includeFuzzy(false);
return this;
}
public Builder includeTranslated()
{
- states.setTranslatedOn(true);
+ states.includeTranslated(true);
return this;
}
public Builder excludeTranslated()
{
- states.setTranslatedOn(false);
+ states.includeTranslated(false);
return this;
}
public Builder includeApproved()
{
- states.setApprovedOn(true);
+ states.includeApproved(true);
return this;
}
public Builder excludeApproved()
{
- states.setApprovedOn(false);
+ states.includeApproved(false);
return this;
}
public Builder includeRejected()
{
- states.setRejectedOn(true);
+ states.includeRejected(true);
return this;
}
public Builder excludeRejected()
{
- states.setRejectedOn(false);
+ states.includeRejected(false);
return this;
}
diff --git a/zanata-war/src/main/java/org/zanata/service/impl/TextFlowSearchServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/TextFlowSearchServiceImpl.java
index e31a97de91..f3016803af 100644
--- a/zanata-war/src/main/java/org/zanata/service/impl/TextFlowSearchServiceImpl.java
+++ b/zanata-war/src/main/java/org/zanata/service/impl/TextFlowSearchServiceImpl.java
@@ -57,11 +57,11 @@
import org.zanata.model.HProjectIteration;
import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
-import org.zanata.search.ActiveStates;
import org.zanata.search.FilterConstraintToQuery;
import org.zanata.search.FilterConstraints;
import org.zanata.service.LocaleService;
import org.zanata.service.TextFlowSearchService;
+import org.zanata.webtrans.shared.model.ContentStateGroup;
import org.zanata.webtrans.shared.model.DocumentId;
import org.zanata.webtrans.shared.model.WorkspaceId;
@@ -140,8 +140,10 @@ private List findTextFlowsByDocumentPaths(WorkspaceId workspace, List
return Collections.emptyList();
}
- ActiveStates includedStates = constraints.getIncludedStates();
- if (!includedStates.isNewOn() && !includedStates.isFuzzyOn() && !includedStates.isTranslatedOn())
+ // FIXME this looks like it assumes only 3 states and would not work properly for getting
+ // e.g. only approved strings while there is a search active.
+ ContentStateGroup includedStates = constraints.getIncludedStates();
+ if (!includedStates.hasNew() && !includedStates.hasFuzzy() && !includedStates.hasTranslated())
{
// including nothing
return Collections.emptyList();
@@ -300,19 +302,19 @@ private List findTextFlowsWithHibernateSearch(String projectSlug, Str
}
targetQuery.add(localeQuery, Occur.MUST);
- if (!constraints.getIncludedStates().isTranslatedOn())
+ if (!constraints.getIncludedStates().hasTranslated())
{
TermQuery approvedStateQuery = new TermQuery(new Term(IndexFieldLabels.CONTENT_STATE_FIELD, ContentState.Approved.toString()));
targetQuery.add(approvedStateQuery, Occur.MUST_NOT);
}
- if (!constraints.getIncludedStates().isFuzzyOn())
+ if (!constraints.getIncludedStates().hasFuzzy())
{
TermQuery approvedStateQuery = new TermQuery(new Term(IndexFieldLabels.CONTENT_STATE_FIELD, ContentState.NeedReview.toString()));
targetQuery.add(approvedStateQuery, Occur.MUST_NOT);
}
- if (!constraints.getIncludedStates().isNewOn())
+ if (!constraints.getIncludedStates().hasNew())
{
TermQuery approvedStateQuery = new TermQuery(new Term(IndexFieldLabels.CONTENT_STATE_FIELD, ContentState.New.toString()));
targetQuery.add(approvedStateQuery, Occur.MUST_NOT);
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 fe76eb80dd..a412836c76 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
@@ -35,12 +35,12 @@
import org.zanata.exception.ZanataServiceException;
import org.zanata.model.HLocale;
import org.zanata.model.HTextFlow;
-import org.zanata.search.ActiveStates;
import org.zanata.search.FilterConstraints;
import org.zanata.security.ZanataIdentity;
import org.zanata.service.LocaleService;
import org.zanata.service.ValidationService;
import org.zanata.webtrans.server.ActionHandlerFor;
+import org.zanata.webtrans.shared.model.ContentStateGroup;
import org.zanata.webtrans.shared.model.TransUnit;
import org.zanata.webtrans.shared.rpc.GetTransUnitList;
import org.zanata.webtrans.shared.rpc.GetTransUnitListResult;
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ContentStateGroup.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ContentStateGroup.java
new file mode 100644
index 0000000000..a104b68cd7
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ContentStateGroup.java
@@ -0,0 +1,183 @@
+package org.zanata.webtrans.shared.model;
+
+import java.util.List;
+
+import org.zanata.common.ContentState;
+
+import com.google.common.collect.Lists;
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+import lombok.ToString;
+
+@ToString
+public class ContentStateGroup implements IsSerializable
+{
+ private boolean hasNew;
+ private boolean hasFuzzy;
+ private boolean hasTranslated;
+ private boolean hasApproved;
+ private boolean hasRejected;
+
+ private ContentStateGroup()
+ {
+ // This exists to allow GWT to serialize
+ }
+
+ private ContentStateGroup(boolean includeNew, boolean includeFuzzy, boolean includeTranslated,
+ boolean includeApproved, boolean includeRejected)
+ {
+ hasNew = includeNew;
+ hasFuzzy = includeFuzzy;
+ hasTranslated = includeTranslated;
+ hasApproved = includeApproved;
+ hasRejected = includeRejected;
+ }
+
+ /**
+ * @return a Builder with all states on by default
+ */
+ public static Builder builder()
+ {
+ return new Builder();
+ }
+
+ public boolean hasNew()
+ {
+ return hasNew;
+ }
+
+ public boolean hasFuzzy()
+ {
+ return hasFuzzy;
+ }
+
+ public boolean hasTranslated()
+ {
+ return hasTranslated;
+ }
+
+ public boolean hasApproved()
+ {
+ return hasApproved;
+ }
+
+ public boolean hasRejected()
+ {
+ return hasRejected;
+ }
+
+ public boolean hasAllStates()
+ {
+ return hasNew && hasFuzzy && hasTranslated && hasApproved && hasRejected;
+ }
+
+ public boolean hasNoStates()
+ {
+ return !(hasNew || hasFuzzy || hasTranslated || hasApproved || hasRejected);
+ }
+
+ public List asList()
+ {
+ List result = Lists.newArrayList();
+ if (hasNew)
+ {
+ result.add(ContentState.New);
+ }
+ if (hasFuzzy)
+ {
+ result.add(ContentState.NeedReview);
+ }
+ if (hasTranslated)
+ {
+ result.add(ContentState.Translated);
+ }
+ if (hasApproved)
+ {
+ result.add(ContentState.Approved);
+ }
+ if (hasRejected)
+ {
+ result.add(ContentState.Rejected);
+ }
+ return result;
+ }
+
+ public static class Builder
+ {
+ private boolean hasNew;
+ private boolean hasFuzzy;
+ private boolean hasTranslated;
+ private boolean hasApproved;
+ private boolean hasRejected;
+
+ public Builder()
+ {
+ addAll();
+ }
+
+ public ContentStateGroup build()
+ {
+ return new ContentStateGroup(hasNew, hasFuzzy, hasTranslated, hasApproved, hasRejected);
+ }
+
+ public Builder addAll()
+ {
+ this.hasNew = true;
+ this.hasFuzzy = true;
+ this.hasTranslated = true;
+ this.hasApproved = true;
+ this.hasRejected = true;
+ return this;
+ }
+
+ public Builder removeAll()
+ {
+ this.hasNew = false;
+ this.hasFuzzy = false;
+ this.hasTranslated = false;
+ this.hasApproved = false;
+ this.hasRejected = false;
+ return this;
+ }
+
+ public Builder fromStates(ContentStateGroup states)
+ {
+ this.hasNew = states.hasNew;
+ this.hasFuzzy = states.hasFuzzy;
+ this.hasTranslated = states.hasTranslated;
+ this.hasApproved = states.hasApproved;
+ this.hasRejected = states.hasRejected;
+ return this;
+ }
+
+ public Builder includeNew(boolean on)
+ {
+ hasNew = on;
+ return this;
+ }
+
+ public Builder includeFuzzy(boolean on)
+ {
+ hasFuzzy = on;
+ return this;
+ }
+
+ public Builder includeTranslated(boolean on)
+ {
+ hasTranslated = on;
+ return this;
+ }
+
+ public Builder includeApproved(boolean on)
+ {
+ hasApproved = on;
+ return this;
+ }
+
+ public Builder includeRejected(boolean on)
+ {
+ hasRejected = on;
+ return this;
+ }
+ }
+}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
index 8d543385ba..00f3645aea 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
@@ -2,8 +2,8 @@
import java.util.List;
-import org.zanata.search.ActiveStates;
import org.zanata.webtrans.client.service.GetTransUnitActionContext;
+import org.zanata.webtrans.shared.model.ContentStateGroup;
import org.zanata.webtrans.shared.model.DocumentId;
import org.zanata.webtrans.shared.model.TransUnitId;
import org.zanata.webtrans.shared.model.ValidationId;
@@ -17,7 +17,7 @@ public class GetTransUnitList extends AbstractWorkspaceAction validationIds;
private TransUnitId targetTransUnitId;
@@ -34,12 +34,12 @@ private GetTransUnitList(GetTransUnitActionContext context)
count = context.getCount();
phrase = context.getFindMessage();
// @formatter :off
- filterStates = ActiveStates.builder()
- .setNewOn(context.isFilterUntranslated())
- .setFuzzyOn(context.isFilterNeedReview())
- .setTranslatedOn(context.isFilterTranslated())
- .setApprovedOn(context.isFilterApproved())
- .setRejectedOn(context.isFilterRejected())
+ filterStates = ContentStateGroup.builder()
+ .includeNew(context.isFilterUntranslated())
+ .includeFuzzy(context.isFilterNeedReview())
+ .includeTranslated(context.isFilterTranslated())
+ .includeApproved(context.isFilterApproved())
+ .includeRejected(context.isFilterRejected())
.build();
// @formatter :on
filterHasError = context.isFilterHasError();
@@ -83,34 +83,34 @@ public String getPhrase()
return this.phrase;
}
- public ActiveStates getFilterStates()
+ public ContentStateGroup getFilterStates()
{
return filterStates;
}
public boolean isFilterTranslated()
{
- return filterStates.isTranslatedOn();
+ return filterStates.hasTranslated();
}
public boolean isFilterNeedReview()
{
- return filterStates.isFuzzyOn();
+ return filterStates.hasFuzzy();
}
public boolean isFilterUntranslated()
{
- return filterStates.isNewOn();
+ return filterStates.hasNew();
}
public boolean isFilterApproved()
{
- return filterStates.isApprovedOn();
+ return filterStates.hasApproved();
}
public boolean isFilterRejected()
{
- return filterStates.isRejectedOn();
+ return filterStates.hasRejected();
}
public boolean isFilterHasError()
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
index 1ca50389b7..1f8cb9a861 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
@@ -21,8 +21,9 @@
package org.zanata.webtrans.shared.rpc;
-import org.zanata.search.ActiveStates;
import org.zanata.webtrans.client.service.GetTransUnitActionContext;
+import org.zanata.webtrans.shared.model.ContentStateGroup;
+
import com.google.common.base.Objects;
public class GetTransUnitsNavigation
@@ -30,14 +31,14 @@ public class GetTransUnitsNavigation
private Long id;
private String phrase;
- private ActiveStates activeStates;
+ private ContentStateGroup activeStates;
@SuppressWarnings("unused")
private GetTransUnitsNavigation()
{
}
- public GetTransUnitsNavigation(Long id, String phrase, ActiveStates activeStates)
+ public GetTransUnitsNavigation(Long id, String phrase, ContentStateGroup activeStates)
{
this.id = id;
this.phrase = phrase;
@@ -48,12 +49,12 @@ public GetTransUnitsNavigation(GetTransUnitActionContext context)
{
this(context.getDocument().getId().getId(),
context.getFindMessage(),
- ActiveStates.builder()
- .setNewOn(context.isFilterUntranslated())
- .setFuzzyOn(context.isFilterNeedReview())
- .setTranslatedOn(context.isFilterTranslated())
- .setApprovedOn(context.isFilterApproved())
- .setRejectedOn(context.isFilterRejected())
+ ContentStateGroup.builder()
+ .includeNew(context.isFilterUntranslated())
+ .includeFuzzy(context.isFilterNeedReview())
+ .includeTranslated(context.isFilterTranslated())
+ .includeApproved(context.isFilterApproved())
+ .includeRejected(context.isFilterRejected())
.build());
}
@@ -72,7 +73,7 @@ public String getPhrase()
return this.phrase;
}
- public ActiveStates getActiveStates()
+ public ContentStateGroup getActiveStates()
{
return activeStates;
}
From 6af192792c53b9c323419d85762c1a7b80d6da34 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Wed, 10 Jul 2013 13:28:28 +1000
Subject: [PATCH 035/184] Fix unit test for new restrictions in workspace
---
.../client/presenter/SearchResultsPresenter.java | 10 +++++-----
.../client/presenter/TransMemoryPresenter.java | 2 +-
.../webtrans/client/resources/WebTransMessages.java | 4 ++--
.../webtrans/shared/model/UserWorkspaceContext.java | 10 ++++++++++
.../webtrans/shared/model/WorkspaceRestrictions.java | 5 +++++
.../client/presenter/SearchResultsPresenterTest.java | 6 +++---
.../client/presenter/TargetContentsPresenterTest.java | 3 ++-
.../client/presenter/TransMemoryPresenterTest.java | 2 +-
8 files changed, 29 insertions(+), 13 deletions(-)
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 a40a69da8b..58b13a37d1 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
@@ -255,7 +255,7 @@ protected void onBind()
docPaths = new HashMap();
selectAllDocList = new HashMap>();
setUiForNothingSelected();
- display.setReplaceAllButtonVisible(!userWorkspaceContext.hasReadOnlyAccess());
+ display.setReplaceAllButtonVisible(userWorkspaceContext.hasWriteAccess());
display.addSearchFieldsSelect("search both", "both");
display.addSearchFieldsSelect("search target", "target");
@@ -368,7 +368,7 @@ public void onWorkspaceContextUpdated(WorkspaceContextUpdateEvent event)
userWorkspaceContext.setProjectActive(event.isProjectActive());
userWorkspaceContext.getWorkspaceContext().getWorkspaceId().getProjectIterationId().setProjectType(event.getProjectType());
- display.setReplaceAllButtonVisible(!userWorkspaceContext.hasReadOnlyAccess());
+ display.setReplaceAllButtonVisible(userWorkspaceContext.hasWriteAccess());
for (TransUnitReplaceInfo info : allReplaceInfos.values())
{
@@ -860,9 +860,9 @@ private List getAllSelected()
*/
private void fireReplaceTextEvent(List toReplace)
{
- if (userWorkspaceContext.hasReadOnlyAccess())
+ if (!userWorkspaceContext.hasWriteAccess())
{
- eventBus.fireEvent(new NotificationEvent(Severity.Warning, messages.cannotReplaceInReadOnlyMode()));
+ eventBus.fireEvent(new NotificationEvent(Severity.Warning, messages.noModifyTranslationAccess()));
return;
}
@@ -1325,7 +1325,7 @@ private int countSelectedFlows()
*/
private void setReplaceState(TransUnitReplaceInfo replaceInfo, ReplacementState replaceState)
{
- if (userWorkspaceContext.hasReadOnlyAccess())
+ if (!userWorkspaceContext.hasWriteAccess())
{
replaceInfo.setReplaceState(ReplacementState.NotAllowed);
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransMemoryPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransMemoryPresenter.java
index 7b1de63323..3992562c66 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransMemoryPresenter.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransMemoryPresenter.java
@@ -257,7 +257,7 @@ public void onTransUnitSelected(TransUnitSelectionEvent event)
@Override
public void onTransMemoryCopy(TransMemoryShortcutCopyEvent event)
{
- if (!userWorkspaceContext.hasReadOnlyAccess())
+ if (userWorkspaceContext.hasWriteAccess())
{
TransMemoryResultItem item = getTMResultOrNull(event);
if (item != null)
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 36f42a3666..e2e9b82e8b 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
@@ -199,8 +199,8 @@ public interface WebTransMessages extends Messages
@DefaultMessage("No replacements to make")
String noReplacementsToMake();
- @DefaultMessage("Replace not possible in read-only workspace")
- String cannotReplaceInReadOnlyMode();
+ @DefaultMessage("You have no access to modify translations")
+ String noModifyTranslationAccess();
@DefaultMessage("View in editor")
String viewDocInEditor();
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java
index 407455e869..7651975ff8 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java
@@ -30,6 +30,11 @@ public void setHasWriteAccess(boolean hasWriteAccess)
{
workspaceRestrictions = workspaceRestrictions.changeWriteAccess(hasWriteAccess);
}
+
+ public void setHasReviewAccess(boolean hasReviewAccess)
+ {
+ workspaceRestrictions = workspaceRestrictions.changeReviewAccess(hasReviewAccess);
+ }
public WorkspaceContext getWorkspaceContext()
{
@@ -40,6 +45,11 @@ public boolean hasReadOnlyAccess()
{
return (!getWorkspaceRestrictions().isProjectActive() || (!getWorkspaceRestrictions().isHasWriteAccess() && !getWorkspaceRestrictions().isHasReviewAccess()));
}
+
+ public boolean hasWriteAccess()
+ {
+ return (getWorkspaceRestrictions().isProjectActive() && getWorkspaceRestrictions().isHasWriteAccess());
+ }
public WorkspaceRestrictions getWorkspaceRestrictions()
{
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/WorkspaceRestrictions.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/WorkspaceRestrictions.java
index a9747c23e7..c397e04907 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/WorkspaceRestrictions.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/WorkspaceRestrictions.java
@@ -62,6 +62,11 @@ public WorkspaceRestrictions changeWriteAccess(boolean hasWriteAccess)
{
return new WorkspaceRestrictions(isProjectActive, hasWriteAccess, hasGlossaryUpdateAccess, hasReviewAccess, projectRequireReview);
}
+
+ public WorkspaceRestrictions changeReviewAccess(boolean hasReviewAccess)
+ {
+ return new WorkspaceRestrictions(isProjectActive, hasWriteAccess, hasGlossaryUpdateAccess, hasReviewAccess, projectRequireReview);
+ }
@Override
public String toString()
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/SearchResultsPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/SearchResultsPresenterTest.java
index c8205bc1c2..d458489a1e 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/SearchResultsPresenterTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/SearchResultsPresenterTest.java
@@ -244,8 +244,8 @@ public void testExpectedActionsOnBind()
when(mockKeyShortcutPresenter.register(capturedKeyShortcuts.capture())).thenReturn(handlerRegistration);
when(mockDataProviderDoc1.getList()).thenReturn(dataProviderDoc1List);
- boolean workspaceIsReadOnly = false;
- when(mockUserWorkspaceContext.hasReadOnlyAccess()).thenReturn(workspaceIsReadOnly);
+ boolean hasModifyTranslationAccess = true;
+ when(mockUserWorkspaceContext.hasWriteAccess()).thenReturn(hasModifyTranslationAccess);
searchResultsPresenter.bind();
@@ -259,7 +259,7 @@ public void testExpectedActionsOnBind()
verify(mockEventBus).addHandler(eq(WorkspaceContextUpdateEvent.getType()), capturedWorkspaceContextUpdatedEventHandler.capture());
- verify(mockDisplay).setReplaceAllButtonVisible(!workspaceIsReadOnly);
+ verify(mockDisplay).setReplaceAllButtonVisible(hasModifyTranslationAccess);
verify(mockDisplay).setReplaceAllButtonEnabled(false);
verify(mockDisplay).addSearchFieldsSelect("search target", "target");
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TargetContentsPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TargetContentsPresenterTest.java
index 103eb2ece2..703c224047 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TargetContentsPresenterTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TargetContentsPresenterTest.java
@@ -440,7 +440,8 @@ public void canGetConfigState()
public void testIsDisplayButtons()
{
userWorkspaceContext.setHasWriteAccess(false);
-
+ userWorkspaceContext.setHasReviewAccess(false);
+
boolean displayButtons = presenter.isDisplayButtons();
assertThat(displayButtons, Matchers.is(false));
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TransMemoryPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TransMemoryPresenterTest.java
index f287e2e2f5..65a9c1446e 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TransMemoryPresenterTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TransMemoryPresenterTest.java
@@ -374,7 +374,7 @@ public void testOnTransUnitSelected()
public void testOnTransMemoryCopy()
{
presenter.setStatesForTesting(Lists.newArrayList(transMemoryResultItem), null);
- when(userWorkspaceContext.hasReadOnlyAccess()).thenReturn(false);
+ when(userWorkspaceContext.hasWriteAccess()).thenReturn(true);
List targetContents = Lists.newArrayList("a");
when(transMemoryResultItem.getTargetContents()).thenReturn(targetContents);
From b75e3966fcf3d9f33d7495853889d054b4d342e1 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 10 Jul 2013 14:48:42 +1000
Subject: [PATCH 036/184] prevent TextFlowDAO from conflating states in queries
---
.../main/java/org/zanata/dao/TextFlowDAO.java | 36 +++++-----
.../java/org/zanata/dao/TextFlowDAOTest.java | 72 ++++++++++++-------
2 files changed, 65 insertions(+), 43 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
index 8ed888ded6..e3f613cbbf 100644
--- a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
@@ -128,7 +128,7 @@ public List getNavigationByDocumentId(Long documentId, HLocale hLocal
.append(" WHERE tf.document_id = :docId AND tf.obsolete = 0");
queryBuilder
.append(" AND ")
- .append(buildContentStateCondition(filterConstraints, "tft"));
+ .append(buildContentStateCondition(filterConstraints.getIncludedStates(), "tft"));
boolean hasSearchString = !Strings.isNullOrEmpty(filterConstraints.getSearchString());
if (hasSearchString)
{
@@ -163,16 +163,12 @@ public List getNavigationByDocumentId(Long documentId, HLocale hLocal
* This will build a SQL query condition in where clause.
* If all status are equal (i.e. all true or all false), it's treated as accept all and it will return '1'.
*
- * @param acceptApproved accept approved status
- * @param acceptFuzzy accept fuzzy status
- * @param acceptUntranslated accept untranslated status
- * @param alias HTextFlowTarget alias
+ * @param includedStates
+ * @param hTextFlowTargetTableAlias alias being used for the target table in the current query
* @return '1' if accept all status or a SQL condition clause with target content state conditions in parentheses '()' joined by 'or'
*/
- protected static String buildContentStateCondition(FilterConstraints constraints, String alias)
+ protected static String buildContentStateCondition(ContentStateGroup includedStates, String hTextFlowTargetTableAlias)
{
-
- ContentStateGroup includedStates = constraints.getIncludedStates();
if (includedStates.hasAllStates() || includedStates.hasNoStates())
{
return "1";
@@ -180,20 +176,26 @@ protected static String buildContentStateCondition(FilterConstraints constraints
StringBuilder builder = new StringBuilder();
builder.append("(");
List conditions = Lists.newArrayList();
- final String column = alias + ".state";
- if (constraints.getIncludedStates().hasTranslated())
+ final String stateColumn = hTextFlowTargetTableAlias + ".state";
+ if (includedStates.hasNew())
+ {
+ conditions.add(stateColumn + "=0 or " + stateColumn + " is null");
+ }
+ if (includedStates.hasFuzzy())
+ {
+ conditions.add(stateColumn + "=1");
+ }
+ if (includedStates.hasTranslated())
{
- conditions.add(column + "=2"); // Translated
- conditions.add(column + "=3"); // Approved
+ conditions.add(stateColumn + "=2");
}
- if (constraints.getIncludedStates().hasFuzzy())
+ if (includedStates.hasApproved())
{
- conditions.add(column + "=1"); // Fuzzy
- conditions.add(column + "=4"); // Rejected
+ conditions.add(stateColumn + "=3");
}
- if (constraints.getIncludedStates().hasNew())
+ if (includedStates.hasRejected())
{
- conditions.add(column + "=0 or " + column + " is null");
+ conditions.add(stateColumn + "=4");
}
Joiner joiner = Joiner.on(" or ");
joiner.appendTo(builder, conditions);
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index 2b9616fead..f9a5d27d2d 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -19,6 +19,7 @@
import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
import org.zanata.search.FilterConstraints;
+import org.zanata.webtrans.shared.model.ContentStateGroup;
import org.zanata.webtrans.shared.model.DocumentId;
@Test(groups = { "jpa-tests" })
@@ -174,69 +175,88 @@ public void thisBreaksForSomeReason() {
public void canBuildAcceptAllQuery()
{
String contentStateCondition = TextFlowDAO.buildContentStateCondition(
- FilterConstraints.builder().keepAll().build(), "tft");
+ ContentStateGroup.builder().addAll().build(), "tft");
assertThat("Conditional that accepts all should be '1'", contentStateCondition, is("1"));
}
+ // FIXME the 'none == all' logic should be limited to the editor
@Test
public void canBuildAcceptAllQueryWhenNoStatesSelected()
{
String contentStateCondition = TextFlowDAO.buildContentStateCondition(
- FilterConstraints.builder().keepNone().build(), "tft");
+ ContentStateGroup.builder().removeAll().build(), "tft");
assertThat("Conditional that accepts all should be '1'", contentStateCondition, is("1"));
}
@Test
public void canBuildNewOnlyConditional()
{
- FilterConstraints constraints = FilterConstraints.builder()
- .keepNone().includeNew().build();
- String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
+ ContentStateGroup contentStates = ContentStateGroup.builder()
+ .removeAll().includeNew(true).build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(contentStates, "tft");
assertThat(contentStateCondition, is("(tft.state=0 or tft.state is null)"));
}
@Test
public void canBuildFuzzyOnlyConditional()
{
- FilterConstraints constraints = FilterConstraints.builder()
- .keepNone().includeFuzzy().build();
- String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
- assertThat(contentStateCondition, is("(tft.state=1 or tft.state=4)"));
+ ContentStateGroup contentStates = ContentStateGroup.builder()
+ .removeAll().includeFuzzy(true).build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(contentStates, "tft");
+ assertThat(contentStateCondition, is("(tft.state=1)"));
}
@Test
public void canBuildTranslatedOnlyConditional()
{
- FilterConstraints constraints = FilterConstraints.builder()
- .keepNone().includeTranslated().build();
- String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
- assertThat(contentStateCondition, is("(tft.state=2 or tft.state=3)"));
+ ContentStateGroup contentStates = ContentStateGroup.builder()
+ .removeAll().includeTranslated(true).build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(contentStates, "tft");
+ assertThat(contentStateCondition, is("(tft.state=2)"));
}
@Test
- public void canBuildContentStateQuery()
+ public void canBuildApprovedOnlyConditional()
{
- FilterConstraints constraints = FilterConstraints.builder()
- .keepNone().includeNew().includeFuzzy().build();
- String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
- assertThat(contentStateCondition, is("(tft.state=1 or tft.state=4 or tft.state=0 or tft.state is null)"));
+ ContentStateGroup contentStates = ContentStateGroup.builder()
+ .removeAll().includeApproved(true).build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(contentStates, "tft");
+ assertThat(contentStateCondition, is("(tft.state=3)"));
+ }
+
+ @Test
+ public void canBuildRejectedOnlyConditional()
+ {
+ ContentStateGroup contentStates = ContentStateGroup.builder()
+ .removeAll().includeRejected(true).build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(contentStates, "tft");
+ assertThat(contentStateCondition, is("(tft.state=4)"));
+ }
+
+ @Test
+ public void canBuildNewAndFuzzyConditional()
+ {
+ ContentStateGroup contentStates = ContentStateGroup.builder()
+ .removeAll().includeNew(true).includeFuzzy(true).build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(contentStates, "tft");
+ assertThat(contentStateCondition, is("(tft.state=0 or tft.state is null or tft.state=1)"));
}
@Test
public void canBuildNewAndTranslatedConditional()
{
- FilterConstraints constraints = FilterConstraints.builder()
- .keepNone().includeNew().includeTranslated().build();
- String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
- assertThat(contentStateCondition, is("(tft.state=2 or tft.state=3 or tft.state=0 or tft.state is null)"));
+ ContentStateGroup contentStates = ContentStateGroup.builder()
+ .removeAll().includeNew(true).includeTranslated(true).build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(contentStates, "tft");
+ assertThat(contentStateCondition, is("(tft.state=0 or tft.state is null or tft.state=2)"));
}
@Test
public void canBuildFuzzyAndTranslatedConditional()
{
- FilterConstraints constraints = FilterConstraints.builder()
- .keepNone().includeFuzzy().includeTranslated().build();
- String contentStateCondition = TextFlowDAO.buildContentStateCondition(constraints, "tft");
- assertThat(contentStateCondition, is("(tft.state=2 or tft.state=3 or tft.state=1 or tft.state=4)"));
+ ContentStateGroup contentStates = ContentStateGroup.builder()
+ .removeAll().includeFuzzy(true).includeTranslated(true).build();
+ String contentStateCondition = TextFlowDAO.buildContentStateCondition(contentStates, "tft");
+ assertThat(contentStateCondition, is("(tft.state=1 or tft.state=2)"));
}
@Test
From 39c1da832c98d284be3ca41f1c2b8ca80f7761d6 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 10 Jul 2013 16:24:55 +1000
Subject: [PATCH 037/184] fix syntax error in inline css in
TransFilterView.ui.xml
This error was leading to several lines of warnings in the gwt build.
---
.../java/org/zanata/webtrans/client/view/TransFilterView.ui.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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..68234e244e 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 {
From f71b38466f3218e3e78fabbd9ce5a756a72e20cf Mon Sep 17 00:00:00 2001
From: David Mason
Date: Thu, 11 Jul 2013 12:14:27 +1000
Subject: [PATCH 038/184] refactor filter state checkbox update code for
readability
---
.../webtrans/client/history/HistoryToken.java | 4 +-
.../webtrans/client/view/TransFilterView.java | 59 ++++++-------------
2 files changed, 20 insertions(+), 43 deletions(-)
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/view/TransFilterView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransFilterView.java
index dafd8695a5..217f8bba00 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,7 +27,6 @@
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;
@@ -35,7 +34,7 @@
import com.google.gwt.uibinder.client.UiHandler;
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.HasValue;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
@@ -53,10 +52,10 @@ public class TransFilterView extends Composite implements TransFilterDisplay
@UiField
CheckBox translatedChk, fuzzyChk, untranslatedChk, approvedChk, rejectedChk, hasErrorChk;
-
+
@UiField
CheckBox incompleteChk, completeChk;
-
+
private String hintMessage;
private boolean focused = false;
@@ -198,52 +197,30 @@ 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());
+ updateStateCheckboxGroups();
+ listener.messageFilterOptionChanged(translatedChk.getValue(), fuzzyChk.getValue(),
+ untranslatedChk.getValue(), approvedChk.getValue(), rejectedChk.getValue(), hasErrorChk.getValue());
}
-
- public void toggleCompleteChk()
+
+ private void updateStateCheckboxGroups()
{
- 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);
- }
+ // TODO show intermediate state if some but not all are checked
+ incompleteChk.setValue(allChecked(untranslatedChk, fuzzyChk, rejectedChk));
+ completeChk.setValue(allChecked(translatedChk, approvedChk));
}
-
- public void toggleIncompleteChk()
+
+ private static boolean allChecked(CheckBox... toggles)
{
- if(untranslatedChk.getValue() == fuzzyChk.getValue() && fuzzyChk.getValue() == rejectedChk.getValue() && rejectedChk.getValue())
+ for (HasValue toggle : toggles)
{
- if(rejectedChk.getValue() == true)
- {
- incompleteChk.setValue(true);
- }
- else
+ if (!toggle.getValue())
{
- incompleteChk.setValue(false);
+ return false;
}
}
- else
- {
- //Should be indeterminate states if all checkboxes has different states
- incompleteChk.setValue(false);
- }
+ return true;
}
-
+
@UiHandler("incompleteChk")
public void onIncompleteChkChanged(ValueChangeEvent event)
{
From fe9691c874b0ba31fed84d92c9a7854aa5bc25e3 Mon Sep 17 00:00:00 2001
From: Damian Jansen
Date: Thu, 11 Jul 2013 13:04:49 +1000
Subject: [PATCH 039/184] Make RFC2822 and username tests use Theories rather
than loops
Control functions (for, if, etc) in tests are bad. The (experimental) Therories
class looks to handle data based tests quite elegantly.
Move username and email validation to separate classes to test.
Also, fix minor bug in GlossaryTestSuite (database reset rules) and
give the Register tests a waitFor for the fields/errors to become visible,
to prevent element stale / not found problems.
---
.../org/zanata/page/account/RegisterPage.java | 69 ++-
.../main/java/org/zanata/util/RFC2822.java | 429 +++++++++---------
.../feature/account/RFC2822NegativeTest.java | 78 ++++
.../feature/account/RFC2822PositiveTest.java | 56 +++
.../feature/account/RegisterDetailedTest.java | 130 +-----
.../feature/account/RegisterTestSuite.java | 42 ++
.../account/UsernameValidationTest.java | 79 ++++
.../feature/glossary/GlossaryTestSuite.java | 2 +-
8 files changed, 560 insertions(+), 325 deletions(-)
create mode 100644 functional-test/src/test/java/org/zanata/feature/account/RFC2822NegativeTest.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/account/RFC2822PositiveTest.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java
diff --git a/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java b/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java
index bc61baa12c..d2c4c834cb 100644
--- a/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java
+++ b/functional-test/src/main/java/org/zanata/page/account/RegisterPage.java
@@ -1,12 +1,37 @@
+/*
+ * 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.page.account;
-import java.util.Map;
+import com.google.common.base.Function;
+import lombok.extern.slf4j.Slf4j;
+import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.zanata.page.AbstractPage;
-import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
/**
* @author Damian Jansen djansen@redhat.com
@@ -42,6 +67,16 @@ public class RegisterPage extends AbstractPage
public RegisterPage(WebDriver driver)
{
super(driver);
+ List elements = new ArrayList();
+ elements.add("registerForm:nameField:name");
+ elements.add("registerForm:emailField:email");
+ elements.add("registerForm:usernameField:username");
+ elements.add("registerForm:passwordField:password");
+ elements.add("registerForm:passwordConfirmField:passwordConfirm");
+ elements.add("registerForm:captcha:verifyCaptcha");
+ elements.add("registerForm:agreedToTerms:agreedToTerms");
+ elements.add("registerForm:registerButton");
+ waitForPage(elements);
}
public RegisterPage enterName(String name)
@@ -86,6 +121,7 @@ public RegisterPage clickTerms()
return new RegisterPage(getDriver());
}
+ // TODO: Add a "signup success" page
public AbstractPage register()
{
registerButton.click();
@@ -124,4 +160,33 @@ public RegisterPage setFields(Map fields)
enterCaptcha(fields.get("captcha"));
return new RegisterPage(getDriver());
}
+
+ public List waitForErrors()
+ {
+ waitForTenSec().until(new Function()
+ {
+ @Override
+ public WebElement apply(WebDriver driver)
+ {
+ return getDriver().findElement(By.xpath("//span[@class='errors']"));
+ }
+ });
+ return getErrors();
+ }
+
+ /*
+ * Wait for all necessary entities to be available
+ */
+ private void waitForPage(List elements) {
+ for (final String element : elements) {
+ waitForTenSec().until(new Function()
+ {
+ @Override
+ public WebElement apply(WebDriver driver)
+ {
+ return getDriver().findElement(By.id(element));
+ }
+ });
+ }
+ }
}
diff --git a/functional-test/src/main/java/org/zanata/util/RFC2822.java b/functional-test/src/main/java/org/zanata/util/RFC2822.java
index d4937a46a6..f30784ec5f 100644
--- a/functional-test/src/main/java/org/zanata/util/RFC2822.java
+++ b/functional-test/src/main/java/org/zanata/util/RFC2822.java
@@ -1,3 +1,23 @@
+/*
+ * 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.util;
import java.util.HashMap;
@@ -20,10 +40,6 @@ public class RFC2822 {
* e.g. me, myself, example, com in me.myself@example.com
* quote / quoting: a section of the localpart contained within quotation marks
*
- * BUG982048
- * This defect is an list of all items that, valid or invalid, are not correctly recognised by the email validation
- * in Zanata.
- *
* Untested:
* RFC2822, section 3.4.1
* The contents of a bracketed domain can have a \ precede a character to escape it,
@@ -37,246 +53,235 @@ public class RFC2822 {
* The maximum allowable length of an email address is 320 characters.
*/
- public static Map invalidEmailAddresses()
- {
- Map invalidEmailAddresses = new HashMap();
-
- /*
- * RFC 2822, section 3.4.1
- * Email addresses consist of a local part, the "@" symbol, and the domain.
- */
- invalidEmailAddresses.put("3.4.1 Plain address", "plainaddress");
- invalidEmailAddresses.put("3.4.1 Missing @", "email.example.com");
- invalidEmailAddresses.put("3.4.1 Missing localpart", "@example.com");
- invalidEmailAddresses.put("3.4.1 Missing domain", "email@");
- invalidEmailAddresses.put("3.4.1 Two @ sign", "email@example@example.com");
+ /*
+ * VALID EMAIL ADDRESSES
+ */
+ /*
+ * RFC 2822, section 3.4.1
+ * Email addresses consist of a local part, the "@" symbol, and the domain.
+ */
+ public static String BASIC_EMAIL = "email@example.com";
- /*
- * RFC 2822, section 3.4.1
- * No periods can start or end the local part.
- * Two periods together is invalid.
- */
- invalidEmailAddresses.put("3.4.1 Leading dot", ".email@example.com");
- invalidEmailAddresses.put("3.4.1 Trailing dot", "email.@example.com");
- invalidEmailAddresses.put("3.4.1 Multiple dots", "email..email@example.com");
+ /*
+ * RFC 2822, sections 3.4.1 and 4.4
+ * The local part can be unquoted, quoted in its entirety, or quoted on a per-label basis.
+ * The quoted local part starts with a quotation mark, ends with a quotation mark.
+ */
+ // BUG982048
+ public static String BASIC_QUOTED_EMAIL = "\"email\"@example.com";
- /*
- * RFC 2822, section 2.2
- * All email addresses are in 7-bit US ASCII.
- */
- // BUG982048invalidEmailAddresses.put("3.4.1 Non unicode characters", "あいうえお@example.com");
+ /*
+ * RFC 2822, section 3.4.1
+ * TEXT can contain alphabetic, numeric, and these symbols: !#$%'*+-/=?^_`{|}~
+ */
+ public static String SPECIAL_CHARACTERS_LOCALPART = "email.!#$%'*+-/=?^_`{|}~.dot@example.com";
- /*
- * RFC 2822, section 3.4.1
- * Unquoted local parts can consist of TEXT
- * TEXT can contain:
- * alphabetic
- * numeric
- * and symbols !#$%'*+-/=?^_`{|}~
- */
- invalidEmailAddresses.put("3.4.1 Invalid unquoted character", "test,user@example.com");
- invalidEmailAddresses.put("3.4.1 Invalid unquoted character", "test(user@example.com");
- invalidEmailAddresses.put("3.4.1 Invalid unquoted character", "test)user@example.com");
+ /*
+ RFC 2822, section 4.4
+ If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
+ or quoted chunks separated by periods.
+ */
+ public static String ENCLOSED_QUOTED_LABEL = "dot.\"email\".dot@example.com";
+ public static String LOCALPART_WITH_EMPTY_QUOTE = "dot.\"\".dot@example.com";
- /*
- * RFC 2822, section 3.4.1
- * The quoted local part starts with a quotation mark, ends with a quotation mark.
- */
- invalidEmailAddresses.put("3.4.1 Invalid quoting", "test\"user@example.com");
+ /*
+ * RFC 2822, section 3.4.1
+ * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
+ * This supersedes the previous rule, allowing spaces and quotation marks in the email address as long as they
+ * are escaped.
+ */
+ public static String QUOTED_ESCAPED_SPECIAL_CHARACTERS = "email.\"(),:;<>\\@\\[\\]\\\\\"@example.com";
+ public static String QUOTED_ESCAPED_QUOTES = "email.\"\\\"\"@example.com";
+ public static String QUOTED_WITH_SPACE = "\"special\\ email\"@example.com";
- /*
- * RFC 2822, section 4.4
- * If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
- * or quoted chunks separated by periods
- */
- invalidEmailAddresses.put("3.4.1 Invalid quoting", "\"test\"user@example.com");
- invalidEmailAddresses.put("4.4 Invalid quoting", "\"test\"quote\"user@example.com");
+ /*
+ * RFC 2822, section 3.4.1
+ * The domain can be bracketed or plain.
+ */
+ public static String BRACKETED_DOMAIN = "email@[example.com]";
+ public static String BRACKETED_IPV4_DOMAIN = "email@[123.45.67.89]";
+ public static String BRACKETED_IPV6_DOMAIN = "email@[IPv6:2001:2d12:c4fe:5afe::1]";
- /*
- * RFC 2822, section 3.4.1
- * The contents of a quoted local part can not contain characters:
- * 9 (TAB)
- * 10 (LF)
- * 13 (CR)
- * 32 (space)
- * 34 (")
- * 91-94 ([, \, ], ^)
- */
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test,user\"@example.com");
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test\\user\"@example.com");
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test[user\"@example.com");
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test]user\"@example.com");
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test^user\"@example.com");
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test user\"@example.com");
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "\"test\"user\"@example.com");
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "test.\"".concat("\t").concat("\".user@example.com"));
+ /*
+ * RFC 1035, section 2.3.4
+ * A plain domain consists of labels separated with periods. No period can start or end a domain name.
+ */
+ public static String LOCALPART_MULTIPLE_LABELS = "another.email@example.com";
+ public static String DOMAIN_MULTIPLE_LABELS = "email@another.example.com";
- /*
- * RFC 2822, section 3.4.1
- * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
- */
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "test.\"\\".concat("\r").concat("\".user@example.com"));
- invalidEmailAddresses.put("3.4.1 Invalid quoted character", "test.\"\\".concat("\n").concat("\".user@example.com"));
+ /*
+ * RFC 1035, section 2.3.4
+ * The maximum length of a label is 63 characters.
+ */
+ public static String DOMAIN_LABEL_MAX_CHARACTERS =
+ "email@B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8.com";
+ public static String LOCALPART_LABEL_MAX_CHARACTERS =
+ "B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8@example.com";
/*
* RFC 1035, section 2.3.4
- * A plain domain consists of labels separated with periods. No period can start or end a domain name.
- * No two periods in succession can be in a domain name.
+ * A label may contain hyphens, but no two hyphens in a row.
*/
- invalidEmailAddresses.put("RFC1035-2.3.4 Trailing dot in domain", "email@example.com.");
- invalidEmailAddresses.put("RFC1035-2.3.4 Leading dot in domain", "email@.example.com");
- invalidEmailAddresses.put("RFC1035-2.3.4 Multiple dots in domain", "email@example..com");
+ public static String HYPHENATED_DOMAIN_LABEL = "email@another-example.com";
+ public static String HYPHENATED_LOCALPART_LABEL = "my-email@example.com";
- /*
- * RFC 2822, section 3.4.1
- * Bracketed domains must:
- * start with [, end with ]
- * not contain characters 9 (TAB), 10 (LF), 13 (CR), 32 (space), 91-94 ([, \, ], ^)
- */
- invalidEmailAddresses.put("3.4.1 Incorrectly quoted domain", "email@[example].com");
- invalidEmailAddresses.put("3.4.1 Incorrectly quoted domain", "email@[ex^ample.com]");
- invalidEmailAddresses.put("3.4.1 Incorrectly quoted domain", "email@[exa\\mple].com");
+ /*
+ * RFC 2821, section 4.5.3.1
+ * The maximum length of the local part is 64 characters.
+ */
+ public static String LOCALPART_MAX_LENGTH =
+ "B3NQyUsDdzODMoymfDdifn6Wztx2wrivm.80LEngHGl182frm6ifCPyv5SntbDg8@example.com";
- /*
- * RFC 1035, section 2.3.4
- * The maximum length of a label is 63 characters.
- */
- // BUG982048 invalidEmailAddresses.put("RFC1035-2.3.4 Domain label too long",
- // "email@IJUr9P6Y7Fx7rFy4sziQDT0qvSC7XKK6jrD0CNC41jorAKgFYIXLTN5ITJLohy58.com");
- /*
- * RFC 1035, section 2.3.4
- * A label may contain hyphens, but no two hyphens in a row.
- * A label must not start nor end with a hyphen.
- */
- // BUG982048 invalidEmailAddresses.put("2.3.4 Leading dash in domain", "email@-example.com");
- // BUG982048 invalidEmailAddresses.put("2.3.4 Trailing dash in domain", "email@example-.com");
- // BUG982048 invalidEmailAddresses.put("2.3.4 Multiple dashes in domain", "email@exa--mple.com");
- invalidEmailAddresses.put("2.3.4 Leading dash in bracketed domain", "email@[-example.com]");
- invalidEmailAddresses.put("2.3.4 Trailing dash in bracketed domain", "email@[example.com-]");
- invalidEmailAddresses.put("2.3.4 Multiple dashes in bracketed domain", "email@[exa--mple.com]");
+ /*
+ * INVALID EMAIL ADDRESSES
+ */
- /*
- * The contents of a bracketed domain can have a \ precede a character to escape it, and the following character
- * must not be 10 (LF) or 13 (CR).
- */
- invalidEmailAddresses.put("3.4.1 Invalid bracketed domain", "test@[\\".concat("\r").concat("example.com]"));
- invalidEmailAddresses.put("3.4.1 Invalid bracketed domain", "test@[\\".concat("\n").concat("example.com]"));
+ /*
+ * RFC 2822, section 3.4.1
+ * Email addresses consist of a local part, the "@" symbol, and the domain.
+ */
+ public static String PLAIN_ADDRESS = "plainaddress";
+ public static String MISSING_AMPERSAT = "email.example.com";
+ public static String MISSING_LOCALPART = "@example.com";
+ public static String MISSING_DOMAIN = "email@";
+ public static String MULTIPLE_APERSAT = "email@example@example.com";
- /*
- * RFC 2821, section 4.5.3.1
- * The maximum length of the local part is 64 characters.
- */
- invalidEmailAddresses.put("RFC2821-4.5.3.1 Max localpart length is 64",
- "emailuhpealgyxntsh5upl5gqn5a4ruqs7mw6wz21j6dn72amzwozqlyua4jx16rd@example.com");
+ /*
+ * RFC 2822, section 3.4.1
+ * No periods can start or end the local part.
+ * Two periods together is invalid.
+ */
+ public static String LEADING_DOT = ".email@example.com";
+ public static String TRAILING_DOT = "email.@example.com";
+ public static String MULTIPLE_DOTS = "email..email@example.com";
- /*
- * RFC 3696, section 2
- * The top level domain must be all alphabetic.
- */
- invalidEmailAddresses.put("RFC3696-2 Encoded html", "Joe Smith ");
- invalidEmailAddresses.put("RFC3696-2 Following text", "email@example.com (Joe Smith)");
- // BUG982048 invalidEmailAddresses.put("RFC3696-2 Invalid IP", "email@111.222.333.44444");
+ /*
+ * RFC 2822, section 2.2
+ * All email addresses are in 7-bit US ASCII.
+ */
+ public static String NON_UNICODE_CHARACTERS = "あいうえお@example.com";
- /*
- * RFC 2821, section 4.5.3.1
- * The maximum length of a "useful" email address is 255 characters.
- */
- /*
- * BUG982048
- invalidEmailAddresses.put("4.5.3.1 Max email length is 255",
- "email@"+
- "Hk3yhCtbBRw3wCT76tL1ryAdfrIaaDszHqvZqnNrZPlNn3Wd7u."+
- "RfpxrueSghp9dkGTGwT9s0fyJL850Sned72RD3Mm5PpEh6QJwQ."+
- "3CeXyEHQEhXNOQdWhYVjGBLzlHz1sJfi4lfn7ighLXcxa5cMAK."+
- "jFXsG8BVsvkODKktTXJ70bQmDWtWQzuh3oz4twumVArDGEbzS1."+
- "slyaBcQqVgUdqXTBdbMY7YJxZwrzZQBBGjCl4e.com");
- */
- return invalidEmailAddresses;
- }
+ /*
+ * RFC 2822, section 3.4.1
+ * Unquoted local parts can consist of TEXT
+ * TEXT can contain:
+ * alphabetic
+ * numeric
+ * and symbols !#$%'*+-/=?^_`{|}~
+ */
+ public static String INVALID_UNQUOTED_COMMA = "test,user@example.com";
+ public static String INVALID_UNQUOTED_LEFT_PARENTHESES = "test(user@example.com";
+ public static String INVALID_UNQUOTED_RIGHT_PARENTHESES = "test)user@example.com";
/*
- * An map of valid emails conforming to RFC2822
+ * RFC 2822, section 3.4.1
+ * The quoted local part starts with a quotation mark, ends with a quotation mark.
*/
- public static Map validEmailAddresses()
- {
- Map validEmailAddresses = new HashMap();
+ public static String INVALID_SINGLE_QUOTING = "test\"user@example.com";
- /*
- * RFC 2822, section 3.4.1
- * Email addresses consist of a local part, the "@" symbol, and the domain.
- */
- validEmailAddresses.put("3.4.1 Basic email", "email@example.com");
+ /*
+ * RFC 2822, section 4.4
+ * If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
+ * or quoted chunks separated by periods
+ */
+ public static String INVALID_QUOTING_SEPARATION = "\"test\"user@example.com";
- /*
- * RFC 2822, sections 3.4.1 and 4.4
- * The local part can be unquoted, quoted in its entirety, or quoted on a per-label basis.
- * The quoted local part starts with a quotation mark, ends with a quotation mark.
- */
- // BUG982048 validEmailAddresses.put("3.4.1 Basic quoted email", "\"email\"@example.com");
+ /*
+ * RFC 2822, section 3.4.1
+ * The contents of a quoted local part can not contain characters:
+ * 9 (TAB)
+ * 10 (LF)
+ * 13 (CR)
+ * 32 (space)
+ * 34 (")
+ * 91-94 ([, \, ], ^)
+ */
+ public static String INVALID_QUOTED_COMMA = "\"test,user\"@example.com";
+ public static String INVALID_QUOTED_BACKSLASH = "\"test\\user\"@example.com";
+ public static String INVALID_QUOTED_LEFT_BRACKET = "\"test[user\"@example.com";
+ public static String INVALID_QUOTED_RIGHT_BRACKET = "\"test]user\"@example.com";
+ public static String INVALID_QUOTED_CARAT = "\"test^user\"@example.com";
+ public static String INVALID_QUOTED_SPACE = "\"test user\"@example.com";
+ public static String INVALID_QUOTED_QUOTE = "\"test\"user\"@example.com";
+ // TODO: public static String Invalid_quoted_tab = "test.\"".concat("\t").concat("\".user@example.com");
- /*
- * RFC 2822, section 3.4.1
- * TEXT can contain alphabetic, numeric, and these symbols: !#$%'*+-/=?^_`{|}~
- */
- validEmailAddresses.put("3.4.1 Allowed special characters in localpart", "email.!#$%'*+-/=?^_`{|}~.dot@example.com");
+ /*
+ * RFC 2822, section 3.4.1
+ * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
+ */
+ public static String INVALID_QUOTED_RETURN = "test.\"\\".concat("\r").concat("\".user@example.com");
+ public static String INVALID_QUOTED_LINEFEED = "test.\"\\".concat("\n").concat("\".user@example.com");
- /*
- RFC 2822, section 4.4
- If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
- or quoted chunks separated by periods.
- */
- // BUG982048 validEmailAddresses.put("4.4 Quoted label with surrounding labels", "dot.\"email\".dot@example.com");
- // BUG982048 validEmailAddresses.put("4.4 Localpart with empty quote", "dot.\"\".dot@example.com");
+ /*
+ * RFC 1035, section 2.3.4
+ * A plain domain consists of labels separated with periods. No period can start or end a domain name.
+ * No two periods in succession can be in a domain name.
+ */
+ public static String TRAILING_DOMAIN_DOT = "email@example.com.";
+ public static String LEADING_DOMAIN_DOT = "email@.example.com";
+ public static String SUCCESSIVE_DOMAIN_DOTS = "email@example..com";
- /*
- * RFC 2822, section 3.4.1
- * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
- * This supersedes the previous rule, allowing spaces and quotation marks in the email address as long as they
- * are escaped.
- */
- // BUG982048 validEmailAddresses.put("3.4.1 Quoted email with escaped special characters", "email.\"(),:;<>\\@\\[\\]\\\\\"@example.com");
- // BUG982048 validEmailAddresses.put("3.4.1 Quoted email with escaped quotes", "email.\"\\\"\"@example.com");
- // BUG982048 validEmailAddresses.put("3.4.1 Quoted email with space character", "\"special\\ email\"@example.com");
+ /*
+ * RFC 2822, section 3.4.1
+ * Bracketed domains must:
+ * start with [, end with ]
+ * not contain characters 9 (TAB), 10 (LF), 13 (CR), 32 (space), 91-94 ([, \, ], ^)
+ */
+ public static String INCORRECTLY_BRACKETED_DOMAIN = "email@[example].com";
+ public static String INVALID_DOMAIN_CHARACTER = "email@[ex^ample.com]";
+ public static String INCORRECTLY_ESCAPED_DOMAIN = "email@[exa\\mple.com]";
- /*
- * RFC 2822, section 3.4.1
- * The domain can be bracketed or plain.
- */
- // BUG982048 validEmailAddresses.put("3.4.1 Email with bracketed domain", "email@[example.com]");
- // BUG982048 validEmailAddresses.put("3.4.1 Bracketed IPv6 domain", "email@[123.45.67.89]");
- // BUG982048 validEmailAddresses.put("3.4.1 Bracketed IPv6 domain", "email@[IPv6:2001:2d12:c4fe:5afe::1]");
+ /*
+ * RFC 1035, section 2.3.4
+ * The maximum length of a label is 63 characters.
+ */
+ public static String DOMAIN_LABEL_LENGTH_EXCEEDED =
+ "email@IJUr9P6Y7Fx7rFy4sziQDT0qvSC7XKK6jrD0CNC41jorAKgFYIXLTN5ITJLohy58.com";
- /*
- * RFC 1035, section 2.3.4
- * A plain domain consists of labels separated with periods. No period can start or end a domain name.
- */
- validEmailAddresses.put("RFC1035-2.3.4 Localpart with multiple labels", "another.email@example.com");
- validEmailAddresses.put("RFC1035-2.3.4 Domain with multiple labels", "email@another.example.com");
+ /*
+ * RFC 1035, section 2.3.4
+ * A label may contain hyphens, but no two hyphens in a row.
+ * A label must not start nor end with a hyphen.
+ */
+ public static String LEADING_DASH_DOMAIN = "email@-example.com";
+ public static String TRAILING_DASH_DOMAIN = "email@example-.com";
+ public static String MULTIPLE_DASHES_DOMAIN = "email@exa--mple.com";
+ public static String LEADING_DASH_BRACKETED_DOMAIN = "email@[-example.com]";
+ public static String TRAILING_DASH_BRACKETED_DOMAIN = "email@[example.com-]";
+ public static String MULTIPLE_DASHES_BRACKETED_DOMAIN = "email@[exa--mple.com]";
/*
- * RFC 1035, section 2.3.4
- * The maximum length of a label is 63 characters.
+ * The contents of a bracketed domain can have a \ precede a character to escape it, and the following character
+ * must not be 10 (LF) or 13 (CR).
*/
- validEmailAddresses.put("RFC1035-2.3.4 Domain label of 63 characters",
- "email@B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8.com");
- validEmailAddresses.put("RFC1035-2.3.4 Localpart label of 63 characters",
- "B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8@example.com");
+ public static String INVALID_BRACKETED_DOMAIN_RETURN = "test@[\\".concat("\r").concat("example.com]");
+ public static String INVALID_BRACKETED_DOMAIN_LINEFEED = "test@[\\".concat("\n").concat("example.com]");
- /*
- * RFC 1035, section 2.3.4
- * A label may contain hyphens, but no two hyphens in a row.
- */
- validEmailAddresses.put("RFC1035-2.3.4 Hyphenated domain label", "email@another-example.com");
- validEmailAddresses.put("RFC1035-2.3.4 Hyphenated localpart label", "my-email@example.com");
+ /*
+ * RFC 2821, section 4.5.3.1
+ * The maximum length of the local part is 64 characters.
+ */
+ public static String LOCALPART_LENGTH_EXCEEDED =
+ "emailuhpealgyxntsh5upl5gqn5a4ruqs7mw6wz21j6dn72amzwozqlyua4jx16rd@example.com";
- /*
- * RFC 2821, section 4.5.3.1
- * The maximum length of the local part is 64 characters.
- */
- validEmailAddresses.put("RFC1035-2.3.4 Localpart length of 64 characters",
- "B3NQyUsDdzODMoymfDdifn6Wztx2wrivm.80LEngHGl182frm6ifCPyv5SntbDg8@example.com");
+ /*
+ * RFC 3696, section 2
+ * The top level domain must be all alphabetic.
+ */
+ public static String INVALID_ENCODED_HTML = "Joe Smith ";
+ public static String INVALID_FOLLOWING_TEXT = "email@example.com (Joe Smith)";
+ public static String INVALID_IP_FORMAT = "email@111.222.333.44444";
- return validEmailAddresses;
- }
+ /*
+ * RFC 2821, section 4.5.3.1
+ * The maximum length of a "useful" email address is 255 characters.
+ */
+ public static String MAX_EMAIL_LENGTH_EXCEEDED =
+ "email@"+
+ "Hk3yhCtbBRw3wCT76tL1ryAdfrIaaDszHqvZqnNrZPlNn3Wd7u."+
+ "RfpxrueSghp9dkGTGwT9s0fyJL850Sned72RD3Mm5PpEh6QJwQ."+
+ "3CeXyEHQEhXNOQdWhYVjGBLzlHz1sJfi4lfn7ighLXcxa5cMAK."+
+ "jFXsG8BVsvkODKktTXJ70bQmDWtWQzuh3oz4twumVArDGEbzS1."+
+ "slyaBcQqVgUdqXTBdbMY7YJxZwrzZQBBGjCl4e.com";
}
\ No newline at end of file
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RFC2822NegativeTest.java b/functional-test/src/test/java/org/zanata/feature/account/RFC2822NegativeTest.java
new file mode 100644
index 0000000000..ea434e633d
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/account/RFC2822NegativeTest.java
@@ -0,0 +1,78 @@
+package org.zanata.feature.account;
+
+import org.hamcrest.Matchers;
+import org.junit.ClassRule;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.zanata.page.account.RegisterPage;
+import org.zanata.util.RFC2822;
+import org.zanata.util.ResetDatabaseRule;
+import org.zanata.workflow.BasicWorkFlow;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Theories.class)
+public class RFC2822NegativeTest {
+ @DataPoint public static String PLAIN_ADDRESS = RFC2822.PLAIN_ADDRESS;
+ @DataPoint public static String MISSING_AMPERSAT = RFC2822.MISSING_AMPERSAT;
+ @DataPoint public static String MISSING_LOCALPART = RFC2822.MISSING_LOCALPART;
+ @DataPoint public static String MISSING_DOMAIN = RFC2822.MISSING_DOMAIN;
+ @DataPoint public static String MULTIPLE_APERSAT = RFC2822.MULTIPLE_APERSAT;
+ @DataPoint public static String LEADING_DOT = RFC2822.LEADING_DOT;
+ @DataPoint public static String TRAILING_DOT = RFC2822.TRAILING_DOT;
+ @DataPoint public static String MULTIPLE_DOTS = RFC2822.MULTIPLE_DOTS;
+ @DataPoint public static String INVALID_UNQUOTED_COMMA = RFC2822.INVALID_UNQUOTED_COMMA;
+ @DataPoint public static String INVALID_UNQUOTED_LEFT_PARENTHESES = RFC2822.INVALID_UNQUOTED_LEFT_PARENTHESES;
+ @DataPoint public static String INVALID_UNQUOTED_RIGHT_PARENTHESES = RFC2822.INVALID_UNQUOTED_RIGHT_PARENTHESES;
+ @DataPoint public static String INVALID_SINGLE_QUOTING = RFC2822.INVALID_SINGLE_QUOTING;
+ @DataPoint public static String INVALID_QUOTING_SEPARATION = RFC2822.INVALID_QUOTING_SEPARATION;
+ @DataPoint public static String INVALID_QUOTED_COMMA = RFC2822.INVALID_QUOTED_COMMA;
+ @DataPoint public static String INVALID_QUOTED_BACKSLASH = RFC2822.INVALID_QUOTED_BACKSLASH;
+ @DataPoint public static String INVALID_QUOTED_LEFT_BRACKET = RFC2822.INVALID_QUOTED_LEFT_BRACKET;
+ @DataPoint public static String INVALID_QUOTED_RIGHT_BRACKET = RFC2822.INVALID_QUOTED_RIGHT_BRACKET;
+ @DataPoint public static String INVALID_QUOTED_CARAT = RFC2822.INVALID_QUOTED_CARAT;
+ @DataPoint public static String INVALID_QUOTED_SPACE = RFC2822.INVALID_QUOTED_SPACE;
+ @DataPoint public static String INVALID_QUOTED_QUOTE = RFC2822.INVALID_QUOTED_QUOTE;
+ @DataPoint public static String INVALID_QUOTED_RETURN = RFC2822.INVALID_QUOTED_RETURN;
+ @DataPoint public static String INVALID_QUOTED_LINEFEED = RFC2822.INVALID_QUOTED_LINEFEED;
+ @DataPoint public static String TRAILING_DOMAIN_DOT = RFC2822.TRAILING_DOMAIN_DOT;
+ @DataPoint public static String LEADING_DOMAIN_DOT = RFC2822.LEADING_DOMAIN_DOT;
+ @DataPoint public static String SUCCESSIVE_DOMAIN_DOTS = RFC2822.SUCCESSIVE_DOMAIN_DOTS;
+ @DataPoint public static String INCORRECTLY_BRACKETED_DOMAIN = RFC2822.INCORRECTLY_BRACKETED_DOMAIN;
+ @DataPoint public static String INVALID_DOMAIN_CHARACTER = RFC2822.INVALID_DOMAIN_CHARACTER;
+ @DataPoint public static String INCORRECTLY_ESCAPED_DOMAIN = RFC2822.INCORRECTLY_ESCAPED_DOMAIN;
+ @DataPoint public static String DOMAIN_LABEL_LENGTH_EXCEEDED = RFC2822.DOMAIN_LABEL_LENGTH_EXCEEDED;
+ @DataPoint public static String LEADING_DASH_BRACKETED_DOMAIN = RFC2822.LEADING_DASH_BRACKETED_DOMAIN;
+ @DataPoint public static String TRAILING_DASH_BRACKETED_DOMAIN = RFC2822.TRAILING_DASH_BRACKETED_DOMAIN;
+ @DataPoint public static String MULTIPLE_DASHES_BRACKETED_DOMAIN = RFC2822.MULTIPLE_DASHES_BRACKETED_DOMAIN;
+ @DataPoint public static String INVALID_BRACKETED_DOMAIN_RETURN = RFC2822.INVALID_BRACKETED_DOMAIN_RETURN;
+ @DataPoint public static String INVALID_BRACKETED_DOMAIN_LINEFEED = RFC2822.INVALID_BRACKETED_DOMAIN_LINEFEED;
+ @DataPoint public static String LOCALPART_LENGTH_EXCEEDED = RFC2822.LOCALPART_LENGTH_EXCEEDED;
+ @DataPoint public static String INVALID_ENCODED_HTML = RFC2822.INVALID_ENCODED_HTML;
+ @DataPoint public static String INVALID_FOLLOWING_TEXT = RFC2822.INVALID_FOLLOWING_TEXT;
+
+ // BUG982048 @DataPoint public static String INVALID_IP_FORMAT = RFC2822.INVALID_IP_FORMAT;
+ // BUG982048 @DataPoint public static String MAX_EMAIL_LENGTH_EXCEEDED = RFC2822.MAX_EMAIL_LENGTH_EXCEEDED;
+ // BUG982048 @DataPoint public static String NON_UNICODE_CHARACTERS = RFC2822.NON_UNICODE_CHARACTERS;
+ // BUG982048 @DataPoint public static String LEADING_DASH_DOMAIN = RFC2822.LEADING_DASH_DOMAIN;
+ // BUG982048 @DataPoint public static String TRAILING_DASH_DOMAIN = RFC2822.TRAILING_DASH_DOMAIN;
+ // BUG982048 @DataPoint public static String MULTIPLE_DASHES_DOMAIN = RFC2822.MULTIPLE_DASHES_DOMAIN;
+
+ @ClassRule
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
+
+ @Theory
+ public void invalidEmailRejection(String emailAddress)
+ {
+ String errorMsg = "not a well-formed email address";
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration();
+ registerPage = registerPage.enterEmail(emailAddress).clickTerms();
+ assertThat("Email validation errors are not shown", registerPage.waitForErrors(), Matchers.hasItem(errorMsg));
+ }
+
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RFC2822PositiveTest.java b/functional-test/src/test/java/org/zanata/feature/account/RFC2822PositiveTest.java
new file mode 100644
index 0000000000..c9a1932986
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/account/RFC2822PositiveTest.java
@@ -0,0 +1,56 @@
+package org.zanata.feature.account;
+
+import org.hamcrest.Matchers;
+import org.junit.ClassRule;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.zanata.page.account.RegisterPage;
+import org.zanata.util.RFC2822;
+import org.zanata.util.ResetDatabaseRule;
+import org.zanata.workflow.BasicWorkFlow;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Theories.class)
+public class RFC2822PositiveTest {
+
+ @DataPoint public static String BASIC_EMAIL = RFC2822.BASIC_EMAIL;
+ @DataPoint public static String SPECIAL_LOCALPART_CHARACTERS = RFC2822.SPECIAL_CHARACTERS_LOCALPART;
+ @DataPoint public static String LOCALPART_MULTIPLE_LABELS = RFC2822.LOCALPART_MULTIPLE_LABELS;
+ @DataPoint public static String DOMAIN_MULTIPLE_LABELS = RFC2822.DOMAIN_MULTIPLE_LABELS;
+ @DataPoint public static String DOMAIN_LABEL_MAX_CHARACTERS = RFC2822.DOMAIN_LABEL_MAX_CHARACTERS;
+ @DataPoint public static String LOCALPART_LABEL_MAX_CHARACTERS = RFC2822.LOCALPART_LABEL_MAX_CHARACTERS;
+ @DataPoint public static String HYPHENATED_DOMAIN_LABEL = RFC2822.HYPHENATED_DOMAIN_LABEL;
+ @DataPoint public static String HYPHENATED_LOCALPART_LABEL = RFC2822.HYPHENATED_LOCALPART_LABEL;
+ @DataPoint public static String LOCALPART_MAX_LENGTH = RFC2822.LOCALPART_MAX_LENGTH;
+
+ // BUG982048 @DataPoint public static String BASIC_QUOTED_EMAIL = RFC2822.BASIC_QUOTED_EMAIL;
+ // BUG982048 @DataPoint public static String ENCLOSED_QUOTED_LABEL = RFC2822.ENCLOSED_QUOTED_LABEL;
+ // BUG982048 @DataPoint public static String LOCALPART_EMPTY_QUOTE = RFC2822.LOCALPART_WITH_EMPTY_QUOTE;
+ // BUG982048 @DataPoint public static String QUOTED_ESCAPED_SPECIAL_CHARACTERS = RFC2822.QUOTED_ESCAPED_SPECIAL_CHARACTERS;
+ // BUG982048 @DataPoint public static String QUOTED_ESCAPED_QUOTES = RFC2822.QUOTED_ESCAPED_QUOTES;
+ // BUG982048 @DataPoint public static String QUOTED_WITH_SPACE = RFC2822.QUOTED_WITH_SPACE;
+ // BUG982048 @DataPoint public static String BRACKETED_DOMAIN = RFC2822.BRACKETED_DOMAIN;
+ // BUG982048 @DataPoint public static String BRACKETED_IPV4_DOMAIN = RFC2822.BRACKETED_IPV4_DOMAIN;
+ // BUG982048 @DataPoint public static String BRACKETED_IPV6_DOMAIN = RFC2822.BRACKETED_IPV6_DOMAIN;
+
+ @ClassRule
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
+
+ @Theory
+ public void validEmailAcceptance(String emailAddress)
+ {
+ String errorMsg = "not a well-formed email address";
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration();
+ registerPage = registerPage.enterEmail(emailAddress).clickTerms();
+ assertThat("Email validation errors are not shown", registerPage.getErrors(),
+ Matchers.not(Matchers.hasItem(errorMsg)));
+
+ }
+
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
index 2b03712090..4c90419e65 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
@@ -20,18 +20,22 @@
*/
package org.zanata.feature.account;
+import lombok.extern.slf4j.Slf4j;
import org.hamcrest.Matchers;
-import org.junit.*;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Test;
import org.zanata.page.HomePage;
import org.zanata.page.account.RegisterPage;
-import org.zanata.util.ResetDatabaseRule;
import org.zanata.util.RFC2822;
-import org.zanata.workflow.AbstractWebWorkFlow;
+import org.zanata.util.ResetDatabaseRule;
+import org.zanata.workflow.BasicWorkFlow;
-import java.util.*;
+import java.util.HashMap;
+import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
-import lombok.extern.slf4j.Slf4j;
/**
* @author Damian Jansen djansen@redhat.com
@@ -40,7 +44,7 @@
public class RegisterDetailedTest
{
@ClassRule
- public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule(ResetDatabaseRule.Config.WithData, ResetDatabaseRule.Config.NoResetAfter);
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
Map fields;
private HomePage homePage;
@@ -59,7 +63,7 @@ public void before()
fields.put("password", "testpassword");
fields.put("confirmpassword", "testpassword");
fields.put("captcha", "555"); // TODO: Expect captcha error, fix
- homePage = new AbstractWebWorkFlow().goToHome();
+ homePage = new BasicWorkFlow().goToHome();
}
@Test
@@ -92,62 +96,23 @@ public void usernameLengthValidation()
assertThat("Size errors are shown for string too long", registerPage.getErrors(), Matchers.hasItem(errorMsg));
}
- @Test
- public void usernameCharacterValidation()
- {
- String errorMsg = "lowercase letters and digits (regex \"^[a-z\\d_]{3,20}$\")";
- fields.put("email", "character.test@example.com");
- for (Map.Entry entry : usernameCharacterValidationData().entrySet())
- {
- log.info("Test " + entry.getKey() + ":" + entry.getValue());
- fields.put("username", entry.getValue());
- RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
- assertThat("Validation errors are shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
- }
- }
-
@Test
@Ignore("Captcha prevents test completion")
public void usernamePreExisting()
{
String errorMsg = "This username is not available";
- fields.put("email", "exists.test@test.com");
- fields.put("username", "alreadyexists");
- RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
- registerPage.register();
-
- fields.put("email", "exists2.test@test.com");
- registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
- assertThat("Username not available message is shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().enterUserName("admin");
+ assertThat("Username not available message is shown", registerPage.waitForErrors(), Matchers.hasItem(errorMsg));
}
@Test
public void emailValidation()
{
String errorMsg = "not a well-formed email address";
+ fields.put("email", RFC2822.PLAIN_ADDRESS);
fields.put("username", "emailvalidation");
- for (Map.Entry entry : RFC2822.invalidEmailAddresses().entrySet())
- {
- log.info("Test " + entry.getKey() + ":" + entry.getValue());
- fields.put("email", entry.getValue());
- RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
- assertThat("Email validation errors are shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
- }
- }
-
- @Test
- public void validEmailAcceptance()
- {
- String errorMsg = "not a well-formed email address";
- fields.put("username", "emailvalidation");
- for (Map.Entry entry : RFC2822.validEmailAddresses().entrySet())
- {
- log.info("Test " + entry.getKey() + ":" + entry.getValue());
- fields.put("email", entry.getValue());
- RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
- assertThat("Email validation errors are not shown", registerPage.getErrors(),
- Matchers.not(Matchers.hasItem(errorMsg)));
- }
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields);
+ assertThat("Email validation errors are shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
}
@Test
@@ -158,7 +123,7 @@ public void rejectIncorrectCaptcha()
fields.put("email", "rejectbadcaptcha@example.com");
fields.put("captcha", "9000");
- RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields).registerFailure();
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields).registerFailure();
assertThat("The Captcha entry is rejected", registerPage.getErrors(), Matchers.contains(errorMsg));
}
@@ -171,7 +136,7 @@ public void passwordsMatch()
fields.put("password", "passwordsmatch");
fields.put("confirmpassword", "passwordsdonotmatch");
- RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields);
assertThat("Passwords fail to match error is shown", registerPage.getErrors(), Matchers.contains(errorMsg));
}
@@ -185,7 +150,7 @@ public void requiredFields()
fields.put("password", "");
fields.put("confirmpassword", "");
- RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields);
assertThat("Value is required shows for all fields", registerPage.getErrors(),
Matchers.contains(errorMsg, errorMsg, errorMsg, errorMsg, errorMsg));
}
@@ -193,68 +158,13 @@ public void requiredFields()
/*
Bugs
*/
- @Test(expected = AssertionError.class)
- public void bug981082_inaccurateErrorMessage()
- {
- String errorMsg = "size must be between 3 and 20";
- fields.put("email", "bug981082test@test.com");
- fields.put("username", "mo");
-
- RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
- assertThat("Size errors are shown for string too short", registerPage.getErrors(), Matchers.hasItem(errorMsg));
-
- fields.put("username", "johndoeusernamevalidation");
- registerPage = registerPage.setFields(fields);
- assertThat("Size errors are shown for string too long", registerPage.getErrors(), Matchers.hasItem(errorMsg));
- }
-
@Test(expected = AssertionError.class)
public void bug981498_underscoreRules()
{
String errorMsg = "lowercase letters and digits (regex \"^[a-z\\d_]{3,20}$\")";
fields.put("email", "bug981498test@example.com");
fields.put("username", "______");
- RegisterPage registerPage = new AbstractWebWorkFlow().goToHome().goToRegistration().setFields(fields);
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields);
assertThat("A username of all underscores is not valid", registerPage.getErrors(), Matchers.hasItem(errorMsg));
}
-
- /*
- Returns a hash of invalid characters for a username
- Hash is String reason for invalid 'character', String character
- */
- private LinkedHashMap usernameCharacterValidationData()
- {
- LinkedHashMap inputData = new LinkedHashMap(100);
- inputData.put("Invalid char |", "user|name");
- inputData.put("Invalid char /", "user/name");
- inputData.put("Invalid char ", "user\\name");
- inputData.put("Invalid char +", "user+name");
- inputData.put("Invalid char *", "user*name");
- inputData.put("Invalid char |", "user|name");
- inputData.put("Invalid char (", "user(name");
- inputData.put("Invalid char )", "user)name");
- inputData.put("Invalid char $", "user$name");
- inputData.put("Invalid char [", "user[name");
- inputData.put("Invalid char ]", "user]name");
- inputData.put("Invalid char :", "user:name");
- inputData.put("Invalid char ;", "user;name");
- inputData.put("Invalid char '", "user'name");
- inputData.put("Invalid char ,", "user,name");
- inputData.put("Invalid char ?", "user?name");
- inputData.put("Invalid char !", "user!name");
- inputData.put("Invalid char @", "user@name");
- inputData.put("Invalid char #", "user#name");
- inputData.put("Invalid char %", "user%name");
- inputData.put("Invalid char ^", "user^name");
- inputData.put("Invalid char =", "user=name");
- inputData.put("Invalid char .", "user.name");
- inputData.put("Invalid char {", "user{name");
- inputData.put("Invalid char }", "user}name");
- // Capital letters are prohibited
- for (char c = 'A'; c <= 'Z'; c++) {
- String letter = String.valueOf(c);
- inputData.put("Invalid capital char ".concat(letter), "user".concat(letter).concat("name"));
- }
- return inputData;
- }
}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java b/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java
new file mode 100644
index 0000000000..5e1f36d8be
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java
@@ -0,0 +1,42 @@
+/*
+ * 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.feature.account;
+
+import org.junit.ClassRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.zanata.util.ResetDatabaseRule;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ RegisterDetailedTest.class,
+ UsernameValidationTest.class,
+ RFC2822PositiveTest.class,
+ RFC2822NegativeTest.class
+})
+public class RegisterTestSuite
+{
+ @ClassRule
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java b/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java
new file mode 100644
index 0000000000..129d3fe45b
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.feature.account;
+
+import org.hamcrest.Matchers;
+import org.junit.ClassRule;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.zanata.page.account.RegisterPage;
+import org.zanata.util.ResetDatabaseRule;
+import org.zanata.workflow.BasicWorkFlow;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Theories.class)
+public class UsernameValidationTest
+{
+ @ClassRule
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
+
+ @DataPoint public static String INVALID_PIPE = "user|name";
+ @DataPoint public static String INVALID_SLASH = "user/name";
+ @DataPoint public static String INVALID_BACKSLASH = "user\\name";
+ @DataPoint public static String INVALID_PLUS = "user+name";
+ @DataPoint public static String INVALID_ASTERISK = "user*name";
+ @DataPoint public static String INVALID_LEFT_PARENTHESES = "user(name";
+ @DataPoint public static String INVALID_RIGHT_PARENTHESES = "user)name";
+ @DataPoint public static String INVALID_DOLLAR = "user$name";
+ @DataPoint public static String INVALID_LEFT_BRACKET = "user[name";
+ @DataPoint public static String INVALID_RIGHT_BRACKET = "user]name";
+ @DataPoint public static String INVALID_COLON = "user:name";
+ @DataPoint public static String INVALID_SEMICOLON = "user;name";
+ @DataPoint public static String INVALID_APOSTROPHE = "user'name";
+ @DataPoint public static String INVALID_COMMA = "user,name";
+ @DataPoint public static String INVALID_QUESTION_MARK = "user?name";
+ @DataPoint public static String INVALID_EXCLAMATION_MARK = "user!name";
+ @DataPoint public static String INVALID_AMPERSAT = "user@name";
+ @DataPoint public static String INVALID_HASH = "user#name";
+ @DataPoint public static String INVALID_PERCENT = "user%name";
+ @DataPoint public static String INVALID_CARAT = "user^name";
+ @DataPoint public static String INVALID_EQUALS = "user=name";
+ @DataPoint public static String INVALID_PERIOD = "user.name";
+ @DataPoint public static String INVALID_LEFT_BRACE = "user{name";
+ @DataPoint public static String INVALID_RIGHT_BRACE = "user}name";
+ @DataPoint public static String INVALID_CAPITAL_A = "userAname";
+ @DataPoint public static String INVALID_CAPITAL_Z = "userZname";
+
+ @Theory
+ public void usernameCharacterValidation(String username)
+ {
+ String errorMsg = "lowercase letters and digits (regex \"^[a-z\\d_]{3,20}$\")";
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration();
+ registerPage = registerPage.enterUserName(username).clickTerms();
+ assertThat("Validation errors are shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
+ }
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryTestSuite.java b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryTestSuite.java
index 37bc3b4289..eebdb08baf 100644
--- a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryTestSuite.java
+++ b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryTestSuite.java
@@ -22,5 +22,5 @@
public class GlossaryTestSuite
{
@ClassRule
- public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule(ResetDatabaseRule.Config.NoResetAfter, ResetDatabaseRule.Config.WithData);
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule(ResetDatabaseRule.Config.WithData);
}
From 06a0a6ab2a716fdc0a6abfb3c780d7d36ea93e9f Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Thu, 11 Jul 2013 14:19:43 +1000
Subject: [PATCH 040/184] Fix functional test for
https://bugzilla.redhat.com/show_bug.cgi?id=981067
---
.../ManageLanguageTeamMemberPage.java | 24 ++++++++++----
.../administration/ManageUserAccountPage.java | 33 +++++--------------
.../org/zanata/workflow/LanguageWorkFlow.java | 2 +-
.../ManageUsersDetailedTest.java | 3 +-
.../administration/ManageUsersTest.java | 13 ++++++--
.../feature/glossary/GlossaryDeleteTest.java | 2 +-
.../TranslatorJoinsLanguageTeamTest.java | 4 +--
.../feature/administration/ManageUsers.html | 3 +-
.../org/zanata/feature/zanata_with_data.sql | 12 ++++---
.../test/resources/create_translator_user.sql | 1 -
.../src/main/resources/messages.properties | 2 +-
11 files changed, 51 insertions(+), 48 deletions(-)
diff --git a/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java b/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java
index 8d71848f03..94150143a3 100644
--- a/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java
+++ b/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java
@@ -26,6 +26,8 @@ public class ManageLanguageTeamMemberPage extends AbstractPage
private WebElement memberPanel;
public static final int USERNAME_COLUMN = 0;
+ public static final int ISTRANSLATOR_COLUMN = 3;
+ public static final int SEARCH_RESULT_PERSON_COLUMN = 1;
public ManageLanguageTeamMemberPage(WebDriver driver)
{
@@ -112,7 +114,7 @@ public WebElement apply(WebDriver driver)
WebElement table = driver.findElement(By.id("resultForm:personTable"));
List tableRows = WebElementUtil.getTableRows(getDriver(), table);
//we want to wait until search result comes back
- if (tableRows.isEmpty() || !tableRows.get(0).getCellContents().get(0).contains(personName))
+ if (tableRows.isEmpty() || !tableRows.get(0).getCellContents().get(SEARCH_RESULT_PERSON_COLUMN).contains(personName))
{
log.debug("waiting for search result refresh...");
return null;
@@ -126,18 +128,26 @@ public WebElement apply(WebDriver driver)
public ManageLanguageTeamMemberPage addToTeam(TableRow personRow)
{
- List cells = personRow.getCells();
- final String personUsername = personRow.getCellContents().get(0);
+ final String personUsername = personRow.getCellContents().get(1);
log.info("username to be added: {}", personUsername);
- WebElement lastColumn = cells.get(cells.size() - 1);
- if (!lastColumn.getText().contains("Already in Team"))
+ WebElement firstCell = personRow.getCells().get(0).findElement(By.tagName("input"));
+ WebElement translatorCell = personRow.getCells().get(3).findElement(By.tagName("input"));
+
+ if (!translatorCell.isSelected())
{
- WebElement addButton = lastColumn.findElement(By.xpath(".//input[@value='Add']"));
+ if(!firstCell.isSelected())
+ {
+ firstCell.click();
+ }
+
+ translatorCell.click();
+
+ WebElement addButton = getDriver().findElement(By.id("resultForm:addSelectedBtn"));
addButton.click();
WebElement closeButton = getDriver().findElement(By.id("searchForm:closeBtn"));
closeButton.click();
// we need to wait for the page to refresh
- WebElementUtil.waitForSeconds(getDriver(), 5).until(new Predicate()
+ WebElementUtil.waitForSeconds(getDriver(), 10).until(new Predicate()
{
@Override
public boolean apply(WebDriver driver)
diff --git a/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java b/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
index 0368fb4cc1..c8bd50855f 100644
--- a/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
+++ b/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
@@ -32,7 +32,6 @@
/**
* @author Damian Jansen djansen@redhat.com
*/
-
public class ManageUserAccountPage extends AbstractPage
{
@@ -67,35 +66,33 @@ public ManageUserAccountPage(WebDriver driver)
roleMap.put("user", "4");
}
- public ManageUserAccountPage enterUsername(String username)
+ public void clearAndEnterUsername(String username)
{
+ usernameField.clear();
usernameField.sendKeys(username);
- return new ManageUserAccountPage(getDriver());
}
- public ManageUserAccountPage enterPassword(String password)
+ public void clearAndEnterPassword(String password)
{
+ passwordField.clear();
passwordField.sendKeys(password);
- return new ManageUserAccountPage(getDriver());
}
- public ManageUserAccountPage enterConfirmPassword(String confirmPassword)
+ public void clearAndEnterConfirmPassword(String confirmPassword)
{
+ passwordConfirmField.clear();
passwordConfirmField.sendKeys(confirmPassword);
- return new ManageUserAccountPage(getDriver());
}
- public ManageUserAccountPage clickEnabled()
+ public void clickEnabled()
{
enabledField.click();
- return new ManageUserAccountPage(getDriver());
}
- public ManageUserAccountPage clickRole(String role)
+ public void clickRole(String role)
{
WebElement roleBox = getDriver().findElement(By.id("userdetailForm:rolesField:roles:".concat(roleMap.get(role))));
roleBox.click();
- return new ManageUserAccountPage(getDriver());
}
public boolean isRoleChecked(String role)
@@ -108,18 +105,4 @@ public ManageUserPage saveUser()
saveButton.click();
return new ManageUserPage(getDriver());
}
-
- public ManageUserPage cancelEditUser()
- {
- cancelButton.click();
- return new ManageUserPage(getDriver());
- }
-
- public ManageUserAccountPage clearFields()
- {
- usernameField.clear();
- passwordField.clear();
- passwordConfirmField.clear();
- return new ManageUserAccountPage(getDriver());
- }
}
diff --git a/functional-test/src/main/java/org/zanata/workflow/LanguageWorkFlow.java b/functional-test/src/main/java/org/zanata/workflow/LanguageWorkFlow.java
index df771f04ae..0ef427c4a6 100644
--- a/functional-test/src/main/java/org/zanata/workflow/LanguageWorkFlow.java
+++ b/functional-test/src/main/java/org/zanata/workflow/LanguageWorkFlow.java
@@ -44,7 +44,7 @@ public void addLanguageAndJoin(String localeId)
log.warn("admin has already joined the language [{}]", localeId);
}
}
-
+
public ManageLanguagePage addLanguage(String localeId)
{
ManageLanguagePage manageLanguagePage = goToHome().goToAdministration().goToManageLanguagePage();
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
index e13fb29465..97e1eb292f 100644
--- a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
@@ -50,7 +50,8 @@ public void changeAUsersUsername()
String username = "administratornamechange";
ManageUserPage manageUserPage = homePage.goToAdministration().goToManageUserPage();
ManageUserAccountPage manageUserAccountPage = manageUserPage.editUserAccount("admin");
- manageUserPage = manageUserAccountPage.clearFields().enterUsername(username).saveUser();
+ manageUserAccountPage.clearAndEnterUsername(username);
+ manageUserAccountPage.saveUser();
assertThat("Administrator is displayed", manageUserPage.getUserList(), Matchers.hasItem(username));
}
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
index 8fa1f9d82a..723a844e49 100644
--- a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
@@ -20,6 +20,8 @@
*/
package org.zanata.feature.administration;
+import lombok.extern.slf4j.Slf4j;
+
import org.concordion.api.extension.Extensions;
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
@@ -36,6 +38,7 @@
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Slf4j
public class ManageUsersTest
{
@ClassRule
@@ -58,13 +61,19 @@ public ManageUserAccountPage editUserAccount(ManageUserPage manageUserPage, Stri
return manageUserPage.editUserAccount(username);
}
- public ManageUserPage changeUsernameAndPassword(ManageUserAccountPage manageUserAccount, String username, String password)
+ public ManageUserPage changeUsernameAndPassword(ManageUserAccountPage manageUserAccount, String newUsername, String newPassword)
{
- return manageUserAccount.clearFields().enterUsername(username).enterPassword(password).enterConfirmPassword(password).saveUser();
+ manageUserAccount.clearAndEnterUsername(newUsername);
+ manageUserAccount.clearAndEnterPassword(newPassword);
+ manageUserAccount.clearAndEnterConfirmPassword(newPassword);
+ ManageUserPage page = manageUserAccount.saveUser();
+
+ return page;
}
public boolean userListContains(ManageUserPage manageUserPage, String username)
{
+ log.info(manageUserPage.getUserList() + "");
return manageUserPage.getUserList().contains(username);
}
diff --git a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryDeleteTest.java b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryDeleteTest.java
index 4a9f8ae0f0..2cc97a9212 100644
--- a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryDeleteTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryDeleteTest.java
@@ -57,7 +57,7 @@ public String resultByLines(List output)
public void translate(String locale)
{
- new LoginWorkFlow().signIn("translator", "translator");
+ new LoginWorkFlow().signIn("admin", "admin");
editorPage = new BasicWorkFlow().goToPage("webtrans/translate?project=about-fedora&iteration=master&localeId=" + locale + "&locale=en#view:doc;doc:About_Fedora", EditorPage.class);
}
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/TranslatorJoinsLanguageTeamTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/TranslatorJoinsLanguageTeamTest.java
index 4a7282e475..2265a224de 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/TranslatorJoinsLanguageTeamTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/TranslatorJoinsLanguageTeamTest.java
@@ -2,6 +2,8 @@
import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+
import org.concordion.api.extension.Extensions;
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
@@ -15,8 +17,6 @@
import org.zanata.util.TableRow;
import org.zanata.workflow.LoginWorkFlow;
-import lombok.extern.slf4j.Slf4j;
-
/**
* @author Patrick Huang pahuang@redhat.com
*/
diff --git a/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html b/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html
index d0babb480a..493a353936 100644
--- a/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html
+++ b/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html
@@ -21,8 +21,7 @@ Changing a User's Login Details
- and pressing Edit on the
- user to be changed, in this example the admin user.
+ and navigate to user 'admin ' and press Edit .
diff --git a/functional-test/src/test/resources/concordion/org/zanata/feature/zanata_with_data.sql b/functional-test/src/test/resources/concordion/org/zanata/feature/zanata_with_data.sql
index 2679e2642c..9d8c268edd 100644
--- a/functional-test/src/test/resources/concordion/org/zanata/feature/zanata_with_data.sql
+++ b/functional-test/src/test/resources/concordion/org/zanata/feature/zanata_with_data.sql
@@ -640,14 +640,16 @@ ALTER TABLE PUBLIC.HPROJECTITERATION_VALIDATION ADD CONSTRAINT PUBLIC.CONSTRAINT
CREATE CACHED TABLE PUBLIC.HLOCALE_MEMBER(
PERSONID BIGINT NOT NULL,
SUPPORTEDLANGUAGEID BIGINT NOT NULL,
- ISCOORDINATOR BOOLEAN DEFAULT FALSE NOT NULL
+ ISCOORDINATOR BOOLEAN DEFAULT FALSE NOT NULL,
+ ISREVIEWER BOOLEAN DEFAULT FALSE NOT NULL,
+ ISTRANSLATOR BOOLEAN DEFAULT FALSE NOT NULL
);
ALTER TABLE PUBLIC.HLOCALE_MEMBER ADD CONSTRAINT PUBLIC.CONSTRAINT_E PRIMARY KEY(SUPPORTEDLANGUAGEID, PERSONID);
-- 3 +/- SELECT COUNT(*) FROM PUBLIC.HLOCALE_MEMBER;
-INSERT INTO PUBLIC.HLOCALE_MEMBER(PERSONID, SUPPORTEDLANGUAGEID, ISCOORDINATOR) VALUES
-(2, 2, FALSE),
-(2, 3, FALSE),
-(2, 4, FALSE);
+INSERT INTO PUBLIC.HLOCALE_MEMBER(PERSONID, SUPPORTEDLANGUAGEID, ISCOORDINATOR, ISREVIEWER, ISTRANSLATOR) VALUES
+(2, 2, FALSE, FALSE, FALSE),
+(2, 3, FALSE, FALSE, TRUE),
+(2, 4, FALSE, FALSE, FALSE);
CREATE CACHED TABLE PUBLIC.HTEXTFLOWTARGET(
ID BIGINT DEFAULT (NEXT VALUE FOR PUBLIC.SYSTEM_SEQUENCE_79179848_56F7_4E3D_B30B_97780C5EF1D9) NOT NULL NULL_TO_DEFAULT SEQUENCE PUBLIC.SYSTEM_SEQUENCE_79179848_56F7_4E3D_B30B_97780C5EF1D9,
CREATIONDATE TIMESTAMP NOT NULL,
diff --git a/functional-test/src/test/resources/create_translator_user.sql b/functional-test/src/test/resources/create_translator_user.sql
index 28b3cd647e..8effca0f23 100644
--- a/functional-test/src/test/resources/create_translator_user.sql
+++ b/functional-test/src/test/resources/create_translator_user.sql
@@ -3,4 +3,3 @@ INSERT INTO HAccount (id,creationDate,lastChanged,versionNum,apiKey,enabled,pass
INSERT INTO HPerson (id,creationDate,lastChanged,versionNum,email,name,accountId) VALUES (2,{ts '2012-04-03 15:06:28'},{ts '2012-04-03 15:06:28'},0,'translator@example.com','translator',2);
INSERT INTO HAccountMembership (accountId,memberOf) VALUES (2,1);
-INSERT INTO HAccountMembership (accountId,memberOf) VALUES (2,5);
diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties
index 5619530858..a06af415f6 100644
--- a/zanata-war/src/main/resources/messages.properties
+++ b/zanata-war/src/main/resources/messages.properties
@@ -395,7 +395,7 @@ jsf.LeaveLanguageTeam=Leave Language Team
jsf.RequestToJoinLanguageTeam=Request To Join Team
jsf.RequestUpdateRoleLanguageTeam=Request role
jsf.contactLanguageTeamCoordinator=Contact Team Coordinators
-jsf.AddTeamMember=Add Team Translator
+jsf.AddTeamMember=Add Team Member
jsf.FindUsersToAdd=Find Users To Add
jsf.Loading=Loading...
jsf.AlreadyInTeam=Already in Team
From 2724c49dff05091130c30bcee7b816eaedabd369 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Thu, 11 Jul 2013 16:04:03 +1000
Subject: [PATCH 041/184] make editor request all states when no states checked
in UI
---
.../webtrans/shared/rpc/GetTransUnitList.java | 20 ++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
index 00f3645aea..9a906c8743 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
@@ -33,6 +33,15 @@ private GetTransUnitList(GetTransUnitActionContext context)
offset = context.getOffset();
count = context.getCount();
phrase = context.getFindMessage();
+ setIncludeStatesFrom(context);
+ setIncludeAllStateIfNoneSelected();
+ filterHasError = context.isFilterHasError();
+ targetTransUnitId = context.getTargetTransUnitId();
+ validationIds = context.getValidationIds();
+ }
+
+ private void setIncludeStatesFrom(GetTransUnitActionContext context)
+ {
// @formatter :off
filterStates = ContentStateGroup.builder()
.includeNew(context.isFilterUntranslated())
@@ -42,9 +51,14 @@ private GetTransUnitList(GetTransUnitActionContext context)
.includeRejected(context.isFilterRejected())
.build();
// @formatter :on
- filterHasError = context.isFilterHasError();
- targetTransUnitId = context.getTargetTransUnitId();
- validationIds = context.getValidationIds();
+ }
+
+ private void setIncludeAllStateIfNoneSelected()
+ {
+ if (filterStates.hasNoStates())
+ {
+ filterStates = ContentStateGroup.builder().addAll().build();
+ }
}
public static GetTransUnitList newAction(GetTransUnitActionContext context)
From 9750d84815107bb47b7de625527f4c18061ba84f Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Thu, 11 Jul 2013 16:09:55 +1000
Subject: [PATCH 042/184] Fix some issues found in findBugs
---
.../org/zanata/ApplicationConfiguration.java | 19 +------------------
.../zanata/action/ViewAllStatusAction.java | 4 ----
.../zanata/config/DatabaseBackedConfig.java | 5 ++++-
.../org/zanata/config/JndiBackedConfig.java | 7 +++++--
.../java/org/zanata/dao/AbstractDAOImpl.java | 5 +++--
.../dao/ApplicationConfigurationDAO.java | 2 --
.../impl/ProcessManagerServiceImpl.java | 2 +-
.../service/impl/ValidationServiceImpl.java | 12 ++++--------
.../main/java/org/zanata/util/DateUtil.java | 13 +++++++------
.../presenter/SearchResultsPresenter.java | 2 +-
.../GlossaryDetailsPresenterTest.java | 1 -
11 files changed, 26 insertions(+), 46 deletions(-)
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/ViewAllStatusAction.java b/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java
index 1eb640034b..5d873d1c0b 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/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..055bbf641d 100644
--- a/zanata-war/src/main/java/org/zanata/util/DateUtil.java
+++ b/zanata-war/src/main/java/org/zanata/util/DateUtil.java
@@ -3,9 +3,11 @@
*/
package org.zanata.util;
-import java.text.SimpleDateFormat;
import java.util.Date;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
/**
*
@@ -18,9 +20,6 @@ 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.toString();
}
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.toString();
}
return null;
}
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 a40a69da8b..eedd68b7d4 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/test/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenterTest.java
index 0a7bb6bea7..87d1aa5fa1 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenterTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenterTest.java
@@ -157,7 +157,6 @@ public void onSaveClick()
public void onSaveClickAndCallbackSuccess()
{
GlossaryDetails glossaryDetails = mock(GlossaryDetails.class);
- Date lastModifiedDate = new Date();
when(mockUserWorkspaceContext.getWorkspaceRestrictions().isHasGlossaryUpdateAccess()).thenReturn(true);
when(display.getTargetText()).thenReturn(targetText);
when(targetText.getText()).thenReturn("new target Text");
From 150f46468edb3829e1988f1da4a66c55c073e416 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Thu, 11 Jul 2013 17:21:59 +1000
Subject: [PATCH 043/184] rhbz983370 show indeterminate state for parent filter
checkboxes when some children checked
---
.../webtrans/client/view/TransFilterView.java | 35 ++++++++++++++-----
1 file changed, 27 insertions(+), 8 deletions(-)
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 217f8bba00..1b1e8381a4 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
@@ -32,6 +32,7 @@
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.HasValue;
@@ -197,23 +198,32 @@ public void onSearchFieldCancel()
@UiHandler({"translatedChk", "fuzzyChk", "untranslatedChk", "approvedChk", "rejectedChk", "hasErrorChk"})
public void onFilterOptionsChanged(ValueChangeEvent event)
{
- updateStateCheckboxGroups();
+ updateParentCheckboxes();
listener.messageFilterOptionChanged(translatedChk.getValue(), fuzzyChk.getValue(),
untranslatedChk.getValue(), approvedChk.getValue(), rejectedChk.getValue(), hasErrorChk.getValue());
}
- private void updateStateCheckboxGroups()
+ private void updateParentCheckboxes()
{
- // TODO show intermediate state if some but not all are checked
- incompleteChk.setValue(allChecked(untranslatedChk, fuzzyChk, rejectedChk));
- completeChk.setValue(allChecked(translatedChk, approvedChk));
+ updateParentCheckboxToMatchChildren(incompleteChk, untranslatedChk, fuzzyChk, rejectedChk);
+ updateParentCheckboxToMatchChildren(completeChk, translatedChk, approvedChk);
}
- private static boolean allChecked(CheckBox... toggles)
+ private void updateParentCheckboxToMatchChildren(CheckBox parent, CheckBox... children)
{
- for (HasValue toggle : toggles)
+ 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 (!toggle.getValue())
+ if (checkbox.getValue() != checkValue)
{
return false;
}
@@ -221,6 +231,15 @@ private static boolean allChecked(CheckBox... toggles)
return true;
}
+ 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("incompleteChk")
public void onIncompleteChkChanged(ValueChangeEvent event)
{
From 87dfb6d16ba3189045a5490f5000c8c99ee8a9f6 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Thu, 11 Jul 2013 17:22:26 +1000
Subject: [PATCH 044/184] rhbz983370 rename parent checkboxes for clarity
---
.../webtrans/client/view/TransFilterView.java | 16 +++++++---------
.../webtrans/client/view/TransFilterView.ui.xml | 4 ++--
2 files changed, 9 insertions(+), 11 deletions(-)
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 1b1e8381a4..d2a1c8b7f2 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
@@ -35,7 +35,6 @@
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.HasValue;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
@@ -52,10 +51,9 @@ 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;
@@ -205,8 +203,8 @@ public void onFilterOptionsChanged(ValueChangeEvent event)
private void updateParentCheckboxes()
{
- updateParentCheckboxToMatchChildren(incompleteChk, untranslatedChk, fuzzyChk, rejectedChk);
- updateParentCheckboxToMatchChildren(completeChk, translatedChk, approvedChk);
+ updateParentCheckboxToMatchChildren(parentIncompleteChk, untranslatedChk, fuzzyChk, rejectedChk);
+ updateParentCheckboxToMatchChildren(parentCompleteChk, translatedChk, approvedChk);
}
private void updateParentCheckboxToMatchChildren(CheckBox parent, CheckBox... children)
@@ -240,7 +238,7 @@ private static native void setElementIndeterminate(Element elem, boolean indeter
elem.getElementsByTagName('input')[0].indeterminate = indeterminate;
}-*/;
- @UiHandler("incompleteChk")
+ @UiHandler("parentIncompleteChk")
public void onIncompleteChkChanged(ValueChangeEvent event)
{
untranslatedChk.setValue(event.getValue());
@@ -249,7 +247,7 @@ public void onIncompleteChkChanged(ValueChangeEvent event)
onFilterOptionsChanged(event);
}
- @UiHandler("completeChk")
+ @UiHandler("parentCompleteChk")
public void onCompleteChkChanged(ValueChangeEvent event)
{
translatedChk.setValue(event.getValue());
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 68234e244e..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
@@ -145,7 +145,7 @@
- Incomplete
+ Incomplete
@@ -161,7 +161,7 @@
- Complete
+ Complete
From 9b9cfeaf9495a86da341c901380ebf589505c6c3 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Thu, 11 Jul 2013 17:24:31 +1000
Subject: [PATCH 045/184] use standard state order for items repeated for each
state
---
.../webtrans/client/view/TransFilterView.java | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
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 d2a1c8b7f2..36e6e9686b 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
@@ -114,9 +114,9 @@ public void setSearchTerm(String searchTerm)
}
@Override
- public void setTranslatedFilter(boolean filterByTranslated)
+ public void setUntranslatedFilter(boolean filterByUntranslated)
{
- translatedChk.setValue(filterByTranslated);
+ untranslatedChk.setValue(filterByUntranslated);
}
@Override
@@ -126,17 +126,17 @@ public void setNeedReviewFilter(boolean filterByNeedReview)
}
@Override
- public void setUntranslatedFilter(boolean filterByUntranslated)
+ public void setTranslatedFilter(boolean filterByTranslated)
{
- untranslatedChk.setValue(filterByUntranslated);
+ translatedChk.setValue(filterByTranslated);
}
-
+
@Override
public void setApprovedFilter(boolean filterByApproved)
{
approvedChk.setValue(filterByApproved);
}
-
+
@Override
public void setRejectedFilter(boolean filterByRejected)
{
@@ -258,9 +258,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());
From 87eb390704d66cf8d68aa22d32abb48c10e70877 Mon Sep 17 00:00:00 2001
From: Sean Flanigan
Date: Fri, 12 Jul 2013 10:16:42 +1000
Subject: [PATCH 046/184] Update to latest parent pom
---
pom.xml | 2 +-
zanata-model/pom.xml | 4 ++++
.../main/java/org/zanata/action/CopyTransManager.java | 11 +++++++++++
3 files changed, 16 insertions(+), 1 deletion(-)
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-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;
From 528142f0c4ee9ce5d98c05e1e74dba57edb21a93 Mon Sep 17 00:00:00 2001
From: Sean Flanigan
Date: Fri, 12 Jul 2013 10:17:36 +1000
Subject: [PATCH 047/184] Add findbugs annotations
---
zanata-war/pom.xml | 4 ++++
.../webtrans/shared/validation/action/TabValidation.java | 1 +
2 files changed, 5 insertions(+)
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/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);
From fd60b69ca0934cceef9f37e7f5dd6ce7b680d67a Mon Sep 17 00:00:00 2001
From: David Mason
Date: Fri, 12 Jul 2013 10:27:11 +1000
Subject: [PATCH 048/184] rhbz983370 show correct parent checkbox state on page
refresh/reload
---
.../client/view/TransFilterDisplay.java | 2 +-
.../webtrans/client/view/TransFilterView.java | 18 ++++++++++++------
2 files changed, 13 insertions(+), 7 deletions(-)
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 36e6e9686b..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
@@ -116,37 +116,43 @@ public void setSearchTerm(String searchTerm)
@Override
public void setUntranslatedFilter(boolean filterByUntranslated)
{
- untranslatedChk.setValue(filterByUntranslated);
+ updateChildCheckbox(untranslatedChk, filterByUntranslated);
}
@Override
public void setNeedReviewFilter(boolean filterByNeedReview)
{
- fuzzyChk.setValue(filterByNeedReview);
+ updateChildCheckbox(fuzzyChk, filterByNeedReview);
}
@Override
public void setTranslatedFilter(boolean filterByTranslated)
{
- translatedChk.setValue(filterByTranslated);
+ 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
From 906d47d7d328a8bc50ba3ce517872479606017ee Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Thu, 27 Jun 2013 14:01:07 +1000
Subject: [PATCH 049/184] rhbz978666 - add database table and liquibase change
log for review translation comment
---
.../org/zanata/model/HTextFlowTarget.java | 23 ++-
.../model/HTextFlowTargetReviewComment.java | 138 ++++++++++++++++++
.../db/changelogs/db.changelog-3.1.xml | 44 ++++++
.../WEB-INF/classes/META-INF/persistence.xml | 1 +
.../org/zanata/dao/TextFlowTargetDAOTest.java | 65 ++++++++-
.../test/resources/META-INF/persistence.xml | 3 +-
.../test/resources/arquillian/persistence.xml | 3 +-
7 files changed, 269 insertions(+), 8 deletions(-)
create mode 100644 zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
create mode 100644 zanata-war/src/main/resources/db/changelogs/db.changelog-3.1.xml
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..82eb96d056 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 userComments;
+
// Only for internal use (persistence transient)
@Setter(AccessLevel.PRIVATE)
private Integer oldVersionNum;
@@ -388,6 +387,22 @@ public Map getHistory()
return history;
}
+ @OneToMany(cascade = { CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST }, mappedBy = "textFlowTarget")
+ public List getUserComments()
+ {
+ if (userComments == null)
+ {
+ userComments = Lists.newArrayList();
+ }
+ return userComments;
+ }
+
+ public HTextFlowTarget addUserComment(String comment, HPerson commenter)
+ {
+ getUserComments().add(new HTextFlowTargetReviewComment(this, comment, commenter));
+ return this;
+ }
+
@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..e02911db6f
--- /dev/null
+++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
@@ -0,0 +1,138 @@
+/*
+ * 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.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.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * @author Patrick Huang pahuang@redhat.com
+ */
+@Entity
+@Immutable
+@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
+@BatchSize(size = 20)
+@Setter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+public class HTextFlowTargetReviewComment extends ModelEntityBase
+{
+ private static final long serialVersionUID = 1413384329431214946L;
+
+ private HPerson commenter;
+ private HTextFlowTarget textFlowTarget;
+ private String comment;
+
+ @Setter(AccessLevel.PROTECTED)
+ private Integer targetVersion;
+
+ @Setter(AccessLevel.NONE)
+ 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();
+ }
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "commenter_id", nullable = false)
+ public HPerson getCommenter()
+ {
+ return commenter;
+ }
+
+ @Transient
+ public String getCommenterName()
+ {
+ return commenterName;
+ }
+
+ @NotNull
+ @Type(type = "text")
+ public String getComment()
+ {
+ return comment;
+ }
+
+ @NotNull
+ @NaturalId
+ @ManyToOne
+ @JoinColumn(name = "target_id")
+ @IndexedEmbedded
+ public HTextFlowTarget getTextFlowTarget()
+ {
+ return textFlowTarget;
+ }
+
+ @NotNull
+ @NaturalId
+ public Integer getTargetVersion()
+ {
+ return targetVersion;
+ }
+
+ // TODO pahuang we probably want to cache below two methods
+ @Transient
+ public ContentState getContentStateOfCommentedTarget()
+ {
+ if (textFlowTarget.getVersionNum().equals(targetVersion))
+ {
+ return textFlowTarget.getState();
+ }
+ return textFlowTarget.getHistory().get(targetVersion).getState();
+ }
+
+ @Transient
+ public List getContentsOfCommentedTarget()
+ {
+ if (textFlowTarget.getVersionNum().equals(targetVersion))
+ {
+ return textFlowTarget.getContents();
+ }
+ return textFlowTarget.getHistory().get(targetVersion).getContents();
+ }
+
+}
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
new file mode 100644
index 0000000000..3122c7e3cb
--- /dev/null
+++ b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.1.xml
@@ -0,0 +1,44 @@
+
+
+
+
+ Add HTextFlowTargetReviewComment table to support user comments.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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..7d3239ae56 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
@@ -34,6 +34,7 @@
org.zanata.model.HTextFlow
org.zanata.model.HTextFlowTargetHistory
org.zanata.model.HTextFlowTarget
+ org.zanata.model.HTextFlowTargetReviewComment
org.zanata.model.HGlossaryEntry
org.zanata.model.HGlossaryTerm
org.zanata.model.HTermComment
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java
index 21b3dac500..ed69f65e26 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java
@@ -20,9 +20,13 @@
*/
package org.zanata.dao;
+import java.util.Date;
+import java.util.List;
+
import lombok.Cleanup;
import org.dbunit.operation.DatabaseOperation;
+import org.hamcrest.Matchers;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.testng.annotations.BeforeMethod;
@@ -31,25 +35,30 @@
import org.zanata.common.ContentState;
import org.zanata.model.HDocument;
import org.zanata.model.HLocale;
+import org.zanata.model.HPerson;
+import org.zanata.model.HTextFlowTargetReviewComment;
import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
@Test(groups = { "jpa-tests" })
public class TextFlowTargetDAOTest extends ZanataDbunitJpaTest
{
private TextFlowTargetDAO textFlowTargetDAO;
-
+
@Override
protected void prepareDBUnitOperations()
{
- // beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/ClearAllTables.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/ClearAllTables.dbunit.xml", DatabaseOperation.DELETE_ALL));
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/AccountData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/ProjectsData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/TextFlowTestData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/LocalesData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
@@ -99,4 +108,56 @@ public void testQuery()
@Cleanup
ScrollableResults scroll = this.textFlowTargetDAO.findMatchingTranslations(doc, hLocale, true, true, true, true);
}
+
+ @Test
+ public void testTargetUserComment()
+ {
+ PersonDAO personDAO = new PersonDAO(getSession());
+ HPerson person = personDAO.findById(1L, false);
+ HTextFlowTarget target = textFlowTargetDAO.findById(1L, false);
+
+ List userComments = target.getUserComments();
+
+ assertThat(userComments, Matchers.empty());
+
+ target.addUserComment("bad translation", person);
+ getEm().persist(target);
+
+ // @formatter:off
+ HTextFlowTargetReviewComment result = getEm()
+ .createQuery("from HTextFlowTargetReviewComment where comment = :comment", HTextFlowTargetReviewComment.class)
+ .setParameter("comment", "bad translation").getSingleResult();
+ // @formatter:on
+
+ assertThat(result.getContentsOfCommentedTarget(), Matchers.equalTo(target.getContents()));
+ assertThat(result.getCommenterName(), Matchers.equalTo(person.getName()));
+ assertThat(result.getCreationDate(), Matchers.lessThanOrEqualTo(new Date()));
+ }
+
+ @Test
+ public void testTargetUserCommentMadeOnPreviousTranslation()
+ {
+ PersonDAO personDAO = new PersonDAO(getSession());
+ HPerson person = personDAO.findById(1L, false);
+ HTextFlowTarget target = textFlowTargetDAO.findById(2L, false);
+
+ List oldTranslation = target.getContents();
+ int oldVersion = target.getVersionNum();
+
+ target.addUserComment("comment blah", person);
+ getEm().persist(target);
+
+ // change target after making comment
+ target.setContent0("new translation");
+ getEm().persist(target);
+
+ // @formatter:off
+ HTextFlowTargetReviewComment result = getEm()
+ .createQuery("from HTextFlowTargetReviewComment where comment = :comment", HTextFlowTargetReviewComment.class)
+ .setParameter("comment", "comment blah").getSingleResult();
+ // @formatter:on
+
+ assertThat(result.getContentsOfCommentedTarget(), Matchers.equalTo(oldTranslation));
+ assertThat(result.getTargetVersion(), Matchers.equalTo(oldVersion));
+ }
}
diff --git a/zanata-war/src/test/resources/META-INF/persistence.xml b/zanata-war/src/test/resources/META-INF/persistence.xml
index b17579c5e2..6ccabf0054 100755
--- a/zanata-war/src/test/resources/META-INF/persistence.xml
+++ b/zanata-war/src/test/resources/META-INF/persistence.xml
@@ -42,7 +42,8 @@
org.zanata.model.HSimpleComment
org.zanata.model.HTextFlowHistory
org.zanata.model.HTextFlow
- org.zanata.model.HTextFlowTargetHistory
+ org.zanata.model.HTextFlowTargetReviewComment
+ org.zanata.model.HTextFlowTargetHistory
org.zanata.model.HTextFlowTarget
org.zanata.model.HGlossaryEntry
org.zanata.model.HGlossaryTerm
diff --git a/zanata-war/src/test/resources/arquillian/persistence.xml b/zanata-war/src/test/resources/arquillian/persistence.xml
index ef4fd1fcfe..d05875fddf 100755
--- a/zanata-war/src/test/resources/arquillian/persistence.xml
+++ b/zanata-war/src/test/resources/arquillian/persistence.xml
@@ -46,7 +46,8 @@
org.zanata.model.HTextFlow
org.zanata.model.HTextFlowTargetHistory
org.zanata.model.HTextFlowTarget
- org.zanata.model.HGlossaryEntry
+ org.zanata.model.HTextFlowTargetReviewComment
+ org.zanata.model.HGlossaryEntry
org.zanata.model.HGlossaryTerm
org.zanata.model.HTermComment
org.zanata.model.HIterationGroup
From f07c6426c39e1c3fbfbb554e1918447229db8383 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Thu, 27 Jun 2013 16:29:02 +1000
Subject: [PATCH 050/184] rhbz978666 - update TransUnit to indicate comment
existance
---
.../org/zanata/model/HTextFlowTarget.java | 12 +--
.../server/rpc/TransUnitTransformer.java | 20 ++++-
.../webtrans/shared/model/TransUnit.java | 26 +++++-
.../webtrans/shared/model/UserComment.java | 83 +++++++++++++++++++
.../org/zanata/dao/TextFlowTargetDAOTest.java | 4 +-
5 files changed, 134 insertions(+), 11 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserComment.java
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 82eb96d056..80c48cf5aa 100644
--- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java
+++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java
@@ -111,7 +111,7 @@ public class HTextFlowTarget extends ModelEntityBase implements HasContents, Has
private Map history;
- private List userComments;
+ private List reviewComments;
// Only for internal use (persistence transient)
@Setter(AccessLevel.PRIVATE)
@@ -388,18 +388,18 @@ public Map getHistory()
}
@OneToMany(cascade = { CascadeType.REMOVE, CascadeType.MERGE, CascadeType.PERSIST }, mappedBy = "textFlowTarget")
- public List getUserComments()
+ public List getReviewComments()
{
- if (userComments == null)
+ if (reviewComments == null)
{
- userComments = Lists.newArrayList();
+ reviewComments = Lists.newArrayList();
}
- return userComments;
+ return reviewComments;
}
public HTextFlowTarget addUserComment(String comment, HPerson commenter)
{
- getUserComments().add(new HTextFlowTargetReviewComment(this, comment, commenter));
+ getReviewComments().add(new HTextFlowTargetReviewComment(this, comment, commenter));
return this;
}
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..a84dcd1fa0 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
@@ -68,7 +68,23 @@ 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())
+ // TODO pahuang we may consider to use a query to gather has comment information
+ .setHasUserComment(target != null && target.getReviewComments().size() > 0)
+ ;
+ // @formatter:on
if (target != null)
{
@@ -82,6 +98,8 @@ private TransUnit transform(HTextFlow hTextFlow, HTextFlowTarget target, HLocale
return builder.build();
}
+
+
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/TransUnit.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransUnit.java
index dcd7dc388a..7901d81f0a 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 boolean hasUserComment;
// 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.hasUserComment = builder.hasUserComment;
}
@Override
@@ -189,6 +191,16 @@ void setTargetComment(String targetComment)
this.targetComment = targetComment;
}
+ public boolean isHasUserComment()
+ {
+ return hasUserComment;
+ }
+
+ void setHasUserComment(boolean hasUserComment)
+ {
+ this.hasUserComment = hasUserComment;
+ }
+
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 boolean hasUserComment;
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.hasUserComment = transUnit.hasUserComment;
}
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 setHasUserComment(boolean hasUserComment)
+ {
+ this.hasUserComment = hasUserComment;
+ return this;
+ }
}
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserComment.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserComment.java
new file mode 100644
index 0000000000..9d0b9474a4
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserComment.java
@@ -0,0 +1,83 @@
+package org.zanata.webtrans.shared.model;
+
+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 UserComment implements IsSerializable
+{
+ private String comment;
+ private List targetContents;
+ private String madeByName;
+ private String madeByDate;
+ private ContentState contentState;
+
+ @SuppressWarnings("unused")
+ public UserComment()
+ {
+ }
+
+ public UserComment(String comment, List targetContents, String madeByName, String madeByDate, ContentState contentState)
+ {
+ this.comment = comment;
+ this.targetContents = targetContents;
+ this.madeByName = madeByName;
+ this.madeByDate = madeByDate;
+ this.contentState = contentState;
+ }
+
+ public String getComment()
+ {
+ return comment;
+ }
+
+ public List getTargetContents()
+ {
+ return targetContents;
+ }
+
+ public String getMadeByName()
+ {
+ return madeByName;
+ }
+
+ public String getMadeByDate()
+ {
+ return madeByDate;
+ }
+
+ public ContentState getContentState()
+ {
+ return contentState;
+ }
+
+ // setters to make gwt serialization happy
+ void setComment(String comment)
+ {
+ this.comment = comment;
+ }
+
+ void setTargetContents(List targetContents)
+ {
+ this.targetContents = targetContents;
+ }
+
+ void setMadeByName(String madeByName)
+ {
+ this.madeByName = madeByName;
+ }
+
+ void setMadeByDate(String madeByDate)
+ {
+ this.madeByDate = madeByDate;
+ }
+
+ void setContentState(ContentState contentState)
+ {
+ this.contentState = contentState;
+ }
+}
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java
index ed69f65e26..a145acfe7a 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java
@@ -24,6 +24,7 @@
import java.util.List;
import lombok.Cleanup;
+import lombok.extern.slf4j.Slf4j;
import org.dbunit.operation.DatabaseOperation;
import org.hamcrest.Matchers;
@@ -48,6 +49,7 @@
import static org.hamcrest.Matchers.not;
@Test(groups = { "jpa-tests" })
+@Slf4j
public class TextFlowTargetDAOTest extends ZanataDbunitJpaTest
{
@@ -116,7 +118,7 @@ public void testTargetUserComment()
HPerson person = personDAO.findById(1L, false);
HTextFlowTarget target = textFlowTargetDAO.findById(1L, false);
- List userComments = target.getUserComments();
+ List userComments = target.getReviewComments();
assertThat(userComments, Matchers.empty());
From 643c7c233ab570d35d3638ee3bcf1d72fa3e7bf4 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Tue, 2 Jul 2013 16:39:43 +1000
Subject: [PATCH 051/184] rhbz978666 - UI and tests
- add review comment rpc
- get review comments rpc
- review comment gwt MVP
- change to TransUnit
- change to editor buttons display
- annotate a few areas that have technical debt (hibernate performance related)
---
.../org/zanata/model/HTextFlowTarget.java | 7 +-
.../model/HTextFlowTargetReviewComment.java | 4 +
.../dao/TextFlowTargetReviewCommentsDAO.java | 67 +++++++
.../presenter/ReviewCommentDataProvider.java | 51 +++++
.../presenter/ReviewCommentPresenter.java | 107 ++++++++++
.../presenter/TargetContentsPresenter.java | 12 +-
.../client/resources/TableEditorMessages.java | 3 +
.../client/resources/WebTransMessages.java | 2 +
.../client/ui/EditorButtonsWidget.java | 19 +-
.../client/ui/EditorButtonsWidget.ui.xml | 1 +
.../client/view/ReviewCommentDisplay.java | 55 ++++++
.../client/view/ReviewCommentView.java | 186 ++++++++++++++++++
.../client/view/ReviewCommentView.ui.xml | 33 ++++
.../client/view/TargetContentsDisplay.java | 4 +
.../client/view/TargetContentsView.java | 47 ++---
.../server/rpc/AddReviewCommentHandler.java | 93 +++++++++
.../server/rpc/GetReviewCommentsHandler.java | 76 +++++++
.../server/rpc/GetTransUnitListHandler.java | 2 +
.../server/rpc/TransUnitTransformer.java | 25 ++-
.../webtrans/shared/model/ReviewComment.java | 113 +++++++++++
.../shared/model/ReviewCommentId.java | 80 ++++++++
.../webtrans/shared/model/TransUnit.java | 20 +-
.../webtrans/shared/model/UserComment.java | 83 --------
.../shared/rpc/AddReviewCommentAction.java | 56 ++++++
.../shared/rpc/AddReviewCommentResult.java | 49 +++++
.../shared/rpc/GetReviewCommentsAction.java | 48 +++++
.../shared/rpc/GetReviewCommentsResult.java | 50 +++++
.../db/changelogs/db.changelog-3.1.xml | 3 +
.../src/main/resources/db/db.changelog.xml | 1 +
.../org/zanata/dao/TextFlowTargetDAOTest.java | 63 +-----
...extFlowTargetReviewCommentsDAOJPATest.java | 118 +++++++++++
.../presenter/ReviewCommentPresenterTest.java | 118 +++++++++++
.../TargetContentsPresenterTest.java | 4 +-
.../rpc/AddReviewCommentHandlerTest.java | 143 ++++++++++++++
.../rpc/GetReviewCommentsHandlerTest.java | 93 +++++++++
.../test/model/ClearAllTables.dbunit.xml | 1 +
.../GetTransUnitListTest.dbunit.xml | 3 +
37 files changed, 1640 insertions(+), 200 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/dao/TextFlowTargetReviewCommentsDAO.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentDataProvider.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenter.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentDisplay.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.ui.xml
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandler.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetReviewCommentsHandler.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/model/ReviewComment.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/model/ReviewCommentId.java
delete mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserComment.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/AddReviewCommentAction.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/AddReviewCommentResult.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetReviewCommentsAction.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetReviewCommentsResult.java
create mode 100644 zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java
create mode 100644 zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java
create mode 100644 zanata-war/src/test/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandlerTest.java
create mode 100644 zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetReviewCommentsHandlerTest.java
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 80c48cf5aa..44d6cbefdc 100644
--- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java
+++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTarget.java
@@ -397,10 +397,11 @@ public List getReviewComments()
return reviewComments;
}
- public HTextFlowTarget addUserComment(String comment, HPerson commenter)
+ public HTextFlowTargetReviewComment addReviewComment(String comment, HPerson commenter)
{
- getReviewComments().add(new HTextFlowTargetReviewComment(this, comment, commenter));
- return this;
+ HTextFlowTargetReviewComment reviewComment = new HTextFlowTargetReviewComment(this, comment, commenter);
+ getReviewComments().add(reviewComment);
+ return reviewComment;
}
@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
index e02911db6f..f078be982b 100644
--- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
+++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
@@ -87,6 +87,10 @@ public HPerson getCommenter()
@Transient
public String getCommenterName()
{
+ if (commenterName == null)
+ {
+ commenterName = getCommenter().getName();
+ }
return commenterName;
}
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..26dc9c2ad4
--- /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 inner join 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/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..3991295ce4
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenter.java
@@ -0,0 +1,107 @@
+/*
+ * 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.rpc.AbstractAsyncCallback;
+import org.zanata.webtrans.client.rpc.CachingDispatchAsync;
+import org.zanata.webtrans.client.view.ReviewCommentDisplay;
+import org.zanata.webtrans.shared.model.ReviewComment;
+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.google.gwt.view.client.ListDataProvider;
+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
+{
+ private final ReviewCommentDisplay display;
+ private final CachingDispatchAsync dispatcher;
+ private final ReviewCommentDataProvider dataProvider;
+ private TransUnitId transUnitId;
+
+ @Inject
+ public ReviewCommentPresenter(ReviewCommentDisplay display, EventBus eventBus, CachingDispatchAsync dispatcher, ReviewCommentDataProvider dataProvider)
+ {
+ super(display, eventBus);
+ this.display = display;
+ this.dispatcher = dispatcher;
+ this.dataProvider = dataProvider;
+
+ display.setListener(this);
+ display.setDataProvider(dataProvider);
+ }
+
+ @Override
+ protected void onBind()
+ {
+ }
+
+ public void displayCommentView(TransUnitId transUnitId)
+ {
+ this.transUnitId = transUnitId;
+ 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), 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/TargetContentsPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TargetContentsPresenter.java
index 3c6d51a321..dcd9a4deca 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;
@@ -680,6 +683,13 @@ public void rejectTranslation(TransUnitId id)
saveCurrent(ContentState.Rejected);
}
+ @Override
+ public void commentTranslation(TransUnitId id)
+ {
+ ensureRowSelection(id);
+ reviewCommentPresenter.displayCommentView(id);
+ }
+
/**
* For testing only
* @param currentTransUnitId current trans unit id
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 36f42a3666..50e3e3355d 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 d1f36313ba..166dad6adb 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,7 +1,9 @@
package org.zanata.webtrans.client.ui;
+import org.zanata.common.ContentState;
import org.zanata.webtrans.client.view.TargetContentsDisplay;
import org.zanata.webtrans.shared.model.TransUnitId;
+import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.resources.client.CssResource;
@@ -35,6 +37,8 @@ public class EditorButtonsWidget extends Composite
InlineLabel acceptIcon;
@UiField
InlineLabel rejectIcon;
+ @UiField
+ InlineLabel commentIcon;
private TargetContentsDisplay.Listener listener;
private TransUnitId id;
@@ -113,15 +117,28 @@ public void onReject(ClickEvent event)
event.stopPropagation();
}
+ @UiHandler("commentIcon")
+ public void onCommentClick(ClickEvent event)
+ {
+ listener.commentTranslation(id);
+ event.stopPropagation();
+ }
+
public void setListener(TargetContentsDisplay.Listener listener)
{
this.listener = listener;
displayReviewButtons(listener.canReviewTranslation());
}
- 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..410e641db8
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentDisplay.java
@@ -0,0 +1,55 @@
+/*
+ * 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();
+
+ 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..a7da69d2a7
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.java
@@ -0,0 +1,186 @@
+/*
+ * 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.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.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;
+
+ private final CellTable commentTable;
+ private Listener listener;
+ private TextBox commentInputBox;
+
+ 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);
+ // TODO pahuang localize
+ Button addButton = new Button("Add", 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 static Column createCommentColumn()
+ {
+ return new Column(new TextCell())
+ {
+ @Override
+ public String getValue(ReviewComment object)
+ {
+ return object.getComment();
+ }
+ };
+ }
+
+ 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 setDataProvider(ListDataProvider dataProvider)
+ {
+ dataProvider.addDataDisplay(commentTable);
+ }
+
+ @Override
+ public void setListener(Listener listener)
+ {
+ this.listener = listener;
+ }
+
+ interface AddReviewCommentViewUiBinder extends UiBinder
+ {
+ }
+}
\ 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..651dd952b1
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/ReviewCommentView.ui.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 e8ac810cb9..049a0d65f9 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);
+ ContentState getCachedState();
+
interface Listener
{
void validate(ToggleEditor editor);
@@ -101,6 +103,8 @@ interface Listener
void acceptTranslation(TransUnitId id);
void rejectTranslation(TransUnitId id);
+
+ void commentTranslation(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..68b16e1b6e 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,6 @@
import java.util.List;
import org.zanata.common.ContentState;
-import org.zanata.webtrans.client.resources.TableEditorMessages;
import org.zanata.webtrans.client.ui.Editor;
import org.zanata.webtrans.client.ui.EditorButtonsWidget;
import org.zanata.webtrans.client.ui.ToggleEditor;
@@ -33,23 +32,17 @@
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;
-import com.google.gwt.event.dom.client.ClickEvent;
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.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;
@@ -120,8 +113,7 @@ public void addUndo(final UndoLink undoLink)
@Override
public void setValueAndCreateNewEditors(TransUnit transUnit)
{
- cachedValue = transUnit;
- buttons.setId(cachedValue.getId());
+ setCachedTU(transUnit);
editors.clear();
List cachedTargets = cachedValue.getTargets();
@@ -139,35 +131,12 @@ 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
@@ -204,8 +173,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
@@ -243,6 +218,12 @@ public List getCachedTargets()
return cachedValue.getTargets();
}
+ @Override
+ public ContentState getCachedState()
+ {
+ return cachedValue.getStatus();
+ }
+
@Override
public TransUnitId getId()
{
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..a3d9405b7d
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandler.java
@@ -0,0 +1,93 @@
+/*
+ * 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.HTextFlowTarget;
+import org.zanata.model.HTextFlowTargetReviewComment;
+import org.zanata.service.SecurityService;
+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.AddReviewCommentAction;
+import org.zanata.webtrans.shared.rpc.AddReviewCommentResult;
+
+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;
+
+ @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();
+
+ // TODO pahuang we will need to publish event to event service if we want client up to date all the time. But do we care?
+ return new AddReviewCommentResult(toDTO(hComment));
+ }
+
+ 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 a84dcd1fa0..53d6e163eb 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,16 +52,13 @@ 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)
{
String msgContext = null;
@@ -81,8 +84,7 @@ private TransUnit transform(HTextFlow hTextFlow, HTextFlowTarget target, HLocale
.setMsgContext(msgContext)
.setRowIndex(hTextFlow.getPos())
.setVerNum(target == null ? NULL_TARGET_VERSION_NUM : target.getVersionNum())
- // TODO pahuang we may consider to use a query to gather has comment information
- .setHasUserComment(target != null && target.getReviewComments().size() > 0)
+ .setCommentsCount(getCommentCount(target))
;
// @formatter:on
@@ -98,6 +100,15 @@ 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)
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 7901d81f0a..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,7 +32,7 @@ public class TransUnit implements IsSerializable, HasTransUnitId
private int rowIndex;
private int verNum;
private String targetComment;
- private boolean hasUserComment;
+ private int commentsCount;
// for GWT
@SuppressWarnings("unused")
@@ -56,7 +56,7 @@ private TransUnit(Builder builder)
this.rowIndex = builder.rowIndex;
this.verNum = builder.verNum;
this.targetComment = builder.targetComment;
- this.hasUserComment = builder.hasUserComment;
+ this.commentsCount = builder.commentsCount;
}
@Override
@@ -191,14 +191,14 @@ void setTargetComment(String targetComment)
this.targetComment = targetComment;
}
- public boolean isHasUserComment()
+ public int getCommentsCount()
{
- return hasUserComment;
+ return commentsCount;
}
- void setHasUserComment(boolean hasUserComment)
+ void setCommentsCount(int commentsCount)
{
- this.hasUserComment = hasUserComment;
+ this.commentsCount = commentsCount;
}
public String debugString()
@@ -236,7 +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 boolean hasUserComment;
+ private int commentsCount;
private Builder(TransUnit transUnit)
{
@@ -253,7 +253,7 @@ private Builder(TransUnit transUnit)
this.lastModifiedTime = transUnit.lastModifiedTime;
this.rowIndex = transUnit.rowIndex;
this.verNum = transUnit.verNum;
- this.hasUserComment = transUnit.hasUserComment;
+ this.commentsCount = transUnit.commentsCount;
}
private Builder()
@@ -398,9 +398,9 @@ public Builder setTargetComment(String targetComment)
return this;
}
- public Builder setHasUserComment(boolean hasUserComment)
+ public Builder setCommentsCount(int commentsCount)
{
- this.hasUserComment = hasUserComment;
+ this.commentsCount = commentsCount;
return this;
}
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserComment.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserComment.java
deleted file mode 100644
index 9d0b9474a4..0000000000
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserComment.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.zanata.webtrans.shared.model;
-
-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 UserComment implements IsSerializable
-{
- private String comment;
- private List targetContents;
- private String madeByName;
- private String madeByDate;
- private ContentState contentState;
-
- @SuppressWarnings("unused")
- public UserComment()
- {
- }
-
- public UserComment(String comment, List targetContents, String madeByName, String madeByDate, ContentState contentState)
- {
- this.comment = comment;
- this.targetContents = targetContents;
- this.madeByName = madeByName;
- this.madeByDate = madeByDate;
- this.contentState = contentState;
- }
-
- public String getComment()
- {
- return comment;
- }
-
- public List getTargetContents()
- {
- return targetContents;
- }
-
- public String getMadeByName()
- {
- return madeByName;
- }
-
- public String getMadeByDate()
- {
- return madeByDate;
- }
-
- public ContentState getContentState()
- {
- return contentState;
- }
-
- // setters to make gwt serialization happy
- void setComment(String comment)
- {
- this.comment = comment;
- }
-
- void setTargetContents(List targetContents)
- {
- this.targetContents = targetContents;
- }
-
- void setMadeByName(String madeByName)
- {
- this.madeByName = madeByName;
- }
-
- void setMadeByDate(String madeByDate)
- {
- this.madeByDate = madeByDate;
- }
-
- void setContentState(ContentState contentState)
- {
- this.contentState = contentState;
- }
-}
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..0176ddf926
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/AddReviewCommentAction.java
@@ -0,0 +1,56 @@
+/*
+ * 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 AddReviewCommentAction extends AbstractWorkspaceAction
+{
+ private static final long serialVersionUID = 1L;
+
+ private String content;
+ private TransUnitId transUnitId;
+
+ @SuppressWarnings("unused")
+ public AddReviewCommentAction()
+ {
+ }
+
+ public AddReviewCommentAction(TransUnitId transUnitId, String content)
+ {
+ this.transUnitId = transUnitId;
+ this.content = content;
+ }
+
+ public String getContent()
+ {
+ return content;
+ }
+
+ public TransUnitId getTransUnitId()
+ {
+ return transUnitId;
+ }
+}
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/resources/db/changelogs/db.changelog-3.1.xml b/zanata-war/src/main/resources/db/changelogs/db.changelog-3.1.xml
index 3122c7e3cb..d00c9d9788 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
@@ -30,6 +30,9 @@
+
+
+
+
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java
index a145acfe7a..f9488cf1a6 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetDAOTest.java
@@ -20,14 +20,7 @@
*/
package org.zanata.dao;
-import java.util.Date;
-import java.util.List;
-
-import lombok.Cleanup;
-import lombok.extern.slf4j.Slf4j;
-
import org.dbunit.operation.DatabaseOperation;
-import org.hamcrest.Matchers;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.testng.annotations.BeforeMethod;
@@ -36,17 +29,15 @@
import org.zanata.common.ContentState;
import org.zanata.model.HDocument;
import org.zanata.model.HLocale;
-import org.zanata.model.HPerson;
-import org.zanata.model.HTextFlowTargetReviewComment;
import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
+import lombok.Cleanup;
+import lombok.extern.slf4j.Slf4j;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
@Test(groups = { "jpa-tests" })
@Slf4j
@@ -111,55 +102,5 @@ public void testQuery()
ScrollableResults scroll = this.textFlowTargetDAO.findMatchingTranslations(doc, hLocale, true, true, true, true);
}
- @Test
- public void testTargetUserComment()
- {
- PersonDAO personDAO = new PersonDAO(getSession());
- HPerson person = personDAO.findById(1L, false);
- HTextFlowTarget target = textFlowTargetDAO.findById(1L, false);
-
- List userComments = target.getReviewComments();
-
- assertThat(userComments, Matchers.empty());
-
- target.addUserComment("bad translation", person);
- getEm().persist(target);
-
- // @formatter:off
- HTextFlowTargetReviewComment result = getEm()
- .createQuery("from HTextFlowTargetReviewComment where comment = :comment", HTextFlowTargetReviewComment.class)
- .setParameter("comment", "bad translation").getSingleResult();
- // @formatter:on
-
- assertThat(result.getContentsOfCommentedTarget(), Matchers.equalTo(target.getContents()));
- assertThat(result.getCommenterName(), Matchers.equalTo(person.getName()));
- assertThat(result.getCreationDate(), Matchers.lessThanOrEqualTo(new Date()));
- }
-
- @Test
- public void testTargetUserCommentMadeOnPreviousTranslation()
- {
- PersonDAO personDAO = new PersonDAO(getSession());
- HPerson person = personDAO.findById(1L, false);
- HTextFlowTarget target = textFlowTargetDAO.findById(2L, false);
- List oldTranslation = target.getContents();
- int oldVersion = target.getVersionNum();
-
- target.addUserComment("comment blah", person);
- getEm().persist(target);
-
- // change target after making comment
- target.setContent0("new translation");
- getEm().persist(target);
-
- // @formatter:off
- HTextFlowTargetReviewComment result = getEm()
- .createQuery("from HTextFlowTargetReviewComment where comment = :comment", HTextFlowTargetReviewComment.class)
- .setParameter("comment", "comment blah").getSingleResult();
- // @formatter:on
-
- assertThat(result.getContentsOfCommentedTarget(), Matchers.equalTo(oldTranslation));
- assertThat(result.getTargetVersion(), Matchers.equalTo(oldVersion));
- }
}
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java
new file mode 100644
index 0000000000..7783c4b314
--- /dev/null
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.Date;
+import java.util.List;
+
+import org.dbunit.operation.DatabaseOperation;
+import org.hamcrest.Matchers;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.zanata.ZanataDbunitJpaTest;
+import org.zanata.common.LocaleId;
+import org.zanata.model.HPerson;
+import org.zanata.model.HTextFlowTarget;
+import org.zanata.model.HTextFlowTargetReviewComment;
+import org.zanata.webtrans.shared.model.TransUnitId;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * @author Patrick Huang pahuang@redhat.com
+ */
+public class TextFlowTargetReviewCommentsDAOJPATest extends ZanataDbunitJpaTest
+{
+ private TextFlowTargetReviewCommentsDAO reviewCommentsDAO;
+ private TextFlowTargetDAO textFlowTargetDAO;
+
+ @Override
+ protected void prepareDBUnitOperations()
+ {
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/ClearAllTables.dbunit.xml", DatabaseOperation.DELETE_ALL));
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/AccountData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/ProjectsData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/TextFlowTestData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
+ beforeTestOperations.add(new DataSetOperation("org/zanata/test/model/LocalesData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
+ }
+
+ @BeforeMethod(firstTimeOnly = true)
+ public void setup()
+ {
+ reviewCommentsDAO = new TextFlowTargetReviewCommentsDAO(getSession());
+ textFlowTargetDAO = new TextFlowTargetDAO(getSession());
+ }
+
+ @Test
+ public void testQuery()
+ {
+ List reviewComments = reviewCommentsDAO.getReviewComments(new TransUnitId(1L), new LocaleId("as"));
+
+ assertThat(reviewComments, Matchers.empty());
+ }
+
+ @Test
+ public void testTargetUserComment()
+ {
+ PersonDAO personDAO = new PersonDAO(getSession());
+ HPerson person = personDAO.findById(1L, false);
+ HTextFlowTarget target = textFlowTargetDAO.findById(1L, false);
+
+ List userComments = target.getReviewComments();
+
+ assertThat(userComments, Matchers.empty());
+
+ target.addReviewComment("bad translation", person);
+ getEm().persist(target);
+
+ List result = reviewCommentsDAO.getReviewComments(new TransUnitId(target.getTextFlow().getId()), target.getLocaleId());
+
+ assertThat(result, Matchers.hasSize(1));
+ assertThat(result.get(0).getContentsOfCommentedTarget(), Matchers.equalTo(target.getContents()));
+ assertThat(result.get(0).getCommenterName(), Matchers.equalTo(person.getName()));
+ assertThat(result.get(0).getCreationDate(), Matchers.lessThanOrEqualTo(new Date()));
+ }
+
+ @Test
+ public void testTargetUserCommentMadeOnPreviousTranslation()
+ {
+ PersonDAO personDAO = new PersonDAO(getSession());
+ HPerson person = personDAO.findById(1L, false);
+ HTextFlowTarget target = textFlowTargetDAO.findById(2L, false);
+
+ List oldTranslation = target.getContents();
+ int oldVersion = target.getVersionNum();
+
+ target.addReviewComment("comment blah", person);
+ getEm().persist(target);
+
+ // change target after making comment
+ target.setContent0("new translation");
+ getEm().persist(target);
+
+ List result = reviewCommentsDAO.getReviewComments(new TransUnitId(target.getTextFlow().getId()), target.getLocaleId());
+
+
+ assertThat(result.get(0).getContentsOfCommentedTarget(), Matchers.equalTo(oldTranslation));
+ assertThat(result.get(0).getTargetVersion(), Matchers.equalTo(oldVersion));
+ }
+}
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java
new file mode 100644
index 0000000000..431f991db6
--- /dev/null
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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 java.util.List;
+
+import org.hamcrest.Matchers;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.zanata.webtrans.client.rpc.CachingDispatchAsync;
+import org.zanata.webtrans.client.view.ReviewCommentDisplay;
+import org.zanata.webtrans.shared.model.ReviewComment;
+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.google.common.collect.Lists;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import net.customware.gwt.presenter.client.EventBus;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Patrick Huang pahuang@redhat.com
+ */
+@Test(groups = "unit-tests")
+public class ReviewCommentPresenterTest
+{
+ private ReviewCommentPresenter presenter;
+ @Mock
+ private ReviewCommentDisplay display;
+ @Mock
+ private EventBus eventBus;
+ @Mock
+ private CachingDispatchAsync dispather;
+ @Mock
+ private ReviewCommentDataProvider dataProvider;
+
+
+ @BeforeMethod
+ public void beforeMethod()
+ {
+ MockitoAnnotations.initMocks(this);
+
+ presenter = new ReviewCommentPresenter(display, eventBus, dispather, dataProvider);
+
+ verify(display).setDataProvider(dataProvider);
+ verify(display).setListener(presenter);
+ }
+ @Test
+ public void testDisplayCommentView() throws Exception
+ {
+ TransUnitId transUnitId = new TransUnitId(1L);
+ ArgumentCaptor actionCaptor = ArgumentCaptor.forClass(GetReviewCommentsAction.class);
+ ArgumentCaptor resultCaptor = ArgumentCaptor.forClass(AsyncCallback.class);
+
+ presenter.displayCommentView(transUnitId);
+
+ verify(dataProvider).setLoading(true);
+ verify(dispather).execute(actionCaptor.capture(), resultCaptor.capture());
+ assertThat(actionCaptor.getValue().getTransUnitId(), Matchers.equalTo(transUnitId));
+
+ AsyncCallback callback = resultCaptor.getValue();
+ GetReviewCommentsResult result = new GetReviewCommentsResult(Lists.newArrayList(new ReviewComment()));
+ callback.onSuccess(result);
+
+ verify(dataProvider).setLoading(false);
+ verify(dataProvider).setList(result.getComments());
+ }
+
+ @Test
+ public void testAddComment() throws Exception
+ {
+ ArgumentCaptor actionCaptor = ArgumentCaptor.forClass(AddReviewCommentAction.class);
+ ArgumentCaptor resultCaptor = ArgumentCaptor.forClass(AsyncCallback.class);
+ List mockList = mock(List.class);
+ when(dataProvider.getList()).thenReturn(mockList);
+
+ presenter.addComment("some comment");
+
+ verify(dispather).execute(actionCaptor.capture(), resultCaptor.capture());
+ assertThat(actionCaptor.getValue().getContent(), Matchers.equalTo("some comment"));
+
+ AsyncCallback callback = resultCaptor.getValue();
+ AddReviewCommentResult result = new AddReviewCommentResult(new ReviewComment());
+ callback.onSuccess(result);
+
+ verify(dataProvider).getList();
+ verify(mockList).add(result.getComment());
+ verify(display).clearInput();
+ }
+}
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TargetContentsPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TargetContentsPresenterTest.java
index 103eb2ece2..5ef375ecdb 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TargetContentsPresenterTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TargetContentsPresenterTest.java
@@ -124,6 +124,8 @@ public class TargetContentsPresenterTest
private UserOptionsService userOptionsService;
@Mock
private SaveAsApprovedConfirmationDisplay saveAsApprovedConfirmation;
+ @Mock
+ private ReviewCommentPresenter reviewCommentPresenter;
@BeforeMethod
public void beforeMethod()
@@ -134,7 +136,7 @@ public void beforeMethod()
when(userOptionsService.getConfigHolder()).thenReturn(configHolder);
userWorkspaceContext = TestFixture.userWorkspaceContext();
- presenter = new TargetContentsPresenter(displayProvider, editorTranslators, eventBus, tableEditorMessages, sourceContentPresenter, userWorkspaceContext, editorKeyShortcuts, historyPresenter, userOptionsService, saveAsApprovedConfirmation);
+ presenter = new TargetContentsPresenter(displayProvider, editorTranslators, eventBus, tableEditorMessages, sourceContentPresenter, userWorkspaceContext, editorKeyShortcuts, historyPresenter, userOptionsService, saveAsApprovedConfirmation, reviewCommentPresenter);
verify(eventBus).addHandler(UserConfigChangeEvent.TYPE, presenter);
verify(eventBus).addHandler(RequestValidationEvent.getType(), presenter);
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandlerTest.java b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandlerTest.java
new file mode 100644
index 0000000000..193662ba69
--- /dev/null
+++ b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandlerTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.hamcrest.Matchers;
+import org.jboss.seam.security.management.JpaIdentityStore;
+import org.mockito.Answers;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.zanata.common.ContentState;
+import org.zanata.common.LocaleId;
+import org.zanata.model.HLocale;
+import org.zanata.model.HPerson;
+import org.zanata.model.HTextFlowTarget;
+import org.zanata.model.HTextFlowTargetReviewComment;
+import org.zanata.seam.SeamAutowire;
+import org.zanata.service.SecurityService;
+import org.zanata.webtrans.shared.NoSuchWorkspaceException;
+import org.zanata.webtrans.shared.model.ReviewCommentId;
+import org.zanata.webtrans.shared.model.TransUnitId;
+import org.zanata.webtrans.shared.rpc.AddReviewCommentAction;
+import org.zanata.webtrans.shared.rpc.AddReviewCommentResult;
+
+import net.customware.gwt.dispatch.shared.ActionException;
+import static org.hamcrest.MatcherAssert.*;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Patrick Huang pahuang@redhat.com
+ */
+@Test(groups = "unit-tests")
+public class AddReviewCommentHandlerTest
+{
+ private AddReviewCommentHandler handler;
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private org.zanata.service.SecurityService securityServiceImpl;
+ @Mock
+ private org.zanata.dao.TextFlowTargetDAO textFlowTargetDAO;
+ @Mock
+ private org.zanata.model.HAccount authenticatedAccount;
+ @Mock
+ private HTextFlowTarget hTextFlowTarget;
+ @Mock
+ private HPerson hPerson;
+ @Mock
+ private HTextFlowTargetReviewComment hReviewComment;
+
+ @BeforeMethod
+ public void setUp() throws Exception
+ {
+ MockitoAnnotations.initMocks(this);
+ // @formatter:off
+ handler = SeamAutowire.instance().reset()
+ .use("securityServiceImpl", securityServiceImpl)
+ .use("textFlowTargetDAO", textFlowTargetDAO)
+ .use(JpaIdentityStore.AUTHENTICATED_USER, authenticatedAccount)
+ .autowire(AddReviewCommentHandler.class);
+ // @formatter:on
+ }
+
+ @Test
+ public void testExecute() throws Exception
+ {
+ // Given: we want to add comment to trans unit id 2 and locale id DE
+ String commentContent = "new comment";
+ TransUnitId transUnitId = new TransUnitId(2L);
+ AddReviewCommentAction action = new AddReviewCommentAction(transUnitId, commentContent);
+ when(authenticatedAccount.getPerson()).thenReturn(hPerson);
+ when(securityServiceImpl.checkPermission(action, SecurityService.TranslationAction.MODIFY).getLocale()).thenReturn(new HLocale(LocaleId.DE));
+ when(textFlowTargetDAO.getTextFlowTarget(transUnitId.getValue(), LocaleId.DE)).thenReturn(hTextFlowTarget);
+ when(hTextFlowTarget.getState()).thenReturn(ContentState.Rejected);
+ when(hTextFlowTarget.addReviewComment(commentContent, hPerson)).thenReturn(hReviewComment);
+ when(hReviewComment.getId()).thenReturn(1L);
+
+ // When:
+ AddReviewCommentResult result = handler.execute(action, null);
+
+ // Then:
+ InOrder inOrder = Mockito.inOrder(textFlowTargetDAO, hTextFlowTarget);
+ inOrder.verify(textFlowTargetDAO).getTextFlowTarget(transUnitId.getValue(), LocaleId.DE);
+ inOrder.verify(hTextFlowTarget).addReviewComment(commentContent, hPerson);
+ inOrder.verify(textFlowTargetDAO).makePersistent(hTextFlowTarget);
+ inOrder.verify(textFlowTargetDAO).flush();
+
+ assertThat(result.getComment().getId(), Matchers.equalTo(new ReviewCommentId(1L)));
+ }
+
+ @Test(expectedExceptions = ActionException.class)
+ public void testExecuteWhenTargetIsNull() throws Exception
+ {
+ // Given: we want to add comment to trans unit id 1 and locale id DE but target is null
+ String commentContent = "new comment";
+ AddReviewCommentAction action = new AddReviewCommentAction(new TransUnitId(1L), commentContent);
+ when(authenticatedAccount.getPerson()).thenReturn(hPerson);
+ when(hPerson.getName()).thenReturn("John Smith");
+ when(securityServiceImpl.checkPermission(action, SecurityService.TranslationAction.MODIFY).getLocale()).thenReturn(new HLocale(LocaleId.DE));
+ when(textFlowTargetDAO.getTextFlowTarget(1L, LocaleId.DE)).thenReturn(null);
+
+ // When:
+ handler.execute(action, null);
+ }
+
+ @Test(expectedExceptions = ActionException.class)
+ public void testExecuteWhenTargetIsUntranslated() throws Exception
+ {
+ // Given: we want to add comment to trans unit id 1 and locale id DE but target is null
+ String commentContent = "new comment";
+ AddReviewCommentAction action = new AddReviewCommentAction(new TransUnitId(1L), commentContent);
+ when(authenticatedAccount.getPerson()).thenReturn(hPerson);
+ when(hPerson.getName()).thenReturn("John Smith");
+ when(securityServiceImpl.checkPermission(action, SecurityService.TranslationAction.MODIFY).getLocale()).thenReturn(new HLocale(LocaleId.DE));
+ when(textFlowTargetDAO.getTextFlowTarget(1L, LocaleId.DE)).thenReturn(hTextFlowTarget);
+ when(hTextFlowTarget.getState()).thenReturn(ContentState.New);
+
+ // When:
+ handler.execute(action, null);
+ }
+}
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetReviewCommentsHandlerTest.java b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetReviewCommentsHandlerTest.java
new file mode 100644
index 0000000000..59f9e7b9f8
--- /dev/null
+++ b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetReviewCommentsHandlerTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.hamcrest.Matchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.zanata.common.ContentState;
+import org.zanata.common.LocaleId;
+import org.zanata.dao.TextFlowTargetReviewCommentsDAO;
+import org.zanata.model.HLocale;
+import org.zanata.model.HPerson;
+import org.zanata.model.HTextFlow;
+import org.zanata.model.HTextFlowTargetReviewComment;
+import org.zanata.model.TestFixture;
+import org.zanata.seam.SeamAutowire;
+import org.zanata.webtrans.shared.model.TransUnitId;
+import org.zanata.webtrans.shared.rpc.GetReviewCommentsAction;
+import org.zanata.webtrans.shared.rpc.GetReviewCommentsResult;
+
+import com.google.common.collect.Lists;
+
+import static org.hamcrest.MatcherAssert.*;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Patrick Huang pahuang@redhat.com
+ */
+@Test(groups = "unit-tests")
+public class GetReviewCommentsHandlerTest
+{
+ private GetReviewCommentsHandler handler;
+ @Mock
+ private TextFlowTargetReviewCommentsDAO dao;
+
+ @BeforeMethod
+ public void setUp() throws Exception
+ {
+ MockitoAnnotations.initMocks(this);
+
+ handler = SeamAutowire.instance().reset().use("textFlowTargetReviewCommentsDAO", dao).autowire(GetReviewCommentsHandler.class);
+ }
+
+ @Test
+ public void testExecute() throws Exception
+ {
+ GetReviewCommentsAction action = new GetReviewCommentsAction(new TransUnitId(1L));
+ action.setWorkspaceId(TestFixture.workspaceId());
+ LocaleId localeId = action.getWorkspaceId().getLocaleId();
+ when(dao.getReviewComments(action.getTransUnitId(), localeId)).thenReturn(Lists.newArrayList(makeCommentEntity(localeId, "a comment"), makeCommentEntity(localeId, "another comment")));
+
+ GetReviewCommentsResult result = handler.execute(action, null);
+
+ assertThat(result.getComments(), Matchers.hasSize(2));
+ assertThat(result.getComments().get(0).getComment(), Matchers.equalTo("a comment"));
+ assertThat(result.getComments().get(1).getComment(), Matchers.equalTo("another comment"));
+
+ }
+
+ private static HTextFlowTargetReviewComment makeCommentEntity(LocaleId localeId, String comment)
+ {
+ HLocale hLocale = new HLocale(localeId);
+ TestFixture.setId(2L, hLocale);
+
+ HTextFlow textFlow = TestFixture.makeHTextFlow(1L, hLocale, ContentState.Rejected);
+
+ HPerson commenter = new HPerson();
+ TestFixture.setId(3L, commenter);
+
+ return new HTextFlowTargetReviewComment(textFlow.getTargets().get(hLocale.getId()), comment, commenter);
+ }
+}
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/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
+
+
+
From de9f9f2e6c66c29b705e18a902175456d658c86a Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Thu, 4 Jul 2013 09:33:16 +1000
Subject: [PATCH 052/184] Tech Debt: eager load text flow targets when we
intended to access them
---
.../main/java/org/zanata/dao/TextFlowDAO.java | 5 +++--
.../server/rpc/GetTransUnitListHandler.java | 2 +-
.../java/org/zanata/dao/TextFlowDAOTest.java | 20 ++++++++++++++-----
.../client/service/MockHandlerFactory.java | 2 +-
4 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
index 41fce047e3..caf112afb6 100644
--- a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
@@ -271,10 +271,11 @@ public int getCountByDocument(Long documentId)
}
@SuppressWarnings("unchecked")
- public List getTextFlowsByDocumentId(DocumentId documentId, int startIndex, int maxSize)
+ public List getTextFlowsByDocumentId(DocumentId documentId, HLocale hLocale, int startIndex, int maxSize)
{
- Query q = getSession().createQuery("from HTextFlow tf where tf.obsolete=0 and tf.document.id = :id order by tf.pos");
+ Query q = getSession().createQuery("from HTextFlow tf left join tf.targets tft with tft.index = :locale where tf.obsolete=0 and tf.document.id = :id order by tf.pos");
q.setParameter("id", documentId.getId());
+ q.setParameter("locale", hLocale.getId());
q.setFirstResult(startIndex);
q.setMaxResults(maxSize);
q.setCacheable(true).setComment("TextFlowDAO.getTextFlowsByDocumentId");
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 d2e20551e4..fb3742f571 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
@@ -124,7 +124,7 @@ private List getTextFlows(GetTransUnitList action, HLocale hLocale, i
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());
+ textFlows = textFlowDAO.getTextFlowsByDocumentId(action.getDocumentId(), hLocale, offset, action.getCount());
}
// has validation filter
else
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index 018457f69e..749408dae3 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -55,11 +55,11 @@ private void printTestData()
}
//3 text flows with single en-US fuzzy target
- List doc2TextFlows = dao.getTextFlowsByDocumentId(new DocumentId(2L, ""), 0, 9999);
- for (HTextFlow doc2tf : doc2TextFlows)
- {
- log.debug("text flow id {} - targets {}", doc2tf.getId(), doc2tf.getTargets());
- }
+// List doc2TextFlows = dao.getTextFlowsByDocumentId(new DocumentId(2L, ""), hLocale, 0, 9999);
+// for (HTextFlow doc2tf : doc2TextFlows)
+// {
+// log.debug("text flow id {} - targets {}", doc2tf.getId(), doc2tf.getTargets());
+// }
//single text flow no target
HTextFlow textFlow6 = dao.findById(6L, false);
@@ -183,4 +183,14 @@ public void queryTest1()
List result = query.list();
}
+
+ @Test
+ public void canGetTextFlowWithTranslationEagerlyLoaded()
+ {
+ //3 text flows with single en-US fuzzy target
+ HLocale enUSLocale = getEm().find(HLocale.class, 4L);
+ log.info("*************");
+ List doc2TextFlows = dao.getTextFlowsByDocumentId(new DocumentId(2L, ""), enUSLocale, 0, 9999);
+
+ }
}
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java b/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java
index cf9c275075..41cfc1f92b 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java
@@ -67,7 +67,7 @@ public GetTransUnitListHandler createGetTransUnitListHandlerWithBehavior(Documen
// @formatter:on
int maxSize = Math.min(startIndex + count, hTextFlows.size());
- when(textFlowDAO.getTextFlowsByDocumentId(documentId, startIndex, count)).thenReturn(hTextFlows.subList(startIndex, maxSize));
+ when(textFlowDAO.getTextFlowsByDocumentId(documentId, hLocale, startIndex, count)).thenReturn(hTextFlows.subList(startIndex, maxSize));
when(localeServiceImpl.validateLocaleByProjectIteration(any(LocaleId.class), anyString(), anyString())).thenReturn(hLocale);
when(resourceUtils.getNumPlurals(any(HDocument.class), any(HLocale.class))).thenReturn(1);
From 30a65f3adef2ec731f112d08610d5a3a2143eaf1 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Thu, 4 Jul 2013 09:33:56 +1000
Subject: [PATCH 053/184] rename methods after refactor
---
zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java | 2 +-
.../zanata/webtrans/server/rpc/GetTransUnitListHandler.java | 3 +--
zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java | 2 +-
.../org/zanata/webtrans/client/service/MockHandlerFactory.java | 2 +-
4 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
index caf112afb6..fadd94010b 100644
--- a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
@@ -271,7 +271,7 @@ public int getCountByDocument(Long documentId)
}
@SuppressWarnings("unchecked")
- public List getTextFlowsByDocumentId(DocumentId documentId, HLocale hLocale, int startIndex, int maxSize)
+ public List getTextFlowsAndTargetsByDocumentId(DocumentId documentId, HLocale hLocale, int startIndex, int maxSize)
{
Query q = getSession().createQuery("from HTextFlow tf left join tf.targets tft with tft.index = :locale where tf.obsolete=0 and tf.document.id = :id order by tf.pos");
q.setParameter("id", documentId.getId());
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 fb3742f571..6d1af11bf2 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,8 +123,7 @@ 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(), hLocale, offset, action.getCount());
+ textFlows = textFlowDAO.getTextFlowsAndTargetsByDocumentId(action.getDocumentId(), hLocale, offset, action.getCount());
}
// has validation filter
else
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index 749408dae3..8f82500963 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -190,7 +190,7 @@ public void canGetTextFlowWithTranslationEagerlyLoaded()
//3 text flows with single en-US fuzzy target
HLocale enUSLocale = getEm().find(HLocale.class, 4L);
log.info("*************");
- List doc2TextFlows = dao.getTextFlowsByDocumentId(new DocumentId(2L, ""), enUSLocale, 0, 9999);
+ List doc2TextFlows = dao.getTextFlowsAndTargetsByDocumentId(new DocumentId(2L, ""), enUSLocale, 0, 9999);
}
}
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java b/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java
index 41cfc1f92b..3d6dfbab52 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java
@@ -67,7 +67,7 @@ public GetTransUnitListHandler createGetTransUnitListHandlerWithBehavior(Documen
// @formatter:on
int maxSize = Math.min(startIndex + count, hTextFlows.size());
- when(textFlowDAO.getTextFlowsByDocumentId(documentId, hLocale, startIndex, count)).thenReturn(hTextFlows.subList(startIndex, maxSize));
+ when(textFlowDAO.getTextFlowsAndTargetsByDocumentId(documentId, hLocale, startIndex, count)).thenReturn(hTextFlows.subList(startIndex, maxSize));
when(localeServiceImpl.validateLocaleByProjectIteration(any(LocaleId.class), anyString(), anyString())).thenReturn(hLocale);
when(resourceUtils.getNumPlurals(any(HDocument.class), any(HLocale.class))).thenReturn(1);
From 5bf3c8a9315d46afa7ba3938cf64808eea28ff0f Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Thu, 4 Jul 2013 12:49:34 +1000
Subject: [PATCH 054/184] revert optimization change
this is too big a refactoring and should do in its own pull request
---
zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java | 5 ++---
.../zanata/webtrans/server/rpc/GetTransUnitListHandler.java | 3 ++-
zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java | 2 +-
.../zanata/webtrans/client/service/MockHandlerFactory.java | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
index fadd94010b..41fce047e3 100644
--- a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
@@ -271,11 +271,10 @@ public int getCountByDocument(Long documentId)
}
@SuppressWarnings("unchecked")
- public List getTextFlowsAndTargetsByDocumentId(DocumentId documentId, HLocale hLocale, int startIndex, int maxSize)
+ public List getTextFlowsByDocumentId(DocumentId documentId, int startIndex, int maxSize)
{
- Query q = getSession().createQuery("from HTextFlow tf left join tf.targets tft with tft.index = :locale where tf.obsolete=0 and tf.document.id = :id order by tf.pos");
+ Query q = getSession().createQuery("from HTextFlow tf where tf.obsolete=0 and tf.document.id = :id order by tf.pos");
q.setParameter("id", documentId.getId());
- q.setParameter("locale", hLocale.getId());
q.setFirstResult(startIndex);
q.setMaxResults(maxSize);
q.setCacheable(true).setComment("TextFlowDAO.getTextFlowsByDocumentId");
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 6d1af11bf2..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,7 +123,8 @@ private List getTextFlows(GetTransUnitList action, HLocale hLocale, i
log.debug("Fetch TransUnits:*");
if (!hasValidationFilter(action))
{
- textFlows = textFlowDAO.getTextFlowsAndTargetsByDocumentId(action.getDocumentId(), hLocale, offset, action.getCount());
+ // 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
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index 8f82500963..5eaf97a455 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -190,7 +190,7 @@ public void canGetTextFlowWithTranslationEagerlyLoaded()
//3 text flows with single en-US fuzzy target
HLocale enUSLocale = getEm().find(HLocale.class, 4L);
log.info("*************");
- List doc2TextFlows = dao.getTextFlowsAndTargetsByDocumentId(new DocumentId(2L, ""), enUSLocale, 0, 9999);
+ List doc2TextFlows = dao.getTextFlowsByDocumentId(new DocumentId(2L, ""), 0, 9999);
}
}
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java b/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java
index 3d6dfbab52..cf9c275075 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/service/MockHandlerFactory.java
@@ -67,7 +67,7 @@ public GetTransUnitListHandler createGetTransUnitListHandlerWithBehavior(Documen
// @formatter:on
int maxSize = Math.min(startIndex + count, hTextFlows.size());
- when(textFlowDAO.getTextFlowsAndTargetsByDocumentId(documentId, hLocale, startIndex, count)).thenReturn(hTextFlows.subList(startIndex, maxSize));
+ when(textFlowDAO.getTextFlowsByDocumentId(documentId, startIndex, count)).thenReturn(hTextFlows.subList(startIndex, maxSize));
when(localeServiceImpl.validateLocaleByProjectIteration(any(LocaleId.class), anyString(), anyString())).thenReturn(hLocale);
when(resourceUtils.getNumPlurals(any(HDocument.class), any(HLocale.class))).thenReturn(1);
From 65bd09cf2614484a32e92fbe0d4ab31fe643d7dd Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Thu, 4 Jul 2013 14:06:29 +1000
Subject: [PATCH 055/184] rhbz978666 - add comment indicator
---
.../webtrans/client/view/TargetContentsDisplay.java | 2 --
.../webtrans/client/view/TargetContentsView.java | 11 +++++------
.../webtrans/client/view/TargetContentsView.ui.xml | 13 +++++++++++++
3 files changed, 18 insertions(+), 8 deletions(-)
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 049a0d65f9..4f9beea5bc 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,8 +70,6 @@ public interface TargetContentsDisplay extends WidgetDisplay, HasTransUnitId, Ha
void setEnableSpellCheck(boolean spellCheckEnabled);
- ContentState getCachedState();
-
interface Listener
{
void validate(ToggleEditor editor);
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 68b16e1b6e..98f8991eb0 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,6 +24,7 @@
import java.util.List;
import org.zanata.common.ContentState;
+import org.zanata.webtrans.client.resources.TableEditorMessages;
import org.zanata.webtrans.client.ui.Editor;
import org.zanata.webtrans.client.ui.EditorButtonsWidget;
import org.zanata.webtrans.client.ui.ToggleEditor;
@@ -65,6 +66,8 @@ public class TargetContentsView extends Composite implements TargetContentsDispl
Label savingIndicator;
@UiField
EditorButtonsWidget buttons;
+ @UiField
+ Label commentIndicator;
private HorizontalPanel rootPanel;
private ArrayList editors;
@@ -114,6 +117,8 @@ public void addUndo(final UndoLink undoLink)
public void setValueAndCreateNewEditors(TransUnit transUnit)
{
setCachedTU(transUnit);
+ commentIndicator.setVisible(transUnit.getCommentsCount() > 0);
+ commentIndicator.setText(String.valueOf(transUnit.getCommentsCount()));
editors.clear();
List cachedTargets = cachedValue.getTargets();
@@ -218,12 +223,6 @@ public List getCachedTargets()
return cachedValue.getTargets();
}
- @Override
- public ContentState getCachedState()
- {
- return cachedValue.getStatus();
- }
-
@Override
public TransUnitId getId()
{
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..6357ac36a7 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,25 @@
background-color: #ff4500;
}
+ .commentCount {
+ position: absolute;
+ top: 8px;
+ right: 30px;
+ font-size: smaller;
+ color: #ffffff;
+ z-index: 1;
+ background-color: #ff4500;
+ border-radius: 3px;
+ border: thick double #ffffff;
+ }
+
+
From 3fbc6adde7ae59f2bdf354f5a3c62705df3f05c6 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Thu, 4 Jul 2013 15:30:03 +1000
Subject: [PATCH 056/184] rhbz978666 - add comment indicator
---
.../client/events/ReviewCommentEvent.java | 52 +++++++++++++++++++
.../events/ReviewCommentEventHandler.java | 29 +++++++++++
.../presenter/ReviewCommentPresenter.java | 12 +++--
.../presenter/TargetContentsPresenter.java | 8 +--
.../client/ui/EditorButtonsWidget.java | 11 ++--
.../client/view/TargetContentsDisplay.java | 1 -
.../client/view/TargetContentsView.java | 18 ++++++-
.../client/view/TargetContentsView.ui.xml | 15 +++---
.../presenter/ReviewCommentPresenterTest.java | 3 +-
9 files changed, 123 insertions(+), 26 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/events/ReviewCommentEvent.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/events/ReviewCommentEventHandler.java
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/presenter/ReviewCommentPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenter.java
index 3991295ce4..f56dc3c072 100644
--- 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
@@ -21,16 +21,16 @@
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.view.ReviewCommentDisplay;
-import org.zanata.webtrans.shared.model.ReviewComment;
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.google.gwt.view.client.ListDataProvider;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -41,7 +41,7 @@
* @author Patrick Huang pahuang@redhat.com
*/
@Singleton
-public class ReviewCommentPresenter extends WidgetPresenter implements ReviewCommentDisplay.Listener
+public class ReviewCommentPresenter extends WidgetPresenter implements ReviewCommentDisplay.Listener, ReviewCommentEventHandler
{
private final ReviewCommentDisplay display;
private final CachingDispatchAsync dispatcher;
@@ -63,11 +63,13 @@ public ReviewCommentPresenter(ReviewCommentDisplay display, EventBus eventBus, C
@Override
protected void onBind()
{
+ eventBus.addHandler(ReviewCommentEvent.TYPE, this);
}
- public void displayCommentView(TransUnitId transUnitId)
+ @Override
+ public void onShowReviewComment(ReviewCommentEvent event)
{
- this.transUnitId = transUnitId;
+ this.transUnitId = event.getTransUnitId();
dataProvider.setLoading(true);
dispatcher.execute(new GetReviewCommentsAction(transUnitId), new AbstractAsyncCallback()
{
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 dcd9a4deca..d5b104e6db 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
@@ -148,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()
@@ -683,13 +684,6 @@ public void rejectTranslation(TransUnitId id)
saveCurrent(ContentState.Rejected);
}
- @Override
- public void commentTranslation(TransUnitId id)
- {
- ensureRowSelection(id);
- reviewCommentPresenter.displayCommentView(id);
- }
-
/**
* For testing only
* @param currentTransUnitId current trans unit id
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 166dad6adb..748331e48d 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,9 +1,9 @@
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.allen_sauer.gwt.log.client.Log;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.resources.client.CssResource;
@@ -15,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;
@@ -43,8 +46,9 @@ public class EditorButtonsWidget extends Composite
private TargetContentsDisplay.Listener listener;
private TransUnitId id;
- public EditorButtonsWidget()
+ public EditorButtonsWidget(EventBus eventBus)
{
+ this.eventBus = eventBus;
initWidget(ourUiBinder.createAndBindUi(this));
displayReviewButtons(listener != null && listener.canReviewTranslation());
}
@@ -120,8 +124,7 @@ public void onReject(ClickEvent event)
@UiHandler("commentIcon")
public void onCommentClick(ClickEvent event)
{
- listener.commentTranslation(id);
- event.stopPropagation();
+ eventBus.fireEvent(new ReviewCommentEvent(id));
}
public void setListener(TargetContentsDisplay.Listener listener)
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 4f9beea5bc..bac390994a 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
@@ -102,7 +102,6 @@ interface Listener
void rejectTranslation(TransUnitId id);
- void commentTranslation(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 98f8991eb0..5fab1a3d9b 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,6 +24,7 @@
import java.util.List;
import org.zanata.common.ContentState;
+import org.zanata.webtrans.client.events.ReviewCommentEvent;
import org.zanata.webtrans.client.resources.TableEditorMessages;
import org.zanata.webtrans.client.ui.Editor;
import org.zanata.webtrans.client.ui.EditorButtonsWidget;
@@ -37,9 +38,11 @@
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
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.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
@@ -48,10 +51,13 @@
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;
@@ -64,7 +70,7 @@ public class TargetContentsView extends Composite implements TargetContentsDispl
@UiField
Label savingIndicator;
- @UiField
+ @UiField(provided = true)
EditorButtonsWidget buttons;
@UiField
Label commentIndicator;
@@ -77,8 +83,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");
@@ -87,6 +95,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)
{
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 6357ac36a7..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,16 +33,19 @@
background-color: #ff4500;
}
- .commentCount {
+ .commentIndicator {
position: absolute;
- top: 8px;
- right: 30px;
+ right: 5px;
font-size: smaller;
color: #ffffff;
z-index: 1;
- background-color: #ff4500;
- border-radius: 3px;
+ background-color: #ff0000;
+ border-radius: 10px;
border: thick double #ffffff;
+ padding-left: 2px;
+ padding-right: 2px;
+ box-shadow: 2px 2px 2px #888;
+ cursor: pointer;
}
@@ -51,7 +54,7 @@
-
+
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java
index 431f991db6..e1f0e6eda7 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java
@@ -29,6 +29,7 @@
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import org.zanata.webtrans.client.events.ReviewCommentEvent;
import org.zanata.webtrans.client.rpc.CachingDispatchAsync;
import org.zanata.webtrans.client.view.ReviewCommentDisplay;
import org.zanata.webtrans.shared.model.ReviewComment;
@@ -80,7 +81,7 @@ public void testDisplayCommentView() throws Exception
ArgumentCaptor actionCaptor = ArgumentCaptor.forClass(GetReviewCommentsAction.class);
ArgumentCaptor resultCaptor = ArgumentCaptor.forClass(AsyncCallback.class);
- presenter.displayCommentView(transUnitId);
+ presenter.onShowReviewComment(new ReviewCommentEvent(transUnitId));
verify(dataProvider).setLoading(true);
verify(dispather).execute(actionCaptor.capture(), resultCaptor.capture());
From 08d2414acfb5d8e5f752a7951f228236245234f6 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Thu, 4 Jul 2013 15:43:43 +1000
Subject: [PATCH 057/184] minor clean up
---
.../presenter/DocumentListPresenter.java | 23 ++++---------------
1 file changed, 4 insertions(+), 19 deletions(-)
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());
From 1744a5abe854af58f236fad8da0630e1ce9c04af Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Fri, 5 Jul 2013 08:54:03 +1000
Subject: [PATCH 058/184] rhbz978666 - comment change is broadcasted thru event
service
---
.../presenter/ReviewCommentPresenter.java | 7 +++--
.../presenter/TargetContentsPresenter.java | 10 +++++++
.../presenter/TransUnitsTablePresenter.java | 9 +++++-
.../client/view/TargetContentsDisplay.java | 2 ++
.../client/view/TargetContentsView.java | 14 +++++++---
.../server/rpc/AddReviewCommentHandler.java | 21 ++++++++++++--
.../server/rpc/TransUnitTransformer.java | 2 +-
.../shared/rpc/AddReviewCommentAction.java | 10 ++++++-
.../webtrans/shared/rpc/TransUnitUpdated.java | 2 +-
.../presenter/ReviewCommentPresenterTest.java | 8 +++++-
.../rpc/AddReviewCommentHandlerTest.java | 28 +++++++++++++------
11 files changed, 92 insertions(+), 21 deletions(-)
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
index f56dc3c072..620d0c3408 100644
--- 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
@@ -25,6 +25,7 @@
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.view.ReviewCommentDisplay;
import org.zanata.webtrans.shared.model.TransUnitId;
import org.zanata.webtrans.shared.rpc.AddReviewCommentAction;
@@ -46,15 +47,17 @@ public class ReviewCommentPresenter extends WidgetPresenter()
+ dispatcher.execute(new AddReviewCommentAction(transUnitId, content, contextHolder.getContext().getDocument().getId()), new AbstractAsyncCallback()
{
@Override
public void onSuccess(AddReviewCommentResult result)
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 d5b104e6db..7ecc6620f3 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
@@ -684,6 +684,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/view/TargetContentsDisplay.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TargetContentsDisplay.java
index bac390994a..1244488195 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);
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 5fab1a3d9b..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
@@ -25,7 +25,6 @@
import org.zanata.common.ContentState;
import org.zanata.webtrans.client.events.ReviewCommentEvent;
-import org.zanata.webtrans.client.resources.TableEditorMessages;
import org.zanata.webtrans.client.ui.Editor;
import org.zanata.webtrans.client.ui.EditorButtonsWidget;
import org.zanata.webtrans.client.ui.ToggleEditor;
@@ -34,7 +33,6 @@
import org.zanata.webtrans.client.util.ContentStateToStyleUtil;
import org.zanata.webtrans.shared.model.TransUnit;
import org.zanata.webtrans.shared.model.TransUnitId;
-
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.gwt.core.client.GWT;
@@ -131,8 +129,7 @@ public void addUndo(final UndoLink undoLink)
public void setValueAndCreateNewEditors(TransUnit transUnit)
{
setCachedTU(transUnit);
- commentIndicator.setVisible(transUnit.getCommentsCount() > 0);
- commentIndicator.setText(String.valueOf(transUnit.getCommentsCount()));
+ updateCommentIndicator(transUnit.getCommentsCount());
editors.clear();
List cachedTargets = cachedValue.getTargets();
@@ -158,6 +155,13 @@ private static String resolveStyleName(ContentState status)
return ContentStateToStyleUtil.stateToStyle(status, "TableEditorRow ");
}
+ @Override
+ public void updateCommentIndicator(int commentsCount)
+ {
+ commentIndicator.setVisible(commentsCount > 0);
+ commentIndicator.setText(String.valueOf(commentsCount));
+ }
+
@Override
public void setState(EditingState editingState)
{
@@ -321,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/server/rpc/AddReviewCommentHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandler.java
index a3d9405b7d..6d2551b3df 100644
--- 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
@@ -29,14 +29,19 @@
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;
@@ -60,12 +65,15 @@ public class AddReviewCommentHandler extends AbstractActionHandler actionCaptor = ArgumentCaptor.forClass(AddReviewCommentAction.class);
ArgumentCaptor resultCaptor = ArgumentCaptor.forClass(AsyncCallback.class);
List mockList = mock(List.class);
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandlerTest.java b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandlerTest.java
index 193662ba69..4322a9cd96 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandlerTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/AddReviewCommentHandlerTest.java
@@ -34,11 +34,14 @@
import org.zanata.common.LocaleId;
import org.zanata.model.HLocale;
import org.zanata.model.HPerson;
+import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
import org.zanata.model.HTextFlowTargetReviewComment;
+import org.zanata.model.TestFixture;
import org.zanata.seam.SeamAutowire;
import org.zanata.service.SecurityService;
import org.zanata.webtrans.shared.NoSuchWorkspaceException;
+import org.zanata.webtrans.shared.model.DocumentId;
import org.zanata.webtrans.shared.model.ReviewCommentId;
import org.zanata.webtrans.shared.model.TransUnitId;
import org.zanata.webtrans.shared.rpc.AddReviewCommentAction;
@@ -63,12 +66,17 @@ public class AddReviewCommentHandlerTest
private org.zanata.dao.TextFlowTargetDAO textFlowTargetDAO;
@Mock
private org.zanata.model.HAccount authenticatedAccount;
- @Mock
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
private HTextFlowTarget hTextFlowTarget;
@Mock
private HPerson hPerson;
@Mock
private HTextFlowTargetReviewComment hReviewComment;
+ private DocumentId documentId = new DocumentId(1L, "my/doc");
+ @Mock
+ private TransUnitTransformer transUnitTransformer;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private HTextFlow hTextFlow;
@BeforeMethod
public void setUp() throws Exception
@@ -79,6 +87,7 @@ public void setUp() throws Exception
.use("securityServiceImpl", securityServiceImpl)
.use("textFlowTargetDAO", textFlowTargetDAO)
.use(JpaIdentityStore.AUTHENTICATED_USER, authenticatedAccount)
+ .use("transUnitTransformer", transUnitTransformer)
.autowire(AddReviewCommentHandler.class);
// @formatter:on
}
@@ -89,11 +98,14 @@ public void testExecute() throws Exception
// Given: we want to add comment to trans unit id 2 and locale id DE
String commentContent = "new comment";
TransUnitId transUnitId = new TransUnitId(2L);
- AddReviewCommentAction action = new AddReviewCommentAction(transUnitId, commentContent);
+ HLocale hLocale = new HLocale(LocaleId.DE);
+ AddReviewCommentAction action = new AddReviewCommentAction(transUnitId, commentContent, documentId);
when(authenticatedAccount.getPerson()).thenReturn(hPerson);
- when(securityServiceImpl.checkPermission(action, SecurityService.TranslationAction.MODIFY).getLocale()).thenReturn(new HLocale(LocaleId.DE));
- when(textFlowTargetDAO.getTextFlowTarget(transUnitId.getValue(), LocaleId.DE)).thenReturn(hTextFlowTarget);
+ when(securityServiceImpl.checkPermission(action, SecurityService.TranslationAction.MODIFY).getLocale()).thenReturn(hLocale);
+ when(textFlowTargetDAO.getTextFlowTarget(transUnitId.getValue(), hLocale.getLocaleId())).thenReturn(hTextFlowTarget);
when(hTextFlowTarget.getState()).thenReturn(ContentState.Rejected);
+ when(hTextFlowTarget.getTextFlow()).thenReturn(hTextFlow);
+ when(transUnitTransformer.transform(hTextFlow, hTextFlowTarget, hLocale)).thenReturn(TestFixture.makeTransUnit(transUnitId.getId()));
when(hTextFlowTarget.addReviewComment(commentContent, hPerson)).thenReturn(hReviewComment);
when(hReviewComment.getId()).thenReturn(1L);
@@ -102,7 +114,7 @@ public void testExecute() throws Exception
// Then:
InOrder inOrder = Mockito.inOrder(textFlowTargetDAO, hTextFlowTarget);
- inOrder.verify(textFlowTargetDAO).getTextFlowTarget(transUnitId.getValue(), LocaleId.DE);
+ inOrder.verify(textFlowTargetDAO).getTextFlowTarget(transUnitId.getValue(), hLocale.getLocaleId());
inOrder.verify(hTextFlowTarget).addReviewComment(commentContent, hPerson);
inOrder.verify(textFlowTargetDAO).makePersistent(hTextFlowTarget);
inOrder.verify(textFlowTargetDAO).flush();
@@ -115,7 +127,7 @@ public void testExecuteWhenTargetIsNull() throws Exception
{
// Given: we want to add comment to trans unit id 1 and locale id DE but target is null
String commentContent = "new comment";
- AddReviewCommentAction action = new AddReviewCommentAction(new TransUnitId(1L), commentContent);
+ AddReviewCommentAction action = new AddReviewCommentAction(new TransUnitId(1L), commentContent, documentId);
when(authenticatedAccount.getPerson()).thenReturn(hPerson);
when(hPerson.getName()).thenReturn("John Smith");
when(securityServiceImpl.checkPermission(action, SecurityService.TranslationAction.MODIFY).getLocale()).thenReturn(new HLocale(LocaleId.DE));
@@ -128,9 +140,9 @@ public void testExecuteWhenTargetIsNull() throws Exception
@Test(expectedExceptions = ActionException.class)
public void testExecuteWhenTargetIsUntranslated() throws Exception
{
- // Given: we want to add comment to trans unit id 1 and locale id DE but target is null
+ // Given: we want to add comment to trans unit id 1 and locale id DE but target is new
String commentContent = "new comment";
- AddReviewCommentAction action = new AddReviewCommentAction(new TransUnitId(1L), commentContent);
+ AddReviewCommentAction action = new AddReviewCommentAction(new TransUnitId(1L), commentContent, documentId);
when(authenticatedAccount.getPerson()).thenReturn(hPerson);
when(hPerson.getName()).thenReturn("John Smith");
when(securityServiceImpl.checkPermission(action, SecurityService.TranslationAction.MODIFY).getLocale()).thenReturn(new HLocale(LocaleId.DE));
From bad1cdb7699a92fd2b277040accde55d5470e524 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Mon, 8 Jul 2013 09:09:43 +1000
Subject: [PATCH 059/184] minor - reformat comment
---
.../zanata/webtrans/server/rpc/TransUnitTransformer.java | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
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 311997f90b..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
@@ -52,8 +52,11 @@ 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.
+ // 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);
From a02e784e16db946bb0f6d2133c40827dd1b02bcc Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Mon, 8 Jul 2013 12:11:10 +1000
Subject: [PATCH 060/184] rhbz978666 - style comments made against old
translation
---
.../presenter/ReviewCommentPresenter.java | 9 ++++-
.../client/view/ReviewCommentDisplay.java | 2 ++
.../client/view/ReviewCommentView.java | 33 +++++++++++++++++--
.../client/view/ReviewCommentView.ui.xml | 7 ++++
.../presenter/ReviewCommentPresenterTest.java | 10 +++++-
5 files changed, 56 insertions(+), 5 deletions(-)
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
index 620d0c3408..251342c8e5 100644
--- 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
@@ -26,12 +26,15 @@
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;
@@ -48,16 +51,18 @@ public class ReviewCommentPresenter extends WidgetPresenter()
{
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
index 410e641db8..0c8b33108a 100644
--- 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
@@ -48,6 +48,8 @@ public Object getKey(ReviewComment item)
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
index a7da69d2a7..ea5f04e7db 100644
--- 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
@@ -26,11 +26,14 @@
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;
@@ -62,10 +65,13 @@ public class ReviewCommentView extends DialogBox implements ReviewCommentDisplay
WebTransMessages messages;
@UiField
VerticalPanel commentsContainer;
+ @UiField
+ Styles style;
private final CellTable commentTable;
private Listener listener;
private TextBox commentInputBox;
+ private Integer currentTargetVersion;
public ReviewCommentView()
{
@@ -91,8 +97,7 @@ private Widget createCommentInput()
FlowPanel panel = new FlowPanel();
commentInputBox = new TextBox();
panel.add(commentInputBox);
- // TODO pahuang localize
- Button addButton = new Button("Add", new ClickHandler()
+ Button addButton = new Button(messages.reviewComment(), new ClickHandler()
{
@Override
public void onClick(ClickEvent event)
@@ -126,7 +131,7 @@ private CellTable setUpTable()
return table;
}
- private static Column createCommentColumn()
+ private Column createCommentColumn()
{
return new Column(new TextCell())
{
@@ -135,6 +140,16 @@ 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);
+ }
};
}
@@ -168,6 +183,12 @@ public void clearInput()
commentInputBox.setText("");
}
+ @Override
+ public void setCurrentTargetVersion(Integer targetVersion)
+ {
+ this.currentTargetVersion = targetVersion;
+ }
+
@Override
public void setDataProvider(ListDataProvider dataProvider)
{
@@ -183,4 +204,10 @@ public void setListener(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
index 651dd952b1..f4f7410e1b 100644
--- 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
@@ -23,6 +23,13 @@
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:z='urn:import:org.zanata.webtrans.client.ui'>
+
+ .obsoleteComment
+ {
+ font-style: italic;
+ text-decoration: line-through;
+ }
+
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java
index cff15d55bd..08eb42371c 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/ReviewCommentPresenterTest.java
@@ -33,6 +33,7 @@
import org.zanata.webtrans.client.events.ReviewCommentEvent;
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.DocumentId;
import org.zanata.webtrans.shared.model.ReviewComment;
@@ -67,6 +68,8 @@ public class ReviewCommentPresenterTest
private ReviewCommentDataProvider dataProvider;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private GetTransUnitActionContextHolder contextHolder;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private NavigationService navigationService;
@BeforeMethod
@@ -74,7 +77,7 @@ public void beforeMethod()
{
MockitoAnnotations.initMocks(this);
- presenter = new ReviewCommentPresenter(display, eventBus, dispather, dataProvider, contextHolder);
+ presenter = new ReviewCommentPresenter(display, eventBus, dispather, dataProvider, contextHolder, navigationService);
verify(display).setDataProvider(dataProvider);
verify(display).setListener(presenter);
@@ -82,12 +85,16 @@ public void beforeMethod()
@Test
public void testDisplayCommentView() throws Exception
{
+ // Given: trans unit id 1 and current target version 99
TransUnitId transUnitId = new TransUnitId(1L);
+ when(navigationService.getByIdOrNull(transUnitId).getVerNum()).thenReturn(99);
ArgumentCaptor actionCaptor = ArgumentCaptor.forClass(GetReviewCommentsAction.class);
ArgumentCaptor resultCaptor = ArgumentCaptor.forClass(AsyncCallback.class);
+ // When:
presenter.onShowReviewComment(new ReviewCommentEvent(transUnitId));
+ // Then:
verify(dataProvider).setLoading(true);
verify(dispather).execute(actionCaptor.capture(), resultCaptor.capture());
assertThat(actionCaptor.getValue().getTransUnitId(), Matchers.equalTo(transUnitId));
@@ -96,6 +103,7 @@ public void testDisplayCommentView() throws Exception
GetReviewCommentsResult result = new GetReviewCommentsResult(Lists.newArrayList(new ReviewComment()));
callback.onSuccess(result);
+ verify(display).setCurrentTargetVersion(99);
verify(dataProvider).setLoading(false);
verify(dataProvider).setList(result.getComments());
}
From ec4db57ec73fa8d9274be1b992acdc6a73159a7f Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Mon, 8 Jul 2013 14:07:24 +1000
Subject: [PATCH 061/184] rhbz978666 - minor query improvement
---
.../zanata/model/HTextFlowTargetReviewComment.java | 2 +-
.../zanata/dao/TextFlowTargetReviewCommentsDAO.java | 2 +-
.../dao/TextFlowTargetReviewCommentsDAOJPATest.java | 5 +++--
.../org/zanata/test/model/TextFlowTestData.dbunit.xml | 11 +++++++++++
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
index f078be982b..377ddd3dc4 100644
--- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
+++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
@@ -103,7 +103,7 @@ public String getComment()
@NotNull
@NaturalId
- @ManyToOne
+ @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "target_id")
@IndexedEmbedded
public HTextFlowTarget getTextFlowTarget()
diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetReviewCommentsDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetReviewCommentsDAO.java
index 26dc9c2ad4..26a7f65bdd 100644
--- a/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetReviewCommentsDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowTargetReviewCommentsDAO.java
@@ -57,7 +57,7 @@ public TextFlowTargetReviewCommentsDAO(Session session)
public List getReviewComments(TransUnitId textFlowId, LocaleId localeId)
{
- Query query = getSession().createQuery("select c from HTextFlowTargetReviewComment c inner join c.commenter where c.textFlowTarget.textFlow.id = :textFlowId and c.textFlowTarget.locale.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");
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java
index 7783c4b314..ea67fe2f17 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java
@@ -65,9 +65,10 @@ public void setup()
@Test
public void testQuery()
{
- List reviewComments = reviewCommentsDAO.getReviewComments(new TransUnitId(1L), new LocaleId("as"));
+ List reviewComments = reviewCommentsDAO.getReviewComments(new TransUnitId(5L), LocaleId.EN_US);
- assertThat(reviewComments, Matchers.empty());
+ assertThat(reviewComments, Matchers.hasSize(1));
+ assertThat(reviewComments.get(0).getCommenter().getName(), Matchers.equalTo("Sample User"));
}
@Test
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"
/>
+
+
From 1a93c5a7873be09c8d1a8f4f6ded2f4cc7722e67 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Mon, 8 Jul 2013 14:07:55 +1000
Subject: [PATCH 062/184] minor ui change
---
.../org/zanata/webtrans/client/view/ReviewCommentView.ui.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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
index f4f7410e1b..29fb1c892b 100644
--- 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
@@ -31,7 +31,7 @@
}
-
+
From cf74cd1eec569e77164b0b398be02d4c4c93b34a Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Mon, 8 Jul 2013 14:31:29 +1000
Subject: [PATCH 063/184] rhbz978666 - remove unused methods
---
.../model/HTextFlowTargetReviewComment.java | 21 -------------------
...extFlowTargetReviewCommentsDAOJPATest.java | 2 --
2 files changed, 23 deletions(-)
diff --git a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
index 377ddd3dc4..3343829d3d 100644
--- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
+++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
@@ -118,25 +118,4 @@ public Integer getTargetVersion()
return targetVersion;
}
- // TODO pahuang we probably want to cache below two methods
- @Transient
- public ContentState getContentStateOfCommentedTarget()
- {
- if (textFlowTarget.getVersionNum().equals(targetVersion))
- {
- return textFlowTarget.getState();
- }
- return textFlowTarget.getHistory().get(targetVersion).getState();
- }
-
- @Transient
- public List getContentsOfCommentedTarget()
- {
- if (textFlowTarget.getVersionNum().equals(targetVersion))
- {
- return textFlowTarget.getContents();
- }
- return textFlowTarget.getHistory().get(targetVersion).getContents();
- }
-
}
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java
index ea67fe2f17..2771b62fd4 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowTargetReviewCommentsDAOJPATest.java
@@ -88,7 +88,6 @@ public void testTargetUserComment()
List result = reviewCommentsDAO.getReviewComments(new TransUnitId(target.getTextFlow().getId()), target.getLocaleId());
assertThat(result, Matchers.hasSize(1));
- assertThat(result.get(0).getContentsOfCommentedTarget(), Matchers.equalTo(target.getContents()));
assertThat(result.get(0).getCommenterName(), Matchers.equalTo(person.getName()));
assertThat(result.get(0).getCreationDate(), Matchers.lessThanOrEqualTo(new Date()));
}
@@ -113,7 +112,6 @@ public void testTargetUserCommentMadeOnPreviousTranslation()
List result = reviewCommentsDAO.getReviewComments(new TransUnitId(target.getTextFlow().getId()), target.getLocaleId());
- assertThat(result.get(0).getContentsOfCommentedTarget(), Matchers.equalTo(oldTranslation));
assertThat(result.get(0).getTargetVersion(), Matchers.equalTo(oldVersion));
}
}
From fa6a9e2fe66b7349f7128d4a59e830fcf5cafa3b Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Tue, 9 Jul 2013 09:27:39 +1000
Subject: [PATCH 064/184] rhbz978666 - remove natural id annotation
---
.../java/org/zanata/model/HTextFlowTargetReviewComment.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
index 3343829d3d..d7325a070d 100644
--- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
+++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
@@ -102,7 +102,6 @@ public String getComment()
}
@NotNull
- @NaturalId
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "target_id")
@IndexedEmbedded
@@ -112,7 +111,6 @@ public HTextFlowTarget getTextFlowTarget()
}
@NotNull
- @NaturalId
public Integer getTargetVersion()
{
return targetVersion;
From 3f56cb52d25c20d84bd8a71c309c44bcd9a39c5c Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Tue, 9 Jul 2013 14:44:16 +1000
Subject: [PATCH 065/184] rhbz978666 - use lombok for entity
---
.../model/HTextFlowTargetReviewComment.java | 50 +++++++------------
1 file changed, 19 insertions(+), 31 deletions(-)
diff --git a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
index d7325a070d..9f68b2ab68 100644
--- a/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
+++ b/zanata-model/src/main/java/org/zanata/model/HTextFlowTargetReviewComment.java
@@ -22,6 +22,8 @@
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;
@@ -41,6 +43,7 @@
import org.zanata.common.ContentState;
import lombok.AccessLevel;
+import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@@ -52,20 +55,34 @@
@Immutable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@BatchSize(size = 20)
-@Setter
@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;
- @Setter(AccessLevel.NONE)
private transient String commenterName;
public HTextFlowTargetReviewComment(HTextFlowTarget target, String comment, HPerson commenter)
@@ -77,13 +94,6 @@ public HTextFlowTargetReviewComment(HTextFlowTarget target, String comment, HPer
targetVersion = target.getVersionNum();
}
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "commenter_id", nullable = false)
- public HPerson getCommenter()
- {
- return commenter;
- }
-
@Transient
public String getCommenterName()
{
@@ -94,26 +104,4 @@ public String getCommenterName()
return commenterName;
}
- @NotNull
- @Type(type = "text")
- public String getComment()
- {
- return comment;
- }
-
- @NotNull
- @ManyToOne(fetch = FetchType.LAZY)
- @JoinColumn(name = "target_id")
- @IndexedEmbedded
- public HTextFlowTarget getTextFlowTarget()
- {
- return textFlowTarget;
- }
-
- @NotNull
- public Integer getTargetVersion()
- {
- return targetVersion;
- }
-
}
From 7a846b5693e0cbda70137a0e189c777196012f55 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Fri, 12 Jul 2013 12:31:17 +1000
Subject: [PATCH 066/184] list classes in persistence.xml in alphabetical order
---
.../WEB-INF/classes/META-INF/persistence.xml | 72 +++++++++----------
.../java/org/zanata/dao/TextFlowDAOTest.java | 10 ---
.../test/resources/META-INF/persistence.xml | 54 +++++++-------
.../test/resources/arquillian/persistence.xml | 44 ++++++------
4 files changed, 85 insertions(+), 95 deletions(-)
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 7d3239ae56..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,42 +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.HTextFlowTargetReviewComment
- 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.HTextFlowTargetReviewComment
+ 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.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.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 d05875fddf..61c6db512c 100755
--- a/zanata-war/src/test/resources/arquillian/persistence.xml
+++ b/zanata-war/src/test/resources/arquillian/persistence.xml
@@ -21,36 +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.HTextFlowTargetReviewComment
- 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
From 8436bd248150d83e2bd41df3d21a580b4f154918 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Fri, 12 Jul 2013 13:46:46 +1000
Subject: [PATCH 067/184] prevent server returning all states when none are
requested
---
.../java/org/zanata/search/FilterConstraints.java | 13 +------------
.../webtrans/client/service/NavigationService.java | 1 -
.../webtrans/shared/rpc/GetTransUnitList.java | 3 +--
3 files changed, 2 insertions(+), 15 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java b/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
index d5803bb1da..6b15dc1a0f 100644
--- a/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
+++ b/zanata-war/src/main/java/org/zanata/search/FilterConstraints.java
@@ -144,18 +144,7 @@ public Builder checkInTarget(boolean check)
public Builder includeStates(ContentStateGroup states)
{
- //FIXME this behaviour is too surprising.
- // It exists because the editor UI should show all states when either
- // all or none of the states are checked. This logic should just happen
- // in the editor backend *before* sending a request to the server.
- if (states.hasNoStates())
- {
- this.states.addAll();
- }
- else
- {
- this.states.fromStates(states);
- }
+ this.states.fromStates(states);
return this;
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/service/NavigationService.java b/zanata-war/src/main/java/org/zanata/webtrans/client/service/NavigationService.java
index 610b6b98e6..0a872a0128 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/service/NavigationService.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/service/NavigationService.java
@@ -55,7 +55,6 @@
import org.zanata.webtrans.client.resources.TableEditorMessages;
import org.zanata.webtrans.client.rpc.CachingDispatchAsync;
import org.zanata.webtrans.shared.auth.EditorClientId;
-import org.zanata.webtrans.shared.model.DocumentInfo;
import org.zanata.webtrans.shared.model.TransUnit;
import org.zanata.webtrans.shared.model.TransUnitId;
import org.zanata.webtrans.shared.rpc.GetTransUnitList;
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
index 9a906c8743..b992cc336d 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
@@ -144,8 +144,7 @@ public List getValidationIds()
public boolean isAcceptAllStatus()
{
- //all filter options are checked or unchecked
- return filterStates.hasNoStates() && !filterHasError || filterStates.hasAllStates() && filterHasError;
+ return filterStates.hasAllStates() && !filterHasError;
}
@Override
From 65824b2234bcffde82e7871bc0b5ef6bc3fb4943 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Fri, 12 Jul 2013 14:01:54 +1000
Subject: [PATCH 068/184] prevent TextFlowDAO returning all states when none
are requested
---
.../main/java/org/zanata/dao/TextFlowDAO.java | 14 ++++++++-----
.../java/org/zanata/dao/TextFlowDAOTest.java | 21 ++++++-------------
2 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
index e3f613cbbf..70b1308c12 100644
--- a/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/TextFlowDAO.java
@@ -160,19 +160,23 @@ public List getNavigationByDocumentId(Long documentId, HLocale hLocal
}
/**
- * This will build a SQL query condition in where clause.
- * If all status are equal (i.e. all true or all false), it's treated as accept all and it will return '1'.
+ * Build a SQL query condition that is true only for text flows with one of the given states.
*
- * @param includedStates
+ * @param includedStates states of targets that should return true
* @param hTextFlowTargetTableAlias alias being used for the target table in the current query
- * @return '1' if accept all status or a SQL condition clause with target content state conditions in parentheses '()' joined by 'or'
+ * @return a valid SQL query condition that is wrapped in parentheses if necessary
*/
protected static String buildContentStateCondition(ContentStateGroup includedStates, String hTextFlowTargetTableAlias)
{
- if (includedStates.hasAllStates() || includedStates.hasNoStates())
+ if (includedStates.hasAllStates())
{
return "1";
}
+ if (includedStates.hasNoStates())
+ {
+ return "0";
+ }
+
StringBuilder builder = new StringBuilder();
builder.append("(");
List conditions = Lists.newArrayList();
diff --git a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
index f9a5d27d2d..43d97cfa48 100644
--- a/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
+++ b/zanata-war/src/test/java/org/zanata/dao/TextFlowDAOTest.java
@@ -10,7 +10,6 @@
import org.dbunit.operation.DatabaseOperation;
import org.hamcrest.Matchers;
-import org.hibernate.Query;
import org.hibernate.Session;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -26,7 +25,7 @@
@Slf4j
public class TextFlowDAOTest extends ZanataDbunitJpaTest
{
-
+ private static final boolean PRINT_TEST_DATA = false;
private TextFlowDAO dao;
@Override
@@ -43,7 +42,10 @@ protected void prepareDBUnitOperations()
public void setup()
{
dao = new TextFlowDAO((Session) getEm().getDelegate());
-// printTestData();
+ if (PRINT_TEST_DATA)
+ {
+ printTestData();
+ }
}
private void printTestData()
@@ -179,13 +181,12 @@ public void canBuildAcceptAllQuery()
assertThat("Conditional that accepts all should be '1'", contentStateCondition, is("1"));
}
- // FIXME the 'none == all' logic should be limited to the editor
@Test
public void canBuildAcceptAllQueryWhenNoStatesSelected()
{
String contentStateCondition = TextFlowDAO.buildContentStateCondition(
ContentStateGroup.builder().removeAll().build(), "tft");
- assertThat("Conditional that accepts all should be '1'", contentStateCondition, is("1"));
+ assertThat("Conditional that accepts none should be '0'", contentStateCondition, is("0"));
}
@Test
@@ -285,14 +286,4 @@ public void testGetTextFlowByDocumentIdWithConstraint()
assertThat(result, Matchers.hasSize(1));
}
- // What is this testing? I can't tell if it is ensuring that no exception is thrown,
- // or if it is just half-written and useless.
- @Test
- public void queryTest1()
- {
- String queryString = "from HTextFlow tf left join tf.targets tft with (index(tft) = 3) " +
- "where (exists (from HTextFlowTarget where textFlow = tf and content0 like '%mssg%'))";
- Query query = getSession().createQuery(queryString);
- List result = query.list();
- }
}
From c910766ab3f6c79cdd48581001f135af4680ac1b Mon Sep 17 00:00:00 2001
From: David Mason
Date: Fri, 12 Jul 2013 14:55:13 +1000
Subject: [PATCH 069/184] move rule for requesting all states when none are
checked into context class
---
.../service/GetTransUnitActionContext.java | 29 ++++++++++++++++++-
.../webtrans/shared/rpc/GetTransUnitList.java | 23 ++-------------
.../shared/rpc/GetTransUnitsNavigation.java | 6 +---
3 files changed, 32 insertions(+), 26 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/service/GetTransUnitActionContext.java b/zanata-war/src/main/java/org/zanata/webtrans/client/service/GetTransUnitActionContext.java
index 322c2b5839..abf063d4f3 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/service/GetTransUnitActionContext.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/service/GetTransUnitActionContext.java
@@ -23,6 +23,7 @@
import java.util.List;
+import org.zanata.webtrans.shared.model.ContentStateGroup;
import org.zanata.webtrans.shared.model.DocumentInfo;
import org.zanata.webtrans.shared.model.TransUnitId;
import org.zanata.webtrans.shared.model.ValidationId;
@@ -292,7 +293,33 @@ public boolean acceptAll()
&& filterUntranslated == filterHasError
&& filterHasError == filterApproved
&& filterApproved == filterRejected;
-
+
return messageFilterAcceptAll && Strings.isNullOrEmpty(findMessage);
}
+
+ public ContentStateGroup getCurrentFilterStates()
+ {
+ return filterStatesFromCheckboxStates(getCheckboxStates());
+ }
+
+ private ContentStateGroup getCheckboxStates()
+ {
+ ContentStateGroup checkboxStates = ContentStateGroup.builder()
+ .includeNew(filterUntranslated)
+ .includeFuzzy(filterNeedReview)
+ .includeTranslated(filterTranslated)
+ .includeApproved(filterApproved)
+ .includeRejected(filterRejected)
+ .build();
+ return checkboxStates;
+ }
+
+ private static ContentStateGroup filterStatesFromCheckboxStates(ContentStateGroup filterStates)
+ {
+ if (filterStates.hasNoStates())
+ {
+ filterStates = ContentStateGroup.builder().addAll().build();
+ }
+ return filterStates;
+ }
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
index b992cc336d..35e77ba64c 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitList.java
@@ -33,32 +33,15 @@ private GetTransUnitList(GetTransUnitActionContext context)
offset = context.getOffset();
count = context.getCount();
phrase = context.getFindMessage();
- setIncludeStatesFrom(context);
- setIncludeAllStateIfNoneSelected();
+ setIncludeStates(context.getCurrentFilterStates());
filterHasError = context.isFilterHasError();
targetTransUnitId = context.getTargetTransUnitId();
validationIds = context.getValidationIds();
}
- private void setIncludeStatesFrom(GetTransUnitActionContext context)
+ private void setIncludeStates(ContentStateGroup contentStateGroup)
{
- // @formatter :off
- filterStates = ContentStateGroup.builder()
- .includeNew(context.isFilterUntranslated())
- .includeFuzzy(context.isFilterNeedReview())
- .includeTranslated(context.isFilterTranslated())
- .includeApproved(context.isFilterApproved())
- .includeRejected(context.isFilterRejected())
- .build();
- // @formatter :on
- }
-
- private void setIncludeAllStateIfNoneSelected()
- {
- if (filterStates.hasNoStates())
- {
- filterStates = ContentStateGroup.builder().addAll().build();
- }
+ filterStates = ContentStateGroup.builder().fromStates(contentStateGroup).build();
}
public static GetTransUnitList newAction(GetTransUnitActionContext context)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
index 1f8cb9a861..0e494d5efc 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitsNavigation.java
@@ -50,11 +50,7 @@ public GetTransUnitsNavigation(GetTransUnitActionContext context)
this(context.getDocument().getId().getId(),
context.getFindMessage(),
ContentStateGroup.builder()
- .includeNew(context.isFilterUntranslated())
- .includeFuzzy(context.isFilterNeedReview())
- .includeTranslated(context.isFilterTranslated())
- .includeApproved(context.isFilterApproved())
- .includeRejected(context.isFilterRejected())
+ .fromStates(context.getCurrentFilterStates())
.build());
}
From 85d0ee8c50bd9337964c6bcdf1872e62c3ef5ac9 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Fri, 12 Jul 2013 15:34:39 +1000
Subject: [PATCH 070/184] fix liquibase changelong for mysql
---
.../src/main/resources/db/changelogs/db.changelog-3.1.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 d00c9d9788..b12f7ced78 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
@@ -18,7 +18,7 @@
-
+
From daf834bbcc0198afe53497fcb0cf102534b01bc8 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Fri, 12 Jul 2013 15:36:16 +1000
Subject: [PATCH 071/184] Fix dateTime formatter util
---
zanata-war/src/main/java/org/zanata/util/DateUtil.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
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 055bbf641d..b13c8b4a06 100644
--- a/zanata-war/src/main/java/org/zanata/util/DateUtil.java
+++ b/zanata-war/src/main/java/org/zanata/util/DateUtil.java
@@ -5,6 +5,7 @@
import java.util.Date;
+import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
@@ -14,7 +15,6 @@
* @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";
@@ -30,7 +30,7 @@ public static String formatShortDate(Date date)
if(date != null)
{
DateTimeFormatter fmt = DateTimeFormat.forPattern(DATE_TIME_SHORT_PATTERN);
- return fmt.toString();
+ return fmt.print(new DateTime(date));
}
return null;
}
@@ -45,7 +45,7 @@ public static String formatTime(Date date)
if(date != null)
{
DateTimeFormatter fmt = DateTimeFormat.forPattern(TIME_SHORT_PATTERN);
- return fmt.toString();
+ return fmt.print(new DateTime(date));
}
return null;
}
From 189970abf372f47227c43e38466d7bd7da16dacf Mon Sep 17 00:00:00 2001
From: Damian Jansen
Date: Fri, 12 Jul 2013 16:06:11 +1000
Subject: [PATCH 072/184] Improve the RFC2822 files to be more descriptive and
clean
Split email addresses into valid and non-valid.
Use an enum for the address entries.
Improve docs.
---
.../main/java/org/zanata/util/RFC2822.java | 287 ------------------
.../rfc2822/InvalidEmailAddressRFC2822.java | 204 +++++++++++++
.../rfc2822/ValidEmailAddressRFC2822.java | 134 ++++++++
.../account/InvalidEmailAddressTest.java | 79 +++++
.../feature/account/RFC2822NegativeTest.java | 78 -----
.../feature/account/RFC2822PositiveTest.java | 56 ----
.../feature/account/RegisterDetailedTest.java | 4 +-
.../feature/account/RegisterTestSuite.java | 4 +-
.../account/ValidEmailAddressTest.java | 57 ++++
9 files changed, 478 insertions(+), 425 deletions(-)
delete mode 100644 functional-test/src/main/java/org/zanata/util/RFC2822.java
create mode 100644 functional-test/src/main/java/org/zanata/util/rfc2822/InvalidEmailAddressRFC2822.java
create mode 100644 functional-test/src/main/java/org/zanata/util/rfc2822/ValidEmailAddressRFC2822.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java
delete mode 100644 functional-test/src/test/java/org/zanata/feature/account/RFC2822NegativeTest.java
delete mode 100644 functional-test/src/test/java/org/zanata/feature/account/RFC2822PositiveTest.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/account/ValidEmailAddressTest.java
diff --git a/functional-test/src/main/java/org/zanata/util/RFC2822.java b/functional-test/src/main/java/org/zanata/util/RFC2822.java
deleted file mode 100644
index f30784ec5f..0000000000
--- a/functional-test/src/main/java/org/zanata/util/RFC2822.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * 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.util;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Damian Jansen djansen@redhat.com
- */
-public class RFC2822 {
-
- /*
- * Synopsis:
- * The functions of this class contain valid and invalid email addresses, as stipulated in the
- * RFC2822 Internet Message Format standard, or referred to standards.
- *
- * Definitions
- * localpart: the section of an address preceding the @ symbol
- * domain: the section of an address following the @ symbol
- * label: section of localpart or domain between the start, @ symbol, period or end (also referred to as "atom")
- * e.g. me, myself, example, com in me.myself@example.com
- * quote / quoting: a section of the localpart contained within quotation marks
- *
- * Untested:
- * RFC2822, section 3.4.1
- * The contents of a bracketed domain can have a \ precede a character to escape it,
- * and the following character must not be 10 (LF) or 13 (CR).
- * This allows spaces in the domain as long as they are escaped.
- *
- * RFC 2821, section 4.5.3.1
- * The maximum length of a "useful" email address is 255 characters.
- *
- * RFC 3696
- * The maximum allowable length of an email address is 320 characters.
- */
-
- /*
- * VALID EMAIL ADDRESSES
- */
- /*
- * RFC 2822, section 3.4.1
- * Email addresses consist of a local part, the "@" symbol, and the domain.
- */
- public static String BASIC_EMAIL = "email@example.com";
-
- /*
- * RFC 2822, sections 3.4.1 and 4.4
- * The local part can be unquoted, quoted in its entirety, or quoted on a per-label basis.
- * The quoted local part starts with a quotation mark, ends with a quotation mark.
- */
- // BUG982048
- public static String BASIC_QUOTED_EMAIL = "\"email\"@example.com";
-
- /*
- * RFC 2822, section 3.4.1
- * TEXT can contain alphabetic, numeric, and these symbols: !#$%'*+-/=?^_`{|}~
- */
- public static String SPECIAL_CHARACTERS_LOCALPART = "email.!#$%'*+-/=?^_`{|}~.dot@example.com";
-
- /*
- RFC 2822, section 4.4
- If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
- or quoted chunks separated by periods.
- */
- public static String ENCLOSED_QUOTED_LABEL = "dot.\"email\".dot@example.com";
- public static String LOCALPART_WITH_EMPTY_QUOTE = "dot.\"\".dot@example.com";
-
- /*
- * RFC 2822, section 3.4.1
- * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
- * This supersedes the previous rule, allowing spaces and quotation marks in the email address as long as they
- * are escaped.
- */
- public static String QUOTED_ESCAPED_SPECIAL_CHARACTERS = "email.\"(),:;<>\\@\\[\\]\\\\\"@example.com";
- public static String QUOTED_ESCAPED_QUOTES = "email.\"\\\"\"@example.com";
- public static String QUOTED_WITH_SPACE = "\"special\\ email\"@example.com";
-
- /*
- * RFC 2822, section 3.4.1
- * The domain can be bracketed or plain.
- */
- public static String BRACKETED_DOMAIN = "email@[example.com]";
- public static String BRACKETED_IPV4_DOMAIN = "email@[123.45.67.89]";
- public static String BRACKETED_IPV6_DOMAIN = "email@[IPv6:2001:2d12:c4fe:5afe::1]";
-
- /*
- * RFC 1035, section 2.3.4
- * A plain domain consists of labels separated with periods. No period can start or end a domain name.
- */
- public static String LOCALPART_MULTIPLE_LABELS = "another.email@example.com";
- public static String DOMAIN_MULTIPLE_LABELS = "email@another.example.com";
-
- /*
- * RFC 1035, section 2.3.4
- * The maximum length of a label is 63 characters.
- */
- public static String DOMAIN_LABEL_MAX_CHARACTERS =
- "email@B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8.com";
- public static String LOCALPART_LABEL_MAX_CHARACTERS =
- "B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8@example.com";
-
- /*
- * RFC 1035, section 2.3.4
- * A label may contain hyphens, but no two hyphens in a row.
- */
- public static String HYPHENATED_DOMAIN_LABEL = "email@another-example.com";
- public static String HYPHENATED_LOCALPART_LABEL = "my-email@example.com";
-
- /*
- * RFC 2821, section 4.5.3.1
- * The maximum length of the local part is 64 characters.
- */
- public static String LOCALPART_MAX_LENGTH =
- "B3NQyUsDdzODMoymfDdifn6Wztx2wrivm.80LEngHGl182frm6ifCPyv5SntbDg8@example.com";
-
-
- /*
- * INVALID EMAIL ADDRESSES
- */
-
- /*
- * RFC 2822, section 3.4.1
- * Email addresses consist of a local part, the "@" symbol, and the domain.
- */
- public static String PLAIN_ADDRESS = "plainaddress";
- public static String MISSING_AMPERSAT = "email.example.com";
- public static String MISSING_LOCALPART = "@example.com";
- public static String MISSING_DOMAIN = "email@";
- public static String MULTIPLE_APERSAT = "email@example@example.com";
-
- /*
- * RFC 2822, section 3.4.1
- * No periods can start or end the local part.
- * Two periods together is invalid.
- */
- public static String LEADING_DOT = ".email@example.com";
- public static String TRAILING_DOT = "email.@example.com";
- public static String MULTIPLE_DOTS = "email..email@example.com";
-
- /*
- * RFC 2822, section 2.2
- * All email addresses are in 7-bit US ASCII.
- */
- public static String NON_UNICODE_CHARACTERS = "あいうえお@example.com";
-
- /*
- * RFC 2822, section 3.4.1
- * Unquoted local parts can consist of TEXT
- * TEXT can contain:
- * alphabetic
- * numeric
- * and symbols !#$%'*+-/=?^_`{|}~
- */
- public static String INVALID_UNQUOTED_COMMA = "test,user@example.com";
- public static String INVALID_UNQUOTED_LEFT_PARENTHESES = "test(user@example.com";
- public static String INVALID_UNQUOTED_RIGHT_PARENTHESES = "test)user@example.com";
-
- /*
- * RFC 2822, section 3.4.1
- * The quoted local part starts with a quotation mark, ends with a quotation mark.
- */
- public static String INVALID_SINGLE_QUOTING = "test\"user@example.com";
-
- /*
- * RFC 2822, section 4.4
- * If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
- * or quoted chunks separated by periods
- */
- public static String INVALID_QUOTING_SEPARATION = "\"test\"user@example.com";
-
- /*
- * RFC 2822, section 3.4.1
- * The contents of a quoted local part can not contain characters:
- * 9 (TAB)
- * 10 (LF)
- * 13 (CR)
- * 32 (space)
- * 34 (")
- * 91-94 ([, \, ], ^)
- */
- public static String INVALID_QUOTED_COMMA = "\"test,user\"@example.com";
- public static String INVALID_QUOTED_BACKSLASH = "\"test\\user\"@example.com";
- public static String INVALID_QUOTED_LEFT_BRACKET = "\"test[user\"@example.com";
- public static String INVALID_QUOTED_RIGHT_BRACKET = "\"test]user\"@example.com";
- public static String INVALID_QUOTED_CARAT = "\"test^user\"@example.com";
- public static String INVALID_QUOTED_SPACE = "\"test user\"@example.com";
- public static String INVALID_QUOTED_QUOTE = "\"test\"user\"@example.com";
- // TODO: public static String Invalid_quoted_tab = "test.\"".concat("\t").concat("\".user@example.com");
-
- /*
- * RFC 2822, section 3.4.1
- * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
- */
- public static String INVALID_QUOTED_RETURN = "test.\"\\".concat("\r").concat("\".user@example.com");
- public static String INVALID_QUOTED_LINEFEED = "test.\"\\".concat("\n").concat("\".user@example.com");
-
- /*
- * RFC 1035, section 2.3.4
- * A plain domain consists of labels separated with periods. No period can start or end a domain name.
- * No two periods in succession can be in a domain name.
- */
- public static String TRAILING_DOMAIN_DOT = "email@example.com.";
- public static String LEADING_DOMAIN_DOT = "email@.example.com";
- public static String SUCCESSIVE_DOMAIN_DOTS = "email@example..com";
-
- /*
- * RFC 2822, section 3.4.1
- * Bracketed domains must:
- * start with [, end with ]
- * not contain characters 9 (TAB), 10 (LF), 13 (CR), 32 (space), 91-94 ([, \, ], ^)
- */
- public static String INCORRECTLY_BRACKETED_DOMAIN = "email@[example].com";
- public static String INVALID_DOMAIN_CHARACTER = "email@[ex^ample.com]";
- public static String INCORRECTLY_ESCAPED_DOMAIN = "email@[exa\\mple.com]";
-
- /*
- * RFC 1035, section 2.3.4
- * The maximum length of a label is 63 characters.
- */
- public static String DOMAIN_LABEL_LENGTH_EXCEEDED =
- "email@IJUr9P6Y7Fx7rFy4sziQDT0qvSC7XKK6jrD0CNC41jorAKgFYIXLTN5ITJLohy58.com";
-
- /*
- * RFC 1035, section 2.3.4
- * A label may contain hyphens, but no two hyphens in a row.
- * A label must not start nor end with a hyphen.
- */
- public static String LEADING_DASH_DOMAIN = "email@-example.com";
- public static String TRAILING_DASH_DOMAIN = "email@example-.com";
- public static String MULTIPLE_DASHES_DOMAIN = "email@exa--mple.com";
- public static String LEADING_DASH_BRACKETED_DOMAIN = "email@[-example.com]";
- public static String TRAILING_DASH_BRACKETED_DOMAIN = "email@[example.com-]";
- public static String MULTIPLE_DASHES_BRACKETED_DOMAIN = "email@[exa--mple.com]";
-
- /*
- * The contents of a bracketed domain can have a \ precede a character to escape it, and the following character
- * must not be 10 (LF) or 13 (CR).
- */
- public static String INVALID_BRACKETED_DOMAIN_RETURN = "test@[\\".concat("\r").concat("example.com]");
- public static String INVALID_BRACKETED_DOMAIN_LINEFEED = "test@[\\".concat("\n").concat("example.com]");
-
- /*
- * RFC 2821, section 4.5.3.1
- * The maximum length of the local part is 64 characters.
- */
- public static String LOCALPART_LENGTH_EXCEEDED =
- "emailuhpealgyxntsh5upl5gqn5a4ruqs7mw6wz21j6dn72amzwozqlyua4jx16rd@example.com";
-
- /*
- * RFC 3696, section 2
- * The top level domain must be all alphabetic.
- */
- public static String INVALID_ENCODED_HTML = "Joe Smith ";
- public static String INVALID_FOLLOWING_TEXT = "email@example.com (Joe Smith)";
- public static String INVALID_IP_FORMAT = "email@111.222.333.44444";
-
- /*
- * RFC 2821, section 4.5.3.1
- * The maximum length of a "useful" email address is 255 characters.
- */
- public static String MAX_EMAIL_LENGTH_EXCEEDED =
- "email@"+
- "Hk3yhCtbBRw3wCT76tL1ryAdfrIaaDszHqvZqnNrZPlNn3Wd7u."+
- "RfpxrueSghp9dkGTGwT9s0fyJL850Sned72RD3Mm5PpEh6QJwQ."+
- "3CeXyEHQEhXNOQdWhYVjGBLzlHz1sJfi4lfn7ighLXcxa5cMAK."+
- "jFXsG8BVsvkODKktTXJ70bQmDWtWQzuh3oz4twumVArDGEbzS1."+
- "slyaBcQqVgUdqXTBdbMY7YJxZwrzZQBBGjCl4e.com";
-}
\ No newline at end of file
diff --git a/functional-test/src/main/java/org/zanata/util/rfc2822/InvalidEmailAddressRFC2822.java b/functional-test/src/main/java/org/zanata/util/rfc2822/InvalidEmailAddressRFC2822.java
new file mode 100644
index 0000000000..ded69fe894
--- /dev/null
+++ b/functional-test/src/main/java/org/zanata/util/rfc2822/InvalidEmailAddressRFC2822.java
@@ -0,0 +1,204 @@
+/*
+ * 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.util.rfc2822;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ * @see RFC2822 Internet Message Format Standard
+ * Synopsis:
+ * The functions of this class contain invalid email addresses, as stipulated in the
+ * RFC2822 Internet Message Format standard, or referred to standards.
+ *
+ * Definitions
+ * localpart: the section of an address preceding the @ symbol
+ * domain: the section of an address following the @ symbol
+ * label: section of localpart or domain between the start, @ symbol, period or end (also referred to as "atom")
+ * e.g. me, myself, example, com in me.myself@example.com
+ * quote / quoting: a section of the localpart contained within quotation marks
+ *
+ * Untested:
+ *
+ * RFC 2821, section 4.5.3.1
+ * The maximum length of a "useful" email address is 255 characters.
+ *
+ * RFC 3696
+ * The maximum allowable length of an email address is 320 characters.
+ */
+public enum InvalidEmailAddressRFC2822 {
+
+ /**
+ * Email addresses consist of a local part, the "@" symbol, and the domain.
+ * @see "RFC 2822, section 3.4.1"
+ */
+ PLAIN_ADDRESS("plainaddress"),
+ MISSING_AMPERSAT("email.example.com"),
+ MISSING_LOCALPART("@example.com"),
+ MISSING_DOMAIN("email@"),
+ MULTIPLE_APERSAT("email@example@example.com"),
+
+ /**
+ * No periods can start or end the local part.
+ * Two periods together is invalid.
+ * @see "RFC 2822, section 3.4.1"
+ */
+ LEADING_DOT(".email@example.com"),
+ TRAILING_DOT("email.@example.com"),
+ MULTIPLE_DOTS("email..email@example.com"),
+
+ /**
+ * All email addresses are in 7-bit US ASCII.
+ * @see "RFC 2822, section 2.2"
+ */
+ NON_UNICODE_CHARACTERS("あいうえお@example.com"),
+
+ /**
+ * Unquoted local parts can consist of TEXT
+ * TEXT can contain:
+ * alphabetic
+ * numeric
+ * and symbols !#$%'*+-/=?^_`{|}~
+ * @see "RFC 2822, section 3.4.1"
+ */
+ INVALID_UNQUOTED_COMMA("test,user@example.com"),
+ INVALID_UNQUOTED_LEFT_PARENTHESES("test(user@example.com"),
+ INVALID_UNQUOTED_RIGHT_PARENTHESES("test)user@example.com"),
+
+ /**
+ * The quoted local part starts with a quotation mark, ends with a quotation mark.
+ * @see "RFC 2822, section 3.4.1"
+ */
+ INVALID_SINGLE_QUOTING("test\"user@example.com"),
+
+ /**
+ * If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
+ * or quoted chunks separated by periods
+ * @see "RFC 2822, section 4.4"
+ */
+ INVALID_QUOTING_SEPARATION("\"test\"user@example.com"),
+
+ /**
+ * The contents of a quoted local part can not contain characters:
+ * 9 (TAB)
+ * 10 (LF)
+ * 13 (CR)
+ * 32 (space)
+ * 34 (")
+ * 91-94 ([, \, ], ^)
+ * @see "RFC 2822, section 3.4.1"
+ */
+ INVALID_QUOTED_COMMA("\"test,user\"@example.com"),
+ INVALID_QUOTED_BACKSLASH("\"test\\user\"@example.com"),
+ INVALID_QUOTED_LEFT_BRACKET("\"test[user\"@example.com"),
+ INVALID_QUOTED_RIGHT_BRACKET("\"test]user\"@example.com"),
+ INVALID_QUOTED_CARAT("\"test^user\"@example.com"),
+ INVALID_QUOTED_SPACE("\"test user\"@example.com"),
+ INVALID_QUOTED_QUOTE("\"test\"user\"@example.com"),
+ INVALID_QUOTED_TAB("test.\"".concat("\t").concat("\".user@example.com")),
+
+ /**
+ * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
+ * @see "RFC 2822, section 3.4.1"
+ */
+ INVALID_QUOTED_RETURN("test.\"\\".concat("\r").concat("\".user@example.com")),
+ INVALID_QUOTED_LINEFEED("test.\"\\".concat("\n").concat("\".user@example.com")),
+
+ /**
+ * A plain domain consists of labels separated with periods. No period can start or end a domain name.
+ * No two periods in succession can be in a domain name.
+ * @see "RFC 1035, section 2.3.4"
+ */
+ TRAILING_DOMAIN_DOT("email@example.com."),
+ LEADING_DOMAIN_DOT("email@.example.com"),
+ SUCCESSIVE_DOMAIN_DOTS("email@example..com"),
+
+ /**
+ * Bracketed domains must:
+ * start with [, end with ]
+ * not contain characters 9 (TAB), 10 (LF), 13 (CR), 32 (space), 91-94 ([, \, ], ^)
+ * @see "RFC 2822, section 3.4.1"
+ */
+ INCORRECTLY_BRACKETED_DOMAIN("email@[example].com"),
+ INVALID_DOMAIN_CHARACTER("email@[ex^ample.com]"),
+ INCORRECTLY_ESCAPED_DOMAIN("email@[exa\\mple.com]"),
+
+ /**
+ * The maximum length of a label is 63 characters.
+ * @see "RFC 1035, section 2.3.4"
+ */
+ DOMAIN_LABEL_LENGTH_EXCEEDED("email@IJUr9P6Y7Fx7rFy4sziQDT0qvSC7XKK6jrD0CNC41jorAKgFYIXLTN5ITJLohy58.com"),
+
+ /**
+ * A label may contain hyphens, but no two hyphens in a row.
+ * A label must not start nor end with a hyphen.
+ * @see "RFC 1035, section 2.3.4"
+ */
+ LEADING_DASH_DOMAIN("email@-example.com"),
+ TRAILING_DASH_DOMAIN("email@example-.com"),
+ MULTIPLE_DASHES_DOMAIN("email@exa--mple.com"),
+ LEADING_DASH_BRACKETED_DOMAIN("email@[-example.com]"),
+ TRAILING_DASH_BRACKETED_DOMAIN("email@[example.com-]"),
+ MULTIPLE_DASHES_BRACKETED_DOMAIN("email@[exa--mple.com]"),
+
+ /**
+ * The contents of a bracketed domain can have a \ precede a character to escape it, and the following character
+ * must not be 10 (LF) or 13 (CR).
+ * @see "RFC2822, section 3.4.1"
+ */
+ INVALID_BRACKETED_DOMAIN_RETURN("test@[\\".concat("\r").concat("example.com]")),
+ INVALID_BRACKETED_DOMAIN_LINEFEED("test@[\\".concat("\n").concat("example.com]")),
+
+ /**
+ * The maximum length of the local part is 64 characters.
+ * @see "RFC 2821, section 4.5.3.1"
+ */
+ LOCALPART_LENGTH_EXCEEDED("emailuhpealgyxntsh5upl5gqn5a4ruqs7mw6wz21j6dn72amzwozqlyua4jx16rd@example.com"),
+
+ /**
+ * The top level domain must be all alphabetic.
+ * @see "RFC 3696, section 2"
+ */
+ INVALID_ENCODED_HTML("Joe Smith "),
+ INVALID_FOLLOWING_TEXT("email@example.com (Joe Smith)"),
+ INVALID_IP_FORMAT("email@111.222.333.44444"),
+
+ /**
+ * The maximum length of a "useful" email address is 255 characters.
+ * @see "RFC 2821, section 4.5.3.1"
+ */
+ MAX_EMAIL_LENGTH_EXCEEDED("email@"+
+ "Hk3yhCtbBRw3wCT76tL1ryAdfrIaaDszHqvZqnNrZPlNn3Wd7u."+
+ "RfpxrueSghp9dkGTGwT9s0fyJL850Sned72RD3Mm5PpEh6QJwQ."+
+ "3CeXyEHQEhXNOQdWhYVjGBLzlHz1sJfi4lfn7ighLXcxa5cMAK."+
+ "jFXsG8BVsvkODKktTXJ70bQmDWtWQzuh3oz4twumVArDGEbzS1."+
+ "slyaBcQqVgUdqXTBdbMY7YJxZwrzZQBBGjCl4e.com");
+
+ private final String address;
+
+ private InvalidEmailAddressRFC2822(String address)
+ {
+ this.address = address;
+ }
+
+ public String toString()
+ {
+ return address;
+ }
+}
\ No newline at end of file
diff --git a/functional-test/src/main/java/org/zanata/util/rfc2822/ValidEmailAddressRFC2822.java b/functional-test/src/main/java/org/zanata/util/rfc2822/ValidEmailAddressRFC2822.java
new file mode 100644
index 0000000000..e153c9049c
--- /dev/null
+++ b/functional-test/src/main/java/org/zanata/util/rfc2822/ValidEmailAddressRFC2822.java
@@ -0,0 +1,134 @@
+/*
+ * 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.util.rfc2822;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ * @see RFC2822 Internet Message Format Standard
+ * Synopsis:
+ * The functions of this class contain valid email addresses, as stipulated in the
+ * RFC2822 Internet Message Format standard, or referred to standards.
+ *
+ * Definitions
+ * localpart: the section of an address preceding the @ symbol
+ * domain: the section of an address following the @ symbol
+ * label: section of localpart or domain between the start, @ symbol, period or end (also referred to as "atom")
+ * e.g. me, myself, example, com in me.myself@example.com
+ * quote / quoting: a section of the localpart contained within quotation marks
+ *
+ * Untested:
+ * RFC2822, section 3.4.1
+ * The contents of a bracketed domain can have a \ precede a character to escape it,
+ * and the following character must not be 10 (LF) or 13 (CR).
+ * This allows spaces in the domain as long as they are escaped.
+ *
+ * RFC 2821, section 4.5.3.1
+ * The maximum length of a "useful" email address is 255 characters.
+ *
+ * RFC 3696
+ * The maximum allowable length of an email address is 320 characters.
+ */
+public enum ValidEmailAddressRFC2822 {
+
+ /**
+ * Email addresses consist of a local part, the "@" symbol, and the domain.
+ * @see "RFC 2822, section 3.4.1"
+ */
+ BASIC_EMAIL("email@example.com"),
+
+ /**
+ * The local part can be unquoted, quoted in its entirety, or quoted on a per-label basis.
+ * The quoted local part starts with a quotation mark, ends with a quotation mark.
+ * @see "RFC 2822, sections 3.4.1 and 4.4"
+ */
+ BASIC_QUOTED_EMAIL("\"email\"@example.com"),
+
+ /**
+ * TEXT can contain alphabetic, numeric, and these symbols: !#$%'*+-/=?^_`{|}~
+ * @see "RFC 2822, section 3.4.1"
+ */
+ SPECIAL_CHARACTERS_LOCALPART("email.!#$%'*+-/=?^_`{|}~.dot@example.com"),
+
+ /**
+ * If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
+ * or quoted chunks separated by periods.
+ * @see "RFC 2822, section 4.4"
+ */
+ ENCLOSED_QUOTED_LABEL("dot.\"email\".dot@example.com"),
+ LOCALPART_WITH_EMPTY_QUOTE("dot.\"\".dot@example.com"),
+
+ /**
+ * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
+ * This supersedes the previous rule, allowing spaces and quotation marks in the email address as long as they
+ * are escaped.
+ * @see "RFC 2822, section 3.4.1"
+ */
+ QUOTED_ESCAPED_SPECIAL_CHARACTERS("email.\"(),:;<>\\@\\[\\]\\\\\"@example.com"),
+ QUOTED_ESCAPED_QUOTES("email.\"\\\"\"@example.com"),
+ QUOTED_WITH_SPACE("\"special\\ email\"@example.com"),
+
+ /**
+ * The domain can be bracketed or plain.
+ * @see "RFC 2822, section 3.4.1"
+ */
+ BRACKETED_DOMAIN("email@[example.com]"),
+ BRACKETED_IPV4_DOMAIN("email@[123.45.67.89]"),
+ BRACKETED_IPV6_DOMAIN("email@[IPv6:2001:2d12:c4fe:5afe::1]"),
+
+ /**
+ * A plain domain consists of labels separated with periods. No period can start or end a domain name.
+ * @see "RFC 1035, section 2.3.4"
+ */
+ LOCALPART_MULTIPLE_LABELS("another.email@example.com"),
+ DOMAIN_MULTIPLE_LABELS("email@another.example.com"),
+
+ /**
+ * The maximum length of a label is 63 characters.
+ * @see "RFC 1035, section 2.3.4"
+ */
+ DOMAIN_LABEL_MAX_CHARACTERS("email@B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8.com"),
+ LOCALPART_LABEL_MAX_CHARACTERS("B3NQyUsDdzODMoymfDdifn6Wztx2wrivm80LEngHGl182frm6ifCPyv5SntbDg8@example.com"),
+
+ /**
+ * A label may contain hyphens, but no two hyphens in a row.
+ * @see "RFC 1035, section 2.3.4"
+ */
+ HYPHENATED_DOMAIN_LABEL("email@another-example.com"),
+ HYPHENATED_LOCALPART_LABEL("my-email@example.com"),
+
+ /**
+ * The maximum length of the local part is 64 characters.
+ * @see "RFC 2821, section 4.5.3.1"
+ */
+ LOCALPART_MAX_LENGTH("B3NQyUsDdzODMoymfDdifn6Wztx2wrivm.80LEngHGl182frm6ifCPyv5SntbDg8@example.com");
+
+ private final String address;
+
+ private ValidEmailAddressRFC2822(String address)
+ {
+ this.address = address;
+ }
+
+ public String toString()
+ {
+ return address;
+ }
+}
\ No newline at end of file
diff --git a/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java b/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java
new file mode 100644
index 0000000000..d307916cee
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java
@@ -0,0 +1,79 @@
+package org.zanata.feature.account;
+
+import org.hamcrest.Matchers;
+import org.junit.ClassRule;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.zanata.page.account.RegisterPage;
+import org.zanata.util.ResetDatabaseRule;
+import org.zanata.util.rfc2822.InvalidEmailAddressRFC2822;
+import org.zanata.workflow.BasicWorkFlow;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.zanata.util.rfc2822.InvalidEmailAddressRFC2822.*;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Theories.class)
+public class InvalidEmailAddressTest {
+ @ClassRule
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
+
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_PLAIN_ADDRESS = PLAIN_ADDRESS;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_MISSING_AMPERSAT = MISSING_AMPERSAT;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_MISSING_LOCALPART = MISSING_LOCALPART;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_MISSING_DOMAIN = MISSING_DOMAIN;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_MULTIPLE_APERSAT = MULTIPLE_APERSAT;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_LEADING_DOT = LEADING_DOT;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_TRAILING_DOT = TRAILING_DOT;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_MULTIPLE_DOTS = MULTIPLE_DOTS;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_UNQUOTED_COMMA = INVALID_UNQUOTED_COMMA;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_UNQUOTED_LEFT_PARENTHESES = INVALID_UNQUOTED_LEFT_PARENTHESES;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_UNQUOTED_RIGHT_PARENTHESES = INVALID_UNQUOTED_RIGHT_PARENTHESES;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_SINGLE_QUOTING = INVALID_SINGLE_QUOTING;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTING_SEPARATION = INVALID_QUOTING_SEPARATION;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTED_COMMA = INVALID_QUOTED_COMMA;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTED_BACKSLASH = INVALID_QUOTED_BACKSLASH;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTED_LEFT_BRACKET = INVALID_QUOTED_LEFT_BRACKET;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTED_RIGHT_BRACKET = INVALID_QUOTED_RIGHT_BRACKET;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTED_CARAT = INVALID_QUOTED_CARAT;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTED_SPACE = INVALID_QUOTED_SPACE;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTED_QUOTE = INVALID_QUOTED_QUOTE;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTED_RETURN = INVALID_QUOTED_RETURN;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_QUOTED_LINEFEED = INVALID_QUOTED_LINEFEED;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_TRAILING_DOMAIN_DOT = TRAILING_DOMAIN_DOT;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_LEADING_DOMAIN_DOT = LEADING_DOMAIN_DOT;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_SUCCESSIVE_DOMAIN_DOTS = SUCCESSIVE_DOMAIN_DOTS;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INCORRECTLY_BRACKETED_DOMAIN = INCORRECTLY_BRACKETED_DOMAIN;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_DOMAIN_CHARACTER = INVALID_DOMAIN_CHARACTER;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INCORRECTLY_ESCAPED_DOMAIN = INCORRECTLY_ESCAPED_DOMAIN;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_DOMAIN_LABEL_LENGTH_EXCEEDED = DOMAIN_LABEL_LENGTH_EXCEEDED;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_LEADING_DASH_BRACKETED_DOMAIN = LEADING_DASH_BRACKETED_DOMAIN;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_TRAILING_DASH_BRACKETED_DOMAIN = TRAILING_DASH_BRACKETED_DOMAIN;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_MULTIPLE_DASHES_BRACKETED_DOMAIN = MULTIPLE_DASHES_BRACKETED_DOMAIN;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_BRACKETED_DOMAIN_RETURN = INVALID_BRACKETED_DOMAIN_RETURN;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_BRACKETED_DOMAIN_LINEFEED = INVALID_BRACKETED_DOMAIN_LINEFEED;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_LOCALPART_LENGTH_EXCEEDED = LOCALPART_LENGTH_EXCEEDED;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_ENCODED_HTML = INVALID_ENCODED_HTML;
+ @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_FOLLOWING_TEXT = INVALID_FOLLOWING_TEXT;
+
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_IP_FORMAT = EmailAddressRFC2822.INVALID_IP_FORMAT;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_MAX_EMAIL_LENGTH_EXCEEDED = EmailAddressRFC2822.MAX_EMAIL_LENGTH_EXCEEDED;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_NON_UNICODE_CHARACTERS = EmailAddressRFC2822.NON_UNICODE_CHARACTERS;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_LEADING_DASH_DOMAIN = EmailAddressRFC2822.LEADING_DASH_DOMAIN;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_TRAILING_DASH_DOMAIN = EmailAddressRFC2822.TRAILING_DASH_DOMAIN;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_MULTIPLE_DASHES_DOMAIN = EmailAddressRFC2822.MULTIPLE_DASHES_DOMAIN;
+
+ @Theory
+ public void invalidEmailRejection(InvalidEmailAddressRFC2822 emailAddress)
+ {
+ String errorMsg = "not a well-formed email address";
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration();
+ registerPage = registerPage.enterEmail(emailAddress.toString()).clickTerms();
+ assertThat("Email validation errors are not shown", registerPage.waitForErrors(), Matchers.hasItem(errorMsg));
+ }
+
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RFC2822NegativeTest.java b/functional-test/src/test/java/org/zanata/feature/account/RFC2822NegativeTest.java
deleted file mode 100644
index ea434e633d..0000000000
--- a/functional-test/src/test/java/org/zanata/feature/account/RFC2822NegativeTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.zanata.feature.account;
-
-import org.hamcrest.Matchers;
-import org.junit.ClassRule;
-import org.junit.experimental.theories.DataPoint;
-import org.junit.experimental.theories.Theories;
-import org.junit.experimental.theories.Theory;
-import org.junit.runner.RunWith;
-import org.zanata.page.account.RegisterPage;
-import org.zanata.util.RFC2822;
-import org.zanata.util.ResetDatabaseRule;
-import org.zanata.workflow.BasicWorkFlow;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-
-/**
- * @author Damian Jansen djansen@redhat.com
- */
-@RunWith(Theories.class)
-public class RFC2822NegativeTest {
- @DataPoint public static String PLAIN_ADDRESS = RFC2822.PLAIN_ADDRESS;
- @DataPoint public static String MISSING_AMPERSAT = RFC2822.MISSING_AMPERSAT;
- @DataPoint public static String MISSING_LOCALPART = RFC2822.MISSING_LOCALPART;
- @DataPoint public static String MISSING_DOMAIN = RFC2822.MISSING_DOMAIN;
- @DataPoint public static String MULTIPLE_APERSAT = RFC2822.MULTIPLE_APERSAT;
- @DataPoint public static String LEADING_DOT = RFC2822.LEADING_DOT;
- @DataPoint public static String TRAILING_DOT = RFC2822.TRAILING_DOT;
- @DataPoint public static String MULTIPLE_DOTS = RFC2822.MULTIPLE_DOTS;
- @DataPoint public static String INVALID_UNQUOTED_COMMA = RFC2822.INVALID_UNQUOTED_COMMA;
- @DataPoint public static String INVALID_UNQUOTED_LEFT_PARENTHESES = RFC2822.INVALID_UNQUOTED_LEFT_PARENTHESES;
- @DataPoint public static String INVALID_UNQUOTED_RIGHT_PARENTHESES = RFC2822.INVALID_UNQUOTED_RIGHT_PARENTHESES;
- @DataPoint public static String INVALID_SINGLE_QUOTING = RFC2822.INVALID_SINGLE_QUOTING;
- @DataPoint public static String INVALID_QUOTING_SEPARATION = RFC2822.INVALID_QUOTING_SEPARATION;
- @DataPoint public static String INVALID_QUOTED_COMMA = RFC2822.INVALID_QUOTED_COMMA;
- @DataPoint public static String INVALID_QUOTED_BACKSLASH = RFC2822.INVALID_QUOTED_BACKSLASH;
- @DataPoint public static String INVALID_QUOTED_LEFT_BRACKET = RFC2822.INVALID_QUOTED_LEFT_BRACKET;
- @DataPoint public static String INVALID_QUOTED_RIGHT_BRACKET = RFC2822.INVALID_QUOTED_RIGHT_BRACKET;
- @DataPoint public static String INVALID_QUOTED_CARAT = RFC2822.INVALID_QUOTED_CARAT;
- @DataPoint public static String INVALID_QUOTED_SPACE = RFC2822.INVALID_QUOTED_SPACE;
- @DataPoint public static String INVALID_QUOTED_QUOTE = RFC2822.INVALID_QUOTED_QUOTE;
- @DataPoint public static String INVALID_QUOTED_RETURN = RFC2822.INVALID_QUOTED_RETURN;
- @DataPoint public static String INVALID_QUOTED_LINEFEED = RFC2822.INVALID_QUOTED_LINEFEED;
- @DataPoint public static String TRAILING_DOMAIN_DOT = RFC2822.TRAILING_DOMAIN_DOT;
- @DataPoint public static String LEADING_DOMAIN_DOT = RFC2822.LEADING_DOMAIN_DOT;
- @DataPoint public static String SUCCESSIVE_DOMAIN_DOTS = RFC2822.SUCCESSIVE_DOMAIN_DOTS;
- @DataPoint public static String INCORRECTLY_BRACKETED_DOMAIN = RFC2822.INCORRECTLY_BRACKETED_DOMAIN;
- @DataPoint public static String INVALID_DOMAIN_CHARACTER = RFC2822.INVALID_DOMAIN_CHARACTER;
- @DataPoint public static String INCORRECTLY_ESCAPED_DOMAIN = RFC2822.INCORRECTLY_ESCAPED_DOMAIN;
- @DataPoint public static String DOMAIN_LABEL_LENGTH_EXCEEDED = RFC2822.DOMAIN_LABEL_LENGTH_EXCEEDED;
- @DataPoint public static String LEADING_DASH_BRACKETED_DOMAIN = RFC2822.LEADING_DASH_BRACKETED_DOMAIN;
- @DataPoint public static String TRAILING_DASH_BRACKETED_DOMAIN = RFC2822.TRAILING_DASH_BRACKETED_DOMAIN;
- @DataPoint public static String MULTIPLE_DASHES_BRACKETED_DOMAIN = RFC2822.MULTIPLE_DASHES_BRACKETED_DOMAIN;
- @DataPoint public static String INVALID_BRACKETED_DOMAIN_RETURN = RFC2822.INVALID_BRACKETED_DOMAIN_RETURN;
- @DataPoint public static String INVALID_BRACKETED_DOMAIN_LINEFEED = RFC2822.INVALID_BRACKETED_DOMAIN_LINEFEED;
- @DataPoint public static String LOCALPART_LENGTH_EXCEEDED = RFC2822.LOCALPART_LENGTH_EXCEEDED;
- @DataPoint public static String INVALID_ENCODED_HTML = RFC2822.INVALID_ENCODED_HTML;
- @DataPoint public static String INVALID_FOLLOWING_TEXT = RFC2822.INVALID_FOLLOWING_TEXT;
-
- // BUG982048 @DataPoint public static String INVALID_IP_FORMAT = RFC2822.INVALID_IP_FORMAT;
- // BUG982048 @DataPoint public static String MAX_EMAIL_LENGTH_EXCEEDED = RFC2822.MAX_EMAIL_LENGTH_EXCEEDED;
- // BUG982048 @DataPoint public static String NON_UNICODE_CHARACTERS = RFC2822.NON_UNICODE_CHARACTERS;
- // BUG982048 @DataPoint public static String LEADING_DASH_DOMAIN = RFC2822.LEADING_DASH_DOMAIN;
- // BUG982048 @DataPoint public static String TRAILING_DASH_DOMAIN = RFC2822.TRAILING_DASH_DOMAIN;
- // BUG982048 @DataPoint public static String MULTIPLE_DASHES_DOMAIN = RFC2822.MULTIPLE_DASHES_DOMAIN;
-
- @ClassRule
- public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
-
- @Theory
- public void invalidEmailRejection(String emailAddress)
- {
- String errorMsg = "not a well-formed email address";
- RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration();
- registerPage = registerPage.enterEmail(emailAddress).clickTerms();
- assertThat("Email validation errors are not shown", registerPage.waitForErrors(), Matchers.hasItem(errorMsg));
- }
-
-}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RFC2822PositiveTest.java b/functional-test/src/test/java/org/zanata/feature/account/RFC2822PositiveTest.java
deleted file mode 100644
index c9a1932986..0000000000
--- a/functional-test/src/test/java/org/zanata/feature/account/RFC2822PositiveTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.zanata.feature.account;
-
-import org.hamcrest.Matchers;
-import org.junit.ClassRule;
-import org.junit.experimental.theories.DataPoint;
-import org.junit.experimental.theories.Theories;
-import org.junit.experimental.theories.Theory;
-import org.junit.runner.RunWith;
-import org.zanata.page.account.RegisterPage;
-import org.zanata.util.RFC2822;
-import org.zanata.util.ResetDatabaseRule;
-import org.zanata.workflow.BasicWorkFlow;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-
-/**
- * @author Damian Jansen djansen@redhat.com
- */
-@RunWith(Theories.class)
-public class RFC2822PositiveTest {
-
- @DataPoint public static String BASIC_EMAIL = RFC2822.BASIC_EMAIL;
- @DataPoint public static String SPECIAL_LOCALPART_CHARACTERS = RFC2822.SPECIAL_CHARACTERS_LOCALPART;
- @DataPoint public static String LOCALPART_MULTIPLE_LABELS = RFC2822.LOCALPART_MULTIPLE_LABELS;
- @DataPoint public static String DOMAIN_MULTIPLE_LABELS = RFC2822.DOMAIN_MULTIPLE_LABELS;
- @DataPoint public static String DOMAIN_LABEL_MAX_CHARACTERS = RFC2822.DOMAIN_LABEL_MAX_CHARACTERS;
- @DataPoint public static String LOCALPART_LABEL_MAX_CHARACTERS = RFC2822.LOCALPART_LABEL_MAX_CHARACTERS;
- @DataPoint public static String HYPHENATED_DOMAIN_LABEL = RFC2822.HYPHENATED_DOMAIN_LABEL;
- @DataPoint public static String HYPHENATED_LOCALPART_LABEL = RFC2822.HYPHENATED_LOCALPART_LABEL;
- @DataPoint public static String LOCALPART_MAX_LENGTH = RFC2822.LOCALPART_MAX_LENGTH;
-
- // BUG982048 @DataPoint public static String BASIC_QUOTED_EMAIL = RFC2822.BASIC_QUOTED_EMAIL;
- // BUG982048 @DataPoint public static String ENCLOSED_QUOTED_LABEL = RFC2822.ENCLOSED_QUOTED_LABEL;
- // BUG982048 @DataPoint public static String LOCALPART_EMPTY_QUOTE = RFC2822.LOCALPART_WITH_EMPTY_QUOTE;
- // BUG982048 @DataPoint public static String QUOTED_ESCAPED_SPECIAL_CHARACTERS = RFC2822.QUOTED_ESCAPED_SPECIAL_CHARACTERS;
- // BUG982048 @DataPoint public static String QUOTED_ESCAPED_QUOTES = RFC2822.QUOTED_ESCAPED_QUOTES;
- // BUG982048 @DataPoint public static String QUOTED_WITH_SPACE = RFC2822.QUOTED_WITH_SPACE;
- // BUG982048 @DataPoint public static String BRACKETED_DOMAIN = RFC2822.BRACKETED_DOMAIN;
- // BUG982048 @DataPoint public static String BRACKETED_IPV4_DOMAIN = RFC2822.BRACKETED_IPV4_DOMAIN;
- // BUG982048 @DataPoint public static String BRACKETED_IPV6_DOMAIN = RFC2822.BRACKETED_IPV6_DOMAIN;
-
- @ClassRule
- public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
-
- @Theory
- public void validEmailAcceptance(String emailAddress)
- {
- String errorMsg = "not a well-formed email address";
- RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration();
- registerPage = registerPage.enterEmail(emailAddress).clickTerms();
- assertThat("Email validation errors are not shown", registerPage.getErrors(),
- Matchers.not(Matchers.hasItem(errorMsg)));
-
- }
-
-}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
index 4c90419e65..2a4b3f0aef 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
@@ -28,7 +28,7 @@
import org.junit.Test;
import org.zanata.page.HomePage;
import org.zanata.page.account.RegisterPage;
-import org.zanata.util.RFC2822;
+import org.zanata.util.rfc2822.InvalidEmailAddressRFC2822;
import org.zanata.util.ResetDatabaseRule;
import org.zanata.workflow.BasicWorkFlow;
@@ -109,7 +109,7 @@ public void usernamePreExisting()
public void emailValidation()
{
String errorMsg = "not a well-formed email address";
- fields.put("email", RFC2822.PLAIN_ADDRESS);
+ fields.put("email", InvalidEmailAddressRFC2822.PLAIN_ADDRESS.toString());
fields.put("username", "emailvalidation");
RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields);
assertThat("Email validation errors are shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java b/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java
index 5e1f36d8be..8201fa4cd6 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java
@@ -32,8 +32,8 @@
@Suite.SuiteClasses({
RegisterDetailedTest.class,
UsernameValidationTest.class,
- RFC2822PositiveTest.class,
- RFC2822NegativeTest.class
+ ValidEmailAddressTest.class,
+ InvalidEmailAddressTest.class
})
public class RegisterTestSuite
{
diff --git a/functional-test/src/test/java/org/zanata/feature/account/ValidEmailAddressTest.java b/functional-test/src/test/java/org/zanata/feature/account/ValidEmailAddressTest.java
new file mode 100644
index 0000000000..17f8a170d3
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/account/ValidEmailAddressTest.java
@@ -0,0 +1,57 @@
+package org.zanata.feature.account;
+
+import org.hamcrest.Matchers;
+import org.junit.ClassRule;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.zanata.page.account.RegisterPage;
+import org.zanata.util.ResetDatabaseRule;
+import org.zanata.util.rfc2822.ValidEmailAddressRFC2822;
+import org.zanata.workflow.BasicWorkFlow;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.zanata.util.rfc2822.ValidEmailAddressRFC2822.*;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Theories.class)
+public class ValidEmailAddressTest {
+
+ @ClassRule
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
+
+ @DataPoint public static ValidEmailAddressRFC2822 TEST_BASIC_EMAIL = BASIC_EMAIL;
+ @DataPoint public static ValidEmailAddressRFC2822 TEST_SPECIAL_LOCALPART_CHARACTERS = SPECIAL_CHARACTERS_LOCALPART;
+ @DataPoint public static ValidEmailAddressRFC2822 TEST_LOCALPART_MULTIPLE_LABELS = LOCALPART_MULTIPLE_LABELS;
+ @DataPoint public static ValidEmailAddressRFC2822 TEST_DOMAIN_MULTIPLE_LABELS = DOMAIN_MULTIPLE_LABELS;
+ @DataPoint public static ValidEmailAddressRFC2822 TEST_DOMAIN_LABEL_MAX_CHARACTERS = DOMAIN_LABEL_MAX_CHARACTERS;
+ @DataPoint public static ValidEmailAddressRFC2822 TEST_LOCALPART_LABEL_MAX_CHARACTERS = LOCALPART_LABEL_MAX_CHARACTERS;
+ @DataPoint public static ValidEmailAddressRFC2822 TEST_HYPHENATED_DOMAIN_LABEL = HYPHENATED_DOMAIN_LABEL;
+ @DataPoint public static ValidEmailAddressRFC2822 TEST_HYPHENATED_LOCALPART_LABEL = HYPHENATED_LOCALPART_LABEL;
+ @DataPoint public static ValidEmailAddressRFC2822 TEST_LOCALPART_MAX_LENGTH = LOCALPART_MAX_LENGTH;
+
+ // BUG982048 @DataPoint public static ValidEmailAddressRFC2822 TEST_BASIC_QUOTED_EMAIL = BASIC_QUOTED_EMAIL;
+ // BUG982048 @DataPoint public static ValidEmailAddressRFC2822 TEST_ENCLOSED_QUOTED_LABEL = ENCLOSED_QUOTED_LABEL;
+ // BUG982048 @DataPoint public static ValidEmailAddressRFC2822 TEST_LOCALPART_EMPTY_QUOTE = LOCALPART_WITH_EMPTY_QUOTE;
+ // BUG982048 @DataPoint public static ValidEmailAddressRFC2822 TEST_QUOTED_ESCAPED_SPECIAL_CHARACTERS = QUOTED_ESCAPED_SPECIAL_CHARACTERS;
+ // BUG982048 @DataPoint public static ValidEmailAddressRFC2822 TEST_QUOTED_ESCAPED_QUOTES = QUOTED_ESCAPED_QUOTES;
+ // BUG982048 @DataPoint public static ValidEmailAddressRFC2822 TEST_QUOTED_WITH_SPACE = QUOTED_WITH_SPACE;
+ // BUG982048 @DataPoint public static ValidEmailAddressRFC2822 TEST_BRACKETED_DOMAIN = BRACKETED_DOMAIN;
+ // BUG982048 @DataPoint public static ValidEmailAddressRFC2822 TEST_BRACKETED_IPV4_DOMAIN = BRACKETED_IPV4_DOMAIN;
+ // BUG982048 @DataPoint public static ValidEmailAddressRFC2822 TEST_BRACKETED_IPV6_DOMAIN = BRACKETED_IPV6_DOMAIN;
+
+ @Theory
+ public void validEmailAcceptance(ValidEmailAddressRFC2822 emailAddress)
+ {
+ String errorMsg = "not a well-formed email address";
+ RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration();
+ registerPage = registerPage.enterEmail(emailAddress.toString()).clickTerms();
+ assertThat("Email validation errors are not shown", registerPage.getErrors(),
+ Matchers.not(Matchers.hasItem(errorMsg)));
+
+ }
+
+}
From 10d1f864e753f49b567265b7812af58b08db11fc Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Mon, 15 Jul 2013 08:49:10 +1000
Subject: [PATCH 073/184] Refactor some coding as per suggested
---
.../ManageLanguageTeamMemberPage.java | 15 +--
.../feature/administration/ManageUsers.html | 5 +-
.../action/ProjectIterationFilesAction.java | 2 +-
.../zanata/action/ViewAllStatusAction.java | 2 +-
.../main/java/org/zanata/dao/PersonDAO.java | 97 +++++++------------
.../zanata/security/SecurityFunctions.java | 6 +-
.../service/impl/RegisterServiceImpl.java | 3 +-
.../presenter/SearchResultsPresenter.java | 2 +-
.../client/resources/WebTransMessages.java | 2 +-
.../client/ui/EditorButtonsWidget.java | 12 +--
.../src/main/resources/messages.properties | 2 +-
11 files changed, 60 insertions(+), 88 deletions(-)
diff --git a/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java b/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java
index 94150143a3..d20d653f04 100644
--- a/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java
+++ b/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java
@@ -26,8 +26,9 @@ public class ManageLanguageTeamMemberPage extends AbstractPage
private WebElement memberPanel;
public static final int USERNAME_COLUMN = 0;
- public static final int ISTRANSLATOR_COLUMN = 3;
+ public static final int SEARCH_RESULT_SELECTED_COLUMN = 0;
public static final int SEARCH_RESULT_PERSON_COLUMN = 1;
+ public static final int ISTRANSLATOR_COLUMN = 3;
public ManageLanguageTeamMemberPage(WebDriver driver)
{
@@ -130,17 +131,17 @@ public ManageLanguageTeamMemberPage addToTeam(TableRow personRow)
{
final String personUsername = personRow.getCellContents().get(1);
log.info("username to be added: {}", personUsername);
- WebElement firstCell = personRow.getCells().get(0).findElement(By.tagName("input"));
- WebElement translatorCell = personRow.getCells().get(3).findElement(By.tagName("input"));
+ WebElement selectRowToUpdateCell = personRow.getCells().get(SEARCH_RESULT_SELECTED_COLUMN).findElement(By.tagName("input"));
+ WebElement isTranslatorCell = personRow.getCells().get(ISTRANSLATOR_COLUMN).findElement(By.tagName("input"));
- if (!translatorCell.isSelected())
+ if (!isTranslatorCell.isSelected())
{
- if(!firstCell.isSelected())
+ if(!selectRowToUpdateCell.isSelected())
{
- firstCell.click();
+ selectRowToUpdateCell.click();
}
- translatorCell.click();
+ isTranslatorCell.click();
WebElement addButton = getDriver().findElement(By.id("resultForm:addSelectedBtn"));
addButton.click();
diff --git a/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html b/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html
index 493a353936..0d989efa88 100644
--- a/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html
+++ b/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html
@@ -1,4 +1,4 @@
-
+ManageUsers
User Administration
@@ -21,7 +21,8 @@ Changing a User's Login Details
- and navigate to user 'admin ' and press Edit .
+ and navigate to user 'admin ' and press
+ Edit .
diff --git a/zanata-war/src/main/java/org/zanata/action/ProjectIterationFilesAction.java b/zanata-war/src/main/java/org/zanata/action/ProjectIterationFilesAction.java
index 155ea79e9a..6c31f7a3bd 100644
--- a/zanata-war/src/main/java/org/zanata/action/ProjectIterationFilesAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/ProjectIterationFilesAction.java
@@ -650,7 +650,7 @@ public List getTranslationDeniedReasonMessages()
}
// User not member of language team
- if (!personDAO.isTranslatorOfLanguageTeam(authenticatedAccount.getPerson(), getLocale()))
+ if (!personDAO.isUserInLanguageTeamWithRoles(authenticatedAccount.getPerson(), getLocale(), true, null, null))
{
displayMessages.add(zanataMessages.getMessage("jsf.iteration.files.translateDenied.UserNotTranslatorInLanguageTeam", getLocale().retrieveDisplayName()));
}
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 1eb640034b..2f1e91d9c1 100644
--- a/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java
@@ -296,7 +296,7 @@ public List getAllStatus()
if (!statsMap.containsKey(var.getLocaleId()))
{
- boolean isMember = authenticatedAccount != null ? personDAO.isMemberOfLanguageTeam(authenticatedAccount.getPerson(), var) : false;
+ boolean isMember = authenticatedAccount != null ? personDAO.isUserInLanguageTeamWithRoles(authenticatedAccount.getPerson(), var, null, null, null) : false;
Status op = new Status(var.getLocaleId().getId(), var.retrieveNativeName(), stats, isMember);
statsMap.put(var.getLocaleId(), op);
diff --git a/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java b/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
index 8d2870cf10..ae7b63293e 100644
--- a/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
@@ -129,73 +129,42 @@ public int getTotalTranslator()
}
/**
- * Indicates if a Person is member of a language team.
- * @param person The person
- * @param language The language team
- * @return True if person is a member of the language team.
+ * Indicates if a Person is a member of a language team with selected roles.
+ * @param person
+ * @param language
+ * @param isTranslator
+ * @param isReviewer
+ * @param isCoordinator
+ * @return True if person is a member of the language team with selected roles.
*/
- public boolean isMemberOfLanguageTeam( HPerson person, HLocale language )
+ public boolean isUserInLanguageTeamWithRoles(HPerson person, HLocale language, Boolean isTranslator, Boolean isReviewer, Boolean isCoordinator)
{
- Query q = getSession().createQuery("select count(*) from HLocaleMember " +
- "where id.person = :person and id.supportedLanguage = :language")
- .setParameter("person", person)
- .setParameter("language", language);
- q.setCacheable(false).setComment("PersonDAO.isMemberOfLanguageTeam");
- Long totalCount = (Long) q.uniqueResult();
- return totalCount > 0L;
- }
-
- /**
- * Indicates if a Person is a translator of a language team.
- * @param person The person
- * @param language The language team
- * @return True if person is a translator of the language team.
- */
- public boolean isTranslatorOfLanguageTeam( HPerson person, HLocale language )
- {
- Query q = getSession().createQuery("select count(*) from HLocaleMember " +
- "where id.person = :person and id.supportedLanguage = :language " +
- "and translator = true")
- .setParameter("person", person)
- .setParameter("language", language);
- q.setCacheable(false).setComment("PersonDAO.isTranslatorOfLanguageTeam");
- Long totalCount = (Long) q.uniqueResult();
- return totalCount > 0L;
- }
-
- /**
- * Indicates if a Person is a reviewer of a language team.
- * @param person The person
- * @param language The language team
- * @return True if person is a reviewer of the language team.
- */
- public boolean isReviewerOfLanguageTeam( HPerson person, HLocale language )
- {
- Query q = getSession().createQuery("select count(*) from HLocaleMember " +
- "where id.person = :person and id.supportedLanguage = :language " +
- "and reviewer = true")
- .setParameter("person", person)
- .setParameter("language", language);
- q.setCacheable(false).setComment("PersonDAO.isReviewerOfLanguageTeam");
- Long totalCount = (Long) q.uniqueResult();
- return totalCount > 0L;
- }
-
-
- /**
- * Indicates if a Person is a coordinator of a language team.
- * @param person The person
- * @param language The language team
- * @return True if person is a coordinator of the language team.
- */
- public boolean isCoordinatorOfLanguageTeam( HPerson person, HLocale language )
- {
- Query q = getSession().createQuery("select count(*) from HLocaleMember " +
- "where id.person = :person and id.supportedLanguage = :language " +
- "and coordinator = true")
+ StringBuilder sb = new StringBuilder();
+ sb.append("select count(*) from HLocaleMember where ");
+ sb.append("id.person = :person ");
+ sb.append("and id.supportedLanguage = :language ");
+
+ if(isTranslator != null)
+ {
+ sb.append("and translator = :isTranslator ");
+ }
+ if(isReviewer != null)
+ {
+ sb.append("and reviewer = :isReviewer ");
+ }
+ if(isCoordinator != null)
+ {
+ sb.append("and coordinator = :isCoordinator ");
+ }
+
+ Query q = getSession().createQuery(sb.toString().trim())
.setParameter("person", person)
- .setParameter("language", language);
- q.setCacheable(false).setComment("PersonDAO.isCoordinatorOfLanguageTeam");
+ .setParameter("language", language)
+ .setParameter("isTranslator", isTranslator.booleanValue())
+ .setParameter("isReviewer", isReviewer.booleanValue())
+ .setParameter("isCoordinator", isCoordinator.booleanValue());
+
+ q.setCacheable(false).setComment("PersonDAO.isUserInLanguageTeamWithRoles");
Long totalCount = (Long) q.uniqueResult();
return totalCount > 0L;
}
diff --git a/zanata-war/src/main/java/org/zanata/security/SecurityFunctions.java b/zanata-war/src/main/java/org/zanata/security/SecurityFunctions.java
index 887e8fb4e7..1568b666e1 100644
--- a/zanata-war/src/main/java/org/zanata/security/SecurityFunctions.java
+++ b/zanata-war/src/main/java/org/zanata/security/SecurityFunctions.java
@@ -73,7 +73,7 @@ public static boolean isUserTranslatorOfLanguageTeam( HLocale lang )
if( authenticatedAccount != null )
{
- return personDAO.isTranslatorOfLanguageTeam( authenticatedAccount.getPerson(), lang );
+ return personDAO.isUserInLanguageTeamWithRoles(authenticatedAccount.getPerson(), lang, true, null, null);
}
return false; // No authenticated user
@@ -86,7 +86,7 @@ public static boolean isUserReviewerOfLanguageTeam( HLocale lang )
if( authenticatedAccount != null )
{
- return personDAO.isReviewerOfLanguageTeam( authenticatedAccount.getPerson(), lang );
+ return personDAO.isUserInLanguageTeamWithRoles( authenticatedAccount.getPerson(), lang, null, true, null );
}
return false; // No authenticated user
@@ -99,7 +99,7 @@ public static boolean isUserCoordinatorOfLanguageTeam( HLocale lang )
if( authenticatedAccount != null )
{
- return personDAO.isCoordinatorOfLanguageTeam( authenticatedAccount.getPerson(), lang );
+ return personDAO.isUserInLanguageTeamWithRoles( authenticatedAccount.getPerson(), lang, null, null, true );
}
return false; // No authenticated user
diff --git a/zanata-war/src/main/java/org/zanata/service/impl/RegisterServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/RegisterServiceImpl.java
index 80f805371f..48893aa114 100644
--- a/zanata-war/src/main/java/org/zanata/service/impl/RegisterServiceImpl.java
+++ b/zanata-war/src/main/java/org/zanata/service/impl/RegisterServiceImpl.java
@@ -270,7 +270,8 @@ public void execute()
if( activeMembership == null )
{
- activeMembership = new HLocaleMember(activePerson, obsoleteMembership.getSupportedLanguage(), obsoleteMembership.isTranslator(), obsoleteMembership.isReviewer(), obsoleteMembership.isCoordinator());
+ activeMembership = new HLocaleMember(activePerson, obsoleteMembership.getSupportedLanguage(),
+ obsoleteMembership.isTranslator(), obsoleteMembership.isReviewer(), obsoleteMembership.isCoordinator());
}
activeMembership.setCoordinator(activeMembership.isCoordinator() || obsoleteMembership.isCoordinator());
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 58b13a37d1..d70be96836 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
@@ -862,7 +862,7 @@ private void fireReplaceTextEvent(List toReplace)
{
if (!userWorkspaceContext.hasWriteAccess())
{
- eventBus.fireEvent(new NotificationEvent(Severity.Warning, messages.noModifyTranslationAccess()));
+ eventBus.fireEvent(new NotificationEvent(Severity.Warning, messages.youAreNotAllowedToModifyTranslations()));
return;
}
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 e2e9b82e8b..4e73a3fbc6 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
@@ -200,7 +200,7 @@ public interface WebTransMessages extends Messages
String noReplacementsToMake();
@DefaultMessage("You have no access to modify translations")
- String noModifyTranslationAccess();
+ String youAreNotAllowedToModifyTranslations();
@DefaultMessage("View in editor")
String viewDocInEditor();
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 6277335db0..4d86a7f05f 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
@@ -42,17 +42,17 @@ public class EditorButtonsWidget extends Composite
public EditorButtonsWidget()
{
initWidget(ourUiBinder.createAndBindUi(this));
- displayReviewButtons(listener != null && listener.canReviewTranslation());
- displayModifyTranslationButtons(listener != null && listener.canModifyTranslation());
+ setDisplayReviewButtons(listener != null && listener.canReviewTranslation());
+ setDisplayModifyTranslationButtons(listener != null && listener.canModifyTranslation());
}
- private void displayReviewButtons(boolean canReview)
+ private void setDisplayReviewButtons(boolean canReview)
{
acceptIcon.setVisible(canReview);
rejectIcon.setVisible(canReview);
}
- private void displayModifyTranslationButtons(boolean canModify)
+ private void setDisplayModifyTranslationButtons(boolean canModify)
{
saveIcon.setVisible(canModify);
fuzzyIcon.setVisible(canModify);
@@ -124,8 +124,8 @@ public void onReject(ClickEvent event)
public void setListener(TargetContentsDisplay.Listener listener)
{
this.listener = listener;
- displayReviewButtons(listener.canReviewTranslation());
- displayModifyTranslationButtons(listener.canModifyTranslation());
+ setDisplayReviewButtons(listener.canReviewTranslation());
+ setDisplayModifyTranslationButtons(listener.canModifyTranslation());
}
public void setId(TransUnitId id)
diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties
index a06af415f6..1c85b2269d 100644
--- a/zanata-war/src/main/resources/messages.properties
+++ b/zanata-war/src/main/resources/messages.properties
@@ -393,7 +393,7 @@ jsf.Coordinator=Coordinator
jsf.JoinLanguageTeam=Join Language Team
jsf.LeaveLanguageTeam=Leave Language Team
jsf.RequestToJoinLanguageTeam=Request To Join Team
-jsf.RequestUpdateRoleLanguageTeam=Request role
+jsf.RequestUpdateRoleLanguageTeam=Request Role
jsf.contactLanguageTeamCoordinator=Contact Team Coordinators
jsf.AddTeamMember=Add Team Member
jsf.FindUsersToAdd=Find Users To Add
From f25b57037a8914536cedaedc2fec6dc58a9be433 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Mon, 15 Jul 2013 09:10:43 +1000
Subject: [PATCH 074/184] Fix null pointer exception
---
.../main/java/org/zanata/dao/PersonDAO.java | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java b/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
index ae7b63293e..24b4abe547 100644
--- a/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
@@ -159,10 +159,20 @@ public boolean isUserInLanguageTeamWithRoles(HPerson person, HLocale language, B
Query q = getSession().createQuery(sb.toString().trim())
.setParameter("person", person)
- .setParameter("language", language)
- .setParameter("isTranslator", isTranslator.booleanValue())
- .setParameter("isReviewer", isReviewer.booleanValue())
- .setParameter("isCoordinator", isCoordinator.booleanValue());
+ .setParameter("language", language);
+
+ if(isTranslator != null)
+ {
+ q.setParameter("isTranslator", isTranslator.booleanValue());
+ }
+ if(isReviewer != null)
+ {
+ q.setParameter("isReviewer", isReviewer.booleanValue());
+ }
+ if(isCoordinator != null)
+ {
+ q.setParameter("isCoordinator", isCoordinator.booleanValue());
+ }
q.setCacheable(false).setComment("PersonDAO.isUserInLanguageTeamWithRoles");
Long totalCount = (Long) q.uniqueResult();
From 41783d7964577c0dd65728ff14553c7a378b1bc4 Mon Sep 17 00:00:00 2001
From: Damian Jansen
Date: Mon, 15 Jul 2013 13:36:54 +1000
Subject: [PATCH 075/184] Fix some line length and function calls
Function calls (specifically new BasicWorkFlow) replaced.
Wrapped some long lines.
---
.../main/java/org/zanata/page/HomePage.java | 2 +-
.../rfc2822/InvalidEmailAddressRFC2822.java | 22 ++++++++++---------
.../rfc2822/ValidEmailAddressRFC2822.java | 21 ++++++++++--------
.../account/InvalidEmailAddressTest.java | 12 +++++-----
.../feature/account/RegisterDetailedTest.java | 16 +++++++-------
5 files changed, 39 insertions(+), 34 deletions(-)
diff --git a/functional-test/src/main/java/org/zanata/page/HomePage.java b/functional-test/src/main/java/org/zanata/page/HomePage.java
index b58226ae46..2442ffe3c1 100644
--- a/functional-test/src/main/java/org/zanata/page/HomePage.java
+++ b/functional-test/src/main/java/org/zanata/page/HomePage.java
@@ -112,7 +112,7 @@ public AdministrationPage goToAdministration()
public RegisterPage goToRegistration()
{
- getDriver().findElement(By.linkText("More")).click();
+ getDriver().findElement(By.id("systemCol")).click();
WebElement registerLink = getDriver().findElement(By.id("Register"));
registerLink.click();
return new RegisterPage(getDriver());
diff --git a/functional-test/src/main/java/org/zanata/util/rfc2822/InvalidEmailAddressRFC2822.java b/functional-test/src/main/java/org/zanata/util/rfc2822/InvalidEmailAddressRFC2822.java
index ded69fe894..9aab26ff2a 100644
--- a/functional-test/src/main/java/org/zanata/util/rfc2822/InvalidEmailAddressRFC2822.java
+++ b/functional-test/src/main/java/org/zanata/util/rfc2822/InvalidEmailAddressRFC2822.java
@@ -24,14 +24,15 @@
* @author Damian Jansen djansen@redhat.com
* @see RFC2822 Internet Message Format Standard
* Synopsis:
- * The functions of this class contain invalid email addresses, as stipulated in the
+ * This enumeration represents a collection of invalid email addresses, as stipulated in the
* RFC2822 Internet Message Format standard, or referred to standards.
*
* Definitions
* localpart: the section of an address preceding the @ symbol
* domain: the section of an address following the @ symbol
- * label: section of localpart or domain between the start, @ symbol, period or end (also referred to as "atom")
- * e.g. me, myself, example, com in me.myself@example.com
+ * label: section of localpart or domain between the start, @ symbol, period or
+ * end (also referred to as "atom")
+ * e.g. me, myself, example, com in me.myself@example.com
* quote / quoting: a section of the localpart contained within quotation marks
*
* Untested:
@@ -88,8 +89,8 @@ public enum InvalidEmailAddressRFC2822 {
INVALID_SINGLE_QUOTING("test\"user@example.com"),
/**
- * If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
- * or quoted chunks separated by periods
+ * If an email is using the obsolete quoting on a per-label basis, then the email
+ * address consists of unquoted or quoted chunks separated by periods
* @see "RFC 2822, section 4.4"
*/
INVALID_QUOTING_SEPARATION("\"test\"user@example.com"),
@@ -114,15 +115,16 @@ public enum InvalidEmailAddressRFC2822 {
INVALID_QUOTED_TAB("test.\"".concat("\t").concat("\".user@example.com")),
/**
- * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
+ * If the quoted local part has a backslash, the following character is escaped and must not be
+ * 10 (LF), 13 (CR).
* @see "RFC 2822, section 3.4.1"
*/
INVALID_QUOTED_RETURN("test.\"\\".concat("\r").concat("\".user@example.com")),
INVALID_QUOTED_LINEFEED("test.\"\\".concat("\n").concat("\".user@example.com")),
/**
- * A plain domain consists of labels separated with periods. No period can start or end a domain name.
- * No two periods in succession can be in a domain name.
+ * A plain domain consists of labels separated with periods. No period can start or end a
+ * domain name. No two periods in succession can be in a domain name.
* @see "RFC 1035, section 2.3.4"
*/
TRAILING_DOMAIN_DOT("email@example.com."),
@@ -158,8 +160,8 @@ public enum InvalidEmailAddressRFC2822 {
MULTIPLE_DASHES_BRACKETED_DOMAIN("email@[exa--mple.com]"),
/**
- * The contents of a bracketed domain can have a \ precede a character to escape it, and the following character
- * must not be 10 (LF) or 13 (CR).
+ * The contents of a bracketed domain can have a \ precede a character to escape it, and the
+ * following character must not be 10 (LF) or 13 (CR).
* @see "RFC2822, section 3.4.1"
*/
INVALID_BRACKETED_DOMAIN_RETURN("test@[\\".concat("\r").concat("example.com]")),
diff --git a/functional-test/src/main/java/org/zanata/util/rfc2822/ValidEmailAddressRFC2822.java b/functional-test/src/main/java/org/zanata/util/rfc2822/ValidEmailAddressRFC2822.java
index e153c9049c..8fd1b7d4b5 100644
--- a/functional-test/src/main/java/org/zanata/util/rfc2822/ValidEmailAddressRFC2822.java
+++ b/functional-test/src/main/java/org/zanata/util/rfc2822/ValidEmailAddressRFC2822.java
@@ -24,14 +24,15 @@
* @author Damian Jansen djansen@redhat.com
* @see RFC2822 Internet Message Format Standard
* Synopsis:
- * The functions of this class contain valid email addresses, as stipulated in the
+ * This enumeration represents a collection of valid email addresses, as stipulated in the
* RFC2822 Internet Message Format standard, or referred to standards.
*
* Definitions
* localpart: the section of an address preceding the @ symbol
* domain: the section of an address following the @ symbol
- * label: section of localpart or domain between the start, @ symbol, period or end (also referred to as "atom")
- * e.g. me, myself, example, com in me.myself@example.com
+ * label: section of localpart or domain between the start, @ symbol, period or
+ * end (also referred to as "atom")
+ * e.g. me, myself, example, com in me.myself@example.com
* quote / quoting: a section of the localpart contained within quotation marks
*
* Untested:
@@ -68,17 +69,18 @@ public enum ValidEmailAddressRFC2822 {
SPECIAL_CHARACTERS_LOCALPART("email.!#$%'*+-/=?^_`{|}~.dot@example.com"),
/**
- * If an email is using the obsolete quoting on a per-label basis, then the email address consists of unquoted
- * or quoted chunks separated by periods.
+ * If an email is using the obsolete quoting on a per-label basis, then the email address
+ * consists of unquoted or quoted chunks separated by periods.
* @see "RFC 2822, section 4.4"
*/
ENCLOSED_QUOTED_LABEL("dot.\"email\".dot@example.com"),
LOCALPART_WITH_EMPTY_QUOTE("dot.\"\".dot@example.com"),
/**
- * If the quoted local part has a backslash, the following character is escaped and must not be 10 (LF), 13 (CR).
- * This supersedes the previous rule, allowing spaces and quotation marks in the email address as long as they
- * are escaped.
+ * If the quoted local part has a backslash, the following character is escaped and must not
+ * be 10 (LF), 13 (CR).
+ * This supersedes the previous rule, allowing spaces and quotation marks in the email address
+ * as long as they are escaped.
* @see "RFC 2822, section 3.4.1"
*/
QUOTED_ESCAPED_SPECIAL_CHARACTERS("email.\"(),:;<>\\@\\[\\]\\\\\"@example.com"),
@@ -94,7 +96,8 @@ public enum ValidEmailAddressRFC2822 {
BRACKETED_IPV6_DOMAIN("email@[IPv6:2001:2d12:c4fe:5afe::1]"),
/**
- * A plain domain consists of labels separated with periods. No period can start or end a domain name.
+ * A plain domain consists of labels separated with periods. No period can start or end
+ * a domain name.
* @see "RFC 1035, section 2.3.4"
*/
LOCALPART_MULTIPLE_LABELS("another.email@example.com"),
diff --git a/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java b/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java
index d307916cee..e79ffe043e 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java
@@ -60,12 +60,12 @@ public class InvalidEmailAddressTest {
@DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_ENCODED_HTML = INVALID_ENCODED_HTML;
@DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_FOLLOWING_TEXT = INVALID_FOLLOWING_TEXT;
- // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_IP_FORMAT = EmailAddressRFC2822.INVALID_IP_FORMAT;
- // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_MAX_EMAIL_LENGTH_EXCEEDED = EmailAddressRFC2822.MAX_EMAIL_LENGTH_EXCEEDED;
- // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_NON_UNICODE_CHARACTERS = EmailAddressRFC2822.NON_UNICODE_CHARACTERS;
- // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_LEADING_DASH_DOMAIN = EmailAddressRFC2822.LEADING_DASH_DOMAIN;
- // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_TRAILING_DASH_DOMAIN = EmailAddressRFC2822.TRAILING_DASH_DOMAIN;
- // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_MULTIPLE_DASHES_DOMAIN = EmailAddressRFC2822.MULTIPLE_DASHES_DOMAIN;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_INVALID_IP_FORMAT = INVALID_IP_FORMAT;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_MAX_EMAIL_LENGTH_EXCEEDED = MAX_EMAIL_LENGTH_EXCEEDED;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_NON_UNICODE_CHARACTERS = NON_UNICODE_CHARACTERS;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_LEADING_DASH_DOMAIN = LEADING_DASH_DOMAIN;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_TRAILING_DASH_DOMAIN = TRAILING_DASH_DOMAIN;
+ // BUG982048 @DataPoint public static InvalidEmailAddressRFC2822 TEST_MULTIPLE_DASHES_DOMAIN = MULTIPLE_DASHES_DOMAIN;
@Theory
public void invalidEmailRejection(InvalidEmailAddressRFC2822 emailAddress)
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
index 2a4b3f0aef..b59dcc24e3 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
@@ -70,13 +70,13 @@ public void before()
@Ignore("Captcha prevents test completion")
public void registerSuccessful()
{
- RegisterPage registerPage = homePage.goToRegistration();
- registerPage = registerPage.setFields(fields);
+ RegisterPage registerPage = homePage.goToRegistration().setFields(fields);
assertThat("No errors are shown", registerPage.getErrors().size(), Matchers.equalTo(0));
registerPage.register();
}
@Test
+ @Ignore("Unstable length matching ")
public void usernameLengthValidation()
{
String errorMsg = "size must be between 3 and 20";
@@ -101,7 +101,7 @@ public void usernameLengthValidation()
public void usernamePreExisting()
{
String errorMsg = "This username is not available";
- RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().enterUserName("admin");
+ RegisterPage registerPage = homePage.goToRegistration().enterUserName("admin");
assertThat("Username not available message is shown", registerPage.waitForErrors(), Matchers.hasItem(errorMsg));
}
@@ -111,7 +111,7 @@ public void emailValidation()
String errorMsg = "not a well-formed email address";
fields.put("email", InvalidEmailAddressRFC2822.PLAIN_ADDRESS.toString());
fields.put("username", "emailvalidation");
- RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields);
+ RegisterPage registerPage = homePage.goToRegistration().setFields(fields);
assertThat("Email validation errors are shown", registerPage.getErrors(), Matchers.hasItem(errorMsg));
}
@@ -123,7 +123,7 @@ public void rejectIncorrectCaptcha()
fields.put("email", "rejectbadcaptcha@example.com");
fields.put("captcha", "9000");
- RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields).registerFailure();
+ RegisterPage registerPage = homePage.goToRegistration().setFields(fields).registerFailure();
assertThat("The Captcha entry is rejected", registerPage.getErrors(), Matchers.contains(errorMsg));
}
@@ -136,7 +136,7 @@ public void passwordsMatch()
fields.put("password", "passwordsmatch");
fields.put("confirmpassword", "passwordsdonotmatch");
- RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields);
+ RegisterPage registerPage = homePage.goToRegistration().setFields(fields);
assertThat("Passwords fail to match error is shown", registerPage.getErrors(), Matchers.contains(errorMsg));
}
@@ -150,7 +150,7 @@ public void requiredFields()
fields.put("password", "");
fields.put("confirmpassword", "");
- RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields);
+ RegisterPage registerPage = homePage.goToRegistration().setFields(fields);
assertThat("Value is required shows for all fields", registerPage.getErrors(),
Matchers.contains(errorMsg, errorMsg, errorMsg, errorMsg, errorMsg));
}
@@ -164,7 +164,7 @@ public void bug981498_underscoreRules()
String errorMsg = "lowercase letters and digits (regex \"^[a-z\\d_]{3,20}$\")";
fields.put("email", "bug981498test@example.com");
fields.put("username", "______");
- RegisterPage registerPage = new BasicWorkFlow().goToHome().goToRegistration().setFields(fields);
+ RegisterPage registerPage = homePage.goToRegistration().setFields(fields);
assertThat("A username of all underscores is not valid", registerPage.getErrors(), Matchers.hasItem(errorMsg));
}
}
From 62087a3b64ab7c020a40133df7281dc7edd74051 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Mon, 15 Jul 2013 13:55:39 +1000
Subject: [PATCH 076/184] Disable modify translation for reviewer using
keyboard shortcut
---
.../org/zanata/service/SecurityService.java | 2 +-
.../presenter/SearchResultsPresenter.java | 8 +-
.../presenter/TargetContentsPresenter.java | 78 ++++++++++---------
.../presenter/TransMemoryPresenter.java | 2 +-
.../presenter/TranslationPresenter.java | 2 +-
.../client/service/TransUnitSaveService.java | 13 +++-
.../org/zanata/webtrans/client/ui/Editor.java | 11 ++-
.../client/ui/EditorButtonsWidget.java | 8 +-
.../client/view/TargetContentsDisplay.java | 4 +-
.../client/view/TargetContentsView.java | 2 +
.../server/rpc/UpdateTransUnitHandler.java | 14 +++-
.../shared/model/UserWorkspaceContext.java | 10 +--
.../shared/model/WorkspaceRestrictions.java | 24 +++---
.../webtrans/shared/rpc/TransUnitUpdated.java | 2 +-
zanata-war/src/main/resources/security.drl | 19 ++++-
.../presenter/SearchResultsPresenterTest.java | 2 +-
.../TargetContentsPresenterTest.java | 6 +-
.../presenter/TransMemoryPresenterTest.java | 2 +-
.../service/TransUnitSaveServiceTest.java | 4 +-
.../rpc/ActivateWorkspaceHandlerTest.java | 2 +-
20 files changed, 134 insertions(+), 81 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/service/SecurityService.java b/zanata-war/src/main/java/org/zanata/service/SecurityService.java
index 3aff690d4f..d38c813f1c 100644
--- a/zanata-war/src/main/java/org/zanata/service/SecurityService.java
+++ b/zanata-war/src/main/java/org/zanata/service/SecurityService.java
@@ -47,7 +47,7 @@ public enum TranslationAction
ADD("add-translation"),
MODIFY("modify-translation"),
REMOVE("remove-translation"),
- APPROVE("approve-translation");
+ REVIEW("review-translation");
private final String action;
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 ba661fa1c6..4c8f1690a5 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
@@ -255,7 +255,7 @@ protected void onBind()
docPaths = new HashMap();
selectAllDocList = new HashMap>();
setUiForNothingSelected();
- display.setReplaceAllButtonVisible(userWorkspaceContext.hasWriteAccess());
+ display.setReplaceAllButtonVisible(userWorkspaceContext.hasEditTranslationAccess());
display.addSearchFieldsSelect("search both", "both");
display.addSearchFieldsSelect("search target", "target");
@@ -368,7 +368,7 @@ public void onWorkspaceContextUpdated(WorkspaceContextUpdateEvent event)
userWorkspaceContext.setProjectActive(event.isProjectActive());
userWorkspaceContext.getWorkspaceContext().getWorkspaceId().getProjectIterationId().setProjectType(event.getProjectType());
- display.setReplaceAllButtonVisible(userWorkspaceContext.hasWriteAccess());
+ display.setReplaceAllButtonVisible(userWorkspaceContext.hasEditTranslationAccess());
for (TransUnitReplaceInfo info : allReplaceInfos.values())
{
@@ -860,7 +860,7 @@ private List getAllSelected()
*/
private void fireReplaceTextEvent(List toReplace)
{
- if (!userWorkspaceContext.hasWriteAccess())
+ if (!userWorkspaceContext.hasEditTranslationAccess())
{
eventBus.fireEvent(new NotificationEvent(Severity.Warning, messages.youAreNotAllowedToModifyTranslations()));
return;
@@ -1325,7 +1325,7 @@ private int countSelectedFlows()
*/
private void setReplaceState(TransUnitReplaceInfo replaceInfo, ReplacementState replaceState)
{
- if (!userWorkspaceContext.hasWriteAccess())
+ if (!userWorkspaceContext.hasEditTranslationAccess())
{
replaceInfo.setReplaceState(ReplacementState.NotAllowed);
}
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 02ac63e867..cbc7f7942a 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
@@ -195,7 +195,7 @@ public void setSelected(final TransUnitId currentTransUnitId)
}
display.showButtons(isDisplayButtons());
- if (userWorkspaceContext.hasReadOnlyAccess())
+ if(!canEditTranslation())
{
display.setToMode(ViewMode.VIEW);
concealDisplay();
@@ -388,12 +388,15 @@ private void ensureRowSelection(TransUnitId transUnitId)
@Override
public void copySource(ToggleEditor editor, TransUnitId id)
{
- currentEditorIndex = editor.getIndex();
- ensureRowSelection(id);
- editor.setTextAndValidate(sourceContentsPresenter.getSelectedSource());
- editor.setFocus();
-
- eventBus.fireEvent(new NotificationEvent(Severity.Info, messages.notifyCopied()));
+ if(canEditTranslation())
+ {
+ currentEditorIndex = editor.getIndex();
+ ensureRowSelection(id);
+ editor.setTextAndValidate(sourceContentsPresenter.getSelectedSource());
+ editor.setFocus();
+
+ eventBus.fireEvent(new NotificationEvent(Severity.Info, messages.notifyCopied()));
+ }
}
protected void copySourceForActiveRow()
@@ -459,21 +462,24 @@ public void onDataCopy(final CopyDataToEditorEvent event)
private void copyTextWhenIsEditing(List contents, boolean isInsertText)
{
- if (isInsertText)
+ if(canEditTranslation())
{
- getCurrentEditor().insertTextInCursorPosition(contents.get(0));
- validate(getCurrentEditor());
- }
- else
- {
- ArrayList editors = display.getEditors();
- for (int i = 0; i < contents.size(); i++)
+ if (isInsertText)
{
- ToggleEditor editor = editors.get(i);
- editor.setTextAndValidate(contents.get(i));
+ getCurrentEditor().insertTextInCursorPosition(contents.get(0));
+ validate(getCurrentEditor());
}
+ else
+ {
+ ArrayList editors = display.getEditors();
+ for (int i = 0; i < contents.size(); i++)
+ {
+ ToggleEditor editor = editors.get(i);
+ editor.setTextAndValidate(contents.get(i));
+ }
+ }
+ eventBus.fireEvent(new NotificationEvent(Severity.Info, messages.notifyCopied()));
}
- eventBus.fireEvent(new NotificationEvent(Severity.Info, messages.notifyCopied()));
}
public void revealDisplay()
@@ -500,10 +506,12 @@ public void showData(List transUnits)
TargetContentsDisplay display = displayProvider.get();
display.setListener(this);
display.setValueAndCreateNewEditors(transUnit);
- if (userWorkspaceContext.hasReadOnlyAccess())
+
+ if(!canEditTranslation())
{
display.setToMode(ViewMode.VIEW);
}
+
display.showButtons(isDisplayButtons());
builder.add(display);
}
@@ -590,28 +598,24 @@ public void onWorkspaceContextUpdated(WorkspaceContextUpdateEvent event)
// FIXME once setting codemirror editor to readonly it won't be editable again
userWorkspaceContext.setProjectActive(event.isProjectActive());
userWorkspaceContext.getWorkspaceContext().getWorkspaceId().getProjectIterationId().setProjectType(event.getProjectType());
-
+
+ for (TargetContentsDisplay targetContentsDisplay : displayList)
+ {
+ ViewMode viewMode = canEditTranslation() ? ViewMode.EDIT : ViewMode.VIEW;
+ boolean showButtons = userWorkspaceContext.hasReadOnlyAccess() ? false : isDisplayButtons();
+
+ targetContentsDisplay.setToMode(viewMode);
+ targetContentsDisplay.showButtons(showButtons);
+ }
+
if (userWorkspaceContext.hasReadOnlyAccess())
{
- Log.info("from editable to readonly");
- for (TargetContentsDisplay targetContentsDisplay : displayList)
- {
- targetContentsDisplay.setToMode(ViewMode.VIEW);
- targetContentsDisplay.showButtons(false);
- }
concealDisplay();
}
- else if (!userWorkspaceContext.hasReadOnlyAccess())
+ else
{
- Log.info("from readonly mode to writable");
- for (TargetContentsDisplay targetContentsDisplay : displayList)
- {
- targetContentsDisplay.setToMode(ViewMode.EDIT);
- targetContentsDisplay.showButtons(isDisplayButtons());
- }
revealDisplay();
}
-
}
/**
@@ -664,17 +668,17 @@ public UserConfigHolder.ConfigurationState getConfigState()
}
@Override
- public boolean canReviewTranslation()
+ public boolean canReview()
{
WorkspaceRestrictions restrictions = userWorkspaceContext.getWorkspaceRestrictions();
return restrictions.isHasReviewAccess() && restrictions.isProjectRequireReview();
}
@Override
- public boolean canModifyTranslation()
+ public boolean canEditTranslation()
{
WorkspaceRestrictions restrictions = userWorkspaceContext.getWorkspaceRestrictions();
- return restrictions.isHasWriteAccess();
+ return restrictions.isHasEditTranslationAccess();
}
@Override
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransMemoryPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransMemoryPresenter.java
index 3992562c66..cb2debdd3b 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransMemoryPresenter.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TransMemoryPresenter.java
@@ -257,7 +257,7 @@ public void onTransUnitSelected(TransUnitSelectionEvent event)
@Override
public void onTransMemoryCopy(TransMemoryShortcutCopyEvent event)
{
- if (userWorkspaceContext.hasWriteAccess())
+ if (userWorkspaceContext.hasEditTranslationAccess())
{
TransMemoryResultItem item = getTMResultOrNull(event);
if (item != null)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationPresenter.java
index 25b4d61a21..fa7306caac 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationPresenter.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationPresenter.java
@@ -150,7 +150,7 @@ public void onKeyShortcut(KeyShortcutEvent event)
@Override
public void onKeyShortcut(KeyShortcutEvent event)
{
- if (!isOtherInputFieldFocused() && userWorkspaceContext.getWorkspaceRestrictions().isHasWriteAccess())
+ if (!isOtherInputFieldFocused() && userWorkspaceContext.getWorkspaceRestrictions().isHasEditTranslationAccess())
{
targetContentsPresenter.setFocus();
targetContentsPresenter.revealDisplay();
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/service/TransUnitSaveService.java b/zanata-war/src/main/java/org/zanata/webtrans/client/service/TransUnitSaveService.java
index 1fab75fb43..40c2aa13bf 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/service/TransUnitSaveService.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/service/TransUnitSaveService.java
@@ -169,7 +169,18 @@ private boolean stateHasNotChanged(TransUnitSaveEvent event)
private TransUnitUpdated.UpdateType workoutUpdateType(ContentState status)
{
- return status == ContentState.NeedReview ? TransUnitUpdated.UpdateType.WebEditorSaveFuzzy : TransUnitUpdated.UpdateType.WebEditorSave;
+ if(status == ContentState.Approved || status == ContentState.Rejected)
+ {
+ return TransUnitUpdated.UpdateType.WebEditorSaveReview;
+ }
+ else if(status == ContentState.NeedReview)
+ {
+ return TransUnitUpdated.UpdateType.WebEditorSaveFuzzy;
+ }
+ else
+ {
+ return TransUnitUpdated.UpdateType.WebEditorSave;
+ }
}
private class UpdateTransUnitCallback implements AsyncCallback
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Editor.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Editor.java
index e55fdfddd0..152acd2a79 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Editor.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Editor.java
@@ -85,10 +85,15 @@ public void execute()
// determine whether to show or hide buttons
showCopySourceButton(listener.isDisplayButtons());
- if (!listener.isReadOnly())
+ if(!listener.canEditTranslation())
+ {
+ setViewMode(ViewMode.VIEW);
+ }
+ else
{
setViewMode(ViewMode.EDIT);
}
+
setText(displayString);
}
@@ -101,7 +106,7 @@ public void setEnableSpellCheck(Boolean enabled)
private void fireValidationEvent()
{
- if (getViewMode() == ViewMode.EDIT)
+ if(listener.canEditTranslation())
{
listener.validate(this);
}
@@ -205,7 +210,7 @@ public void insertTextInCursorPosition(String suggestion)
String preCursor = textArea.getText().substring(0, textArea.getCursorPos());
String postCursor = textArea.getText().substring(textArea.getCursorPos(), textArea.getText().length());
- textArea.setText(preCursor + suggestion + postCursor);
+ setTextAndValidate(preCursor + suggestion + postCursor);
textArea.setCursorPos(textArea.getText().indexOf(suggestion) + suggestion.length());
}
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 f932a819cd..d11795bbef 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
@@ -50,8 +50,8 @@ public EditorButtonsWidget(EventBus eventBus)
{
this.eventBus = eventBus;
initWidget(ourUiBinder.createAndBindUi(this));
- setDisplayReviewButtons(listener != null && listener.canReviewTranslation());
- setDisplayModifyTranslationButtons(listener != null && listener.canModifyTranslation());
+ setDisplayReviewButtons(listener != null && listener.canReview());
+ setDisplayModifyTranslationButtons(listener != null && listener.canEditTranslation());
}
private void setDisplayReviewButtons(boolean canReview)
@@ -138,8 +138,8 @@ public void onCommentClick(ClickEvent event)
public void setListener(TargetContentsDisplay.Listener listener)
{
this.listener = listener;
- setDisplayReviewButtons(listener.canReviewTranslation());
- setDisplayModifyTranslationButtons(listener.canModifyTranslation());
+ setDisplayReviewButtons(listener.canReview());
+ setDisplayModifyTranslationButtons(listener.canEditTranslation());
}
public void setIdAndState(TransUnitId id, ContentState state)
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 eec4764ae3..2a83987837 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
@@ -98,9 +98,9 @@ interface Listener
UserConfigHolder.ConfigurationState getConfigState();
- boolean canReviewTranslation();
+ boolean canReview();
- boolean canModifyTranslation();
+ boolean canEditTranslation();
void acceptTranslation(TransUnitId id);
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 b3e798c179..3a14a0f9ec 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
@@ -33,6 +33,8 @@
import org.zanata.webtrans.client.util.ContentStateToStyleUtil;
import org.zanata.webtrans.shared.model.TransUnit;
import org.zanata.webtrans.shared.model.TransUnitId;
+
+import com.allen_sauer.gwt.log.client.Log;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.gwt.core.client.GWT;
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateTransUnitHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateTransUnitHandler.java
index 69ce084931..a53296b085 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateTransUnitHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateTransUnitHandler.java
@@ -45,6 +45,7 @@
import org.zanata.webtrans.shared.model.TransUnitUpdateInfo;
import org.zanata.webtrans.shared.model.TransUnitUpdateRequest;
import org.zanata.webtrans.shared.rpc.TransUnitUpdated;
+import org.zanata.webtrans.shared.rpc.TransUnitUpdated.UpdateType;
import org.zanata.webtrans.shared.rpc.UpdateTransUnit;
import org.zanata.webtrans.shared.rpc.UpdateTransUnitResult;
@@ -67,7 +68,18 @@ public class UpdateTransUnitHandler extends AbstractActionHandler currentEditors = Lists.newArrayList(editor);
when(editor.getId()).thenReturn(selectedTU.getId());
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TransMemoryPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TransMemoryPresenterTest.java
index 65a9c1446e..70b518ad86 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TransMemoryPresenterTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TransMemoryPresenterTest.java
@@ -374,7 +374,7 @@ public void testOnTransUnitSelected()
public void testOnTransMemoryCopy()
{
presenter.setStatesForTesting(Lists.newArrayList(transMemoryResultItem), null);
- when(userWorkspaceContext.hasWriteAccess()).thenReturn(true);
+ when(userWorkspaceContext.hasEditTranslationAccess()).thenReturn(true);
List targetContents = Lists.newArrayList("a");
when(transMemoryResultItem.getTargetContents()).thenReturn(targetContents);
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/service/TransUnitSaveServiceTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/service/TransUnitSaveServiceTest.java
index ef58d72622..be3c415c62 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/service/TransUnitSaveServiceTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/service/TransUnitSaveServiceTest.java
@@ -124,7 +124,7 @@ public void willSaveIfSomethingHasChanged()
UpdateTransUnit updateTransUnit = actionCaptor.getValue();
assertThat(updateTransUnit.getUpdateRequests(), hasSize(1));
- assertThat(updateTransUnit.getUpdateType(), equalTo(TransUnitUpdated.UpdateType.WebEditorSave));
+ assertThat(updateTransUnit.getUpdateType(), equalTo(TransUnitUpdated.UpdateType.WebEditorSaveReview));
TransUnitUpdateRequest request = updateTransUnit.getUpdateRequests().get(0);
assertThat(request.getTransUnitId(), equalTo(TRANS_UNIT_ID));
@@ -149,7 +149,7 @@ public void willSaveToQueueIfItsSavingSameRow()
UpdateTransUnit updateTransUnit = actionCaptor.getValue();
assertThat(updateTransUnit.getUpdateRequests(), hasSize(1));
- assertThat(updateTransUnit.getUpdateType(), equalTo(TransUnitUpdated.UpdateType.WebEditorSave));
+ assertThat(updateTransUnit.getUpdateType(), equalTo(TransUnitUpdated.UpdateType.WebEditorSaveReview));
TransUnitUpdateRequest request = updateTransUnit.getUpdateRequests().get(0);
assertThat(request.getTransUnitId(), equalTo(TRANS_UNIT_ID));
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandlerTest.java b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandlerTest.java
index 5e1e52e0f1..531dc37e40 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandlerTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandlerTest.java
@@ -174,7 +174,7 @@ public void testExecute() throws Exception
UserWorkspaceContext userWorkspaceContext = result.getUserWorkspaceContext();
assertThat(userWorkspaceContext.getWorkspaceRestrictions().isHasGlossaryUpdateAccess(), Matchers.equalTo(true));
assertThat(userWorkspaceContext.getWorkspaceRestrictions().isProjectActive(), Matchers.equalTo(true));
- assertThat(userWorkspaceContext.getWorkspaceRestrictions().isHasWriteAccess(), Matchers.equalTo(true));
+ assertThat(userWorkspaceContext.getWorkspaceRestrictions().isHasEditTranslationAccess(), Matchers.equalTo(true));
assertThat(result.getStoredUserConfiguration(), Matchers.sameInstance(optionsResult.getConfiguration()));
}
From ce224e3f9345c1812f6a239499d274971bd1eea1 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Mon, 15 Jul 2013 14:43:33 +1000
Subject: [PATCH 077/184] fix paging bug in editor:
https://bugzilla.redhat.com/show_bug.cgi?id=983786
---
.../org/zanata/webtrans/client/ui/Pager.java | 31 ++++++++++++++-----
.../zanata/webtrans/client/ui/Pager.ui.xml | 7 ++++-
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java
index d792e745a5..cd3a35edd1 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java
@@ -3,6 +3,7 @@
import org.zanata.webtrans.client.resources.Resources;
import org.zanata.webtrans.client.resources.WebTransMessages;
+import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
@@ -42,7 +43,6 @@ interface Styles extends CssResource
String disabled();
}
-
@UiField
InlineLabel firstPage, lastPage, nextPage, prevPage;
@@ -158,7 +158,7 @@ public void setValue(Integer value)
@Override
public void setValue(Integer value, boolean fireEvents)
{
- if (value != this.currentPage)
+ if (value != this.currentPage && (value > 0 && value <= pageCount))
{
this.currentPage = value;
if (fireEvents)
@@ -183,23 +183,40 @@ public void onClick(ClickEvent event)
{
if (event.getSource() == firstPage)
{
- setValue(1);
+ if (isButtonEnabled(firstPage))
+ {
+ setValue(1);
+ }
}
else if (event.getSource() == lastPage)
{
- setValue(pageCount);
+ if (isButtonEnabled(lastPage))
+ {
+ setValue(pageCount);
+ }
}
else if (event.getSource() == nextPage)
{
- setValue(currentPage + 1);
+ if (isButtonEnabled(nextPage))
+ {
+ setValue(currentPage + 1);
+ }
}
else if (event.getSource() == prevPage)
{
- setValue(currentPage - 1);
+ if (isButtonEnabled(prevPage))
+ {
+ setValue(currentPage - 1);
+ }
}
}
};
+ private boolean isButtonEnabled(InlineLabel button)
+ {
+ return button.getStyleName().contains(style.enabled());
+ }
+
@Override
public HandlerRegistration addFocusHandler(FocusHandler handler)
{
@@ -214,7 +231,7 @@ public HandlerRegistration addBlurHandler(BlurHandler handler)
private void setEnabled(InlineLabel button, boolean enabled)
{
- if(enabled)
+ if (enabled)
{
button.removeStyleName(style.disabled());
button.addStyleName(style.enabled());
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.ui.xml
index 96c0ab97e9..7c7fd3be74 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.ui.xml
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.ui.xml
@@ -6,7 +6,7 @@
.nav-button {
- font-size:16px;
+ font-size:1.1em;
}
.rootContainer {
@@ -23,6 +23,11 @@
{
opacity:1;
cursor:pointer;
+ transition:0.2s;
+ }
+
+ .enabled:hover {
+ color:#0085cc;
}
.disabled
From 13d53e52d8f92574dcab91aef9f0014145954349 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Mon, 15 Jul 2013 16:31:57 +1000
Subject: [PATCH 078/184] rhbz980658 rearrange source upload method to prepare
for better structuring
---
.../org/zanata/rest/service/FileService.java | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 9db2284135..53151331b6 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -183,6 +183,16 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
Optional tempFile;
int totalChunks;
+ if (!uploadForm.getLast())
+ {
+ HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE, uploadForm);
+ totalChunks = upload.getParts().size();
+ return Response.status(Status.ACCEPTED)
+ .entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
+ "Chunk accepted, awaiting remaining chunks."))
+ .build();
+ }
+
if (isSinglePart(uploadForm))
{
totalChunks = 1;
@@ -192,13 +202,6 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
{
HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE, uploadForm);
totalChunks = upload.getParts().size();
- if (!uploadForm.getLast())
- {
- return Response.status(Status.ACCEPTED)
- .entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
- "Chunk accepted, awaiting remaining chunks."))
- .build();
- }
tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload));
}
@@ -398,7 +401,7 @@ private File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload)
return tempFile;
}
- private boolean isSinglePart(DocumentFileUploadForm uploadForm)
+ private static boolean isSinglePart(DocumentFileUploadForm uploadForm)
{
return uploadForm.getFirst() && uploadForm.getLast();
}
From b9325322bd00c36a903ce2aab1a715ffdaf13aaf Mon Sep 17 00:00:00 2001
From: David Mason
Date: Mon, 15 Jul 2013 16:59:01 +1000
Subject: [PATCH 079/184] rhbz980658 add GlobalDocumentId with tests
---
.../org/zanata/file/GlobalDocumentId.java | 20 ++++++++++
.../org/zanata/rest/service/FileService.java | 4 +-
.../org/zanata/file/GlobalDocumentIdTest.java | 38 +++++++++++++++++++
3 files changed, 61 insertions(+), 1 deletion(-)
create mode 100644 zanata-war/src/main/java/org/zanata/file/GlobalDocumentId.java
create mode 100644 zanata-war/src/test/java/org/zanata/file/GlobalDocumentIdTest.java
diff --git a/zanata-war/src/main/java/org/zanata/file/GlobalDocumentId.java b/zanata-war/src/main/java/org/zanata/file/GlobalDocumentId.java
new file mode 100644
index 0000000000..3e0fae3723
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/file/GlobalDocumentId.java
@@ -0,0 +1,20 @@
+package org.zanata.file;
+
+import lombok.Getter;
+
+@Getter
+public class GlobalDocumentId
+{
+
+ private final String projectSlug;
+ private final String versionSlug;
+ private final String docId;
+
+ public GlobalDocumentId(String projectSlug, String iterationSlug, String docId)
+ {
+ this.projectSlug = projectSlug;
+ this.versionSlug = iterationSlug;
+ this.docId = docId;
+ }
+
+}
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 53151331b6..c5125222a0 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -81,6 +81,7 @@
import org.zanata.exception.HashMismatchException;
import org.zanata.exception.VirusDetectedException;
import org.zanata.exception.ZanataServiceException;
+import org.zanata.file.GlobalDocumentId;
import org.zanata.model.HDocument;
import org.zanata.model.HDocumentUpload;
import org.zanata.model.HDocumentUploadPart;
@@ -178,6 +179,7 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
{
try
{
+ GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm);
Optional tempFile;
@@ -185,7 +187,7 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
if (!uploadForm.getLast())
{
- HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE, uploadForm);
+ HDocumentUpload upload = saveUploadPart(id.getProjectSlug(), id.getVersionSlug(), id.getDocId(), NULL_LOCALE, uploadForm);
totalChunks = upload.getParts().size();
return Response.status(Status.ACCEPTED)
.entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
diff --git a/zanata-war/src/test/java/org/zanata/file/GlobalDocumentIdTest.java b/zanata-war/src/test/java/org/zanata/file/GlobalDocumentIdTest.java
new file mode 100644
index 0000000000..c79d05f168
--- /dev/null
+++ b/zanata-war/src/test/java/org/zanata/file/GlobalDocumentIdTest.java
@@ -0,0 +1,38 @@
+package org.zanata.file;
+
+import static org.hamcrest.MatcherAssert.*;
+import static org.hamcrest.Matchers.*;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+@Test(groups = { "unit-tests" })
+public class GlobalDocumentIdTest
+{
+
+ private static final String PROJECT_SLUG = "project";
+ private static final String VERSION_SLUG = "version";
+ private static final String DOCUMENT_ID = "document";
+
+ private GlobalDocumentId id;
+
+ @BeforeMethod
+ public void setup()
+ {
+ id = new GlobalDocumentId(PROJECT_SLUG, VERSION_SLUG, DOCUMENT_ID);
+ }
+
+ public void getDocId()
+ {
+ assertThat(id.getDocId(), is(DOCUMENT_ID));
+ }
+
+ public void getIterationSlug()
+ {
+ assertThat(id.getVersionSlug(), is(VERSION_SLUG));
+ }
+
+ public void getProjectSlug()
+ {
+ assertThat(id.getProjectSlug(), is(PROJECT_SLUG));
+ }
+}
From b8841539c28ba260c907f0d09e5c8dec0c1ada32 Mon Sep 17 00:00:00 2001
From: Sean Flanigan
Date: Mon, 15 Jul 2013 17:46:40 +1000
Subject: [PATCH 080/184] Update xom version for server
---
pom.xml | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/pom.xml b/pom.xml
index 72d7079998..6a56d6f8e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -505,6 +505,16 @@
test-jar
test
+
+
+ xom
+ xom
+ 1.2.5
+
chrome
+ :0
${project.build.directory}/webdriver.log
@@ -402,7 +403,11 @@
-Dzanata.sample.projects.basedir=${project.build.testOutputDirectory}/sample-projects
-Dcargo.debug.jvm.args : If not set by default will listen to port 8787. Need to set to empty on jenkins
- -Dinclude.test.patterns : by default is **/*TestSuite.java. Can be used to control what test to run.
+ -Dinclude.test.patterns=test filter pattern. Can be used to control what test to run. Default is **/*TestSuite.java.
+ -Dwebdriver.type=run tests in htmlUnit, chrome or firefox. For chrome, see also webdriver.chrome.* Default is htmlUnit.
+ -Dwebdriver.display=display to run test browser in, for Xnest or otherwise. Default is :0.
+ -Dwebdriver.chrome.bin=full path to chrome binary.
+ -Dwebdriver.chrome.driver=full path to chromedriver binary.
==========================================================
diff --git a/functional-test/src/main/java/org/zanata/page/WebDriverFactory.java b/functional-test/src/main/java/org/zanata/page/WebDriverFactory.java
index b08a1ef61f..2d120d3e59 100644
--- a/functional-test/src/main/java/org/zanata/page/WebDriverFactory.java
+++ b/functional-test/src/main/java/org/zanata/page/WebDriverFactory.java
@@ -29,6 +29,7 @@
import java.io.IOException;
import java.util.concurrent.TimeUnit;
+import com.google.common.collect.ImmutableMap;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.firefox.FirefoxBinary;
@@ -105,11 +106,11 @@ private WebDriver configureChromeDriver()
driverService = new ChromeDriverService.Builder()
.usingDriverExecutable(new File(PropertiesHolder.properties.getProperty("webdriver.chrome.driver")))
.usingAnyFreePort()
+ .withEnvironment(ImmutableMap.of("DISPLAY", PropertiesHolder.properties.getProperty("webdriver.display")))
.withLogFile(new File(PropertiesHolder.properties.getProperty("webdriver.log")))
.build();
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability("chrome.binary", PropertiesHolder.properties.getProperty("webdriver.chrome.bin"));
-// System.setProperty("webdriver.chrome.driver", properties.getProperty("webdriver.chrome.driver"));
try
{
driverService.start();
@@ -134,11 +135,13 @@ private WebDriver configureFirefoxDriver()
{
firefoxBinary = new FirefoxBinary();
}
- //we timeout the connection in 10 seconds
-// firefoxBinary.setTimeout(SECONDS.toMillis(10));
-
+ /*
+ * TODO: Evaluate current timeout
+ * Timeout the connection in 30 seconds
+ * firefoxBinary.setTimeout(TimeUnit.SECONDS.toMillis(30));
+ */
+ firefoxBinary.setEnvironmentProperty("DISPLAY", PropertiesHolder.properties.getProperty("webdriver.display"));
return new FirefoxDriver(firefoxBinary, makeFirefoxProfile());
-// return new FirefoxDriver();
}
private FirefoxProfile makeFirefoxProfile()
@@ -149,12 +152,16 @@ private FirefoxProfile makeFirefoxProfile()
// TODO - look at FirefoxDriver.getProfile().
}
final FirefoxProfile firefoxProfile = new FirefoxProfile();
- // firefoxProfile.setPreference("browser.safebrowsing.malware.enabled",
- // false); // disables connection to sb-ssl.google.com
+
+ /*
+ * TODO: Evaluate need for this
+ * Disable unnecessary connection to sb-ssl.google.com
+ * firefoxProfile.setPreference("browser.safebrowsing.malware.enabled", false);
+ */
+
firefoxProfile.setAlwaysLoadNoFocusLib(true);
firefoxProfile.setEnableNativeEvents(true);
firefoxProfile.setAcceptUntrustedCertificates(true);
-// firefoxProfile.setPort(8000);
return firefoxProfile;
}
diff --git a/functional-test/src/test/resources/setup.properties b/functional-test/src/test/resources/setup.properties
index dbc26a0322..072e2be2d1 100644
--- a/functional-test/src/test/resources/setup.properties
+++ b/functional-test/src/test/resources/setup.properties
@@ -6,7 +6,7 @@ webdriver.chrome.driver=${webdriver.chrome.driver}
#this decides what web driver type we intended to use.
webdriver.type=${webdriver.type}
webdriver.log=${webdriver.log}
-
+webdriver.display=${webdriver.display}
zanata.instance.url=${zanata.instance.url}
zanata.sample.projects.basedir=${zanata.sample.projects.basedir}
zanata.apikey=${zanata.apikey}
From 49e1ee4df6a4a98a1dd6ab0bdd433665691d6144 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Tue, 16 Jul 2013 11:44:28 +1000
Subject: [PATCH 089/184] add wait until logic around dynamic field
---
.../administration/ManageUserAccountPage.java | 30 +++++++++++++++----
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java b/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
index 0368fb4cc1..1c005b80b9 100644
--- a/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
+++ b/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
@@ -28,6 +28,7 @@
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.zanata.page.AbstractPage;
+import com.google.common.base.Predicate;
/**
* @author Damian Jansen djansen@redhat.com
@@ -36,9 +37,6 @@
public class ManageUserAccountPage extends AbstractPage
{
- @FindBy(id = "userdetailForm:usernameField:username")
- private WebElement usernameField;
-
@FindBy(id = "userdetailForm:passwordField:password")
private WebElement passwordField;
@@ -56,6 +54,9 @@ public class ManageUserAccountPage extends AbstractPage
private Map roleMap;
+ // username field will trigger ajax call and become stale
+ private By usernameBy = By.id("userdetailForm:usernameField:username");
+
public ManageUserAccountPage(WebDriver driver)
{
super(driver);
@@ -67,9 +68,18 @@ public ManageUserAccountPage(WebDriver driver)
roleMap.put("user", "4");
}
- public ManageUserAccountPage enterUsername(String username)
+ public ManageUserAccountPage enterUsername(final String username)
{
- usernameField.sendKeys(username);
+ waitForTenSec().until(new Predicate()
+ {
+ @Override
+ public boolean apply(WebDriver input)
+ {
+ WebElement usernameField = input.findElement(usernameBy);
+ usernameField.sendKeys(username);
+ return input.findElement(usernameBy).getAttribute("value").equals(username);
+ }
+ });
return new ManageUserAccountPage(getDriver());
}
@@ -117,7 +127,15 @@ public ManageUserPage cancelEditUser()
public ManageUserAccountPage clearFields()
{
- usernameField.clear();
+ waitForTenSec().until(new Predicate()
+ {
+ @Override
+ public boolean apply(WebDriver input)
+ {
+ input.findElement(usernameBy).clear();
+ return input.findElement(usernameBy).getAttribute("value").isEmpty();
+ }
+ });
passwordField.clear();
passwordConfirmField.clear();
return new ManageUserAccountPage(getDriver());
From de43f0cad800db9e115b57f7e2fb32e400bcac22 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 12:44:12 +1000
Subject: [PATCH 090/184] strip trailing whitespace and tabs
---
.../ManageLanguageTeamMemberPage.java | 6 +-
.../org/zanata/workflow/LanguageWorkFlow.java | 2 +-
.../ManageUsersDetailedTest.java | 2 +-
.../administration/ManageUsersTest.java | 2 +-
.../java/org/zanata/model/HLocaleMember.java | 16 ++--
.../org/zanata/action/LanguageTeamAction.java | 46 +++++-----
.../main/java/org/zanata/dao/PersonDAO.java | 10 +-
.../presenter/TargetContentsPresenter.java | 8 +-
.../server/rpc/UpdateTransUnitHandler.java | 5 +-
.../shared/model/UserWorkspaceContext.java | 4 +-
.../shared/model/WorkspaceRestrictions.java | 2 +-
.../db/changelogs/db.changelog-3.1.xml | 28 +++---
.../email/email_request_role_language.xhtml | 44 ++++-----
.../email_request_to_join_language.xhtml | 48 +++++-----
zanata-war/src/main/webapp/WEB-INF/pages.xml | 8 +-
.../src/main/webapp/WEB-INF/urlrewrite.xml | 2 +-
.../src/main/webapp/iteration/files.xhtml | 5 +-
.../src/main/webapp/language/language.xhtml | 91 +++++++++----------
.../request_to_join_update_role.xhtml | 50 +++++-----
.../src/main/webapp/project/project.xhtml | 1 -
20 files changed, 186 insertions(+), 194 deletions(-)
diff --git a/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java b/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java
index 311d2d7c44..bd5e98499d 100644
--- a/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java
+++ b/functional-test/src/main/java/org/zanata/page/administration/ManageLanguageTeamMemberPage.java
@@ -133,16 +133,16 @@ public ManageLanguageTeamMemberPage addToTeam(TableRow personRow)
log.info("username to be added: {}", personUsername);
WebElement selectRowToUpdateCell = personRow.getCells().get(SEARCH_RESULT_SELECTED_COLUMN).findElement(By.tagName("input"));
WebElement isTranslatorCell = personRow.getCells().get(ISTRANSLATOR_COLUMN).findElement(By.tagName("input"));
-
+
if (!isTranslatorCell.isSelected())
{
if(!selectRowToUpdateCell.isSelected())
{
selectRowToUpdateCell.click();
}
-
+
isTranslatorCell.click();
-
+
WebElement addButton = getDriver().findElement(By.id("resultForm:addSelectedBtn"));
addButton.click();
WebElement closeButton = getDriver().findElement(By.id("searchForm:closeBtn"));
diff --git a/functional-test/src/main/java/org/zanata/workflow/LanguageWorkFlow.java b/functional-test/src/main/java/org/zanata/workflow/LanguageWorkFlow.java
index 0ef427c4a6..df771f04ae 100644
--- a/functional-test/src/main/java/org/zanata/workflow/LanguageWorkFlow.java
+++ b/functional-test/src/main/java/org/zanata/workflow/LanguageWorkFlow.java
@@ -44,7 +44,7 @@ public void addLanguageAndJoin(String localeId)
log.warn("admin has already joined the language [{}]", localeId);
}
}
-
+
public ManageLanguagePage addLanguage(String localeId)
{
ManageLanguagePage manageLanguagePage = goToHome().goToAdministration().goToManageLanguagePage();
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
index 829831eb00..c4aa1df771 100644
--- a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
@@ -49,7 +49,7 @@ public void changeAUsersUsername()
{
String username = "administratornamechange";
ManageUserPage manageUserPage = homePage.goToAdministration().goToManageUserPage();
-
+
ManageUserAccountPage manageUserAccountPage = manageUserPage.editUserAccount("admin");
manageUserPage = manageUserAccountPage.clearAndEnterUsername(username).saveUser();
assertThat("Administrator is displayed", manageUserPage.getUserList(), Matchers.hasItem(username));
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
index 44dcf06271..cb3b83ae16 100644
--- a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
@@ -67,7 +67,7 @@ public ManageUserPage changeUsernameAndPassword(ManageUserAccountPage manageUser
.clearAndEnterPassword(newPassword)
.clearAndEnterConfirmPassword(newPassword)
.saveUser();
-
+
return page;
}
diff --git a/zanata-model/src/main/java/org/zanata/model/HLocaleMember.java b/zanata-model/src/main/java/org/zanata/model/HLocaleMember.java
index c1b405a7cc..26eebb6802 100644
--- a/zanata-model/src/main/java/org/zanata/model/HLocaleMember.java
+++ b/zanata-model/src/main/java/org/zanata/model/HLocaleMember.java
@@ -50,15 +50,13 @@
public class HLocaleMember implements Serializable
{
private static final long serialVersionUID = 1L;
-
+
private HLocaleMemberPk id = new HLocaleMemberPk();
-
+
private boolean isCoordinator;
-
private boolean isReviewer;
-
private boolean isTranslator;
-
+
public HLocaleMember( HPerson person, HLocale supportedLanguage, boolean isTranslator, boolean isReviewer, boolean isCoordinator)
{
id.setPerson(person);
@@ -67,13 +65,13 @@ public HLocaleMember( HPerson person, HLocale supportedLanguage, boolean isTrans
setReviewer(isReviewer);
setCoordinator(isCoordinator);
}
-
+
@EmbeddedId
protected HLocaleMemberPk getId()
{
return id;
}
-
+
protected void setId(HLocaleMemberPk id)
{
this.id = id;
@@ -84,13 +82,13 @@ public boolean isCoordinator()
{
return isCoordinator;
}
-
+
@Column(name="isReviewer")
public boolean isReviewer()
{
return isReviewer;
}
-
+
@Column(name="isTranslator")
public boolean isTranslator()
{
diff --git a/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java b/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java
index fa94863cda..2d4f1ebacb 100644
--- a/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/LanguageTeamAction.java
@@ -52,28 +52,28 @@
public class LanguageTeamAction implements Serializable
{
private static final long serialVersionUID = 1L;
-
+
@In
private LanguageTeamService languageTeamServiceImpl;
-
+
@In
private LocaleDAO localeDAO;
@In
private LocaleMemberDAO localeMemberDAO;
-
+
@In
private PersonDAO personDAO;
-
+
@In
private LocaleService localeServiceImpl;
-
+
@In(required = false, value = JpaIdentityStore.AUTHENTICATED_USER)
HAccount authenticatedAccount;
-
+
@Logger
Log log;
-
+
private String language;
private String searchTerm;
private List searchResults;
@@ -88,7 +88,7 @@ public void setLanguage(String language)
{
this.language = language;
}
-
+
public String getSearchTerm()
{
return searchTerm;
@@ -105,7 +105,7 @@ public List getSearchResults()
{
searchResults = new ArrayList();
}
-
+
return searchResults;
}
@@ -113,7 +113,7 @@ public boolean isUserInTeam()
{
return authenticatedAccount != null && this.isPersonInTeam( this.authenticatedAccount.getId() );
}
-
+
public void selectAll()
{
for (SelectablePerson selectablePerson : getSearchResults())
@@ -124,7 +124,7 @@ public void selectAll()
}
}
}
-
+
@Restrict("#{s:hasPermission(languageTeamAction.locale, 'manage-language-team')}")
public void addSelected()
{
@@ -197,7 +197,7 @@ public void leaveTribe()
log.info("{0} left tribe {1}", authenticatedAccount.getUsername(), this.language);
FacesMessages.instance().add("You have left the {0} language team", getLocale().retrieveNativeName());
}
-
+
@Restrict("#{s:hasPermission(languageTeamAction.locale, 'manage-language-team')}")
public void saveTeamCoordinator( HLocaleMember member )
{
@@ -212,7 +212,7 @@ public void saveTeamCoordinator( HLocaleMember member )
FacesMessages.instance().add("{0} has been removed from as Team Coordinators", member.getPerson().getAccount().getUsername());
}
}
-
+
@Restrict("#{s:hasPermission(languageTeamAction.locale, 'manage-language-team')}")
public void saveTeamReviewer( HLocaleMember member )
{
@@ -227,7 +227,7 @@ public void saveTeamReviewer( HLocaleMember member )
FacesMessages.instance().add("{0} has been removed from as Team Reviewer", member.getPerson().getAccount().getUsername());
}
}
-
+
@Restrict("#{s:hasPermission(languageTeamAction.locale, 'manage-language-team')}")
public void saveTeamTranslator( HLocaleMember member )
{
@@ -253,7 +253,7 @@ public void removeMembership( HLocaleMember member )
{
this.languageTeamServiceImpl.leaveLanguageTeam(this.language, member.getPerson().getId());
}
-
+
public boolean isPersonInTeam( final Long personId )
{
for( HLocaleMember lm : getLocale().getMembers() )
@@ -265,7 +265,7 @@ public boolean isPersonInTeam( final Long personId )
}
return false;
}
-
+
private HLocaleMember getLocaleMember( final Long personId )
{
for( HLocaleMember lm : getLocale().getMembers() )
@@ -277,7 +277,7 @@ private HLocaleMember getLocaleMember( final Long personId )
}
return null;
}
-
+
public void searchForTeamMembers()
{
getSearchResults().clear();
@@ -299,7 +299,7 @@ public void searchForTeamMembers()
getSearchResults().add(new SelectablePerson(person, isMember, isTranslator, isReviewer, isCoordinator));
}
}
-
+
public boolean isSelectAll()
{
return selectAll;
@@ -309,16 +309,16 @@ public void setSelectAll(boolean selectAll)
{
this.selectAll = selectAll;
}
-
+
public final class SelectablePerson
{
private HPerson person;
private boolean selected;
-
+
private boolean isReviewer;
private boolean isCoordinator;
private boolean isTranslator;
-
+
public SelectablePerson(HPerson person, boolean selected, boolean isTranslator, boolean isReviewer, boolean isCoordinator)
{
this.person = person;
@@ -357,7 +357,7 @@ public void setTranslator(boolean isTranslator)
{
this.isTranslator = isTranslator;
}
-
+
public HPerson getPerson()
{
return person;
@@ -375,5 +375,5 @@ public void setSelected(boolean selected)
this.selected = selected;
}
}
-
+
}
diff --git a/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java b/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
index 24b4abe547..1f380a7ad7 100644
--- a/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
+++ b/zanata-war/src/main/java/org/zanata/dao/PersonDAO.java
@@ -93,7 +93,7 @@ public HPerson findByUsername(String username)
query.setComment("PersonDAO.findByUsername");
return (HPerson) query.uniqueResult();
}
-
+
public String findEmail(String username)
{
Query query = getSession().createQuery("select p.email from HPerson as p where p.account.username = :username");
@@ -143,7 +143,7 @@ public boolean isUserInLanguageTeamWithRoles(HPerson person, HLocale language, B
sb.append("select count(*) from HLocaleMember where ");
sb.append("id.person = :person ");
sb.append("and id.supportedLanguage = :language ");
-
+
if(isTranslator != null)
{
sb.append("and translator = :isTranslator ");
@@ -156,11 +156,11 @@ public boolean isUserInLanguageTeamWithRoles(HPerson person, HLocale language, B
{
sb.append("and coordinator = :isCoordinator ");
}
-
+
Query q = getSession().createQuery(sb.toString().trim())
.setParameter("person", person)
.setParameter("language", language);
-
+
if(isTranslator != null)
{
q.setParameter("isTranslator", isTranslator.booleanValue());
@@ -173,7 +173,7 @@ public boolean isUserInLanguageTeamWithRoles(HPerson person, HLocale language, B
{
q.setParameter("isCoordinator", isCoordinator.booleanValue());
}
-
+
q.setCacheable(false).setComment("PersonDAO.isUserInLanguageTeamWithRoles");
Long totalCount = (Long) q.uniqueResult();
return totalCount > 0L;
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 cbc7f7942a..6200dbd149 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
@@ -598,16 +598,16 @@ public void onWorkspaceContextUpdated(WorkspaceContextUpdateEvent event)
// FIXME once setting codemirror editor to readonly it won't be editable again
userWorkspaceContext.setProjectActive(event.isProjectActive());
userWorkspaceContext.getWorkspaceContext().getWorkspaceId().getProjectIterationId().setProjectType(event.getProjectType());
-
+
for (TargetContentsDisplay targetContentsDisplay : displayList)
{
ViewMode viewMode = canEditTranslation() ? ViewMode.EDIT : ViewMode.VIEW;
boolean showButtons = userWorkspaceContext.hasReadOnlyAccess() ? false : isDisplayButtons();
-
+
targetContentsDisplay.setToMode(viewMode);
targetContentsDisplay.showButtons(showButtons);
}
-
+
if (userWorkspaceContext.hasReadOnlyAccess())
{
concealDisplay();
@@ -673,7 +673,7 @@ public boolean canReview()
WorkspaceRestrictions restrictions = userWorkspaceContext.getWorkspaceRestrictions();
return restrictions.isHasReviewAccess() && restrictions.isProjectRequireReview();
}
-
+
@Override
public boolean canEditTranslation()
{
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateTransUnitHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateTransUnitHandler.java
index fac9640a93..f925d77750 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateTransUnitHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateTransUnitHandler.java
@@ -67,7 +67,7 @@ public class UpdateTransUnitHandler extends AbstractActionHandler
- Add a flag indicating when a member of a Language team (locale) is a team reviewer.
-
-
-
-
-
+ Add a flag indicating when a member of a Language team (locale) is a team reviewer.
+
+
+
+
+
-
+
- Add a flag indicating when a member of a Language team (locale) is a team translator.
-
-
-
-
-
+ Add a flag indicating when a member of a Language team (locale) is a team translator.
+
+
+
+
+
-
+
Make current locale members and coordinator as translator
diff --git a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml
index 7ccb8e31e7..0ba2c06398 100644
--- a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml
+++ b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_role_language.xhtml
@@ -15,30 +15,30 @@
#{messages['jsf.email.coordinator.DearCoordinator']}
-
+
- #{messages['jsf.email.rolerequest.UserRequestingRole']}
-
-
-
- #{messages['jsf.Translator']}
-
-
-
-
-
- #{messages['jsf.Reviewer']}
-
-
-
-
-
- #{messages['jsf.Coordinator']}
-
-
-
+ #{messages['jsf.email.rolerequest.UserRequestingRole']}
+
+
+
+ #{messages['jsf.Translator']}
+
+
+
+
+
+ #{messages['jsf.Reviewer']}
+
+
+
+
+
+ #{messages['jsf.Coordinator']}
+
+
+
-
+
#{messages['jsf.email.UserMessageIntro']}
diff --git a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
index 82dde18481..b65a9da719 100644
--- a/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
+++ b/zanata-war/src/main/webapp/WEB-INF/facelets/email/email_request_to_join_language.xhtml
@@ -16,31 +16,31 @@
#{messages['jsf.email.coordinator.DearCoordinator']}
- #{messages['jsf.email.joinrequest.UserRequestingToJoin']}
-
- #{messages['jsf.email.joinrequest.RoleRequested']}
-
-
-
- #{messages['jsf.Translator']}
-
-
-
-
-
- #{messages['jsf.Reviewer']}
-
-
-
-
-
- #{messages['jsf.Coordinator']}
-
-
-
-
+ #{messages['jsf.email.joinrequest.UserRequestingToJoin']}
+
+ #{messages['jsf.email.joinrequest.RoleRequested']}
+
+
+
+ #{messages['jsf.Translator']}
+
+
+
+
+
+ #{messages['jsf.Reviewer']}
+
+
+
+
+
+ #{messages['jsf.Coordinator']}
+
+
+
+
-
+
#{messages['jsf.email.UserMessageIntro']}
diff --git a/zanata-war/src/main/webapp/WEB-INF/pages.xml b/zanata-war/src/main/webapp/WEB-INF/pages.xml
index 81fa26b6ad..47e429b5e3 100644
--- a/zanata-war/src/main/webapp/WEB-INF/pages.xml
+++ b/zanata-war/src/main/webapp/WEB-INF/pages.xml
@@ -864,7 +864,7 @@
-
+
@@ -874,11 +874,11 @@
-
+
-
+
@@ -893,7 +893,7 @@
-
+
diff --git a/zanata-war/src/main/webapp/WEB-INF/urlrewrite.xml b/zanata-war/src/main/webapp/WEB-INF/urlrewrite.xml
index 5300e45a63..2961595d9c 100644
--- a/zanata-war/src/main/webapp/WEB-INF/urlrewrite.xml
+++ b/zanata-war/src/main/webapp/WEB-INF/urlrewrite.xml
@@ -41,7 +41,7 @@
^/language/join/(.+)$
/language/request_to_join_update_role.seam\?emailType=request_to_join_update_role_language&id=$1
-
+
/language/contact/(.+)$
/language/contact_coordinator.seam\?emailType=contact_coordinator&id=$1
diff --git a/zanata-war/src/main/webapp/iteration/files.xhtml b/zanata-war/src/main/webapp/iteration/files.xhtml
index eb5c02c522..6b719e42a0 100644
--- a/zanata-war/src/main/webapp/iteration/files.xhtml
+++ b/zanata-war/src/main/webapp/iteration/files.xhtml
@@ -117,8 +117,6 @@
-
-
@@ -139,7 +137,6 @@
-
#{messages['jsf.iteration.files.Download']}
@@ -274,7 +271,7 @@
#{messages['jsf.Open']}
-
+
diff --git a/zanata-war/src/main/webapp/language/language.xhtml b/zanata-war/src/main/webapp/language/language.xhtml
index abc2f3e001..d06592256a 100644
--- a/zanata-war/src/main/webapp/language/language.xhtml
+++ b/zanata-war/src/main/webapp/language/language.xhtml
@@ -47,7 +47,7 @@
#{messages['jsf.Email']}
#{member.person.email}
-
+
#{messages['jsf.Translator']}
-
+
#{messages['jsf.Reviewer']}
-
+
#{messages['jsf.Coordinator']}
-
+
#{messages['jsf.Actions']}
@@ -106,15 +106,15 @@
-
-
-
+ rendered="#{identity.loggedIn and not languageTeamAction.isUserInTeam()}">
+
+
+
-
-
-
+ rendered="#{identity.loggedIn and languageTeamAction.isUserInTeam() and !(s:hasPermission(languageTeamAction.locale, 'manage-language-team'))}">
+
+
+
@@ -140,60 +140,59 @@
onclick="#{rich:component('userAddPanel')}.hide(); return false;" />
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
#{messages['jsf.Name']}
- #{selectablePerson.person.name}
+ #{selectablePerson.person.name}
-
+
#{messages['jsf.Username']}
- #{selectablePerson.person.account.username}
+ #{selectablePerson.person.account.username}
-
-
-
- #{messages['jsf.Translator']}
-
-
-
-
- #{messages['jsf.Reviewer']}
-
-
-
-
- #{messages['jsf.Coordinator']}
-
-
-
+
+
+ #{messages['jsf.Translator']}
+
+
+
+
+ #{messages['jsf.Reviewer']}
+
+
+
+
+ #{messages['jsf.Coordinator']}
+
+
+
-
-
+
+
diff --git a/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml b/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml
index 88d624c80f..a2036f729f 100644
--- a/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml
+++ b/zanata-war/src/main/webapp/language/request_to_join_update_role.xhtml
@@ -16,25 +16,25 @@
-
- #{messages['jsf.RequestRoleAs']}
-
-
-
- #{messages['jsf.Translator']}
-
-
-
-
- #{messages['jsf.Reviewer']}
-
-
-
-
- #{messages['jsf.Coordinator']}
-
-
-
+
+ #{messages['jsf.RequestRoleAs']}
+
+
+
+ #{messages['jsf.Translator']}
+
+
+
+
+ #{messages['jsf.Reviewer']}
+
+
+
+
+ #{messages['jsf.Coordinator']}
+
+
+
#{messages['jsf.email.From']}
#{messages['jsf.email.ReplyAddress']} #{messages['jsf.email.ReplyAddress.description']}
-
+
#{messages['jsf.email.Subject']}
@@ -55,11 +55,11 @@
#{messages['jsf.AdditionalInfo']}
-
- #{messages['jsf.email.AdditionalInfoMessage']}
-
-
-
+
+ #{messages['jsf.email.AdditionalInfoMessage']}
+
+
+
-
From 35dc682a178d8fe7c210380eb9d500ee1c47f9ec Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 12:46:37 +1000
Subject: [PATCH 091/184] remove apparent accidental paste
---
.../org/zanata/feature/administration/ManageUsers.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html b/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html
index 0d989efa88..5d3a54a540 100644
--- a/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html
+++ b/functional-test/src/test/resources/concordion/org/zanata/feature/administration/ManageUsers.html
@@ -1,4 +1,4 @@
-ManageUsers
+
User Administration
From 32123ed8ea58732493ead21b3362ca1039dff617 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 12:49:20 +1000
Subject: [PATCH 092/184] revert ManageUserAccountPage methods to prevent
instability in Chrome
---
.../zanata/page/administration/ManageUserAccountPage.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java b/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
index ef410209aa..7285637a4f 100644
--- a/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
+++ b/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
@@ -87,15 +87,17 @@ public ManageUserAccountPage clearAndEnterConfirmPassword(String confirmPassword
return new ManageUserAccountPage(getDriver());
}
- public void clickEnabled()
+ public ManageUserAccountPage clickEnabled()
{
enabledField.click();
+ return new ManageUserAccountPage(getDriver());
}
- public void clickRole(String role)
+ public ManageUserAccountPage clickRole(String role)
{
WebElement roleBox = getDriver().findElement(By.id("userdetailForm:rolesField:roles:".concat(roleMap.get(role))));
roleBox.click();
+ return new ManageUserAccountPage(getDriver());
}
public boolean isRoleChecked(String role)
From 5e14a3aa273ab88da92585b25ca37b8eb2c12a78 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 14:26:04 +1000
Subject: [PATCH 093/184] move virus scan exception handling to lower level
---
.../org/zanata/rest/service/FileService.java | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index c5125222a0..9c5b66acee 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -232,13 +232,6 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
.entity(new ChunkUploadResponse(e.getMessage()))
.build();
}
- catch (VirusDetectedException e)
- {
- log.warn("File failed virus scan: {}", e.getMessage());
- return Response.status(Status.BAD_REQUEST)
- .entity(new ChunkUploadResponse("uploaded file did not pass virus scan"))
- .build();
- }
catch (ChunkUploadException e)
{
return Response.status(e.getStatusCode())
@@ -322,7 +315,15 @@ private void processAdapterFile(@Nonnull File tempFile, String projectSlug, Stri
String docId, DocumentFileUploadForm uploadForm) throws VirusDetectedException
{
String name = projectSlug+":"+iterationSlug+":"+docId;
- virusScanner.scan(tempFile, name);
+ try
+ {
+ virusScanner.scan(tempFile, name);
+ }
+ catch (VirusDetectedException e)
+ {
+ log.warn("File failed virus scan: {}", e.getMessage());
+ throw new ChunkUploadException(Status.BAD_REQUEST, "Uploaded file did not pass virus scan");
+ }
HDocument document;
Optional params;
From 1cc81e267aafd4d2d419b3cccc17fc80f53af319 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 14:34:51 +1000
Subject: [PATCH 094/184] move source upload authorization exception handling
to lower level
---
.../org/zanata/rest/service/FileService.java | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 9c5b66acee..bc51e525eb 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -226,12 +226,6 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
}
return sourceUploadSuccessResponse(isNewDocument(projectSlug, iterationSlug, docId), totalChunks);
}
- catch (AuthorizationException e)
- {
- return Response.status(Status.UNAUTHORIZED)
- .entity(new ChunkUploadResponse(e.getMessage()))
- .build();
- }
catch (ChunkUploadException e)
{
return Response.status(e.getStatusCode())
@@ -260,8 +254,15 @@ private InputStream getInputStream(Optional tempFile, DocumentFileUploadFo
private void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
{
- checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm);
- checkSourceUploadAllowed(projectSlug, iterationSlug);
+ try
+ {
+ checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm);
+ checkSourceUploadAllowed(projectSlug, iterationSlug);
+ }
+ catch (AuthorizationException e)
+ {
+ throw new ChunkUploadException(Status.UNAUTHORIZED, e.getMessage());
+ }
checkValidSourceUploadType(uploadForm);
}
From 34969b3a997db7cdfebb28c2d677c0223eac175c Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 15:23:05 +1000
Subject: [PATCH 095/184] sort eclipse formatting rules to enhance future diffs
---
.../eclipse-code-formatter-profile.xml | 514 +++++++++---------
1 file changed, 257 insertions(+), 257 deletions(-)
diff --git a/zanata-war/eclipse/eclipse-code-formatter-profile.xml b/zanata-war/eclipse/eclipse-code-formatter-profile.xml
index 2aa99463a2..1984964d29 100644
--- a/zanata-war/eclipse/eclipse-code-formatter-profile.xml
+++ b/zanata-war/eclipse/eclipse-code-formatter-profile.xml
@@ -1,291 +1,291 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 8fa963db059beebc9ec37088ba17c88825b5e34f Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 15:40:43 +1000
Subject: [PATCH 096/184] remove obsolete throws declaration
---
.../src/main/java/org/zanata/rest/service/FileService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index bc51e525eb..50339b9d4d 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -313,7 +313,7 @@ private File persistTempFileFromUpload(DocumentFileUploadForm uploadForm)
}
private void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm) throws VirusDetectedException
+ String docId, DocumentFileUploadForm uploadForm)
{
String name = projectSlug+":"+iterationSlug+":"+docId;
try
From 6e92450179a66558218cce97fc32b2e455172c01 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 15:54:37 +1000
Subject: [PATCH 097/184] Extract methods for source and target document
upload.
This is a preliminary step in moving this code into separate classes.
---
.../java/org/zanata/rest/service/FileService.java | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 50339b9d4d..967c8affb0 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -176,6 +176,11 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
@PathParam("iterationSlug") String iterationSlug,
@QueryParam("docId") String docId,
@MultipartForm DocumentFileUploadForm uploadForm )
+ {
+ return tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm);
+ }
+
+ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
{
try
{
@@ -628,6 +633,11 @@ public Response uploadTranslationFile( @PathParam("projectSlug") String projectS
@QueryParam("docId") String docId,
@QueryParam("merge") String merge,
@MultipartForm DocumentFileUploadForm uploadForm )
+ {
+ return tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm);
+ }
+
+ private Response tryUploadTranslationFile(String projectSlug, String iterationSlug, String docId, String localeId, String mergeType, DocumentFileUploadForm uploadForm)
{
HLocale locale;
try
@@ -683,7 +693,7 @@ public Response uploadTranslationFile( @PathParam("projectSlug") String projectS
Set extensions = newExtensions(uploadForm.getFileType().equals(".po"));
// TODO useful error message for failed saving?
List warnings = translationServiceImpl.translateAllInDoc(projectSlug, iterationSlug,
- docId, locale.getLocaleId(), transRes, extensions, mergeTypeFromString(merge));
+ docId, locale.getLocaleId(), transRes, extensions, mergeTypeFromString(mergeType));
return transUploadResponse(totalChunks, warnings);
}
From 447bc0960c984188a110890d391a3a06b73bb3bb Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:06:58 +1000
Subject: [PATCH 098/184] make FileService.isNewDocument static (mikado method)
---
.../main/java/org/zanata/rest/service/FileService.java | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 967c8affb0..2081972622 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -229,7 +229,7 @@ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, S
{
tempFile.get().delete();
}
- return sourceUploadSuccessResponse(isNewDocument(projectSlug, iterationSlug, docId), totalChunks);
+ return sourceUploadSuccessResponse(isNewDocument(projectSlug, iterationSlug, docId, documentDAO), totalChunks);
}
catch (ChunkUploadException e)
{
@@ -417,12 +417,12 @@ private static boolean isSinglePart(DocumentFileUploadForm uploadForm)
private boolean useOfflinePo(String projectSlug, String iterationSlug, String docId)
{
- return !isNewDocument(projectSlug, iterationSlug, docId) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
+ return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
}
- private boolean isNewDocument(String projectSlug, String iterationSlug, String docId)
+ private static boolean isNewDocument(String projectSlug, String iterationSlug, String docId, DocumentDAO dao)
{
- return documentDAO.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId) == null;
+ return dao.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId) == null;
}
private File combineToTempFile(HDocumentUpload upload) throws SQLException
@@ -840,7 +840,7 @@ private void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm)
private void checkDocumentExists(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
{
- if (isNewDocument(projectSlug, iterationSlug, docId))
+ if (isNewDocument(projectSlug, iterationSlug, docId, documentDAO))
{
throw new ChunkUploadException(Status.NOT_FOUND,
"No document with id \"" + docId + "\" exists in project-version \"" +
From 1c9ccda72b242b6baa25b47001cc1fd36a7aa019 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:07:59 +1000
Subject: [PATCH 099/184] make FileService.sourceUploadSuccessResponse static
(mikado method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 2081972622..78eb135ac7 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -598,7 +598,7 @@ private void parsePotFile(InputStream documentStream, String docId, String fileT
documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, new StringSet(ExtensionType.GetText.toString()), false);
}
- private Response sourceUploadSuccessResponse(boolean isNewDocument, int acceptedChunks)
+ private static Response sourceUploadSuccessResponse(boolean isNewDocument, int acceptedChunks)
{
Response response;
ChunkUploadResponse uploadResponse = new ChunkUploadResponse();
From b4f1a974bf563a0ad6a21b772142b36a2a508334 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:09:07 +1000
Subject: [PATCH 100/184] make FileService.getInputStream static (mikado
method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 78eb135ac7..ed16644f0f 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -245,7 +245,7 @@ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, S
}
}
- private InputStream getInputStream(Optional tempFile, DocumentFileUploadForm uploadForm) throws FileNotFoundException
+ private static InputStream getInputStream(Optional tempFile, DocumentFileUploadForm uploadForm) throws FileNotFoundException
{
if (tempFile.isPresent())
{
From cc628afc49511a9c2eaf4e68fa258f8a2dac658f Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:13:49 +1000
Subject: [PATCH 101/184] make FileService.combineToTempFile static (mikado
method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index ed16644f0f..ad4de4ee58 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -388,7 +388,7 @@ private File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload)
File tempFile;
try
{
- tempFile = combineToTempFile(upload);
+ tempFile = combineToTempFile(upload, translationFileServiceImpl);
}
catch (HashMismatchException e)
{
@@ -425,7 +425,7 @@ private static boolean isNewDocument(String projectSlug, String iterationSlug, S
return dao.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId) == null;
}
- private File combineToTempFile(HDocumentUpload upload) throws SQLException
+ private static File combineToTempFile(HDocumentUpload upload, TranslationFileService service) throws SQLException
{
Vector partStreams = new Vector();
for (HDocumentUploadPart part : upload.getParts())
@@ -445,7 +445,7 @@ private File combineToTempFile(HDocumentUpload upload) throws SQLException
}
InputStream combinedParts = new SequenceInputStream(partStreams.elements());
combinedParts = new DigestInputStream(combinedParts, md);
- File tempFile = translationFileServiceImpl.persistToTempFile(combinedParts);
+ File tempFile = service.persistToTempFile(combinedParts);
String md5hash = new String(Hex.encodeHex(md.digest()));
if (!md5hash.equals(upload.getContentHash()))
From a1f58b7d8c2983b853976a081a6bc3b78f7bf21f Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:18:47 +1000
Subject: [PATCH 102/184] make
FileService.combineToTempFileAndDeleteUploadRecord static (mikado method)
---
.../main/java/org/zanata/rest/service/FileService.java | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index ad4de4ee58..c44ff41df9 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -209,7 +209,7 @@ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, S
{
HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE, uploadForm);
totalChunks = upload.getParts().size();
- tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload));
+ tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
}
if (uploadForm.getFileType().equals(".pot"))
@@ -383,12 +383,13 @@ private void processAdapterFile(@Nonnull File tempFile, String projectSlug, Stri
translationFileServiceImpl.removeTempFile(tempFile);
}
- private File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload)
+ private static File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload, Session session,
+ TranslationFileService transFileService)
{
File tempFile;
try
{
- tempFile = combineToTempFile(upload, translationFileServiceImpl);
+ tempFile = combineToTempFile(upload, transFileService);
}
catch (HashMismatchException e)
{
@@ -665,7 +666,7 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
"Chunk accepted, awaiting remaining chunks."))
.build();
}
- tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload));
+ tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
}
TranslationsResource transRes;
From 44cebb1fab7e5ef541156e433f7ec007ccf4377d Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:23:21 +1000
Subject: [PATCH 103/184] make FileService.persistTempFileFromUpload static
(mikado method)
---
.../main/java/org/zanata/rest/service/FileService.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index c44ff41df9..d36a0b409b 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -221,7 +221,7 @@ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, S
{
if (!tempFile.isPresent())
{
- tempFile = Optional.of(persistTempFileFromUpload(uploadForm));
+ tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
}
processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm);
}
@@ -292,14 +292,14 @@ private void checkValidSourceUploadType(DocumentFileUploadForm uploadForm)
}
}
- private File persistTempFileFromUpload(DocumentFileUploadForm uploadForm)
+ private static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
{
File tempFile;
try
{
MessageDigest md = MessageDigest.getInstance("MD5");
InputStream fileContents = new DigestInputStream(uploadForm.getFileStream(), md);
- tempFile = translationFileServiceImpl.persistToTempFile(fileContents);
+ tempFile = transFileService.persistToTempFile(fileContents);
String md5hash = new String(Hex.encodeHex(md.digest()));
if (!md5hash.equals(uploadForm.getHash()))
{
@@ -679,7 +679,7 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
{
if (!tempFile.isPresent())
{
- tempFile = Optional.of(persistTempFileFromUpload(uploadForm));
+ tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
}
// FIXME this is misusing the 'filename' field. the method should probably take a
// type anyway
From 8c1533f23a786cda2d7b5c02f5c00cd24590f95b Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:31:48 +1000
Subject: [PATCH 104/184] make FileService.isDocumentUploadAllowed and
.checkValidSourceUploadType static (mikado method)
---
.../org/zanata/rest/service/FileService.java | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index d36a0b409b..5163bd82e9 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -268,12 +268,12 @@ private void checkSourceUploadPreconditions(String projectSlug, String iteration
{
throw new ChunkUploadException(Status.UNAUTHORIZED, e.getMessage());
}
- checkValidSourceUploadType(uploadForm);
+ checkValidSourceUploadType(uploadForm, translationFileServiceImpl);
}
private void checkSourceUploadAllowed(String projectSlug, String iterationSlug)
{
- if (!isDocumentUploadAllowed(projectSlug, iterationSlug))
+ if (!isDocumentUploadAllowed(projectSlug, iterationSlug, identity, projectIterationDAO))
{
throw new ChunkUploadException(Status.FORBIDDEN,
"You do not have permission to upload source documents to project-version \""
@@ -281,10 +281,17 @@ private void checkSourceUploadAllowed(String projectSlug, String iterationSlug)
}
}
- private void checkValidSourceUploadType(DocumentFileUploadForm uploadForm)
+ private static boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
+ {
+ HProjectIteration projectIteration = projIterDAO.getBySlug(projectSlug, iterationSlug);
+ return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
+ && identity != null && identity.hasPermission("import-template", projectIteration);
+ }
+
+ private static void checkValidSourceUploadType(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
{
if (!uploadForm.getFileType().equals(".pot")
- && !translationFileServiceImpl.hasAdapterFor(DocumentType.typeFor(uploadForm.getFileType())))
+ && !transFileService.hasAdapterFor(DocumentType.typeFor(uploadForm.getFileType())))
{
throw new ChunkUploadException(Status.BAD_REQUEST,
"The type \"" + uploadForm.getFileType() + "\" specified in form parameter 'type' "
@@ -578,13 +585,6 @@ private void checkUploadPreconditions(String projectSlug, String iterationSlug,
}
}
- private boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug)
- {
- HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
- return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
- && identity != null && identity.hasPermission("import-template", projectIteration);
- }
-
private void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
{
parsePotFile(potStream, docId, uploadForm.getFileType(), projectSlug, iterationSlug, useOfflinePo(projectSlug, iterationSlug, docId));
From 8aa96f2eb3f6c31f2d188a1b4e9f9130debc3ec5 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:33:44 +1000
Subject: [PATCH 105/184] make FileService.checkSourceUploadAllowed static
(mikado method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 5163bd82e9..8d2909f64d 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -262,7 +262,7 @@ private void checkSourceUploadPreconditions(String projectSlug, String iteration
try
{
checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm);
- checkSourceUploadAllowed(projectSlug, iterationSlug);
+ checkSourceUploadAllowed(projectSlug, iterationSlug, identity, projectIterationDAO);
}
catch (AuthorizationException e)
{
@@ -271,9 +271,9 @@ private void checkSourceUploadPreconditions(String projectSlug, String iteration
checkValidSourceUploadType(uploadForm, translationFileServiceImpl);
}
- private void checkSourceUploadAllowed(String projectSlug, String iterationSlug)
+ private static void checkSourceUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
{
- if (!isDocumentUploadAllowed(projectSlug, iterationSlug, identity, projectIterationDAO))
+ if (!isDocumentUploadAllowed(projectSlug, iterationSlug, identity, projIterDAO))
{
throw new ChunkUploadException(Status.FORBIDDEN,
"You do not have permission to upload source documents to project-version \""
From 739237b9e718b074613c4b031873e0c458bcb5fd Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:37:37 +1000
Subject: [PATCH 106/184] make FileService.retrieveUploadObject static (mikado
method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 8d2909f64d..8fd583b76c 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -463,7 +463,7 @@ private static File combineToTempFile(HDocumentUpload upload, TranslationFileSer
return tempFile;
}
- private HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploadForm)
+ private static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploadForm, Session session)
{
// TODO put in DAO
Criteria criteria = session.createCriteria(HDocumentUpload.class);
@@ -529,7 +529,7 @@ private void checkUploadPreconditions(String projectSlug, String iterationSlug,
"Form parameter 'uploadId' must be provided when this is not the first part.");
}
- HDocumentUpload upload = retrieveUploadObject(uploadForm);
+ HDocumentUpload upload = retrieveUploadObject(uploadForm, session);
if (upload == null)
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
@@ -770,7 +770,7 @@ private HDocumentUpload saveUploadPart(String projectSlug, String iterationSlug,
}
else
{
- upload = retrieveUploadObject(uploadForm);
+ upload = retrieveUploadObject(uploadForm, session);
}
saveUploadPart(uploadForm, upload);
return upload;
From f0ad299dc7e2ae35a8f2e8d6a598d2571bb753e8 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:47:12 +1000
Subject: [PATCH 107/184] make FileService.checkUploadPreconditions static
(mikado method)
---
.../main/java/org/zanata/rest/service/FileService.java | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 8fd583b76c..23f7d873a4 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -261,7 +261,7 @@ private void checkSourceUploadPreconditions(String projectSlug, String iteration
{
try
{
- checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm);
+ checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
checkSourceUploadAllowed(projectSlug, iterationSlug, identity, projectIterationDAO);
}
catch (AuthorizationException e)
@@ -495,7 +495,9 @@ private void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentUpload u
session.flush();
}
- private void checkUploadPreconditions(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
+ private static void checkUploadPreconditions(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm, ZanataIdentity identity,
+ ProjectIterationDAO projectIterationDAO, Session session)
{
if (!identity.isLoggedIn())
{
@@ -819,7 +821,7 @@ private HLocale findHLocale(String localeString)
private void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug, String docId, String localeId, DocumentFileUploadForm uploadForm)
{
- checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm);
+ checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
// TODO check translation upload allowed
From c18b33a6de49a1fc4ac0b42b1711d98ef61657a8 Mon Sep 17 00:00:00 2001
From: Damian Jansen
Date: Tue, 16 Jul 2013 16:33:17 +1000
Subject: [PATCH 108/184] Introduce Categories to the functional tests
Categories can be used for sanely filtering test execution.
The Categories of functional tests are:
1. Basic Acceptance Test
2. Detailed Test
3. Concordion Test
Execution of the categories is similar to before, but instead now the
top level suite file can be used, eg.
-Dinclude.test.patterns="**/DetailedTestSuite.java
---
functional-test/pom.xml | 6 +--
.../zanata/feature/AggregateTestSuite.java | 42 +++++++++++++++
.../zanata/feature/BasicAcceptanceTest.java | 33 ++++++++++++
.../feature/BasicAcceptanceTestSuite.java | 34 ++++++++++++
.../org/zanata/feature/ConcordionTest.java | 33 ++++++++++++
.../zanata/feature/ConcordionTestSuite.java | 34 ++++++++++++
.../java/org/zanata/feature/DetailedTest.java | 31 +++++++++++
.../org/zanata/feature/DetailedTestSuite.java | 14 +++++
.../account/InvalidEmailAddressTest.java | 23 ++++++++
...etailedTest.java => RegisterFullTest.java} | 9 ++--
.../feature/account/RegisterTestSuite.java | 6 +--
.../account/UsernameValidationTest.java | 3 ++
.../account/ValidEmailAddressTest.java | 23 ++++++++
.../administration/AdministrationTest.java | 38 +++++++++++++
.../AdministrationTestSuite.java | 28 +++++++---
...iledTest.java => ManageUsersFullTest.java} | 7 ++-
.../administration/ManageUsersTest.java | 3 ++
.../feature/glossary/GlossaryDeleteTest.java | 23 ++++++++
.../feature/glossary/GlossaryPushCSVTest.java | 23 ++++++++
.../feature/glossary/GlossaryPushTest.java | 26 +++++++--
.../zanata/feature/glossary/GlossaryTest.java | 23 ++++++++
.../glossary/InvalidGlossaryPushTest.java | 24 ++++++++-
.../zanata/feature/security/LoginTest.java | 3 ++
.../zanata/feature/security/SecurityTest.java | 25 ++++++++-
.../startNewProject/AddLanguageTest.java | 23 ++++++++
.../startNewProject/CreateNewProjectTest.java | 30 ++++++++---
.../CreateVersionAndAddToProjectTest.java | 23 ++++++++
.../DocumentListInWebTransTest.java | 29 ++++++++--
.../PushPodirPluralProjectTest.java | 54 +++++++++++--------
.../startNewProject/StartNewProjectTest.java | 23 ++++++++
.../TranslatorJoinsLanguageTeamTest.java | 26 +++++++--
.../versionGroup/VersionGroupBasicTest.java | 26 +++++++--
...ledTest.java => VersionGroupFullTest.java} | 32 +++++++++--
.../versionGroup/VersionGroupTest.java | 23 ++++++++
.../versionGroup/VersionGroupTestSuite.java | 12 ++---
35 files changed, 737 insertions(+), 78 deletions(-)
create mode 100644 functional-test/src/test/java/org/zanata/feature/AggregateTestSuite.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/BasicAcceptanceTest.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/BasicAcceptanceTestSuite.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/ConcordionTest.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/ConcordionTestSuite.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/DetailedTest.java
create mode 100644 functional-test/src/test/java/org/zanata/feature/DetailedTestSuite.java
rename functional-test/src/test/java/org/zanata/feature/account/{RegisterDetailedTest.java => RegisterFullTest.java} (96%)
create mode 100644 functional-test/src/test/java/org/zanata/feature/administration/AdministrationTest.java
rename functional-test/src/test/java/org/zanata/feature/administration/{ManageUsersDetailedTest.java => ManageUsersFullTest.java} (93%)
rename functional-test/src/test/java/org/zanata/feature/versionGroup/{VersionGroupDetailedTest.java => VersionGroupFullTest.java} (84%)
diff --git a/functional-test/pom.xml b/functional-test/pom.xml
index de108cc3b1..4c5786fb39 100644
--- a/functional-test/pom.xml
+++ b/functional-test/pom.xml
@@ -62,7 +62,7 @@
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787 -Xnoagent -Djava.compiler=NONE
- **/*TestSuite.java
+ **/AggregateTestSuite.java
@@ -403,8 +403,8 @@
-Dzanata.sample.projects.basedir=${project.build.testOutputDirectory}/sample-projects
-Dcargo.debug.jvm.args : If not set by default will listen to port 8787. Need to set to empty on jenkins
- -Dinclude.test.patterns=test filter pattern. Can be used to control what test to run. Default is **/*TestSuite.java.
- -Dwebdriver.type=run tests in htmlUnit, chrome or firefox. For chrome, see also webdriver.chrome.* Default is htmlUnit.
+ -Dinclude.test.patterns=test filter pattern. Can be used to control what test to run. Default is **/*AggregateTestSuite.java.
+ -Dwebdriver.type=run tests in htmlUnit, chrome or firefox. For chrome, see also webdriver.chrome.* Default is chrome.
-Dwebdriver.display=display to run test browser in, for Xnest or otherwise. Default is :0.
-Dwebdriver.chrome.bin=full path to chrome binary.
-Dwebdriver.chrome.driver=full path to chromedriver binary.
diff --git a/functional-test/src/test/java/org/zanata/feature/AggregateTestSuite.java b/functional-test/src/test/java/org/zanata/feature/AggregateTestSuite.java
new file mode 100644
index 0000000000..3b55438285
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/AggregateTestSuite.java
@@ -0,0 +1,42 @@
+/*
+ * 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.feature;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.zanata.feature.account.RegisterTestSuite;
+import org.zanata.feature.administration.AdministrationTestSuite;
+import org.zanata.feature.glossary.GlossaryTestSuite;
+import org.zanata.feature.security.SecurityTestSuite;
+import org.zanata.feature.startNewProject.CreateSampleProjectTestSuite;
+import org.zanata.feature.versionGroup.VersionGroupTestSuite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ RegisterTestSuite.class,
+ AdministrationTestSuite.class,
+ GlossaryTestSuite.class,
+ SecurityTestSuite.class,
+ CreateSampleProjectTestSuite.class,
+ VersionGroupTestSuite.class
+})
+public class AggregateTestSuite {
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/BasicAcceptanceTest.java b/functional-test/src/test/java/org/zanata/feature/BasicAcceptanceTest.java
new file mode 100644
index 0000000000..9757b57e11
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/BasicAcceptanceTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.feature;
+/**
+ * Interface for the execution of the Basic Acceptance Tests (BAT) category.
+ *
+ * Tests in this category exercise features only so far as to demonstrate that the feature works,
+ * and perhaps have a single handled negative case.
+ * BAT suites should not exceed an agreed interval (e.g. approximately 10 minutes) in order to
+ * maintain a positive GitHub workflow.
+ *
+ * @author Damian Jansen djansen@redhat.com
+ * @see "http://junit.org/javadoc/4.9/org/junit/experimental/categories/Categories.html"
+ */
+public interface BasicAcceptanceTest { }
diff --git a/functional-test/src/test/java/org/zanata/feature/BasicAcceptanceTestSuite.java b/functional-test/src/test/java/org/zanata/feature/BasicAcceptanceTestSuite.java
new file mode 100644
index 0000000000..e45ec8c5cd
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/BasicAcceptanceTestSuite.java
@@ -0,0 +1,34 @@
+/*
+ * 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.feature;
+
+import org.junit.experimental.categories.Categories;
+import org.junit.runner.RunWith;
+
+/**
+ * Extend the full test suite, but filter by the Basic Acceptance Test category
+ *
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Categories.class)
+@Categories.IncludeCategory(BasicAcceptanceTest.class)
+public class BasicAcceptanceTestSuite extends AggregateTestSuite {
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/ConcordionTest.java b/functional-test/src/test/java/org/zanata/feature/ConcordionTest.java
new file mode 100644
index 0000000000..a95ce98556
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/ConcordionTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.feature;
+/**
+ * Interface for the execution of the Concordion Tests category.
+ *
+ * Tests in this category exercise features to a limited point,in order to validate the feature
+ * in a given use case and generate what is, effectively, a user manual.
+ * These tests are of a low priority due to the specific system requirements, e.g. actions which
+ * result in screenshots require a single display environment.
+ *
+ * @author Damian Jansen djansen@redhat.com
+ * @see "http://junit.org/javadoc/4.9/org/junit/experimental/categories/Categories.html"
+ */
+public interface ConcordionTest { }
diff --git a/functional-test/src/test/java/org/zanata/feature/ConcordionTestSuite.java b/functional-test/src/test/java/org/zanata/feature/ConcordionTestSuite.java
new file mode 100644
index 0000000000..8cb327f27d
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/ConcordionTestSuite.java
@@ -0,0 +1,34 @@
+/*
+ * 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.feature;
+
+import org.junit.experimental.categories.Categories;
+import org.junit.runner.RunWith;
+
+/**
+ * Filter by the Concordion Test category
+ *
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Categories.class)
+@Categories.IncludeCategory(ConcordionTest.class)
+public class ConcordionTestSuite extends AggregateTestSuite {
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/DetailedTest.java b/functional-test/src/test/java/org/zanata/feature/DetailedTest.java
new file mode 100644
index 0000000000..563b96be2f
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/DetailedTest.java
@@ -0,0 +1,31 @@
+/*
+ * 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.feature;
+/**
+ * Interface for the execution of the detailed tests category.
+ *
+ * Tests that fall under this category exercise features more so than the Basic Acceptance Tests
+ * (BAT), but are time constrained and are as such not in the "Long" test collection.
+ *
+ * @author Damian Jansen djansen@redhat.com
+ * @see "http://junit.org/javadoc/4.9/org/junit/experimental/categories/Categories.html"
+ */
+public interface DetailedTest { }
diff --git a/functional-test/src/test/java/org/zanata/feature/DetailedTestSuite.java b/functional-test/src/test/java/org/zanata/feature/DetailedTestSuite.java
new file mode 100644
index 0000000000..233e13f4b9
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/DetailedTestSuite.java
@@ -0,0 +1,14 @@
+package org.zanata.feature;
+
+import org.junit.experimental.categories.Categories;
+import org.junit.runner.RunWith;
+
+/**
+ * Extend the full test suite, but filter by the Detailed Test category
+ *
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Categories.class)
+@Categories.IncludeCategory(DetailedTest.class)
+public class DetailedTestSuite extends AggregateTestSuite {
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java b/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java
index e79ffe043e..58365f6fce 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/InvalidEmailAddressTest.java
@@ -1,11 +1,33 @@
+/*
+ * 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.feature.account;
import org.hamcrest.Matchers;
import org.junit.ClassRule;
+import org.junit.experimental.categories.Category;
import org.junit.experimental.theories.DataPoint;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
+import org.zanata.feature.DetailedTest;
import org.zanata.page.account.RegisterPage;
import org.zanata.util.ResetDatabaseRule;
import org.zanata.util.rfc2822.InvalidEmailAddressRFC2822;
@@ -18,6 +40,7 @@
* @author Damian Jansen djansen@redhat.com
*/
@RunWith(Theories.class)
+@Category(DetailedTest.class)
public class InvalidEmailAddressTest {
@ClassRule
public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/account/RegisterFullTest.java
similarity index 96%
rename from functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
rename to functional-test/src/test/java/org/zanata/feature/account/RegisterFullTest.java
index b59dcc24e3..5caf869597 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/RegisterDetailedTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/RegisterFullTest.java
@@ -20,12 +20,14 @@
*/
package org.zanata.feature.account;
-import lombok.extern.slf4j.Slf4j;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.zanata.feature.BasicAcceptanceTest;
+import org.zanata.feature.DetailedTest;
import org.zanata.page.HomePage;
import org.zanata.page.account.RegisterPage;
import org.zanata.util.rfc2822.InvalidEmailAddressRFC2822;
@@ -40,8 +42,8 @@
/**
* @author Damian Jansen djansen@redhat.com
*/
-@Slf4j
-public class RegisterDetailedTest
+@Category(DetailedTest.class)
+public class RegisterFullTest
{
@ClassRule
public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
@@ -67,6 +69,7 @@ public void before()
}
@Test
+ @Category(BasicAcceptanceTest.class)
@Ignore("Captcha prevents test completion")
public void registerSuccessful()
{
diff --git a/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java b/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java
index 8201fa4cd6..3549f756bc 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/RegisterTestSuite.java
@@ -20,23 +20,19 @@
*/
package org.zanata.feature.account;
-import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
-import org.zanata.util.ResetDatabaseRule;
/**
* @author Damian Jansen djansen@redhat.com
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
- RegisterDetailedTest.class,
+ RegisterFullTest.class,
UsernameValidationTest.class,
ValidEmailAddressTest.class,
InvalidEmailAddressTest.class
})
public class RegisterTestSuite
{
- @ClassRule
- public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
}
diff --git a/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java b/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java
index 129d3fe45b..b407ecdcc3 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/UsernameValidationTest.java
@@ -22,10 +22,12 @@
import org.hamcrest.Matchers;
import org.junit.ClassRule;
+import org.junit.experimental.categories.Category;
import org.junit.experimental.theories.DataPoint;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
+import org.zanata.feature.DetailedTest;
import org.zanata.page.account.RegisterPage;
import org.zanata.util.ResetDatabaseRule;
import org.zanata.workflow.BasicWorkFlow;
@@ -36,6 +38,7 @@
* @author Damian Jansen djansen@redhat.com
*/
@RunWith(Theories.class)
+@Category(DetailedTest.class)
public class UsernameValidationTest
{
@ClassRule
diff --git a/functional-test/src/test/java/org/zanata/feature/account/ValidEmailAddressTest.java b/functional-test/src/test/java/org/zanata/feature/account/ValidEmailAddressTest.java
index 17f8a170d3..6685e4e1f6 100644
--- a/functional-test/src/test/java/org/zanata/feature/account/ValidEmailAddressTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/account/ValidEmailAddressTest.java
@@ -1,11 +1,33 @@
+/*
+ * 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.feature.account;
import org.hamcrest.Matchers;
import org.junit.ClassRule;
+import org.junit.experimental.categories.Category;
import org.junit.experimental.theories.DataPoint;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
+import org.zanata.feature.DetailedTest;
import org.zanata.page.account.RegisterPage;
import org.zanata.util.ResetDatabaseRule;
import org.zanata.util.rfc2822.ValidEmailAddressRFC2822;
@@ -18,6 +40,7 @@
* @author Damian Jansen djansen@redhat.com
*/
@RunWith(Theories.class)
+@Category(DetailedTest.class)
public class ValidEmailAddressTest {
@ClassRule
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/AdministrationTest.java b/functional-test/src/test/java/org/zanata/feature/administration/AdministrationTest.java
new file mode 100644
index 0000000000..9082a805b1
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/administration/AdministrationTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.feature.administration;
+
+import org.concordion.api.extension.Extensions;
+import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.zanata.concordion.IndexPageBuilderExtension;
+import org.zanata.feature.ConcordionTest;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(ConcordionRunner.class)
+@Extensions({IndexPageBuilderExtension.class})
+@Category(ConcordionTest.class)
+public class AdministrationTest
+{
+}
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/AdministrationTestSuite.java b/functional-test/src/test/java/org/zanata/feature/administration/AdministrationTestSuite.java
index 89e2c69abb..de932b9bdd 100644
--- a/functional-test/src/test/java/org/zanata/feature/administration/AdministrationTestSuite.java
+++ b/functional-test/src/test/java/org/zanata/feature/administration/AdministrationTestSuite.java
@@ -1,19 +1,33 @@
+/*
+ * 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.feature.administration;
-import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
-import org.zanata.util.ResetDatabaseRule;
-
-import static org.zanata.util.ResetDatabaseRule.Config.*;
/**
* @author Damian Jansen djansen@redhat.com
*/
@RunWith(Suite.class)
-@Suite.SuiteClasses({ManageUsersTest.class, ManageUsersDetailedTest.class})
+@Suite.SuiteClasses({ManageUsersTest.class, ManageUsersFullTest.class, AdministrationTest.class})
public class AdministrationTestSuite
{
- @ClassRule
- public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
}
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersFullTest.java
similarity index 93%
rename from functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
rename to functional-test/src/test/java/org/zanata/feature/administration/ManageUsersFullTest.java
index e13fb29465..fdbae05dac 100644
--- a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersFullTest.java
@@ -21,6 +21,8 @@
package org.zanata.feature.administration;
import org.junit.*;
+import org.junit.experimental.categories.Category;
+import org.zanata.feature.DetailedTest;
import org.zanata.page.HomePage;
import org.zanata.page.administration.ManageUserPage;
import org.zanata.page.administration.ManageUserAccountPage;
@@ -28,11 +30,12 @@
import org.zanata.workflow.LoginWorkFlow;
import org.hamcrest.Matchers;
import static org.hamcrest.MatcherAssert.assertThat;
+
/**
* @author Damian Jansen djansen@redhat.com
*/
-
-public class ManageUsersDetailedTest
+@Category(DetailedTest.class)
+public class ManageUsersFullTest
{
@ClassRule
public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule(ResetDatabaseRule.Config.Empty);
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
index 8fa1f9d82a..200255d74c 100644
--- a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
@@ -26,8 +26,10 @@
import org.concordion.integration.junit4.ConcordionRunner;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.HomePage;
import org.zanata.workflow.LoginWorkFlow;
import org.zanata.util.ResetDatabaseRule;
@@ -36,6 +38,7 @@
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class ManageUsersTest
{
@ClassRule
diff --git a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryDeleteTest.java b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryDeleteTest.java
index 4a9f8ae0f0..1c04e57ff8 100644
--- a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryDeleteTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryDeleteTest.java
@@ -1,3 +1,23 @@
+/*
+ * 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.feature.glossary;
import java.io.File;
@@ -7,8 +27,10 @@
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.webtrans.EditorPage;
import org.zanata.workflow.BasicWorkFlow;
import org.zanata.workflow.ClientPushWorkFlow;
@@ -22,6 +44,7 @@
*/
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class GlossaryDeleteTest
{
private ClientPushWorkFlow clientPushWorkFlow = new ClientPushWorkFlow();
diff --git a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryPushCSVTest.java b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryPushCSVTest.java
index c55e1dd265..cab7e9c394 100644
--- a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryPushCSVTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryPushCSVTest.java
@@ -1,3 +1,23 @@
+/*
+ * 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.feature.glossary;
import java.io.File;
@@ -7,8 +27,10 @@
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.workflow.ClientPushWorkFlow;
import com.google.common.base.Joiner;
@@ -19,6 +41,7 @@
*/
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class GlossaryPushCSVTest
{
private ClientPushWorkFlow clientPushWorkFlow = new ClientPushWorkFlow();
diff --git a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryPushTest.java b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryPushTest.java
index a82924756f..237eeb9b09 100644
--- a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryPushTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryPushTest.java
@@ -1,3 +1,23 @@
+/*
+ * 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.feature.glossary;
import java.io.File;
@@ -7,16 +27,16 @@
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.webtrans.EditorPage;
import org.zanata.workflow.BasicWorkFlow;
import org.zanata.workflow.ClientPushWorkFlow;
import org.zanata.workflow.LoginWorkFlow;
import com.google.common.base.Joiner;
-import lombok.extern.slf4j.Slf4j;
-
/**
* @see TCMS case
*
@@ -24,7 +44,7 @@
*/
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
-@Slf4j
+@Category(ConcordionTest.class)
public class GlossaryPushTest
{
private ClientPushWorkFlow clientPushWorkFlow = new ClientPushWorkFlow();
diff --git a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryTest.java b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryTest.java
index 3614084305..c3399ea1c7 100644
--- a/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/glossary/GlossaryTest.java
@@ -1,15 +1,38 @@
+/*
+ * 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.feature.glossary;
import org.concordion.api.extension.Extensions;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.IndexPageBuilderExtension;
+import org.zanata.feature.ConcordionTest;
/**
* @author Patrick Huang pahuang@redhat.com
*/
@RunWith(ConcordionRunner.class)
@Extensions({IndexPageBuilderExtension.class})
+@Category(ConcordionTest.class)
public class GlossaryTest
{
}
diff --git a/functional-test/src/test/java/org/zanata/feature/glossary/InvalidGlossaryPushTest.java b/functional-test/src/test/java/org/zanata/feature/glossary/InvalidGlossaryPushTest.java
index c6ffcd30da..99acc7f541 100644
--- a/functional-test/src/test/java/org/zanata/feature/glossary/InvalidGlossaryPushTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/glossary/InvalidGlossaryPushTest.java
@@ -1,3 +1,23 @@
+/*
+ * 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.feature.glossary;
import java.io.File;
@@ -7,8 +27,10 @@
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.workflow.ClientPushWorkFlow;
import com.google.common.base.Joiner;
@@ -21,7 +43,7 @@
*/
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
-@Slf4j
+@Category(ConcordionTest.class)
public class InvalidGlossaryPushTest
{
private ClientPushWorkFlow clientPushWorkFlow = new ClientPushWorkFlow();
diff --git a/functional-test/src/test/java/org/zanata/feature/security/LoginTest.java b/functional-test/src/test/java/org/zanata/feature/security/LoginTest.java
index b1991a7dd6..a6a01e8a62 100644
--- a/functional-test/src/test/java/org/zanata/feature/security/LoginTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/security/LoginTest.java
@@ -25,8 +25,10 @@
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
import org.hamcrest.Matchers;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.HomePage;
import org.zanata.workflow.LoginWorkFlow;
@@ -35,6 +37,7 @@
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class LoginTest
{
public boolean signInAs(String username, String password)
diff --git a/functional-test/src/test/java/org/zanata/feature/security/SecurityTest.java b/functional-test/src/test/java/org/zanata/feature/security/SecurityTest.java
index 4a3f057722..f789e28080 100644
--- a/functional-test/src/test/java/org/zanata/feature/security/SecurityTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/security/SecurityTest.java
@@ -1,17 +1,38 @@
+/*
+ * 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.feature.security;
import org.concordion.api.extension.Extensions;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.IndexPageBuilderExtension;
-
-import lombok.extern.slf4j.Slf4j;
+import org.zanata.feature.ConcordionTest;
/**
* @author Patrick Huang pahuang@redhat.com
*/
@RunWith(ConcordionRunner.class)
@Extensions({IndexPageBuilderExtension.class})
+@Category(ConcordionTest.class)
public class SecurityTest
{
}
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java
index 2c9b5d326b..1895effcae 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java
@@ -1,3 +1,23 @@
+/*
+ * 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.feature.startNewProject;
import java.util.List;
@@ -7,8 +27,10 @@
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
import org.junit.Before;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.HomePage;
import org.zanata.page.administration.ManageLanguagePage;
import org.zanata.page.administration.ManageLanguageTeamMemberPage;
@@ -22,6 +44,7 @@
@Slf4j
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class AddLanguageTest
{
private HomePage homePage;
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/CreateNewProjectTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/CreateNewProjectTest.java
index 4377bce019..34bf8f08e9 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/CreateNewProjectTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/CreateNewProjectTest.java
@@ -1,28 +1,44 @@
+/*
+ * 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.feature.startNewProject;
-import java.util.List;
-
import org.concordion.api.extension.Extensions;
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
import org.junit.Before;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
-import org.zanata.page.HomePage;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.projects.ProjectPage;
-import org.zanata.page.projects.ProjectsPage;
import org.zanata.workflow.LoginWorkFlow;
import org.zanata.workflow.ProjectWorkFlow;
-import lombok.extern.slf4j.Slf4j;
-
/**
* @author Patrick Huang pahuang@redhat.com
*/
-@Slf4j
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class CreateNewProjectTest
{
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/CreateVersionAndAddToProjectTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/CreateVersionAndAddToProjectTest.java
index d5e31c75c5..f03cb6dce5 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/CreateVersionAndAddToProjectTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/CreateVersionAndAddToProjectTest.java
@@ -1,3 +1,23 @@
+/*
+ * 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.feature.startNewProject;
import java.util.List;
@@ -7,8 +27,10 @@
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
import org.junit.Before;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.projects.ProjectPage;
import org.zanata.page.projects.ProjectVersionPage;
import org.zanata.workflow.LoginWorkFlow;
@@ -22,6 +44,7 @@
@Slf4j
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class CreateVersionAndAddToProjectTest
{
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/DocumentListInWebTransTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/DocumentListInWebTransTest.java
index 24aa95d5e1..b3061d99ee 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/DocumentListInWebTransTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/DocumentListInWebTransTest.java
@@ -1,28 +1,47 @@
+/*
+ * 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.feature.startNewProject;
-import java.util.List;
-
import org.concordion.api.extension.Extensions;
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.HomePage;
-import org.zanata.page.projects.ProjectPage;
import org.zanata.page.projects.ProjectVersionPage;
import org.zanata.page.webtrans.DocumentsViewPage;
import org.zanata.workflow.BasicWorkFlow;
import org.zanata.workflow.LoginWorkFlow;
-import lombok.extern.slf4j.Slf4j;
+import java.util.List;
/**
* @author Patrick Huang pahuang@redhat.com
*/
-@Slf4j
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class DocumentListInWebTransTest
{
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/PushPodirPluralProjectTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/PushPodirPluralProjectTest.java
index 9e77172d09..196eaa9a7c 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/PushPodirPluralProjectTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/PushPodirPluralProjectTest.java
@@ -1,14 +1,27 @@
+/*
+ * 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.feature.startNewProject;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
+import com.google.common.base.Joiner;
+import com.google.common.io.Files;
import org.concordion.api.extension.ConcordionExtension;
import org.concordion.api.extension.Extension;
import org.concordion.api.extension.Extensions;
@@ -16,28 +29,25 @@
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.workflow.ClientPushWorkFlow;
-import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.io.Files;
-import com.google.common.util.concurrent.SimpleTimeLimiter;
-
-import lombok.extern.slf4j.Slf4j;
-import static org.hamcrest.MatcherAssert.assertThat;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
* @author Patrick Huang pahuang@redhat.com
*/
-@Slf4j
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class, LoggingTooltipExtension.class})
+@Category(ConcordionTest.class)
public class PushPodirPluralProjectTest
{
private final static Logger tooltipLog = Logger.getLogger(PushPodirPluralProjectTest.class.getName());
@@ -71,8 +81,6 @@ public List push(String command, String configPath) throws Exception
return clientPushWorkFlow.callWithTimeout(projectRootPath, command + configPath);
}
-
-
public boolean isPushSuccessful(List output)
{
return clientPushWorkFlow.isPushSuccessful(output);
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/StartNewProjectTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/StartNewProjectTest.java
index c773b677ed..72d12b5085 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/StartNewProjectTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/StartNewProjectTest.java
@@ -1,9 +1,31 @@
+/*
+ * 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.feature.startNewProject;
import org.concordion.api.extension.Extension;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.IndexPageBuilderExtension;
+import org.zanata.feature.ConcordionTest;
/**
* This is the index page for startNewProject package.
@@ -14,6 +36,7 @@
* @author Patrick Huang pahuang@redhat.com
*/
@RunWith(ConcordionRunner.class)
+@Category(ConcordionTest.class)
public class StartNewProjectTest
{
@Extension
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/TranslatorJoinsLanguageTeamTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/TranslatorJoinsLanguageTeamTest.java
index 4a7282e475..51c636bce5 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/TranslatorJoinsLanguageTeamTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/TranslatorJoinsLanguageTeamTest.java
@@ -1,3 +1,23 @@
+/*
+ * 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.feature.startNewProject;
import java.util.List;
@@ -7,22 +27,22 @@
import org.concordion.ext.TimestampFormatterExtension;
import org.concordion.integration.junit4.ConcordionRunner;
import org.junit.Before;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.HomePage;
import org.zanata.page.administration.ManageLanguagePage;
import org.zanata.page.administration.ManageLanguageTeamMemberPage;
import org.zanata.util.TableRow;
import org.zanata.workflow.LoginWorkFlow;
-import lombok.extern.slf4j.Slf4j;
-
/**
* @author Patrick Huang pahuang@redhat.com
*/
-@Slf4j
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class TranslatorJoinsLanguageTeamTest
{
private HomePage homePage;
diff --git a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupBasicTest.java b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupBasicTest.java
index ace7a5cc6d..b3d62aca44 100644
--- a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupBasicTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupBasicTest.java
@@ -1,3 +1,23 @@
+/*
+ * 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.feature.versionGroup;
import java.util.List;
@@ -7,8 +27,10 @@
import org.concordion.integration.junit4.ConcordionRunner;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.CustomResourceExtension;
+import org.zanata.feature.ConcordionTest;
import org.zanata.page.HomePage;
import org.zanata.page.groups.VersionGroupPage;
import org.zanata.page.groups.VersionGroupsPage;
@@ -18,15 +40,14 @@
import org.zanata.workflow.ProjectWorkFlow;
import org.zanata.util.ResetDatabaseRule;
-import lombok.extern.slf4j.Slf4j;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Patrick Huang pahuang@redhat.com
*/
-@Slf4j
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
+@Category(ConcordionTest.class)
public class VersionGroupBasicTest
{
@@ -87,7 +108,6 @@ public VersionGroupsPage toggleObsolete(VersionGroupsPage versionGroupsPage)
public VersionGroupsPage groups()
{
VersionGroupsPage versionGroupsPage = projectWorkFlow.goToHome().goToGroups();
- log.info("title is {}", versionGroupsPage.getTitle());
return versionGroupsPage;
}
diff --git a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupFullTest.java
similarity index 84%
rename from functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupDetailedTest.java
rename to functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupFullTest.java
index 9c4680ce5f..445ecc652d 100644
--- a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupDetailedTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupFullTest.java
@@ -1,3 +1,23 @@
+/*
+ * 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.feature.versionGroup;
import java.util.*;
@@ -6,6 +26,9 @@
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.*;
+import org.junit.experimental.categories.Category;
+import org.zanata.feature.BasicAcceptanceTest;
+import org.zanata.feature.DetailedTest;
import org.zanata.page.HomePage;
import org.zanata.page.groups.VersionGroupPage;
import org.zanata.page.groups.VersionGroupsPage;
@@ -15,15 +38,15 @@
import lombok.extern.slf4j.Slf4j;
-
/**
* @author Damian Jansen djansen@redhat.com
*/
@Slf4j
-public class VersionGroupDetailedTest
+@Category(DetailedTest.class)
+public class VersionGroupFullTest
{
@ClassRule
- public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule(ResetDatabaseRule.Config.Empty);
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
private HomePage homePage;
@Before
@@ -33,6 +56,7 @@ public void before()
}
@Test
+ @Category(BasicAcceptanceTest.class)
public void createABasicGroup()
{
String groupID = "basic-group";
@@ -55,7 +79,7 @@ public void inputValidationForID()
String errorMsg = "must start and end with letter or number, and contain only letters, numbers, underscores and hyphens.";
for (Map.Entry entry : inputValidationForIDData().entrySet())
{
- log.info("Test " + entry.getKey() + ":" + entry.getValue());
+ VersionGroupFullTest.log.info("Test " + entry.getKey() + ":" + entry.getValue());
VersionGroupsPage versionGroupsPage = homePage.goToGroups();
CreateVersionGroupPage groupPage = versionGroupsPage.createNewGroup();
groupPage.inputGroupId(entry.getValue()).inputGroupName(entry.getValue());
diff --git a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTest.java b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTest.java
index a3c9065971..ea6e3b6839 100644
--- a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTest.java
@@ -1,15 +1,38 @@
+/*
+ * 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.feature.versionGroup;
import org.concordion.api.extension.Extensions;
import org.concordion.integration.junit4.ConcordionRunner;
+import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.zanata.concordion.IndexPageBuilderExtension;
+import org.zanata.feature.ConcordionTest;
/**
* @author Patrick Huang pahuang@redhat.com
*/
@RunWith(ConcordionRunner.class)
@Extensions({IndexPageBuilderExtension.class})
+@Category(ConcordionTest.class)
public class VersionGroupTest
{
}
diff --git a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTestSuite.java b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTestSuite.java
index 6be8d3a12b..a08b0b2ef6 100644
--- a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTestSuite.java
+++ b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupTestSuite.java
@@ -1,19 +1,17 @@
package org.zanata.feature.versionGroup;
-import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
-import org.zanata.util.ResetDatabaseRule;
-
-import static org.zanata.util.ResetDatabaseRule.Config.*;
/**
* @author Patrick Huang pahuang@redhat.com
*/
@RunWith(Suite.class)
-@Suite.SuiteClasses({VersionGroupTest.class, VersionGroupBasicTest.class})
+@Suite.SuiteClasses({
+ VersionGroupTest.class,
+ VersionGroupFullTest.class,
+ VersionGroupBasicTest.class
+})
public class VersionGroupTestSuite
{
- @ClassRule
- public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
}
From 8406c41a726b0692459bdc9f655f5ae2922f0331 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:50:40 +1000
Subject: [PATCH 109/184] make FileService.checkSourceUploadPreconditions
static (mikado method)
---
.../main/java/org/zanata/rest/service/FileService.java | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 23f7d873a4..1872253cdf 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -185,7 +185,8 @@ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, S
try
{
GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
- checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm);
+ checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity,
+ session, projectIterationDAO, translationFileServiceImpl);
Optional tempFile;
int totalChunks;
@@ -257,7 +258,12 @@ private static InputStream getInputStream(Optional tempFile, DocumentFileU
}
}
- private void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
+ private static void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm,
+ ZanataIdentity identity,
+ Session session,
+ ProjectIterationDAO projectIterationDAO,
+ TranslationFileService translationFileServiceImpl)
{
try
{
From de288bfa552dc5d62661d26a969d0cabcae8d78b Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 16:58:29 +1000
Subject: [PATCH 110/184] make FileService.saveUploadPart static (mikado
method)
---
.../org/zanata/rest/service/FileService.java | 42 +++++++++++--------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 1872253cdf..626ee70aa8 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -193,7 +193,8 @@ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, S
if (!uploadForm.getLast())
{
- HDocumentUpload upload = saveUploadPart(id.getProjectSlug(), id.getVersionSlug(), id.getDocId(), NULL_LOCALE, uploadForm);
+ HDocumentUpload upload = saveUploadPart(id.getProjectSlug(), id.getVersionSlug(),
+ id.getDocId(), NULL_LOCALE, uploadForm, session, projectIterationDAO);
totalChunks = upload.getParts().size();
return Response.status(Status.ACCEPTED)
.entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
@@ -208,7 +209,8 @@ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, S
}
else
{
- HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE, uploadForm);
+ HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE,
+ uploadForm, session, projectIterationDAO);
totalChunks = upload.getParts().size();
tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
}
@@ -478,7 +480,9 @@ private static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploa
return upload;
}
- private HDocumentUpload createMultipartUpload(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm, HLocale locale)
+ private static HDocumentUpload createMultipartUpload(String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm, HLocale locale,
+ ProjectIterationDAO projectIterationDAO)
{
HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
HDocumentUpload newUpload = new HDocumentUpload();
@@ -491,16 +495,6 @@ private HDocumentUpload createMultipartUpload(String projectSlug, String iterati
return newUpload;
}
- private void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentUpload upload)
- {
- Blob partContent = session.getLobHelper().createBlob(uploadForm.getFileStream(), uploadForm.getSize().intValue());
- HDocumentUploadPart newPart = new HDocumentUploadPart();
- newPart.setContent(partContent);
- upload.getParts().add(newPart);
- session.saveOrUpdate(upload);
- session.flush();
- }
-
private static void checkUploadPreconditions(String projectSlug, String iterationSlug, String docId,
DocumentFileUploadForm uploadForm, ZanataIdentity identity,
ProjectIterationDAO projectIterationDAO, Session session)
@@ -665,7 +659,8 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
}
else
{
- HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, locale, uploadForm);
+ HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, locale,
+ uploadForm, session, projectIterationDAO);
totalChunks = upload.getParts().size();
if (!uploadForm.getLast())
{
@@ -769,21 +764,34 @@ private Set newExtensions(boolean gettextExtensions)
return extensions;
}
- private HDocumentUpload saveUploadPart(String projectSlug, String iterationSlug, String docId, HLocale locale, DocumentFileUploadForm uploadForm)
+ private static HDocumentUpload saveUploadPart(String projectSlug, String iterationSlug, String docId,
+ HLocale locale, DocumentFileUploadForm uploadForm, Session session,
+ ProjectIterationDAO projectIterationDAO)
{
HDocumentUpload upload;
if (uploadForm.getFirst())
{
- upload = createMultipartUpload(projectSlug, iterationSlug, docId, uploadForm, locale);
+ upload = createMultipartUpload(projectSlug, iterationSlug, docId, uploadForm, locale, projectIterationDAO);
}
else
{
upload = retrieveUploadObject(uploadForm, session);
}
- saveUploadPart(uploadForm, upload);
+ saveUploadPart(uploadForm, upload, session);
return upload;
}
+ private static void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentUpload upload,
+ Session session)
+ {
+ Blob partContent = session.getLobHelper().createBlob(uploadForm.getFileStream(), uploadForm.getSize().intValue());
+ HDocumentUploadPart newPart = new HDocumentUploadPart();
+ newPart.setContent(partContent);
+ upload.getParts().add(newPart);
+ session.saveOrUpdate(upload);
+ session.flush();
+ }
+
private void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale)
{
if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale))
From b985a9222cb3540860cc1199c739addfd3e23789 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Tue, 16 Jul 2013 17:10:44 +1000
Subject: [PATCH 111/184] make FileService.parsePotFile static (mikado method)
---
.../org/zanata/rest/service/FileService.java | 28 ++++++++++---------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 626ee70aa8..27d435be68 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -218,7 +218,8 @@ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, S
if (uploadForm.getFileType().equals(".pot"))
{
InputStream potStream = getInputStream(tempFile, uploadForm);
- parsePotFile(potStream, projectSlug, iterationSlug, docId, uploadForm);
+ parsePotFile(potStream, projectSlug, iterationSlug, docId, uploadForm,
+ translationFileServiceImpl, documentServiceImpl, documentDAO);
}
else
{
@@ -431,11 +432,6 @@ private static boolean isSinglePart(DocumentFileUploadForm uploadForm)
return uploadForm.getFirst() && uploadForm.getLast();
}
- private boolean useOfflinePo(String projectSlug, String iterationSlug, String docId)
- {
- return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
- }
-
private static boolean isNewDocument(String projectSlug, String iterationSlug, String docId, DocumentDAO dao)
{
return dao.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId) == null;
@@ -587,20 +583,26 @@ private static void checkUploadPreconditions(String projectSlug, String iteratio
}
}
- private void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
- {
- parsePotFile(potStream, docId, uploadForm.getFileType(), projectSlug, iterationSlug, useOfflinePo(projectSlug, iterationSlug, docId));
- }
-
- private void parsePotFile(InputStream documentStream, String docId, String fileType, String projectSlug, String iterationSlug, boolean asOfflinePo)
+ private static void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm,
+ TranslationFileService translationFileServiceImpl,
+ DocumentService documentServiceImpl,
+ DocumentDAO documentDAO)
{
Resource doc;
- doc = translationFileServiceImpl.parseUpdatedPotFile(documentStream, docId, fileType, asOfflinePo);
+ doc = translationFileServiceImpl.parseUpdatedPotFile(potStream, docId, uploadForm.getFileType(),
+ useOfflinePo(projectSlug, iterationSlug, docId, documentDAO, translationFileServiceImpl));
doc.setLang( new LocaleId("en-US") );
// TODO Copy Trans values
documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, new StringSet(ExtensionType.GetText.toString()), false);
}
+ private static boolean useOfflinePo(String projectSlug, String iterationSlug, String docId,
+ DocumentDAO documentDAO, TranslationFileService translationFileServiceImpl)
+ {
+ return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
+ }
+
private static Response sourceUploadSuccessResponse(boolean isNewDocument, int acceptedChunks)
{
Response response;
From ddb3a3b72db48ad8426ccfbcc2617890121345b9 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Wed, 17 Jul 2013 08:00:07 +1000
Subject: [PATCH 112/184] refactor code as suggested
---
.../java/org/zanata/action/ViewAllStatusAction.java | 12 ++++++------
zanata-war/src/main/resources/messages.properties | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
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 15c19461c0..0f7609d586 100644
--- a/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java
@@ -219,8 +219,8 @@ public void refreshStatistic()
{
HProjectIteration iteration = projectIterationDAO.getBySlug(this.projectSlug, this.iterationSlug);
- List locale = this.getDisplayLocales();
- String[] localeIds = getLocaleIds(locale);
+ List localeList = this.getDisplayLocales();
+ String[] localeIds = getLocaleIds(localeList);
ContainerTranslationStatistics iterationStats = statisticsServiceImpl.getStatistics(this.projectSlug, this.iterationSlug, false, true, localeIds);
@@ -234,9 +234,9 @@ public void refreshStatistic()
total = projectIterationDAO.getTotalCountForIteration(iteration.getId());
}
- for (HLocale var : locale)
+ for (HLocale locale : localeList)
{
- TranslationStatistics stats = iterationStats.getStats(var.getLocaleId().getId(), statsOption);
+ TranslationStatistics stats = iterationStats.getStats(locale.getLocaleId().getId(), statsOption);
if (stats == null)
{
stats = new TranslationStatistics(statsOption);
@@ -244,9 +244,9 @@ public void refreshStatistic()
// stats.setTotal(total);
}
- if (statsMap.containsKey(var.getLocaleId()))
+ if (statsMap.containsKey(locale.getLocaleId()))
{
- statsMap.get(var.getLocaleId()).setStats(stats);
+ statsMap.get(locale.getLocaleId()).setStats(stats);
}
}
}
diff --git a/zanata-war/src/main/resources/messages.properties b/zanata-war/src/main/resources/messages.properties
index a84c03ce58..d73e64330c 100644
--- a/zanata-war/src/main/resources/messages.properties
+++ b/zanata-war/src/main/resources/messages.properties
@@ -343,7 +343,7 @@ jsf.iteration.files.translateDenied.NotLoggedIn=You are not logged In.
jsf.iteration.files.translateDenied.VersionIsReadOnly=This project version is Read-Only.
jsf.iteration.files.translateDenied.VersionIsObsolete=This project version is Obsolete.
! {0} is a language name
-jsf.iteration.files.translateDenied.UserNotTranslatorInLanguageTeam=You are not translator of the {0} language team.
+jsf.iteration.files.translateDenied.UserNotTranslatorInLanguageTeam=You are a not translator of the {0} language team.
! {0} is a list of user roles
jsf.iteration.files.translateDenied.UserNotInProjectRole=You must be part of these user roles to translate this project: {0}
@@ -401,7 +401,7 @@ jsf.Loading=Loading...
jsf.AlreadyInTeam=Already in Team
jsf.Reviewer=Reviewer
jsf.Translator=Translator
-jsf.RequestRoleAs=Request role in '#{sendEmail.locale.localeId.id}' language team as :
+jsf.RequestRoleAs=Request the following roles in the '#{sendEmail.locale.localeId.id}' language team:
#------ [home] > Help ------
From e55c1f3dc631690afa3bee74928293170d02274e Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Wed, 17 Jul 2013 08:17:55 +1000
Subject: [PATCH 113/184] Fix functional test
---
.../zanata/page/administration/ManageUserAccountPage.java | 8 ++++----
.../feature/administration/ManageUsersDetailedTest.java | 2 +-
.../zanata/feature/administration/ManageUsersTest.java | 7 ++++---
3 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java b/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
index d2084312c3..52204368cd 100644
--- a/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
+++ b/functional-test/src/main/java/org/zanata/page/administration/ManageUserAccountPage.java
@@ -28,6 +28,7 @@
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.zanata.page.AbstractPage;
+import com.google.common.base.Predicate;
/**
* @author Damian Jansen djansen@redhat.com
@@ -35,10 +36,6 @@
public class ManageUserAccountPage extends AbstractPage
{
-
- @FindBy(id = "userdetailForm:usernameField:username")
- private WebElement usernameField;
-
@FindBy(id = "userdetailForm:passwordField:password")
private WebElement passwordField;
@@ -54,6 +51,9 @@ public class ManageUserAccountPage extends AbstractPage
@FindBy(id = "userdetailForm:userdetailCancel")
private WebElement cancelButton;
+ // username field will trigger ajax call and become stale
+ private By usernameBy = By.id("userdetailForm:usernameField:username");
+
private Map roleMap;
public ManageUserAccountPage(WebDriver driver)
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
index c4aa1df771..7b13af799c 100644
--- a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersDetailedTest.java
@@ -51,7 +51,7 @@ public void changeAUsersUsername()
ManageUserPage manageUserPage = homePage.goToAdministration().goToManageUserPage();
ManageUserAccountPage manageUserAccountPage = manageUserPage.editUserAccount("admin");
- manageUserPage = manageUserAccountPage.clearAndEnterUsername(username).saveUser();
+ manageUserPage = manageUserAccountPage.clearFields().enterUsername(username).saveUser();
assertThat("Administrator is displayed", manageUserPage.getUserList(), Matchers.hasItem(username));
}
diff --git a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
index cb3b83ae16..0b2babb0ba 100644
--- a/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/administration/ManageUsersTest.java
@@ -63,9 +63,10 @@ public ManageUserAccountPage editUserAccount(ManageUserPage manageUserPage, Stri
public ManageUserPage changeUsernameAndPassword(ManageUserAccountPage manageUserAccount, String newUsername, String newPassword)
{
- ManageUserPage page = manageUserAccount.clearAndEnterUsername(newUsername)
- .clearAndEnterPassword(newPassword)
- .clearAndEnterConfirmPassword(newPassword)
+ ManageUserPage page = manageUserAccount.clearFields()
+ .enterUsername(newUsername)
+ .enterPassword(newPassword)
+ .enterConfirmPassword(newPassword)
.saveUser();
return page;
From 486144e5772faa1cd77b0870140ae1859060dc63 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 08:26:47 +1000
Subject: [PATCH 114/184] make FileService.processAdapterFile static (mikado
method)
---
.../java/org/zanata/rest/service/FileService.java | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 27d435be68..d4b3210a84 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -227,7 +227,9 @@ private Response tryUploadSourceFile(String projectSlug, String iterationSlug, S
{
tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
}
- processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm);
+ processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm,
+ virusScanner, documentDAO, documentServiceImpl, translationFileServiceImpl,
+ identity);
}
if (tempFile.isPresent())
{
@@ -333,8 +335,13 @@ private static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm,
return tempFile;
}
- private void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm)
+ private static void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm,
+ VirusScanner virusScanner,
+ DocumentDAO documentDAO,
+ DocumentService documentServiceImpl,
+ TranslationFileService translationFileServiceImpl,
+ ZanataIdentity identity)
{
String name = projectSlug+":"+iterationSlug+":"+docId;
try
From 8d767c24f325ca0509c85208eac9c5a11a3f259c Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 08:31:28 +1000
Subject: [PATCH 115/184] make FileService.tryUploadSourceFile static (mikado
method)
---
.../java/org/zanata/rest/service/FileService.java | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index d4b3210a84..e1a0931fb6 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -177,10 +177,20 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
@QueryParam("docId") String docId,
@MultipartForm DocumentFileUploadForm uploadForm )
{
- return tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm);
+ return tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm,
+ identity, session, translationFileServiceImpl, projectIterationDAO,
+ documentDAO, documentServiceImpl, virusScanner);
}
- private Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
+ private static Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm,
+ ZanataIdentity identity,
+ Session session,
+ TranslationFileService translationFileServiceImpl,
+ ProjectIterationDAO projectIterationDAO,
+ DocumentDAO documentDAO,
+ DocumentService documentServiceImpl,
+ VirusScanner virusScanner)
{
try
{
From 2be2f12986216e380572104b4d3c8d7ab4c9bc79 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 08:58:03 +1000
Subject: [PATCH 116/184] move all source upload methods from FileService to
new DocumentUpload (mikado method)
---
.../java/org/zanata/file/DocumentUpload.java | 571 ++++++++++++++++++
.../org/zanata/rest/service/FileService.java | 523 +---------------
2 files changed, 580 insertions(+), 514 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
diff --git a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
new file mode 100644
index 0000000000..8271a9e300
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
@@ -0,0 +1,571 @@
+/*
+ * 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.file;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.Vector;
+
+import javax.annotation.Nonnull;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.hibernate.Criteria;
+import org.hibernate.LobHelper;
+import org.hibernate.Session;
+import org.hibernate.criterion.Restrictions;
+import org.jboss.seam.security.AuthorizationException;
+import org.jboss.seam.util.Hex;
+import org.zanata.common.DocumentType;
+import org.zanata.common.EntityStatus;
+import org.zanata.common.LocaleId;
+import org.zanata.dao.DocumentDAO;
+import org.zanata.dao.ProjectIterationDAO;
+import org.zanata.exception.ChunkUploadException;
+import org.zanata.exception.HashMismatchException;
+import org.zanata.exception.VirusDetectedException;
+import org.zanata.exception.ZanataServiceException;
+import org.zanata.model.HDocument;
+import org.zanata.model.HDocumentUpload;
+import org.zanata.model.HDocumentUploadPart;
+import org.zanata.model.HLocale;
+import org.zanata.model.HProjectIteration;
+import org.zanata.model.HRawDocument;
+import org.zanata.rest.DocumentFileUploadForm;
+import org.zanata.rest.StringSet;
+import org.zanata.rest.dto.ChunkUploadResponse;
+import org.zanata.rest.dto.extensions.ExtensionType;
+import org.zanata.rest.dto.resource.Resource;
+import org.zanata.rest.service.VirusScanner;
+import org.zanata.security.ZanataIdentity;
+import org.zanata.service.DocumentService;
+import org.zanata.service.TranslationFileService;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+
+@Slf4j
+public class DocumentUpload
+{
+
+ public static final HLocale NULL_LOCALE = null;
+
+ public static Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm,
+ ZanataIdentity identity,
+ Session session,
+ TranslationFileService translationFileServiceImpl,
+ ProjectIterationDAO projectIterationDAO,
+ DocumentDAO documentDAO,
+ DocumentService documentServiceImpl,
+ VirusScanner virusScanner)
+ {
+ try
+ {
+ GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
+ checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity,
+ session, projectIterationDAO, translationFileServiceImpl);
+
+ Optional tempFile;
+ int totalChunks;
+
+ if (!uploadForm.getLast())
+ {
+ HDocumentUpload upload = saveUploadPart(id.getProjectSlug(), id.getVersionSlug(),
+ id.getDocId(), NULL_LOCALE, uploadForm, session, projectIterationDAO);
+ totalChunks = upload.getParts().size();
+ return Response.status(Status.ACCEPTED)
+ .entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
+ "Chunk accepted, awaiting remaining chunks."))
+ .build();
+ }
+
+ if (isSinglePart(uploadForm))
+ {
+ totalChunks = 1;
+ tempFile = Optional.absent();
+ }
+ else
+ {
+ HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE,
+ uploadForm, session, projectIterationDAO);
+ totalChunks = upload.getParts().size();
+ tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
+ }
+
+ if (uploadForm.getFileType().equals(".pot"))
+ {
+ InputStream potStream = getInputStream(tempFile, uploadForm);
+ parsePotFile(potStream, projectSlug, iterationSlug, docId, uploadForm,
+ translationFileServiceImpl, documentServiceImpl, documentDAO);
+ }
+ else
+ {
+ if (!tempFile.isPresent())
+ {
+ tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
+ }
+ processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm,
+ virusScanner, documentDAO, documentServiceImpl, translationFileServiceImpl,
+ identity);
+ }
+ if (tempFile.isPresent())
+ {
+ tempFile.get().delete();
+ }
+ return sourceUploadSuccessResponse(isNewDocument(projectSlug, iterationSlug, docId, documentDAO), totalChunks);
+ }
+ catch (ChunkUploadException e)
+ {
+ return Response.status(e.getStatusCode())
+ .entity(new ChunkUploadResponse(e.getMessage()))
+ .build();
+ }
+ catch (FileNotFoundException e)
+ {
+ log.error("failed to create input stream from temp file", e);
+ return Response.status(Status.INTERNAL_SERVER_ERROR)
+ .entity(e).build();
+ }
+ }
+
+ public static void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm,
+ ZanataIdentity identity,
+ Session session,
+ ProjectIterationDAO projectIterationDAO,
+ TranslationFileService translationFileServiceImpl)
+ {
+ try
+ {
+ checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
+ checkSourceUploadAllowed(projectSlug, iterationSlug, identity, projectIterationDAO);
+ }
+ catch (AuthorizationException e)
+ {
+ throw new ChunkUploadException(Status.UNAUTHORIZED, e.getMessage());
+ }
+ checkValidSourceUploadType(uploadForm, translationFileServiceImpl);
+ }
+
+ public static void checkUploadPreconditions(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm, ZanataIdentity identity,
+ ProjectIterationDAO projectIterationDAO, Session session)
+ {
+ if (!identity.isLoggedIn())
+ {
+ throw new AuthorizationException("Valid combination of username and api-key for this" +
+ " server were not included in the request.");
+ }
+
+ if (docId == null || docId.isEmpty())
+ {
+ throw new ChunkUploadException(Status.PRECONDITION_FAILED,
+ "Required query string parameter 'docId' was not found.");
+ }
+
+ if (uploadForm.getFileStream() == null)
+ {
+ throw new ChunkUploadException(Status.PRECONDITION_FAILED,
+ "Required form parameter 'file' containing file content was not found.");
+ }
+
+ if (uploadForm.getFirst() == null || uploadForm.getLast() == null)
+ {
+ throw new ChunkUploadException(Status.PRECONDITION_FAILED,
+ "Form parameters 'first' and 'last' must both be provided.");
+ }
+
+ if (!uploadForm.getFirst())
+ {
+ if (uploadForm.getUploadId() == null)
+ {
+ throw new ChunkUploadException(Status.PRECONDITION_FAILED,
+ "Form parameter 'uploadId' must be provided when this is not the first part.");
+ }
+
+ HDocumentUpload upload = retrieveUploadObject(uploadForm, session);
+ if (upload == null)
+ {
+ throw new ChunkUploadException(Status.PRECONDITION_FAILED,
+ "No incomplete uploads found for uploadId '" + uploadForm.getUploadId() + "'.");
+ }
+ if (!upload.getDocId().equals(docId))
+ {
+ throw new ChunkUploadException(Status.PRECONDITION_FAILED,
+ "Supplied uploadId '" + uploadForm.getUploadId()
+ + "' in request is not valid for document '" + docId + "'.");
+ }
+ }
+
+ String fileType = uploadForm.getFileType();
+ if (fileType == null || fileType.isEmpty())
+ {
+ throw new ChunkUploadException(Status.PRECONDITION_FAILED,
+ "Required form parameter 'type' was not found.");
+ }
+
+ if (DocumentType.typeFor(fileType) == null)
+ {
+ throw new ChunkUploadException(Status.PRECONDITION_FAILED,
+ "Value '" + fileType + "' is not a recognized document type.");
+ }
+
+ String contentHash = uploadForm.getHash();
+ if (contentHash == null || contentHash.isEmpty())
+ {
+ throw new ChunkUploadException(Status.PRECONDITION_FAILED,
+ "Required form parameter 'hash' was not found.");
+ }
+
+ HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
+ if (projectIteration == null)
+ {
+ throw new ChunkUploadException(Status.NOT_FOUND,
+ "The specified project-version \"" + projectSlug + ":" + iterationSlug +
+ "\" does not exist on this server.");
+ }
+
+ if (projectIteration.getProject().getStatus() != EntityStatus.ACTIVE)
+ {
+ throw new ChunkUploadException(Status.FORBIDDEN,
+ "The project \"" + projectSlug + "\" is not active. Document upload is not allowed.");
+ }
+
+ if (projectIteration.getStatus() != EntityStatus.ACTIVE)
+ {
+ throw new ChunkUploadException(Status.FORBIDDEN,
+ "The project-version \"" + projectSlug + ":" + iterationSlug +
+ "\" is not active. Document upload is not allowed.");
+ }
+ }
+
+ public static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploadForm, Session session)
+ {
+ // TODO put in DAO
+ Criteria criteria = session.createCriteria(HDocumentUpload.class);
+ criteria.add(Restrictions.idEq(uploadForm.getUploadId()));
+ HDocumentUpload upload = (HDocumentUpload) criteria.uniqueResult();
+ return upload;
+ }
+
+ public static void checkSourceUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
+ {
+ if (!isDocumentUploadAllowed(projectSlug, iterationSlug, identity, projIterDAO))
+ {
+ throw new ChunkUploadException(Status.FORBIDDEN,
+ "You do not have permission to upload source documents to project-version \""
+ + projectSlug + ":" + iterationSlug + "\".");
+ }
+ }
+
+ public static boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
+ {
+ HProjectIteration projectIteration = projIterDAO.getBySlug(projectSlug, iterationSlug);
+ return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
+ && identity != null && identity.hasPermission("import-template", projectIteration);
+ }
+
+ public static void checkValidSourceUploadType(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
+ {
+ if (!uploadForm.getFileType().equals(".pot")
+ && !transFileService.hasAdapterFor(DocumentType.typeFor(uploadForm.getFileType())))
+ {
+ throw new ChunkUploadException(Status.BAD_REQUEST,
+ "The type \"" + uploadForm.getFileType() + "\" specified in form parameter 'type' "
+ + "is not valid for a source file on this server.");
+ }
+ }
+
+ public static HDocumentUpload saveUploadPart(String projectSlug, String iterationSlug, String docId,
+ HLocale locale, DocumentFileUploadForm uploadForm, Session session,
+ ProjectIterationDAO projectIterationDAO)
+ {
+ HDocumentUpload upload;
+ if (uploadForm.getFirst())
+ {
+ upload = createMultipartUpload(projectSlug, iterationSlug, docId, uploadForm, locale, projectIterationDAO);
+ }
+ else
+ {
+ upload = retrieveUploadObject(uploadForm, session);
+ }
+ saveUploadPart(uploadForm, upload, session);
+ return upload;
+ }
+
+ public static HDocumentUpload createMultipartUpload(String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm, HLocale locale,
+ ProjectIterationDAO projectIterationDAO)
+ {
+ HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
+ HDocumentUpload newUpload = new HDocumentUpload();
+ newUpload.setProjectIteration(projectIteration);
+ newUpload.setDocId(docId);
+ newUpload.setType(DocumentType.typeFor(uploadForm.getFileType()));
+ // locale intentionally left null for source
+ newUpload.setLocale(locale);
+ newUpload.setContentHash(uploadForm.getHash());
+ return newUpload;
+ }
+
+ public static void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentUpload upload,
+ Session session)
+ {
+ Blob partContent = session.getLobHelper().createBlob(uploadForm.getFileStream(), uploadForm.getSize().intValue());
+ HDocumentUploadPart newPart = new HDocumentUploadPart();
+ newPart.setContent(partContent);
+ upload.getParts().add(newPart);
+ session.saveOrUpdate(upload);
+ session.flush();
+ }
+
+ public static boolean isSinglePart(DocumentFileUploadForm uploadForm)
+ {
+ return uploadForm.getFirst() && uploadForm.getLast();
+ }
+
+ public static File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload, Session session,
+ TranslationFileService transFileService)
+ {
+ File tempFile;
+ try
+ {
+ tempFile = DocumentUpload.combineToTempFile(upload, transFileService);
+ }
+ catch (HashMismatchException e)
+ {
+ throw new ChunkUploadException(Status.CONFLICT,
+ "MD5 hash \"" + e.getExpectedHash() + "\" sent with initial request does not match" +
+ " server-generated hash of combined parts \"" + e.getGeneratedHash() +
+ "\". Upload aborted. Retry upload from first part.");
+ }
+ catch (SQLException e)
+ {
+ throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR,
+ "Error while retreiving document upload part contents", e);
+ }
+ finally
+ {
+ // no more need for upload
+ session.delete(upload);
+ }
+ return tempFile;
+ }
+
+ public static File combineToTempFile(HDocumentUpload upload, TranslationFileService service) throws SQLException
+ {
+ Vector partStreams = new Vector();
+ for (HDocumentUploadPart part : upload.getParts())
+ {
+ partStreams.add(part.getContent().getBinaryStream());
+ }
+
+ MessageDigest md;
+ try
+ {
+ md = MessageDigest.getInstance("MD5");
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ log.error("MD5 algorithm not available.", e);
+ throw new RuntimeException(e);
+ }
+ InputStream combinedParts = new SequenceInputStream(partStreams.elements());
+ combinedParts = new DigestInputStream(combinedParts, md);
+ File tempFile = service.persistToTempFile(combinedParts);
+ String md5hash = new String(Hex.encodeHex(md.digest()));
+
+ if (!md5hash.equals(upload.getContentHash()))
+ {
+ throw new HashMismatchException("MD5 hashes do not match.\n", upload.getContentHash(), md5hash);
+ }
+ return tempFile;
+ }
+
+ public static InputStream getInputStream(Optional tempFile, DocumentFileUploadForm uploadForm) throws FileNotFoundException
+ {
+ if (tempFile.isPresent())
+ {
+ return new FileInputStream(tempFile.get());
+ }
+ else
+ {
+ return uploadForm.getFileStream();
+ }
+ }
+
+ public static void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm,
+ TranslationFileService translationFileServiceImpl,
+ DocumentService documentServiceImpl,
+ DocumentDAO documentDAO)
+ {
+ Resource doc;
+ doc = translationFileServiceImpl.parseUpdatedPotFile(potStream, docId, uploadForm.getFileType(),
+ useOfflinePo(projectSlug, iterationSlug, docId, documentDAO, translationFileServiceImpl));
+ doc.setLang( new LocaleId("en-US") );
+ // TODO Copy Trans values
+ documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, new StringSet(ExtensionType.GetText.toString()), false);
+ }
+
+ public static boolean useOfflinePo(String projectSlug, String iterationSlug, String docId,
+ DocumentDAO documentDAO, TranslationFileService translationFileServiceImpl)
+ {
+ return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
+ }
+
+ public static boolean isNewDocument(String projectSlug, String iterationSlug, String docId, DocumentDAO dao)
+ {
+ return dao.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId) == null;
+ }
+
+ public static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
+ {
+ File tempFile;
+ try
+ {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ InputStream fileContents = new DigestInputStream(uploadForm.getFileStream(), md);
+ tempFile = transFileService.persistToTempFile(fileContents);
+ String md5hash = new String(Hex.encodeHex(md.digest()));
+ if (!md5hash.equals(uploadForm.getHash()))
+ {
+ throw new ChunkUploadException(Status.CONFLICT,
+ "MD5 hash \"" + uploadForm.getHash() +
+ "\" sent with request does not match server-generated hash. " +
+ "Aborted upload operation.");
+ }
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR,
+ "MD5 hash algorithm not available", e);
+ }
+ return tempFile;
+ }
+
+ public static void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm,
+ VirusScanner virusScanner,
+ DocumentDAO documentDAO,
+ DocumentService documentServiceImpl,
+ TranslationFileService translationFileServiceImpl,
+ ZanataIdentity identity)
+ {
+ String name = projectSlug+":"+iterationSlug+":"+docId;
+ try
+ {
+ virusScanner.scan(tempFile, name);
+ }
+ catch (VirusDetectedException e)
+ {
+ log.warn("File failed virus scan: {}", e.getMessage());
+ throw new ChunkUploadException(Status.BAD_REQUEST, "Uploaded file did not pass virus scan");
+ }
+
+ HDocument document;
+ Optional params;
+ params = Optional.fromNullable(Strings.emptyToNull(uploadForm.getAdapterParams()));
+ if (!params.isPresent())
+ {
+ params = documentDAO.getAdapterParams(projectSlug, iterationSlug, docId);
+ }
+ try {
+ Resource doc = translationFileServiceImpl.parseUpdatedAdapterDocumentFile(tempFile.toURI(), docId, uploadForm.getFileType(), params);
+ doc.setLang( new LocaleId("en-US") );
+ // TODO Copy Trans values
+ document = documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, Collections.emptySet(), false);
+ }
+ catch (SecurityException e)
+ {
+ throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR, e.getMessage(), e);
+ }
+ catch (ZanataServiceException e)
+ {
+ throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR, e.getMessage(), e);
+ }
+
+ HRawDocument rawDocument = new HRawDocument();
+ rawDocument.setDocument(document);
+ rawDocument.setContentHash(uploadForm.getHash());
+ rawDocument.setType(DocumentType.typeFor(uploadForm.getFileType()));
+ rawDocument.setUploadedBy(identity.getCredentials().getUsername());
+ FileInputStream tempFileStream;
+ try
+ {
+ tempFileStream = new FileInputStream(tempFile);
+ }
+ catch (FileNotFoundException e)
+ {
+ log.error("Failed to open stream from temp source file", e);
+ throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR,
+ "Error saving uploaded document on server, download in original format may fail.\n",
+ e);
+ }
+ LobHelper lobHelper = documentDAO.getLobHelper();
+ Blob fileContents = lobHelper.createBlob(tempFileStream, (int)tempFile.length());
+ rawDocument.setContent(fileContents);
+ if (params.isPresent())
+ {
+ rawDocument.setAdapterParameters(params.get());
+ }
+ documentDAO.addRawDocument(document, rawDocument);
+ documentDAO.flush();
+
+ translationFileServiceImpl.removeTempFile(tempFile);
+ }
+
+ public static Response sourceUploadSuccessResponse(boolean isNewDocument, int acceptedChunks)
+ {
+ Response response;
+ ChunkUploadResponse uploadResponse = new ChunkUploadResponse();
+ uploadResponse.setAcceptedChunks(acceptedChunks);
+ uploadResponse.setExpectingMore(false);
+ if (isNewDocument)
+ {
+ uploadResponse.setSuccessMessage("Upload of new source document successful.");
+ response = Response.status(Status.CREATED)
+ .entity(uploadResponse)
+ .build();
+ }
+ else
+ {
+ uploadResponse.setSuccessMessage("Upload of new version of source document successful.");
+ response = Response.status(Status.OK)
+ .entity(uploadResponse)
+ .build();
+ }
+ return response;
+ }
+
+}
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index e1a0931fb6..f22fd72b91 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -26,12 +26,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.SequenceInputStream;
import java.net.URI;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.sql.Blob;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
@@ -40,7 +35,6 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-import java.util.Vector;
import javax.annotation.Nonnull;
import javax.ws.rs.Consumes;
@@ -58,15 +52,11 @@
import lombok.extern.slf4j.Slf4j;
-import org.hibernate.Criteria;
-import org.hibernate.LobHelper;
import org.hibernate.Session;
-import org.hibernate.criterion.Restrictions;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.security.AuthorizationException;
-import org.jboss.seam.util.Hex;
import org.zanata.adapter.FileFormatAdapter;
import org.zanata.adapter.po.PoWriter2;
import org.zanata.common.ContentState;
@@ -78,16 +68,11 @@
import org.zanata.dao.LocaleDAO;
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.exception.ChunkUploadException;
-import org.zanata.exception.HashMismatchException;
-import org.zanata.exception.VirusDetectedException;
-import org.zanata.exception.ZanataServiceException;
-import org.zanata.file.GlobalDocumentId;
+import org.zanata.file.DocumentUpload;
import org.zanata.model.HDocument;
import org.zanata.model.HDocumentUpload;
-import org.zanata.model.HDocumentUploadPart;
import org.zanata.model.HLocale;
import org.zanata.model.HProjectIteration;
-import org.zanata.model.HRawDocument;
import org.zanata.rest.DocumentFileUploadForm;
import org.zanata.rest.StringSet;
import org.zanata.rest.dto.ChunkUploadResponse;
@@ -153,7 +138,6 @@ public class FileService implements FileResource
// FIXME remove when using DAO for HDocumentUpload
@In
private Session session;
- private static final HLocale NULL_LOCALE = null;
@Override
@GET
@@ -177,472 +161,11 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
@QueryParam("docId") String docId,
@MultipartForm DocumentFileUploadForm uploadForm )
{
- return tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm,
+ return DocumentUpload.tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm,
identity, session, translationFileServiceImpl, projectIterationDAO,
documentDAO, documentServiceImpl, virusScanner);
}
- private static Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm,
- ZanataIdentity identity,
- Session session,
- TranslationFileService translationFileServiceImpl,
- ProjectIterationDAO projectIterationDAO,
- DocumentDAO documentDAO,
- DocumentService documentServiceImpl,
- VirusScanner virusScanner)
- {
- try
- {
- GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
- checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity,
- session, projectIterationDAO, translationFileServiceImpl);
-
- Optional tempFile;
- int totalChunks;
-
- if (!uploadForm.getLast())
- {
- HDocumentUpload upload = saveUploadPart(id.getProjectSlug(), id.getVersionSlug(),
- id.getDocId(), NULL_LOCALE, uploadForm, session, projectIterationDAO);
- totalChunks = upload.getParts().size();
- return Response.status(Status.ACCEPTED)
- .entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
- "Chunk accepted, awaiting remaining chunks."))
- .build();
- }
-
- if (isSinglePart(uploadForm))
- {
- totalChunks = 1;
- tempFile = Optional.absent();
- }
- else
- {
- HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE,
- uploadForm, session, projectIterationDAO);
- totalChunks = upload.getParts().size();
- tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
- }
-
- if (uploadForm.getFileType().equals(".pot"))
- {
- InputStream potStream = getInputStream(tempFile, uploadForm);
- parsePotFile(potStream, projectSlug, iterationSlug, docId, uploadForm,
- translationFileServiceImpl, documentServiceImpl, documentDAO);
- }
- else
- {
- if (!tempFile.isPresent())
- {
- tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
- }
- processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm,
- virusScanner, documentDAO, documentServiceImpl, translationFileServiceImpl,
- identity);
- }
- if (tempFile.isPresent())
- {
- tempFile.get().delete();
- }
- return sourceUploadSuccessResponse(isNewDocument(projectSlug, iterationSlug, docId, documentDAO), totalChunks);
- }
- catch (ChunkUploadException e)
- {
- return Response.status(e.getStatusCode())
- .entity(new ChunkUploadResponse(e.getMessage()))
- .build();
- }
- catch (FileNotFoundException e)
- {
- log.error("failed to create input stream from temp file", e);
- return Response.status(Status.INTERNAL_SERVER_ERROR)
- .entity(e).build();
- }
- }
-
- private static InputStream getInputStream(Optional tempFile, DocumentFileUploadForm uploadForm) throws FileNotFoundException
- {
- if (tempFile.isPresent())
- {
- return new FileInputStream(tempFile.get());
- }
- else
- {
- return uploadForm.getFileStream();
- }
- }
-
- private static void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm,
- ZanataIdentity identity,
- Session session,
- ProjectIterationDAO projectIterationDAO,
- TranslationFileService translationFileServiceImpl)
- {
- try
- {
- checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
- checkSourceUploadAllowed(projectSlug, iterationSlug, identity, projectIterationDAO);
- }
- catch (AuthorizationException e)
- {
- throw new ChunkUploadException(Status.UNAUTHORIZED, e.getMessage());
- }
- checkValidSourceUploadType(uploadForm, translationFileServiceImpl);
- }
-
- private static void checkSourceUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
- {
- if (!isDocumentUploadAllowed(projectSlug, iterationSlug, identity, projIterDAO))
- {
- throw new ChunkUploadException(Status.FORBIDDEN,
- "You do not have permission to upload source documents to project-version \""
- + projectSlug + ":" + iterationSlug + "\".");
- }
- }
-
- private static boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
- {
- HProjectIteration projectIteration = projIterDAO.getBySlug(projectSlug, iterationSlug);
- return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
- && identity != null && identity.hasPermission("import-template", projectIteration);
- }
-
- private static void checkValidSourceUploadType(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
- {
- if (!uploadForm.getFileType().equals(".pot")
- && !transFileService.hasAdapterFor(DocumentType.typeFor(uploadForm.getFileType())))
- {
- throw new ChunkUploadException(Status.BAD_REQUEST,
- "The type \"" + uploadForm.getFileType() + "\" specified in form parameter 'type' "
- + "is not valid for a source file on this server.");
- }
- }
-
- private static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
- {
- File tempFile;
- try
- {
- MessageDigest md = MessageDigest.getInstance("MD5");
- InputStream fileContents = new DigestInputStream(uploadForm.getFileStream(), md);
- tempFile = transFileService.persistToTempFile(fileContents);
- String md5hash = new String(Hex.encodeHex(md.digest()));
- if (!md5hash.equals(uploadForm.getHash()))
- {
- throw new ChunkUploadException(Status.CONFLICT,
- "MD5 hash \"" + uploadForm.getHash() +
- "\" sent with request does not match server-generated hash. " +
- "Aborted upload operation.");
- }
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR,
- "MD5 hash algorithm not available", e);
- }
- return tempFile;
- }
-
- private static void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm,
- VirusScanner virusScanner,
- DocumentDAO documentDAO,
- DocumentService documentServiceImpl,
- TranslationFileService translationFileServiceImpl,
- ZanataIdentity identity)
- {
- String name = projectSlug+":"+iterationSlug+":"+docId;
- try
- {
- virusScanner.scan(tempFile, name);
- }
- catch (VirusDetectedException e)
- {
- log.warn("File failed virus scan: {}", e.getMessage());
- throw new ChunkUploadException(Status.BAD_REQUEST, "Uploaded file did not pass virus scan");
- }
-
- HDocument document;
- Optional params;
- params = Optional.fromNullable(Strings.emptyToNull(uploadForm.getAdapterParams()));
- if (!params.isPresent())
- {
- params = documentDAO.getAdapterParams(projectSlug, iterationSlug, docId);
- }
- try {
- Resource doc = translationFileServiceImpl.parseUpdatedAdapterDocumentFile(tempFile.toURI(), docId, uploadForm.getFileType(), params);
- doc.setLang( new LocaleId("en-US") );
- // TODO Copy Trans values
- document = documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, Collections.emptySet(), false);
- }
- catch (SecurityException e)
- {
- throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR, e.getMessage(), e);
- }
- catch (ZanataServiceException e)
- {
- throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR, e.getMessage(), e);
- }
-
- HRawDocument rawDocument = new HRawDocument();
- rawDocument.setDocument(document);
- rawDocument.setContentHash(uploadForm.getHash());
- rawDocument.setType(DocumentType.typeFor(uploadForm.getFileType()));
- rawDocument.setUploadedBy(identity.getCredentials().getUsername());
- FileInputStream tempFileStream;
- try
- {
- tempFileStream = new FileInputStream(tempFile);
- }
- catch (FileNotFoundException e)
- {
- log.error("Failed to open stream from temp source file", e);
- throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR,
- "Error saving uploaded document on server, download in original format may fail.\n",
- e);
- }
- LobHelper lobHelper = documentDAO.getLobHelper();
- Blob fileContents = lobHelper.createBlob(tempFileStream, (int)tempFile.length());
- rawDocument.setContent(fileContents);
- if (params.isPresent())
- {
- rawDocument.setAdapterParameters(params.get());
- }
- documentDAO.addRawDocument(document, rawDocument);
- documentDAO.flush();
-
- translationFileServiceImpl.removeTempFile(tempFile);
- }
-
- private static File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload, Session session,
- TranslationFileService transFileService)
- {
- File tempFile;
- try
- {
- tempFile = combineToTempFile(upload, transFileService);
- }
- catch (HashMismatchException e)
- {
- throw new ChunkUploadException(Status.CONFLICT,
- "MD5 hash \"" + e.getExpectedHash() + "\" sent with initial request does not match" +
- " server-generated hash of combined parts \"" + e.getGeneratedHash() +
- "\". Upload aborted. Retry upload from first part.");
- }
- catch (SQLException e)
- {
- throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR,
- "Error while retreiving document upload part contents", e);
- }
- finally
- {
- // no more need for upload
- session.delete(upload);
- }
- return tempFile;
- }
-
- private static boolean isSinglePart(DocumentFileUploadForm uploadForm)
- {
- return uploadForm.getFirst() && uploadForm.getLast();
- }
-
- private static boolean isNewDocument(String projectSlug, String iterationSlug, String docId, DocumentDAO dao)
- {
- return dao.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId) == null;
- }
-
- private static File combineToTempFile(HDocumentUpload upload, TranslationFileService service) throws SQLException
- {
- Vector partStreams = new Vector();
- for (HDocumentUploadPart part : upload.getParts())
- {
- partStreams.add(part.getContent().getBinaryStream());
- }
-
- MessageDigest md;
- try
- {
- md = MessageDigest.getInstance("MD5");
- }
- catch (NoSuchAlgorithmException e)
- {
- log.error("MD5 algorithm not available.", e);
- throw new RuntimeException(e);
- }
- InputStream combinedParts = new SequenceInputStream(partStreams.elements());
- combinedParts = new DigestInputStream(combinedParts, md);
- File tempFile = service.persistToTempFile(combinedParts);
- String md5hash = new String(Hex.encodeHex(md.digest()));
-
- if (!md5hash.equals(upload.getContentHash()))
- {
- throw new HashMismatchException("MD5 hashes do not match.\n", upload.getContentHash(), md5hash);
- }
- return tempFile;
- }
-
- private static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploadForm, Session session)
- {
- // TODO put in DAO
- Criteria criteria = session.createCriteria(HDocumentUpload.class);
- criteria.add(Restrictions.idEq(uploadForm.getUploadId()));
- HDocumentUpload upload = (HDocumentUpload) criteria.uniqueResult();
- return upload;
- }
-
- private static HDocumentUpload createMultipartUpload(String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm, HLocale locale,
- ProjectIterationDAO projectIterationDAO)
- {
- HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
- HDocumentUpload newUpload = new HDocumentUpload();
- newUpload.setProjectIteration(projectIteration);
- newUpload.setDocId(docId);
- newUpload.setType(DocumentType.typeFor(uploadForm.getFileType()));
- // locale intentionally left null for source
- newUpload.setLocale(locale);
- newUpload.setContentHash(uploadForm.getHash());
- return newUpload;
- }
-
- private static void checkUploadPreconditions(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm, ZanataIdentity identity,
- ProjectIterationDAO projectIterationDAO, Session session)
- {
- if (!identity.isLoggedIn())
- {
- throw new AuthorizationException("Valid combination of username and api-key for this" +
- " server were not included in the request.");
- }
-
- if (docId == null || docId.isEmpty())
- {
- throw new ChunkUploadException(Status.PRECONDITION_FAILED,
- "Required query string parameter 'docId' was not found.");
- }
-
- if (uploadForm.getFileStream() == null)
- {
- throw new ChunkUploadException(Status.PRECONDITION_FAILED,
- "Required form parameter 'file' containing file content was not found.");
- }
-
- if (uploadForm.getFirst() == null || uploadForm.getLast() == null)
- {
- throw new ChunkUploadException(Status.PRECONDITION_FAILED,
- "Form parameters 'first' and 'last' must both be provided.");
- }
-
- if (!uploadForm.getFirst())
- {
- if (uploadForm.getUploadId() == null)
- {
- throw new ChunkUploadException(Status.PRECONDITION_FAILED,
- "Form parameter 'uploadId' must be provided when this is not the first part.");
- }
-
- HDocumentUpload upload = retrieveUploadObject(uploadForm, session);
- if (upload == null)
- {
- throw new ChunkUploadException(Status.PRECONDITION_FAILED,
- "No incomplete uploads found for uploadId '" + uploadForm.getUploadId() + "'.");
- }
- if (!upload.getDocId().equals(docId))
- {
- throw new ChunkUploadException(Status.PRECONDITION_FAILED,
- "Supplied uploadId '" + uploadForm.getUploadId()
- + "' in request is not valid for document '" + docId + "'.");
- }
- }
-
- String fileType = uploadForm.getFileType();
- if (fileType == null || fileType.isEmpty())
- {
- throw new ChunkUploadException(Status.PRECONDITION_FAILED,
- "Required form parameter 'type' was not found.");
- }
-
- if (DocumentType.typeFor(fileType) == null)
- {
- throw new ChunkUploadException(Status.PRECONDITION_FAILED,
- "Value '" + fileType + "' is not a recognized document type.");
- }
-
- String contentHash = uploadForm.getHash();
- if (contentHash == null || contentHash.isEmpty())
- {
- throw new ChunkUploadException(Status.PRECONDITION_FAILED,
- "Required form parameter 'hash' was not found.");
- }
-
- HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
- if (projectIteration == null)
- {
- throw new ChunkUploadException(Status.NOT_FOUND,
- "The specified project-version \"" + projectSlug + ":" + iterationSlug +
- "\" does not exist on this server.");
- }
-
- if (projectIteration.getProject().getStatus() != EntityStatus.ACTIVE)
- {
- throw new ChunkUploadException(Status.FORBIDDEN,
- "The project \"" + projectSlug + "\" is not active. Document upload is not allowed.");
- }
-
- if (projectIteration.getStatus() != EntityStatus.ACTIVE)
- {
- throw new ChunkUploadException(Status.FORBIDDEN,
- "The project-version \"" + projectSlug + ":" + iterationSlug +
- "\" is not active. Document upload is not allowed.");
- }
- }
-
- private static void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm,
- TranslationFileService translationFileServiceImpl,
- DocumentService documentServiceImpl,
- DocumentDAO documentDAO)
- {
- Resource doc;
- doc = translationFileServiceImpl.parseUpdatedPotFile(potStream, docId, uploadForm.getFileType(),
- useOfflinePo(projectSlug, iterationSlug, docId, documentDAO, translationFileServiceImpl));
- doc.setLang( new LocaleId("en-US") );
- // TODO Copy Trans values
- documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, new StringSet(ExtensionType.GetText.toString()), false);
- }
-
- private static boolean useOfflinePo(String projectSlug, String iterationSlug, String docId,
- DocumentDAO documentDAO, TranslationFileService translationFileServiceImpl)
- {
- return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
- }
-
- private static Response sourceUploadSuccessResponse(boolean isNewDocument, int acceptedChunks)
- {
- Response response;
- ChunkUploadResponse uploadResponse = new ChunkUploadResponse();
- uploadResponse.setAcceptedChunks(acceptedChunks);
- uploadResponse.setExpectingMore(false);
- if (isNewDocument)
- {
- uploadResponse.setSuccessMessage("Upload of new source document successful.");
- response = Response.status(Status.CREATED)
- .entity(uploadResponse)
- .build();
- }
- else
- {
- uploadResponse.setSuccessMessage("Upload of new version of source document successful.");
- response = Response.status(Status.OK)
- .entity(uploadResponse)
- .build();
- }
- return response;
- }
-
// TODO this shares a lot of logic with .uploadSourceFile(), try to unify.
@Override
@POST
@@ -671,14 +194,14 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
Optional tempFile;
int totalChunks;
- if (isSinglePart(uploadForm))
+ if (DocumentUpload.isSinglePart(uploadForm))
{
totalChunks = 1;
tempFile = Optional.absent();
}
else
{
- HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, locale,
+ HDocumentUpload upload = DocumentUpload.saveUploadPart(projectSlug, iterationSlug, docId, locale,
uploadForm, session, projectIterationDAO);
totalChunks = upload.getParts().size();
if (!uploadForm.getLast())
@@ -688,20 +211,20 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
"Chunk accepted, awaiting remaining chunks."))
.build();
}
- tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
+ tempFile = Optional.of(DocumentUpload.combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
}
TranslationsResource transRes;
if (uploadForm.getFileType().equals(".po"))
{
- InputStream poStream = getInputStream(tempFile, uploadForm);
+ InputStream poStream = DocumentUpload.getInputStream(tempFile, uploadForm);
transRes = translationFileServiceImpl.parsePoFile(poStream, projectSlug, iterationSlug, docId);
}
else
{
if (!tempFile.isPresent())
{
- tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
+ tempFile = Optional.of(DocumentUpload.persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
}
// FIXME this is misusing the 'filename' field. the method should probably take a
// type anyway
@@ -783,34 +306,6 @@ private Set newExtensions(boolean gettextExtensions)
return extensions;
}
- private static HDocumentUpload saveUploadPart(String projectSlug, String iterationSlug, String docId,
- HLocale locale, DocumentFileUploadForm uploadForm, Session session,
- ProjectIterationDAO projectIterationDAO)
- {
- HDocumentUpload upload;
- if (uploadForm.getFirst())
- {
- upload = createMultipartUpload(projectSlug, iterationSlug, docId, uploadForm, locale, projectIterationDAO);
- }
- else
- {
- upload = retrieveUploadObject(uploadForm, session);
- }
- saveUploadPart(uploadForm, upload, session);
- return upload;
- }
-
- private static void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentUpload upload,
- Session session)
- {
- Blob partContent = session.getLobHelper().createBlob(uploadForm.getFileStream(), uploadForm.getSize().intValue());
- HDocumentUploadPart newPart = new HDocumentUploadPart();
- newPart.setContent(partContent);
- upload.getParts().add(newPart);
- session.saveOrUpdate(upload);
- session.flush();
- }
-
private void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale)
{
if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale))
@@ -854,7 +349,7 @@ private HLocale findHLocale(String localeString)
private void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug, String docId, String localeId, DocumentFileUploadForm uploadForm)
{
- checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
+ DocumentUpload.checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
// TODO check translation upload allowed
@@ -876,7 +371,7 @@ private void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm)
private void checkDocumentExists(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
{
- if (isNewDocument(projectSlug, iterationSlug, docId, documentDAO))
+ if (DocumentUpload.isNewDocument(projectSlug, iterationSlug, docId, documentDAO))
{
throw new ChunkUploadException(Status.NOT_FOUND,
"No document with id \"" + docId + "\" exists in project-version \"" +
From 01fd646c05d1a0ce1991ab0fe80dcbb1e00016d2 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 09:01:28 +1000
Subject: [PATCH 117/184] make tryUploadSourceFile an instance method (mikado
method)
---
zanata-war/src/main/java/org/zanata/file/DocumentUpload.java | 2 +-
.../src/main/java/org/zanata/rest/service/FileService.java | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
index 8271a9e300..46cf6fd5a4 100644
--- a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
@@ -79,7 +79,7 @@ public class DocumentUpload
public static final HLocale NULL_LOCALE = null;
- public static Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
+ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
DocumentFileUploadForm uploadForm,
ZanataIdentity identity,
Session session,
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index f22fd72b91..c4ed7f4529 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -161,7 +161,8 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
@QueryParam("docId") String docId,
@MultipartForm DocumentFileUploadForm uploadForm )
{
- return DocumentUpload.tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm,
+ DocumentUpload upload = new DocumentUpload();
+ return upload.tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm,
identity, session, translationFileServiceImpl, projectIterationDAO,
documentDAO, documentServiceImpl, virusScanner);
}
From 363ff91efd20f4ad6e687d119f09090ef6110599 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 09:15:06 +1000
Subject: [PATCH 118/184] make helper arguments for source upload into instance
fields (mikado method)
---
.../java/org/zanata/file/DocumentUpload.java | 30 +++++++++++++++----
.../org/zanata/rest/service/FileService.java | 9 +++---
2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
index 46cf6fd5a4..38d0b55341 100644
--- a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
@@ -79,15 +79,35 @@ public class DocumentUpload
public static final HLocale NULL_LOCALE = null;
- public Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm,
+ private final DocumentService documentServiceImpl;
+ private final VirusScanner virusScanner;
+ private final ZanataIdentity identity;
+ private final Session session;
+ private final DocumentDAO documentDAO;
+ private final ProjectIterationDAO projectIterationDAO;
+ private final TranslationFileService translationFileServiceImpl;
+
+
+ public DocumentUpload(
ZanataIdentity identity,
Session session,
- TranslationFileService translationFileServiceImpl,
- ProjectIterationDAO projectIterationDAO,
DocumentDAO documentDAO,
+ ProjectIterationDAO projectIterationDAO,
DocumentService documentServiceImpl,
- VirusScanner virusScanner)
+ VirusScanner virusScanner,
+ TranslationFileService translationFileServiceImpl)
+ {
+ this.identity = identity;
+ this.session = session;
+ this.documentDAO = documentDAO;
+ this.projectIterationDAO = projectIterationDAO;
+ this.documentServiceImpl = documentServiceImpl;
+ this.virusScanner = virusScanner;
+ this.translationFileServiceImpl = translationFileServiceImpl;
+ }
+
+ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm)
{
try
{
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index c4ed7f4529..2c7b52cad4 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -161,13 +161,12 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
@QueryParam("docId") String docId,
@MultipartForm DocumentFileUploadForm uploadForm )
{
- DocumentUpload upload = new DocumentUpload();
- return upload.tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm,
- identity, session, translationFileServiceImpl, projectIterationDAO,
- documentDAO, documentServiceImpl, virusScanner);
+ DocumentUpload uploader = new DocumentUpload(identity, session, documentDAO, projectIterationDAO,
+ documentServiceImpl, virusScanner, translationFileServiceImpl);
+ return uploader.tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm);
}
- // TODO this shares a lot of logic with .uploadSourceFile(), try to unify.
+ // TODO this shares a lot of logic with .tryUploadSourceFile(), try to unify.
@Override
@POST
@Path(TRANSLATION_UPLOAD_TEMPLATE)
From 4512ce78209fe6e41abc6ca226d3d0521d9351d4 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 09:20:50 +1000
Subject: [PATCH 119/184] make source upload helper methods private (mikado
method)
---
.../java/org/zanata/file/DocumentUpload.java | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
index 38d0b55341..85a93b9c9c 100644
--- a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
@@ -178,7 +178,7 @@ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, St
}
}
- public static void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
+ private static void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
DocumentFileUploadForm uploadForm,
ZanataIdentity identity,
Session session,
@@ -289,7 +289,7 @@ public static void checkUploadPreconditions(String projectSlug, String iteration
}
}
- public static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploadForm, Session session)
+ private static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploadForm, Session session)
{
// TODO put in DAO
Criteria criteria = session.createCriteria(HDocumentUpload.class);
@@ -298,7 +298,7 @@ public static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm upload
return upload;
}
- public static void checkSourceUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
+ private static void checkSourceUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
{
if (!isDocumentUploadAllowed(projectSlug, iterationSlug, identity, projIterDAO))
{
@@ -308,14 +308,14 @@ public static void checkSourceUploadAllowed(String projectSlug, String iteration
}
}
- public static boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
+ private static boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
{
HProjectIteration projectIteration = projIterDAO.getBySlug(projectSlug, iterationSlug);
return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
&& identity != null && identity.hasPermission("import-template", projectIteration);
}
- public static void checkValidSourceUploadType(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
+ private static void checkValidSourceUploadType(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
{
if (!uploadForm.getFileType().equals(".pot")
&& !transFileService.hasAdapterFor(DocumentType.typeFor(uploadForm.getFileType())))
@@ -343,7 +343,7 @@ public static HDocumentUpload saveUploadPart(String projectSlug, String iteratio
return upload;
}
- public static HDocumentUpload createMultipartUpload(String projectSlug, String iterationSlug,
+ private static HDocumentUpload createMultipartUpload(String projectSlug, String iterationSlug,
String docId, DocumentFileUploadForm uploadForm, HLocale locale,
ProjectIterationDAO projectIterationDAO)
{
@@ -358,7 +358,7 @@ public static HDocumentUpload createMultipartUpload(String projectSlug, String i
return newUpload;
}
- public static void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentUpload upload,
+ private static void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentUpload upload,
Session session)
{
Blob partContent = session.getLobHelper().createBlob(uploadForm.getFileStream(), uploadForm.getSize().intValue());
@@ -402,7 +402,7 @@ public static File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload
return tempFile;
}
- public static File combineToTempFile(HDocumentUpload upload, TranslationFileService service) throws SQLException
+ private static File combineToTempFile(HDocumentUpload upload, TranslationFileService service) throws SQLException
{
Vector partStreams = new Vector();
for (HDocumentUploadPart part : upload.getParts())
@@ -444,7 +444,7 @@ public static InputStream getInputStream(Optional tempFile, DocumentFileUp
}
}
- public static void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
+ private static void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
String docId, DocumentFileUploadForm uploadForm,
TranslationFileService translationFileServiceImpl,
DocumentService documentServiceImpl,
@@ -458,7 +458,7 @@ public static void parsePotFile(InputStream potStream, String projectSlug, Strin
documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, new StringSet(ExtensionType.GetText.toString()), false);
}
- public static boolean useOfflinePo(String projectSlug, String iterationSlug, String docId,
+ private static boolean useOfflinePo(String projectSlug, String iterationSlug, String docId,
DocumentDAO documentDAO, TranslationFileService translationFileServiceImpl)
{
return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
@@ -494,7 +494,7 @@ public static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm,
return tempFile;
}
- public static void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
+ private static void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
String docId, DocumentFileUploadForm uploadForm,
VirusScanner virusScanner,
DocumentDAO documentDAO,
@@ -565,7 +565,7 @@ public static void processAdapterFile(@Nonnull File tempFile, String projectSlug
translationFileServiceImpl.removeTempFile(tempFile);
}
- public static Response sourceUploadSuccessResponse(boolean isNewDocument, int acceptedChunks)
+ private static Response sourceUploadSuccessResponse(boolean isNewDocument, int acceptedChunks)
{
Response response;
ChunkUploadResponse uploadResponse = new ChunkUploadResponse();
From 425a3251d701dee9d047e539946e7c6bdca8b5df Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 09:36:54 +1000
Subject: [PATCH 120/184] move source upload and helper methods to subclass
(mikado method)
---
.../java/org/zanata/file/DocumentUpload.java | 264 +-------------
.../org/zanata/file/SourceDocumentUpload.java | 322 ++++++++++++++++++
.../org/zanata/rest/service/FileService.java | 3 +-
3 files changed, 331 insertions(+), 258 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
diff --git a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
index 85a93b9c9c..12c8521e56 100644
--- a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
@@ -30,63 +30,46 @@
import java.security.NoSuchAlgorithmException;
import java.sql.Blob;
import java.sql.SQLException;
-import java.util.Collections;
import java.util.Vector;
-import javax.annotation.Nonnull;
-import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.Criteria;
-import org.hibernate.LobHelper;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.jboss.seam.security.AuthorizationException;
import org.jboss.seam.util.Hex;
import org.zanata.common.DocumentType;
import org.zanata.common.EntityStatus;
-import org.zanata.common.LocaleId;
import org.zanata.dao.DocumentDAO;
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.exception.ChunkUploadException;
import org.zanata.exception.HashMismatchException;
-import org.zanata.exception.VirusDetectedException;
-import org.zanata.exception.ZanataServiceException;
-import org.zanata.model.HDocument;
import org.zanata.model.HDocumentUpload;
import org.zanata.model.HDocumentUploadPart;
import org.zanata.model.HLocale;
import org.zanata.model.HProjectIteration;
-import org.zanata.model.HRawDocument;
import org.zanata.rest.DocumentFileUploadForm;
-import org.zanata.rest.StringSet;
-import org.zanata.rest.dto.ChunkUploadResponse;
-import org.zanata.rest.dto.extensions.ExtensionType;
-import org.zanata.rest.dto.resource.Resource;
import org.zanata.rest.service.VirusScanner;
import org.zanata.security.ZanataIdentity;
import org.zanata.service.DocumentService;
import org.zanata.service.TranslationFileService;
import com.google.common.base.Optional;
-import com.google.common.base.Strings;
@Slf4j
public class DocumentUpload
{
- public static final HLocale NULL_LOCALE = null;
-
- private final DocumentService documentServiceImpl;
- private final VirusScanner virusScanner;
- private final ZanataIdentity identity;
- private final Session session;
- private final DocumentDAO documentDAO;
- private final ProjectIterationDAO projectIterationDAO;
- private final TranslationFileService translationFileServiceImpl;
-
+ protected final DocumentService documentServiceImpl;
+ protected final VirusScanner virusScanner;
+ protected final ZanataIdentity identity;
+ protected final Session session;
+ protected final DocumentDAO documentDAO;
+ protected final ProjectIterationDAO projectIterationDAO;
+ protected final TranslationFileService translationFileServiceImpl;
public DocumentUpload(
ZanataIdentity identity,
@@ -106,97 +89,6 @@ public DocumentUpload(
this.translationFileServiceImpl = translationFileServiceImpl;
}
- public Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm)
- {
- try
- {
- GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
- checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity,
- session, projectIterationDAO, translationFileServiceImpl);
-
- Optional tempFile;
- int totalChunks;
-
- if (!uploadForm.getLast())
- {
- HDocumentUpload upload = saveUploadPart(id.getProjectSlug(), id.getVersionSlug(),
- id.getDocId(), NULL_LOCALE, uploadForm, session, projectIterationDAO);
- totalChunks = upload.getParts().size();
- return Response.status(Status.ACCEPTED)
- .entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
- "Chunk accepted, awaiting remaining chunks."))
- .build();
- }
-
- if (isSinglePart(uploadForm))
- {
- totalChunks = 1;
- tempFile = Optional.absent();
- }
- else
- {
- HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE,
- uploadForm, session, projectIterationDAO);
- totalChunks = upload.getParts().size();
- tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
- }
-
- if (uploadForm.getFileType().equals(".pot"))
- {
- InputStream potStream = getInputStream(tempFile, uploadForm);
- parsePotFile(potStream, projectSlug, iterationSlug, docId, uploadForm,
- translationFileServiceImpl, documentServiceImpl, documentDAO);
- }
- else
- {
- if (!tempFile.isPresent())
- {
- tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
- }
- processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm,
- virusScanner, documentDAO, documentServiceImpl, translationFileServiceImpl,
- identity);
- }
- if (tempFile.isPresent())
- {
- tempFile.get().delete();
- }
- return sourceUploadSuccessResponse(isNewDocument(projectSlug, iterationSlug, docId, documentDAO), totalChunks);
- }
- catch (ChunkUploadException e)
- {
- return Response.status(e.getStatusCode())
- .entity(new ChunkUploadResponse(e.getMessage()))
- .build();
- }
- catch (FileNotFoundException e)
- {
- log.error("failed to create input stream from temp file", e);
- return Response.status(Status.INTERNAL_SERVER_ERROR)
- .entity(e).build();
- }
- }
-
- private static void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm,
- ZanataIdentity identity,
- Session session,
- ProjectIterationDAO projectIterationDAO,
- TranslationFileService translationFileServiceImpl)
- {
- try
- {
- checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
- checkSourceUploadAllowed(projectSlug, iterationSlug, identity, projectIterationDAO);
- }
- catch (AuthorizationException e)
- {
- throw new ChunkUploadException(Status.UNAUTHORIZED, e.getMessage());
- }
- checkValidSourceUploadType(uploadForm, translationFileServiceImpl);
- }
-
public static void checkUploadPreconditions(String projectSlug, String iterationSlug, String docId,
DocumentFileUploadForm uploadForm, ZanataIdentity identity,
ProjectIterationDAO projectIterationDAO, Session session)
@@ -298,34 +190,6 @@ private static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploa
return upload;
}
- private static void checkSourceUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
- {
- if (!isDocumentUploadAllowed(projectSlug, iterationSlug, identity, projIterDAO))
- {
- throw new ChunkUploadException(Status.FORBIDDEN,
- "You do not have permission to upload source documents to project-version \""
- + projectSlug + ":" + iterationSlug + "\".");
- }
- }
-
- private static boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
- {
- HProjectIteration projectIteration = projIterDAO.getBySlug(projectSlug, iterationSlug);
- return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
- && identity != null && identity.hasPermission("import-template", projectIteration);
- }
-
- private static void checkValidSourceUploadType(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
- {
- if (!uploadForm.getFileType().equals(".pot")
- && !transFileService.hasAdapterFor(DocumentType.typeFor(uploadForm.getFileType())))
- {
- throw new ChunkUploadException(Status.BAD_REQUEST,
- "The type \"" + uploadForm.getFileType() + "\" specified in form parameter 'type' "
- + "is not valid for a source file on this server.");
- }
- }
-
public static HDocumentUpload saveUploadPart(String projectSlug, String iterationSlug, String docId,
HLocale locale, DocumentFileUploadForm uploadForm, Session session,
ProjectIterationDAO projectIterationDAO)
@@ -444,26 +308,6 @@ public static InputStream getInputStream(Optional tempFile, DocumentFileUp
}
}
- private static void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm,
- TranslationFileService translationFileServiceImpl,
- DocumentService documentServiceImpl,
- DocumentDAO documentDAO)
- {
- Resource doc;
- doc = translationFileServiceImpl.parseUpdatedPotFile(potStream, docId, uploadForm.getFileType(),
- useOfflinePo(projectSlug, iterationSlug, docId, documentDAO, translationFileServiceImpl));
- doc.setLang( new LocaleId("en-US") );
- // TODO Copy Trans values
- documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, new StringSet(ExtensionType.GetText.toString()), false);
- }
-
- private static boolean useOfflinePo(String projectSlug, String iterationSlug, String docId,
- DocumentDAO documentDAO, TranslationFileService translationFileServiceImpl)
- {
- return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
- }
-
public static boolean isNewDocument(String projectSlug, String iterationSlug, String docId, DocumentDAO dao)
{
return dao.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId) == null;
@@ -494,98 +338,4 @@ public static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm,
return tempFile;
}
- private static void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm,
- VirusScanner virusScanner,
- DocumentDAO documentDAO,
- DocumentService documentServiceImpl,
- TranslationFileService translationFileServiceImpl,
- ZanataIdentity identity)
- {
- String name = projectSlug+":"+iterationSlug+":"+docId;
- try
- {
- virusScanner.scan(tempFile, name);
- }
- catch (VirusDetectedException e)
- {
- log.warn("File failed virus scan: {}", e.getMessage());
- throw new ChunkUploadException(Status.BAD_REQUEST, "Uploaded file did not pass virus scan");
- }
-
- HDocument document;
- Optional params;
- params = Optional.fromNullable(Strings.emptyToNull(uploadForm.getAdapterParams()));
- if (!params.isPresent())
- {
- params = documentDAO.getAdapterParams(projectSlug, iterationSlug, docId);
- }
- try {
- Resource doc = translationFileServiceImpl.parseUpdatedAdapterDocumentFile(tempFile.toURI(), docId, uploadForm.getFileType(), params);
- doc.setLang( new LocaleId("en-US") );
- // TODO Copy Trans values
- document = documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, Collections.emptySet(), false);
- }
- catch (SecurityException e)
- {
- throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR, e.getMessage(), e);
- }
- catch (ZanataServiceException e)
- {
- throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR, e.getMessage(), e);
- }
-
- HRawDocument rawDocument = new HRawDocument();
- rawDocument.setDocument(document);
- rawDocument.setContentHash(uploadForm.getHash());
- rawDocument.setType(DocumentType.typeFor(uploadForm.getFileType()));
- rawDocument.setUploadedBy(identity.getCredentials().getUsername());
- FileInputStream tempFileStream;
- try
- {
- tempFileStream = new FileInputStream(tempFile);
- }
- catch (FileNotFoundException e)
- {
- log.error("Failed to open stream from temp source file", e);
- throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR,
- "Error saving uploaded document on server, download in original format may fail.\n",
- e);
- }
- LobHelper lobHelper = documentDAO.getLobHelper();
- Blob fileContents = lobHelper.createBlob(tempFileStream, (int)tempFile.length());
- rawDocument.setContent(fileContents);
- if (params.isPresent())
- {
- rawDocument.setAdapterParameters(params.get());
- }
- documentDAO.addRawDocument(document, rawDocument);
- documentDAO.flush();
-
- translationFileServiceImpl.removeTempFile(tempFile);
- }
-
- private static Response sourceUploadSuccessResponse(boolean isNewDocument, int acceptedChunks)
- {
- Response response;
- ChunkUploadResponse uploadResponse = new ChunkUploadResponse();
- uploadResponse.setAcceptedChunks(acceptedChunks);
- uploadResponse.setExpectingMore(false);
- if (isNewDocument)
- {
- uploadResponse.setSuccessMessage("Upload of new source document successful.");
- response = Response.status(Status.CREATED)
- .entity(uploadResponse)
- .build();
- }
- else
- {
- uploadResponse.setSuccessMessage("Upload of new version of source document successful.");
- response = Response.status(Status.OK)
- .entity(uploadResponse)
- .build();
- }
- return response;
- }
-
}
diff --git a/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
new file mode 100644
index 0000000000..60001ba8b2
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
@@ -0,0 +1,322 @@
+/*
+ * 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.file;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.sql.Blob;
+import java.util.Collections;
+
+import javax.annotation.Nonnull;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.hibernate.LobHelper;
+import org.hibernate.Session;
+import org.jboss.seam.security.AuthorizationException;
+import org.zanata.common.DocumentType;
+import org.zanata.common.EntityStatus;
+import org.zanata.common.LocaleId;
+import org.zanata.dao.DocumentDAO;
+import org.zanata.dao.ProjectIterationDAO;
+import org.zanata.exception.ChunkUploadException;
+import org.zanata.exception.VirusDetectedException;
+import org.zanata.exception.ZanataServiceException;
+import org.zanata.model.HDocument;
+import org.zanata.model.HDocumentUpload;
+import org.zanata.model.HLocale;
+import org.zanata.model.HProjectIteration;
+import org.zanata.model.HRawDocument;
+import org.zanata.rest.DocumentFileUploadForm;
+import org.zanata.rest.StringSet;
+import org.zanata.rest.dto.ChunkUploadResponse;
+import org.zanata.rest.dto.extensions.ExtensionType;
+import org.zanata.rest.dto.resource.Resource;
+import org.zanata.rest.service.VirusScanner;
+import org.zanata.security.ZanataIdentity;
+import org.zanata.service.DocumentService;
+import org.zanata.service.TranslationFileService;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+
+@Slf4j
+public class SourceDocumentUpload extends DocumentUpload
+{
+
+ private static final HLocale NULL_LOCALE = null;
+
+ public SourceDocumentUpload(ZanataIdentity identity,
+ Session session,
+ DocumentDAO documentDAO,
+ ProjectIterationDAO projectIterationDAO,
+ DocumentService documentServiceImpl,
+ VirusScanner virusScanner,
+ TranslationFileService translationFileServiceImpl)
+ {
+ super(identity,
+ session,
+ documentDAO,
+ projectIterationDAO,
+ documentServiceImpl,
+ virusScanner,
+ translationFileServiceImpl);
+ }
+
+ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm)
+ {
+ try
+ {
+ GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
+ checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity,
+ session, projectIterationDAO, translationFileServiceImpl);
+
+ Optional tempFile;
+ int totalChunks;
+
+ if (!uploadForm.getLast())
+ {
+ HDocumentUpload upload = saveUploadPart(id.getProjectSlug(), id.getVersionSlug(),
+ id.getDocId(), NULL_LOCALE, uploadForm, session, projectIterationDAO);
+ totalChunks = upload.getParts().size();
+ return Response.status(Status.ACCEPTED)
+ .entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
+ "Chunk accepted, awaiting remaining chunks."))
+ .build();
+ }
+
+ if (isSinglePart(uploadForm))
+ {
+ totalChunks = 1;
+ tempFile = Optional. absent();
+ }
+ else
+ {
+ HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE,
+ uploadForm, session, projectIterationDAO);
+ totalChunks = upload.getParts().size();
+ tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
+ }
+
+ if (uploadForm.getFileType().equals(".pot"))
+ {
+ InputStream potStream = getInputStream(tempFile, uploadForm);
+ parsePotFile(potStream, projectSlug, iterationSlug, docId, uploadForm,
+ translationFileServiceImpl, documentServiceImpl, documentDAO);
+ }
+ else
+ {
+ if (!tempFile.isPresent())
+ {
+ tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
+ }
+ processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm,
+ virusScanner, documentDAO, documentServiceImpl, translationFileServiceImpl,
+ identity);
+ }
+ if (tempFile.isPresent())
+ {
+ tempFile.get().delete();
+ }
+ return sourceUploadSuccessResponse(isNewDocument(projectSlug, iterationSlug, docId, documentDAO), totalChunks);
+ }
+ catch (ChunkUploadException e)
+ {
+ return Response.status(e.getStatusCode())
+ .entity(new ChunkUploadResponse(e.getMessage()))
+ .build();
+ }
+ catch (FileNotFoundException e)
+ {
+ log.error("failed to create input stream from temp file", e);
+ return Response.status(Status.INTERNAL_SERVER_ERROR)
+ .entity(e).build();
+ }
+ }
+
+ private static void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm,
+ ZanataIdentity identity,
+ Session session,
+ ProjectIterationDAO projectIterationDAO,
+ TranslationFileService translationFileServiceImpl)
+ {
+ try
+ {
+ checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
+ checkSourceUploadAllowed(projectSlug, iterationSlug, identity, projectIterationDAO);
+ }
+ catch (AuthorizationException e)
+ {
+ throw new ChunkUploadException(Status.UNAUTHORIZED, e.getMessage());
+ }
+ checkValidSourceUploadType(uploadForm, translationFileServiceImpl);
+ }
+
+ private static void checkSourceUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
+ {
+ if (!isDocumentUploadAllowed(projectSlug, iterationSlug, identity, projIterDAO))
+ {
+ throw new ChunkUploadException(Status.FORBIDDEN,
+ "You do not have permission to upload source documents to project-version \""
+ + projectSlug + ":" + iterationSlug + "\".");
+ }
+ }
+
+ private static boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
+ {
+ HProjectIteration projectIteration = projIterDAO.getBySlug(projectSlug, iterationSlug);
+ return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
+ && identity != null && identity.hasPermission("import-template", projectIteration);
+ }
+
+ private static void checkValidSourceUploadType(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
+ {
+ if (!uploadForm.getFileType().equals(".pot")
+ && !transFileService.hasAdapterFor(DocumentType.typeFor(uploadForm.getFileType())))
+ {
+ throw new ChunkUploadException(Status.BAD_REQUEST,
+ "The type \"" + uploadForm.getFileType() + "\" specified in form parameter 'type' "
+ + "is not valid for a source file on this server.");
+ }
+ }
+
+ private static Response sourceUploadSuccessResponse(boolean isNewDocument, int acceptedChunks)
+ {
+ Response response;
+ ChunkUploadResponse uploadResponse = new ChunkUploadResponse();
+ uploadResponse.setAcceptedChunks(acceptedChunks);
+ uploadResponse.setExpectingMore(false);
+ if (isNewDocument)
+ {
+ uploadResponse.setSuccessMessage("Upload of new source document successful.");
+ response = Response.status(Status.CREATED)
+ .entity(uploadResponse)
+ .build();
+ }
+ else
+ {
+ uploadResponse.setSuccessMessage("Upload of new version of source document successful.");
+ response = Response.status(Status.OK)
+ .entity(uploadResponse)
+ .build();
+ }
+ return response;
+ }
+
+ private static void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm,
+ VirusScanner virusScanner,
+ DocumentDAO documentDAO,
+ DocumentService documentServiceImpl,
+ TranslationFileService translationFileServiceImpl,
+ ZanataIdentity identity)
+ {
+ String name = projectSlug + ":" + iterationSlug + ":" + docId;
+ try
+ {
+ virusScanner.scan(tempFile, name);
+ }
+ catch (VirusDetectedException e)
+ {
+ log.warn("File failed virus scan: {}", e.getMessage());
+ throw new ChunkUploadException(Status.BAD_REQUEST, "Uploaded file did not pass virus scan");
+ }
+
+ HDocument document;
+ Optional params;
+ params = Optional.fromNullable(Strings.emptyToNull(uploadForm.getAdapterParams()));
+ if (!params.isPresent())
+ {
+ params = documentDAO.getAdapterParams(projectSlug, iterationSlug, docId);
+ }
+ try
+ {
+ Resource doc = translationFileServiceImpl.parseUpdatedAdapterDocumentFile(tempFile.toURI(), docId, uploadForm.getFileType(), params);
+ doc.setLang(new LocaleId("en-US"));
+ // TODO Copy Trans values
+ document = documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, Collections. emptySet(), false);
+ }
+ catch (SecurityException e)
+ {
+ throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR, e.getMessage(), e);
+ }
+ catch (ZanataServiceException e)
+ {
+ throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR, e.getMessage(), e);
+ }
+
+ HRawDocument rawDocument = new HRawDocument();
+ rawDocument.setDocument(document);
+ rawDocument.setContentHash(uploadForm.getHash());
+ rawDocument.setType(DocumentType.typeFor(uploadForm.getFileType()));
+ rawDocument.setUploadedBy(identity.getCredentials().getUsername());
+ FileInputStream tempFileStream;
+ try
+ {
+ tempFileStream = new FileInputStream(tempFile);
+ }
+ catch (FileNotFoundException e)
+ {
+ log.error("Failed to open stream from temp source file", e);
+ throw new ChunkUploadException(Status.INTERNAL_SERVER_ERROR,
+ "Error saving uploaded document on server, download in original format may fail.\n",
+ e);
+ }
+ LobHelper lobHelper = documentDAO.getLobHelper();
+ Blob fileContents = lobHelper.createBlob(tempFileStream, (int) tempFile.length());
+ rawDocument.setContent(fileContents);
+ if (params.isPresent())
+ {
+ rawDocument.setAdapterParameters(params.get());
+ }
+ documentDAO.addRawDocument(document, rawDocument);
+ documentDAO.flush();
+
+ translationFileServiceImpl.removeTempFile(tempFile);
+ }
+
+ private static void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm,
+ TranslationFileService translationFileServiceImpl,
+ DocumentService documentServiceImpl,
+ DocumentDAO documentDAO)
+ {
+ Resource doc;
+ doc = translationFileServiceImpl.parseUpdatedPotFile(potStream, docId, uploadForm.getFileType(),
+ useOfflinePo(projectSlug, iterationSlug, docId, documentDAO, translationFileServiceImpl));
+ doc.setLang(new LocaleId("en-US"));
+ // TODO Copy Trans values
+ documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, new StringSet(ExtensionType.GetText.toString()), false);
+ }
+
+ private static boolean useOfflinePo(String projectSlug, String iterationSlug, String docId,
+ DocumentDAO documentDAO, TranslationFileService translationFileServiceImpl)
+ {
+ return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
+ }
+
+}
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 2c7b52cad4..179e8edd01 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -69,6 +69,7 @@
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.exception.ChunkUploadException;
import org.zanata.file.DocumentUpload;
+import org.zanata.file.SourceDocumentUpload;
import org.zanata.model.HDocument;
import org.zanata.model.HDocumentUpload;
import org.zanata.model.HLocale;
@@ -161,7 +162,7 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
@QueryParam("docId") String docId,
@MultipartForm DocumentFileUploadForm uploadForm )
{
- DocumentUpload uploader = new DocumentUpload(identity, session, documentDAO, projectIterationDAO,
+ SourceDocumentUpload uploader = new SourceDocumentUpload(identity, session, documentDAO, projectIterationDAO,
documentServiceImpl, virusScanner, translationFileServiceImpl);
return uploader.tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm);
}
From 48bf83b8cc2d6296fd58ef710d90ba7c50412a7d Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 09:48:59 +1000
Subject: [PATCH 121/184] use instance helpers in source upload methods (mikado
method)
---
.../org/zanata/file/SourceDocumentUpload.java | 55 +++++++------------
1 file changed, 19 insertions(+), 36 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
index 60001ba8b2..bbcaba42f6 100644
--- a/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
@@ -91,8 +91,7 @@ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, St
try
{
GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
- checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity,
- session, projectIterationDAO, translationFileServiceImpl);
+ checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm);
Optional tempFile;
int totalChunks;
@@ -124,8 +123,7 @@ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, St
if (uploadForm.getFileType().equals(".pot"))
{
InputStream potStream = getInputStream(tempFile, uploadForm);
- parsePotFile(potStream, projectSlug, iterationSlug, docId, uploadForm,
- translationFileServiceImpl, documentServiceImpl, documentDAO);
+ parsePotFile(potStream, projectSlug, iterationSlug, docId, uploadForm);
}
else
{
@@ -133,9 +131,7 @@ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, St
{
tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
}
- processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm,
- virusScanner, documentDAO, documentServiceImpl, translationFileServiceImpl,
- identity);
+ processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm);
}
if (tempFile.isPresent())
{
@@ -157,28 +153,24 @@ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, St
}
}
- private static void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm,
- ZanataIdentity identity,
- Session session,
- ProjectIterationDAO projectIterationDAO,
- TranslationFileService translationFileServiceImpl)
+ private void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm)
{
try
{
checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
- checkSourceUploadAllowed(projectSlug, iterationSlug, identity, projectIterationDAO);
+ checkSourceUploadAllowed(projectSlug, iterationSlug);
}
catch (AuthorizationException e)
{
throw new ChunkUploadException(Status.UNAUTHORIZED, e.getMessage());
}
- checkValidSourceUploadType(uploadForm, translationFileServiceImpl);
+ checkValidSourceUploadType(uploadForm);
}
- private static void checkSourceUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
+ private void checkSourceUploadAllowed(String projectSlug, String iterationSlug)
{
- if (!isDocumentUploadAllowed(projectSlug, iterationSlug, identity, projIterDAO))
+ if (!isDocumentUploadAllowed(projectSlug, iterationSlug))
{
throw new ChunkUploadException(Status.FORBIDDEN,
"You do not have permission to upload source documents to project-version \""
@@ -186,17 +178,17 @@ private static void checkSourceUploadAllowed(String projectSlug, String iteratio
}
}
- private static boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug, ZanataIdentity identity, ProjectIterationDAO projIterDAO)
+ private boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug)
{
- HProjectIteration projectIteration = projIterDAO.getBySlug(projectSlug, iterationSlug);
+ HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
&& identity != null && identity.hasPermission("import-template", projectIteration);
}
- private static void checkValidSourceUploadType(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
+ private void checkValidSourceUploadType(DocumentFileUploadForm uploadForm)
{
if (!uploadForm.getFileType().equals(".pot")
- && !transFileService.hasAdapterFor(DocumentType.typeFor(uploadForm.getFileType())))
+ && !translationFileServiceImpl.hasAdapterFor(DocumentType.typeFor(uploadForm.getFileType())))
{
throw new ChunkUploadException(Status.BAD_REQUEST,
"The type \"" + uploadForm.getFileType() + "\" specified in form parameter 'type' "
@@ -227,13 +219,8 @@ private static Response sourceUploadSuccessResponse(boolean isNewDocument, int a
return response;
}
- private static void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm,
- VirusScanner virusScanner,
- DocumentDAO documentDAO,
- DocumentService documentServiceImpl,
- TranslationFileService translationFileServiceImpl,
- ZanataIdentity identity)
+ private void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm)
{
String name = projectSlug + ":" + iterationSlug + ":" + docId;
try
@@ -299,22 +286,18 @@ private static void processAdapterFile(@Nonnull File tempFile, String projectSlu
translationFileServiceImpl.removeTempFile(tempFile);
}
- private static void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm,
- TranslationFileService translationFileServiceImpl,
- DocumentService documentServiceImpl,
- DocumentDAO documentDAO)
+ private void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
+ String docId, DocumentFileUploadForm uploadForm)
{
Resource doc;
doc = translationFileServiceImpl.parseUpdatedPotFile(potStream, docId, uploadForm.getFileType(),
- useOfflinePo(projectSlug, iterationSlug, docId, documentDAO, translationFileServiceImpl));
+ useOfflinePo(projectSlug, iterationSlug, docId));
doc.setLang(new LocaleId("en-US"));
// TODO Copy Trans values
documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, new StringSet(ExtensionType.GetText.toString()), false);
}
- private static boolean useOfflinePo(String projectSlug, String iterationSlug, String docId,
- DocumentDAO documentDAO, TranslationFileService translationFileServiceImpl)
+ private boolean useOfflinePo(String projectSlug, String iterationSlug, String docId)
{
return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
}
From b46e6e66bb6957f262ea2917da41763f2ca74a8f Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:26:18 +1000
Subject: [PATCH 122/184] use composite id object for all source upload methods
(mikado method)
---
.../java/org/zanata/file/DocumentUpload.java | 31 +++++-----
.../org/zanata/file/SourceDocumentUpload.java | 58 +++++++++----------
.../org/zanata/rest/service/FileService.java | 11 ++--
3 files changed, 49 insertions(+), 51 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
index 12c8521e56..6875683451 100644
--- a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
@@ -89,7 +89,7 @@ public DocumentUpload(
this.translationFileServiceImpl = translationFileServiceImpl;
}
- public static void checkUploadPreconditions(String projectSlug, String iterationSlug, String docId,
+ public static void checkUploadPreconditions(GlobalDocumentId id,
DocumentFileUploadForm uploadForm, ZanataIdentity identity,
ProjectIterationDAO projectIterationDAO, Session session)
{
@@ -99,7 +99,7 @@ public static void checkUploadPreconditions(String projectSlug, String iteration
" server were not included in the request.");
}
- if (docId == null || docId.isEmpty())
+ if (id.getDocId() == null || id.getDocId().isEmpty())
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Required query string parameter 'docId' was not found.");
@@ -131,11 +131,11 @@ public static void checkUploadPreconditions(String projectSlug, String iteration
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"No incomplete uploads found for uploadId '" + uploadForm.getUploadId() + "'.");
}
- if (!upload.getDocId().equals(docId))
+ if (!upload.getDocId().equals(id.getDocId()))
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Supplied uploadId '" + uploadForm.getUploadId()
- + "' in request is not valid for document '" + docId + "'.");
+ + "' in request is not valid for document '" + id.getDocId() + "'.");
}
}
@@ -159,24 +159,24 @@ public static void checkUploadPreconditions(String projectSlug, String iteration
"Required form parameter 'hash' was not found.");
}
- HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
+ HProjectIteration projectIteration = projectIterationDAO.getBySlug(id.getProjectSlug(), id.getVersionSlug());
if (projectIteration == null)
{
throw new ChunkUploadException(Status.NOT_FOUND,
- "The specified project-version \"" + projectSlug + ":" + iterationSlug +
+ "The specified project-version \"" + id.getProjectSlug() + ":" + id.getVersionSlug() +
"\" does not exist on this server.");
}
if (projectIteration.getProject().getStatus() != EntityStatus.ACTIVE)
{
throw new ChunkUploadException(Status.FORBIDDEN,
- "The project \"" + projectSlug + "\" is not active. Document upload is not allowed.");
+ "The project \"" + id.getProjectSlug() + "\" is not active. Document upload is not allowed.");
}
if (projectIteration.getStatus() != EntityStatus.ACTIVE)
{
throw new ChunkUploadException(Status.FORBIDDEN,
- "The project-version \"" + projectSlug + ":" + iterationSlug +
+ "The project-version \"" + id.getProjectSlug() + ":" + id.getVersionSlug() +
"\" is not active. Document upload is not allowed.");
}
}
@@ -190,14 +190,14 @@ private static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploa
return upload;
}
- public static HDocumentUpload saveUploadPart(String projectSlug, String iterationSlug, String docId,
+ public static HDocumentUpload saveUploadPart(GlobalDocumentId id,
HLocale locale, DocumentFileUploadForm uploadForm, Session session,
ProjectIterationDAO projectIterationDAO)
{
HDocumentUpload upload;
if (uploadForm.getFirst())
{
- upload = createMultipartUpload(projectSlug, iterationSlug, docId, uploadForm, locale, projectIterationDAO);
+ upload = createMultipartUpload(id, uploadForm, locale, projectIterationDAO);
}
else
{
@@ -207,14 +207,13 @@ public static HDocumentUpload saveUploadPart(String projectSlug, String iteratio
return upload;
}
- private static HDocumentUpload createMultipartUpload(String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm, HLocale locale,
+ private static HDocumentUpload createMultipartUpload(GlobalDocumentId id, DocumentFileUploadForm uploadForm, HLocale locale,
ProjectIterationDAO projectIterationDAO)
{
- HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
+ HProjectIteration projectIteration = projectIterationDAO.getBySlug(id.getProjectSlug(), id.getVersionSlug());
HDocumentUpload newUpload = new HDocumentUpload();
newUpload.setProjectIteration(projectIteration);
- newUpload.setDocId(docId);
+ newUpload.setDocId(id.getDocId());
newUpload.setType(DocumentType.typeFor(uploadForm.getFileType()));
// locale intentionally left null for source
newUpload.setLocale(locale);
@@ -308,9 +307,9 @@ public static InputStream getInputStream(Optional tempFile, DocumentFileUp
}
}
- public static boolean isNewDocument(String projectSlug, String iterationSlug, String docId, DocumentDAO dao)
+ public static boolean isNewDocument(GlobalDocumentId id, DocumentDAO dao)
{
- return dao.getByProjectIterationAndDocId(projectSlug, iterationSlug, docId) == null;
+ return dao.getByProjectIterationAndDocId(id.getProjectSlug(), id.getVersionSlug(), id.getDocId()) == null;
}
public static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
diff --git a/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
index bbcaba42f6..c54c45a9a4 100644
--- a/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
@@ -85,21 +85,18 @@ public SourceDocumentUpload(ZanataIdentity identity,
translationFileServiceImpl);
}
- public Response tryUploadSourceFile(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm)
+ public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm uploadForm)
{
try
{
- GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
- checkSourceUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm);
+ checkSourceUploadPreconditions(id, uploadForm);
Optional tempFile;
int totalChunks;
if (!uploadForm.getLast())
{
- HDocumentUpload upload = saveUploadPart(id.getProjectSlug(), id.getVersionSlug(),
- id.getDocId(), NULL_LOCALE, uploadForm, session, projectIterationDAO);
+ HDocumentUpload upload = saveUploadPart(id, NULL_LOCALE, uploadForm, session, projectIterationDAO);
totalChunks = upload.getParts().size();
return Response.status(Status.ACCEPTED)
.entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
@@ -114,7 +111,7 @@ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, St
}
else
{
- HDocumentUpload upload = saveUploadPart(projectSlug, iterationSlug, docId, NULL_LOCALE,
+ HDocumentUpload upload = saveUploadPart(id, NULL_LOCALE,
uploadForm, session, projectIterationDAO);
totalChunks = upload.getParts().size();
tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
@@ -123,7 +120,7 @@ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, St
if (uploadForm.getFileType().equals(".pot"))
{
InputStream potStream = getInputStream(tempFile, uploadForm);
- parsePotFile(potStream, projectSlug, iterationSlug, docId, uploadForm);
+ parsePotFile(potStream, id, uploadForm);
}
else
{
@@ -131,13 +128,13 @@ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, St
{
tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
}
- processAdapterFile(tempFile.get(), projectSlug, iterationSlug, docId, uploadForm);
+ processAdapterFile(tempFile.get(), id, uploadForm);
}
if (tempFile.isPresent())
{
tempFile.get().delete();
}
- return sourceUploadSuccessResponse(isNewDocument(projectSlug, iterationSlug, docId, documentDAO), totalChunks);
+ return sourceUploadSuccessResponse(isNewDocument(id, documentDAO), totalChunks);
}
catch (ChunkUploadException e)
{
@@ -153,13 +150,13 @@ public Response tryUploadSourceFile(String projectSlug, String iterationSlug, St
}
}
- private void checkSourceUploadPreconditions(String projectSlug, String iterationSlug, String docId,
+ private void checkSourceUploadPreconditions(GlobalDocumentId id,
DocumentFileUploadForm uploadForm)
{
try
{
- checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
- checkSourceUploadAllowed(projectSlug, iterationSlug);
+ checkUploadPreconditions(id, uploadForm, identity, projectIterationDAO, session);
+ checkSourceUploadAllowed(id);
}
catch (AuthorizationException e)
{
@@ -168,19 +165,19 @@ private void checkSourceUploadPreconditions(String projectSlug, String iteration
checkValidSourceUploadType(uploadForm);
}
- private void checkSourceUploadAllowed(String projectSlug, String iterationSlug)
+ private void checkSourceUploadAllowed(GlobalDocumentId id)
{
- if (!isDocumentUploadAllowed(projectSlug, iterationSlug))
+ if (!isDocumentUploadAllowed(id))
{
throw new ChunkUploadException(Status.FORBIDDEN,
"You do not have permission to upload source documents to project-version \""
- + projectSlug + ":" + iterationSlug + "\".");
+ + id.getProjectSlug() + ":" + id.getVersionSlug() + "\".");
}
}
- private boolean isDocumentUploadAllowed(String projectSlug, String iterationSlug)
+ private boolean isDocumentUploadAllowed(GlobalDocumentId id)
{
- HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
+ HProjectIteration projectIteration = projectIterationDAO.getBySlug(id.getProjectSlug(), id.getVersionSlug());
return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
&& identity != null && identity.hasPermission("import-template", projectIteration);
}
@@ -219,10 +216,9 @@ private static Response sourceUploadSuccessResponse(boolean isNewDocument, int a
return response;
}
- private void processAdapterFile(@Nonnull File tempFile, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm)
+ private void processAdapterFile(@Nonnull File tempFile, GlobalDocumentId id, DocumentFileUploadForm uploadForm)
{
- String name = projectSlug + ":" + iterationSlug + ":" + docId;
+ String name = id.getProjectSlug() + ":" + id.getVersionSlug() + ":" + id.getDocId();
try
{
virusScanner.scan(tempFile, name);
@@ -238,14 +234,14 @@ private void processAdapterFile(@Nonnull File tempFile, String projectSlug, Stri
params = Optional.fromNullable(Strings.emptyToNull(uploadForm.getAdapterParams()));
if (!params.isPresent())
{
- params = documentDAO.getAdapterParams(projectSlug, iterationSlug, docId);
+ params = documentDAO.getAdapterParams(id.getProjectSlug(), id.getVersionSlug(), id.getDocId());
}
try
{
- Resource doc = translationFileServiceImpl.parseUpdatedAdapterDocumentFile(tempFile.toURI(), docId, uploadForm.getFileType(), params);
+ Resource doc = translationFileServiceImpl.parseUpdatedAdapterDocumentFile(tempFile.toURI(), id.getDocId(), uploadForm.getFileType(), params);
doc.setLang(new LocaleId("en-US"));
// TODO Copy Trans values
- document = documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, Collections. emptySet(), false);
+ document = documentServiceImpl.saveDocument(id.getProjectSlug(), id.getVersionSlug(), doc, Collections. emptySet(), false);
}
catch (SecurityException e)
{
@@ -286,20 +282,20 @@ private void processAdapterFile(@Nonnull File tempFile, String projectSlug, Stri
translationFileServiceImpl.removeTempFile(tempFile);
}
- private void parsePotFile(InputStream potStream, String projectSlug, String iterationSlug,
- String docId, DocumentFileUploadForm uploadForm)
+ private void parsePotFile(InputStream potStream, GlobalDocumentId id, DocumentFileUploadForm uploadForm)
{
Resource doc;
- doc = translationFileServiceImpl.parseUpdatedPotFile(potStream, docId, uploadForm.getFileType(),
- useOfflinePo(projectSlug, iterationSlug, docId));
+ doc = translationFileServiceImpl.parseUpdatedPotFile(potStream, id.getDocId(), uploadForm.getFileType(),
+ useOfflinePo(id));
doc.setLang(new LocaleId("en-US"));
// TODO Copy Trans values
- documentServiceImpl.saveDocument(projectSlug, iterationSlug, doc, new StringSet(ExtensionType.GetText.toString()), false);
+ documentServiceImpl.saveDocument(id.getProjectSlug(), id.getVersionSlug(), doc, new StringSet(ExtensionType.GetText.toString()), false);
}
- private boolean useOfflinePo(String projectSlug, String iterationSlug, String docId)
+ private boolean useOfflinePo(GlobalDocumentId id)
{
- return !isNewDocument(projectSlug, iterationSlug, docId, documentDAO) && !translationFileServiceImpl.isPoDocument(projectSlug, iterationSlug, docId);
+ return !isNewDocument(id, documentDAO)
+ && !translationFileServiceImpl.isPoDocument(id.getProjectSlug(), id.getVersionSlug(), id.getDocId());
}
}
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 179e8edd01..6266103158 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -69,6 +69,7 @@
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.exception.ChunkUploadException;
import org.zanata.file.DocumentUpload;
+import org.zanata.file.GlobalDocumentId;
import org.zanata.file.SourceDocumentUpload;
import org.zanata.model.HDocument;
import org.zanata.model.HDocumentUpload;
@@ -162,9 +163,11 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
@QueryParam("docId") String docId,
@MultipartForm DocumentFileUploadForm uploadForm )
{
+ GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
+
SourceDocumentUpload uploader = new SourceDocumentUpload(identity, session, documentDAO, projectIterationDAO,
documentServiceImpl, virusScanner, translationFileServiceImpl);
- return uploader.tryUploadSourceFile(projectSlug, iterationSlug, docId, uploadForm);
+ return uploader.tryUploadSourceFile(id, uploadForm);
}
// TODO this shares a lot of logic with .tryUploadSourceFile(), try to unify.
@@ -202,7 +205,7 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
}
else
{
- HDocumentUpload upload = DocumentUpload.saveUploadPart(projectSlug, iterationSlug, docId, locale,
+ HDocumentUpload upload = DocumentUpload.saveUploadPart(new GlobalDocumentId(projectSlug, iterationSlug, docId), locale,
uploadForm, session, projectIterationDAO);
totalChunks = upload.getParts().size();
if (!uploadForm.getLast())
@@ -350,7 +353,7 @@ private HLocale findHLocale(String localeString)
private void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug, String docId, String localeId, DocumentFileUploadForm uploadForm)
{
- DocumentUpload.checkUploadPreconditions(projectSlug, iterationSlug, docId, uploadForm, identity, projectIterationDAO, session);
+ DocumentUpload.checkUploadPreconditions(new GlobalDocumentId(projectSlug, iterationSlug, docId), uploadForm, identity, projectIterationDAO, session);
// TODO check translation upload allowed
@@ -372,7 +375,7 @@ private void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm)
private void checkDocumentExists(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
{
- if (DocumentUpload.isNewDocument(projectSlug, iterationSlug, docId, documentDAO))
+ if (DocumentUpload.isNewDocument(new GlobalDocumentId(projectSlug, iterationSlug, docId), documentDAO))
{
throw new ChunkUploadException(Status.NOT_FOUND,
"No document with id \"" + docId + "\" exists in project-version \"" +
From cddc233baf8d441f5b30ec6a99417ad2da920e25 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:39:24 +1000
Subject: [PATCH 123/184] make FileService.checkDocumentExists static (mikado
method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 6266103158..e4c1a62a07 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -357,7 +357,7 @@ private void checkTranslationUploadPreconditions(String projectSlug, String iter
// TODO check translation upload allowed
- checkDocumentExists(projectSlug, iterationSlug, docId, uploadForm);
+ checkDocumentExists(projectSlug, iterationSlug, docId, uploadForm, documentDAO);
checkValidTranslationUploadType(uploadForm);
}
@@ -373,7 +373,9 @@ private void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm)
}
}
- private void checkDocumentExists(String projectSlug, String iterationSlug, String docId, DocumentFileUploadForm uploadForm)
+ private static void checkDocumentExists(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm,
+ DocumentDAO documentDAO)
{
if (DocumentUpload.isNewDocument(new GlobalDocumentId(projectSlug, iterationSlug, docId), documentDAO))
{
From c2213fb90e2fe7209f7ff5a4cc9c1fd31ab1e8ba Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:40:52 +1000
Subject: [PATCH 124/184] make FileService.checkValidTranslationUploadType
static (mikado method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index e4c1a62a07..fb3fb924c4 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -358,10 +358,11 @@ private void checkTranslationUploadPreconditions(String projectSlug, String iter
// TODO check translation upload allowed
checkDocumentExists(projectSlug, iterationSlug, docId, uploadForm, documentDAO);
- checkValidTranslationUploadType(uploadForm);
+ checkValidTranslationUploadType(uploadForm, translationFileServiceImpl);
}
- private void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm)
+ private static void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm,
+ TranslationFileService translationFileServiceImpl)
{
String fileType = uploadForm.getFileType();
if (!fileType.equals(".po")
From fc4c7c71b1db4aa826e1b674fe4b7fccf8b07664 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:44:02 +1000
Subject: [PATCH 125/184] make FileService.checkTranslationUploadPrecondiditons
static (mikado method)
---
.../java/org/zanata/rest/service/FileService.java | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index fb3fb924c4..979406225c 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -191,7 +191,8 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
HLocale locale;
try
{
- checkTranslationUploadPreconditions(projectSlug, iterationSlug, docId, localeId, uploadForm);
+ checkTranslationUploadPreconditions(projectSlug, iterationSlug, docId, localeId, uploadForm,
+ identity, projectIterationDAO, session, documentDAO, translationFileServiceImpl);
locale = findHLocale(localeId);
checkTranslationUploadAllowed(projectSlug, iterationSlug, localeId, locale);
@@ -351,9 +352,16 @@ private HLocale findHLocale(String localeString)
return locale;
}
- private void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug, String docId, String localeId, DocumentFileUploadForm uploadForm)
+ private static void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug,
+ String docId, String localeId, DocumentFileUploadForm uploadForm,
+ ZanataIdentity identity,
+ ProjectIterationDAO projectIterationDAO,
+ Session session,
+ DocumentDAO documentDAO,
+ TranslationFileService translationFileServiceImpl)
{
- DocumentUpload.checkUploadPreconditions(new GlobalDocumentId(projectSlug, iterationSlug, docId), uploadForm, identity, projectIterationDAO, session);
+ DocumentUpload.checkUploadPreconditions(new GlobalDocumentId(projectSlug, iterationSlug, docId),
+ uploadForm, identity, projectIterationDAO, session);
// TODO check translation upload allowed
From 6ca82d5e9c0a002a72adaac65270fa7cc300100b Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:46:25 +1000
Subject: [PATCH 126/184] make FileService.findHLocale static (mikado method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 979406225c..d122ad00eb 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -193,7 +193,7 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
{
checkTranslationUploadPreconditions(projectSlug, iterationSlug, docId, localeId, uploadForm,
identity, projectIterationDAO, session, documentDAO, translationFileServiceImpl);
- locale = findHLocale(localeId);
+ locale = findHLocale(localeId, localeDAO);
checkTranslationUploadAllowed(projectSlug, iterationSlug, localeId, locale);
Optional tempFile;
@@ -330,7 +330,7 @@ private boolean isTranslationUploadAllowed(String projectSlug, String iterationS
&& identity != null && identity.hasPermission("add-translation", projectIteration.getProject(), localeId);
}
- private HLocale findHLocale(String localeString)
+ private static HLocale findHLocale(String localeString, LocaleDAO localeDAO)
{
LocaleId localeId;
try
From 46a472ca684cacd3c030e5f7d8570b27c8830d0a Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:49:21 +1000
Subject: [PATCH 127/184] make FileService.isTranslationUploadAllowed static
(mikado method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index d122ad00eb..7cdf3630d1 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -313,7 +313,8 @@ private Set newExtensions(boolean gettextExtensions)
private void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale)
{
- if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale))
+ if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale,
+ projectIterationDAO, identity))
{
throw new ChunkUploadException(Status.FORBIDDEN,
"You do not have permission to upload translations for locale \"" + localeId +
@@ -321,7 +322,9 @@ private void checkTranslationUploadAllowed(String projectSlug, String iterationS
}
}
- private boolean isTranslationUploadAllowed(String projectSlug, String iterationSlug, HLocale localeId)
+ private static boolean isTranslationUploadAllowed(String projectSlug, String iterationSlug, HLocale localeId,
+ ProjectIterationDAO projectIterationDAO,
+ ZanataIdentity identity)
{
HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
// TODO should this check be "add-translation" or "modify-translation"?
From 3e6f8997269e763f1dff0b4a464d1473a62b8e48 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:50:52 +1000
Subject: [PATCH 128/184] make FileService.checkTranslationUploadAllowed static
(mikado method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 7cdf3630d1..bbe97191b2 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -194,7 +194,8 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
checkTranslationUploadPreconditions(projectSlug, iterationSlug, docId, localeId, uploadForm,
identity, projectIterationDAO, session, documentDAO, translationFileServiceImpl);
locale = findHLocale(localeId, localeDAO);
- checkTranslationUploadAllowed(projectSlug, iterationSlug, localeId, locale);
+ checkTranslationUploadAllowed(projectSlug, iterationSlug, localeId, locale,
+ projectIterationDAO, identity);
Optional tempFile;
int totalChunks;
@@ -311,7 +312,9 @@ private Set newExtensions(boolean gettextExtensions)
return extensions;
}
- private void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale)
+ private static void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale,
+ ProjectIterationDAO projectIterationDAO,
+ ZanataIdentity identity)
{
if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale,
projectIterationDAO, identity))
From 860b096aa99c071a2627db850c6dccbaae8c599a Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:52:11 +1000
Subject: [PATCH 129/184] make FileService.newExtensions static (mikado method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index bbe97191b2..7ab453f2b2 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -298,7 +298,7 @@ private String buildWarningString(List warnings)
return warningString;
}
- private Set newExtensions(boolean gettextExtensions)
+ private static Set newExtensions(boolean gettextExtensions)
{
Set extensions;
if (gettextExtensions)
From 72e2055cb0aeba812fe7555aa30be5c9760dec41 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:53:24 +1000
Subject: [PATCH 130/184] make FileService.mergeTypeFromString static (mikado
method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 7ab453f2b2..1af61d8563 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -400,7 +400,7 @@ private static void checkDocumentExists(String projectSlug, String iterationSlug
}
}
- private MergeType mergeTypeFromString(String type)
+ private static MergeType mergeTypeFromString(String type)
{
if ("import".equals(type))
{
From 789477c48d37adbe368dd84e82115a99bf1ad302 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:55:11 +1000
Subject: [PATCH 131/184] make FileService.transUploadResponse and helper
static (mikado method)
---
.../src/main/java/org/zanata/rest/service/FileService.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 1af61d8563..1e729bb53b 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -269,7 +269,7 @@ private Response tryUploadTranslationFile(String projectSlug, String iterationSl
}
}
- private Response transUploadResponse(int totalChunks, List warnings)
+ private static Response transUploadResponse(int totalChunks, List warnings)
{
ChunkUploadResponse response = new ChunkUploadResponse();
response.setExpectingMore(false);
@@ -285,7 +285,7 @@ private Response transUploadResponse(int totalChunks, List warnings)
return Response.status(Status.OK).entity(response).build();
}
- private String buildWarningString(List warnings)
+ private static String buildWarningString(List warnings)
{
StringBuilder warningText = new StringBuilder("Upload succeeded but had the following warnings:");
for (String warning : warnings)
From 2cac2c18f97e4953677f3384f3335eaf55afd96a Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 10:59:12 +1000
Subject: [PATCH 132/184] make FileService.tryUploadTranslationFile static
(mikado method)
---
.../java/org/zanata/rest/service/FileService.java | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 1e729bb53b..acc0bbbd8e 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -183,10 +183,20 @@ public Response uploadTranslationFile( @PathParam("projectSlug") String projectS
@QueryParam("merge") String merge,
@MultipartForm DocumentFileUploadForm uploadForm )
{
- return tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm);
+ return tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm,
+ identity, projectIterationDAO, session, documentDAO, localeDAO,
+ translationFileServiceImpl, translationServiceImpl);
}
- private Response tryUploadTranslationFile(String projectSlug, String iterationSlug, String docId, String localeId, String mergeType, DocumentFileUploadForm uploadForm)
+ private static Response tryUploadTranslationFile(String projectSlug, String iterationSlug, String docId,
+ String localeId, String mergeType, DocumentFileUploadForm uploadForm,
+ ZanataIdentity identity,
+ ProjectIterationDAO projectIterationDAO,
+ Session session,
+ DocumentDAO documentDAO,
+ LocaleDAO localeDAO,
+ TranslationFileService translationFileServiceImpl,
+ TranslationService translationServiceImpl)
{
HLocale locale;
try
From 06ad0612718d1404e95340bbe95ca76c9a805ad4 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Wed, 17 Jul 2013 11:07:44 +1000
Subject: [PATCH 133/184] Fix problem where approve/reject changes states the
editor row (color)
---
.../org/zanata/webtrans/client/view/TargetContentsView.java | 4 ----
1 file changed, 4 deletions(-)
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 3a14a0f9ec..4c94c49aee 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
@@ -167,10 +167,6 @@ public void updateCommentIndicator(int commentsCount)
@Override
public void setState(EditingState editingState)
{
- if (this.editingState == editingState)
- {
- return;
- }
this.editingState = editingState;
if (editingState == EditingState.UNSAVED)
{
From ca4027a4fb8bf72aa09cb1ca492be149dbaf59e7 Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Wed, 17 Jul 2013 12:17:28 +1000
Subject: [PATCH 134/184] Rename variables name
---
.../zanata/action/ViewAllStatusAction.java | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
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 0f7609d586..060ec27fb6 100644
--- a/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java
+++ b/zanata-war/src/main/java/org/zanata/action/ViewAllStatusAction.java
@@ -256,8 +256,8 @@ public List getAllStatus()
{
HProjectIteration iteration = projectIterationDAO.getBySlug(this.projectSlug, this.iterationSlug);
- List locale = this.getDisplayLocales();
- String[] localeIds = getLocaleIds(locale);
+ List localeList = this.getDisplayLocales();
+ String[] localeIds = getLocaleIds(localeList);
ContainerTranslationStatistics iterationStats = statisticsServiceImpl.getStatistics(this.projectSlug, this.iterationSlug, false, true, localeIds);
@@ -271,15 +271,15 @@ public List getAllStatus()
total = projectIterationDAO.getTotalCountForIteration(iteration.getId());
}
- for (HLocale var : locale)
+ for (HLocale locale : localeList)
{
- TranslationStatistics stats = iterationStats.getStats(var.getLocaleId().getId(), statsOption);
+ TranslationStatistics stats = iterationStats.getStats(locale.getLocaleId().getId(), statsOption);
if (stats == null)
{
stats = new TranslationStatistics(statsOption);
stats.setUntranslated(total);
- HTextFlowTarget lastTranslatedTarget = localeServiceImpl.getLastTranslated(projectSlug, iterationSlug, var.getLocaleId());
+ HTextFlowTarget lastTranslatedTarget = localeServiceImpl.getLastTranslated(projectSlug, iterationSlug, locale.getLocaleId());
if (lastTranslatedTarget != null)
{
@@ -290,16 +290,16 @@ public List getAllStatus()
}
- if (!statsMap.containsKey(var.getLocaleId()))
+ if (!statsMap.containsKey(locale.getLocaleId()))
{
- boolean isMember = authenticatedAccount != null ? personDAO.isUserInLanguageTeamWithRoles(authenticatedAccount.getPerson(), var, null, null, null) : false;
+ boolean isMember = authenticatedAccount != null ? personDAO.isUserInLanguageTeamWithRoles(authenticatedAccount.getPerson(), locale, null, null, null) : false;
- Status op = new Status(var.getLocaleId().getId(), var.retrieveNativeName(), stats, isMember);
- statsMap.put(var.getLocaleId(), op);
+ Status op = new Status(locale.getLocaleId().getId(), locale.retrieveNativeName(), stats, isMember);
+ statsMap.put(locale.getLocaleId(), op);
}
else
{
- statsMap.get(var.getLocaleId()).setStats(stats);
+ statsMap.get(locale.getLocaleId()).setStats(stats);
}
}
From 14772769034d3003f5d65ba1077e8a554cbc51a0 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 12:31:58 +1000
Subject: [PATCH 135/184] move all translation upload methods from FileService
to new TranslationDocumentUpload (mikado method)
---
.../file/TranslationDocumentUpload.java | 316 ++++++++++++++++++
.../org/zanata/rest/service/FileService.java | 253 +-------------
2 files changed, 318 insertions(+), 251 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
diff --git a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
new file mode 100644
index 0000000000..798fc3c1a4
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
@@ -0,0 +1,316 @@
+/*
+ * 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.file;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.hibernate.Session;
+import org.jboss.seam.security.AuthorizationException;
+import org.zanata.common.DocumentType;
+import org.zanata.common.EntityStatus;
+import org.zanata.common.LocaleId;
+import org.zanata.common.MergeType;
+import org.zanata.dao.DocumentDAO;
+import org.zanata.dao.LocaleDAO;
+import org.zanata.dao.ProjectIterationDAO;
+import org.zanata.exception.ChunkUploadException;
+import org.zanata.model.HDocumentUpload;
+import org.zanata.model.HLocale;
+import org.zanata.model.HProjectIteration;
+import org.zanata.rest.DocumentFileUploadForm;
+import org.zanata.rest.StringSet;
+import org.zanata.rest.dto.ChunkUploadResponse;
+import org.zanata.rest.dto.extensions.ExtensionType;
+import org.zanata.rest.dto.resource.TranslationsResource;
+import org.zanata.rest.service.VirusScanner;
+import org.zanata.security.ZanataIdentity;
+import org.zanata.service.DocumentService;
+import org.zanata.service.TranslationFileService;
+import org.zanata.service.TranslationService;
+
+import com.google.common.base.Optional;
+
+@Slf4j
+public class TranslationDocumentUpload extends DocumentUpload
+{
+
+ public TranslationDocumentUpload(ZanataIdentity identity,
+ Session session,
+ DocumentDAO documentDAO,
+ ProjectIterationDAO projectIterationDAO,
+ DocumentService documentServiceImpl,
+ VirusScanner virusScanner,
+ TranslationFileService translationFileServiceImpl)
+ {
+ super(identity,
+ session,
+ documentDAO,
+ projectIterationDAO,
+ documentServiceImpl,
+ virusScanner,
+ translationFileServiceImpl);
+ }
+
+ public static Response tryUploadTranslationFile(String projectSlug, String iterationSlug, String docId,
+ String localeId, String mergeType, DocumentFileUploadForm uploadForm,
+ ZanataIdentity identity,
+ ProjectIterationDAO projectIterationDAO,
+ Session session,
+ DocumentDAO documentDAO,
+ LocaleDAO localeDAO,
+ TranslationFileService translationFileServiceImpl,
+ TranslationService translationServiceImpl)
+ {
+ HLocale locale;
+ try
+ {
+ checkTranslationUploadPreconditions(projectSlug, iterationSlug, docId, localeId, uploadForm,
+ identity, projectIterationDAO, session, documentDAO, translationFileServiceImpl);
+ locale = findHLocale(localeId, localeDAO);
+ checkTranslationUploadAllowed(projectSlug, iterationSlug, localeId, locale,
+ projectIterationDAO, identity);
+
+ Optional tempFile;
+ int totalChunks;
+
+ if (isSinglePart(uploadForm))
+ {
+ totalChunks = 1;
+ tempFile = Optional.absent();
+ }
+ else
+ {
+ HDocumentUpload upload = saveUploadPart(new GlobalDocumentId(projectSlug, iterationSlug, docId), locale,
+ uploadForm, session, projectIterationDAO);
+ totalChunks = upload.getParts().size();
+ if (!uploadForm.getLast())
+ {
+ return Response.status(Status.ACCEPTED)
+ .entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
+ "Chunk accepted, awaiting remaining chunks."))
+ .build();
+ }
+ tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
+ }
+
+ TranslationsResource transRes;
+ if (uploadForm.getFileType().equals(".po"))
+ {
+ InputStream poStream = getInputStream(tempFile, uploadForm);
+ transRes = translationFileServiceImpl.parsePoFile(poStream, projectSlug, iterationSlug, docId);
+ }
+ else
+ {
+ if (!tempFile.isPresent())
+ {
+ tempFile = Optional.of(DocumentUpload.persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
+ }
+ // FIXME this is misusing the 'filename' field. the method should probably take a
+ // type anyway
+ transRes = translationFileServiceImpl.parseAdapterTranslationFile(tempFile.get(),
+ projectSlug, iterationSlug, docId, localeId, uploadForm.getFileType());
+ }
+ if (tempFile.isPresent())
+ {
+ tempFile.get().delete();
+ }
+
+ Set extensions = newExtensions(uploadForm.getFileType().equals(".po"));
+ // TODO useful error message for failed saving?
+ List warnings = translationServiceImpl.translateAllInDoc(projectSlug, iterationSlug,
+ docId, locale.getLocaleId(), transRes, extensions, mergeTypeFromString(mergeType));
+
+ return transUploadResponse(totalChunks, warnings);
+ }
+ catch (AuthorizationException e)
+ {
+ return Response.status(Status.UNAUTHORIZED)
+ .entity(new ChunkUploadResponse(e.getMessage()))
+ .build();
+ }
+ catch (FileNotFoundException e)
+ {
+ log.error("failed to create input stream from temp file", e);
+ return Response.status(Status.INTERNAL_SERVER_ERROR)
+ .entity(e).build();
+ }
+ catch (ChunkUploadException e)
+ {
+ return Response.status(e.getStatusCode())
+ .entity(new ChunkUploadResponse(e.getMessage()))
+ .build();
+ }
+ }
+
+ public static void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug,
+ String docId, String localeId, DocumentFileUploadForm uploadForm,
+ ZanataIdentity identity,
+ ProjectIterationDAO projectIterationDAO,
+ Session session,
+ DocumentDAO documentDAO,
+ TranslationFileService translationFileServiceImpl)
+ {
+ checkUploadPreconditions(new GlobalDocumentId(projectSlug, iterationSlug, docId),
+ uploadForm, identity, projectIterationDAO, session);
+
+ // TODO check translation upload allowed
+
+ checkDocumentExists(projectSlug, iterationSlug, docId, uploadForm, documentDAO);
+ checkValidTranslationUploadType(uploadForm, translationFileServiceImpl);
+ }
+
+ public static void checkDocumentExists(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm,
+ DocumentDAO documentDAO)
+ {
+ if (isNewDocument(new GlobalDocumentId(projectSlug, iterationSlug, docId), documentDAO))
+ {
+ throw new ChunkUploadException(Status.NOT_FOUND,
+ "No document with id \"" + docId + "\" exists in project-version \"" +
+ projectSlug + ":" + iterationSlug + "\".");
+ }
+ }
+
+ public static void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm,
+ TranslationFileService translationFileServiceImpl)
+ {
+ String fileType = uploadForm.getFileType();
+ if (!fileType.equals(".po")
+ && !translationFileServiceImpl.hasAdapterFor(DocumentType.typeFor(fileType)))
+ {
+ throw new ChunkUploadException(Status.BAD_REQUEST,
+ "The type \"" + fileType + "\" specified in form parameter 'type' " +
+ "is not valid for a translation file on this server.");
+ }
+ }
+
+ public static HLocale findHLocale(String localeString, LocaleDAO localeDAO)
+ {
+ LocaleId localeId;
+ try
+ {
+ localeId = new LocaleId(localeString);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ChunkUploadException(Status.BAD_REQUEST,
+ "Invalid value for locale", e);
+ }
+
+ HLocale locale = localeDAO.findByLocaleId(localeId);
+ if (locale == null)
+ {
+ throw new ChunkUploadException(Status.NOT_FOUND,
+ "The specified locale \"" + localeString + "\" does not exist on this server.");
+ }
+ return locale;
+ }
+
+ public static void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale,
+ ProjectIterationDAO projectIterationDAO,
+ ZanataIdentity identity)
+ {
+ if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale,
+ projectIterationDAO, identity))
+ {
+ throw new ChunkUploadException(Status.FORBIDDEN,
+ "You do not have permission to upload translations for locale \"" + localeId +
+ "\" to project-version \"" + projectSlug + ":" + iterationSlug + "\".");
+ }
+ }
+
+ public static boolean isTranslationUploadAllowed(String projectSlug, String iterationSlug, HLocale localeId,
+ ProjectIterationDAO projectIterationDAO,
+ ZanataIdentity identity)
+ {
+ HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
+ // TODO should this check be "add-translation" or "modify-translation"?
+ // They appear to be granted identically at the moment.
+ return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
+ && identity != null && identity.hasPermission("add-translation", projectIteration.getProject(), localeId);
+ }
+
+ public static Set newExtensions(boolean gettextExtensions)
+ {
+ Set extensions;
+ if (gettextExtensions)
+ {
+ extensions = new StringSet(ExtensionType.GetText.toString());
+ }
+ else
+ {
+ extensions = Collections.emptySet();
+ }
+ return extensions;
+ }
+
+ public static Response transUploadResponse(int totalChunks, List warnings)
+ {
+ ChunkUploadResponse response = new ChunkUploadResponse();
+ response.setExpectingMore(false);
+ response.setAcceptedChunks(totalChunks);
+ if (warnings != null && !warnings.isEmpty())
+ {
+ response.setSuccessMessage(buildWarningString(warnings));
+ }
+ else
+ {
+ response.setSuccessMessage("Translations uploaded successfully");
+ }
+ return Response.status(Status.OK).entity(response).build();
+ }
+
+ public static String buildWarningString(List warnings)
+ {
+ StringBuilder warningText = new StringBuilder("Upload succeeded but had the following warnings:");
+ for (String warning : warnings)
+ {
+ warningText.append("\n\t");
+ warningText.append(warning);
+ }
+ warningText.append("\n");
+ String warningString = warningText.toString();
+ return warningString;
+ }
+
+ public static MergeType mergeTypeFromString(String type)
+ {
+ if ("import".equals(type))
+ {
+ return MergeType.IMPORT;
+ }
+ else
+ {
+ return MergeType.AUTO;
+ }
+ }
+
+}
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index acc0bbbd8e..29f59abfee 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -22,7 +22,6 @@
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -31,7 +30,6 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -50,35 +48,23 @@
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.StreamingOutput;
-import lombok.extern.slf4j.Slf4j;
-
import org.hibernate.Session;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
-import org.jboss.seam.security.AuthorizationException;
import org.zanata.adapter.FileFormatAdapter;
import org.zanata.adapter.po.PoWriter2;
import org.zanata.common.ContentState;
-import org.zanata.common.DocumentType;
-import org.zanata.common.EntityStatus;
import org.zanata.common.LocaleId;
-import org.zanata.common.MergeType;
import org.zanata.dao.DocumentDAO;
import org.zanata.dao.LocaleDAO;
import org.zanata.dao.ProjectIterationDAO;
-import org.zanata.exception.ChunkUploadException;
-import org.zanata.file.DocumentUpload;
import org.zanata.file.GlobalDocumentId;
import org.zanata.file.SourceDocumentUpload;
+import org.zanata.file.TranslationDocumentUpload;
import org.zanata.model.HDocument;
-import org.zanata.model.HDocumentUpload;
-import org.zanata.model.HLocale;
-import org.zanata.model.HProjectIteration;
import org.zanata.rest.DocumentFileUploadForm;
import org.zanata.rest.StringSet;
-import org.zanata.rest.dto.ChunkUploadResponse;
-import org.zanata.rest.dto.extensions.ExtensionType;
import org.zanata.rest.dto.resource.Resource;
import org.zanata.rest.dto.resource.TextFlowTarget;
import org.zanata.rest.dto.resource.TranslationsResource;
@@ -98,7 +84,6 @@
@Path(FileResource.FILE_RESOURCE)
@Produces( { MediaType.APPLICATION_OCTET_STREAM })
@Consumes( { MediaType.APPLICATION_OCTET_STREAM })
-@Slf4j
public class FileService implements FileResource
{
private static final String FILE_TYPE_OFFLINE_PO = "offlinepo";
@@ -183,245 +168,11 @@ public Response uploadTranslationFile( @PathParam("projectSlug") String projectS
@QueryParam("merge") String merge,
@MultipartForm DocumentFileUploadForm uploadForm )
{
- return tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm,
+ return TranslationDocumentUpload.tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm,
identity, projectIterationDAO, session, documentDAO, localeDAO,
translationFileServiceImpl, translationServiceImpl);
}
- private static Response tryUploadTranslationFile(String projectSlug, String iterationSlug, String docId,
- String localeId, String mergeType, DocumentFileUploadForm uploadForm,
- ZanataIdentity identity,
- ProjectIterationDAO projectIterationDAO,
- Session session,
- DocumentDAO documentDAO,
- LocaleDAO localeDAO,
- TranslationFileService translationFileServiceImpl,
- TranslationService translationServiceImpl)
- {
- HLocale locale;
- try
- {
- checkTranslationUploadPreconditions(projectSlug, iterationSlug, docId, localeId, uploadForm,
- identity, projectIterationDAO, session, documentDAO, translationFileServiceImpl);
- locale = findHLocale(localeId, localeDAO);
- checkTranslationUploadAllowed(projectSlug, iterationSlug, localeId, locale,
- projectIterationDAO, identity);
-
- Optional tempFile;
- int totalChunks;
-
- if (DocumentUpload.isSinglePart(uploadForm))
- {
- totalChunks = 1;
- tempFile = Optional.absent();
- }
- else
- {
- HDocumentUpload upload = DocumentUpload.saveUploadPart(new GlobalDocumentId(projectSlug, iterationSlug, docId), locale,
- uploadForm, session, projectIterationDAO);
- totalChunks = upload.getParts().size();
- if (!uploadForm.getLast())
- {
- return Response.status(Status.ACCEPTED)
- .entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
- "Chunk accepted, awaiting remaining chunks."))
- .build();
- }
- tempFile = Optional.of(DocumentUpload.combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
- }
-
- TranslationsResource transRes;
- if (uploadForm.getFileType().equals(".po"))
- {
- InputStream poStream = DocumentUpload.getInputStream(tempFile, uploadForm);
- transRes = translationFileServiceImpl.parsePoFile(poStream, projectSlug, iterationSlug, docId);
- }
- else
- {
- if (!tempFile.isPresent())
- {
- tempFile = Optional.of(DocumentUpload.persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
- }
- // FIXME this is misusing the 'filename' field. the method should probably take a
- // type anyway
- transRes = translationFileServiceImpl.parseAdapterTranslationFile(tempFile.get(),
- projectSlug, iterationSlug, docId, localeId, uploadForm.getFileType());
- }
- if (tempFile.isPresent())
- {
- tempFile.get().delete();
- }
-
- Set extensions = newExtensions(uploadForm.getFileType().equals(".po"));
- // TODO useful error message for failed saving?
- List warnings = translationServiceImpl.translateAllInDoc(projectSlug, iterationSlug,
- docId, locale.getLocaleId(), transRes, extensions, mergeTypeFromString(mergeType));
-
- return transUploadResponse(totalChunks, warnings);
- }
- catch (AuthorizationException e)
- {
- return Response.status(Status.UNAUTHORIZED)
- .entity(new ChunkUploadResponse(e.getMessage()))
- .build();
- }
- catch (FileNotFoundException e)
- {
- log.error("failed to create input stream from temp file", e);
- return Response.status(Status.INTERNAL_SERVER_ERROR)
- .entity(e).build();
- }
- catch (ChunkUploadException e)
- {
- return Response.status(e.getStatusCode())
- .entity(new ChunkUploadResponse(e.getMessage()))
- .build();
- }
- }
-
- private static Response transUploadResponse(int totalChunks, List warnings)
- {
- ChunkUploadResponse response = new ChunkUploadResponse();
- response.setExpectingMore(false);
- response.setAcceptedChunks(totalChunks);
- if (warnings != null && !warnings.isEmpty())
- {
- response.setSuccessMessage(buildWarningString(warnings));
- }
- else
- {
- response.setSuccessMessage("Translations uploaded successfully");
- }
- return Response.status(Status.OK).entity(response).build();
- }
-
- private static String buildWarningString(List warnings)
- {
- StringBuilder warningText = new StringBuilder("Upload succeeded but had the following warnings:");
- for (String warning : warnings)
- {
- warningText.append("\n\t");
- warningText.append(warning);
- }
- warningText.append("\n");
- String warningString = warningText.toString();
- return warningString;
- }
-
- private static Set newExtensions(boolean gettextExtensions)
- {
- Set extensions;
- if (gettextExtensions)
- {
- extensions = new StringSet(ExtensionType.GetText.toString());
- }
- else
- {
- extensions = Collections.emptySet();
- }
- return extensions;
- }
-
- private static void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale,
- ProjectIterationDAO projectIterationDAO,
- ZanataIdentity identity)
- {
- if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale,
- projectIterationDAO, identity))
- {
- throw new ChunkUploadException(Status.FORBIDDEN,
- "You do not have permission to upload translations for locale \"" + localeId +
- "\" to project-version \"" + projectSlug + ":" + iterationSlug + "\".");
- }
- }
-
- private static boolean isTranslationUploadAllowed(String projectSlug, String iterationSlug, HLocale localeId,
- ProjectIterationDAO projectIterationDAO,
- ZanataIdentity identity)
- {
- HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
- // TODO should this check be "add-translation" or "modify-translation"?
- // They appear to be granted identically at the moment.
- return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
- && identity != null && identity.hasPermission("add-translation", projectIteration.getProject(), localeId);
- }
-
- private static HLocale findHLocale(String localeString, LocaleDAO localeDAO)
- {
- LocaleId localeId;
- try
- {
- localeId = new LocaleId(localeString);
- }
- catch (IllegalArgumentException e)
- {
- throw new ChunkUploadException(Status.BAD_REQUEST,
- "Invalid value for locale", e);
- }
-
- HLocale locale = localeDAO.findByLocaleId(localeId);
- if (locale == null)
- {
- throw new ChunkUploadException(Status.NOT_FOUND,
- "The specified locale \"" + localeString + "\" does not exist on this server.");
- }
- return locale;
- }
-
- private static void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug,
- String docId, String localeId, DocumentFileUploadForm uploadForm,
- ZanataIdentity identity,
- ProjectIterationDAO projectIterationDAO,
- Session session,
- DocumentDAO documentDAO,
- TranslationFileService translationFileServiceImpl)
- {
- DocumentUpload.checkUploadPreconditions(new GlobalDocumentId(projectSlug, iterationSlug, docId),
- uploadForm, identity, projectIterationDAO, session);
-
- // TODO check translation upload allowed
-
- checkDocumentExists(projectSlug, iterationSlug, docId, uploadForm, documentDAO);
- checkValidTranslationUploadType(uploadForm, translationFileServiceImpl);
- }
-
- private static void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm,
- TranslationFileService translationFileServiceImpl)
- {
- String fileType = uploadForm.getFileType();
- if (!fileType.equals(".po")
- && !translationFileServiceImpl.hasAdapterFor(DocumentType.typeFor(fileType)))
- {
- throw new ChunkUploadException(Status.BAD_REQUEST,
- "The type \"" + fileType + "\" specified in form parameter 'type' " +
- "is not valid for a translation file on this server.");
- }
- }
-
- private static void checkDocumentExists(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm,
- DocumentDAO documentDAO)
- {
- if (DocumentUpload.isNewDocument(new GlobalDocumentId(projectSlug, iterationSlug, docId), documentDAO))
- {
- throw new ChunkUploadException(Status.NOT_FOUND,
- "No document with id \"" + docId + "\" exists in project-version \"" +
- projectSlug + ":" + iterationSlug + "\".");
- }
- }
-
- private static MergeType mergeTypeFromString(String type)
- {
- if ("import".equals(type))
- {
- return MergeType.IMPORT;
- }
- else
- {
- return MergeType.AUTO;
- }
- }
-
/**
* Downloads a single source file.
*
From 106cf414c872f4648b73d7c435603f1daeffdc56 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 12:34:38 +1000
Subject: [PATCH 136/184] make tryUploadTranslationFile an instance method
(mikado method)
---
.../java/org/zanata/file/TranslationDocumentUpload.java | 2 +-
.../src/main/java/org/zanata/rest/service/FileService.java | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
index 798fc3c1a4..25ce629246 100644
--- a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
@@ -79,7 +79,7 @@ public TranslationDocumentUpload(ZanataIdentity identity,
translationFileServiceImpl);
}
- public static Response tryUploadTranslationFile(String projectSlug, String iterationSlug, String docId,
+ public Response tryUploadTranslationFile(String projectSlug, String iterationSlug, String docId,
String localeId, String mergeType, DocumentFileUploadForm uploadForm,
ZanataIdentity identity,
ProjectIterationDAO projectIterationDAO,
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 29f59abfee..49be3cd894 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -168,7 +168,11 @@ public Response uploadTranslationFile( @PathParam("projectSlug") String projectS
@QueryParam("merge") String merge,
@MultipartForm DocumentFileUploadForm uploadForm )
{
- return TranslationDocumentUpload.tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm,
+
+ TranslationDocumentUpload uploader = new TranslationDocumentUpload(identity, session, documentDAO, projectIterationDAO,
+ documentServiceImpl, virusScanner, translationFileServiceImpl);
+
+ return uploader.tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm,
identity, projectIterationDAO, session, documentDAO, localeDAO,
translationFileServiceImpl, translationServiceImpl);
}
From ce90deb6a544b37bf1dfe372a274582b968891c0 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 12:40:17 +1000
Subject: [PATCH 137/184] make helper arguments to translation upload into
instance fields (mikado method)
---
.../zanata/file/TranslationDocumentUpload.java | 18 +++++++++---------
.../org/zanata/rest/service/FileService.java | 6 ++----
2 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
index 25ce629246..ea86ed94e8 100644
--- a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
@@ -62,13 +62,18 @@
public class TranslationDocumentUpload extends DocumentUpload
{
+ private final LocaleDAO localeDAO;
+ private final TranslationService translationServiceImpl;
+
public TranslationDocumentUpload(ZanataIdentity identity,
Session session,
DocumentDAO documentDAO,
ProjectIterationDAO projectIterationDAO,
DocumentService documentServiceImpl,
VirusScanner virusScanner,
- TranslationFileService translationFileServiceImpl)
+ TranslationFileService translationFileServiceImpl,
+ LocaleDAO localeDAO,
+ TranslationService translationServiceImpl)
{
super(identity,
session,
@@ -77,17 +82,12 @@ public TranslationDocumentUpload(ZanataIdentity identity,
documentServiceImpl,
virusScanner,
translationFileServiceImpl);
+ this.localeDAO = localeDAO;
+ this.translationServiceImpl = translationServiceImpl;
}
public Response tryUploadTranslationFile(String projectSlug, String iterationSlug, String docId,
- String localeId, String mergeType, DocumentFileUploadForm uploadForm,
- ZanataIdentity identity,
- ProjectIterationDAO projectIterationDAO,
- Session session,
- DocumentDAO documentDAO,
- LocaleDAO localeDAO,
- TranslationFileService translationFileServiceImpl,
- TranslationService translationServiceImpl)
+ String localeId, String mergeType, DocumentFileUploadForm uploadForm)
{
HLocale locale;
try
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 49be3cd894..92c92ef617 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -170,11 +170,9 @@ public Response uploadTranslationFile( @PathParam("projectSlug") String projectS
{
TranslationDocumentUpload uploader = new TranslationDocumentUpload(identity, session, documentDAO, projectIterationDAO,
- documentServiceImpl, virusScanner, translationFileServiceImpl);
+ documentServiceImpl, virusScanner, translationFileServiceImpl, localeDAO, translationServiceImpl);
- return uploader.tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm,
- identity, projectIterationDAO, session, documentDAO, localeDAO,
- translationFileServiceImpl, translationServiceImpl);
+ return uploader.tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm);
}
/**
From 0d7bc9ebd7211a3fdd0d6e9eb963bd98086743dd Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 12:42:22 +1000
Subject: [PATCH 138/184] make translation upload helper methods private
(mikado method)
---
.../file/TranslationDocumentUpload.java | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
index ea86ed94e8..dd57afc948 100644
--- a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
@@ -170,7 +170,7 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
}
}
- public static void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug,
+ private static void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug,
String docId, String localeId, DocumentFileUploadForm uploadForm,
ZanataIdentity identity,
ProjectIterationDAO projectIterationDAO,
@@ -187,7 +187,7 @@ public static void checkTranslationUploadPreconditions(String projectSlug, Strin
checkValidTranslationUploadType(uploadForm, translationFileServiceImpl);
}
- public static void checkDocumentExists(String projectSlug, String iterationSlug, String docId,
+ private static void checkDocumentExists(String projectSlug, String iterationSlug, String docId,
DocumentFileUploadForm uploadForm,
DocumentDAO documentDAO)
{
@@ -199,7 +199,7 @@ public static void checkDocumentExists(String projectSlug, String iterationSlug,
}
}
- public static void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm,
+ private static void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm,
TranslationFileService translationFileServiceImpl)
{
String fileType = uploadForm.getFileType();
@@ -212,7 +212,7 @@ public static void checkValidTranslationUploadType(DocumentFileUploadForm upload
}
}
- public static HLocale findHLocale(String localeString, LocaleDAO localeDAO)
+ private static HLocale findHLocale(String localeString, LocaleDAO localeDAO)
{
LocaleId localeId;
try
@@ -234,7 +234,7 @@ public static HLocale findHLocale(String localeString, LocaleDAO localeDAO)
return locale;
}
- public static void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale,
+ private static void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale,
ProjectIterationDAO projectIterationDAO,
ZanataIdentity identity)
{
@@ -247,7 +247,7 @@ public static void checkTranslationUploadAllowed(String projectSlug, String iter
}
}
- public static boolean isTranslationUploadAllowed(String projectSlug, String iterationSlug, HLocale localeId,
+ private static boolean isTranslationUploadAllowed(String projectSlug, String iterationSlug, HLocale localeId,
ProjectIterationDAO projectIterationDAO,
ZanataIdentity identity)
{
@@ -258,7 +258,7 @@ public static boolean isTranslationUploadAllowed(String projectSlug, String iter
&& identity != null && identity.hasPermission("add-translation", projectIteration.getProject(), localeId);
}
- public static Set newExtensions(boolean gettextExtensions)
+ private static Set newExtensions(boolean gettextExtensions)
{
Set extensions;
if (gettextExtensions)
@@ -272,7 +272,7 @@ public static Set newExtensions(boolean gettextExtensions)
return extensions;
}
- public static Response transUploadResponse(int totalChunks, List warnings)
+ private static Response transUploadResponse(int totalChunks, List warnings)
{
ChunkUploadResponse response = new ChunkUploadResponse();
response.setExpectingMore(false);
@@ -288,7 +288,7 @@ public static Response transUploadResponse(int totalChunks, List warning
return Response.status(Status.OK).entity(response).build();
}
- public static String buildWarningString(List warnings)
+ private static String buildWarningString(List warnings)
{
StringBuilder warningText = new StringBuilder("Upload succeeded but had the following warnings:");
for (String warning : warnings)
@@ -301,7 +301,7 @@ public static String buildWarningString(List warnings)
return warningString;
}
- public static MergeType mergeTypeFromString(String type)
+ private static MergeType mergeTypeFromString(String type)
{
if ("import".equals(type))
{
From 01d0f7a037807a0096591b4333a6db48c83b0ec5 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 12:45:26 +1000
Subject: [PATCH 139/184] protect shared upload helper methods (mikado method)
---
.../java/org/zanata/file/DocumentUpload.java | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
index 6875683451..8e99eaad60 100644
--- a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
@@ -71,7 +71,7 @@ public class DocumentUpload
protected final ProjectIterationDAO projectIterationDAO;
protected final TranslationFileService translationFileServiceImpl;
- public DocumentUpload(
+ protected DocumentUpload(
ZanataIdentity identity,
Session session,
DocumentDAO documentDAO,
@@ -89,7 +89,7 @@ public DocumentUpload(
this.translationFileServiceImpl = translationFileServiceImpl;
}
- public static void checkUploadPreconditions(GlobalDocumentId id,
+ protected static void checkUploadPreconditions(GlobalDocumentId id,
DocumentFileUploadForm uploadForm, ZanataIdentity identity,
ProjectIterationDAO projectIterationDAO, Session session)
{
@@ -190,7 +190,7 @@ private static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploa
return upload;
}
- public static HDocumentUpload saveUploadPart(GlobalDocumentId id,
+ protected static HDocumentUpload saveUploadPart(GlobalDocumentId id,
HLocale locale, DocumentFileUploadForm uploadForm, Session session,
ProjectIterationDAO projectIterationDAO)
{
@@ -232,12 +232,12 @@ private static void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentU
session.flush();
}
- public static boolean isSinglePart(DocumentFileUploadForm uploadForm)
+ protected static boolean isSinglePart(DocumentFileUploadForm uploadForm)
{
return uploadForm.getFirst() && uploadForm.getLast();
}
- public static File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload, Session session,
+ protected static File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload, Session session,
TranslationFileService transFileService)
{
File tempFile;
@@ -295,7 +295,7 @@ private static File combineToTempFile(HDocumentUpload upload, TranslationFileSer
return tempFile;
}
- public static InputStream getInputStream(Optional tempFile, DocumentFileUploadForm uploadForm) throws FileNotFoundException
+ protected static InputStream getInputStream(Optional tempFile, DocumentFileUploadForm uploadForm) throws FileNotFoundException
{
if (tempFile.isPresent())
{
@@ -307,12 +307,12 @@ public static InputStream getInputStream(Optional tempFile, DocumentFileUp
}
}
- public static boolean isNewDocument(GlobalDocumentId id, DocumentDAO dao)
+ protected static boolean isNewDocument(GlobalDocumentId id, DocumentDAO dao)
{
return dao.getByProjectIterationAndDocId(id.getProjectSlug(), id.getVersionSlug(), id.getDocId()) == null;
}
- public static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
+ protected static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
{
File tempFile;
try
From b9fd4b42a936b506bacf743c9769bc645fa5801c Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 12:51:41 +1000
Subject: [PATCH 140/184] use instance helpers for TranslationDocumentUpload
methods (mikado method)
---
.../file/TranslationDocumentUpload.java | 42 +++++++------------
1 file changed, 14 insertions(+), 28 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
index dd57afc948..bfebc30f2b 100644
--- a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
@@ -92,11 +92,9 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
HLocale locale;
try
{
- checkTranslationUploadPreconditions(projectSlug, iterationSlug, docId, localeId, uploadForm,
- identity, projectIterationDAO, session, documentDAO, translationFileServiceImpl);
- locale = findHLocale(localeId, localeDAO);
- checkTranslationUploadAllowed(projectSlug, iterationSlug, localeId, locale,
- projectIterationDAO, identity);
+ checkTranslationUploadPreconditions(projectSlug, iterationSlug, docId, localeId, uploadForm);
+ locale = findHLocale(localeId);
+ checkTranslationUploadAllowed(projectSlug, iterationSlug, localeId, locale);
Optional tempFile;
int totalChunks;
@@ -170,26 +168,20 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
}
}
- private static void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug,
- String docId, String localeId, DocumentFileUploadForm uploadForm,
- ZanataIdentity identity,
- ProjectIterationDAO projectIterationDAO,
- Session session,
- DocumentDAO documentDAO,
- TranslationFileService translationFileServiceImpl)
+ private void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug,
+ String docId, String localeId, DocumentFileUploadForm uploadForm)
{
checkUploadPreconditions(new GlobalDocumentId(projectSlug, iterationSlug, docId),
uploadForm, identity, projectIterationDAO, session);
// TODO check translation upload allowed
- checkDocumentExists(projectSlug, iterationSlug, docId, uploadForm, documentDAO);
- checkValidTranslationUploadType(uploadForm, translationFileServiceImpl);
+ checkDocumentExists(projectSlug, iterationSlug, docId, uploadForm);
+ checkValidTranslationUploadType(uploadForm);
}
- private static void checkDocumentExists(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm,
- DocumentDAO documentDAO)
+ private void checkDocumentExists(String projectSlug, String iterationSlug, String docId,
+ DocumentFileUploadForm uploadForm)
{
if (isNewDocument(new GlobalDocumentId(projectSlug, iterationSlug, docId), documentDAO))
{
@@ -199,8 +191,7 @@ private static void checkDocumentExists(String projectSlug, String iterationSlug
}
}
- private static void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm,
- TranslationFileService translationFileServiceImpl)
+ private void checkValidTranslationUploadType(DocumentFileUploadForm uploadForm)
{
String fileType = uploadForm.getFileType();
if (!fileType.equals(".po")
@@ -212,7 +203,7 @@ private static void checkValidTranslationUploadType(DocumentFileUploadForm uploa
}
}
- private static HLocale findHLocale(String localeString, LocaleDAO localeDAO)
+ private HLocale findHLocale(String localeString)
{
LocaleId localeId;
try
@@ -234,12 +225,9 @@ private static HLocale findHLocale(String localeString, LocaleDAO localeDAO)
return locale;
}
- private static void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale,
- ProjectIterationDAO projectIterationDAO,
- ZanataIdentity identity)
+ private void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale)
{
- if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale,
- projectIterationDAO, identity))
+ if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale))
{
throw new ChunkUploadException(Status.FORBIDDEN,
"You do not have permission to upload translations for locale \"" + localeId +
@@ -247,9 +235,7 @@ private static void checkTranslationUploadAllowed(String projectSlug, String ite
}
}
- private static boolean isTranslationUploadAllowed(String projectSlug, String iterationSlug, HLocale localeId,
- ProjectIterationDAO projectIterationDAO,
- ZanataIdentity identity)
+ private boolean isTranslationUploadAllowed(String projectSlug, String iterationSlug, HLocale localeId)
{
HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
// TODO should this check be "add-translation" or "modify-translation"?
From 02762da1ba4344e2aaa95a6d46fcc420b67c8a16 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 13:05:27 +1000
Subject: [PATCH 141/184] use instance helpers for DocumentUpload methods
(mikado method)
---
.../java/org/zanata/file/DocumentUpload.java | 59 +++++++++----------
.../org/zanata/file/SourceDocumentUpload.java | 15 +++--
.../file/TranslationDocumentUpload.java | 10 ++--
3 files changed, 39 insertions(+), 45 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
index 8e99eaad60..881bca5358 100644
--- a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
@@ -89,9 +89,8 @@ protected DocumentUpload(
this.translationFileServiceImpl = translationFileServiceImpl;
}
- protected static void checkUploadPreconditions(GlobalDocumentId id,
- DocumentFileUploadForm uploadForm, ZanataIdentity identity,
- ProjectIterationDAO projectIterationDAO, Session session)
+ protected void checkUploadPreconditions(GlobalDocumentId id,
+ DocumentFileUploadForm uploadForm)
{
if (!identity.isLoggedIn())
{
@@ -125,7 +124,7 @@ protected static void checkUploadPreconditions(GlobalDocumentId id,
"Form parameter 'uploadId' must be provided when this is not the first part.");
}
- HDocumentUpload upload = retrieveUploadObject(uploadForm, session);
+ HDocumentUpload upload = retrieveUploadObject(uploadForm);
if (upload == null)
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
@@ -181,34 +180,32 @@ protected static void checkUploadPreconditions(GlobalDocumentId id,
}
}
- private static HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploadForm, Session session)
- {
- // TODO put in DAO
- Criteria criteria = session.createCriteria(HDocumentUpload.class);
- criteria.add(Restrictions.idEq(uploadForm.getUploadId()));
- HDocumentUpload upload = (HDocumentUpload) criteria.uniqueResult();
- return upload;
- }
-
- protected static HDocumentUpload saveUploadPart(GlobalDocumentId id,
- HLocale locale, DocumentFileUploadForm uploadForm, Session session,
- ProjectIterationDAO projectIterationDAO)
+ protected HDocumentUpload saveUploadPart(GlobalDocumentId id,
+ HLocale locale, DocumentFileUploadForm uploadForm)
{
HDocumentUpload upload;
if (uploadForm.getFirst())
{
- upload = createMultipartUpload(id, uploadForm, locale, projectIterationDAO);
+ upload = createMultipartUpload(id, uploadForm, locale);
}
else
{
- upload = retrieveUploadObject(uploadForm, session);
+ upload = retrieveUploadObject(uploadForm);
}
- saveUploadPart(uploadForm, upload, session);
+ saveUploadPart(uploadForm, upload);
+ return upload;
+ }
+
+ private HDocumentUpload retrieveUploadObject(DocumentFileUploadForm uploadForm)
+ {
+ // TODO put in DAO
+ Criteria criteria = session.createCriteria(HDocumentUpload.class);
+ criteria.add(Restrictions.idEq(uploadForm.getUploadId()));
+ HDocumentUpload upload = (HDocumentUpload) criteria.uniqueResult();
return upload;
}
- private static HDocumentUpload createMultipartUpload(GlobalDocumentId id, DocumentFileUploadForm uploadForm, HLocale locale,
- ProjectIterationDAO projectIterationDAO)
+ private HDocumentUpload createMultipartUpload(GlobalDocumentId id, DocumentFileUploadForm uploadForm, HLocale locale)
{
HProjectIteration projectIteration = projectIterationDAO.getBySlug(id.getProjectSlug(), id.getVersionSlug());
HDocumentUpload newUpload = new HDocumentUpload();
@@ -221,8 +218,7 @@ private static HDocumentUpload createMultipartUpload(GlobalDocumentId id, Docume
return newUpload;
}
- private static void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentUpload upload,
- Session session)
+ private void saveUploadPart(DocumentFileUploadForm uploadForm, HDocumentUpload upload)
{
Blob partContent = session.getLobHelper().createBlob(uploadForm.getFileStream(), uploadForm.getSize().intValue());
HDocumentUploadPart newPart = new HDocumentUploadPart();
@@ -237,13 +233,12 @@ protected static boolean isSinglePart(DocumentFileUploadForm uploadForm)
return uploadForm.getFirst() && uploadForm.getLast();
}
- protected static File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload, Session session,
- TranslationFileService transFileService)
+ protected File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload)
{
File tempFile;
try
{
- tempFile = DocumentUpload.combineToTempFile(upload, transFileService);
+ tempFile = combineToTempFile(upload);
}
catch (HashMismatchException e)
{
@@ -265,7 +260,7 @@ protected static File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upl
return tempFile;
}
- private static File combineToTempFile(HDocumentUpload upload, TranslationFileService service) throws SQLException
+ private File combineToTempFile(HDocumentUpload upload) throws SQLException
{
Vector partStreams = new Vector();
for (HDocumentUploadPart part : upload.getParts())
@@ -285,7 +280,7 @@ private static File combineToTempFile(HDocumentUpload upload, TranslationFileSer
}
InputStream combinedParts = new SequenceInputStream(partStreams.elements());
combinedParts = new DigestInputStream(combinedParts, md);
- File tempFile = service.persistToTempFile(combinedParts);
+ File tempFile = translationFileServiceImpl.persistToTempFile(combinedParts);
String md5hash = new String(Hex.encodeHex(md.digest()));
if (!md5hash.equals(upload.getContentHash()))
@@ -307,19 +302,19 @@ protected static InputStream getInputStream(Optional tempFile, DocumentFil
}
}
- protected static boolean isNewDocument(GlobalDocumentId id, DocumentDAO dao)
+ protected boolean isNewDocument(GlobalDocumentId id)
{
- return dao.getByProjectIterationAndDocId(id.getProjectSlug(), id.getVersionSlug(), id.getDocId()) == null;
+ return documentDAO.getByProjectIterationAndDocId(id.getProjectSlug(), id.getVersionSlug(), id.getDocId()) == null;
}
- protected static File persistTempFileFromUpload(DocumentFileUploadForm uploadForm, TranslationFileService transFileService)
+ protected File persistTempFileFromUpload(DocumentFileUploadForm uploadForm)
{
File tempFile;
try
{
MessageDigest md = MessageDigest.getInstance("MD5");
InputStream fileContents = new DigestInputStream(uploadForm.getFileStream(), md);
- tempFile = transFileService.persistToTempFile(fileContents);
+ tempFile = translationFileServiceImpl.persistToTempFile(fileContents);
String md5hash = new String(Hex.encodeHex(md.digest()));
if (!md5hash.equals(uploadForm.getHash()))
{
diff --git a/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
index c54c45a9a4..cb40cc9e66 100644
--- a/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
@@ -96,7 +96,7 @@ public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm
if (!uploadForm.getLast())
{
- HDocumentUpload upload = saveUploadPart(id, NULL_LOCALE, uploadForm, session, projectIterationDAO);
+ HDocumentUpload upload = saveUploadPart(id, NULL_LOCALE, uploadForm);
totalChunks = upload.getParts().size();
return Response.status(Status.ACCEPTED)
.entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
@@ -111,10 +111,9 @@ public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm
}
else
{
- HDocumentUpload upload = saveUploadPart(id, NULL_LOCALE,
- uploadForm, session, projectIterationDAO);
+ HDocumentUpload upload = saveUploadPart(id, NULL_LOCALE, uploadForm);
totalChunks = upload.getParts().size();
- tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
+ tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload));
}
if (uploadForm.getFileType().equals(".pot"))
@@ -126,7 +125,7 @@ public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm
{
if (!tempFile.isPresent())
{
- tempFile = Optional.of(persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
+ tempFile = Optional.of(persistTempFileFromUpload(uploadForm));
}
processAdapterFile(tempFile.get(), id, uploadForm);
}
@@ -134,7 +133,7 @@ public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm
{
tempFile.get().delete();
}
- return sourceUploadSuccessResponse(isNewDocument(id, documentDAO), totalChunks);
+ return sourceUploadSuccessResponse(isNewDocument(id), totalChunks);
}
catch (ChunkUploadException e)
{
@@ -155,7 +154,7 @@ private void checkSourceUploadPreconditions(GlobalDocumentId id,
{
try
{
- checkUploadPreconditions(id, uploadForm, identity, projectIterationDAO, session);
+ checkUploadPreconditions(id, uploadForm);
checkSourceUploadAllowed(id);
}
catch (AuthorizationException e)
@@ -294,7 +293,7 @@ private void parsePotFile(InputStream potStream, GlobalDocumentId id, DocumentFi
private boolean useOfflinePo(GlobalDocumentId id)
{
- return !isNewDocument(id, documentDAO)
+ return !isNewDocument(id)
&& !translationFileServiceImpl.isPoDocument(id.getProjectSlug(), id.getVersionSlug(), id.getDocId());
}
diff --git a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
index bfebc30f2b..ec9eced62e 100644
--- a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
@@ -107,7 +107,7 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
else
{
HDocumentUpload upload = saveUploadPart(new GlobalDocumentId(projectSlug, iterationSlug, docId), locale,
- uploadForm, session, projectIterationDAO);
+ uploadForm);
totalChunks = upload.getParts().size();
if (!uploadForm.getLast())
{
@@ -116,7 +116,7 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
"Chunk accepted, awaiting remaining chunks."))
.build();
}
- tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload, session, translationFileServiceImpl));
+ tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload));
}
TranslationsResource transRes;
@@ -129,7 +129,7 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
{
if (!tempFile.isPresent())
{
- tempFile = Optional.of(DocumentUpload.persistTempFileFromUpload(uploadForm, translationFileServiceImpl));
+ tempFile = Optional.of(persistTempFileFromUpload(uploadForm));
}
// FIXME this is misusing the 'filename' field. the method should probably take a
// type anyway
@@ -172,7 +172,7 @@ private void checkTranslationUploadPreconditions(String projectSlug, String iter
String docId, String localeId, DocumentFileUploadForm uploadForm)
{
checkUploadPreconditions(new GlobalDocumentId(projectSlug, iterationSlug, docId),
- uploadForm, identity, projectIterationDAO, session);
+ uploadForm);
// TODO check translation upload allowed
@@ -183,7 +183,7 @@ private void checkTranslationUploadPreconditions(String projectSlug, String iter
private void checkDocumentExists(String projectSlug, String iterationSlug, String docId,
DocumentFileUploadForm uploadForm)
{
- if (isNewDocument(new GlobalDocumentId(projectSlug, iterationSlug, docId), documentDAO))
+ if (isNewDocument(new GlobalDocumentId(projectSlug, iterationSlug, docId)))
{
throw new ChunkUploadException(Status.NOT_FOUND,
"No document with id \"" + docId + "\" exists in project-version \"" +
From aed0cf5243cf44c582a2c6fbc5648606033eac38 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 13:20:31 +1000
Subject: [PATCH 142/184] use composite id object for all translation upload
methods (mikado method)
---
.../file/TranslationDocumentUpload.java | 46 +++++++++----------
.../org/zanata/rest/service/FileService.java | 3 +-
2 files changed, 24 insertions(+), 25 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
index ec9eced62e..83d890c7ef 100644
--- a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
@@ -86,15 +86,15 @@ public TranslationDocumentUpload(ZanataIdentity identity,
this.translationServiceImpl = translationServiceImpl;
}
- public Response tryUploadTranslationFile(String projectSlug, String iterationSlug, String docId,
+ public Response tryUploadTranslationFile(GlobalDocumentId id,
String localeId, String mergeType, DocumentFileUploadForm uploadForm)
{
HLocale locale;
try
{
- checkTranslationUploadPreconditions(projectSlug, iterationSlug, docId, localeId, uploadForm);
+ checkTranslationUploadPreconditions(id, localeId, uploadForm);
locale = findHLocale(localeId);
- checkTranslationUploadAllowed(projectSlug, iterationSlug, localeId, locale);
+ checkTranslationUploadAllowed(id, localeId, locale);
Optional tempFile;
int totalChunks;
@@ -106,8 +106,7 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
}
else
{
- HDocumentUpload upload = saveUploadPart(new GlobalDocumentId(projectSlug, iterationSlug, docId), locale,
- uploadForm);
+ HDocumentUpload upload = saveUploadPart(id, locale, uploadForm);
totalChunks = upload.getParts().size();
if (!uploadForm.getLast())
{
@@ -123,7 +122,8 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
if (uploadForm.getFileType().equals(".po"))
{
InputStream poStream = getInputStream(tempFile, uploadForm);
- transRes = translationFileServiceImpl.parsePoFile(poStream, projectSlug, iterationSlug, docId);
+ transRes = translationFileServiceImpl.parsePoFile(poStream, id.getProjectSlug(),
+ id.getVersionSlug(), id.getDocId());
}
else
{
@@ -134,7 +134,7 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
// FIXME this is misusing the 'filename' field. the method should probably take a
// type anyway
transRes = translationFileServiceImpl.parseAdapterTranslationFile(tempFile.get(),
- projectSlug, iterationSlug, docId, localeId, uploadForm.getFileType());
+ id.getProjectSlug(), id.getVersionSlug(), id.getDocId(), localeId, uploadForm.getFileType());
}
if (tempFile.isPresent())
{
@@ -143,8 +143,8 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
Set extensions = newExtensions(uploadForm.getFileType().equals(".po"));
// TODO useful error message for failed saving?
- List warnings = translationServiceImpl.translateAllInDoc(projectSlug, iterationSlug,
- docId, locale.getLocaleId(), transRes, extensions, mergeTypeFromString(mergeType));
+ List warnings = translationServiceImpl.translateAllInDoc(id.getProjectSlug(), id.getVersionSlug(),
+ id.getDocId(), locale.getLocaleId(), transRes, extensions, mergeTypeFromString(mergeType));
return transUploadResponse(totalChunks, warnings);
}
@@ -168,26 +168,24 @@ public Response tryUploadTranslationFile(String projectSlug, String iterationSlu
}
}
- private void checkTranslationUploadPreconditions(String projectSlug, String iterationSlug,
- String docId, String localeId, DocumentFileUploadForm uploadForm)
+ private void checkTranslationUploadPreconditions(GlobalDocumentId id, String localeId,
+ DocumentFileUploadForm uploadForm)
{
- checkUploadPreconditions(new GlobalDocumentId(projectSlug, iterationSlug, docId),
- uploadForm);
+ checkUploadPreconditions(id, uploadForm);
// TODO check translation upload allowed
- checkDocumentExists(projectSlug, iterationSlug, docId, uploadForm);
+ checkDocumentExists(id, uploadForm);
checkValidTranslationUploadType(uploadForm);
}
- private void checkDocumentExists(String projectSlug, String iterationSlug, String docId,
- DocumentFileUploadForm uploadForm)
+ private void checkDocumentExists(GlobalDocumentId id, DocumentFileUploadForm uploadForm)
{
- if (isNewDocument(new GlobalDocumentId(projectSlug, iterationSlug, docId)))
+ if (isNewDocument(id))
{
throw new ChunkUploadException(Status.NOT_FOUND,
- "No document with id \"" + docId + "\" exists in project-version \"" +
- projectSlug + ":" + iterationSlug + "\".");
+ "No document with id \"" + id.getDocId() + "\" exists in project-version \"" +
+ id.getProjectSlug() + ":" + id.getVersionSlug() + "\".");
}
}
@@ -225,19 +223,19 @@ private HLocale findHLocale(String localeString)
return locale;
}
- private void checkTranslationUploadAllowed(String projectSlug, String iterationSlug, String localeId, HLocale locale)
+ private void checkTranslationUploadAllowed(GlobalDocumentId id, String localeId, HLocale locale)
{
- if (!isTranslationUploadAllowed(projectSlug, iterationSlug, locale))
+ if (!isTranslationUploadAllowed(id, locale))
{
throw new ChunkUploadException(Status.FORBIDDEN,
"You do not have permission to upload translations for locale \"" + localeId +
- "\" to project-version \"" + projectSlug + ":" + iterationSlug + "\".");
+ "\" to project-version \"" + id.getProjectSlug() + ":" + id.getVersionSlug() + "\".");
}
}
- private boolean isTranslationUploadAllowed(String projectSlug, String iterationSlug, HLocale localeId)
+ private boolean isTranslationUploadAllowed(GlobalDocumentId id, HLocale localeId)
{
- HProjectIteration projectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);
+ HProjectIteration projectIteration = projectIterationDAO.getBySlug(id.getProjectSlug(), id.getVersionSlug());
// TODO should this check be "add-translation" or "modify-translation"?
// They appear to be granted identically at the moment.
return projectIteration.getStatus() == EntityStatus.ACTIVE && projectIteration.getProject().getStatus() == EntityStatus.ACTIVE
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index 92c92ef617..fce260ec60 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -168,11 +168,12 @@ public Response uploadTranslationFile( @PathParam("projectSlug") String projectS
@QueryParam("merge") String merge,
@MultipartForm DocumentFileUploadForm uploadForm )
{
+ GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
TranslationDocumentUpload uploader = new TranslationDocumentUpload(identity, session, documentDAO, projectIterationDAO,
documentServiceImpl, virusScanner, translationFileServiceImpl, localeDAO, translationServiceImpl);
- return uploader.tryUploadTranslationFile(projectSlug, iterationSlug, docId, localeId, merge, uploadForm);
+ return uploader.tryUploadTranslationFile(id, localeId, merge, uploadForm);
}
/**
From d3f24c9e896e0346a133b329a0c5d924e35d57fd Mon Sep 17 00:00:00 2001
From: David Mason
Date: Wed, 17 Jul 2013 13:22:55 +1000
Subject: [PATCH 143/184] use consistent naming in GlobalDocumentId
---
.../src/main/java/org/zanata/file/GlobalDocumentId.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/file/GlobalDocumentId.java b/zanata-war/src/main/java/org/zanata/file/GlobalDocumentId.java
index 3e0fae3723..c3db46b357 100644
--- a/zanata-war/src/main/java/org/zanata/file/GlobalDocumentId.java
+++ b/zanata-war/src/main/java/org/zanata/file/GlobalDocumentId.java
@@ -10,10 +10,10 @@ public class GlobalDocumentId
private final String versionSlug;
private final String docId;
- public GlobalDocumentId(String projectSlug, String iterationSlug, String docId)
+ public GlobalDocumentId(String projectSlug, String versionSlug, String docId)
{
this.projectSlug = projectSlug;
- this.versionSlug = iterationSlug;
+ this.versionSlug = versionSlug;
this.docId = docId;
}
From 5c19bd2a33114228cad3d03ce2d2eaffbac4962e Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Thu, 18 Jul 2013 08:47:25 +1000
Subject: [PATCH 144/184] Refactor pager widget
---
.../presenter/TranslationEditorPresenter.java | 18 ++--
.../org/zanata/webtrans/client/ui/Pager.java | 102 +++++++++++-------
.../client/view/TranslationEditorDisplay.java | 6 +-
.../client/view/TranslationEditorView.java | 7 ++
.../server/rpc/GetTransUnitListHandler.java | 1 -
5 files changed, 81 insertions(+), 53 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationEditorPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationEditorPresenter.java
index ca46e5b036..bec2ec7347 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationEditorPresenter.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationEditorPresenter.java
@@ -31,8 +31,6 @@
import org.zanata.webtrans.client.events.RefreshPageEvent;
import org.zanata.webtrans.client.view.TranslationEditorDisplay;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.inject.Inject;
public class TranslationEditorPresenter extends WidgetPresenter implements PageChangeEventHandler, PageCountChangeEventHandler, TranslationEditorDisplay.Listener
@@ -68,14 +66,6 @@ protected void onBind()
transUnitNavigationPresenter.bind();
display.setTransUnitNavigation(transUnitNavigationPresenter.getDisplay().asWidget());
- registerHandler(display.getPageNavigation().addValueChangeHandler(new ValueChangeHandler()
- {
- @Override
- public void onValueChange(ValueChangeEvent event)
- {
- transUnitsTablePresenter.goToPage(event.getValue());
- }
- }));
registerHandler(eventBus.addHandler(PageChangeEvent.TYPE, this));
registerHandler(eventBus.addHandler(PageCountChangeEvent.TYPE, this));
}
@@ -133,9 +123,17 @@ public void onPagerBlurred()
{
editorKeyShortcuts.enableEditContext();
}
+
+ @Override
+ public void onPagerValueChanged(Integer pageNumber)
+ {
+ transUnitsTablePresenter.goToPage(pageNumber);
+ }
public void setReadOnly(boolean isReadOnly)
{
display.getResizeButton().setVisible(isReadOnly);
}
+
+
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java
index cd3a35edd1..15e64d09f2 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java
@@ -1,3 +1,23 @@
+/*
+ * 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.ui;
import org.zanata.webtrans.client.resources.Resources;
@@ -13,7 +33,6 @@
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
-import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
@@ -27,9 +46,14 @@
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
+/**
+ * @author Alex Eng aeng@redhat.com
+ *
+ */
public class Pager extends Composite implements HasPager
{
-
+ public static final int PAGECOUNT_UNKNOWN = -1;
+
private static PagerUiBinder uiBinder = GWT.create(PagerUiBinder.class);
interface PagerUiBinder extends UiBinder
@@ -59,11 +83,10 @@ interface Styles extends CssResource
Styles style;
private int pageCount = PAGECOUNT_UNKNOWN;
+ private int minPageCount = 0;
private int currentPage;
private boolean isFocused;
- public static final int PAGECOUNT_UNKNOWN = -1;
-
public Pager(final WebTransMessages messages, final Resources resources)
{
this.resources = resources;
@@ -87,29 +110,36 @@ public void onGotoPageBlur(BlurEvent event)
{
isFocused = false;
}
-
- @Override
- protected void onLoad()
+
+ @UiHandler("gotoPage")
+ public void onGotoPageKeyDown(KeyDownEvent event)
{
- super.onLoad();
- gotoPage.addKeyDownHandler(new KeyDownHandler()
+ if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER)
{
- @Override
- public void onKeyDown(KeyDownEvent event)
+ try
{
- if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER)
+ int newValue = Integer.parseInt(gotoPage.getText());
+ if (newValue < minPageCount)
+ {
+ newValue = minPageCount;
+ }
+ else if(newValue > pageCount)
{
- try
- {
- int newValue = Integer.parseInt(gotoPage.getText());
- setValue(newValue);
- }
- catch (NumberFormatException nfe)
- {
- }
+ newValue = pageCount;
}
+ setValue(newValue);
}
- });
+ catch (NumberFormatException nfe)
+ {
+ Log.error("Invalid page number entered");
+ }
+ }
+ }
+
+ @Override
+ protected void onLoad()
+ {
+ super.onLoad();
firstPage.addClickHandler(clickHandler);
lastPage.addClickHandler(clickHandler);
@@ -122,8 +152,8 @@ private void refresh()
{
String page = pageCount == PAGECOUNT_UNKNOWN ? "" : "of " + pageCount;
pageCountLabel.setText(page);
- setEnabled(firstPage, currentPage != 1);
- setEnabled(prevPage, currentPage != 1);
+ setEnabled(firstPage, currentPage > minPageCount);
+ setEnabled(prevPage, currentPage > minPageCount);
setEnabled(nextPage, currentPage != pageCount);
setEnabled(lastPage, currentPage != pageCount && pageCount != PAGECOUNT_UNKNOWN);
@@ -134,6 +164,7 @@ private void refresh()
public void setPageCount(int pageCount)
{
this.pageCount = pageCount;
+ this.minPageCount = pageCount <= 0 ? 0 : 1;
refresh();
}
@@ -158,7 +189,7 @@ public void setValue(Integer value)
@Override
public void setValue(Integer value, boolean fireEvents)
{
- if (value != this.currentPage && (value > 0 && value <= pageCount))
+ if (value >= minPageCount && value <= pageCount)
{
this.currentPage = value;
if (fireEvents)
@@ -177,34 +208,25 @@ public HandlerRegistration addValueChangeHandler(ValueChangeHandler han
private final ClickHandler clickHandler = new ClickHandler()
{
-
@Override
public void onClick(ClickEvent event)
{
- if (event.getSource() == firstPage)
+ Widget clickedButton = (Widget) event.getSource();
+ if (isButtonEnabled(clickedButton))
{
- if (isButtonEnabled(firstPage))
+ if (clickedButton == firstPage)
{
setValue(1);
}
- }
- else if (event.getSource() == lastPage)
- {
- if (isButtonEnabled(lastPage))
+ else if (clickedButton == lastPage)
{
setValue(pageCount);
}
- }
- else if (event.getSource() == nextPage)
- {
- if (isButtonEnabled(nextPage))
+ else if (clickedButton == nextPage)
{
setValue(currentPage + 1);
}
- }
- else if (event.getSource() == prevPage)
- {
- if (isButtonEnabled(prevPage))
+ else if (clickedButton == prevPage)
{
setValue(currentPage - 1);
}
@@ -212,7 +234,7 @@ else if (event.getSource() == prevPage)
}
};
- private boolean isButtonEnabled(InlineLabel button)
+ private boolean isButtonEnabled(Widget button)
{
return button.getStyleName().contains(style.enabled());
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TranslationEditorDisplay.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TranslationEditorDisplay.java
index 6263498c4d..1a3df410f3 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TranslationEditorDisplay.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TranslationEditorDisplay.java
@@ -6,11 +6,11 @@
import com.google.gwt.user.client.ui.HasVisibility;
import com.google.gwt.user.client.ui.IsWidget;
-import com.google.gwt.user.client.ui.Widget;
+
/**
- * @author aeng
+ * @author Alex Eng aeng@redhat.com
*
*/
public interface TranslationEditorDisplay extends WidgetDisplay
@@ -38,6 +38,8 @@ interface Listener
void onPagerFocused();
void onPagerBlurred();
+
+ void onPagerValueChanged(Integer pageNumber);
}
HasVisibility getResizeButton();
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TranslationEditorView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TranslationEditorView.java
index 250b7e7fd7..f514e1013f 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TranslationEditorView.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TranslationEditorView.java
@@ -29,6 +29,7 @@
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.FocusEvent;
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
@@ -180,6 +181,12 @@ public void onPagerBlurred(BlurEvent event)
{
listener.onPagerBlurred();
}
+
+ @UiHandler("pager")
+ public void onPagerValueChanged(ValueChangeEvent event)
+ {
+ listener.onPagerValueChanged(event.getValue());
+ }
@UiHandler("resize")
public void onResizeIconClick(ClickEvent event)
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 fc17eefe0a..5599aae95e 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
@@ -40,7 +40,6 @@
import org.zanata.service.LocaleService;
import org.zanata.service.ValidationService;
import org.zanata.webtrans.server.ActionHandlerFor;
-import org.zanata.webtrans.shared.model.ContentStateGroup;
import org.zanata.webtrans.shared.model.TransUnit;
import org.zanata.webtrans.shared.rpc.GetTransUnitList;
import org.zanata.webtrans.shared.rpc.GetTransUnitListResult;
From cb1ede979a9ff43eb1ce33a976f2ae67fab6ede9 Mon Sep 17 00:00:00 2001
From: Damian Jansen
Date: Wed, 17 Jul 2013 10:42:56 +1000
Subject: [PATCH 145/184] Remove for loops and conditions in tests.
For loops and if conditions are sub-optimal in tests, for both
stability and readability. Removed and replaced with Theory run
features.
Though this adds some time to the detailed tests, it's more correct.
---
.../startNewProject/AddLanguageTest.java | 29 +------
.../versionGroup/VersionGroupFullTest.java | 67 ++--------------
.../VersionGroupIDValidationTest.java | 76 +++++++++++++++++++
3 files changed, 85 insertions(+), 87 deletions(-)
create mode 100644 functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupIDValidationTest.java
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java
index 1895effcae..362d013724 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java
@@ -20,8 +20,7 @@
*/
package org.zanata.feature.startNewProject;
-import java.util.List;
-
+import lombok.extern.slf4j.Slf4j;
import org.concordion.api.extension.Extensions;
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
@@ -36,8 +35,6 @@
import org.zanata.page.administration.ManageLanguageTeamMemberPage;
import org.zanata.workflow.LoginWorkFlow;
-import lombok.extern.slf4j.Slf4j;
-
/**
* @author Patrick Huang pahuang@redhat.com
*/
@@ -64,31 +61,11 @@ public ManageLanguagePage goToManageLanguagePage()
public ManageLanguagePage addNewLanguage(String locale)
{
- List locales = manageLanguagePage.getLanguageLocales();
- if (locales.contains(locale))
- {
- log.warn("{} has already been added, enabling by default", locale);
- manageLanguagePage = manageLanguagePage.enableLanguageByDefault(locale);
- }
- else
- {
- //continue to add the new language
- manageLanguagePage = manageLanguagePage.addNewLanguage().enableLanguageByDefault().inputLanguage(locale).saveLanguage();
- }
- return manageLanguagePage;
+ return manageLanguagePage.addNewLanguage().enableLanguageByDefault().inputLanguage(locale).saveLanguage();
}
public ManageLanguageTeamMemberPage joinLanguageAsAdmin(String locale)
{
- ManageLanguageTeamMemberPage teamMemberPage = manageLanguagePage.manageTeamMembersFor(locale);
- if (teamMemberPage.getMemberUsernames().contains("admin"))
- {
- log.warn("admin has already joined the language [{}]", locale);
- return teamMemberPage;
- }
- else
- {
- return teamMemberPage.joinLanguageTeam();
- }
+ return manageLanguagePage.manageTeamMembersFor(locale).joinLanguageTeam();
}
}
diff --git a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupFullTest.java b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupFullTest.java
index 445ecc652d..67e67aff24 100644
--- a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupFullTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupFullTest.java
@@ -20,28 +20,25 @@
*/
package org.zanata.feature.versionGroup;
-import java.util.*;
-
import org.hamcrest.Matchers;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import org.junit.*;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.zanata.feature.BasicAcceptanceTest;
import org.zanata.feature.DetailedTest;
import org.zanata.page.HomePage;
+import org.zanata.page.groups.CreateVersionGroupPage;
import org.zanata.page.groups.VersionGroupPage;
import org.zanata.page.groups.VersionGroupsPage;
-import org.zanata.page.groups.CreateVersionGroupPage;
import org.zanata.util.ResetDatabaseRule;
import org.zanata.workflow.LoginWorkFlow;
-import lombok.extern.slf4j.Slf4j;
+import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Damian Jansen djansen@redhat.com
*/
-@Slf4j
@Category(DetailedTest.class)
public class VersionGroupFullTest
{
@@ -73,21 +70,6 @@ public void createABasicGroup()
assertThat("The group is displayed", groupView.getTitle(), Matchers.equalTo("Zanata: Groups:".concat(groupName)));
}
- @Test
- public void inputValidationForID()
- {
- String errorMsg = "must start and end with letter or number, and contain only letters, numbers, underscores and hyphens.";
- for (Map.Entry entry : inputValidationForIDData().entrySet())
- {
- VersionGroupFullTest.log.info("Test " + entry.getKey() + ":" + entry.getValue());
- VersionGroupsPage versionGroupsPage = homePage.goToGroups();
- CreateVersionGroupPage groupPage = versionGroupsPage.createNewGroup();
- groupPage.inputGroupId(entry.getValue()).inputGroupName(entry.getValue());
- groupPage.saveGroupFailure();
- assertThat("Validation error is displayed for " + entry.getKey(), groupPage.getErrors().contains(errorMsg));
- }
- }
-
@Test
public void requiredFields()
{
@@ -96,7 +78,7 @@ public void requiredFields()
String groupName = "verifyRequiredFieldsGroupName";
CreateVersionGroupPage groupPage = homePage.goToGroups().createNewGroup().saveGroupFailure();
- assertThat("The two errors are value is required", groupPage.getErrors(),Matchers.contains(errorMsg, errorMsg));
+ assertThat("The two errors are value is required", groupPage.getErrors(), Matchers.contains(errorMsg, errorMsg));
groupPage.clearFields();
groupPage.inputGroupName(groupName);
@@ -150,41 +132,4 @@ public void groupDescriptionFieldSize()
}
- private LinkedHashMap inputValidationForIDData()
- {
- LinkedHashMap inputData = new LinkedHashMap(100);
- inputData.put("Invalid char |", "Group|ID");
- inputData.put("Invalid char /", "Group/ID");
- inputData.put("Invalid char ", "Group\\ID");
- inputData.put("Invalid char +", "Group+ID");
- inputData.put("Invalid char *", "Group*ID");
- inputData.put("Invalid char |", "Group|ID");
- inputData.put("Invalid char (", "Group(ID");
- inputData.put("Invalid char )", "Group)ID");
- inputData.put("Invalid char $", "Group$ID");
- inputData.put("Invalid char [", "Group[ID");
- inputData.put("Invalid char ]", "Group]ID");
- inputData.put("Invalid char :", "Group:ID");
- inputData.put("Invalid char ;", "Group;ID");
- inputData.put("Invalid char '", "Group'ID");
- inputData.put("Invalid char ,", "Group,ID");
- inputData.put("Invalid char ?", "Group?ID");
- inputData.put("Invalid char !", "Group!ID");
- inputData.put("Invalid char @", "Group@ID");
- inputData.put("Invalid char #", "Group#ID");
- inputData.put("Invalid char %", "Group%ID");
- inputData.put("Invalid char ^", "Group^ID");
- inputData.put("Invalid char =", "Group=ID");
- inputData.put("Must start with alphanumeric", "-GroupID");
- inputData.put("Must end with alphanumeric", "GroupID-");
-
- /* BUG id=973509 - remove/uncomment depending on outcome
- inputData.put("Invalid char .", "Group.ID");
- inputData.put("Invalid char {", "Group{ID");
- inputData.put("Invalid char }", "Group}ID");
- */
-
- return inputData;
- }
-
}
diff --git a/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupIDValidationTest.java b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupIDValidationTest.java
new file mode 100644
index 0000000000..16a97d9dee
--- /dev/null
+++ b/functional-test/src/test/java/org/zanata/feature/versionGroup/VersionGroupIDValidationTest.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.feature.versionGroup;
+
+import org.junit.ClassRule;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.runner.RunWith;
+import org.zanata.page.groups.CreateVersionGroupPage;
+import org.zanata.util.ResetDatabaseRule;
+import org.zanata.workflow.LoginWorkFlow;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * @author Damian Jansen djansen@redhat.com
+ */
+@RunWith(Theories.class)
+public class VersionGroupIDValidationTest {
+
+ @ClassRule
+ public static ResetDatabaseRule resetDatabaseRule = new ResetDatabaseRule();
+
+ @DataPoint public static String INVALID_CHARACTER_PIPE = "Group|ID";
+ @DataPoint public static String INVALID_CHARACTER_SLASH = "Group/ID";
+ @DataPoint public static String INVALID_CHARACTER_BACKSLASH = "Group\\ID";
+ @DataPoint public static String INVALID_CHARACTER_PLUS = "Group+ID";
+ @DataPoint public static String INVALID_CHARACTER_ASTERISK = "Group*ID";
+ @DataPoint public static String INVALID_CHARACTER_LEFT_PARENTHESES = "Group(ID";
+ @DataPoint public static String INVALID_CHARACTER_RIGHT_PARENTHESES = "Group)ID";
+ @DataPoint public static String INVALID_CHARACTER_DOLLAR = "Group$ID";
+ @DataPoint public static String INVALID_CHARACTER_LEFT_BRACKET = "Group[ID";
+ @DataPoint public static String INVALID_CHARACTER_RIGHT_BRACKET = "Group]ID";
+ @DataPoint public static String INVALID_CHARACTER_COLON = "Group:ID";
+ @DataPoint public static String INVALID_CHARACTER_SEMICOLON = "Group;ID";
+ @DataPoint public static String INVALID_CHARACTER_APOSTROPHE = "Group'ID";
+ @DataPoint public static String INVALID_CHARACTER_COMMA = "Group,ID";
+ @DataPoint public static String INVALID_CHARACTER_QUESTION = "Group?ID";
+ @DataPoint public static String INVALID_CHARACTER_EXCLAMATION = "Group!ID";
+ @DataPoint public static String INVALID_CHARACTER_AMPERSAT = "Group@ID";
+ @DataPoint public static String INVALID_CHARACTER_HASH = "Group#ID";
+ @DataPoint public static String INVALID_CHARACTER_PERCENT = "Group%ID";
+ @DataPoint public static String INVALID_CHARACTER_CARAT = "Group^ID";
+ @DataPoint public static String INVALID_CHARACTER_EQUALS = "Group=ID";
+ @DataPoint public static String MUST_START_ALPHANUMERIC = "-GroupID";
+ @DataPoint public static String MUST_END_ALPHANUMERIC = "GroupID-";
+
+ @Theory
+ public void inputValidationForID(String inputText)
+ {
+ String errorMsg = "must start and end with letter or number, and contain only letters, numbers, underscores and hyphens.";
+ CreateVersionGroupPage groupPage = new LoginWorkFlow().signIn("admin", "admin").goToGroups().createNewGroup();
+ groupPage.inputGroupId(inputText).inputGroupName(inputText);
+ groupPage.saveGroupFailure();
+ assertThat("Validation error is displayed for input " + inputText, groupPage.getErrors().contains(errorMsg));
+ }
+}
From cbd2656b15a26ba3ef46b181bb7a4a0e9f57e439 Mon Sep 17 00:00:00 2001
From: Damian Jansen
Date: Thu, 18 Jul 2013 10:04:27 +1000
Subject: [PATCH 146/184] Fix AddLanguageTest.java
Broken in previous commit.
---
.../org/zanata/feature/startNewProject/AddLanguageTest.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java b/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java
index 362d013724..9c81900b22 100644
--- a/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java
+++ b/functional-test/src/test/java/org/zanata/feature/startNewProject/AddLanguageTest.java
@@ -20,7 +20,6 @@
*/
package org.zanata.feature.startNewProject;
-import lombok.extern.slf4j.Slf4j;
import org.concordion.api.extension.Extensions;
import org.concordion.ext.ScreenshotExtension;
import org.concordion.ext.TimestampFormatterExtension;
@@ -38,7 +37,6 @@
/**
* @author Patrick Huang pahuang@redhat.com
*/
-@Slf4j
@RunWith(ConcordionRunner.class)
@Extensions({ScreenshotExtension.class, TimestampFormatterExtension.class, CustomResourceExtension.class})
@Category(ConcordionTest.class)
From 9a821546ecdc874bc7e320109ab406b97e0169be Mon Sep 17 00:00:00 2001
From: David Mason
Date: Thu, 18 Jul 2013 12:00:09 +1000
Subject: [PATCH 147/184] change document upload classes to services
---
...entUpload.java => DocumentUploadUtil.java} | 85 ++++++++-----------
.../org/zanata/file/SourceDocumentUpload.java | 53 ++++++------
.../file/TranslationDocumentUpload.java | 57 ++++++-------
.../org/zanata/rest/service/FileService.java | 42 ++-------
.../rest/service/raw/FileRawRestITCase.java | 35 +++++---
5 files changed, 118 insertions(+), 154 deletions(-)
rename zanata-war/src/main/java/org/zanata/file/{DocumentUpload.java => DocumentUploadUtil.java} (86%)
diff --git a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/DocumentUploadUtil.java
similarity index 86%
rename from zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
rename to zanata-war/src/main/java/org/zanata/file/DocumentUploadUtil.java
index 881bca5358..d294c0bd3a 100644
--- a/zanata-war/src/main/java/org/zanata/file/DocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/DocumentUploadUtil.java
@@ -39,6 +39,8 @@
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Name;
import org.jboss.seam.security.AuthorizationException;
import org.jboss.seam.util.Hex;
import org.zanata.common.DocumentType;
@@ -52,43 +54,29 @@
import org.zanata.model.HLocale;
import org.zanata.model.HProjectIteration;
import org.zanata.rest.DocumentFileUploadForm;
-import org.zanata.rest.service.VirusScanner;
import org.zanata.security.ZanataIdentity;
-import org.zanata.service.DocumentService;
import org.zanata.service.TranslationFileService;
import com.google.common.base.Optional;
@Slf4j
-public class DocumentUpload
+@Name("documentUploadUtil")
+public class DocumentUploadUtil
{
- protected final DocumentService documentServiceImpl;
- protected final VirusScanner virusScanner;
- protected final ZanataIdentity identity;
- protected final Session session;
- protected final DocumentDAO documentDAO;
- protected final ProjectIterationDAO projectIterationDAO;
- protected final TranslationFileService translationFileServiceImpl;
-
- protected DocumentUpload(
- ZanataIdentity identity,
- Session session,
- DocumentDAO documentDAO,
- ProjectIterationDAO projectIterationDAO,
- DocumentService documentServiceImpl,
- VirusScanner virusScanner,
- TranslationFileService translationFileServiceImpl)
- {
- this.identity = identity;
- this.session = session;
- this.documentDAO = documentDAO;
- this.projectIterationDAO = projectIterationDAO;
- this.documentServiceImpl = documentServiceImpl;
- this.virusScanner = virusScanner;
- this.translationFileServiceImpl = translationFileServiceImpl;
- }
+ @In
+ private ZanataIdentity identity;
+ @In
+ private Session session;
+ @In
+ private DocumentDAO documentDAO;
+ @In
+ private ProjectIterationDAO projectIterationDAO;
+ @In
+ private TranslationFileService translationFileServiceImpl;
+ // TODO change name and add thrown exception to make it clear
+ // that this is meant to throw.
protected void checkUploadPreconditions(GlobalDocumentId id,
DocumentFileUploadForm uploadForm)
{
@@ -97,25 +85,25 @@ protected void checkUploadPreconditions(GlobalDocumentId id,
throw new AuthorizationException("Valid combination of username and api-key for this" +
" server were not included in the request.");
}
-
+
if (id.getDocId() == null || id.getDocId().isEmpty())
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Required query string parameter 'docId' was not found.");
}
-
+
if (uploadForm.getFileStream() == null)
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Required form parameter 'file' containing file content was not found.");
}
-
+
if (uploadForm.getFirst() == null || uploadForm.getLast() == null)
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Form parameters 'first' and 'last' must both be provided.");
}
-
+
if (!uploadForm.getFirst())
{
if (uploadForm.getUploadId() == null)
@@ -123,7 +111,7 @@ protected void checkUploadPreconditions(GlobalDocumentId id,
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Form parameter 'uploadId' must be provided when this is not the first part.");
}
-
+
HDocumentUpload upload = retrieveUploadObject(uploadForm);
if (upload == null)
{
@@ -134,49 +122,49 @@ protected void checkUploadPreconditions(GlobalDocumentId id,
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Supplied uploadId '" + uploadForm.getUploadId()
- + "' in request is not valid for document '" + id.getDocId() + "'.");
+ + "' in request is not valid for document '" + id.getDocId() + "'.");
}
}
-
+
String fileType = uploadForm.getFileType();
if (fileType == null || fileType.isEmpty())
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Required form parameter 'type' was not found.");
}
-
+
if (DocumentType.typeFor(fileType) == null)
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Value '" + fileType + "' is not a recognized document type.");
}
-
+
String contentHash = uploadForm.getHash();
if (contentHash == null || contentHash.isEmpty())
{
throw new ChunkUploadException(Status.PRECONDITION_FAILED,
"Required form parameter 'hash' was not found.");
}
-
+
HProjectIteration projectIteration = projectIterationDAO.getBySlug(id.getProjectSlug(), id.getVersionSlug());
if (projectIteration == null)
{
throw new ChunkUploadException(Status.NOT_FOUND,
"The specified project-version \"" + id.getProjectSlug() + ":" + id.getVersionSlug() +
- "\" does not exist on this server.");
+ "\" does not exist on this server.");
}
-
+
if (projectIteration.getProject().getStatus() != EntityStatus.ACTIVE)
{
throw new ChunkUploadException(Status.FORBIDDEN,
"The project \"" + id.getProjectSlug() + "\" is not active. Document upload is not allowed.");
}
-
+
if (projectIteration.getStatus() != EntityStatus.ACTIVE)
{
throw new ChunkUploadException(Status.FORBIDDEN,
"The project-version \"" + id.getProjectSlug() + ":" + id.getVersionSlug() +
- "\" is not active. Document upload is not allowed.");
+ "\" is not active. Document upload is not allowed.");
}
}
@@ -244,8 +232,8 @@ protected File combineToTempFileAndDeleteUploadRecord(HDocumentUpload upload)
{
throw new ChunkUploadException(Status.CONFLICT,
"MD5 hash \"" + e.getExpectedHash() + "\" sent with initial request does not match" +
- " server-generated hash of combined parts \"" + e.getGeneratedHash() +
- "\". Upload aborted. Retry upload from first part.");
+ " server-generated hash of combined parts \"" + e.getGeneratedHash() +
+ "\". Upload aborted. Retry upload from first part.");
}
catch (SQLException e)
{
@@ -267,7 +255,7 @@ private File combineToTempFile(HDocumentUpload upload) throws SQLException
{
partStreams.add(part.getContent().getBinaryStream());
}
-
+
MessageDigest md;
try
{
@@ -282,7 +270,7 @@ private File combineToTempFile(HDocumentUpload upload) throws SQLException
combinedParts = new DigestInputStream(combinedParts, md);
File tempFile = translationFileServiceImpl.persistToTempFile(combinedParts);
String md5hash = new String(Hex.encodeHex(md.digest()));
-
+
if (!md5hash.equals(upload.getContentHash()))
{
throw new HashMismatchException("MD5 hashes do not match.\n", upload.getContentHash(), md5hash);
@@ -319,9 +307,8 @@ protected File persistTempFileFromUpload(DocumentFileUploadForm uploadForm)
if (!md5hash.equals(uploadForm.getHash()))
{
throw new ChunkUploadException(Status.CONFLICT,
- "MD5 hash \"" + uploadForm.getHash() +
- "\" sent with request does not match server-generated hash. " +
- "Aborted upload operation.");
+ "MD5 hash \"" + uploadForm.getHash() + "\" sent with request does not match " +
+ "server-generated hash. Aborted upload operation.");
}
}
catch (NoSuchAlgorithmException e)
diff --git a/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
index cb40cc9e66..c86c9c2a28 100644
--- a/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/SourceDocumentUpload.java
@@ -20,6 +20,9 @@
*/
package org.zanata.file;
+import static org.zanata.file.DocumentUploadUtil.getInputStream;
+import static org.zanata.file.DocumentUploadUtil.isSinglePart;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -34,7 +37,8 @@
import lombok.extern.slf4j.Slf4j;
import org.hibernate.LobHelper;
-import org.hibernate.Session;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Name;
import org.jboss.seam.security.AuthorizationException;
import org.zanata.common.DocumentType;
import org.zanata.common.EntityStatus;
@@ -63,27 +67,26 @@
import com.google.common.base.Strings;
@Slf4j
-public class SourceDocumentUpload extends DocumentUpload
+@Name("sourceDocumentUploader")
+public class SourceDocumentUpload
{
private static final HLocale NULL_LOCALE = null;
- public SourceDocumentUpload(ZanataIdentity identity,
- Session session,
- DocumentDAO documentDAO,
- ProjectIterationDAO projectIterationDAO,
- DocumentService documentServiceImpl,
- VirusScanner virusScanner,
- TranslationFileService translationFileServiceImpl)
- {
- super(identity,
- session,
- documentDAO,
- projectIterationDAO,
- documentServiceImpl,
- virusScanner,
- translationFileServiceImpl);
- }
+ @In(create = true, value = "documentUploadUtil")
+ private DocumentUploadUtil util;
+ @In
+ private ZanataIdentity identity;
+ @In
+ private ProjectIterationDAO projectIterationDAO;
+ @In
+ private TranslationFileService translationFileServiceImpl;
+ @In
+ private VirusScanner virusScanner;
+ @In
+ private DocumentDAO documentDAO;
+ @In
+ private DocumentService documentServiceImpl;
public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm uploadForm)
{
@@ -96,7 +99,7 @@ public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm
if (!uploadForm.getLast())
{
- HDocumentUpload upload = saveUploadPart(id, NULL_LOCALE, uploadForm);
+ HDocumentUpload upload = util.saveUploadPart(id, NULL_LOCALE, uploadForm);
totalChunks = upload.getParts().size();
return Response.status(Status.ACCEPTED)
.entity(new ChunkUploadResponse(upload.getId(), totalChunks, true,
@@ -111,9 +114,9 @@ public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm
}
else
{
- HDocumentUpload upload = saveUploadPart(id, NULL_LOCALE, uploadForm);
+ HDocumentUpload upload = util.saveUploadPart(id, NULL_LOCALE, uploadForm);
totalChunks = upload.getParts().size();
- tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload));
+ tempFile = Optional.of(util.combineToTempFileAndDeleteUploadRecord(upload));
}
if (uploadForm.getFileType().equals(".pot"))
@@ -125,7 +128,7 @@ public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm
{
if (!tempFile.isPresent())
{
- tempFile = Optional.of(persistTempFileFromUpload(uploadForm));
+ tempFile = Optional.of(util.persistTempFileFromUpload(uploadForm));
}
processAdapterFile(tempFile.get(), id, uploadForm);
}
@@ -133,7 +136,7 @@ public Response tryUploadSourceFile(GlobalDocumentId id, DocumentFileUploadForm
{
tempFile.get().delete();
}
- return sourceUploadSuccessResponse(isNewDocument(id), totalChunks);
+ return sourceUploadSuccessResponse(util.isNewDocument(id), totalChunks);
}
catch (ChunkUploadException e)
{
@@ -154,7 +157,7 @@ private void checkSourceUploadPreconditions(GlobalDocumentId id,
{
try
{
- checkUploadPreconditions(id, uploadForm);
+ util.checkUploadPreconditions(id, uploadForm);
checkSourceUploadAllowed(id);
}
catch (AuthorizationException e)
@@ -293,7 +296,7 @@ private void parsePotFile(InputStream potStream, GlobalDocumentId id, DocumentFi
private boolean useOfflinePo(GlobalDocumentId id)
{
- return !isNewDocument(id)
+ return !util.isNewDocument(id)
&& !translationFileServiceImpl.isPoDocument(id.getProjectSlug(), id.getVersionSlug(), id.getDocId());
}
diff --git a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
index 83d890c7ef..a1912e8ee2 100644
--- a/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
+++ b/zanata-war/src/main/java/org/zanata/file/TranslationDocumentUpload.java
@@ -20,6 +20,9 @@
*/
package org.zanata.file;
+import static org.zanata.file.DocumentUploadUtil.getInputStream;
+import static org.zanata.file.DocumentUploadUtil.isSinglePart;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
@@ -32,13 +35,13 @@
import lombok.extern.slf4j.Slf4j;
-import org.hibernate.Session;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Name;
import org.jboss.seam.security.AuthorizationException;
import org.zanata.common.DocumentType;
import org.zanata.common.EntityStatus;
import org.zanata.common.LocaleId;
import org.zanata.common.MergeType;
-import org.zanata.dao.DocumentDAO;
import org.zanata.dao.LocaleDAO;
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.exception.ChunkUploadException;
@@ -50,41 +53,29 @@
import org.zanata.rest.dto.ChunkUploadResponse;
import org.zanata.rest.dto.extensions.ExtensionType;
import org.zanata.rest.dto.resource.TranslationsResource;
-import org.zanata.rest.service.VirusScanner;
import org.zanata.security.ZanataIdentity;
-import org.zanata.service.DocumentService;
import org.zanata.service.TranslationFileService;
import org.zanata.service.TranslationService;
import com.google.common.base.Optional;
@Slf4j
-public class TranslationDocumentUpload extends DocumentUpload
+@Name("translationDocumentUploader")
+public class TranslationDocumentUpload
{
- private final LocaleDAO localeDAO;
- private final TranslationService translationServiceImpl;
-
- public TranslationDocumentUpload(ZanataIdentity identity,
- Session session,
- DocumentDAO documentDAO,
- ProjectIterationDAO projectIterationDAO,
- DocumentService documentServiceImpl,
- VirusScanner virusScanner,
- TranslationFileService translationFileServiceImpl,
- LocaleDAO localeDAO,
- TranslationService translationServiceImpl)
- {
- super(identity,
- session,
- documentDAO,
- projectIterationDAO,
- documentServiceImpl,
- virusScanner,
- translationFileServiceImpl);
- this.localeDAO = localeDAO;
- this.translationServiceImpl = translationServiceImpl;
- }
+ @In(create = true, value = "documentUploadUtil")
+ private DocumentUploadUtil util;
+ @In
+ private ZanataIdentity identity;
+ @In
+ private LocaleDAO localeDAO;
+ @In
+ private ProjectIterationDAO projectIterationDAO;
+ @In
+ private TranslationService translationServiceImpl;
+ @In
+ private TranslationFileService translationFileServiceImpl;
public Response tryUploadTranslationFile(GlobalDocumentId id,
String localeId, String mergeType, DocumentFileUploadForm uploadForm)
@@ -106,7 +97,7 @@ public Response tryUploadTranslationFile(GlobalDocumentId id,
}
else
{
- HDocumentUpload upload = saveUploadPart(id, locale, uploadForm);
+ HDocumentUpload upload = util.saveUploadPart(id, locale, uploadForm);
totalChunks = upload.getParts().size();
if (!uploadForm.getLast())
{
@@ -115,7 +106,7 @@ public Response tryUploadTranslationFile(GlobalDocumentId id,
"Chunk accepted, awaiting remaining chunks."))
.build();
}
- tempFile = Optional.of(combineToTempFileAndDeleteUploadRecord(upload));
+ tempFile = Optional.of(util.combineToTempFileAndDeleteUploadRecord(upload));
}
TranslationsResource transRes;
@@ -129,7 +120,7 @@ public Response tryUploadTranslationFile(GlobalDocumentId id,
{
if (!tempFile.isPresent())
{
- tempFile = Optional.of(persistTempFileFromUpload(uploadForm));
+ tempFile = Optional.of(util.persistTempFileFromUpload(uploadForm));
}
// FIXME this is misusing the 'filename' field. the method should probably take a
// type anyway
@@ -171,7 +162,7 @@ public Response tryUploadTranslationFile(GlobalDocumentId id,
private void checkTranslationUploadPreconditions(GlobalDocumentId id, String localeId,
DocumentFileUploadForm uploadForm)
{
- checkUploadPreconditions(id, uploadForm);
+ util.checkUploadPreconditions(id, uploadForm);
// TODO check translation upload allowed
@@ -181,7 +172,7 @@ private void checkTranslationUploadPreconditions(GlobalDocumentId id, String loc
private void checkDocumentExists(GlobalDocumentId id, DocumentFileUploadForm uploadForm)
{
- if (isNewDocument(id))
+ if (util.isNewDocument(id))
{
throw new ChunkUploadException(Status.NOT_FOUND,
"No document with id \"" + id.getDocId() + "\" exists in project-version \"" +
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index fce260ec60..bcadedce82 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -48,7 +48,6 @@
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.StreamingOutput;
-import org.hibernate.Session;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
@@ -57,8 +56,6 @@
import org.zanata.common.ContentState;
import org.zanata.common.LocaleId;
import org.zanata.dao.DocumentDAO;
-import org.zanata.dao.LocaleDAO;
-import org.zanata.dao.ProjectIterationDAO;
import org.zanata.file.GlobalDocumentId;
import org.zanata.file.SourceDocumentUpload;
import org.zanata.file.TranslationDocumentUpload;
@@ -68,16 +65,12 @@
import org.zanata.rest.dto.resource.Resource;
import org.zanata.rest.dto.resource.TextFlowTarget;
import org.zanata.rest.dto.resource.TranslationsResource;
-import org.zanata.security.ZanataIdentity;
-import org.zanata.service.DocumentService;
import org.zanata.service.FileSystemService;
import org.zanata.service.FileSystemService.DownloadDescriptorProperties;
import org.zanata.service.TranslationFileService;
-import org.zanata.service.TranslationService;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
-
import com.google.common.io.ByteStreams;
@Name("fileService")
@@ -89,30 +82,15 @@ public class FileService implements FileResource
private static final String FILE_TYPE_OFFLINE_PO = "offlinepo";
private static final String FILE_TYPE_OFFLINE_PO_TEMPLATE = "offlinepot";
- @In
- private ZanataIdentity identity;
-
- @In
- private LocaleDAO localeDAO;
-
@In
private DocumentDAO documentDAO;
- @In
- private DocumentService documentServiceImpl;
-
- @In
- private ProjectIterationDAO projectIterationDAO;
-
@In(create=true)
private TranslatedDocResourceService translatedDocResourceService;
@In
private FileSystemService fileSystemServiceImpl;
- @In
- private TranslationService translationServiceImpl;
-
@In
private TranslationFileService translationFileServiceImpl;
@@ -122,9 +100,11 @@ public class FileService implements FileResource
@In
private VirusScanner virusScanner;
- // FIXME remove when using DAO for HDocumentUpload
- @In
- private Session session;
+ @In(value = "sourceDocumentUploader", create = true)
+ private SourceDocumentUpload sourceUploader;
+
+ @In(value = "translationDocumentUploader", create = true)
+ private TranslationDocumentUpload translationUploader;
@Override
@GET
@@ -149,13 +129,9 @@ public Response uploadSourceFile( @PathParam("projectSlug") String projectSlug,
@MultipartForm DocumentFileUploadForm uploadForm )
{
GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
-
- SourceDocumentUpload uploader = new SourceDocumentUpload(identity, session, documentDAO, projectIterationDAO,
- documentServiceImpl, virusScanner, translationFileServiceImpl);
- return uploader.tryUploadSourceFile(id, uploadForm);
+ return sourceUploader.tryUploadSourceFile(id, uploadForm);
}
- // TODO this shares a lot of logic with .tryUploadSourceFile(), try to unify.
@Override
@POST
@Path(TRANSLATION_UPLOAD_TEMPLATE)
@@ -169,11 +145,7 @@ public Response uploadTranslationFile( @PathParam("projectSlug") String projectS
@MultipartForm DocumentFileUploadForm uploadForm )
{
GlobalDocumentId id = new GlobalDocumentId(projectSlug, iterationSlug, docId);
-
- TranslationDocumentUpload uploader = new TranslationDocumentUpload(identity, session, documentDAO, projectIterationDAO,
- documentServiceImpl, virusScanner, translationFileServiceImpl, localeDAO, translationServiceImpl);
-
- return uploader.tryUploadTranslationFile(id, localeId, merge, uploadForm);
+ return translationUploader.tryUploadTranslationFile(id, localeId, merge, uploadForm);
}
/**
diff --git a/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java b/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java
index e47eaf1800..293a6728b7 100644
--- a/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java
+++ b/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java
@@ -53,7 +53,7 @@ protected void prepareDBUnitOperations()
addBeforeTestOperation(new DataSetOperation("org/zanata/test/model/LocalesData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
addBeforeTestOperation(new DataSetOperation("org/zanata/test/model/TextFlowTestData.dbunit.xml", DatabaseOperation.CLEAN_INSERT));
}
-
+
@Test
@RunAsClient
public void getPo() throws Exception
@@ -69,6 +69,8 @@ protected void prepareRequest(ClientRequest request)
@Override
protected void onResponse(ClientResponse response)
{
+ System.out.println("getPo() response object");
+ printResponse(response);
assertThat(response.getStatus(), is(200)); // Ok
assertHeaderValue(response, "Content-Disposition", "attachment; filename=\"document.txt.po\"");
assertHeaderValue(response, HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);
@@ -78,7 +80,7 @@ protected void onResponse(ClientResponse response)
}
}.run();
}
-
+
@Test
@RunAsClient
public void getPo2() throws Exception
@@ -94,6 +96,8 @@ protected void prepareRequest(ClientRequest request)
@Override
protected void onResponse(ClientResponse response)
{
+ System.out.println("getPo2() response object");
+ printResponse(response);
assertThat(response.getStatus(), is(200)); // Ok
assertHeaderValue(response, "Content-Disposition", "attachment; filename=\"document-2.txt.po\"");
assertHeaderValue(response, HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);
@@ -105,15 +109,21 @@ protected void onResponse(ClientResponse response)
}
}.run();
}
-
+
+ private static void printResponse(ClientResponse response)
+ {
+ System.out.println("Status: " + response.getStatus());
+ System.out.println("Entity: " + (String) response.getEntity(String.class));
+ }
+
private static void assertPoFileCorrect( String poFileContents )
{
MessageStreamParser messageParser = new MessageStreamParser( new StringReader(poFileContents) );
-
+
while (messageParser.hasNext())
{
Message message = messageParser.next();
-
+
if( message.isHeader() )
{
// assert that expected headers are present (with values if needed)
@@ -128,7 +138,7 @@ private static void assertPoFileCorrect( String poFileContents )
}
}
}
-
+
/**
* Validates that the po files contains the appropriate translations.
* @param poFileContents The contents of the PO file as a string
@@ -140,16 +150,17 @@ private static void assertPoFileContainsTranslations( String poFileContents, Str
{
throw new AssertionError("Translation parameters should be given in pairs.");
}
-
+
MessageStreamParser messageParser = new MessageStreamParser( new StringReader(poFileContents) );
-
+
List found = new ArrayList( translations.length );
-
+
+ // FIXME extract method instead of adding comment
// Assert that all the given translations are present
while (messageParser.hasNext())
{
Message message = messageParser.next();
-
+
if( !message.isHeader() )
{
// Find the message id in the array given to check
@@ -173,7 +184,7 @@ private static void assertPoFileContainsTranslations( String poFileContents, Str
}
}
}
-
+
// If there are some messages not found
if( found.size() < translations.length / 2 )
{
@@ -185,7 +196,7 @@ private static void assertPoFileContainsTranslations( String poFileContents, Str
assertionError.append( translations[i]+" | " );
}
}
-
+
throw new AssertionError( assertionError.toString() );
}
}
From efcdf5c950319d414456168db4750deed3a2c6c7 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Thu, 18 Jul 2013 12:45:26 +1000
Subject: [PATCH 148/184] remove unnecessary warning suppression
---
.../src/main/java/org/zanata/rest/service/FileService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
index bcadedce82..a8e34c4315 100644
--- a/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
+++ b/zanata-war/src/main/java/org/zanata/rest/service/FileService.java
@@ -492,7 +492,7 @@ public FileStreamingOutput( File file )
}
@Override
- public void write(@SuppressWarnings("null") @Nonnull OutputStream output) throws IOException, WebApplicationException
+ public void write(@Nonnull OutputStream output) throws IOException, WebApplicationException
{
FileInputStream input = new FileInputStream(this.file);
try
From d20f7044d86d80241f4ee716130ce731dd5942ba Mon Sep 17 00:00:00 2001
From: David Mason
Date: Thu, 18 Jul 2013 12:50:08 +1000
Subject: [PATCH 149/184] remove extra logging that was accidentally checked in
---
.../org/zanata/rest/service/raw/FileRawRestITCase.java | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java b/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java
index 293a6728b7..07053504b8 100644
--- a/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java
+++ b/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java
@@ -69,8 +69,6 @@ protected void prepareRequest(ClientRequest request)
@Override
protected void onResponse(ClientResponse response)
{
- System.out.println("getPo() response object");
- printResponse(response);
assertThat(response.getStatus(), is(200)); // Ok
assertHeaderValue(response, "Content-Disposition", "attachment; filename=\"document.txt.po\"");
assertHeaderValue(response, HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);
@@ -96,8 +94,6 @@ protected void prepareRequest(ClientRequest request)
@Override
protected void onResponse(ClientResponse response)
{
- System.out.println("getPo2() response object");
- printResponse(response);
assertThat(response.getStatus(), is(200)); // Ok
assertHeaderValue(response, "Content-Disposition", "attachment; filename=\"document-2.txt.po\"");
assertHeaderValue(response, HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);
@@ -110,12 +106,6 @@ protected void onResponse(ClientResponse response)
}.run();
}
- private static void printResponse(ClientResponse response)
- {
- System.out.println("Status: " + response.getStatus());
- System.out.println("Entity: " + (String) response.getEntity(String.class));
- }
-
private static void assertPoFileCorrect( String poFileContents )
{
MessageStreamParser messageParser = new MessageStreamParser( new StringReader(poFileContents) );
From 720a687f412b65bd60ba50d0d3c1754648959538 Mon Sep 17 00:00:00 2001
From: David Mason
Date: Thu, 18 Jul 2013 12:54:30 +1000
Subject: [PATCH 150/184] remove excessive comment
---
.../test/java/org/zanata/rest/service/raw/FileRawRestITCase.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java b/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java
index 07053504b8..15a9b5ba70 100644
--- a/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java
+++ b/zanata-war/src/test/java/org/zanata/rest/service/raw/FileRawRestITCase.java
@@ -145,7 +145,6 @@ private static void assertPoFileContainsTranslations( String poFileContents, Str
List found = new ArrayList( translations.length );
- // FIXME extract method instead of adding comment
// Assert that all the given translations are present
while (messageParser.hasNext())
{
From bc8876888199f5fbdb4932c175b81cb8fefcbd3e Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Thu, 18 Jul 2013 13:10:14 +1000
Subject: [PATCH 151/184] Implement fix for bug:
https://bugzilla.redhat.com/show_bug.cgi?id=983782
---
.../client/service/NavigationService.java | 4 +-
.../server/rpc/GetTransUnitListHandler.java | 36 ++++---
.../shared/rpc/GetTransUnitListResult.java | 2 +-
.../TranslationEditorPresenterTest.java | 27 ++----
.../rpc/GetTransUnitListHandlerTest.java | 96 +++++++++++++------
5 files changed, 101 insertions(+), 64 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/service/NavigationService.java b/zanata-war/src/main/java/org/zanata/webtrans/client/service/NavigationService.java
index 0a872a0128..3fb1e71aaa 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/service/NavigationService.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/service/NavigationService.java
@@ -144,7 +144,7 @@ public void onSuccess(GetTransUnitListResult result)
navigationStateHolder.init(result.getNavigationIndex().getTransIdStateList(), result.getNavigationIndex().getIdIndexList());
eventBus.fireEvent(new PageCountChangeEvent(navigationStateHolder.getPageCount()));
}
- navigationStateHolder.updateCurrentPage(result.getTargetPage());
+ navigationStateHolder.updateCurrentPage(result.getTargetPageIndex());
if (!units.isEmpty())
{
@@ -153,7 +153,7 @@ public void onSuccess(GetTransUnitListResult result)
// in case there is pending save (as fuzzy) happening, we do not want to trigger another pending save
eventBus.fireEvent(new TableRowSelectedEvent(selectedId).setSuppressSavePending(true));
}
- eventBus.fireEvent(new PageChangeEvent(result.getTargetPage()));
+ eventBus.fireEvent(new PageChangeEvent(result.getTargetPageIndex()));
highlightSearch();
// run validation on TransUnit and display error message
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 5599aae95e..82e151fe7f 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
@@ -83,7 +83,7 @@ public GetTransUnitListResult execute(GetTransUnitList action, ExecutionContext
log.info("action: {}", action);
int targetOffset = action.getOffset();
- int targetPage = action.getOffset() / action.getCount();
+ int targetPageIndex = targetOffset / action.getCount();
GetTransUnitsNavigationResult navigationResult = null;
if (action.isNeedReloadIndex())
{
@@ -91,27 +91,34 @@ public GetTransUnitListResult execute(GetTransUnitList action, ExecutionContext
log.debug("get trans unit navigation action: {}", getTransUnitsNavigation);
navigationResult = getTransUnitsNavigationService.getNavigationIndexes(getTransUnitsNavigation, hLocale);
- int totalPageNumber = navigationResult.getIdIndexList().size() / action.getCount();
- if (targetPage > totalPageNumber)
+ int totalPageIndex = getTotalPageIndex(navigationResult.getIdIndexList().size(), action.getCount());
+
+ if (targetPageIndex > totalPageIndex)
{
- targetPage = totalPageNumber;
- targetOffset = action.getCount() * targetPage;
+ targetPageIndex = totalPageIndex;
+ targetOffset = action.getCount() * targetPageIndex;
}
-
+
if (action.getTargetTransUnitId() != null)
{
int targetIndexInDoc = navigationResult.getIdIndexList().indexOf(action.getTargetTransUnitId());
- targetPage = targetIndexInDoc / action.getCount();
- targetOffset = action.getCount() * targetPage;
+ targetPageIndex = targetIndexInDoc / action.getCount();
+ targetOffset = action.getCount() * targetPageIndex;
}
}
List textFlows = getTextFlows(action, hLocale, targetOffset);
-
- GetTransUnitListResult result = transformToTransUnits(action, hLocale, textFlows, targetOffset, targetPage);
+
+ GetTransUnitListResult result = transformToTransUnits(action, hLocale, textFlows, targetOffset, targetPageIndex);
result.setNavigationIndex(navigationResult);
return result;
}
+
+ private int getTotalPageIndex(int indexListSize, int countPerPage)
+ {
+ int totalPageNumber = (int)Math.ceil((float)indexListSize / countPerPage);
+ return totalPageNumber > 0 ? totalPageNumber - 1 : totalPageNumber;
+ }
private List getTextFlows(GetTransUnitList action, HLocale hLocale, int offset)
{
@@ -121,12 +128,14 @@ 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)
+ // TODO debt: this should use a left join to fetch target (and
+ // possibly comments)
textFlows = textFlowDAO.getTextFlowsByDocumentId(action.getDocumentId(), offset, action.getCount());
}
else
{
- // TODO debt: this is not scalable. But we may not have other choice for validation filter. Maybe use scrollable result will help?
+ // 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());
}
@@ -191,7 +200,8 @@ private GetTransUnitListResult transformToTransUnits(GetTransUnitList action, HL
gotoRow = row;
}
}
- // stupid GWT RPC can't handle com.google.common.collect.Lists$TransformingRandomAccessList
+ // stupid GWT RPC can't handle
+ // com.google.common.collect.Lists$TransformingRandomAccessList
return new GetTransUnitListResult(action.getDocumentId(), Lists.newArrayList(units), gotoRow, targetOffset, targetPage);
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitListResult.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitListResult.java
index 049e689217..f303ecf28b 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitListResult.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTransUnitListResult.java
@@ -53,7 +53,7 @@ public int getTargetOffset()
return targetOffset;
}
- public int getTargetPage()
+ public int getTargetPageIndex()
{
return targetPage;
}
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TranslationEditorPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TranslationEditorPresenterTest.java
index 470d9ef3a8..dd52a2247f 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TranslationEditorPresenterTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/TranslationEditorPresenterTest.java
@@ -5,9 +5,7 @@
import static org.mockito.Mockito.when;
import net.customware.gwt.presenter.client.EventBus;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -21,9 +19,6 @@
import org.zanata.webtrans.client.view.TransUnitsTableDisplay;
import org.zanata.webtrans.client.view.TranslationEditorDisplay;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
-
/**
* @author Patrick Huang pahuang@redhat.com
*/
@@ -85,21 +80,6 @@ public void onBind()
verify(eventBus).addHandler(PageChangeEvent.TYPE, presenter);
verify(eventBus).addHandler(PageChangeEvent.TYPE, presenter);
-
- // test page navigation value change handler
- ArgumentCaptor pageValueChangeHandlerCaptor = ArgumentCaptor.forClass(ValueChangeHandler.class);
- verify(pageNavigation).addValueChangeHandler(pageValueChangeHandlerCaptor.capture());
- ValueChangeHandler valueChangeHandler = pageValueChangeHandlerCaptor.getValue();
- valueChangeHandler.onValueChange(createMockEventWithValue(1));
- verify(transUnitsTablePresenter).goToPage(1);
- }
-
- private static ValueChangeEvent createMockEventWithValue(int value)
- {
- @SuppressWarnings("unchecked")
- ValueChangeEvent valueChangeEvent = Mockito.mock(ValueChangeEvent.class);
- when(valueChangeEvent.getValue()).thenReturn(value);
- return valueChangeEvent;
}
@Test
@@ -118,6 +98,13 @@ public void testOnPageCountChange() throws Exception
verify(pageNavigation).setPageCount(99);
}
+
+ @Test
+ public void testOnPagerValueChanged()
+ {
+ presenter.onPagerValueChanged(100);
+ verify(transUnitsTablePresenter).goToPage(100);
+ }
@Test
public void testIsTransFilterFocused() throws Exception
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandlerTest.java b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandlerTest.java
index 47fce653d5..338e31567a 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandlerTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandlerTest.java
@@ -2,6 +2,12 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Matchers.isA;
+
+import java.util.ArrayList;
+import java.util.List;
+
import lombok.extern.slf4j.Slf4j;
import org.dbunit.operation.DatabaseOperation;
@@ -18,29 +24,28 @@
import org.zanata.dao.DocumentDAO;
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.dao.TextFlowDAO;
-import org.zanata.model.HDocument;
import org.zanata.model.HLocale;
import org.zanata.model.TestFixture;
import org.zanata.rest.service.ResourceUtils;
import org.zanata.seam.SeamAutowire;
import org.zanata.security.ZanataIdentity;
import org.zanata.service.LocaleService;
-import org.zanata.service.TextFlowSearchService;
-import org.zanata.service.ValidationService;
import org.zanata.service.impl.TextFlowSearchServiceImpl;
import org.zanata.service.impl.TranslationStateCacheImpl;
import org.zanata.service.impl.ValidationServiceImpl;
-import org.zanata.util.ZanataMessages;
import org.zanata.webtrans.client.service.GetTransUnitActionContext;
import org.zanata.webtrans.shared.auth.EditorClientId;
-import org.zanata.webtrans.shared.model.DocumentId;
import org.zanata.webtrans.shared.model.DocumentInfo;
import org.zanata.webtrans.shared.model.ProjectIterationId;
+import org.zanata.webtrans.shared.model.TransUnitId;
import org.zanata.webtrans.shared.rpc.GetTransUnitList;
import org.zanata.webtrans.shared.rpc.GetTransUnitListResult;
+import org.zanata.webtrans.shared.rpc.GetTransUnitsNavigation;
+import org.zanata.webtrans.shared.rpc.GetTransUnitsNavigationResult;
/**
- * @author Patrick Huang pahuang@redhat.com
+ * @author Patrick Huang pahuang@redhat.com
*/
@Test(groups = { "jpa-tests" })
@Slf4j
@@ -51,6 +56,9 @@ public class GetTransUnitListHandlerTest extends ZanataDbunitJpaTest
private ZanataIdentity identity;
@Mock
private LocaleService localeService;
+ @Mock
+ private GetTransUnitsNavigationService getTransUnitsNavigationService;
+
private final DocumentInfo document = TestFixture.documentInfo(1L, "");
private final LocaleId localeId = new LocaleId("ja");
private HLocale jaHLocale;
@@ -66,23 +74,10 @@ public void setUp() throws Exception
{
MockitoAnnotations.initMocks(this);
ResourceUtils resourceUtils = new ResourceUtils();
- resourceUtils.create(); //postConstruct
+ resourceUtils.create(); // postConstruct
TransUnitTransformer transUnitTransformer = SeamAutowire.instance().use("resourceUtils", resourceUtils).autowire(TransUnitTransformer.class);
- SeamAutowire seam = SeamAutowire.instance()
- .use("localeServiceImpl", localeService)
- .use("documentDAO", new DocumentDAO(getSession()))
- .use("projectIterationDAO", new ProjectIterationDAO(getSession()))
- .use("entityManager", new FullTextEntityManagerImpl(getEm()))
- .use("session", new FullTextSessionImpl(getSession()))
- .use("identity", identity)
- .use("localeServiceImpl", localeService)
- .use("textFlowDAO", new TextFlowDAO(getSession()))
- .use("transUnitTransformer", transUnitTransformer)
- .useImpl(TranslationStateCacheImpl.class)
- .useImpl(TextFlowSearchServiceImpl.class)
- .useImpl(ValidationServiceImpl.class)
- .allowCycles();
+ SeamAutowire seam = SeamAutowire.instance().use("localeServiceImpl", localeService).use("documentDAO", new DocumentDAO(getSession())).use("projectIterationDAO", new ProjectIterationDAO(getSession())).use("entityManager", new FullTextEntityManagerImpl(getEm())).use("session", new FullTextSessionImpl(getSession())).use("identity", identity).use("textFlowDAO", new TextFlowDAO(getSession())).use("transUnitTransformer", transUnitTransformer).use("webtrans.gwt.GetTransUnitsNavigationHandler", getTransUnitsNavigationService).useImpl(TranslationStateCacheImpl.class).useImpl(TextFlowSearchServiceImpl.class).useImpl(ValidationServiceImpl.class).allowCycles();
// @formatter:off
handler = seam.autowire(GetTransUnitListHandler.class);
@@ -144,11 +139,11 @@ public void testExecuteWithHasErrorFilterOnly() throws Exception
assertThat(TestFixture.asIds(result.getUnits()), Matchers.contains(1, 2, 3, 4, 5));
}
-
@Test
public void testExecuteWithSearchOnly() throws Exception
{
- // Given: we want to search for file (mixed case) and we change page size to 10 and start from index 2
+ // Given: we want to search for file (mixed case) and we change page size
+ // to 10 and start from index 2
GetTransUnitList action = GetTransUnitList.newAction(new GetTransUnitActionContext(document).changeFindMessage("FiLe").changeCount(10).changeOffset(1));
prepareActionAndMockLocaleService(action);
@@ -165,9 +160,9 @@ public void testExecuteWithSearchOnly() throws Exception
@Test
public void testExecuteWithSearchAndStatusFilter() throws Exception
{
- // Given: we want to search for file (mixed case) in fuzzy and untranslated text flows
- GetTransUnitList action = GetTransUnitList.newAction(new GetTransUnitActionContext(document)
- .changeFindMessage("FiLe").changeFilterUntranslated(true).changeFilterFuzzy(true));
+ // Given: we want to search for file (mixed case) in fuzzy and
+ // untranslated text flows
+ GetTransUnitList action = GetTransUnitList.newAction(new GetTransUnitActionContext(document).changeFindMessage("FiLe").changeFilterUntranslated(true).changeFilterFuzzy(true));
prepareActionAndMockLocaleService(action);
// When:
@@ -196,10 +191,55 @@ public void testExecuteWithSearchAndStatusFilter2() throws Exception
assertThat(TestFixture.asIds(result.getUnits()), Matchers.contains(3, 5, 6, 8));
}
+ @Test
+ public void testExecuteWithPageSize() throws Exception
+ {
+ /**
+ * Client request for page 4 data
+ */
+ int offset = 76;
+ int countPerPage = 25;
+
+ GetTransUnitList action = GetTransUnitList.newAction(new GetTransUnitActionContext(document).changeFindMessage("FiLe").changeFilterUntranslated(true).changeFilterFuzzy(true).changeFilterHasError(true).changeOffset(offset).changeCount(countPerPage));
+
+ prepareActionAndMockLocaleService(action);
+
+ // When:
+ GetTransUnitListResult result = handler.execute(action, null);
+
+ assertThat(result.getTargetPageIndex(), Matchers.equalTo(3));
+ }
@Test
- public void selectDocument()
+ public void testExecuteWithPageSizeNeedReload() throws Exception
{
- HDocument hDocument = getEm().find(HDocument.class, 1L);
+ /**
+ * Client request for page 4 data -
+ * Offset:75
+ * Count per page: 25
+ * Assuming tft from getTransUnitsNavigationService.getNavigationIndexes = 74
+ */
+ int offset = 75;
+ int countPerPage = 25;
+
+ GetTransUnitsNavigationResult navigationResult = mock(GetTransUnitsNavigationResult.class);
+ List idIndexList = new ArrayList();
+ for (int i = 1; i < offset; i++)
+ {
+ idIndexList.add(new TransUnitId(i));
+ }
+
+ GetTransUnitList action = GetTransUnitList.newAction(new GetTransUnitActionContext(document).changeFindMessage("FiLe").changeFilterUntranslated(true).changeFilterFuzzy(true).changeFilterHasError(true).changeOffset(offset).changeCount(countPerPage));
+ action.setNeedReloadIndex(true);
+
+ prepareActionAndMockLocaleService(action);
+
+ // When:
+ when(getTransUnitsNavigationService.getNavigationIndexes(isA(GetTransUnitsNavigation.class), isA(HLocale.class))).thenReturn(navigationResult);
+ when(navigationResult.getIdIndexList()).thenReturn(idIndexList);
+
+ GetTransUnitListResult result = handler.execute(action, null);
+
+ assertThat(result.getTargetPageIndex(), Matchers.equalTo(2));
}
}
From 5033267dbb871e2008c01332f7176f3ac086b77f Mon Sep 17 00:00:00 2001
From: Alex Eng
Date: Thu, 18 Jul 2013 13:57:47 +1000
Subject: [PATCH 152/184] Refactor code
---
.../org/zanata/webtrans/client/ui/Pager.java | 25 +++++++++++--------
.../rpc/GetTransUnitListHandlerTest.java | 24 ++++++++++++------
2 files changed, 32 insertions(+), 17 deletions(-)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java
index 15e64d09f2..ddee64d111 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/Pager.java
@@ -118,16 +118,7 @@ public void onGotoPageKeyDown(KeyDownEvent event)
{
try
{
- int newValue = Integer.parseInt(gotoPage.getText());
- if (newValue < minPageCount)
- {
- newValue = minPageCount;
- }
- else if(newValue > pageCount)
- {
- newValue = pageCount;
- }
- setValue(newValue);
+ setValue(getCorrectedGotoPage(gotoPage.getText()));
}
catch (NumberFormatException nfe)
{
@@ -135,6 +126,20 @@ else if(newValue > pageCount)
}
}
}
+
+ private int getCorrectedGotoPage(String pageText)
+ {
+ int page = Integer.parseInt(pageText);
+ if (page < minPageCount)
+ {
+ page = minPageCount;
+ }
+ else if(page > pageCount)
+ {
+ page = pageCount;
+ }
+ return page;
+ }
@Override
protected void onLoad()
diff --git a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandlerTest.java b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandlerTest.java
index 338e31567a..757109038c 100644
--- a/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandlerTest.java
+++ b/zanata-war/src/test/java/org/zanata/webtrans/server/rpc/GetTransUnitListHandlerTest.java
@@ -1,9 +1,9 @@
package org.zanata.webtrans.server.rpc;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.mock;
import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
@@ -77,7 +77,19 @@ public void setUp() throws Exception
resourceUtils.create(); // postConstruct
TransUnitTransformer transUnitTransformer = SeamAutowire.instance().use("resourceUtils", resourceUtils).autowire(TransUnitTransformer.class);
- SeamAutowire seam = SeamAutowire.instance().use("localeServiceImpl", localeService).use("documentDAO", new DocumentDAO(getSession())).use("projectIterationDAO", new ProjectIterationDAO(getSession())).use("entityManager", new FullTextEntityManagerImpl(getEm())).use("session", new FullTextSessionImpl(getSession())).use("identity", identity).use("textFlowDAO", new TextFlowDAO(getSession())).use("transUnitTransformer", transUnitTransformer).use("webtrans.gwt.GetTransUnitsNavigationHandler", getTransUnitsNavigationService).useImpl(TranslationStateCacheImpl.class).useImpl(TextFlowSearchServiceImpl.class).useImpl(ValidationServiceImpl.class).allowCycles();
+ SeamAutowire seam = SeamAutowire.instance()
+ .use("localeServiceImpl", localeService)
+ .use("documentDAO", new DocumentDAO(getSession()))
+ .use("projectIterationDAO", new ProjectIterationDAO(getSession()))
+ .use("entityManager", new FullTextEntityManagerImpl(getEm()))
+ .use("session", new FullTextSessionImpl(getSession()))
+ .use("identity", identity).use("textFlowDAO", new TextFlowDAO(getSession()))
+ .use("transUnitTransformer", transUnitTransformer)
+ .use("webtrans.gwt.GetTransUnitsNavigationHandler", getTransUnitsNavigationService)
+ .useImpl(TranslationStateCacheImpl.class)
+ .useImpl(TextFlowSearchServiceImpl.class)
+ .useImpl(ValidationServiceImpl.class)
+ .allowCycles();
// @formatter:off
handler = seam.autowire(GetTransUnitListHandler.class);
@@ -214,10 +226,8 @@ public void testExecuteWithPageSize() throws Exception
public void testExecuteWithPageSizeNeedReload() throws Exception
{
/**
- * Client request for page 4 data -
- * Offset:75
- * Count per page: 25
- * Assuming tft from getTransUnitsNavigationService.getNavigationIndexes = 74
+ * Client request for page 4 data - Offset:75 Count per page: 25 Assuming
+ * tft from getTransUnitsNavigationService.getNavigationIndexes = 74
*/
int offset = 75;
int countPerPage = 25;
From 0c820b4700f0793b3b77612162c24e7d4be13174 Mon Sep 17 00:00:00 2001
From: Patrick Huang
Date: Wed, 10 Jul 2013 11:30:23 +1000
Subject: [PATCH 153/184] rhbz978666 - prove of concept works
---
.../presenter/TransUnitsTablePresenter.java | 3 +-
.../TranslationHistoryPresenter.java | 97 +-
.../webtrans/client/ui/ListItemWidget.java | 52 +
.../client/ui/ReviewCommentItemLine.java | 71 +
.../client/ui/ReviewCommentItemLine.ui.xml | 32 +
.../client/ui/TransHistoryItemLine.java | 103 +
.../client/ui/TransHistoryItemLine.ui.xml | 48 +
.../client/ui/TranslationHistoryDisplay.java | 12 +
.../client/ui/TranslationHistoryView.java | 68 +-
.../client/ui/TranslationHistoryView.ui.xml | 9 +-
.../client/ui/UnorderedListWidget.java | 50 +
.../rpc/GetTranslationHistoryHandler.java | 37 +-
.../shared/model/ComparableByDate.java | 38 +
.../webtrans/shared/model/ReviewComment.java | 38 +-
.../shared/model/TransHistoryItem.java | 8 +-
.../rpc/GetTranslationHistoryResult.java | 13 +-
.../zanata/webtrans/public/Application.xhtml | 1 +
.../org/zanata/webtrans/public/style.css | 3900 +++++++++++++++++
.../TransUnitsTablePresenterTest.java | 6 +-
.../TranslationHistoryPresenterTest.java | 3 +-
20 files changed, 4474 insertions(+), 115 deletions(-)
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/ui/ListItemWidget.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/ui/ReviewCommentItemLine.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/ui/ReviewCommentItemLine.ui.xml
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/ui/TransHistoryItemLine.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/ui/TransHistoryItemLine.ui.xml
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/ui/UnorderedListWidget.java
create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/model/ComparableByDate.java
create mode 100644 zanata-war/src/main/resources/org/zanata/webtrans/public/style.css
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 4b9cc3f460..fe06f865d2 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
@@ -53,6 +53,7 @@
import org.zanata.webtrans.client.view.TargetContentsDisplay;
import org.zanata.webtrans.client.view.TransUnitsTableDisplay;
import org.zanata.webtrans.shared.auth.EditorClientId;
+import org.zanata.webtrans.shared.model.ReviewComment;
import org.zanata.webtrans.shared.model.TransHistoryItem;
import org.zanata.webtrans.shared.model.TransUnit;
import org.zanata.webtrans.shared.model.TransUnitId;
@@ -286,7 +287,7 @@ public void refreshRow(TransUnit updatedTransUnit, EditorClientId editorClientId
{
translationHistoryPresenter.popupAndShowLoading(messages.concurrentEditTitle());
TransHistoryItem latest = new TransHistoryItem(updatedTransUnit.getVerNum().toString(), updatedTransUnit.getTargets(), updatedTransUnit.getStatus(), updatedTransUnit.getLastModifiedBy(), updatedTransUnit.getLastModifiedTime());
- translationHistoryPresenter.displayEntries(latest, Collections. emptyList());
+ translationHistoryPresenter.displayEntries(latest, Collections. emptyList(), Collections.emptyList());
}
}
if (updateType == TransUnitUpdated.UpdateType.AddComment)
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationHistoryPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationHistoryPresenter.java
index 63bdcabd39..3d03175c9a 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationHistoryPresenter.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/TranslationHistoryPresenter.java
@@ -1,5 +1,6 @@
package org.zanata.webtrans.client.presenter;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
@@ -14,6 +15,8 @@
import org.zanata.webtrans.client.resources.WebTransMessages;
import org.zanata.webtrans.client.rpc.CachingDispatchAsync;
import org.zanata.webtrans.client.ui.TranslationHistoryDisplay;
+import org.zanata.webtrans.shared.model.ComparableByDate;
+import org.zanata.webtrans.shared.model.ReviewComment;
import org.zanata.webtrans.shared.model.TransHistoryItem;
import org.zanata.webtrans.shared.model.TransUnitId;
import org.zanata.webtrans.shared.rpc.GetTranslationHistoryAction;
@@ -21,6 +24,7 @@
import com.allen_sauer.gwt.log.client.Log;
import com.google.common.base.Objects;
+import com.google.common.collect.Lists;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.view.client.SelectionChangeEvent;
@@ -31,14 +35,14 @@
* @author Patrick Huang pahuang@redhat.com
*/
@Singleton
-public class TranslationHistoryPresenter extends WidgetPresenter implements SelectionChangeEvent.Handler
+public class TranslationHistoryPresenter extends WidgetPresenter implements SelectionChangeEvent.Handler, TranslationHistoryDisplay.Listener
{
private final TranslationHistoryDisplay display;
private final EventBus eventBus;
private final CachingDispatchAsync dispatcher;
private final WebTransMessages messages;
- private final TransHistoryDataProvider listDataProvider;
- private final TransHistorySelectionModel selectionModel;
+// private final TransHistoryDataProvider listDataProvider;
+// private final TransHistorySelectionModel selectionModel;
private TargetContentsPresenter targetContentsPresenter;
@Inject
@@ -49,16 +53,18 @@ public TranslationHistoryPresenter(TranslationHistoryDisplay display, EventBus e
this.eventBus = eventBus;
this.dispatcher = dispatcher;
this.messages = messages;
- this.selectionModel = selectionModel;
- listDataProvider = dataProvider;
- this.display.setDataProvider(listDataProvider);
+ display.setListener(this);
+// this.selectionModel = selectionModel;
- ColumnSortEvent.ListHandler sortHandler = new ColumnSortEvent.ListHandler(listDataProvider.getList());
- this.display.addVersionSortHandler(sortHandler);
+// listDataProvider = dataProvider;
+// this.display.setDataProvider(listDataProvider);
- this.selectionModel.addSelectionChangeHandler(this);
- this.display.setSelectionModel(this.selectionModel);
+// ColumnSortEvent.ListHandler sortHandler = new ColumnSortEvent.ListHandler(listDataProvider.getList());
+// this.display.addVersionSortHandler(sortHandler);
+
+// this.selectionModel.addSelectionChangeHandler(this);
+// this.display.setSelectionModel(this.selectionModel);
}
public void showTranslationHistory(final TransUnitId transUnitId)
@@ -78,7 +84,7 @@ public void onFailure(Throwable caught)
public void onSuccess(GetTranslationHistoryResult result)
{
Log.info("get back " + result.getHistoryItems().size() + " trans history for id:" + transUnitId);
- displayEntries(result.getLatest(), result.getHistoryItems());
+ displayEntries(result.getLatest(), result.getHistoryItems(), result.getReviewComments());
}
});
}
@@ -86,49 +92,54 @@ public void onSuccess(GetTranslationHistoryResult result)
protected void popupAndShowLoading(String title)
{
//here we CANNOT use listDataProvider.setList() because we need to retain the same list reference which is used by ColumnSortEvent.ListHandler
- listDataProvider.getList().clear();
- listDataProvider.setLoading(true);
- selectionModel.clear();
+// listDataProvider.getList().clear();
+// listDataProvider.setLoading(true);
+// selectionModel.clear();
display.setTitle(title);
display.resetView();
display.center();
}
- protected void displayEntries(TransHistoryItem latest, List otherEntries)
+ protected void displayEntries(TransHistoryItem latest, List otherEntries, List reviewComments)
{
- if (latest != null)
- {
- //add indicator for latest version
- latest.setVersionNum(messages.latestVersion(latest.getVersionNum()));
- List newTargets = targetContentsPresenter.getNewTargets();
- if (!Objects.equal(latest.getContents(), newTargets))
- {
- listDataProvider.getList().add(new TransHistoryItem(messages.unsaved(), newTargets, ContentState.New, "", null));
- }
- listDataProvider.getList().add(latest);
- }
- listDataProvider.getList().addAll(otherEntries);
- Comparator reverseComparator = Collections.reverseOrder(TransHistoryVersionComparator.COMPARATOR);
- Collections.sort(listDataProvider.getList(), reverseComparator);
- listDataProvider.setLoading(false);
+ List all = Lists.newArrayList(latest);
+ all.addAll(otherEntries);
+ all.addAll(reviewComments);
+ Collections.sort(all, Collections.reverseOrder());
+ display.setData(all);
+// if (latest != null)
+// {
+// //add indicator for latest version
+// latest.setVersionNum(messages.latestVersion(latest.getVersionNum()));
+// List newTargets = targetContentsPresenter.getNewTargets();
+// if (!Objects.equal(latest.getContents(), newTargets))
+// {
+// listDataProvider.getList().add(new TransHistoryItem(messages.unsaved(), newTargets, ContentState.New, "", null));
+// }
+// listDataProvider.getList().add(latest);
+// }
+// listDataProvider.getList().addAll(otherEntries);
+// Comparator reverseComparator = Collections.reverseOrder(TransHistoryVersionComparator.COMPARATOR);
+// Collections.sort(listDataProvider.getList(), reverseComparator);
+// listDataProvider.setLoading(false);
}
@Override
public void onSelectionChange(SelectionChangeEvent event)
{
- Set historyItems = selectionModel.getSelectedSet();
- if (historyItems.size() == 2)
- {
- //selected two. Compare against each other
- Iterator iterator = historyItems.iterator();
- TransHistoryItem one = iterator.next();
- TransHistoryItem two = iterator.next();
- display.showDiff(one, two, messages.translationHistoryComparison(one.getVersionNum(), two.getVersionNum()));
- }
- else
- {
- display.disableComparison();
- }
+// Set historyItems = selectionModel.getSelectedSet();
+// if (historyItems.size() == 2)
+// {
+// //selected two. Compare against each other
+// Iterator iterator = historyItems.iterator();
+// TransHistoryItem one = iterator.next();
+// TransHistoryItem two = iterator.next();
+// display.showDiff(one, two, messages.translationHistoryComparison(one.getVersionNum(), two.getVersionNum()));
+// }
+// else
+// {
+// display.disableComparison();
+// }
}
@Override
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/ListItemWidget.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/ListItemWidget.java
new file mode 100644
index 0000000000..f81f8736e3
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/ListItemWidget.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.ui;
+
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.user.client.ui.SimplePanel;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * This is the widget to create a <li>.
+ *
+ * @author Patrick Huang pahuang@redhat.com
+ */
+public class ListItemWidget extends SimplePanel
+{
+ public ListItemWidget()
+ {
+ super((Element) Document.get().createLIElement().cast());
+ }
+
+ public ListItemWidget(String text)
+ {
+ this();
+ getElement().setInnerText(text);
+ }
+
+ public ListItemWidget(Widget widget)
+ {
+ this();
+ add(widget);
+ }
+}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/ReviewCommentItemLine.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/ReviewCommentItemLine.java
new file mode 100644
index 0000000000..0d2b904777
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/ReviewCommentItemLine.java
@@ -0,0 +1,71 @@
+/*
+ * 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.ui;
+
+import org.zanata.webtrans.client.util.DateUtil;
+import org.zanata.webtrans.shared.model.ReviewComment;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.safehtml.client.SafeHtmlTemplates;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.InlineHTML;
+
+public class ReviewCommentItemLine extends Composite
+{
+ private static ReviewCommentItemLineUiBinder ourUiBinder = GWT.create(ReviewCommentItemLineUiBinder.class);
+ private static ReviewCommentItemTemplate template = GWT.create(ReviewCommentItemTemplate.class);
+
+ @UiField(provided = true)
+ InlineHTML heading;
+ @UiField(provided = true)
+ InlineHTML commentContent;
+ @UiField(provided = true)
+ InlineHTML commentTime;
+
+ public ReviewCommentItemLine(ReviewComment comment)
+ {
+ heading = new InlineHTML(template.heading(comment.getCommenterName()));
+ commentContent = new InlineHTML(template.content(comment.getComment()));
+ commentTime = new InlineHTML(template.timestamp(DateUtil.formatShortDate(comment.getCreationDate())));
+
+ initWidget(ourUiBinder.createAndBindUi(this));
+ }
+
+ interface ReviewCommentItemLineUiBinder extends UiBinder
+ {
+ }
+
+ interface ReviewCommentItemTemplate extends SafeHtmlTemplates
+ {
+ @Template("{0} left a comment
")
+ SafeHtml heading(String person);
+
+ @Template("{0}
")
+ SafeHtml content(String comment);
+
+ @Template("")
+ SafeHtml timestamp(String commentTime);
+ }
+}
\ No newline at end of file
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/ReviewCommentItemLine.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/ReviewCommentItemLine.ui.xml
new file mode 100644
index 0000000000..6735db19af
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/ReviewCommentItemLine.ui.xml
@@ -0,0 +1,32 @@
+
+
+
+
+ Comment
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TransHistoryItemLine.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TransHistoryItemLine.java
new file mode 100644
index 0000000000..ae902f3dff
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TransHistoryItemLine.java
@@ -0,0 +1,103 @@
+/*
+ * 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.ui;
+
+import org.zanata.common.ContentState;
+import org.zanata.webtrans.client.util.DateUtil;
+import org.zanata.webtrans.shared.model.TransHistoryItem;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.safehtml.client.SafeHtmlTemplates;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.InlineHTML;
+import com.google.gwt.user.client.ui.InlineLabel;
+
+public class TransHistoryItemLine extends Composite
+{
+ private static TransHistoryItemLineUiBinder ourUiBinder = GWT.create(TransHistoryItemLineUiBinder.class);
+ private static TransHistoryItemTemplate template = GWT.create(TransHistoryItemTemplate.class);
+ private final TranslationHistoryDisplay.Listener listener;
+
+ @UiField(provided = true)
+ InlineHTML heading;
+ @UiField(provided = true)
+ InlineHTML targetContents;
+ @UiField
+ InlineLabel creationDate;
+ @UiField(provided = true)
+ InlineHTML revision;
+ @UiField
+ InlineLabel compare;
+ @UiField
+ InlineLabel copyIntoEditor;
+
+ public TransHistoryItemLine(TransHistoryItem item, TranslationHistoryDisplay.Listener listener)
+ {
+ this.listener = listener;
+ heading = new InlineHTML(template.heading(item.getModifiedBy(), stateToStyle(item.getStatus()), item.getStatus().name()));
+ targetContents = new InlineHTML(template.targetContent(TextContentsDisplay.asSyntaxHighlight(item.getContents()).toSafeHtml()));
+ revision = new InlineHTML(template.targetRevision(item.getVersionNum(), ""));
+ initWidget(ourUiBinder.createAndBindUi(this));
+
+ creationDate.setText(DateUtil.formatShortDate(item.getModifiedDate()));
+
+ }
+ // TODO uiHandler for compare and copyIntoEditor
+
+ // TODO pahuang confirm styles
+ private static String stateToStyle(ContentState status)
+ {
+ switch (status)
+ {
+ case New:
+ return "text--status--new";
+ case NeedReview:
+ return "text--status--unsure";
+ case Translated:
+ return "text--status--ok";
+ case Approved:
+ return "text--status--approved";
+ case Rejected:
+ return "text--status--rejected";
+ }
+ return "";
+ }
+
+ interface TransHistoryItemLineUiBinder extends UiBinder
+ {
+ }
+
+ public interface TransHistoryItemTemplate extends SafeHtmlTemplates
+ {
+ @Template("{0}
")
+ SafeHtml targetContent(SafeHtml message);
+
+ @Template("{0} created a {2} revision
")
+ SafeHtml heading(String person, String contentStateStyle, String contentState);
+
+ @Template("Revision {0} {1} ")
+ SafeHtml targetRevision(String versionNum, String optionalLabel);
+ }
+}
\ No newline at end of file
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TransHistoryItemLine.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TransHistoryItemLine.ui.xml
new file mode 100644
index 0000000000..e40850dfb2
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TransHistoryItemLine.ui.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+ Translation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryDisplay.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryDisplay.java
index ad89f587e6..0a551a3b85 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryDisplay.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryDisplay.java
@@ -1,5 +1,8 @@
package org.zanata.webtrans.client.ui;
+import java.util.List;
+
+import org.zanata.webtrans.shared.model.ComparableByDate;
import org.zanata.webtrans.shared.model.TransHistoryItem;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.view.client.ListDataProvider;
@@ -38,4 +41,13 @@ public Object getKey(TransHistoryItem item)
void setDataProvider(ListDataProvider dataProvider);
void setTitle(String title);
+
+ void setListener(Listener listener);
+
+ void setData(List items);
+
+ interface Listener
+ {
+
+ }
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryView.java
index 6a54101071..dc76f0da91 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryView.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryView.java
@@ -4,12 +4,12 @@
import net.customware.gwt.presenter.client.EventBus;
-import org.zanata.common.ContentState;
import org.zanata.webtrans.client.events.CopyDataToEditorEvent;
-import org.zanata.webtrans.client.presenter.TransHistoryVersionComparator;
import org.zanata.webtrans.client.resources.WebTransMessages;
import org.zanata.webtrans.client.util.ContentStateToStyleUtil;
import org.zanata.webtrans.client.util.DateUtil;
+import org.zanata.webtrans.shared.model.ComparableByDate;
+import org.zanata.webtrans.shared.model.ReviewComment;
import org.zanata.webtrans.shared.model.TransHistoryItem;
import com.google.common.base.Strings;
@@ -30,14 +30,11 @@
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
-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.HTMLPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TabLayoutPanel;
-import com.google.gwt.user.client.ui.VerticalPanel;
-import com.google.gwt.view.client.DefaultSelectionEventManager;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionModel;
import com.google.inject.Inject;
@@ -50,12 +47,12 @@ public class TranslationHistoryView extends DialogBox implements TranslationHist
private static final int COMPARISON_TAB_INDEX = 1;
private static final CellTableResources CELL_TABLE_RESOURCES = GWT.create(CellTableResources.class);
private static TranslationHistoryViewUiBinder uiBinder = GWT.create(TranslationHistoryViewUiBinder.class);
- private final CellTable historyTable;
+// private final CellTable historyTable;
private final EventBus eventBus;
@UiField
WebTransMessages messages;
@UiField
- VerticalPanel historyPanel;
+ HTMLPanel historyPanel;
@UiField
HistoryEntryComparisonPanel comparisonPanel;
@UiField
@@ -68,6 +65,9 @@ public class TranslationHistoryView extends DialogBox implements TranslationHist
private Column versionColumn;
@UiField
Button compareButton;
+ @UiField
+ UnorderedListWidget itemList;
+ private Listener listener;
@Inject
public TranslationHistoryView(EventBus eventBus)
@@ -80,16 +80,32 @@ public TranslationHistoryView(EventBus eventBus)
tabLayoutPanel.ensureDebugId("transHistoryTabPanel");
setGlassEnabled(true);
- historyTable = setUpHistoryTable();
+// historyTable = setUpHistoryTable();
- SimplePager simplePager = new SimplePager();
- simplePager.setDisplay(historyTable);
+// SimplePager simplePager = new SimplePager();
+// simplePager.setDisplay(historyTable);
- historyPanel.add(historyTable);
- historyPanel.add(simplePager);
+// historyPanel.add(historyTable);
+// historyPanel.add(simplePager);
setWidget(container);
}
+ @Override
+ public void setData(List items)
+ {
+ for (ComparableByDate item : items)
+ {
+ if (item instanceof TransHistoryItem)
+ {
+ itemList.add(new TransHistoryItemLine((TransHistoryItem) item, listener));
+ }
+ if (item instanceof ReviewComment)
+ {
+ itemList.add(new ReviewCommentItemLine((ReviewComment) item));
+ }
+ }
+ }
+
private CellTable setUpHistoryTable()
{
CellTable historyTable = new CellTable(PAGE_SIZE, CELL_TABLE_RESOURCES, HISTORY_ITEM_PROVIDES_KEY);
@@ -182,16 +198,16 @@ public void disableComparison()
@Override
public void setSelectionModel(SelectionModel multiSelectionModel)
{
- historyTable.setSelectionModel(multiSelectionModel, DefaultSelectionEventManager.createCheckboxManager());
- Column checkboxColumn = createCheckboxColumn(multiSelectionModel);
- historyTable.insertColumn(0, checkboxColumn);
- historyTable.setColumnWidth(checkboxColumn, 10, Style.Unit.PX);
+// historyTable.setSelectionModel(multiSelectionModel, DefaultSelectionEventManager.createCheckboxManager());
+// Column checkboxColumn = createCheckboxColumn(multiSelectionModel);
+// historyTable.insertColumn(0, checkboxColumn);
+// historyTable.setColumnWidth(checkboxColumn, 10, Style.Unit.PX);
}
@Override
public void setDataProvider(ListDataProvider dataProvider)
{
- dataProvider.addDataDisplay(historyTable);
+// dataProvider.addDataDisplay(historyTable);
}
@Override
@@ -200,13 +216,19 @@ public void setTitle(String title)
getCaption().setText(title);
}
+ @Override
+ public void setListener(Listener listener)
+ {
+ this.listener = listener;
+ }
+
@Override
public void addVersionSortHandler(ColumnSortEvent.ListHandler sortHandler)
{
- sortHandler.setComparator(versionColumn, TransHistoryVersionComparator.COMPARATOR);
- historyTable.addColumnSortHandler(sortHandler);
- //push it to make column sort in desc order at start
- historyTable.getColumnSortList().push(versionColumn);
+// sortHandler.setComparator(versionColumn, TransHistoryVersionComparator.COMPARATOR);
+// historyTable.addColumnSortHandler(sortHandler);
+// push it to make column sort in desc order at start
+// historyTable.getColumnSortList().push(versionColumn);
}
private void setComparisonTitle(String description)
@@ -218,8 +240,8 @@ private void setComparisonTitle(String description)
@Override
public void resetView()
{
- historyTable.setPageStart(0);
- disableComparison();
+// historyTable.setPageStart(0);
+// disableComparison();
}
private static Column createVersionColumn()
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryView.ui.xml
index d380d113cb..8d79af893d 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryView.ui.xml
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/TranslationHistoryView.ui.xml
@@ -23,7 +23,14 @@
-
+
+
+
+
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/ui/UnorderedListWidget.java b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/UnorderedListWidget.java
new file mode 100644
index 0000000000..b7eec51df5
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/client/ui/UnorderedListWidget.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.client.ui;
+
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.UListElement;
+import com.google.gwt.user.client.ui.ComplexPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * @author Patrick Huang pahuang@redhat.com
+ */
+public class UnorderedListWidget extends ComplexPanel
+{
+ public UnorderedListWidget()
+ {
+ setElement(Document.get().createULElement());
+ }
+
+ public void setDir(String dir)
+ {
+ // Set an attribute specific to this tag
+ ((UListElement) getElement().cast()).setDir(dir);
+ }
+
+ public void add(Widget widget)
+ {
+ // ComplexPanel requires the two-arg add() method
+ super.add(widget, getElement());
+ }
+}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTranslationHistoryHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTranslationHistoryHandler.java
index 26fd29de6f..7674183abf 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTranslationHistoryHandler.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTranslationHistoryHandler.java
@@ -1,5 +1,6 @@
package org.zanata.webtrans.server.rpc;
+import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
@@ -11,21 +12,26 @@
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.zanata.dao.TextFlowDAO;
+import org.zanata.dao.TextFlowTargetReviewCommentsDAO;
import org.zanata.exception.ZanataServiceException;
import org.zanata.model.HLocale;
import org.zanata.model.HPerson;
import org.zanata.model.HTextFlow;
import org.zanata.model.HTextFlowTarget;
import org.zanata.model.HTextFlowTargetHistory;
+import org.zanata.model.HTextFlowTargetReviewComment;
import org.zanata.security.ZanataIdentity;
import org.zanata.service.LocaleService;
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.model.TransHistoryItem;
import org.zanata.webtrans.shared.rpc.GetTranslationHistoryAction;
import org.zanata.webtrans.shared.rpc.GetTranslationHistoryResult;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
@@ -38,13 +44,16 @@
public class GetTranslationHistoryHandler extends AbstractActionHandler
{
@In
- ZanataIdentity identity;
+ private ZanataIdentity identity;
@In
- LocaleService localeServiceImpl;
+ private LocaleService localeServiceImpl;
@In
- TextFlowDAO textFlowDAO;
+ private TextFlowDAO textFlowDAO;
+
+ @In
+ private TextFlowTargetReviewCommentsDAO textFlowTargetReviewCommentsDAO;
@Override
public GetTranslationHistoryResult execute(GetTranslationHistoryAction action, ExecutionContext context) throws ActionException
@@ -77,8 +86,14 @@ public GetTranslationHistoryResult execute(GetTranslationHistoryAction action, E
}
Iterable historyItems = Iterables.transform(history.values(), new TargetHistoryToTransHistoryItemFunction());
+
log.debug("found {} history for text flow id {}", Iterables.size(historyItems), action.getTransUnitId());
- return new GetTranslationHistoryResult(historyItems, latest);
+
+ List reviewComments = getReviewComments(action);
+ log. debug("found {} review comments for text flow id {}", reviewComments.size(), action.getTransUnitId());
+
+ // we re-wrap the list because gwt rpc doesn't like other list implementation
+ return new GetTranslationHistoryResult(Lists.newArrayList(historyItems), latest, Lists.newArrayList(reviewComments));
}
private static String nameOrEmptyString(HPerson lastModifiedBy)
@@ -86,6 +101,20 @@ private static String nameOrEmptyString(HPerson lastModifiedBy)
return lastModifiedBy != null ? lastModifiedBy.getName() : "";
}
+ private List getReviewComments(GetTranslationHistoryAction action)
+ {
+ List hComments = textFlowTargetReviewCommentsDAO.getReviewComments(action.getTransUnitId(), action.getWorkspaceId().getLocaleId());
+
+ return 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());
+ }
+ });
+ }
+
@Override
public void rollback(GetTranslationHistoryAction action, GetTranslationHistoryResult result, ExecutionContext context) throws ActionException
{
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ComparableByDate.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ComparableByDate.java
new file mode 100644
index 0000000000..47ecc005ba
--- /dev/null
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/ComparableByDate.java
@@ -0,0 +1,38 @@
+/*
+ * 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.util.Date;
+
+/**
+ * @author Patrick Huang pahuang@redhat.com
+ */
+public abstract class ComparableByDate implements Comparable
+{
+ protected abstract Date getDate();
+
+ @Override
+ public int compareTo(ComparableByDate o)
+ {
+ return getDate().compareTo(o.getDate());
+ }
+}
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
index 582c9286b6..aa702dd2be 100644
--- 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
@@ -9,7 +9,7 @@
/**
* @author Patrick Huang pahuang@redhat.com
*/
-public class ReviewComment implements IsSerializable
+public class ReviewComment extends ComparableByDate implements IsSerializable
{
private ReviewCommentId id;
private String comment;
@@ -75,39 +75,9 @@ public Integer getTargetVersion()
return targetVersion;
}
- // setters to make gwt serialization happy
- void setId(ReviewCommentId id)
+ @Override
+ protected Date getDate()
{
- 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;
+ return creationDate;
}
}
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransHistoryItem.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransHistoryItem.java
index 226d2c4cb4..e2f0b57281 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransHistoryItem.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/TransHistoryItem.java
@@ -12,7 +12,7 @@
/**
* @author Patrick Huang pahuang@redhat.com
*/
-public class TransHistoryItem implements IsSerializable
+public class TransHistoryItem extends ComparableByDate implements IsSerializable
{
private String versionNum;
private List contents;
@@ -65,6 +65,12 @@ public void setVersionNum(String newVersionNum)
versionNum = newVersionNum;
}
+ @Override
+ protected Date getDate()
+ {
+ return modifiedDate;
+ }
+
@Override
public String toString()
{
diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTranslationHistoryResult.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTranslationHistoryResult.java
index 4cafaf8b61..f8ce92784b 100644
--- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTranslationHistoryResult.java
+++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetTranslationHistoryResult.java
@@ -2,6 +2,7 @@
import java.util.List;
+import org.zanata.webtrans.shared.model.ReviewComment;
import org.zanata.webtrans.shared.model.TransHistoryItem;
import com.google.common.collect.Lists;
@@ -12,18 +13,19 @@
public class GetTranslationHistoryResult implements DispatchResult
{
private List historyItems = Lists.newArrayList();
+ private List reviewComments = Lists.newArrayList();
private TransHistoryItem latest;
-
@SuppressWarnings("unused")
private GetTranslationHistoryResult()
{
}
- public GetTranslationHistoryResult(Iterable historyItems, TransHistoryItem latest)
+ public GetTranslationHistoryResult(List historyItems, TransHistoryItem latest, List reviewComments)
{
this.latest = latest;
- this.historyItems = Lists.newArrayList(historyItems);
+ this.historyItems = historyItems;
+ this.reviewComments = reviewComments;
}
public List