package com.springone.myrestaurants.web; import static org.springframework.data.document.mongodb.query.Criteria.*; import java.io.OutputStream; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.DBObject; import com.mongodb.Mongo; import com.mongodb.QueryBuilder; import com.springone.myrestaurants.dao.RestaurantDao; import com.springone.myrestaurants.domain.Restaurant; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.category.DefaultCategoryDataset; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.document.analytics.ControllerCounter; import org.springframework.data.document.mongodb.MongoTemplate; import org.springframework.data.document.mongodb.query.Query; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @RequestMapping("/charts") @Controller public class ChartController { @Autowired private RestaurantDao restaurantDao; @RequestMapping("/favorites.png") public void renderChart(String variation, OutputStream stream) throws Exception { boolean rotate = "rotate".equals(variation); // add ?variation=rotate to // the URL to rotate the // chart JFreeChart chart = generateChart(rotate); ChartUtilities.writeChartAsPNG(stream, chart, 750, 400); } @RequestMapping("/controllers.png") public void renderControllers(String controllerName, OutputStream stream) throws Exception { JFreeChart chart = generateControllerChart(controllerName); ChartUtilities.writeChartAsPNG(stream, chart, 750, 400); } private JFreeChart generateControllerChart(String controllerName) { DefaultCategoryDataset dataset = getControllerData(controllerName); String xAxisLabel; String title; if (controllerName != null) { xAxisLabel = controllerName; title = controllerName + " Actions"; } else { xAxisLabel = "Controllers"; title = "Controller Invocations"; } return ChartFactory.createBarChart(title, xAxisLabel, "Number of times invoked", // y-axis label dataset, PlotOrientation.VERTICAL, true, // legend displayed true, // tooltips displayed false); // no URLs*/ } private JFreeChart generateChart(boolean rotate) { DefaultCategoryDataset dataset = getFavoritesData(); return ChartFactory.createBarChart("Favorited Restaurants", // title "Restaurants", // x-axis label "Number of times recommended", // y-axis label dataset, rotate ? PlotOrientation.HORIZONTAL : PlotOrientation.VERTICAL, true, // legend displayed true, // tooltips displayed false); // no URLs*/ } private DefaultCategoryDataset getControllerData(String controllerName) { MongoTemplate mongoTemplate; DefaultCategoryDataset ds = null; try { Mongo m = new Mongo(); mongoTemplate = new MongoTemplate(m, "mvc"); List<ControllerCounter> counters; ds = new DefaultCategoryDataset(); if (controllerName != null) { counters = mongoTemplate.find(new Query(where("name").is(controllerName)), ControllerCounter.class, "counters"); for (ControllerCounter controllerCounter : counters) { Map<String, Double> methodInvocations = controllerCounter.getMethods(); Set<Entry<String, Double>> es = methodInvocations.entrySet(); for (Entry<String, Double> entry : es) { ds.addValue(entry.getValue(), "invoked", entry.getKey()); } } } else { counters = mongoTemplate.findAll(ControllerCounter.class, "counters"); for (ControllerCounter controllerCounter : counters) { ds.addValue(controllerCounter.getCount(), "invoked (aggregate)", controllerCounter.getName()); } } /* if (result instanceof BasicDBList) { BasicDBList dbList = (BasicDBList) result; for (Iterator iterator = dbList.iterator(); iterator.hasNext();) { DBObject dbo = (DBObject) iterator.next(); System.out.println(dbo); Restaurant r = restaurantDao.findRestaurant(Long.parseLong(dbo.get("parameters.p1").toString())); ds.addValue(Double.parseDouble(dbo.get("count").toString()), "recommended", r.getName()); } }*/ return ds; } catch (Exception e) { e.printStackTrace(); } return ds; } private DefaultCategoryDataset getFavoritesData() { MongoTemplate mongoTemplate; DefaultCategoryDataset ds = null; try { Mongo m = new Mongo(); mongoTemplate = new MongoTemplate(m, "mvc"); DBObject result = getTopRecommendedRestaurants(mongoTemplate); /* Example data. * [ { "parameters.p1" : "1" , "count" : 5.0} , * { "parameters.p1" : "2" , "count" : 6.0} , * { "parameters.p1" : "3" , "count" : 3.0} , * { "parameters.p1" : "4" , "count" : 8.0}] */ ds = new DefaultCategoryDataset(); if (result instanceof BasicDBList) { BasicDBList dbList = (BasicDBList) result; for (Iterator iterator = dbList.iterator(); iterator.hasNext(); ) { DBObject dbo = (DBObject) iterator.next(); System.out.println(dbo); Restaurant r = restaurantDao.findRestaurant(Long.parseLong(dbo.get("parameters.p1").toString())); ds.addValue(Double.parseDouble(dbo.get("count").toString()), "recommended", r.getName()); } } return ds; } catch (Exception e) { e.printStackTrace(); } return ds; } public DBObject getTopRecommendedRestaurants(MongoTemplate mongoTemplate) { //This circumvents exception translation DBCollection collection = mongoTemplate.getCollection("mvc"); Date startDate = createDate(1, 5, 2010); Date endDate = createDate(1, 12, 2010); DBObject cond = QueryBuilder.start("date").greaterThanEquals(startDate).lessThan(endDate).and("action").is("addFavoriteRestaurant").get(); DBObject key = new BasicDBObject("parameters.p1", true); DBObject intitial = new BasicDBObject("count", 0); DBObject result = collection.group(key, cond, intitial, "function(doc, out){ out.count++; }"); //List<ParameterRanking> parameterRanking = mongoTemplate.queryForListGroupBy(groupQuery, ParameterRanking.class); return result; } private Date createDate(int day, int month, int year) { Calendar d = Calendar.getInstance(); d.clear(); d.set(Calendar.YEAR, year); d.set(Calendar.MONTH, month); d.set(Calendar.DATE, day); return d.getTime(); } }