/******************************************************************************* * Copyright 2011 Antti Havanko * * This file is part of Motiver.fi. * Motiver.fi is licensed under one open source license and one commercial license. * * Commercial license: This is the appropriate option if you want to use Motiver.fi in * commercial purposes. Contact license@motiver.fi for licensing options. * * Open source license: This is the appropriate option if you are creating an open source * application with a license compatible with the GNU GPL license v3. Although the GPLv3 has * many terms, the most important is that you must provide the source code of your application * to your users so they can be free to modify your application for their own needs. ******************************************************************************/ /** * */ package com.delect.motiver.server.servlet; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.jdo.PersistenceManager; import javax.jdo.Query; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.datanucleus.store.appengine.query.JDOCursorHelper; import com.delect.motiver.server.PMF; import com.delect.motiver.server.jdo.MonthlySummary; import com.delect.motiver.server.jdo.MonthlySummaryExercise; import com.delect.motiver.server.jdo.UserOpenid; import com.delect.motiver.server.jdo.training.Exercise; import com.delect.motiver.server.jdo.training.Workout; import com.delect.motiver.server.service.MyServiceImpl; import com.delect.motiver.shared.util.WorkoutUtils; import com.delect.motiver.shared.util.WorkoutUtils.ExerciseInfo; import com.google.appengine.api.datastore.Cursor; import com.google.gwt.user.server.rpc.RemoteServiceServlet; /** * Creates monthly summary for each user. * @author Antti * */ public class MonthlyReportServlet extends RemoteServiceServlet { private static final long serialVersionUID = 5384098111620397L; @SuppressWarnings({"unchecked", "deprecation"}) @Override public void doGet(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/html"); PersistenceManager pm = PMF.get().getPersistenceManager(); try { //get users List<UserOpenid> users = this.getAll(pm, UserOpenid.class); response.getWriter().write(users.size()+" users found.<br><br>"); Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); cal.set(Calendar.HOUR, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); cal.add(Calendar.MONTH, -1); //get date from parameters try { if(request.getParameter("month") != null && request.getParameter("year") != null) { cal.set(Calendar.MONTH, Integer.parseInt(request.getParameter("month"))-1); cal.set(Calendar.YEAR, Integer.parseInt(request.getParameter("year"))); } } catch (Exception e1) { response.getWriter().write("error1: "+e1); } //get dates cal.set(Calendar.DATE, 1); Date d1 = cal.getTime(); cal.add(Calendar.MONTH, 1); cal.add(Calendar.DATE, -1); Date d2 = cal.getTime(); final Date dStart = MyServiceImpl.stripTime(d1, true); final Date dEnd = MyServiceImpl.stripTime(d2, false); cal.set(Calendar.DATE, 1); response.getWriter().write(dStart+" - "+dEnd+"<br>"); for(UserOpenid user : users) { try { //remove all this month's data Query qD = pm.newQuery(MonthlySummary.class); qD.setFilter("openId == openIdParam && date >= dateParam"); qD.declareParameters("java.lang.String openIdParam, java.util.Date dateParam"); List<MonthlySummary> data = (List<MonthlySummary>) qD.execute(user.getUid(), dStart); pm.deletePersistentAll(data); //get this months workouts Query qW = pm.newQuery(Workout.class); qW.setFilter("openId == openIdParam && date >= dateStartParam && date <= dateEndParam"); qW.declareParameters("java.lang.String openIdParam, java.util.Date dateStartParam, java.util.Date dateEndParam"); List<Workout> workouts = (List<Workout>) qW.execute(user.getUid(), dStart, dEnd); if(workouts.size() > 0) { response.getWriter().write(user.getEmail()+"<br>"); response.getWriter().write("<table width='100%' border=1 cellpadding=5>"); response.getWriter().write("<tr><td>nameId"+ "<td>Sets"+ "<td>reps string"+ "<td><b>reps</b>"+ "<td>weights string"+ "<td><b>weights</b>"+ "<td>max"+ "<td>length"+ "<td>work"+ "</td></tr>"); //hashtables which we save one rep maxes and best exercises Hashtable<Long, MonthlySummaryExercise> tableMax = new Hashtable<Long, MonthlySummaryExercise>(); Hashtable<String, MonthlySummaryExercise> tableBest = new Hashtable<String, MonthlySummaryExercise>(); //model final MonthlySummary model = new MonthlySummary(cal.getTime()); model.setUid(user.getUid()); final List<MonthlySummaryExercise> list = new ArrayList<MonthlySummaryExercise>(); //go through each workouts for(Workout w : workouts) { response.getWriter().write("<tr><td colspan=9>"+w.getName()+" - "+w.getDate()+"</td></tr>"); for(Exercise e : w.getExercises()) { try { final long nameId = e.getNameId(); if(nameId > 0) { ExerciseInfo info = new ExerciseInfo(e.getSets(), e.getReps(), e.getWeights()); WorkoutUtils.parseExercise(info); if(!info.isOk()) { continue; } double[] re = info.reps; double[] we = info.weights; response.getWriter().write("<tr><td>"+nameId+ "<td>"+e.getSets()+ "<td>"+e.getReps()+ "<td><b>"+((re.length == we.length)? Arrays.toString(re) : "ERR")+"</b>"+ "<td>"+e.getWeights()+ "<td><b>"+((re.length == we.length)? Arrays.toString(we) : "ERR")+"</b>"+ "<td>"+info.max+ "<td>"+info.sets+ "<td>"+info.work+ "</td></tr>"); //create model MonthlySummaryExercise modelE = new MonthlySummaryExercise(0, info.max); modelE.setReps(e.getReps()); modelE.setSets(e.getSets()); modelE.setWeights(e.getWeights()); modelE.setWorkoutDate(w.getDate()); modelE.setLength(info.sets); modelE.setNameId(e.getNameId()); modelE.setUid(user.getUid()); //set date cal.setTime(w.getDate()); //if max found if(info.max > 0) { //save max if(tableMax.containsKey(nameId)) { if(tableMax.get(nameId).getValue() < info.max) { tableMax.put(nameId, modelE); } } else { tableMax.put(nameId, modelE); } } //save best exercises else { modelE.setType(1, info.work); boolean found = false; if(tableBest.containsKey(nameId+"_"+info.sets)) { //if lower value and same length if(tableBest.get(nameId+"_"+info.sets).getValue() < info.work) { tableBest.put(nameId+"_"+info.sets, modelE); found = true; } } //if not found -> insert new if(!found) { tableBest.put(nameId+"_"+info.sets, modelE); } } } } catch (IOException ex) { ex.printStackTrace(); } } } //save max results response.getWriter().write("<tr><td colspan=9>Max</td></tr>"); Set<Long> set = tableMax.keySet(); Iterator<Long> itr = set.iterator(); while (itr.hasNext()) { long nameId = itr.next(); MonthlySummaryExercise modelE = tableMax.get(nameId); //check if personal best Query qIsBest = pm.newQuery(MonthlySummaryExercise.class); qIsBest.setFilter("openId == openIdParam && nameId == nameIdParam && type == 0 && length == lengthParam && value > valueParam"); qIsBest.declareParameters("java.lang.String openIdParam, java.lang.Long nameIdParam, java.lang.Integer lengthParam, java.lang.Double valueParam"); List<MonthlySummaryExercise> dataIsBest = (List<MonthlySummaryExercise>)qIsBest.executeWithArray( new Object[] {user.getUid(), nameId, modelE.getLength(), modelE.getValue()} ); modelE.setPersonalBest(dataIsBest.size() == 0); //add to list list.add(modelE); response.getWriter().write("<tr><td>"+nameId+ "<td>"+ "<td>"+ "<td>"+ "<td>"+ "<td>"+ "<td>"+ "<td>"+modelE.getValue()+ "</td></tr>"); } //print best exercises response.getWriter().write("<tr><td colspan=9>Best</td></tr>"); Set<String> set2 = tableBest.keySet(); Iterator<String> itr2 = set2.iterator(); while (itr2.hasNext()) { String nameId = itr2.next(); MonthlySummaryExercise modelE = tableBest.get(nameId); //check if personal best Query qIsBest = pm.newQuery(MonthlySummaryExercise.class); qIsBest.setFilter("openId == openIdParam && nameId == nameIdParam && type == 1 && length == lengthParam && value > valueParam"); qIsBest.declareParameters("java.lang.String openIdParam, java.lang.Long nameIdParam, java.lang.Integer lengthParam, java.lang.Double valueParam"); qIsBest.setRange(0, 1); List<MonthlySummaryExercise> dataIsBest = (List<MonthlySummaryExercise>)qIsBest.executeWithArray( new Object[] {user.getUid(), modelE.getNameId(), modelE.getLength(), modelE.getValue()} ); modelE.setPersonalBest(dataIsBest.size() == 0); //add to list list.add(modelE); response.getWriter().write("<tr><td>"+nameId+ "<td>"+ "<td>"+ "<td>"+ "<td>"+ "<td>"+ "<td>"+ "<td>"+ "<td>"+modelE.getValue()+ "</td></tr>"); } boolean found = false; if(list.size() > 0) { model.setExercises(list); found = true; } //if something found -> save entity if(found) { pm.makePersistent(model); } response.getWriter().write("</table>"); } } catch (IOException e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } finally { if (!pm.isClosed()) { pm.close(); } } } private List getAll(PersistenceManager pm, Class class1) { List list = new ArrayList(); Cursor cursor = null; Map<String, Object> extensionMap = new HashMap<String, Object>(); while(true){ Query q = pm.newQuery(class1); q.setRange(0, 700); if(cursor != null) { extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, cursor); q.setExtensions(extensionMap); } List u = (List) q.execute(); cursor = JDOCursorHelper.getCursor(u); list.addAll(u); if(u.size() == 0) { break; } } return list; } }