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

Commit

Permalink
rhbz1183994 - refactor to return a list
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Huang committed Mar 19, 2015
1 parent 21f03e6 commit da6345f
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 154 deletions.
18 changes: 0 additions & 18 deletions zanata-war/src/main/java/org/zanata/dao/DatabaseSpecific.java

This file was deleted.

5 changes: 5 additions & 0 deletions zanata-war/src/main/java/org/zanata/dao/NativeQuery.java
Expand Up @@ -15,4 +15,9 @@
* Reason why it has to be native query.
*/
String value() default "";

/**
* If the query is specific to certain database due to built-in function etc.
*/
String specificTo() default "";
}
Expand Up @@ -20,32 +20,26 @@
*/
package org.zanata.dao;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.transform.ResultTransformer;
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.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.zanata.common.ContentState;
import org.zanata.model.HLocale;
import org.zanata.model.HPerson;
import org.zanata.model.HProjectIteration;
import org.zanata.model.HTextFlowTarget;
import org.zanata.model.HTextFlowTargetHistory;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Name("textFlowTargetHistoryDAO")
@AutoCreate
Expand Down Expand Up @@ -198,13 +192,15 @@ public boolean findConflictInHistory(HTextFlowTarget target,
* different from system time zone
* @param systemZone
* current system time zone
* @return a list of UserTranslationMatrix object
* @param resultTransformer
* result transformer to transform query results
* @return a list of transformed object
*/
@NativeQuery("need to use union")
@DatabaseSpecific("uses mysql date() function. In test we can override stripTimeFromDateTimeFunction(String) below to workaround it.")
public List<UserTranslationMatrix> getUserTranslationMatrix(
@NativeQuery(value = "need to use union", specificTo = "mysql due to usage of date() and convert_tz() functions.")
public <T> List<T> getUserTranslationMatrix(
HPerson user, DateTime fromDate, DateTime toDate,
Optional<DateTimeZone> userZoneOpt, DateTimeZone systemZone) {
Optional<DateTimeZone> userZoneOpt, DateTimeZone systemZone,
ResultTransformer resultTransformer) {
// @formatter:off
String queryHistory = "select history.id, iter.id as iteration, tft.locale as locale, tf.wordCount as wordCount, history.state as state, history.lastChanged as lastChanged " +
" from HTextFlowTargetHistory history " +
Expand Down Expand Up @@ -239,29 +235,12 @@ public List<UserTranslationMatrix> getUserTranslationMatrix(
Query query = getSession().createSQLQuery(queryString)
.setParameter("user", user.getId())
.setTimestamp("fromDate", fromDate.toDate())
.setTimestamp("toDate", toDate.toDate());
@SuppressWarnings("unchecked")
List<Object[]> result = query.list();
ImmutableList.Builder<UserTranslationMatrix> builder =
ImmutableList.builder();
for (Object[] objects : result) {
Date savedDate = new DateTime(objects[0]).toDate();
HProjectIteration iteration =
loadById(objects[1], HProjectIteration.class);
HLocale locale = loadById(objects[2], HLocale.class);
ContentState savedState = ContentState.values()[(int) objects[3]];
long wordCount =
((BigDecimal) objects[4]).toBigInteger().longValue();
UserTranslationMatrix matrix =
new UserTranslationMatrix(savedDate, iteration, locale,
savedState, wordCount);
builder.add(matrix);
}
return builder.build();
.setTimestamp("toDate", toDate.toDate())
.setResultTransformer(resultTransformer);
return query.list();
}

@VisibleForTesting
@DatabaseSpecific("uses mysql function")
protected String convertTimeZoneFunction(String columnName,
Optional<DateTimeZone> userZoneOpt, DateTimeZone systemZone) {
if (userZoneOpt.isPresent()) {
Expand All @@ -275,7 +254,6 @@ protected String convertTimeZoneFunction(String columnName,

// This is so we can override it in test and be able to test it against h2
@VisibleForTesting
@DatabaseSpecific("uses mysql function")
protected String stripTimeFromDateTimeFunction(String columnName) {
return "date(" + columnName + ")";
}
Expand All @@ -297,13 +275,4 @@ private static String getOffsetAsString(DateTimeZone zone) {
TimeUnit.MILLISECONDS.toHours(standardOffset));
}

@Getter
@RequiredArgsConstructor
public static class UserTranslationMatrix {
private final Date savedDate;
private final HProjectIteration projectIteration;
private final HLocale locale;
private final ContentState savedState;
private final long wordCount;
}
}
@@ -1,20 +1,24 @@
package org.zanata.rest.dto.matrix;
package org.zanata.rest.dto;

import org.zanata.common.ContentState;
import org.zanata.common.LocaleId;
import lombok.AllArgsConstructor;
import lombok.Data;

import org.zanata.common.ContentState;
import org.zanata.common.LocaleId;

/**
* @author Patrick Huang
* <a href="mailto:pahuang@redhat.com">pahuang@redhat.com</a>
*/
@Data
@AllArgsConstructor
public class DetailMatrix {
public class TranslationMatrix {
private String savedDate;
private String projectSlug;
private String projectName;
private String versionSlug;
private LocaleId localeId;
private String localeDisplayName;
private ContentState savedState;
private long wordCount;
}

This file was deleted.

Expand Up @@ -21,21 +21,25 @@
package org.zanata.rest.service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import javax.persistence.EntityManager;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang.StringUtils;
import org.hibernate.transform.ResultTransformer;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
Expand All @@ -53,15 +57,14 @@
import org.zanata.dao.PersonDAO;
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.dao.TextFlowTargetHistoryDAO;
import org.zanata.dao.TextFlowTargetHistoryDAO.UserTranslationMatrix;
import org.zanata.model.HDocument;
import org.zanata.model.HLocale;
import org.zanata.model.HPerson;
import org.zanata.model.HProjectIteration;
import org.zanata.model.HTextFlowTarget;
import org.zanata.rest.NoSuchEntityException;
import org.zanata.rest.dto.Link;
import org.zanata.rest.dto.matrix.UserWorkMatrix;
import org.zanata.rest.dto.TranslationMatrix;
import org.zanata.rest.dto.stats.ContainerTranslationStatistics;
import org.zanata.rest.dto.stats.TranslationStatistics;
import org.zanata.rest.dto.stats.TranslationStatistics.StatUnit;
Expand Down Expand Up @@ -106,6 +109,9 @@ public class StatisticsServiceImpl implements StatisticsResource {
@In
private PersonDAO personDAO;

@In
private EntityManager entityManager;

@In
private TranslationStateCache translationStateCacheImpl;

Expand Down Expand Up @@ -299,12 +305,10 @@ public ContainerTranslationStatistics getStatistics(String projectSlug,
* Get contribution statistic (translations) from project-version within
* given date range.
*
* Throws NoSuchEntityException if:
* - project/version not found or is obsolete,
* - user not found
* Throws NoSuchEntityException if: - project/version not found or is
* obsolete, - user not found
*
* Throws InvalidDateParamException if:
* - dateRangeParam is in wrong format,
* Throws InvalidDateParamException if: - dateRangeParam is in wrong format,
* - date range is over MAX_STATS_DAYS
*
* @param projectSlug
Expand All @@ -314,8 +318,8 @@ public ContainerTranslationStatistics getStatistics(String projectSlug,
* @param username
* username of contributor
* @param dateRangeParam
* from..to (yyyy-mm-dd..yyyy-mm-dd),
* date range maximum: 365 days
* from..to (yyyy-mm-dd..yyyy-mm-dd), date range maximum: 365
* days
*/
@Override
public ContributionStatistics getContributionStatistics(String projectSlug,
Expand Down Expand Up @@ -443,7 +447,7 @@ public ContainerTranslationStatistics getDocStatistics(Long documentId,
@Path("user/{username}/{dateRangeParam}")
@GET
@Produces({"application/json"})
public UserWorkMatrix getUserWorkMatrix(
public List<TranslationMatrix> getUserWorkMatrix(
@PathParam("username") final String username,
@PathParam("dateRangeParam") String dateRangeParam,
@QueryParam("userTimeZone") String userTimeZoneID) {
Expand All @@ -468,22 +472,60 @@ public UserWorkMatrix getUserWorkMatrix(
userZoneOpt = Optional.absent();
}

// TODO pahuang restrict toDate to yesterday (with timezone)
// if (toDate.isAfter(new DateTime().withTimeAtStartOfDay())) {
// toDate = new DateTime().withTimeAtStartOfDay();
// }
List<UserTranslationMatrix> databaseRecords =
List<TranslationMatrix> translationMatrixList =
textFlowTargetHistoryDAO.getUserTranslationMatrix(person,
fromDate, toDate, userZoneOpt, systemZone);
fromDate, toDate, userZoneOpt, systemZone,
new UserMatrixResultTransformer(entityManager, dateFormatter));

UserWorkMatrix result = new UserWorkMatrix();
return translationMatrixList;
}

for (UserTranslationMatrix matrixRecord : databaseRecords) {
String dateString = dateFormatter.print(
matrixRecord.getSavedDate().getTime());
result.putOrCreateIfAbsent(dateString, matrixRecord);
@RequiredArgsConstructor
public static class UserMatrixResultTransformer implements
ResultTransformer {
private static final long serialVersionUID = 1L;
private final EntityManager entityManager;
private final DateTimeFormatter dateFormater;

@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
String savedDate = dateFormater.print(
new DateTime(tuple[0]).toDate().getTime());
HProjectIteration iteration =
entityManager.find(HProjectIteration.class,
((BigInteger) tuple[1]).longValue());
String projectSlug = iteration.getProject().getSlug();
String projectName = iteration.getProject().getName();
String versionSlug = iteration.getSlug();

HLocale locale =
entityManager.find(HLocale.class,
((BigInteger) tuple[2]).longValue());
String localeDisplayName = locale.retrieveDisplayName();
LocaleId localeId = locale.getLocaleId();

ContentState savedState = ContentState.values()[(int) tuple[3]];
long wordCount =
((BigDecimal) tuple[4]).toBigInteger().longValue();

return new TranslationMatrix(savedDate, projectSlug, projectName,
versionSlug, localeId, localeDisplayName,
savedState, wordCount);
}

return result;
@Override
public List transformList(List collection) {
return collection;
}
}

@Getter
@RequiredArgsConstructor
public static class UserTranslationMatrix {
private final Date savedDate;
private final HProjectIteration projectIteration;
private final HLocale locale;
private final ContentState savedState;
private final long wordCount;
}
}

0 comments on commit da6345f

Please sign in to comment.