001: /*
002: * (C) Copyright 2000 - 2003 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:
020: package com.nabhinc.portlet.feed;
021:
022: import java.io.IOException;
023:
024: import javax.portlet.ActionRequest;
025: import javax.portlet.ActionResponse;
026: import javax.portlet.PortletConfig;
027: import javax.portlet.PortletException;
028: import javax.portlet.PortletMode;
029: import javax.portlet.PortletModeException;
030: import javax.portlet.PortletSecurityException;
031: import javax.portlet.RenderRequest;
032: import javax.portlet.RenderResponse;
033:
034: import com.nabhinc.portal.api.EntityLockedException;
035: import com.nabhinc.portal.api.PortalInformationStoreLocator;
036: import com.nabhinc.portal.container.ActionRequestImpl;
037: import com.nabhinc.portal.container.PortalInterface;
038: import com.nabhinc.portal.container.RenderRequestImpl;
039: import com.nabhinc.portal.core.PortalConstants;
040: import com.nabhinc.portal.model.PortalApplication;
041: import com.nabhinc.portal.model.PortalApplicationView;
042: import com.nabhinc.portlet.base.BasePortlet;
043: import com.nabhinc.portlet.common.StatefulPortlet;
044: import com.nabhinc.util.StringUtil;
045: import com.nabhinc.ws.core.WebServiceSecurityException;
046: import com.nabhinc.ws.service.feedcacher.FeedCacherServiceLocator;
047: import com.sun.syndication.feed.synd.SyndFeed;
048: import com.sun.syndication.io.FeedException;
049:
050: /**
051: *
052: *
053: * @author Padmanabh Dabke
054: * (c) 2003 Nabh Information Systems, Inc. All Rights Reserved.
055: */
056: public class FeedPortlet extends BasePortlet implements StatefulPortlet {
057: public static final String FEED_CONFIG_ATTRIBUTE = "sb.feed.config";
058: public static final String FEED_DATA_ATTRIBUTE = "sb.feed.data";
059: public static final String FEED_DEFAULT_URL_ATTRIBUTE = "sb.feed.default_url";
060: public static final String ERROR_ATTRIB = "sb.feed.error";
061: private String fpDefaultFeed = "http://www.nabh.com/portlets/news/SiteNews/rss.xml";
062:
063: public void init(PortletConfig config) throws PortletException {
064: super .init(config);
065: String temp = config.getInitParameter("defaultFeed");
066: if (StringUtil.isNotNullOrEmpty(temp))
067: fpDefaultFeed = temp;
068: }
069:
070: public void render(RenderRequest request, RenderResponse response)
071: throws PortletException, java.io.IOException {
072: String pMode = request.getPortletMode().toString()
073: .toLowerCase();
074: if (pMode.equals("view"))
075: doView(request, response);
076: else if (pMode.equals("config"))
077: doConfig(request, response);
078: else if (pMode.equals("help"))
079: doHelp(request, response);
080: else
081: throw new PortletException("Unsupported portlet mode: "
082: + pMode);
083: }
084:
085: /**
086: * Displays portlet content configured via "content" parameter.
087: * The default implementation throws an exception.
088: * @param request The portlet request.
089: * @param response The render response.
090: * @exception PortletException If the portlet cannot fulfilling the request.
091: * @exception IOException If the streaming causes an I/O problem
092: */
093: public void doView(RenderRequest request, RenderResponse response)
094: throws PortletException, java.io.IOException {
095: try {
096: PortalInterface pi = ((RenderRequestImpl) request)
097: .getPortalInterface();
098: FeedConfig feedConf = (FeedConfig) pi
099: .getPortletWindowConfig();
100: String feedUrl = null;
101: if (feedConf != null) {
102: feedUrl = feedConf.getFeedURL();
103: if (feedConf.getTitle() != null)
104: response.setTitle(feedConf.getTitle());
105: request.setAttribute(FEED_CONFIG_ATTRIBUTE, feedConf);
106: } else {
107: feedUrl = fpDefaultFeed;
108: request.setAttribute(FEED_DEFAULT_URL_ATTRIBUTE,
109: feedUrl);
110: }
111: try {
112: SyndFeed feed = FeedCacherServiceLocator.getService()
113: .getFeed(feedUrl);
114: if (feed.getTitle() != null)
115: response.setTitle(feed.getTitle());
116: request.setAttribute(FEED_DATA_ATTRIBUTE, feed);
117: } catch (FeedException e) {
118: request.setAttribute(ERROR_ATTRIB, e.getMessage());
119: }
120:
121: super .doView(request, response);
122: } finally {
123: request.removeAttribute(FEED_DATA_ATTRIBUTE);
124: request.removeAttribute(FEED_CONFIG_ATTRIBUTE);
125: }
126: }
127:
128: /**
129: * Helper method to serve up the <code>edit</code> mode.
130: * The default implementation throws an exception.
131: * @param request The portlet request
132: * @param response The render response
133: * @exception PortletException If the portlet cannot fulfilling the request
134: * @exception IOException If the streaming causes an I/O problem
135: */
136: public void doConfig(RenderRequest request, RenderResponse response)
137: throws PortletException, java.io.IOException {
138: try {
139: PortalInterface pi = ((RenderRequestImpl) request)
140: .getPortalInterface();
141: FeedConfig feedConf = (FeedConfig) pi
142: .getPortletWindowConfig();
143: if (feedConf != null) {
144: request.setAttribute(FEED_CONFIG_ATTRIBUTE, feedConf);
145: try {
146: SyndFeed feed = FeedCacherServiceLocator
147: .getService()
148: .getFeed(feedConf.getFeedURL());
149: if (feed.getTitle() != null)
150: response.setTitle(feed.getTitle());
151: } catch (Exception e) {
152: // Ignore exceptions since we want the user to reset the URL.
153: }
154: } else {
155: request.setAttribute(FEED_DEFAULT_URL_ATTRIBUTE,
156: fpDefaultFeed);
157:
158: }
159: super .doConfig(request, response);
160: } finally {
161: request.removeAttribute(FEED_CONFIG_ATTRIBUTE);
162: }
163: }
164:
165: public void processAction(ActionRequest request,
166: ActionResponse response) throws PortletException,
167: IOException {
168:
169: if (request.getParameter("cancel") != null) {
170: try {
171: response.setPortletMode(PortletMode.VIEW);
172: } catch (PortletModeException e) {
173: // Ignore. we are supporting view mode
174: e.printStackTrace();
175: }
176: return;
177: }
178: String feedURL = request.getParameter("feed_url");
179: if (StringUtil.isNullOrEmpty(feedURL)) {
180: response.setRenderParameter("error",
181: "You must provide a feed URL.");
182: return;
183: }
184: String maxHeadlineStr = request.getParameter("max_headlines");
185: int maxHeadlines = 5;
186: if (maxHeadlineStr != null) {
187: try {
188: maxHeadlines = Integer.parseInt(maxHeadlineStr);
189: if (maxHeadlines <= 0) {
190: response
191: .setRenderParameter("error",
192: "Maximum headlines must be a positive number.");
193: return;
194: }
195: } catch (Exception e) {
196: response.setRenderParameter("error",
197: "Maximum headlines must be a positive number.");
198: return;
199: }
200: }
201: PortalApplication portalApp = ((PortalApplicationView) request
202: .getAttribute(PortalConstants.CURRENT_PORTAL_APP_VIEW))
203: .getPortalApplication();
204: synchronized (portalApp) {
205: PortalInterface pi = ((ActionRequestImpl) request)
206: .getPortalInterface();
207: FeedConfig feedConf = (FeedConfig) pi
208: .getPortletWindowConfig();
209: if (feedConf == null) {
210: feedConf = new FeedConfig();
211: pi.setPortletWindowConfig(feedConf);
212: }
213: String title = request.getParameter("title");
214: if (StringUtil.isNullOrEmpty(title))
215: title = null;
216: feedConf.setFeedURL(feedURL.trim());
217: feedConf.setTitle(title);
218: feedConf.setMaxItems(maxHeadlines);
219: try {
220: PortalInformationStoreLocator
221: .getPortalInformationStore()
222: .savePortalApplication(portalApp, true);
223: } catch (EntityLockedException e) {
224: throw new PortletException(
225: "You changes could not be persisted since the psite is locked by another user.");
226: } catch (WebServiceSecurityException e) {
227: throw new PortletSecurityException(e);
228: }
229: }
230: response.setPortletMode(PortletMode.VIEW);
231: }
232:
233: }
|