001    /**
002     * Copyright (c) 2000-2013 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 doDispatch(
054                            RenderRequest renderRequest, RenderResponse renderResponse)
055                    throws IOException, PortletException {
056    
057                    String file = renderRequest.getParameter(getFileParam());
058    
059                    if (file != null) {
060                            include(file, renderRequest, renderResponse);
061                    }
062                    else {
063                            super.doDispatch(renderRequest, renderResponse);
064                    }
065            }
066    
067            @Override
068            public void doEdit(
069                            RenderRequest renderRequest, RenderResponse renderResponse)
070                    throws IOException, PortletException {
071    
072                    if (renderRequest.getPreferences() == null) {
073                            super.doEdit(renderRequest, renderResponse);
074                    }
075                    else {
076                            include(editFile, renderRequest, renderResponse);
077                    }
078            }
079    
080            @Override
081            public void doHelp(
082                            RenderRequest renderRequest, RenderResponse renderResponse)
083                    throws IOException {
084    
085                    include(helpFile, renderRequest, renderResponse);
086            }
087    
088            @Override
089            public void doView(
090                            RenderRequest renderRequest, RenderResponse renderResponse)
091                    throws IOException {
092    
093                    include(viewFile, renderRequest, renderResponse);
094            }
095    
096            @Override
097            public void init() {
098                    editFile = getInitParameter("edit-file");
099                    helpFile = getInitParameter("help-file");
100                    viewFile = getInitParameter("view-file");
101                    actionFile = getInitParameter("action-file");
102                    resourceFile = getInitParameter("resource-file");
103                    globalFiles = StringUtil.split(getInitParameter("global-files"));
104    
105                    BSFManager.registerScriptingEngine(
106                            getScriptingEngineLanguage(), getScriptingEngineClassName(),
107                            new String[] {getScriptingEngineExtension()});
108    
109                    bsfManager = new BSFManager();
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 abstract String getFileParam();
189    
190            protected String getGlobalScript() throws IOException {
191                    if (globalFiles.length == 0) {
192                            return StringPool.BLANK;
193                    }
194    
195                    StringBundler sb = new StringBundler();
196    
197                    for (int i = 0; i < globalFiles.length; i++) {
198                            InputStream is = getPortletContext().getResourceAsStream(
199                                    globalFiles[i]);
200    
201                            if (is == null) {
202                                    if (_log.isWarnEnabled()) {
203                                            _log.warn(
204                                                    "Global file " + globalFiles[i] + " does not exist");
205                                    }
206                            }
207    
208                            if (is != null) {
209                                    sb.append(new String(FileUtil.getBytes(is)));
210                                    sb.append(StringPool.NEW_LINE);
211                            }
212                    }
213    
214                    return sb.toString();
215            }
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 actionFile;
259            protected BSFManager bsfManager;
260            protected String editFile;
261            protected String[] globalFiles;
262            protected String helpFile;
263            protected String resourceFile;
264            protected String viewFile;
265    
266            private static Log _log = LogFactoryUtil.getLog(BaseBSFPortlet.class);
267    
268    }