KickJava   Java API By Example, From Geeks To Geeks.

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


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
17 package org.apache.jetspeed.portal.portlets;
18
19 //jetspeed
20
import org.apache.jetspeed.capability.CapabilityMap;
21 import org.apache.jetspeed.capability.CapabilityMapFactory;
22 import org.apache.jetspeed.om.registry.MediaTypeEntry;
23 import org.apache.jetspeed.om.registry.PortletEntry;
24 import org.apache.jetspeed.portal.BasePortletConfig;
25 import org.apache.jetspeed.portal.expire.Expire;
26 import org.apache.jetspeed.portal.expire.ExpireFactory;
27 import org.apache.jetspeed.portal.Portlet;
28 import org.apache.jetspeed.portal.PortletConfig;
29 import org.apache.jetspeed.portal.PortletException;
30 import org.apache.jetspeed.portal.PortletState;
31 import org.apache.jetspeed.services.persistence.PersistenceManager;
32 import org.apache.jetspeed.services.persistence.PortalPersistenceException;
33 import org.apache.jetspeed.portal.PortletInstance;
34 import org.apache.jetspeed.services.portletcache.Cacheable;
35 import org.apache.jetspeed.services.Registry;
36 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
37 import org.apache.jetspeed.services.logging.JetspeedLogger;
38 import org.apache.jetspeed.util.JetspeedException;
39 import org.apache.jetspeed.util.MetaData;
40 import org.apache.jetspeed.util.MimeType;
41
42 //ecs
43
import org.apache.jetspeed.util.JetspeedClearElement;
44 import org.apache.ecs.ConcreteElement;
45
46 //turbine stuff
47
import org.apache.turbine.services.cache.CachedObject;
48 import org.apache.turbine.services.cache.Refreshable;
49 import org.apache.turbine.util.RunData;
50
51 //java stuff
52
import java.util.Hashtable JavaDoc;
53 import java.util.Iterator JavaDoc;
54 /**
55 <p>
56 Should be used by most Portlets that wish to conform to default behavior
57 </p>
58
59 <p>
60 PERFORMANCE NOTE:
61
62 getContent returns a StringElement that was generated on setContent(). This is
63 used so that performance is increased since ECS does not have to work overtime
64 to generate output.
65 </p>
66
67 @author <A HREF="mailto:burton@apache.org">Kevin A. Burton</A>
68 @author <A HREF="mailto:raphael@apache.org">RaphaŽl Luta</A>
69 @author <A HREF="mailto:sgala@apache.org">Santiago Gala</A>
70 @author <A HREF="mailto:paulsp@apache.org">Paul Spencer</A>
71 @author <A HREF="mailto:morciuch@apache.org">Mark Orciuch</A>
72 @version $Id: AbstractPortlet.java,v 1.65 2004/03/29 21:38:42 taylor Exp $
73 */

74 public abstract class AbstractPortlet implements Portlet, PortletState, Cacheable, Refreshable
75 {
76
77     /**
78      * Static initialization of the logger for this class
79      */

80     private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(AbstractPortlet.class.getName());
81     
82     private boolean cacheable = true;
83     private PortletConfig pc = null;
84
85     /**
86     Provide a required name for this Portlet
87     */

88     private String JavaDoc name = null;
89
90     /**
91     Provide a Unique Portlet ID
92     */

93     private String JavaDoc id = null;
94
95     /**
96     Cache handle for this object.
97     */

98     private String JavaDoc handle = "";
99
100     /**
101     Expiration time of object in milliseconds since the standard base time
102     known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
103     */

104     private Long JavaDoc expirationMillis = null;
105
106     /**
107     Holds instances of ConcreteElements (Portlet output/content)
108     based on its current CapabilityMap.
109     */

110     protected Hashtable JavaDoc content = new Hashtable JavaDoc();
111
112     /**
113     The time this portlet was created.
114     */

115     private long creationTime;
116
117     /**
118      * Handle to cached object
119      */

120     private CachedObject cachedObject = null;
121
122     /**
123     */

124     protected void clearContent() {
125         this.content.clear();
126     }
127
128     /**
129      */

130     protected void setContent( ConcreteElement content ) {
131         this.setContent( content,
132                          CapabilityMapFactory.getDefaultCapabilityMap() );
133     }
134
135     /**
136     */

137     protected void setContent( String JavaDoc content ) {
138         this.setContent( new JetspeedClearElement( content ),
139                          CapabilityMapFactory.getDefaultCapabilityMap() );
140     }
141
142     /**
143     */

144     protected void setContent( ConcreteElement content,
145                                CapabilityMap map )
146                           throws IllegalArgumentException JavaDoc
147     {
148         CapabilityMap mymap = map;
149         if ( mymap == null ) {
150             mymap = CapabilityMapFactory.getDefaultCapabilityMap();
151         }
152
153         ConcreteElement buffer = new JetspeedClearElement( content.toString( ) );
154         this.content.put( mymap.toString(), buffer );
155     }
156
157
158     /*
159      * Implement methods required by Refreshable
160      */

161
162     /**
163      * Usually called by caching system when portlet is marked as expired, but
164      * has not be idle longer then TimeToLive.
165      *
166      * This method should be implement in cachable portlets
167      */

168     public void refresh() {
169         /*
170          * The following message is here to add in debugging. It is
171          * expected the any portlet type that is refreshable will
172          * implement this method.
173          */

174         logger.debug( "AbstractPortlet - Refreshing " + this.getName() );
175     }
176
177     /*
178      * Implement methods required by Cacheable
179      */

180
181     /**
182      * Is this portlet cacheable. It is the portlet's responsability to
183      * cache the content.
184      *
185      * @return <CODE>true</CODE> Cachable<BR>
186      * <CODE>false</CODE> Not cachable
187      */

188     public boolean isCacheable() {
189         return this.cacheable;
190     }
191
192     /**
193      * Set cachable. This should only be called in the portlet's init().
194      *
195      * @param cacheable <CODE>true</CODE> Portlet is cachable<BR>
196      * <CODE>false</CODE> Portlet is NOT cachable
197      */

198     public void setCacheable(boolean cacheable) {
199         this.cacheable = cacheable;
200     }
201
202
203     /**
204      * Used by a Cacheable object to determine when it should expire itself from the cache.
205      *
206      * @return Expire
207      */

208     public Expire getExpire() {
209         try {
210             return ExpireFactory.getExpire( this, ExpireFactory.NO_EXPIRE );
211         } catch ( JetspeedException e ) {
212             logger.error("Exception", e);
213             return null;
214         }
215     }
216
217     /**
218      * <p>Used by the cache to get a unique reference on what you want to add
219      * and then retrieve in the future from the cache</p>
220      *
221      * <p>Most implementations should just call the CacheHandleManager with
222      * the given params within the implementation and just return this.</p>
223      *
224      * @return Cache handle (key)
225      */

226     public final String JavaDoc getHandle() {
227         return this.handle;
228     }
229
230     /**
231      * Used by a Cacheable object to determine when it should
232      * expire itself from the cache.
233      *
234      * @param handle Cache Handle
235      *
236      * @deprecated cacheable classes should now implement a static getHandle(config) method
237      */

238     public final void setHandle( String JavaDoc handle ) {
239         this.handle = handle;
240     }
241
242     /**
243      * Set the expiration time in milliseconds.
244      *
245      * @return Expiration time in milliseconds since epoch, or null if the expiration was not set.
246      */

247     public Long JavaDoc getExpirationMillis() {
248       return this.expirationMillis;
249     }
250
251     /**
252      * Sets the cache expiration time. When the portlet is stale (expired),
253      * the refresh() will be called if the portlet has not been untouched
254      * longer then then it's TimeToLive.
255      *
256      * @param expirationMillis setExpirationMillis Expiration in milliseconds since epoch
257      */

258     public void setExpirationMillis( long expirationMillis) {
259       this.expirationMillis = new Long JavaDoc(expirationMillis);
260
261       if (cachedObject != null) {
262           long expirationInterval = this.expirationMillis.longValue() - cachedObject.getCreated();
263           if (expirationInterval > 0) {
264               cachedObject.setExpires(expirationInterval);
265           } else {
266               cachedObject.setStale(true);
267           }
268       }
269     }
270
271     /**
272      * Builds a new cache handle for this cacheable class with the specified
273      * config object.
274      *
275      * @param config The configuration object to use for building the handle
276      *
277      * @return A cache handle
278      */

279     public static Object JavaDoc getHandle(Object JavaDoc config)
280     {
281         //this implementation expects a PortletConfig object as its
282
// configuration
283
PortletConfig pc = null;
284
285         if (!(config instanceof PortletConfig))
286         {
287             return null;
288
289         }
290
291         // By default, only take into account the init parameters
292
pc = (PortletConfig)config;
293         StringBuffer JavaDoc handle = new StringBuffer JavaDoc(256);
294
295         if (pc.getURL()!=null && pc.isCachedOnURL())
296         {
297             handle.append(String.valueOf(pc.getURL().hashCode()));
298         }
299
300         Iterator JavaDoc i = pc.getInitParameterNames();
301         while(i.hasNext())
302         {
303             String JavaDoc name = (String JavaDoc)i.next();
304             String JavaDoc value = pc.getInitParameter(name);
305
306             if (value!=null)
307             {
308                 handle.append("|").append(name).append("-").append(value);
309             }
310         }
311
312         return handle.toString();
313     }
314
315     /**
316      * Set this portlet's cached object.
317      *
318      * @param cachedObject Cached Object associated to this portlet
319      */

320      public void setCachedObject(CachedObject cachedObject) {
321         this.cachedObject = cachedObject;
322     }
323
324     /*
325      * Implement methods required by Portlet
326      */

327
328     /**
329      * Get the portlet's name
330      *
331      * @return Name of the portlet
332      */

333     public String JavaDoc getName()
334     {
335
336         if ( name == null )
337         {
338             if (getPortletConfig()!=null)
339             {
340                 if (getPortletConfig().getName()!=null)
341                 {
342                     return getPortletConfig().getName();
343                 }
344                 else
345                 {
346                     return this.getClass().getName();
347                 }
348             }
349         }
350
351         return name;
352
353     }
354
355     /**
356      * Set the name of the portlet
357      *
358      * @param name Name of the portlet
359      */

360     public void setName( String JavaDoc name ) {
361         this.name = name;
362     }
363
364     /**
365      * Get the config of this servlet
366      *
367      * @return PortletConfig Portlet
368      */

369     public PortletConfig getPortletConfig() {
370         return this.pc;
371     }
372
373     /**
374      * Set's the configuration of this servlet.
375      */

376     public void setPortletConfig( PortletConfig pc ) {
377         this.pc = pc;
378     }
379
380     /**
381      * @param rundata The RunData object for the current request
382      */

383     public ConcreteElement getContent( RunData rundata ) {
384
385         return getContent( rundata, null , true );
386     }
387
388     public ConcreteElement getContent( RunData rundata, CapabilityMap map ) {
389         CapabilityMap mymap = map;
390         if ( mymap == null ) mymap = CapabilityMapFactory.getCapabilityMap( rundata );
391
392         return (ConcreteElement)content.get( mymap.toString() );
393     }
394
395     /**
396      * @param rundata The RunData object for the current request
397      */

398     public ConcreteElement getContent( RunData rundata,
399                                        CapabilityMap map,
400                                        boolean allowRecurse ) {
401
402         CapabilityMap mymap = map;
403         if ( mymap == null ) mymap = CapabilityMapFactory.getCapabilityMap( rundata );
404
405         ConcreteElement element = (ConcreteElement)content.get( mymap.toString() );
406
407         if ( element == null ) {
408             if ( allowRecurse ) {
409                 try {
410                     // init will put content under default cmap
411
init( );
412                     element = getContent( rundata, mymap, false );
413                     if( element != null ) {
414                         // now we put it under our cmap
415
this.setContent( element, mymap );
416                     }
417                 } catch (Exception JavaDoc e) {
418                     element = new JetspeedClearElement("Error when retrieving Portlet contents");
419                     if( logger.isDebugEnabled() ) {
420                         logger.debug( "Error when retrieving Portlet contents", e );
421                     }
422                 }
423             } else {
424                 if( element == null ) {
425                     //FIXME: Let's asume that the contents under "default" map are good
426
mymap = CapabilityMapFactory.getDefaultCapabilityMap();
427                     element = (ConcreteElement)content.get( mymap.toString() );
428                     if( element == null ) {
429                         element = new JetspeedClearElement("Unknown Problem getting Contents");
430                     }
431                 }
432             }
433         }
434
435         return element;
436
437     }
438
439     /**
440      * Provide a description within PML if the user has specified one.
441      *
442      * @return a null entry if the user hasn't defined anything
443      */

444     public String JavaDoc getDescription() {
445         if (getPortletConfig()!=null)
446             if (getPortletConfig().getMetainfo()!=null)
447                 return getPortletConfig().getMetainfo().getDescription();
448
449         return null;
450     }
451
452     /**
453      * Provide a Description within PML if the user has specified one.
454      *
455      * @return a null if entry AND portlet have not defined a description
456      */

457     public String JavaDoc getDescription(String JavaDoc instanceDescription)
458     {
459       if (instanceDescription != null)
460           return instanceDescription;
461       return getDescription();
462     }
463
464     /**
465      */

466     public void setDescription( String JavaDoc description ) {
467         PortletConfig pc = getPortletConfig();
468         if (pc==null) {
469             pc = new BasePortletConfig();
470             setPortletConfig(pc);
471         }
472
473         MetaData meta = pc.getMetainfo();
474         if (meta==null) {
475             meta = new MetaData();
476             pc.setMetainfo(meta);
477         }
478
479         meta.setDescription(description);
480     }
481
482     //provide default titles so that the user can define them in PML
483

484     /**
485      * Provide a title within PML if the user has specified one.
486      *
487      * @return a null entry if the user hasn't defined anything
488      */

489     public String JavaDoc getTitle()
490     {
491         if (getPortletConfig()!=null)
492             if (getPortletConfig().getMetainfo()!=null)
493                 return getPortletConfig().getMetainfo().getTitle();
494
495         return null;
496     }
497
498     /**
499      * Provide a title within PML if the user has specified one.
500      *
501      * @return a null if entry AND portlet have not defined a title
502      */

503     public String JavaDoc getTitle(String JavaDoc instanceTitle)
504     {
505       if (instanceTitle != null)
506           return instanceTitle;
507       return getTitle();
508     }
509
510     /**
511      * Set the title for this Portlet.
512      * @param title Portlet title.
513      */

514     public void setTitle( String JavaDoc title ) {
515         PortletConfig pc = getPortletConfig();
516         if (pc==null) {
517             pc = new BasePortletConfig();
518             setPortletConfig(pc);
519         }
520
521         MetaData meta = pc.getMetainfo();
522         if (meta==null) {
523             meta = new MetaData();
524             pc.setMetainfo(meta);
525         }
526
527         meta.setTitle(title);
528     }
529
530
531     /**
532      * Getter for property image.
533      * @return Name of portlet image, icon. The name is expected to be in the form of a URL.
534      */

535     public String JavaDoc getImage()
536     {
537         if (getPortletConfig()!=null)
538             if (getPortletConfig().getMetainfo()!=null)
539                 return getPortletConfig().getMetainfo().getImage();
540
541         return null;
542     }
543
544     /**
545      * Getter for property image.
546      * @return a null if entry AND portlet have not defined an icon.
547      */

548     public String JavaDoc getImage(String JavaDoc instanceImage)
549     {
550       if (instanceImage != null)
551           return instanceImage;
552       return getImage();
553     }
554
555     public void setImage( String JavaDoc image )
556     {
557         PortletConfig pc = getPortletConfig();
558         if (pc==null) {
559             pc = new BasePortletConfig();
560             setPortletConfig(pc);
561         }
562
563         MetaData meta = pc.getMetainfo();
564         if (meta==null) {
565             meta = new MetaData();
566             pc.setMetainfo(meta);
567         }
568
569         meta.setImage(image);
570     }
571
572     /**
573      * Is the portled editable/customizeable.
574      * @param rundata The RunData object for the current request
575      * @return <CODE>true</CODE> Editing is allow
576      * <CODE>false</CODE> Editing is NOT alowed
577      */

578     public boolean getAllowEdit( RunData rundata )
579     {
580         return allowCustomize(rundata);
581     }
582
583     /**
584      * Is the portled viewable.
585      * @param rundata The RunData object for the current request
586      * @return <CODE>true</CODE> Viewing is allow
587      * <CODE>false</CODE> Viewing is NOT alowed
588      *
589      * Override this method to control your own View behavior
590      */

591     public boolean getAllowView( RunData rundata )
592     {
593         return allowView( rundata );
594     }
595     
596     /**
597      * Can this portlet be maximized
598      * @param rundata The RunData object for the current request
599      * @return <CODE>true</CODE> Portlet can be maximized<br>
600      * <CODE>false</CODE> Portlet can NOT be maximized
601      */

602     public boolean getAllowMaximize( RunData rundata )
603     {
604         return allowMaximize( rundata );
605     }
606
607     /**
608      * By default don't provide any initialization
609      */

610     public void init( ) throws PortletException
611     {
612         // make sure to clean all content
613
clearContent();
614     }
615
616     /**
617      */

618     public long getCreationTime() {
619         return this.creationTime;
620     }
621
622     /**
623      */

624     public void setCreationTime( long creationTime ) {
625         this.creationTime = creationTime;
626     }
627
628     /**
629      */

630     public boolean supportsType( MimeType mimeType )
631     {
632         PortletEntry entry = (PortletEntry)Registry.getEntry(Registry.PORTLET, getName() );
633         String JavaDoc baseType = mimeType.toString();
634         if (entry!=null)
635         {
636             Iterator JavaDoc i = entry.listMediaTypes();
637
638             while(i.hasNext())
639             {
640                 String JavaDoc name = (String JavaDoc)i.next();
641                 MediaTypeEntry media = (MediaTypeEntry)Registry.getEntry(Registry.MEDIA_TYPE, name);
642                 if (media != null)
643                 {
644                     if (baseType.equals(media.getMimeType())) return true;
645                 }
646             }
647         }
648
649         return MimeType.HTML.equals( mimeType );
650     }
651
652     /*
653      * Implement methods required by PortletState
654      */

655
656     /**
657      * Implements the default close behavior:
658      * security permissions will be checked.
659      *
660      * @param rundata The RunData object for the current request
661      */

662     public boolean allowClose( RunData rundata )
663     {
664         //Security will not allow this call to succeed if there are
665
//not enough permissions
666
return !isClosed( rundata );
667     }
668
669     /**
670      * Returns true if this portlet is currently closed
671      *
672      * @param rundata The RunData object for the current request
673      */

674     public boolean isClosed(RunData rundata)
675     {
676         return this.getAttribute("_display", "normal", rundata ).equals("closed");
677     }
678
679     /**
680      * Toggles the portlet state between closed and normal
681      *
682      * @param minimized the new portlet state
683      * @param rundata The RunData object for the current request
684      */

685     public void setClosed(boolean close, RunData rundata)
686     {
687         if( allowClose( rundata ) )
688         {
689             this.setAttribute("_display", close ? "closed" : "normal", rundata );
690         }
691     }
692
693     /**
694      * Implements the default info behavior:
695      * security permissions will be checked.
696      *
697      * @param rundata The RunData object for the current request
698      */

699     public boolean allowInfo( RunData rundata )
700     {
701         //Security will not allow this call to succeed if there are
702
//not enough permissions
703
return true;
704     }
705
706     /**
707      * Implements the default customize behavior:
708      * security permissions will be checked.
709      *
710      * @param rundata The RunData object for the current request
711      */

712     public boolean allowCustomize( RunData rundata )
713     {
714         //Security will not allow this call to succeed if there are
715
//not enough permissions
716
return true;
717     }
718
719     /**
720      * Implements the default maximize behavior:
721      * security permissions will be checked.
722      *
723      * @param rundata The RunData object for the current request
724      */

725     public boolean allowMaximize( RunData rundata )
726     {
727         //Security will not allow this call to succeed if there are
728
//not enough permissions
729
return true;
730     }
731
732     /**
733      * Implements the default info behavior:
734      * security permissions will be checked.
735      *
736      * @param rundata The RunData object for the current request
737      */

738     public boolean allowMinimize( RunData rundata )
739     {
740         //Security will not allow this call to succeed if there are
741
//not enough permissions
742
return true;
743     }
744
745     /**
746      * Implements the default view behavior:
747      * security permissions will be checked.
748      *
749      * @param rundata The RunData object for the current request
750      */

751     public boolean allowView( RunData rundata )
752     {
753         //Security will not allow this call to succeed if there are
754
//not enough permissions
755
return true;
756     }
757     
758     /**
759      * Implements the default print friendly format behavior:
760      * security permissions will be checked.
761      *
762      * @param rundata The RunData object for the current request
763      */

764     public boolean allowPrintFriendly( RunData rundata )
765     {
766         //Security will not allow this call to succeed if there are
767
//not enough permissions
768
return true;
769     }
770
771     /**
772      * Returns true if this portlet is currently minimized
773      *
774      * @param rundata The RunData object for the current request
775      */

776     public boolean isMinimized(RunData rundata)
777     {
778         return this.getAttribute("_display", "normal", rundata ).equals("minimized");
779     }
780
781     /**
782      * Change the portlet visibility state ( minimized <-> normal )
783      *
784      * @param minimize True if the portlet change to minimized
785      * @param rundata The RunData object for the current request
786      */

787     public void setMinimized( boolean minimize, RunData rundata )
788     {
789         if( allowMinimize( rundata ) )
790         {
791             this.setAttribute("_display", minimize ? "minimized" : "normal", rundata );
792         }
793     }
794
795     /**
796      * Returns TRUE if the title bar in should be displayed. The title bar includes
797      * the portlet title and action buttons. This
798      *
799      * @param rundata The RunData object for the current request
800      */

801     public boolean isShowTitleBar(RunData rundata)
802     {
803         if (getPortletConfig()!=null)
804         {
805             // Parameter can exist in PSML or <portlet-entry>
806
return Boolean.valueOf(getPortletConfig().getInitParameter("_showtitlebar","true")).booleanValue();
807         }
808         return this.getAttribute("_showtitlebar", "true", rundata ).equals("true");
809     }
810     // utility methods
811

812     /**
813      * Retrieve a portlet attribute from persistent storage
814      *
815      * @param attrName The attribute to retrieve
816      * @param attrDefValue The value if the attr doesn't exists
817      * @param rundata The RunData object for the current request
818      * @return The attribute value
819      */

820     public String JavaDoc getAttribute( String JavaDoc attrName, String JavaDoc attrDefValue, RunData rundata )
821     {
822         String JavaDoc attrValue = null ;
823
824         PortletInstance instance = PersistenceManager.getInstance(this, rundata);
825         attrValue = instance.getAttribute(attrName, attrDefValue);
826
827         return attrValue;
828     }
829
830     /**
831      * Stores a portlet attribute in persistent storage
832      *
833      * @param attrName The attribute to retrieve
834      * @paarm attrValue The value to store
835      * @param rundata The RunData object for the current request
836      */

837     public void setAttribute( String JavaDoc attrName, String JavaDoc attrValue, RunData rundata )
838     {
839         try
840         {
841             PortletInstance instance = PersistenceManager.getInstance(this, rundata);
842             instance.setAttribute(attrName, attrValue);
843             PersistenceManager.store(instance);
844         }
845         catch (PortalPersistenceException e)
846         {
847             logger.error("Exception while setting attribute "+attrName+" for portlet "+getName(), e);
848         }
849     }
850
851     /**
852      * Gets the portlet instance associated with this portlet.
853      *
854      * @param rundata The RunData object for the current request
855      * @return PortletInstance
856      */

857     public PortletInstance getInstance(RunData rundata)
858     {
859         return PersistenceManager.getInstance(this, rundata);
860     }
861
862     //
863
// DST: Shouldn't getID and setID be deprecated and added to PortletInstance...
864
//
865
public String JavaDoc getID()
866     {
867         return id;
868     }
869
870     public void setID(String JavaDoc id)
871     {
872         this.id = id;
873     }
874
875     /**
876     * @return true if the portlet does its own customization
877     */

878     public boolean providesCustomization()
879     {
880         return false;
881     }
882
883 }
884
Popular Tags