1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.portal.controls;
18
19
20 import org.apache.turbine.services.velocity.TurbineVelocity;
21 import org.apache.turbine.services.pull.TurbinePull;
22 import org.apache.turbine.util.RunData;
23
24
25 import org.apache.jetspeed.portal.Portlet;
26 import org.apache.jetspeed.portal.PortletState;
27 import org.apache.jetspeed.portal.security.portlets.PortletWrapper;
28 import org.apache.jetspeed.services.TemplateLocator;
29 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
30 import org.apache.jetspeed.services.logging.JetspeedLogger;
31 import org.apache.jetspeed.services.persistence.PersistenceManager;
32 import org.apache.jetspeed.services.resources.JetspeedResources;
33 import org.apache.jetspeed.services.rundata.JetspeedRunData;
34 import org.apache.jetspeed.util.template.JetspeedTool;
35 import org.apache.jetspeed.util.template.JetspeedLink;
36 import org.apache.jetspeed.util.template.JetspeedLinkFactory;
37 import org.apache.jetspeed.services.JetspeedSecurity;
38 import org.apache.jetspeed.om.security.JetspeedUser;
39
40
41 import org.apache.ecs.ConcreteElement;
42 import org.apache.ecs.StringElement;
43
44
45 import org.apache.velocity.context.Context;
46
47
48 import java.util.List;
49 import java.util.Vector;
50 import java.util.Iterator;
51
52 /***
53 * A Velocity based portlet control which implements all PortletState action
54 *
55 * <p>To use this control you need to define in your registry the following
56 * entry or similar:</p>
57 * <pre>
58 * <portlet-control-entry name="TitlePortletControl">
59 * <classname>org.apache.jetspeed.portal.controls.VelocityPortletControl</classname>
60 * <parameter name="theme" value="default.vm"/>
61 * <meta-info>
62 * <title>TitleControl</title>
63 * <description>The standard Jetspeed boxed control</description>
64 * <image>url of image (icon)</description>
65 * </meta-info>
66 * <media-type ref="html"/>
67 * </portlet-control-entry>
68 * </pre>
69 *
70 *
71 * @author <a href="mailto:re_carrasco@bco011.sonda.cl">Roberto Carrasco</a>
72 * @author <a href="mailto:raphael@apache.org">Raphaël Luta</a>
73 * @author <a href="mailto:morciuch@apache.org">Mark Orciuch</a>
74 *
75 * @version $Id: VelocityPortletControl.java,v 1.30 2004/03/29 21:38:42 taylor Exp $
76 *
77 */
78 public class VelocityPortletControl extends AbstractPortletControl
79 {
80
81 /***
82 * Static initialization of the logger for this class
83 */
84 private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(VelocityPortletControl.class.getName());
85
86 /*** Disable content caching */
87 public boolean isCacheable()
88 {
89 return false;
90 }
91
92 /***
93 * Handles the content generation for this control using Velocity
94 */
95 public ConcreteElement getContent( RunData rundata )
96 {
97 Portlet portlet = getPortlet();
98 JetspeedRunData jdata = (JetspeedRunData)rundata;
99
100
101
102
103 if (portlet instanceof PortletWrapper)
104 {
105 PortletWrapper wrapper = (PortletWrapper)portlet;
106 if (!wrapper.getAllowView(rundata))
107 {
108 if (JetspeedResources.getBoolean("defaultportletcontrol.hide.decorator", true))
109 {
110 return new StringElement("");
111 }
112 }
113 }
114
115
116
117 Context context = TurbineVelocity.getContext();
118
119 context.put("data", rundata );
120 context.put("actions", buildActionList( rundata, portlet ) );
121 context.put("conf", getConfig() );
122 context.put("skin", portlet.getPortletConfig().getPortletSkin() );
123
124
125 TurbinePull.populateContext(context, rundata);
126
127 if ( portlet.getName().equals(jdata.getCustomized())
128 && (!portlet.providesCustomization()) )
129 {
130 context.put("portlet",JetspeedTool.getCustomizer(portlet));
131 context.put("portlet_instance",JetspeedTool.getCustomizer(portlet));
132 }
133 else
134 {
135 context.put("portlet", portlet );
136 if (PersistenceManager.getInstance(portlet, jdata) == null)
137 {
138 context.put("portlet_instance", portlet );
139 }
140 else
141 {
142 context.put("portlet_instance", PersistenceManager.getInstance(portlet, jdata) );
143 }
144 }
145
146
147 buildContext( rundata, context );
148
149 String theme = getConfig().getInitParameter("theme","default.vm");
150
151 String s = "";
152 try
153 {
154 String template = TemplateLocator.locateControlTemplate(rundata,theme);
155 TurbineVelocity.handleRequest(context, template, rundata.getOut());
156 }
157 catch( Exception e )
158 {
159 logger.error( "Exception while creating content ", e );
160 s = e.toString();
161 }
162
163 TurbineVelocity.requestFinished(context);
164
165 return new StringElement( s );
166 }
167
168 /***
169 * This method allows subclasses of the VelocityPortletControl
170 * to populate the context of this control before rendering by
171 * the template engine.
172 *
173 * @param rundata the RunData object for this request
174 * @param context the Context used by the template
175 */
176 public void buildContext( RunData rundata, Context context )
177 {
178
179 }
180
181 /*** Builds a list of possible window actions for this portlet
182 * instance. For best results, the portlet should also implement the
183 * PortletState interface.
184 *
185 * @param rundata the request RunData
186 * @param the portlet instance managed by this control
187 * @return a list of ordered PortletAction objects describing the
188 * the actions available for this portlet
189 */
190 protected List buildActionList( RunData rundata, Portlet portlet )
191 {
192 List actions = new Vector();
193 JetspeedLink jsLink = null;
194 JetspeedRunData jdata = (JetspeedRunData)rundata;
195
196
197 if (JetspeedSecurity.areActionsDisabledForAllUsers())
198 {
199 return actions;
200 }
201 JetspeedUser user = jdata.getJetspeedUser();
202 if (JetspeedSecurity.areActionsDisabledForAnon() && false == user.hasLoggedIn())
203 {
204 return actions;
205 }
206
207
208
209 if (portlet instanceof PortletState)
210 {
211
212 PortletState state = (PortletState)portlet;
213 boolean customized = (jdata.getMode()==JetspeedRunData.CUSTOMIZE);
214 boolean maximized = customized||(jdata.getMode()==JetspeedRunData.MAXIMIZE);
215 boolean infoAdded = false;
216
217 if ( state.allowCustomize( rundata ) )
218 {
219 if (! customized )
220 {
221 actions.add( new PortletAction("customize", "Customize") );
222 }
223 }
224 else
225 {
226 if ( state.allowInfo( rundata ) )
227 {
228 actions.add( new PortletAction("info", "Information") );
229 infoAdded = true;
230 }
231 }
232
233 if ( (!customized) && state.allowPrintFriendly( rundata ) )
234 {
235 actions.add( new PortletAction("print", "Print Friendly Format") );
236 }
237
238 if ( (!customized) && state.allowInfo( rundata ) && (!infoAdded) )
239 {
240 actions.add( new PortletAction("info", "Information") );
241 }
242
243 if ( (!customized) && (!maximized) && state.allowClose( rundata ) )
244 {
245 actions.add( new PortletAction("close", "Close") );
246 }
247
248 if ( state.isMinimized( rundata ) || maximized )
249 {
250 actions.add( new PortletAction("restore", "Restore") );
251 }
252 else
253 {
254 if ( state.allowMinimize( rundata ) )
255 {
256 actions.add( new PortletAction("minimize", "Minimize") );
257 }
258
259 if ( state.allowMaximize( rundata ) )
260 {
261 actions.add( new PortletAction("maximize", "Maximize") );
262 }
263 }
264 }
265 else
266 {
267
268 if ( portlet.getAllowEdit( rundata ) )
269 {
270 actions.add( new PortletAction("info", "Information") );
271 }
272
273 if ( portlet.getAllowMaximize( rundata ) )
274 {
275 actions.add( new PortletAction("maximize", "Maximize") );
276 }
277 }
278
279
280
281 Iterator i = actions.iterator();
282
283 while( i.hasNext() )
284 {
285 PortletAction action = (PortletAction)i.next();
286
287 try
288 {
289 jsLink = JetspeedLinkFactory.getInstance(rundata);
290 }
291 catch( Exception e)
292 {
293 logger.error( "Exception in buildActionList", e );
294 }
295
296
297
298 action.setLink( jsLink.setAction( getAction( action.getName()), portlet).toString());
299 JetspeedLinkFactory.putInstance(jsLink);
300 jsLink=null;
301 }
302
303 return actions;
304 }
305
306 /*** Transforms an Action name in Turbine valid action name, by
307 * adding a controls package prefix and capitalizing the first
308 * letter of the name.
309 */
310 protected static String getAction( String name )
311 {
312 StringBuffer buffer = new StringBuffer( "controls." );
313
314 buffer.append( name.substring(0,1).toUpperCase() );
315 buffer.append( name.substring(1, name.length() ) );
316
317 return buffer.toString();
318 }
319
320 /*** This utility class is used to give information about the actions
321 * available in a control theme template
322 */
323 public class PortletAction
324 {
325 String name = null;
326 String link = null;
327 String alt = null;
328
329 /***
330 * Constructor
331 *
332 * @param name Name of the action
333 * @param alt Alternative text description (localized)
334 */
335 protected PortletAction( String name, String alt )
336 {
337 this.name = name;
338 this.alt = alt;
339 }
340
341 public String getName()
342 {
343 return this.name;
344 }
345
346 public String getLink()
347 {
348 return this.link;
349 }
350
351 public void setLink(String link)
352 {
353 this.link = link;
354 }
355
356 public String getAlt()
357 {
358 return this.alt;
359 }
360
361 }
362 }
363