1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.util.bridges.bsf;
24  
25  import com.liferay.portal.kernel.log.Log;
26  import com.liferay.portal.kernel.log.LogFactoryUtil;
27  import com.liferay.portal.kernel.util.FileUtil;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.StringUtil;
30  
31  import java.io.IOException;
32  import java.io.InputStream;
33  
34  import java.util.Map;
35  
36  import javax.portlet.ActionRequest;
37  import javax.portlet.ActionResponse;
38  import javax.portlet.GenericPortlet;
39  import javax.portlet.PortletConfig;
40  import javax.portlet.PortletContext;
41  import javax.portlet.PortletException;
42  import javax.portlet.PortletPreferences;
43  import javax.portlet.PortletRequest;
44  import javax.portlet.PortletResponse;
45  import javax.portlet.RenderRequest;
46  import javax.portlet.RenderResponse;
47  import javax.portlet.ResourceRequest;
48  import javax.portlet.ResourceResponse;
49  
50  import org.apache.bsf.BSFException;
51  import org.apache.bsf.BSFManager;
52  
53  /**
54   * <a href="BaseBSFPortlet.java.html"><b><i>View Source</i></b></a>
55   *
56   * @author Jorge Ferrer
57   * @author Brian Wing Shun Chan
58   */
59  public abstract class BaseBSFPortlet extends GenericPortlet {
60  
61      public void init() {
62          editFile = getInitParameter("edit-file");
63          helpFile = getInitParameter("help-file");
64          viewFile = getInitParameter("view-file");
65          actionFile = getInitParameter("action-file");
66          resourceFile = getInitParameter("resource-file");
67          globalFiles = StringUtil.split(getInitParameter("global-files"));
68  
69          BSFManager.registerScriptingEngine(
70              getScriptingEngineLanguage(), getScriptingEngineClassName(),
71              new String[] {getScriptingEngineExtension()});
72  
73          bsfManager = new BSFManager();
74      }
75  
76      public void doDispatch(
77              RenderRequest renderRequest, RenderResponse renderResponse)
78          throws IOException, PortletException {
79  
80          String file = renderRequest.getParameter(getFileParam());
81  
82          if (file != null) {
83              include(file, renderRequest, renderResponse);
84          }
85          else {
86              super.doDispatch(renderRequest, renderResponse);
87          }
88      }
89  
90      public void doEdit(
91              RenderRequest renderRequest, RenderResponse renderResponse)
92          throws IOException, PortletException {
93  
94          if (renderRequest.getPreferences() == null) {
95              super.doEdit(renderRequest, renderResponse);
96          }
97          else {
98              include(editFile, renderRequest, renderResponse);
99          }
100     }
101 
102     public void doHelp(
103             RenderRequest renderRequest, RenderResponse renderResponse)
104         throws IOException {
105 
106         include(helpFile, renderRequest, renderResponse);
107     }
108 
109     public void doView(
110             RenderRequest renderRequest, RenderResponse renderResponse)
111         throws IOException {
112 
113         include(viewFile, renderRequest, renderResponse);
114     }
115 
116     public void processAction(
117             ActionRequest actionRequest, ActionResponse actionResponse)
118         throws IOException {
119 
120         include(actionFile, actionRequest, actionResponse);
121     }
122 
123     public void serveResource(
124             ResourceRequest resourceRequest, ResourceResponse resourceResponse)
125         throws IOException {
126 
127         include(resourceFile, resourceRequest, resourceResponse);
128     }
129 
130     protected void declareBeans(
131             InputStream is, PortletRequest portletRequest,
132             PortletResponse portletResponse)
133         throws BSFException, IOException {
134 
135         declareBeans(
136             new String(FileUtil.getBytes(is)), portletRequest, portletResponse);
137     }
138 
139     protected void declareBeans(
140             String code, PortletRequest portletRequest,
141             PortletResponse portletResponse)
142         throws BSFException, IOException {
143 
144         StringBuilder sb = new StringBuilder();
145 
146         sb.append(getGlobalScript());
147         sb.append(code);
148 
149         String script = sb.toString();
150 
151         PortletConfig portletConfig = getPortletConfig();
152         PortletContext portletContext = getPortletContext();
153         PortletPreferences preferences = portletRequest.getPreferences();
154         Map<String, String> userInfo =
155             (Map<String, String>)portletRequest.getAttribute(
156                 PortletRequest.USER_INFO);
157 
158         bsfManager.declareBean(
159             "portletConfig", portletConfig, PortletConfig.class);
160         bsfManager.declareBean(
161             "portletContext", portletContext, PortletContext.class);
162         bsfManager.declareBean(
163             "preferences", preferences, PortletPreferences.class);
164         bsfManager.declareBean("userInfo", userInfo, Map.class);
165 
166         if (portletRequest instanceof ActionRequest) {
167             bsfManager.declareBean(
168                 "actionRequest", portletRequest, ActionRequest.class);
169         }
170         else if (portletRequest instanceof RenderRequest) {
171             bsfManager.declareBean(
172                 "renderRequest", portletRequest, RenderRequest.class);
173         }
174         else if (portletRequest instanceof ResourceRequest) {
175             bsfManager.declareBean(
176                 "resourceRequest", portletRequest, ResourceRequest.class);
177         }
178 
179         if (portletResponse instanceof ActionResponse) {
180             bsfManager.declareBean(
181                 "actionResponse", portletResponse, ActionResponse.class);
182         }
183         else if (portletResponse instanceof RenderResponse) {
184             bsfManager.declareBean(
185                 "renderResponse", portletResponse, RenderResponse.class);
186         }
187         else if (portletResponse instanceof ResourceResponse) {
188             bsfManager.declareBean(
189                 "resourceResponse", portletResponse, ResourceResponse.class);
190         }
191 
192         bsfManager.exec(getScriptingEngineLanguage(), "(java)", 1, 1, script);
193     }
194 
195     protected String getGlobalScript() throws IOException {
196         StringBuilder sb = new StringBuilder();
197 
198         for (int i = 0; i < globalFiles.length; i++) {
199             InputStream is = getPortletContext().getResourceAsStream(
200                 globalFiles[i]);
201 
202             if (is == null) {
203                 if (_log.isWarnEnabled()) {
204                     _log.warn(
205                         "Global file " + globalFiles[i] + " does not exist");
206                 }
207             }
208 
209             try {
210                 if (is != null) {
211                     sb.append(new String(FileUtil.getBytes(is)));
212                     sb.append(StringPool.NEW_LINE);
213                 }
214             }
215             finally {
216                 is.close();
217             }
218         }
219 
220         return sb.toString();
221     }
222 
223     protected abstract String getFileParam();
224 
225     protected abstract String getScriptingEngineClassName();
226 
227     protected abstract String getScriptingEngineExtension();
228 
229     protected abstract String getScriptingEngineLanguage();
230 
231     protected void include(
232             String path, PortletRequest portletRequest,
233             PortletResponse portletResponse)
234         throws IOException {
235 
236         InputStream is = getPortletContext().getResourceAsStream(path);
237 
238         if (is == null) {
239             _log.error(
240                 path + " is not a valid " + getScriptingEngineLanguage() +
241                     " file");
242 
243             return;
244         }
245 
246         try {
247             declareBeans(is, portletRequest, portletResponse);
248         }
249         catch (BSFException bsfe) {
250             logBSFException(bsfe, path);
251         }
252         finally {
253             is.close();
254         }
255     }
256 
257     protected void logBSFException(BSFException bsfe, String path) {
258         String message =
259             "The script at " + path + " or one of the global files has errors.";
260 
261         Throwable t = bsfe.getTargetException();
262 
263         _log.error(message, t);
264     }
265 
266     protected String editFile;
267     protected String helpFile;
268     protected String viewFile;
269     protected String actionFile;
270     protected String resourceFile;
271     protected String[] globalFiles;
272     protected BSFManager bsfManager;
273 
274     private static Log _log = LogFactoryUtil.getLog(BaseBSFPortlet.class);
275 
276 }