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