001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.util.bridges.bsf;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.FileUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.StringUtil;
023    
024    import java.io.IOException;
025    import java.io.InputStream;
026    
027    import java.util.Map;
028    
029    import javax.portlet.ActionRequest;
030    import javax.portlet.ActionResponse;
031    import javax.portlet.GenericPortlet;
032    import javax.portlet.PortletConfig;
033    import javax.portlet.PortletContext;
034    import javax.portlet.PortletException;
035    import javax.portlet.PortletPreferences;
036    import javax.portlet.PortletRequest;
037    import javax.portlet.PortletResponse;
038    import javax.portlet.RenderRequest;
039    import javax.portlet.RenderResponse;
040    import javax.portlet.ResourceRequest;
041    import javax.portlet.ResourceResponse;
042    
043    import org.apache.bsf.BSFException;
044    import org.apache.bsf.BSFManager;
045    
046    /**
047     * @author Jorge Ferrer
048     * @author Brian Wing Shun Chan
049     */
050    public abstract class BaseBSFPortlet extends GenericPortlet {
051    
052            @Override
053            public void init() {
054                    editFile = getInitParameter("edit-file");
055                    helpFile = getInitParameter("help-file");
056                    viewFile = getInitParameter("view-file");
057                    actionFile = getInitParameter("action-file");
058                    resourceFile = getInitParameter("resource-file");
059                    globalFiles = StringUtil.split(getInitParameter("global-files"));
060    
061                    BSFManager.registerScriptingEngine(
062                            getScriptingEngineLanguage(), getScriptingEngineClassName(),
063                            new String[] {getScriptingEngineExtension()});
064    
065                    bsfManager = new BSFManager();
066            }
067    
068            @Override
069            public void doDispatch(
070                            RenderRequest renderRequest, RenderResponse renderResponse)
071                    throws IOException, PortletException {
072    
073                    String file = renderRequest.getParameter(getFileParam());
074    
075                    if (file != null) {
076                            include(file, renderRequest, renderResponse);
077                    }
078                    else {
079                            super.doDispatch(renderRequest, renderResponse);
080                    }
081            }
082    
083            @Override
084            public void doEdit(
085                            RenderRequest renderRequest, RenderResponse renderResponse)
086                    throws IOException, PortletException {
087    
088                    if (renderRequest.getPreferences() == null) {
089                            super.doEdit(renderRequest, renderResponse);
090                    }
091                    else {
092                            include(editFile, renderRequest, renderResponse);
093                    }
094            }
095    
096            @Override
097            public void doHelp(
098                            RenderRequest renderRequest, RenderResponse renderResponse)
099                    throws IOException {
100    
101                    include(helpFile, renderRequest, renderResponse);
102            }
103    
104            @Override
105            public void doView(
106                            RenderRequest renderRequest, RenderResponse renderResponse)
107                    throws IOException {
108    
109                    include(viewFile, renderRequest, renderResponse);
110            }
111    
112            @Override
113            public void processAction(
114                            ActionRequest actionRequest, ActionResponse actionResponse)
115                    throws IOException {
116    
117                    include(actionFile, actionRequest, actionResponse);
118            }
119    
120            @Override
121            public void serveResource(
122                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
123                    throws IOException {
124    
125                    include(resourceFile, resourceRequest, resourceResponse);
126            }
127    
128            protected void declareBeans(
129                            InputStream is, PortletRequest portletRequest,
130                            PortletResponse portletResponse)
131                    throws BSFException, IOException {
132    
133                    declareBeans(
134                            new String(FileUtil.getBytes(is)), portletRequest, portletResponse);
135            }
136    
137            protected void declareBeans(
138                            String code, PortletRequest portletRequest,
139                            PortletResponse portletResponse)
140                    throws BSFException, IOException {
141    
142                    String script = getGlobalScript().concat(code);
143    
144                    PortletConfig portletConfig = getPortletConfig();
145                    PortletContext portletContext = getPortletContext();
146                    PortletPreferences preferences = portletRequest.getPreferences();
147                    Map<String, String> userInfo =
148                            (Map<String, String>)portletRequest.getAttribute(
149                                    PortletRequest.USER_INFO);
150    
151                    bsfManager.declareBean(
152                            "portletConfig", portletConfig, PortletConfig.class);
153                    bsfManager.declareBean(
154                            "portletContext", portletContext, PortletContext.class);
155                    bsfManager.declareBean(
156                            "preferences", preferences, PortletPreferences.class);
157                    bsfManager.declareBean("userInfo", userInfo, Map.class);
158    
159                    if (portletRequest instanceof ActionRequest) {
160                            bsfManager.declareBean(
161                                    "actionRequest", portletRequest, ActionRequest.class);
162                    }
163                    else if (portletRequest instanceof RenderRequest) {
164                            bsfManager.declareBean(
165                                    "renderRequest", portletRequest, RenderRequest.class);
166                    }
167                    else if (portletRequest instanceof ResourceRequest) {
168                            bsfManager.declareBean(
169                                    "resourceRequest", portletRequest, ResourceRequest.class);
170                    }
171    
172                    if (portletResponse instanceof ActionResponse) {
173                            bsfManager.declareBean(
174                                    "actionResponse", portletResponse, ActionResponse.class);
175                    }
176                    else if (portletResponse instanceof RenderResponse) {
177                            bsfManager.declareBean(
178                                    "renderResponse", portletResponse, RenderResponse.class);
179                    }
180                    else if (portletResponse instanceof ResourceResponse) {
181                            bsfManager.declareBean(
182                                    "resourceResponse", portletResponse, ResourceResponse.class);
183                    }
184    
185                    bsfManager.exec(getScriptingEngineLanguage(), "(java)", 1, 1, script);
186            }
187    
188            protected String getGlobalScript() throws IOException {
189                    if (globalFiles.length == 0) {
190                            return StringPool.BLANK;
191                    }
192    
193                    StringBundler sb = new StringBundler();
194    
195                    for (int i = 0; i < globalFiles.length; i++) {
196                            InputStream is = getPortletContext().getResourceAsStream(
197                                    globalFiles[i]);
198    
199                            if (is == null) {
200                                    if (_log.isWarnEnabled()) {
201                                            _log.warn(
202                                                    "Global file " + globalFiles[i] + " does not exist");
203                                    }
204                            }
205    
206                            if (is != null) {
207                                    sb.append(new String(FileUtil.getBytes(is)));
208                                    sb.append(StringPool.NEW_LINE);
209                            }
210                    }
211    
212                    return sb.toString();
213            }
214    
215            protected abstract String getFileParam();
216    
217            protected abstract String getScriptingEngineClassName();
218    
219            protected abstract String getScriptingEngineExtension();
220    
221            protected abstract String getScriptingEngineLanguage();
222    
223            protected void include(
224                            String path, PortletRequest portletRequest,
225                            PortletResponse portletResponse)
226                    throws IOException {
227    
228                    InputStream is = getPortletContext().getResourceAsStream(path);
229    
230                    if (is == null) {
231                            _log.error(
232                                    path + " is not a valid " + getScriptingEngineLanguage() +
233                                            " file");
234    
235                            return;
236                    }
237    
238                    try {
239                            declareBeans(is, portletRequest, portletResponse);
240                    }
241                    catch (BSFException bsfe) {
242                            logBSFException(bsfe, path);
243                    }
244                    finally {
245                            is.close();
246                    }
247            }
248    
249            protected void logBSFException(BSFException bsfe, String path) {
250                    String message =
251                            "The script at " + path + " or one of the global files has errors.";
252    
253                    Throwable t = bsfe.getTargetException();
254    
255                    _log.error(message, t);
256            }
257    
258            protected String editFile;
259            protected String helpFile;
260            protected String viewFile;
261            protected String actionFile;
262            protected String resourceFile;
263            protected String[] globalFiles;
264            protected BSFManager bsfManager;
265    
266            private static Log _log = LogFactoryUtil.getLog(BaseBSFPortlet.class);
267    
268    }