001: /*
002: * (C) Copyright 2000 - 2005 Nabh Information Systems, Inc.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: */
019: package com.nabhinc.portlet.portletadmin;
020:
021: import java.io.IOException;
022: import java.util.HashMap;
023: import java.util.Hashtable;
024:
025: import javax.portlet.ActionRequest;
026: import javax.portlet.ActionResponse;
027: import javax.portlet.PortletException;
028: import javax.servlet.http.HttpServletRequest;
029: import javax.servlet.http.HttpServletResponse;
030:
031: import com.nabhinc.core.MimeTypes;
032: import com.nabhinc.portal.config.PortletType;
033: import com.nabhinc.portal.container.PortletRequestImpl;
034: import com.nabhinc.portal.container.PortletResponseImpl;
035: import com.nabhinc.portal.core.PortalServlet;
036: import com.nabhinc.portal.core.PortletConfigInfo;
037: import com.nabhinc.portlet.portletadmin.PortletUtil;
038: import com.nabhinc.portlet.base.BasePortlet;
039: import com.nabhinc.portlet.chart.BaseJDBCDataset;
040: import com.nabhinc.portlet.chart.BaseXMLDataset;
041: import com.nabhinc.portlet.chart.ChartPortlet;
042: import com.nabhinc.portlet.mvcportlet.core.ActionConfig;
043: import com.nabhinc.portlet.mvcportlet.core.ActionProcessor;
044: import com.nabhinc.portlet.mvcportlet.core.BaseRequestProcessor;
045: import com.nabhinc.util.StringUtil;
046:
047: /**
048: *
049: *
050: * @author Padmanabh Dabke
051: * (c) 2005 Nabh Information Systems, Inc. All Rights Reserved.
052: * @since 2.4.1
053: */
054: public class ChartPortletCreator extends BaseRequestProcessor implements
055: ActionProcessor {
056:
057: /* (non-Javadoc)
058: * @see com.nabhinc.portlet.mvcportlet.core.ActionProcessor#process(javax.portlet.ActionRequest, javax.portlet.ActionResponse, com.nabhinc.portlet.mvcportlet.core.ActionConfig)
059: */
060: public String process(ActionRequest request,
061: ActionResponse response, ActionConfig actionConfig)
062: throws PortletException, IOException {
063:
064: final String PORTLET_TYPE = "com.nabhinc.portlet.chart.ChartPortlet";
065:
066: final String VIEW_MODE = "view";
067: final String EDIT_MODE = "edit";
068: final String HELP_MODE = "help";
069:
070: boolean isEdit = "true".equals(request.getParameter("edit"));
071: String portletIndex = request.getParameter("portlet_index");
072: int pIndex = portletIndex == null ? -1 : Integer
073: .parseInt(portletIndex);
074: String requestType = request.getParameter("request_type");
075:
076: //HTML mime type is supported by default
077: boolean isHTMLMimeTypeSupported = true; //rReq.getParameter("html_mime_type") != null;
078: boolean isHTMLEditSupported = request
079: .getParameter("html_edit_mode") != null;
080: boolean isHTMLHelpSupported = request
081: .getParameter("html_help_mode") != null;
082: boolean isXHTMLMimeTypeSupported = true;
083: boolean isWMLMimeTypeSupported = false; // does not generate chart supported by WML
084:
085: String pName = request.getParameter("pname");
086: String title = request.getParameter("title");
087: String keywordsStr = request.getParameter("keywords");
088: String shortTitle = request.getParameter("short_title");
089: String expCache = request.getParameter("exp_cache");
090: String resourceBundleName = request
091: .getParameter("resource_bundle");
092: String supportedLocales = request
093: .getParameter("supported_locales");
094:
095: String totalSecRoles = request.getParameter("sec_roles_total");
096: String totalDescrLang = request
097: .getParameter("descr_lang_total");
098: String totalDispLang = request
099: .getParameter("display_lang_total");
100:
101: int numOfSecRoles = Integer.parseInt(totalSecRoles);
102: int numOfDescrLangs = Integer.parseInt(totalDescrLang);
103: int numOfDispLangs = Integer.parseInt(totalDispLang);
104:
105: String chartType = request.getParameter("chart_type");
106: String imageType = request.getParameter("image_type");
107: String dataType = request.getParameter("data_type");
108:
109: // required for xml data type
110: String xmlUrl = request.getParameter("xml_url");
111: String xmlPath = request.getParameter("xml_path");
112:
113: //required for JDBC type of datasource
114: String dataSource = request.getParameter("data_source");
115: String sql = request.getParameter("sql");
116:
117: String chartTitle = request.getParameter("chart_title");
118: String chartColors = request.getParameter("chart_colors");
119: String aspectRatio = request.getParameter("aspect_ratio");
120: String bgImage = request.getParameter("bg_image");
121: String xLabel = request.getParameter("x_label");
122: String yLabel = request.getParameter("y_label");
123:
124: String viewPath = request.getParameter("view_path");
125: String editPath = request.getParameter("edit_path");
126: String helpPath = request.getParameter("help_path");
127: String dataSourceClass = null;
128:
129: String error = "";
130: // Check for errors
131: if (pName == null || "".equals(pName.trim())) {
132: error += "You must provide portlet name.<br/>";
133: } else if (PortalServlet.getInstance().isPortletExists(pName)) {
134: if (!isEdit
135: || !pName.equals(((PortletConfigInfo) PortalServlet
136: .getInstance().getPortletConfigInfoList()
137: .elementAt(pIndex)).name)) {
138: error += "Duplicate portlet name.<br/>";
139: }
140: }
141: if (title == null || "".equals(title.trim())) {
142: error += "You must provide portlet title.<br/>";
143: }
144: if ("db".equals(dataType)) {
145: if (dataSource == null || sql == null
146: || "".equals(dataSource.trim())
147: || "".equals(sql.trim()))
148: error += "Data source and Data SQL are required for database data type.<br/>";
149:
150: } else {
151: if (xmlUrl == null || xmlPath == null
152: || xmlUrl.trim().equals("")
153: && xmlPath.trim().equals("")) {
154: error += "Either XML document URL or path is required for XML data type.<br/>";
155:
156: } else if (xmlUrl != null && !"".equals(xmlUrl.trim())
157: && xmlUrl.indexOf("://") == -1) {
158: error += "Invalid XML document URL. The URL should be in the form of http:// or file://<br/>";
159: }
160: }
161:
162: if (viewPath == null || "".equals(viewPath.trim())) {
163: error += "View page path must be specified. This page should define template for the chart.<br/>";
164: }
165: if (aspectRatio != null && !"".equals(aspectRatio.trim())) {
166: try {
167: Integer.parseInt(aspectRatio);
168: } catch (Exception ex) {
169: error += "Aspect ratio must be a number.<br/>";
170: }
171: }
172: if (expCache != null && !expCache.trim().equals("")) {
173: try {
174: Integer.parseInt(expCache);
175: } catch (Exception ex) {
176: error += "Expiration cache must be a number.<br/>";
177: }
178: }
179:
180: // Not supported (will be removed)
181: /*
182: if ("xml".equals(dataType)) {
183: if (chartType.equals("scatter") || chartType.equals("candlestick"))
184: error += "Currently the selected chart's type is not supported by XML data type.";
185: }
186: */
187:
188: if (!error.equals("")) {
189: response.setRenderParameter("error", error);
190: if (isEdit)
191: response.setRenderParameter("edit", "true");
192: return "failure";
193: }
194:
195: PortletType pType = PortletUtil.createPortletType(pName,
196: PORTLET_TYPE);
197: PortletUtil.setTitle(title, pType);
198: PortletUtil.setShortTitle(shortTitle, pType);
199: PortletUtil.setResourceBundle(resourceBundleName, pType);
200: PortletUtil.setKeywords(keywordsStr, pType);
201:
202: HashMap descrMap = new HashMap();
203: for (int i = 0; i < numOfDescrLangs; i++) {
204: String lang = request.getParameter("descr_lang" + i);
205: String descr = request.getParameter("descr" + i);
206: if (descrMap.containsKey(lang))
207: continue;
208: descrMap.put(lang, descr);
209: }
210: PortletUtil.setDescription(descrMap, pType);
211:
212: HashMap displayMap = new HashMap();
213: for (int i = 0; i < numOfDispLangs; i++) {
214: String lang = request.getParameter("display_lang" + i);
215: String displayName = request.getParameter("display_name"
216: + i);
217: if (displayMap.containsKey(lang))
218: continue;
219: displayMap.put(lang, displayName);
220: }
221: PortletUtil.setDisplayName(displayMap, pType);
222:
223: if (expCache != null && !expCache.trim().equals(""))
224: PortletUtil.setExpirationCache(Integer.parseInt(expCache),
225: pType);
226:
227: Hashtable initParams = new Hashtable();
228:
229: // Determine data source class
230: if ("db".equals(dataType)) {
231: if (chartType.startsWith("pie")) {
232: dataSourceClass = "com.nabhinc.portlet.chart.JDBCPieDataset";
233: } else if (chartType.equals("line")
234: || chartType.indexOf("-bar") != -1) {
235: dataSourceClass = "com.nabhinc.portlet.chart.JDBCCategoryDataset";
236: } else if (chartType.equals("candlestick")) {
237: dataSourceClass = "com.nabhinc.portlet.chart.JDBCHighLowDataset";
238: } else {
239: dataSourceClass = "org.jfree.data.JDBCXYDataSet";
240: }
241:
242: initParams.put(BaseJDBCDataset.DATA_SOURCE_INIT_PARAM,
243: dataSource);
244: initParams.put(BaseJDBCDataset.SQL_INIT_PARAM, sql);
245:
246: } else {
247: if (chartType.startsWith("pie")) {
248: dataSourceClass = "com.nabhinc.portlet.chart.XMLPieDataset";
249: } else if (chartType.equals("line")
250: || chartType.indexOf("-bar") != -1) {
251: dataSourceClass = "com.nabhinc.portlet.chart.XMLCategoryDataset";
252: } else if (chartType.equals("candlestick")) {
253: // Not implemented yet
254: dataSourceClass = "com.nabhinc.portlet.chart.XMLHighLowDataset";
255: } else {
256: // Not implemented yet
257: dataSourceClass = "com.nabhinc.portlet.chart.XMLXYDataSet";
258: }
259:
260: if (xmlUrl != null && !xmlUrl.trim().equals("")) {
261: initParams.put(BaseXMLDataset.XML_DOC_URL_INIT_PARAM,
262: xmlUrl);
263: } else {
264: if (!xmlPath.startsWith("/")) {
265: xmlPath = "/" + xmlPath;
266: }
267: initParams
268: .put(
269: BaseXMLDataset.XML_DOC_RELATIVE_PATH_INIT_PARAM,
270: xmlPath);
271: }
272: }
273:
274: initParams.put(ChartPortlet.CHART_TYPE, chartType);
275: initParams.put(ChartPortlet.IMAGE_TYPE, imageType);
276: initParams.put(ChartPortlet.DATA_SOURCE_CLASS, dataSourceClass);
277: addInitParameter(initParams, ChartPortlet.CHART_TITLE,
278: chartTitle);
279: addInitParameter(initParams, ChartPortlet.CHART_COLORS,
280: chartColors);
281: addInitParameter(initParams, ChartPortlet.CHART_ASPECT_RATIO,
282: aspectRatio);
283: addInitParameter(initParams, ChartPortlet.BG_IMAGE_URL, bgImage);
284: addInitParameter(initParams, ChartPortlet.X_AXIS_TITLE, xLabel);
285: addInitParameter(initParams, ChartPortlet.Y_AXIS_TITLE, yLabel);
286:
287: if (viewPath.indexOf("://") == -1 && !viewPath.startsWith("/")) {
288: viewPath = "/" + viewPath;
289: }
290: initParams.put(BasePortlet.CONTENT_JSP_PARAM, viewPath);
291:
292: if (editPath != null && !editPath.trim().equals("")) {
293: if (editPath.indexOf("://") == -1
294: && !editPath.startsWith("/")) {
295: editPath = "/" + editPath;
296: }
297: initParams.put(BasePortlet.EDIT_JSP_PARAM, editPath);
298: isHTMLEditSupported = true;
299: }
300:
301: if (helpPath != null && !helpPath.trim().equals("")) {
302: if (helpPath.indexOf("://") == -1
303: && !helpPath.startsWith("/")) {
304: helpPath = "/" + helpPath;
305: }
306: initParams.put(BasePortlet.HELP_JSP_PARAM, helpPath);
307: isHTMLHelpSupported = true;
308: }
309:
310: PortletUtil.setInitParams(initParams, pType);
311:
312: if (isHTMLMimeTypeSupported) {
313: String[] supportedModes = null;
314: if (isHTMLEditSupported && isHTMLHelpSupported) {
315: supportedModes = new String[] { EDIT_MODE, HELP_MODE };
316:
317: } else if (isHTMLEditSupported) {
318: supportedModes = new String[] { EDIT_MODE };
319:
320: } else if (isHTMLHelpSupported) {
321: supportedModes = new String[] { HELP_MODE };
322:
323: }
324:
325: PortletUtil.setSupports(supportedModes, MimeTypes.HTML,
326: pType);
327: }
328:
329: if (isXHTMLMimeTypeSupported) {
330: String[] supportedModes = new String[0];
331: PortletUtil.setSupports(supportedModes, MimeTypes.XHTML_MP,
332: pType);
333: }
334:
335: if (isWMLMimeTypeSupported) {
336: String[] supportedModes = new String[0];
337: PortletUtil.setSupports(supportedModes, MimeTypes.WML,
338: pType);
339: }
340:
341: Hashtable prefMap = new Hashtable();
342: PortletUtil.setPreferences(prefMap, pType);
343:
344: if (supportedLocales != null
345: && !"".equals(supportedLocales.trim())) {
346: String[] locales = StringUtil.split(supportedLocales, ",");
347: PortletUtil.setSupportedLocales(locales, pType);
348: }
349:
350: HashMap secRoleMap = new HashMap();
351: for (int i = 0; i < numOfSecRoles; i++) {
352: String roleName = request.getParameter("role_name" + i);
353: if (roleName != null && !"".equals(roleName.trim())) {
354: secRoleMap.put(roleName, request
355: .getParameter("role_link" + i));
356: }
357: }
358: PortletUtil.setSecurityRoleReference(secRoleMap, pType);
359:
360: try {
361: if (isEdit) {
362: HttpServletRequest req = ((PortletRequestImpl) request)
363: .getHttpServletRequest();
364: HttpServletResponse res = ((PortletResponseImpl) response)
365: .getHttpServletResponse();
366: PortalServlet.getInstance().replacePortlet(pType,
367: pIndex, req, res);
368: } else {
369: PortalServlet.getInstance().addPortlet(pType);
370: }
371: PortalServlet.getInstance().savePortletConfiguration();
372:
373: } catch (Exception ex) {
374: throw new PortletException(
375: "Failed to create Chart portlet.", ex);
376: }
377: return "success";
378: }
379:
380: private void addInitParameter(Hashtable table, String paramName,
381: String paramValue) {
382: if (paramValue != null) {
383: paramValue = paramValue.trim();
384: if (!paramValue.equals("")) {
385: table.put(paramName, paramValue);
386: }
387: }
388: }
389:
390: }
|