001: /*
002: *
003: * Copyright (c) 2004 SourceTap - www.sourcetap.com
004: *
005: * The contents of this file are subject to the SourceTap Public License
006: * ("License"); You may not use this file except in compliance with the
007: * License. You may obtain a copy of the License at http://www.sourcetap.com/license.htm
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
010: * the specific language governing rights and limitations under the License.
011: *
012: * The above copyright notice and this permission notice shall be included
013: * in all copies or substantial portions of the Software.
014: *
015: */
016:
017: package com.sourcetap.sfa.chart;
018:
019: import java.awt.BasicStroke;
020: import java.awt.Color;
021: import java.awt.Font;
022: import java.awt.Graphics2D;
023: import java.awt.Paint;
024: import java.awt.image.BufferedImage;
025: import java.io.IOException;
026: import java.util.ArrayList;
027: import java.util.Calendar;
028: import java.util.Date;
029: import java.util.Enumeration;
030:
031: import javax.servlet.ServletConfig;
032: import javax.servlet.ServletContext;
033: import javax.servlet.ServletException;
034: import javax.servlet.http.HttpServlet;
035: import javax.servlet.http.HttpServletRequest;
036: import javax.servlet.http.HttpServletResponse;
037: import javax.servlet.http.HttpSession;
038:
039: import org.jCharts.axisChart.BarChart;
040: import org.jCharts.chartData.SingleDataSet;
041: import org.jCharts.properties.AxisProperties;
042: import org.jCharts.properties.BarChartProperties;
043: import org.jCharts.properties.LineChartProperties;
044: import org.ofbiz.base.util.Debug;
045: import org.ofbiz.base.util.UtilHttp;
046: import org.ofbiz.base.util.UtilTimer;
047: import org.ofbiz.base.util.UtilValidate;
048: import org.ofbiz.content.webapp.control.RequestHandler;
049: import org.ofbiz.entity.GenericDelegator;
050: import org.ofbiz.entity.GenericValue;
051: import org.ofbiz.entity.condition.EntityExpr;
052: import org.ofbiz.entity.condition.EntityOperator;
053:
054: import com.sourcetap.sfa.activity.CalendarUtil;
055: import com.sourcetap.sfa.util.UserInfo;
056:
057: /**
058: * ChartServlet.java - Generate Charts and stream to browser as jpeg images
059: *
060: * @author <a href="mailto:sfowler@sourcetap.com">Steve Fowler</a>
061: * @since 2.0
062: */
063: public class ChartServlet extends HttpServlet {
064:
065: public static final String module = ChartServlet.class.getName();
066:
067: public ChartServlet() {
068: super ();
069: }
070:
071: /**
072: * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
073: */
074: public void init(ServletConfig config) throws ServletException {
075: super .init(config);
076: }
077:
078: /**
079: * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
080: */
081: public void doPost(HttpServletRequest request,
082: HttpServletResponse response) throws ServletException,
083: IOException {
084: doGet(request, response);
085: }
086:
087: /**
088: * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
089: */
090: public void doGet(HttpServletRequest request,
091: HttpServletResponse response) throws ServletException,
092: IOException {
093: // setup content type
094: String contentType = "image/jpeg";
095: response.setContentType(contentType);
096:
097: long requestStartTime = System.currentTimeMillis();
098: HttpSession session = request.getSession();
099:
100: GenericValue userLogin = (GenericValue) session
101: .getAttribute("userLogin");
102: UserInfo userInfo = (UserInfo) session.getAttribute("userInfo");
103: //Debug.log("Cert Chain: " + request.getAttribute("javax.servlet.request.X509Certificate"), module);
104:
105: // workaraound if we are in the root webapp
106: String webappName = UtilHttp.getApplicationName(request);
107:
108: String rname = "";
109: if (request.getPathInfo() != null) {
110: rname = request.getPathInfo().substring(1);
111: }
112: if (rname.indexOf('/') > 0) {
113: rname = rname.substring(0, rname.indexOf('/'));
114: }
115:
116: UtilTimer timer = null;
117: if (Debug.timingOn()) {
118: timer = new UtilTimer();
119: timer.setLog(true);
120: timer.timerString("[" + rname
121: + "] Servlet Starting, doing setup", module);
122: }
123:
124: // Setup the CONTROL_PATH for JSP dispatching.
125: request.setAttribute("_CONTROL_PATH_", request.getContextPath()
126: + request.getServletPath());
127: if (Debug.verboseOn())
128: Debug.logVerbose("Control Path: "
129: + request.getAttribute("_CONTROL_PATH_"), module);
130:
131: // for convenience, and necessity with event handlers, make security and delegator available in the request:
132: // try to get it from the session first so that we can have a delegator/dispatcher/security for a certain user if desired
133: GenericDelegator delegator = null;
134: String delegatorName = (String) session
135: .getAttribute("delegatorName");
136: if (UtilValidate.isNotEmpty(delegatorName)) {
137: delegator = GenericDelegator
138: .getGenericDelegator(delegatorName);
139: }
140: if (delegator == null) {
141: delegator = (GenericDelegator) getServletContext()
142: .getAttribute("delegator");
143: }
144: if (delegator == null) {
145: Debug
146: .logError(
147: "[ControlServlet] ERROR: delegator not found in ServletContext",
148: module);
149: } else {
150: request.setAttribute("delegator", delegator);
151: // always put this in the session too so that session events can use the delegator
152: session.setAttribute("delegatorName", delegator
153: .getDelegatorName());
154: }
155:
156: // display details on the servlet objects
157: if (Debug.verboseOn()) {
158: logRequestInfo(request);
159: }
160:
161: int fyStartMonth = CalendarUtil.getFiscalYearStartMonth(
162: delegator, userInfo);
163:
164: if (Debug.timingOn())
165: timer.timerString("[" + rname
166: + "] Setup done, doing Event(s) and View(s)",
167: module);
168:
169: try {
170: String monthLabel[] = { "", "January", "February", "March",
171: "April", "May", "June", "July", "August",
172: "September", "October", "November", "December" };
173: BarChartProperties properties = new BarChartProperties();
174: AxisProperties axisProperties = new AxisProperties();
175: axisProperties
176: .setScaleFont(new Font("Arial", Font.BOLD, 12));
177: axisProperties.setAxisTitleFont(new Font("Arial",
178: Font.BOLD, 12));
179: axisProperties.setYAxisUseDollarSigns(true);
180:
181: LineChartProperties lineChartProperties = new LineChartProperties(
182: new BasicStroke());
183:
184: Paint[] paints = { new Color(100, 150, 100) };
185: int width = 330;
186: int height = 216;
187: String xAxisTitle = " ";
188: String yAxisTitle = " ";
189:
190: ArrayList xAxisLabels = new ArrayList();
191: ArrayList legendLabels = new ArrayList();
192:
193: if (request.getParameter("report")
194: .equals("salesForQuarter")) {
195: double data[] = new double[3];
196: Calendar cal = Calendar.getInstance();
197:
198: int month = cal.get(Calendar.MONTH) + 1;
199: int year = cal.get(Calendar.YEAR);
200: int quarterNumbers[] = CalendarUtil
201: .getQuarterMonthNumbers(month, fyStartMonth);
202:
203: ArrayList list = new ArrayList();
204: list.add(new EntityExpr("ownerId",
205: EntityOperator.EQUALS, userInfo.getPartyId()));
206: list.add(new EntityExpr("dealStatusId",
207: EntityOperator.EQUALS, "10"));
208: list.add(new EntityExpr("actualCloseDate",
209: EntityOperator.LESS_THAN_EQUAL_TO,
210: new java.sql.Date(CalendarUtil
211: .getMaximumQuarterDate(
212: cal.get(Calendar.MONTH) + 1,
213: cal.get(Calendar.YEAR),
214: fyStartMonth).getTime())));
215: list.add(new EntityExpr("actualCloseDate",
216: EntityOperator.GREATER_THAN_EQUAL_TO,
217: new java.sql.Date(CalendarUtil
218: .getMinimumQuarterDate(
219: cal.get(Calendar.MONTH) + 1,
220: cal.get(Calendar.YEAR),
221: fyStartMonth).getTime())));
222:
223: ArrayList order = new ArrayList();
224: order.add("actualCloseDate");
225:
226: java.util.List dealList = delegator.findByAnd("Deal",
227: list, order);
228: GenericValue dealValues[] = (GenericValue[]) dealList
229: .toArray(new GenericValue[0]);
230: GenericValue dealValue = null;
231:
232: String months[] = CalendarUtil.getQuarterMonthNames(cal
233: .get(Calendar.MONTH) + 1, fyStartMonth);
234: for (int iz = 0; iz < months.length; iz++) {
235: xAxisLabels.add((String) months[iz]);
236: }
237:
238: xAxisTitle = "Month";
239: yAxisTitle = "Sales";
240:
241: legendLabels.add("Pipeline for Quarter");
242:
243: for (int iz = 0; iz < dealValues.length; iz++) {
244: dealValue = dealValues[iz];
245: Calendar calendar = Calendar.getInstance();
246: calendar.setTime(dealValue
247: .getDate("actualCloseDate"));
248:
249: if ((calendar.get(Calendar.MONTH) + 1) == quarterNumbers[0]
250: && calendar.get(Calendar.YEAR) == year) {
251: data[0] = data[0]
252: + dealValue.getDouble("amount")
253: .doubleValue();
254: }
255: if ((calendar.get(Calendar.MONTH) + 1) == quarterNumbers[1]
256: && calendar.get(Calendar.YEAR) == year) {
257: data[1] = data[1]
258: + dealValue.getDouble("amount")
259: .doubleValue();
260: }
261: if ((calendar.get(Calendar.MONTH) + 1) == quarterNumbers[2]
262: && calendar.get(Calendar.YEAR) == year) {
263: data[2] = data[2]
264: + dealValue.getDouble("amount")
265: .doubleValue();
266: }
267: }
268:
269: try {
270: BarChart barChart = new BarChart(new SingleDataSet(
271: data, (String[]) legendLabels
272: .toArray(new String[0]),
273: (String[]) xAxisLabels
274: .toArray(new String[0]), paints,
275: xAxisTitle, yAxisTitle), false, properties,
276: axisProperties, width, height);
277:
278: response.reset();
279: response.setContentType("image/jpeg");
280:
281: barChart
282: .exportJPG(response.getOutputStream(), 1.0f);
283: response.getOutputStream().flush();
284: } catch (Throwable throwable) {
285: throwable.printStackTrace();
286: }
287: }
288:
289: if (request.getParameter("report")
290: .equals("leadsForQuarter")) {
291: double data[] = new double[3];
292: Calendar cal = Calendar.getInstance();
293:
294: int month = cal.get(Calendar.MONTH) + 1;
295: int year = cal.get(Calendar.YEAR);
296: int quarterNumbers[] = CalendarUtil
297: .getQuarterMonthNumbers(month, fyStartMonth);
298:
299: ArrayList list = new ArrayList();
300: list.add(new EntityExpr("leadOwnerId",
301: EntityOperator.EQUALS, userInfo.getPartyId()));
302: list.add(new EntityExpr("statusId",
303: EntityOperator.EQUALS, "50"));
304: list.add(new EntityExpr("convertedDate",
305: EntityOperator.LESS_THAN_EQUAL_TO,
306: new java.sql.Date(CalendarUtil
307: .getMaximumQuarterDate(
308: cal.get(Calendar.MONTH) + 1,
309: cal.get(Calendar.YEAR),
310: fyStartMonth).getTime())));
311: list.add(new EntityExpr("convertedDate",
312: EntityOperator.GREATER_THAN_EQUAL_TO,
313: new java.sql.Date(CalendarUtil
314: .getMinimumQuarterDate(
315: cal.get(Calendar.MONTH) + 1,
316: cal.get(Calendar.YEAR),
317: fyStartMonth).getTime())));
318:
319: ArrayList order = new ArrayList();
320: order.add("convertedDate");
321:
322: java.util.List dealList = delegator.findByAnd("Lead",
323: list, order);
324: GenericValue leadValues[] = (GenericValue[]) dealList
325: .toArray(new GenericValue[0]);
326: GenericValue leadValue = null;
327:
328: String months[] = CalendarUtil.getQuarterMonthNames(cal
329: .get(Calendar.MONTH) + 1, fyStartMonth);
330: for (int iz = 0; iz < months.length; iz++) {
331: xAxisLabels.add((String) months[iz]);
332: }
333: xAxisTitle = "Month";
334: yAxisTitle = "Leads";
335:
336: legendLabels.add("Leads for Quarter");
337:
338: for (int iz = 0; iz < leadValues.length; iz++) {
339: leadValue = leadValues[iz];
340: Calendar calendar = Calendar.getInstance();
341: calendar.setTime(leadValue
342: .getTimestamp("convertedDate"));
343:
344: if ((calendar.get(Calendar.MONTH) + 1) == quarterNumbers[0]
345: && calendar.get(Calendar.YEAR) == year) {
346: data[0] = data[0] + 1;
347: }
348: if ((calendar.get(Calendar.MONTH) + 1) == quarterNumbers[1]
349: && calendar.get(Calendar.YEAR) == year) {
350: data[1] = data[1] + 1;
351: }
352: if ((calendar.get(Calendar.MONTH) + 1) == quarterNumbers[2]
353: && calendar.get(Calendar.YEAR) == year) {
354: data[2] = data[2] + 1;
355: }
356: }
357:
358: axisProperties.setYAxisUseDollarSigns(false);
359: axisProperties.setYAxisRoundValuesToNearest(0);
360: // axisProperties.setXAxisVerticalScaleFlag(true);
361:
362: try {
363: BarChart barChart = new BarChart(new SingleDataSet(
364: data, (String[]) legendLabels
365: .toArray(new String[0]),
366: (String[]) xAxisLabels
367: .toArray(new String[0]), paints,
368: xAxisTitle, yAxisTitle), false, properties,
369: axisProperties, width, height);
370:
371: response.reset();
372: response.setContentType("image/jpeg");
373: barChart
374: .exportJPG(response.getOutputStream(), 1.0f);
375: response.getOutputStream().flush();
376: } catch (Throwable throwable) {
377: throwable.printStackTrace();
378: }
379: }
380:
381: if (request.getParameter("report").equals(
382: "forecastedForQuarter")) {
383: double data[] = new double[3];
384: Calendar cal = Calendar.getInstance();
385:
386: int month = cal.get(Calendar.MONTH) + 1;
387: int year = cal.get(Calendar.YEAR);
388: int quarterNumbers[] = CalendarUtil
389: .getQuarterMonthNumbers(month, fyStartMonth);
390:
391: ArrayList list = new ArrayList();
392: list.add(new EntityExpr("ownerId",
393: EntityOperator.EQUALS, userInfo.getPartyId()));
394: list.add(new EntityExpr("projectedCloseDate",
395: EntityOperator.LESS_THAN_EQUAL_TO,
396: new java.sql.Date(CalendarUtil
397: .getMaximumQuarterDate(
398: cal.get(Calendar.MONTH) + 1,
399: cal.get(Calendar.YEAR),
400: fyStartMonth).getTime())));
401: list.add(new EntityExpr("projectedCloseDate",
402: EntityOperator.GREATER_THAN_EQUAL_TO,
403: new java.sql.Date(CalendarUtil
404: .getMinimumQuarterDate(
405: cal.get(Calendar.MONTH) + 1,
406: cal.get(Calendar.YEAR),
407: fyStartMonth).getTime())));
408:
409: ArrayList order = new ArrayList();
410: order.add("projectedCloseDate");
411:
412: java.util.List dealList = delegator.findByAnd("Deal",
413: list, order);
414: GenericValue dealValues[] = (GenericValue[]) dealList
415: .toArray(new GenericValue[0]);
416: GenericValue dealValue = null;
417:
418: String months[] = CalendarUtil.getQuarterMonthNames(cal
419: .get(Calendar.MONTH) + 1, fyStartMonth);
420: for (int iz = 0; iz < months.length; iz++) {
421: xAxisLabels.add((String) months[iz]);
422: }
423:
424: xAxisTitle = "month";
425: yAxisTitle = "sales";
426:
427: legendLabels.add("Forecasted Sales for Quarter");
428:
429: for (int iz = 0; iz < dealValues.length; iz++) {
430: dealValue = dealValues[iz];
431: Calendar calendar = Calendar.getInstance();
432: calendar.setTime(dealValue
433: .getDate("projectedCloseDate"));
434:
435: if ((calendar.get(Calendar.MONTH) + 1) == quarterNumbers[0]
436: && calendar.get(Calendar.YEAR) == year) {
437: data[0] = data[0]
438: + dealValue.getDouble("amount")
439: .doubleValue();
440: }
441: if ((calendar.get(Calendar.MONTH) + 1) == quarterNumbers[1]
442: && calendar.get(Calendar.YEAR) == year) {
443: data[1] = data[1]
444: + dealValue.getDouble("amount")
445: .doubleValue();
446: }
447: if ((calendar.get(Calendar.MONTH) + 1) == quarterNumbers[2]
448: && calendar.get(Calendar.YEAR) == year) {
449: data[2] = data[2]
450: + dealValue.getDouble("amount")
451: .doubleValue();
452: }
453: }
454:
455: try {
456: BarChart barChart = new BarChart(new SingleDataSet(
457: data, (String[]) legendLabels
458: .toArray(new String[0]),
459: (String[]) xAxisLabels
460: .toArray(new String[0]), paints,
461: xAxisTitle, yAxisTitle), false, properties,
462: axisProperties, width, height);
463:
464: response.reset();
465: response.setContentType("image/jpeg");
466: barChart
467: .exportJPG(response.getOutputStream(), 1.0f);
468: response.getOutputStream().flush();
469: } catch (Throwable throwable) {
470: Debug.logError("error creating bar chart", module);
471: throwable.printStackTrace();
472: }
473: }
474:
475: } catch (Exception e2) {
476: Debug.logError("error creating chart", module);
477: }
478:
479: if (Debug.timingOn())
480: timer
481: .timerString(
482: "["
483: + rname
484: + "] Done rendering page, Servlet Finished",
485: module);
486: }
487:
488: /**
489: * @see javax.servlet.Servlet#destroy()
490: */
491: public void destroy() {
492: super .destroy();
493: }
494:
495: protected RequestHandler getRequestHandler() {
496: RequestHandler rh = (RequestHandler) getServletContext()
497: .getAttribute("_REQUEST_HANDLER_");
498: if (rh == null) {
499: rh = new RequestHandler();
500: rh.init(getServletContext());
501: getServletContext().setAttribute("_REQUEST_HANDLER_", rh);
502: }
503: return rh;
504: }
505:
506: public void generateChart(HttpServletRequest req,
507: HttpServletResponse res, BarChartProperties properties,
508: AxisProperties axisProperties, int width, int height,
509: SingleDataSet singleDataSet) throws ServletException,
510: IOException {
511: try {
512: BarChart barChart = new BarChart(singleDataSet, false,
513: properties, axisProperties, width, height);
514: BufferedImage bi = barChart.getBufferedImage();
515: Graphics2D graphics = barChart.getGraphics2D();
516: // graphics.scale(0.75, 0.75d);
517: //graphics.
518: barChart.exportJPG(res.getOutputStream(), 1.0f);
519: res.getOutputStream().flush();
520: } catch (Throwable throwable) {
521: throwable.printStackTrace();
522: Debug.logError("error in generateChart", module);
523: }
524: }
525:
526: protected void logRequestInfo(HttpServletRequest request) {
527: ServletContext servletContext = this .getServletContext();
528: HttpSession session = request.getSession();
529:
530: Debug.logVerbose("--- Start Request Headers: ---", module);
531: Enumeration headerNames = request.getHeaderNames();
532: while (headerNames.hasMoreElements()) {
533: String headerName = (String) headerNames.nextElement();
534: Debug.logVerbose(headerName + ":"
535: + request.getHeader(headerName), module);
536: }
537: Debug.logVerbose("--- End Request Headers: ---", module);
538:
539: Debug.logVerbose("--- Start Request Parameters: ---", module);
540: Enumeration paramNames = request.getParameterNames();
541: while (paramNames.hasMoreElements()) {
542: String paramName = (String) paramNames.nextElement();
543: Debug.logVerbose(paramName + ":"
544: + request.getParameter(paramName), module);
545: }
546: Debug.logVerbose("--- End Request Parameters: ---", module);
547:
548: Debug.logVerbose("--- Start Request Attributes: ---", module);
549: Enumeration reqNames = request.getAttributeNames();
550: while (reqNames != null && reqNames.hasMoreElements()) {
551: String attName = (String) reqNames.nextElement();
552: Debug.logVerbose(attName + ":"
553: + request.getAttribute(attName), module);
554: }
555: Debug.logVerbose("--- End Request Attributes ---", module);
556:
557: Debug.logVerbose("--- Start Session Attributes: ---", module);
558: Enumeration sesNames = null;
559: try {
560: sesNames = session.getAttributeNames();
561: } catch (IllegalStateException e) {
562: Debug.logVerbose("Cannot get session attributes : "
563: + e.getMessage(), module);
564: }
565: while (sesNames != null && sesNames.hasMoreElements()) {
566: String attName = (String) sesNames.nextElement();
567: Debug.logVerbose(attName + ":"
568: + session.getAttribute(attName), module);
569: }
570: Debug.logVerbose("--- End Session Attributes ---", module);
571:
572: Enumeration appNames = servletContext.getAttributeNames();
573: Debug.logVerbose("--- Start ServletContext Attributes: ---",
574: module);
575: while (appNames != null && appNames.hasMoreElements()) {
576: String attName = (String) appNames.nextElement();
577: Debug.logVerbose(attName + ":"
578: + servletContext.getAttribute(attName), module);
579: }
580: Debug.logVerbose("--- End ServletContext Attributes ---",
581: module);
582: }
583: }
|