001    /**
002     * Copyright (c) 2000-2010 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            public void init() {
053                    editFile = getInitParameter("edit-file");
054                    helpFile = getInitParameter("help-file");
055                    viewFile = getInitParameter("view-file");
056                    actionFile = getInitParameter("action-file");
057                    resourceFile = getInitParameter("resource-file");
058                    globalFiles = StringUtil.split(getInitParameter("global-files"));
059    
060                    BSFManager.registerScriptingEngine(
061                            getScriptingEngineLanguage(), getScriptingEngineClassName(),
062                            new String[] {getScriptingEngineExtension()});
063    
064                    bsfManager = new BSFManager();
065            }
066    
067            public void doDispatch(
068                            RenderRequest renderRequest, RenderResponse renderResponse)
069                    throws IOException, PortletException {
070    
071                    String file = renderRequest.getParameter(getFileParam());
072    
073                    if (file != null) {
074                            include(file, renderRequest, renderResponse);
075                    }
076                    else {
077                            super.doDispatch(renderRequest, renderResponse);
078                    }
079            }
080    
081            public void doEdit(
082                            RenderRequest renderRequest, RenderResponse renderResponse)
083                    throws IOException, PortletException {
084    
085                    if (renderRequest.getPreferences() == null) {
086                            super.doEdit(renderRequest, renderResponse);
087                    }
088                    else {
089                            include(editFile, renderRequest, renderResponse);
090                    }
091            }
092    
093            public void doHelp(
094                            RenderRequest renderRequest, RenderResponse renderResponse)
095                    throws IOException {
096    
097                    include(helpFile, renderRequest, renderResponse);
098            }
099    
100            public void doView(
101                            RenderRequest renderRequest, RenderResponse renderResponse)
102                    throws IOException {
103    
104                    include(viewFile, renderRequest, renderResponse);
105            }
106    
107            public void processAction(
108                            ActionRequest actionRequest, ActionResponse actionResponse)
109                    throws IOException {
110    
111                    include(actionFile, actionRequest, actionResponse);
112            }
113    
114            public void serveResource(
115                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
116                    throws IOException {
117    
118                    include(resourceFile, resourceRequest, resourceResponse);
119            }
120    
121            protected void declareBeans(
122                            InputStream is, PortletRequest portletRequest,
123                            PortletResponse portletResponse)
124                    throws BSFException, IOException {
125    
126                    declareBeans(
127                            new String(FileUtil.getBytes(is)), portletRequest, portletResponse);
128            }
129    
130            protected void declareBeans(
131                            String code, PortletRequest portletRequest,
132                            PortletResponse portletResponse)
133                    throws BSFException, IOException {
134    
135                    String script = getGlobalScript().concat(code);
136    
137                    PortletConfig portletConfig = getPortletConfig();
138                    PortletContext portletContext = getPortletContext();
139                    PortletPreferences preferences = portletRequest.getPreferences();
140                    Map<String, String> userInfo =
141                            (Map<String, String>)portletRequest.getAttribute(
142                                    PortletRequest.USER_INFO);
143    
144                    bsfManager.declareBean(
145                            "portletConfig", portletConfig, PortletConfig.class);
146                    bsfManager.declareBean(
147                            "portletContext", portletContext, PortletContext.class);
148                    bsfManager.declareBean(
149                            "preferences", preferences, PortletPreferences.class);
150                    bsfManager.declareBean("userInfo", userInfo, Map.class);
151    
152                    if (portletRequest instanceof ActionRequest) {
153                            bsfManager.declareBean(
154                                    "actionRequest", portletRequest, ActionRequest.class);
155                    }
156                    else if (portletRequest instanceof RenderRequest) {
157                            bsfManager.declareBean(
158                                    "renderRequest", portletRequest, RenderRequest.class);
159                    }
160                    else if (portletRequest instanceof ResourceRequest) {
161                            bsfManager.declareBean(
162                                    "resourceRequest", portletRequest, ResourceRequest.class);
163                    }
164    
165                    if (portletResponse instanceof ActionResponse) {
166                            bsfManager.declareBean(
167                                    "actionResponse", portletResponse, ActionResponse.class);
168                    }
169                    else if (portletResponse instanceof RenderResponse) {
170                            bsfManager.declareBean(
171                                    "renderResponse", portletResponse, RenderResponse.class);
172                    }
173                    else if (portletResponse instanceof ResourceResponse) {
174                            bsfManager.declareBean(
175                                    "resourceResponse", portletResponse, ResourceResponse.class);
176                    }
177    
178                    bsfManager.exec(getScriptingEngineLanguage(), "(java)", 1, 1, script);
179            }
180    
181            protected String getGlobalScript() throws IOException {
182                    if (globalFiles.length == 0) {
183                            return StringPool.BLANK;
184                    }
185    
186                    StringBundler sb = new StringBundler();
187    
188                    for (int i = 0; i < globalFiles.length; i++) {
189                            InputStream is = getPortletContext().getResourceAsStream(
190                                    globalFiles[i]);
191    
192                            if (is == null) {
193                                    if (_log.isWarnEnabled()) {
194                                            _log.warn(
195                                                    "Global file " + globalFiles[i] + " does not exist");
196                                    }
197                            }
198    
199                            try {
200                                    if (is != null) {
201                                            sb.append(new String(FileUtil.getBytes(is)));
202                                            sb.append(StringPool.NEW_LINE);
203                                    }
204                            }
205                            finally {
206                                    is.close();
207                            }
208                    }
209    
210                    return sb.toString();
211            }
212    
213            protected abstract String getFileParam();
214    
215            protected abstract String getScriptingEngineClassName();
216    
217            protected abstract String getScriptingEngineExtension();
218    
219            protected abstract String getScriptingEngineLanguage();
220    
221            protected void include(
222                            String path, PortletRequest portletRequest,
223                            PortletResponse portletResponse)
224                    throws IOException {
225    
226                    InputStream is = getPortletContext().getResourceAsStream(path);
227    
228                    if (is == null) {
229                            _log.error(
230                                    path + " is not a valid " + getScriptingEngineLanguage() +
231                                            " file");
232    
233                            return;
234                    }
235    
236                    try {
237                            declareBeans(is, portletRequest, portletResponse);
238                    }
239                    catch (BSFException bsfe) {
240                            logBSFException(bsfe, path);
241                    }
242                    finally {
243                            is.close();
244                    }
245            }
246    
247            protected void logBSFException(BSFException bsfe, String path) {
248                    String message =
249                            "The script at " + path + " or one of the global files has errors.";
250    
251                    Throwable t = bsfe.getTargetException();
252    
253                    _log.error(message, t);
254            }
255    
256            protected String editFile;
257            protected String helpFile;
258            protected String viewFile;
259            protected String actionFile;
260            protected String resourceFile;
261            protected String[] globalFiles;
262            protected BSFManager bsfManager;
263    
264            private static Log _log = LogFactoryUtil.getLog(BaseBSFPortlet.class);
265    
266    }