001: /*********************************************************************************
002: * The contents of this file are subject to the OpenI Public License Version 1.0
003: * ("License"); You may not use this file except in compliance with the
004: * License. You may obtain a copy of the License at
005: * http://www.openi.org/docs/LICENSE.txt
006: *
007: * Software distributed under the License is distributed on an "AS IS" basis,
008: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009: * the specific language governing rights and limitations under the License.
010: *
011: * The Original Code is: OpenI Open Source
012: *
013: * The Initial Developer of the Original Code is Loyalty Matrix, Inc.
014: * Portions created by Loyalty Matrix, Inc. are
015: * Copyright (C) 2005 Loyalty Matrix, Inc.; All Rights Reserved.
016: *
017: * Contributor(s): ______________________________________.
018: *
019: ********************************************************************************/package org.openi.web.controller.analysis;
020:
021: import java.io.File;
022: import java.util.HashMap;
023: import java.util.List;
024: import java.util.Map;
025:
026: import javax.jms.JMSException;
027: import javax.jms.Message;
028: import javax.jms.Session;
029: import javax.servlet.http.HttpServletRequest;
030: import javax.servlet.http.HttpServletResponse;
031: import javax.servlet.http.HttpSession;
032: import javax.servlet.jsp.JspException;
033:
034: import org.apache.log4j.Logger;
035: import org.openi.analysis.Analysis;
036: import org.openi.analysis.Datasource;
037: import org.openi.application.Application;
038: import org.openi.chart.EnhancedChartComponent;
039: import org.openi.chart.EnhancedChartTag;
040: import org.openi.jms.helper.JmsManager;
041: import org.openi.menu.ToolbarState;
042: import org.openi.olap.drillthrough.DrillthroughMessage;
043: import org.openi.project.ProjectContext;
044: import org.openi.xmla.XMLAQueryTag;
045: import org.springframework.jms.core.JmsTemplate;
046: import org.springframework.jms.core.MessageCreator;
047: import org.springframework.web.servlet.ModelAndView;
048: import org.springframework.web.servlet.mvc.AbstractController;
049:
050: import com.tonbeller.wcf.controller.RequestContext;
051: import com.tonbeller.wcf.table.EditableTableComponent;
052:
053: /**
054: * @author Uddhab Pant <br>
055: *
056: * Controller to handle analysis request. It does following tasks:
057: * <ul>
058: * <li> Restores analysis when analysis link is clicked.
059: * <li> Retrieves datasource.
060: * <li> Creates and configures query.
061: * <li> Creates and customizes chart.
062: * </ul>
063: *
064: */
065: public class AnalysisController extends AbstractController {
066: private static Logger logger = Logger
067: .getLogger(AnalysisController.class);
068: private HttpSession session = null;
069: private Analysis analysis = null;
070: private ProjectContext projectContext = null;
071:
072: //Spring JmsTemplate initialized by Spring IoC. Needed to send jms message to the destination 'dtRequestQueue'.
073: private JmsTemplate dtRequestQueueTemplate;
074: //needed to start listener
075: private JmsManager jmsManager;
076:
077: public JmsTemplate getDtRequestQueueTemplate() {
078: return dtRequestQueueTemplate;
079: }
080:
081: public void setDtRequestQueueTemplate(
082: JmsTemplate dtRequestQueueTemplate) {
083: this .dtRequestQueueTemplate = dtRequestQueueTemplate;
084: }
085:
086: public JmsManager getJmsManager() {
087: return jmsManager;
088: }
089:
090: public void setJmsManager(JmsManager jmsManager) {
091: this .jmsManager = jmsManager;
092: }
093:
094: /**
095: *
096: * @param request HttpServletRequest
097: * @param response HttpServletResponse
098: * @return ModelAndView
099: * @throws Exception
100: */
101: protected ModelAndView handleRequestInternal(
102: HttpServletRequest request, HttpServletResponse response)
103: throws Exception {
104: Map model;
105: String analysisConfigName = null;
106: Datasource datasource = null;
107:
108: session = request.getSession();
109: // get project context from session
110: projectContext = (ProjectContext) session
111: .getAttribute("projectContext");
112:
113: //wcf toolbar requires reference bean in session to set button visibility
114: ToolbarState toolbarState = (ToolbarState) session
115: .getAttribute("toolbarState");
116: if (toolbarState == null) {
117: toolbarState = new ToolbarState();
118: session.setAttribute("toolbarState", toolbarState);
119: }
120:
121: ////
122: try {
123: // setting attribute to request. This attribute is used to check whether
124: // current view is analysis page or not.
125: request.setAttribute("analysisPage", "true");
126:
127: // analysis name
128: analysisConfigName = request.getParameter("config");
129:
130: model = new HashMap();
131:
132: // when clicked on analyses link
133: if (request.getParameter("config") != null) {
134:
135: //checks whether analysis is viewable or not
136: // should be:
137: // * new analsysis
138: // * current user analysis
139: // * public analysis
140: // or user should be :
141: // * app admin
142: //
143: // otherwise not allowed to look at
144: // also check whether module path is allowed or not
145: if (!"newanalysis".equalsIgnoreCase(analysisConfigName)
146: && !projectContext.isAppAdminUser()
147: && !((projectContext
148: .isPathBeneathUserDir(analysisConfigName) || projectContext
149: .isPathBeneathPublicDir(analysisConfigName)) && projectContext
150: .isPathAllowed(analysisConfigName))) {
151: response.sendError(
152: HttpServletResponse.SC_FORBIDDEN,
153: "access denied");
154: return null;
155:
156: }
157:
158: // store analysis config in session
159:
160: session.setAttribute("analysisConfigName",
161: analysisConfigName);
162:
163: // remove jPivot and wcf objects from session
164: removeSessionObjects();
165:
166: // restore analysis from file
167: if (!"newanalysis".equalsIgnoreCase(analysisConfigName)) {
168: analysis = projectContext
169: .restoreAnalysis(analysisConfigName);
170: session.setAttribute("analysis01", analysis);
171: } else {
172: analysis = (Analysis) session
173: .getAttribute("analysis01");
174: }
175:
176: // get datasource of the analysis.
177: datasource = projectContext.getDatasource(analysis
178: .getDataSourceName());
179:
180: // Query object
181: XMLAQueryTag query = new XMLAQueryTag();
182:
183: // set query properties
184: query.setCatalog(datasource.getCatalog());
185: query.setMdxQuery(analysis.getMdxQuery());
186: query.setUri(datasource.getServer());
187: query.setId("query01");
188:
189: // if basic authentication is enabled, set username and password to query.
190: if (Application.getInstance().isBasicAuthentication()) {
191: query.setUser(request.getUserPrincipal().getName());
192: query.setPassword((String) session
193: .getAttribute("user.credentials"));
194: } else {
195: query.setUser("");
196: query.setPassword("");
197: }
198:
199: // initialize query object. this also store query object in session.
200: query.init(RequestContext.instance());
201:
202: // create object of enhanced chart tag/
203: EnhancedChartTag chartTag = new EnhancedChartTag();
204:
205: // set query to chart tag.
206: chartTag.setQuery("query01");
207:
208: // create enhanced chart component from chart tag object
209: EnhancedChartComponent chart = (EnhancedChartComponent) chartTag
210: .createComponent(RequestContext.instance());
211: chart.initialize(RequestContext.instance());
212:
213: this .setChartSize(chart);
214: this .translateChart(chart);// translate chart to wcf chart component
215:
216: session.setAttribute("chart01", chart);
217:
218: } else {
219: if (session.getAttribute("query01.drillthroughtable") != null
220: && ((EditableTableComponent) session
221: .getAttribute("query01.drillthroughtable"))
222: .isVisible()) {
223:
224: if ("An error occured"
225: .equalsIgnoreCase(((EditableTableComponent) session
226: .getAttribute("query01.drillthroughtable"))
227: .getModel().getColumnTitle(0))) {
228:
229: model.put("hideDownloadLink", Boolean.TRUE);
230: }
231:
232: request.setAttribute("drillthrough", Boolean.TRUE);
233:
234: }
235:
236: }
237:
238: if (request.getParameter("toolbar02.drillThrough01.x") != null) {
239: request.setAttribute("drillButtonClicked", "true");
240: }
241:
242: //send drillthrough if requested
243: if (request.getAttribute("drillthroughRequestMessage") != null) {
244: DrillthroughMessage message = (DrillthroughMessage) request
245: .getAttribute("drillthroughRequestMessage");
246: sendDrillthroughRequest(message);
247: String msg = projectContext
248: .getResourceString("java_AnalysisController.drillthroughMessage")
249: + new File(message.getOutFile()).getName();
250: model.put("message", msg);
251: } else {
252: //for backward compatibility
253: model.put("message", request.getParameter("message"));
254: }
255: // setup toolbar visibility state
256: analysisConfigName = (String) session
257: .getAttribute("analysisConfigName");
258: setupToolbarState(toolbarState, analysisConfigName);
259:
260: return new ModelAndView("analysisView", "model", model);
261: } catch (Exception e) {
262: logger.error("Exception:", e);
263: throw e;
264: }
265: }
266:
267: /**
268: * manages the toolbar button's visibility and link based on permission
269: * @param toolbarState
270: * @param path
271: * @throws Exception
272: */
273: private void setupToolbarState(ToolbarState toolbarState,
274: String path) throws Exception {
275:
276: boolean privateAnalysis = projectContext
277: .isPathBeneathUserDir(path);
278: boolean newAnalysis = "newanalysis".equals(path);
279: boolean adminUser = projectContext.isAppAdminUser();
280:
281: boolean deleteAllowed = adminUser
282: || projectContext.checkPermission(
283: "/deleteanalysis.htm*", null);
284: boolean createNewAllowed = adminUser
285: || projectContext.checkPermission("/newanalysis.htm*",
286: null);
287:
288: Map param = new HashMap();
289: param.put("saveOnly", "1");
290: boolean savePublicAllowed = adminUser
291: || projectContext.checkPermission("/saveanalysis.htm*",
292: param);
293:
294: boolean saveAsPublicAllowed = adminUser
295: || projectContext.checkPermission("/saveanalysis.htm*",
296: null);
297:
298: toolbarState.getNewButton().setVisible(createNewAllowed);
299: //create new and change ds uses same priviledge
300: toolbarState.getChangeDatasourceButton().setVisible(
301: createNewAllowed);
302:
303: toolbarState.getDeleteButton().setVisible(true);
304: toolbarState.getDeleteButton().setHref(
305: "deleteanalysis.htm?config=" + path);
306:
307: toolbarState.getSaveButton().setVisible(true);
308: toolbarState.getSaveButton().setHref(
309: "saveanalysis.htm?saveOnly=true");
310:
311: toolbarState.getSaveAsButton().setVisible(true);
312: toolbarState.getSaveAsButton().setHref("saveanalysis.htm");
313:
314: if (!deleteAllowed) {
315: if (privateAnalysis) {
316: toolbarState.getDeleteButton().setHref(
317: "deleteprivateanalysis.htm?config=" + path);
318: } else {
319: toolbarState.getDeleteButton().setVisible(false);
320: }
321: }
322:
323: if (!savePublicAllowed) {
324: if (privateAnalysis) {
325: toolbarState.getSaveButton().setHref(
326: "saveprivateanalysis.htm?saveOnly=true");
327: } else {
328: toolbarState.getSaveButton().setVisible(false);
329: }
330: }
331:
332: if (!saveAsPublicAllowed) {
333: toolbarState.getSaveAsButton().setHref(
334: "saveprivateanalysis.htm");
335: }
336: //TODO: add for mdx edit, sql edit too
337: //toolbarState.getSqlEditButton().setVisible(true);
338: //toolbarState.getMdxEditButton().setVisible(true);
339: //see tree_navigation_analysis.jsp for sqlEdit visibility check
340: //due to dependencies on wcf render we can not control that here
341: //do not show save/delete button for unsaved analysis
342: if (newAnalysis) {
343: toolbarState.getSaveButton().setVisible(false);
344: toolbarState.getDeleteButton().setVisible(false);
345: }
346: if (!projectContext.isAppAdminUser()
347: && Application.getInstance()
348: .isShowButtonsForAdminsOnly()) {
349: toolbarState.setShowButtons(false);
350: } else {
351: toolbarState.setShowButtons(true);
352: }
353: }
354:
355: private void sendDrillthroughRequest(
356: final DrillthroughMessage message) throws Exception {
357:
358: if (jmsManager == null) {
359: throw new JspException("JMS manager has not been set");
360: }
361: if (!jmsManager.isInitialized())
362: jmsManager.connectListeners();
363:
364: dtRequestQueueTemplate.send(new MessageCreator() {
365: public Message createMessage(Session session)
366: throws JMSException {
367: logger.debug("Sending drillthrough request");
368: return session.createObjectMessage(message);
369: }
370: });
371:
372: }
373:
374: private void setChartSize(EnhancedChartComponent chart) {
375: if (analysis.isUseChartSize()) {
376: chart.setChartHeight(analysis.getChartHeight());
377: chart.setChartWidth(analysis.getChartWidth());
378:
379: // otherwise set chart size based on screen size.
380: } else {
381: // set chart height and width as per client window height and width.
382: if (session.getAttribute("clientWindowWidth") != null) {
383: chart
384: .setChartWidth(Integer.parseInt(session
385: .getAttribute("clientWindowWidth")
386: .toString()) - 250);
387: }
388:
389: if (session.getAttribute("clientWindowHeight") != null) {
390: chart
391: .setChartHeight((Integer.parseInt(session
392: .getAttribute("clientWindowHeight")
393: .toString()) / 2) + 150);
394: }
395: }
396: }
397:
398: private void translateChart(EnhancedChartComponent chart) {
399: // use persisted chart size is set to true, set chart size from restored values.
400:
401: // set color palette
402: List palette = (List) projectContext.getProject()
403: .getColorPalette(
404: projectContext.getProject()
405: .getDefaultPaletteName());
406: chart.setColorPalette(palette);
407:
408: chart.setShowPareto(analysis.getShowPareto());
409: chart.setForegroundAlpha(analysis.getForegroundAlpha());
410:
411: chart.setChartTitle(analysis.getChartTitle());
412: chart.setChartType(analysis.getChartType());
413: chart.setFontName(analysis.getFontName());
414: chart.setFontStyle(analysis.getFontStyle());
415: chart.setFontSize(analysis.getFontSize());
416:
417: //legend
418: chart.setShowLegend(analysis.isShowLegend());
419:
420: //if legend is visible, set properties
421: if (analysis.isShowLegend() == true) {
422: chart.setLegendFontName(analysis.getLegendFontName());
423: chart.setLegendFontStyle(analysis.getLegendFontStyle());
424: chart.setLegendFontSize(analysis.getLegendFontSize());
425: chart.setLegendPosition(analysis.getLegendPosition());
426: }
427:
428: //slicer
429: chart.setShowSlicer(analysis.isShowSlicer());
430:
431: //if slicer is visible, set properties
432: if (analysis.isShowSlicer() == true) {
433: chart.setSlicerPosition(analysis.getSlicerPosition());
434: chart.setSlicerAlignment(analysis.getSlicerAlignment());
435: chart.setSlicerFontName(analysis.getSlicerFontName());
436: chart.setSlicerFontStyle(analysis.getSlicerFontStyle());
437: chart.setSlicerFontSize(analysis.getSlicerFontSize());
438: }
439:
440: //axes
441: chart.setAxisFontName(analysis.getAxisFontName());
442: chart.setAxisFontStyle(analysis.getAxisFontStyle());
443: chart.setAxisFontSize(analysis.getAxisFontSize());
444: chart.setHorizAxisLabel(analysis.getHorizAxisLabel());
445: chart.setVertAxisLabel(analysis.getVertAxisLabel());
446: chart.setAxisTickFontName(analysis.getAxisTickFontName());
447: chart.setAxisTickFontStyle(analysis.getAxisTickFontStyle());
448: chart.setAxisTickFontSize(analysis.getAxisTickFontSize());
449:
450: chart.setDrillThroughEnabled(analysis.isDrillThroughEnabled());
451: chart.setTickLabelRotate(analysis.getTickLabelRotate());
452:
453: chart.setUseChartSize(analysis.isUseChartSize());
454:
455: //set chart visible status
456: chart.setVisible(analysis.isShowChart());
457:
458: // background color
459: chart.setBgColorB(analysis.getBgColorB());
460: chart.setBgColorG(analysis.getBgColorG());
461: chart.setBgColorR(analysis.getBgColorR());
462:
463: chart.setWriteImageMap(projectContext.getProject()
464: .getWriteImageMap());
465: }
466:
467: /**
468: * Removes jPovt and WCF objects from session
469: *
470: */
471: private void removeSessionObjects() {
472: //remove following objects from session.
473: if (session.getAttribute("query01") != null) {
474: session.removeAttribute("query01");
475: }
476:
477: if (session.getAttribute("table01") != null) {
478: session.removeAttribute("table01");
479: }
480:
481: if (session.getAttribute("minichartform01") != null) {
482: session.removeAttribute("minichartform01");
483: }
484:
485: if (session.getAttribute("mdxedit01") != null) {
486: session.removeAttribute("mdxedit01");
487: }
488:
489: if (session.getAttribute("navi01") != null) {
490: session.removeAttribute("navi01");
491: }
492:
493: if (session.getAttribute("print01") != null) {
494: session.removeAttribute("print01");
495: }
496:
497: if (session.getAttribute("sortform01") != null) {
498: session.removeAttribute("sortform01");
499: }
500:
501: if (session.getAttribute("printform01") != null) {
502: session.removeAttribute("printform01");
503: }
504:
505: if (session.getAttribute("chartform01") != null) {
506: session.removeAttribute("chartform01");
507: }
508:
509: if (session.getAttribute("query01.drillthroughtable") != null) {
510: session.removeAttribute("query01.drillthroughtable");
511: }
512: }
513: }
|