KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > portal > portlets > GenericMVCPortlet


1 /*
2  * Copyright 2000-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.jetspeed.portal.portlets;
17
18 import java.io.IOException JavaDoc;
19 import java.io.PrintWriter JavaDoc;
20 import java.io.UnsupportedEncodingException JavaDoc;
21 import java.net.URLEncoder JavaDoc;
22
23 import javax.servlet.http.HttpServletRequest JavaDoc;
24
25 import org.apache.ecs.ConcreteElement;
26 import org.apache.jetspeed.om.profile.Profile;
27 import org.apache.jetspeed.portal.PortletException;
28 import org.apache.jetspeed.portal.portlets.viewprocessor.ViewProcessor;
29 import org.apache.jetspeed.portal.portlets.viewprocessor.ViewProcessorFactory;
30 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
31 import org.apache.jetspeed.services.logging.JetspeedLogger;
32 import org.apache.jetspeed.services.rundata.JetspeedRunData;
33 import org.apache.jetspeed.util.PortletSessionState;
34 import org.apache.jetspeed.util.template.JetspeedLink;
35 import org.apache.jetspeed.util.template.JetspeedTemplateLink;
36 import org.apache.jetspeed.util.template.JspTemplate;
37 import org.apache.turbine.modules.ActionLoader;
38 import org.apache.turbine.services.pull.TurbinePull;
39 import org.apache.turbine.util.RunData;
40
41 /**
42  * Provides the basic MVC Portlet functionality independant of any
43  * specific view technology (ie jsp, velocity, xslt, etc). It handles
44  * the views via a ViewProcessor, which is a pluggable, factory
45  * created, run time module for which ever view technology your portlet
46  * uses.
47  *
48  * There is no need to extend this portlet class, just define your porlet
49  * entry in the registy as a child of this class and provide your template
50  * and action class (extened from GenericMVCAction of course) and you
51  * are good to go.
52  *
53  * Example .xreg entry:
54  *
55  * <portlet-entry name="GenericMVCPortlet" hidden="false"
56  * type="abstract" application="false">
57  * <security-ref parent="default"/>
58  * <classname>com.cisco.it.psf.portal.portlets.GenericMVCPortlet</classname>
59  * <media-type ref="html"/>
60  * <url cachedOnURL="true"/>
61  * </portlet-entry>
62  * <portlet-entry name="VelocityMVCExample" hidden="false" type="ref"
63  * parent="GenericMVCPortlet" application="false">
64  * <meta-info>
65  * <title>Velocity MVC Portlet</title>
66  * <description>Velocity Generic MVC Portlet</description>
67  * </meta-info>
68  * <classname>com.cisco.it.psf.portal.portlets.GenericMVCPortlet</classname>
69  * <parameter name="template" value="mvc-example" hidden="true"
70  * cachedOnName="true" cachedOnValue="true"/>
71  * <parameter name="viewtype" value="Velocity" hidden="true"
72  * cachedOnName="true" cachedOnValue="true"/>
73  * <parameter name="action"
74  * value="portlets.ExampleGenericMVCAction" hidden="true"
75  * cachedOnName="true" cachedOnValue="true"/>
76  * <url cachedOnURL="true"/>
77  * </portlet-entry>
78  *
79  * See the Velocity and JSP MVC Portlet examples for template and action class clues.
80  *
81  * To add new view processor types, simply implement the ViewProcessor
82  * interface and add your type into the <b>viewprocessor.properties</b> file as
83  * shown in the example below:
84  *
85  * mvc.viewprocessor.Velocity = org.apache.jetspeedportlets.viewprocessors.VelocityViewProcessor
86  * mvc.viewprocessor.JSP = org.apache.jetspeedportlets.viewprocessors.JSPViewProcessor
87  * mvc.viewprocessor.XSL = org.apache.jetspeedportlets.viewprocessors.XSLViewProcessor
88  *
89  * @stereotype role
90  * @author tkuebler
91  * @author <a HREF="mailto:weaver@apache.org">Scott T. Weaver</a>
92  * @version $Id: GenericMVCPortlet.java,v 1.11 2003/02/11 23:09:18 tkuebler Exp $
93  */

94 public class GenericMVCPortlet extends AbstractInstancePortlet
95 {
96     
97     /**
98      * Static initialization of the logger for this class
99      */

100     private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(GenericMVCPortlet.class.getName());
101     
102     // STW: Context keys
103
public static final String JavaDoc PORTLET = "portlet";
104     public static final String JavaDoc TEMPLATE = "template";
105     public static final String JavaDoc RUNDATA = "data";
106     public static final String JavaDoc PORTLET_CONFIG = "conf";
107     public static final String JavaDoc SKIN = "skin";
108     public static final String JavaDoc VIEW_TYPE = "viewType";
109     public static final String JavaDoc IS_CACHEABLE = "_IsCacheable";
110
111     // need cache timer, etc
112
private String JavaDoc viewType = "ERROR: not set in config";
113     private String JavaDoc actionName = "ERROR: not set in config";
114     private String JavaDoc template = "ERROR: not set in config";
115     private String JavaDoc configureTemplate;
116     private String JavaDoc maximizedTemplate;
117     private ViewProcessor processor = null;
118     private boolean providesCustomization;
119
120     public static final String JavaDoc RENDERING_DELAYED = "renderingDelayed";
121     public static final String JavaDoc SIMULATE_DELAY = "simulateDelay";
122     public static final String JavaDoc PORTLET_ID = "__portletId";
123     public static final String JavaDoc DOC_URL = "__docUrl";
124   
125     public void init() throws PortletException
126     {
127         
128         //STW: check custimization attribute
129
String JavaDoc provConf = getPortletConfig().getInitParameter("provides.customization", "false");
130         providesCustomization = new Boolean JavaDoc(provConf).booleanValue();
131         
132         // pull the important info out of the portlet config
133
actionName = getPortletConfig().getInitParameter("action");
134         // STW: Allow subclasses to set viewtype for backward compatibillity
135
if (getPortletConfig().getInitParameter("viewtype") != null)
136         {
137             viewType = getPortletConfig().getInitParameter("viewtype");
138         }
139
140         template = getPortletConfig().getInitParameter("template");
141
142         // get viewprocessor from factory
143
logger.info(
144             "GenericMVCPortlet - creating view processor for viewtype = "
145                 + viewType
146                 + ", template = "
147                 + template);
148         processor = ViewProcessorFactory.getViewProcessor(viewType);
149
150         // initialize view processor with portlet info
151
processor.init(this);
152
153         // should make this config file driven
154
// STW removed this so subclasses can decide this for
155
// themselves.
156
// setCacheable(false);
157
}
158
159     /**
160      * By default MVCPortlets are cacheable. This can be overriden by specifying
161      * "_IsCacheable" parameter.
162      *
163      * @return
164      */

165     public boolean isCacheable()
166     {
167         return getPortletConfig().getInitParameter(IS_CACHEABLE, "true").equalsIgnoreCase("true");
168     }
169
170 /**
171  * Whether or not this portlet provides it's own customizer.
172  * This can be set at the registry level by adding a
173  * boolean paramter "provides.customization"
174  * Defaults to "false"
175  */

176     public boolean providesCustomization()
177     {
178         return providesCustomization;
179     }
180
181     public ConcreteElement getContent(RunData rundata)
182     {
183         if (useDelayedRendering(rundata))
184         {
185             Profile profile = ((JetspeedRunData) rundata).getProfile();
186             String JavaDoc path = profile.getPath();
187             String JavaDoc portletId = getID();
188             
189             // FIXME: please use JetspeedLink to create Portal URLs
190
String JavaDoc docUrl = "portal/" + path + "/js_peid/" + portletId + "?action=controls.Print";
191             docUrl = URLEncoder.encode(docUrl); //, "UTF-8");
192
// END FIXME:
193

194             HttpServletRequest JavaDoc request = rundata.getRequest();
195             request.setAttribute(PORTLET_ID, portletId);
196             request.setAttribute(DOC_URL, docUrl);
197
198             // render content that pulls
199
return renderJspTemplate(rundata, "delayedContent.jsp");
200         }
201         
202         simulateDelay();
203             
204         //if caching is turned off or no expiration time set, generate and return the content
205
if (!isCacheable() || null == getExpirationMillis())
206         {
207             return buildContent(rundata);
208         }
209
210         //is the cached content still valid, if not, generate and return the content
211
if (getExpirationMillis().longValue() <= System.currentTimeMillis())
212         {
213             return buildContent(rundata);
214         }
215
216         //else, the cached content is fine to be returned
217
return getContent(rundata, null, true);
218
219     }
220
221     protected ConcreteElement buildContent(RunData rundata)
222     {
223         // create a new context
224
// populate it with data
225
GenericMVCContext context = new GenericMVCContext(TurbinePull.getGlobalContext());
226         context.put(RUNDATA, rundata);
227         context.put(PORTLET, this);
228         context.put(PORTLET_CONFIG, this.getPortletConfig());
229         context.put(SKIN, this.getPortletConfig().getPortletSkin());
230         context.put(TEMPLATE, getCurrentTemplate(rundata));
231         context.put(VIEW_TYPE, viewType);
232         populateRequest(rundata);
233
234         // put references to the pull tools in the context
235
TurbinePull.populateContext(context, rundata);
236         // Initialize jlink and jslink tools with ourselves
237
// to enable links between portlets
238
Object JavaDoc jlink = context.get("jlink");
239
240         if (jlink instanceof JetspeedTemplateLink)
241         {
242             ((JetspeedTemplateLink) jlink).setPortlet(this);
243         }
244
245         Object JavaDoc jslink = context.get("jslink");
246
247         if (jslink instanceof JetspeedLink)
248         {
249             ((JetspeedLink) jslink).setPortlet(this);
250         }
251
252         // Handle Action
253
if (actionName != null)
254         {
255
256             try
257             {
258
259                 // store the context so that the action can retrieve it
260
//Log.debug("VelocityPortlet found action "+actionName+" context "+context);
261
// note: the name it is stored under is legacy, leaving it this way
262
// because some of the routines fall back to old default behavior
263
// of the velocity portlet and might depend on the name
264
rundata.getTemplateInfo().setTemplateContext("VelocityPortletContext", context);
265
266                 if (logger.isDebugEnabled())
267                 {
268                     logger.debug(
269                         "GenericMVCPortlet: Executing action ["
270                             + actionName
271                             + "] for portlet ["
272                             + this.getName()
273                             + "]");
274                 }
275
276                 ActionLoader.getInstance().exec(rundata, actionName);
277             }
278             catch (Exception JavaDoc e)
279             {
280                 logger.error("GenericMVCPortlet - error executing action", e);
281             }
282         }
283
284         // Process View
285
// call processView method
286
logger.info("GenericMVCPortlet - calling processView on processor");
287
288         ConcreteElement result = (ConcreteElement) processor.processView(context);
289         logger.info("GenericMVCPortlet - setting this portlet's content");
290         clearContent();
291         setContent(result); // only needed when caching is true I believe
292

293         // return result
294
return result;
295     }
296     /**
297      * @see setViewType()
298      * @return String
299      */

300     protected String JavaDoc getViewType()
301     {
302         return viewType;
303     }
304
305     /**
306     * STW: Added for backward compatibility when using this
307      * class to subclass the existing Jsp and Velocity portlets
308      * so they can set their view prior to super.init();
309      * @param viewType The viewType to set
310      */

311     protected void setViewType(String JavaDoc viewType)
312     {
313         this.viewType = viewType;
314     }
315
316     /**
317      * This is called before any action execution happens.
318      * This provides backward compatibility to JspPortletActions
319      * who retreive information, like Portlet, from the request
320      * BEFORE the ViewProcessor.processView() is called
321      * which normally populates the request with Context objects.
322      * @author <a HREF="mailto:sweaver@rippe.com">Scott Weaver</a>
323      */

324     protected void populateRequest(RunData rundata)
325     {
326         HttpServletRequest JavaDoc request = rundata.getRequest();
327         request.setAttribute("data", rundata);
328         request.setAttribute("portlet", this);
329         request.setAttribute("conf", this.getPortletConfig());
330         request.setAttribute("skin", this.getPortletConfig().getPortletSkin());
331         request.setAttribute("template", getCurrentTemplate(rundata));
332         request.setAttribute("viewType", viewType);
333     }
334     
335     /**
336      *
337      */

338     protected String JavaDoc getCurrentTemplate( RunData data)
339     {
340         String JavaDoc useTemplate = (String JavaDoc) PortletSessionState.getAttribute(this, data, TEMPLATE);
341         if(useTemplate == null)
342         {
343             useTemplate = this.template;
344         }
345
346         return useTemplate;
347     }
348     
349     protected boolean useDelayedRendering(RunData rundata)
350     {
351         String JavaDoc renderingDelayedString = getPortletConfig().getInitParameter(RENDERING_DELAYED);
352         boolean renderingDelayed = false;
353         if (renderingDelayedString != null)
354         {
355             renderingDelayed = (Boolean.valueOf(renderingDelayedString) == Boolean.TRUE);
356         }
357
358         HttpServletRequest JavaDoc request = rundata.getRequest();
359         String JavaDoc action = rundata.getAction();
360
361         return renderingDelayed && (action == null || action.length() == 0 || "controls.Restore".equals(action));
362     }
363
364     protected ConcreteElement renderJspTemplate(RunData rundata, String JavaDoc templateName)
365     {
366         JspTemplate t = new JspTemplate(rundata, "/portlets/html/" + templateName);
367         PrintWriter JavaDoc out = null;
368         try
369         {
370             out = rundata.getOut();
371             out.println(t.getContent());
372         }
373         catch (IOException JavaDoc ioe)
374         {
375             logger.error(ioe);
376         }
377
378         return null;
379     }
380     
381     private void simulateDelay()
382     {
383         String JavaDoc simulateDelayString = getPortletConfig().getInitParameter(SIMULATE_DELAY);
384         int simulateDelay = 0; // seconds
385
if (simulateDelayString != null)
386         {
387             simulateDelay = Integer.parseInt(simulateDelayString);
388         }
389
390         if (simulateDelay > 0)
391         {
392             long delayInMilliseconds = simulateDelay * 1000;
393             try
394             {
395                 Thread.sleep(delayInMilliseconds);
396             }
397             catch (InterruptedException JavaDoc e)
398             {
399             }
400         }
401                 
402     }
403 }
404
Popular Tags