KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > portlet > deployment > jboss > PortletAppDeployment


1 /*****************************************
2  * *
3  * JBoss Portal: The OpenSource Portal *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  *****************************************/

9 package org.jboss.portal.portlet.deployment.jboss;
10
11 import org.jboss.portal.server.deployment.jboss.Deployment;
12 import org.jboss.portal.server.deployment.PortalWebApp;
13 import org.jboss.portal.server.metadata.ComponentConfigurationMetaData;
14 import org.jboss.portal.server.metadata.PreferenceMetaData;
15 import org.jboss.portal.server.metadata.ContentTypesMetaData;
16 import org.jboss.portal.server.metadata.ContentTypeMetaData;
17 import org.jboss.portal.server.metadata.InterceptorListMetaData;
18 import org.jboss.portal.server.metadata.InterceptorMetaData;
19 import org.jboss.portal.server.plugins.mode.Mode;
20 import org.jboss.portal.server.ServerManager;
21 import org.jboss.portal.server.kernel.ServiceFailureException;
22 import org.jboss.portal.server.config.Configuration;
23 import org.jboss.portal.portlet.metadata.PortletMetaData;
24 import org.jboss.portal.portlet.metadata.PortletApplicationMetaData;
25 import org.jboss.portal.portlet.metadata.PortletModeMetaData;
26 import org.jboss.portal.portlet.metadata.WindowStateMetaData;
27 import org.jboss.portal.portlet.metadata.UserAttributeMetaData;
28 import org.jboss.portal.portlet.metadata.SecurityConstraintMetaData;
29 import org.jboss.portal.portlet.metadata.UserDataConstraintMetaData;
30 import org.jboss.portal.portlet.metadata.TransportGuarantee;
31 import org.jboss.portal.portlet.metadata.PortletPreferencesMetaData;
32 import org.jboss.portal.portlet.metadata.LanguagesMetaData;
33 import org.jboss.portal.portlet.metadata.SecurityRoleRefMetaData;
34 import org.jboss.portal.portlet.metadata.ParameterMetaData;
35 import org.jboss.portal.portlet.metadata.DescriptionMetaData;
36 import org.jboss.portal.portlet.metadata.DisplayNameMetaData;
37 import org.jboss.portal.portlet.PortletUtils;
38 import org.jboss.portal.portlet.PortletInitializationException;
39 import org.jboss.portal.common.util.XML;
40 import org.jboss.portal.common.util.LocaleInfo;
41 import org.jboss.portal.common.util.Tools;
42 import org.jboss.deployment.DeploymentException;
43 import org.w3c.dom.Element JavaDoc;
44 import org.w3c.dom.NodeList JavaDoc;
45 import org.w3c.dom.Document JavaDoc;
46
47 import javax.servlet.ServletContext JavaDoc;
48 import javax.xml.parsers.DocumentBuilder JavaDoc;
49 import java.net.URL JavaDoc;
50 import java.util.Set JavaDoc;
51 import java.util.HashSet JavaDoc;
52 import java.util.Iterator JavaDoc;
53 import java.util.LinkedHashSet JavaDoc;
54 import java.util.List JavaDoc;
55 import java.util.ArrayList JavaDoc;
56 import java.util.Map JavaDoc;
57 import java.util.HashMap JavaDoc;
58 import java.util.Locale JavaDoc;
59 import java.util.Collections JavaDoc;
60 import java.io.InputStream JavaDoc;
61 import java.io.File JavaDoc;
62 import java.io.FileOutputStream JavaDoc;
63 import java.io.IOException JavaDoc;
64
65 /**
66  * @author <a HREF="mailto:julien@jboss.org">Julien Viet</a>
67  * @version $Revision: 1.8 $
68  */

69 public class PortletAppDeployment extends Deployment
70 {
71
72    /**
73     * The existing configurations.
74     */

75    protected Map JavaDoc configurations;
76
77    /**
78     * .
79     */

80    protected PortletApplicationMetaData portletAppMD;
81
82    /**
83     * .
84     */

85    protected PortletMetaData[] portletMDs;
86
87    /**
88     * JBoss specific deployment descriptor for portlets.
89     */

90    protected Map JavaDoc jbossPortletElts;
91
92    public PortletAppDeployment(ServerManager serverManager, URL JavaDoc url, PortalWebApp pwa, String JavaDoc appName)
93    {
94       super(serverManager, url, pwa, appName);
95    }
96
97    public void create() throws DeploymentException
98    {
99       //
100
readJBossDescriptor();
101
102       InputStream JavaDoc in = null;
103       try
104       {
105          // Load the component configurations
106
Configuration config = getServerManager().getConfiguration();
107          in = config.load("/standardjboss-portlet.xml");
108          DocumentBuilder JavaDoc builder = XML.getDocumentBuilderFactory().newDocumentBuilder();
109          Document JavaDoc doc = builder.parse(in);
110          Element JavaDoc portalAppElt = doc.getDocumentElement();
111          Map JavaDoc configurations = new HashMap JavaDoc();
112          List JavaDoc componentConfigurationElts = XML.getChildren(portalAppElt, "portlet-configuration");
113          for (int i = 0; i < componentConfigurationElts.size(); i++)
114          {
115             Element JavaDoc componentConfigurationElt = (Element JavaDoc)componentConfigurationElts.get(i);
116             Element JavaDoc configurationNameElt = XML.getUniqueChild(componentConfigurationElt, "configuration-name", true);
117             String JavaDoc name = XML.asString(configurationNameElt);
118
119             ComponentConfigurationMetaData componentConfigurationMD = new ComponentConfigurationMetaData(name);
120             Element JavaDoc interceptorsElt = XML.getUniqueChild(componentConfigurationElt, "interceptors", true);
121             loadInterceptorSetMetaData(componentConfigurationMD.getInterceptorList(), interceptorsElt);
122
123             configurations.put(componentConfigurationMD.getName(), componentConfigurationMD);
124          }
125          this.configurations = configurations;
126       }
127       catch (Exception JavaDoc e)
128       {
129          throw new DeploymentException("Cannot read default configuration standardjboss-portlet.xml", e);
130       }
131       finally
132       {
133          Tools.safeClose(in);
134       }
135
136       importTLD();
137
138       //
139
try
140       {
141          in = url.openStream();
142          DocumentBuilder JavaDoc builder = XML.getDocumentBuilderFactory().newDocumentBuilder();
143          Document JavaDoc doc = builder.parse(url.openStream());
144
145          //
146
Element JavaDoc portletAppElt = doc.getDocumentElement();
147          portletAppMD = buildPortletAppMetaData(portletAppElt);
148
149          //
150
List JavaDoc portletElts = XML.getChildren(portletAppElt, "portlet");
151          portletMDs = new PortletMetaData[portletElts.size()];
152          for (int i = 0; i < portletElts.size(); i++)
153          {
154             Element JavaDoc portletElt = (Element JavaDoc)portletElts.get(i);
155             portletMDs[i] = buildPortletMetaData(portletElt);
156          }
157
158          //
159
getServerManager().deploy(portletAppMD);
160          for (int i = 0; i < portletMDs.length; i++)
161          {
162             PortletMetaData portletMD = portletMDs[i];
163             try
164             {
165                getServerManager().deploy(portletMD);
166             }
167             catch (ServiceFailureException e)
168             {
169                Exception JavaDoc failure = e.getException();
170                if (failure instanceof PortletInitializationException)
171                {
172                   PortletInitializationException pie = (PortletInitializationException)failure;
173                   log.error("The portlet cannot be started due to an error that occcured during init", pie);
174                }
175                else
176                {
177                   throw e;
178                }
179             }
180          }
181       }
182       catch (Exception JavaDoc e)
183       {
184          throw new DeploymentException("Cannot deploy portlet application", e);
185       }
186       finally
187       {
188          Tools.safeClose(in);
189       }
190    }
191
192    /**
193     * Import the portlet jsp tag TLD in the deployed application.
194     */

195    protected void importTLD()
196    {
197       // Import the tld automatically in the web app
198
File JavaDoc targetContextRoot = new File JavaDoc(pwa.getServletContext().getRealPath("/WEB-INF"));
199       if (targetContextRoot.exists() && targetContextRoot.isDirectory())
200       {
201          InputStream JavaDoc sourceTLD = null;
202          FileOutputStream JavaDoc targetTLD = null;
203          try
204          {
205             sourceTLD = Thread.currentThread().getContextClassLoader().getResourceAsStream("org/jboss/portal/portlet/portlet.tld");
206             targetTLD = new FileOutputStream JavaDoc(new File JavaDoc(targetContextRoot, "portlet.tld"));
207             Tools.copy(sourceTLD, targetTLD);
208             log.debug("Copied portlet.tld file");
209          }
210          catch (IOException JavaDoc e)
211          {
212             log.warn("Cannot copy TLD file to the portlet application", e);
213          }
214          finally
215          {
216             Tools.safeClose(sourceTLD);
217             Tools.safeClose(targetTLD);
218          }
219       }
220       else
221       {
222          log.warn("Cannot access the WEB-INF for the portlet application");
223       }
224    }
225
226    public void destroy() throws DeploymentException
227    {
228       for (int i = 0; i < portletMDs.length; i++)
229       {
230          PortletMetaData portletMD = portletMDs[i];
231          getServerManager().undeploy(portletMD.getID());
232       }
233       getServerManager().undeploy(portletAppMD.getID());
234    }
235
236    // Application related **********************************************************************************************
237

238    /**
239     * Can be overriden by subclass to provide extension.
240     */

241    protected PortletMetaData createPortletMetaData(String JavaDoc applicationName, String JavaDoc portletName)
242    {
243       return new PortletMetaData(applicationName, portletName);
244    }
245
246    /**
247     * <complexType name="portlet-appType">
248     * <sequence>
249     * <element name="portlet" type="portlet:portletType" minOccurs="0" maxOccurs="unbounded"></element>
250     * <element name="custom-portlet-mode" type="portlet:custom-portlet-modeType" minOccurs="0" maxOccurs="unbounded"/>
251     * <element name="custom-window-state" type="portlet:custom-window-stateType" minOccurs="0" maxOccurs="unbounded"/>
252     * <element name="user-attribute" type="portlet:user-attributeType" minOccurs="0" maxOccurs="unbounded"/>
253     * <element name="security-constraint" type="portlet:security-constraintType" minOccurs="0" maxOccurs="unbounded"/>
254     * </sequence>
255     * <attribute name="version" type="string" use="required"/>
256     * </complexType>
257     */

258    protected PortletApplicationMetaData buildPortletAppMetaData(Element JavaDoc portletAppElt)
259    {
260       //
261
PortletApplicationMetaData portletAppMD = new PortletApplicationMetaData(appName,
262          pwa.getServletContext(),
263          pwa.getContextPath(),
264          pwa.getClassLoader());
265
266       //
267
portletAppMD.setVersion(portletAppElt.getAttribute("version"));
268
269       //
270
List JavaDoc customPortletModeElts = XML.getChildren(portletAppElt, "custom-portlet-mode");
271       for (int i = 0; i < customPortletModeElts.size(); i++)
272       {
273          Element JavaDoc customPortletModeElt = (Element JavaDoc)customPortletModeElts.get(i);
274          PortletModeMetaData customPortletModeMD = buildCustomPortletModeMetaData(customPortletModeElt);
275          portletAppMD.getPortletModes().put(customPortletModeMD.getPortletMode(), customPortletModeMD);
276       }
277
278       //
279
List JavaDoc customWindowStateElts = XML.getChildren(portletAppElt, "custom-window-state");
280       for (int i = 0; i < customWindowStateElts.size(); i++)
281       {
282          Element JavaDoc customWindowStateElt = (Element JavaDoc)customWindowStateElts.get(i);
283          WindowStateMetaData customWindowStateMD = buildCustomWindowStateMetaData(customWindowStateElt);
284          portletAppMD.getWindowStates().put(customWindowStateMD.getWindowState(), customWindowStateMD);
285       }
286
287       //
288
List JavaDoc userAttributeElts = XML.getChildren(portletAppElt, "user-attribute");
289       for (int i = 0; i < userAttributeElts.size(); i++)
290       {
291          Element JavaDoc userAttributeElt = (Element JavaDoc)userAttributeElts.get(i);
292          UserAttributeMetaData userAttributeMD = buildUserAttributeMetaData(userAttributeElt);
293          portletAppMD.getUserAttributes().put(userAttributeMD.getName(), userAttributeMD);
294       }
295
296       //
297
List JavaDoc securityConstraintElts = XML.getChildren(portletAppElt, "security-constraint");
298       for (int i = 0; i < securityConstraintElts.size(); i++)
299       {
300          Element JavaDoc securityConstraintElt = (Element JavaDoc)securityConstraintElts.get(i);
301          SecurityConstraintMetaData securityConstraintMD = buildSecurityConstraintMetaData(securityConstraintElt);
302          portletAppMD.getSecurityConstraints().add(securityConstraintMD);
303       }
304
305       return portletAppMD;
306    }
307
308    /**
309     * <complexType name="user-attributeType">
310     * <annotation>
311     * <documentation>
312     * User attribute defines a user specific attribute that the
313     * portlet application needs. The portlet within this application
314     * can access this attribute via the request parameter USER_INFO
315     * map.
316     * Used in: portlet-app
317     * </documentation>
318     * </annotation>
319     * <sequence>
320     * <element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
321     * <element name="name" type="portlet:nameType"/>
322     * </sequence>
323     * </complexType>
324     */

325    private UserAttributeMetaData buildUserAttributeMetaData(Element JavaDoc userAttributeElt)
326    {
327       UserAttributeMetaData userAttributeMD = new UserAttributeMetaData();
328       userAttributeMD.setDescriptions(buildDescriptionsMetaData(XML.getChildren(userAttributeElt, "description")));
329       userAttributeMD.setName(XML.asString(XML.getUniqueChild(userAttributeElt, "name", true)));
330       return userAttributeMD;
331    }
332
333    /**
334     * <complexType name="custom-window-stateType">
335     * <annotation>
336     * <documentation>
337     * A custom window state that one or more portlets in this
338     * portlet application supports.
339     * Used in: portlet-app
340     * </documentation>
341     * </annotation>
342     * <sequence>
343     * <element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
344     * <element name="window-state" type="portlet:window-stateType"/>
345     * </sequence>
346     * </complexType>
347     * <p/>
348     * <complexType name="window-stateType">
349     * <annotation>
350     * <documentation>
351     * Portlet window state. Window state names are not case sensitive.
352     * Used in: custom-window-state
353     * </documentation>
354     * </annotation>
355     * <simpleContent>
356     * <extension base="string"/>
357     * </simpleContent>
358     * </complexType>
359     */

360    private WindowStateMetaData buildCustomWindowStateMetaData(Element JavaDoc customWindowStateElt)
361    {
362       WindowStateMetaData customWindowStateMD = new WindowStateMetaData();
363       customWindowStateMD.setDescriptions(buildDescriptionsMetaData(XML.getChildren(customWindowStateElt, "description")));
364       customWindowStateMD.setWindowState(PortletUtils.decodeWindowState(XML.asString(XML.getUniqueChild(customWindowStateElt, "window-state", true))));
365       return customWindowStateMD;
366    }
367
368    /**
369     * <complexType name="custom-portlet-modeType">
370     * <annotation>
371     * <documentation>
372     * A custom portlet mode that one or more portlets in
373     * this portlet application supports.
374     * Used in: portlet-app
375     * </documentation>
376     * </annotation>
377     * <sequence>
378     * <element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
379     * <element name="portlet-mode" type="portlet:portlet-modeType"/>
380     * </sequence>
381     * </complexType>
382     * <p/>
383     * <complexType name="portlet-modeType">
384     * <annotation>
385     * <documentation>
386     * Portlet modes. The specification pre-defines the following values
387     * as valid portlet mode constants:
388     * "edit", "help", "view".
389     * Portlet mode names are not case sensitive.
390     * Used in: custom-portlet-mode, supports
391     * </documentation>
392     * </annotation>
393     * <simpleContent>
394     * <extension base="string"/>
395     * </simpleContent>
396     * </complexType>
397     */

398    private PortletModeMetaData buildCustomPortletModeMetaData(Element JavaDoc customPortletModeElt)
399    {
400       PortletModeMetaData customPortleModeMD = new PortletModeMetaData();
401       customPortleModeMD.setDescriptions(buildDescriptionsMetaData(XML.getChildren(customPortletModeElt, "description")));
402       customPortleModeMD.setPortletMode(PortletUtils.decodePortletMode(XML.asString(XML.getUniqueChild(customPortletModeElt, "portlet-mode", true))));
403       return customPortleModeMD;
404    }
405
406    /**
407     * <complexType name="security-constraintType">
408     * <annotation>
409     * <documentation>
410     * The security-constraintType is used to associate
411     * intended security constraints with one or more portlets.
412     * Used in: portlet-app
413     * </documentation>
414     * </annotation>
415     * <sequence>
416     * <element name="display-name" type="portlet:display-nameType" minOccurs="0" maxOccurs="unbounded"/>
417     * <element name="portlet-collection" type="portlet:portlet-collectionType"/>
418     * <element name="user-data-constraint" type="portlet:user-data-constraintType"/>
419     * </sequence>
420     * </complexType>
421     * <p/>
422     * <complexType name="portlet-collectionType">
423     * <annotation>
424     * <documentation>
425     * The portlet-collectionType is used to identify a subset
426     * of portlets within a portlet application to which a
427     * security constraint applies.
428     * Used in: security-constraint
429     * </documentation>
430     * </annotation>
431     * <sequence>
432     * <element name="portlet-name" type="portlet:portlet-nameType" maxOccurs="unbounded"/>
433     * </sequence>
434     * </complexType>
435     */

436    private SecurityConstraintMetaData buildSecurityConstraintMetaData(Element JavaDoc securityConstraintElt)
437    {
438       Set JavaDoc portletNames = new HashSet JavaDoc();
439       List JavaDoc portletNameElts = XML.getChildren(XML.getUniqueChild(securityConstraintElt, "portlet-collection", true), "portlet-name");
440       for (int i = 0; i < portletNameElts.size(); i++)
441       {
442          String JavaDoc portletName = XML.asString((Element JavaDoc)portletNameElts.get(i));
443          if (portletNames.add(portletName))
444          {
445             // log.debug("Duplicate portlet name " + portletName);
446
}
447       }
448
449       SecurityConstraintMetaData securityConstraintMD = new SecurityConstraintMetaData();
450       securityConstraintMD.setDisplayNames(buildDisplayNames(XML.getChildren(securityConstraintElt, "display-name")));
451       securityConstraintMD.setPortletNames(portletNames);
452       securityConstraintMD.setUserDataConstraint(buildUserDataConstraintMetaData(XML.getUniqueChild(securityConstraintElt, "user-data-constraint", true)));
453       return securityConstraintMD;
454    }
455
456    /**
457     * <complexType name="user-data-constraintType">
458     * <annotation>
459     * <documentation>
460     * The user-data-constraintType is used to indicate how
461     * data communicated between the client and portlet should be
462     * protected.
463     * Used in: security-constraint
464     * </documentation>
465     * </annotation>
466     * <sequence>
467     * <element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
468     * <element name="transport-guarantee" type="portlet:transport-guaranteeType"/>
469     * </sequence>
470     * </complexType>
471     */

472    private UserDataConstraintMetaData buildUserDataConstraintMetaData(Element JavaDoc userDataConstraintElt)
473    {
474       UserDataConstraintMetaData userDataConstraintMD = new UserDataConstraintMetaData();
475       userDataConstraintMD.setDescriptions(buildDescriptionsMetaData(XML.getChildren(userDataConstraintElt, "description")));
476       userDataConstraintMD.setTransportGuarantee(TransportGuarantee.decode(XML.asString(XML.getUniqueChild(userDataConstraintElt, "transport-guarantee", true))));
477       return new UserDataConstraintMetaData();
478    }
479
480    // Portlet related **************************************************************************************************
481

482    protected InterceptorListMetaData buildComponentConfiguration(String JavaDoc portletName)
483    {
484       // A priori we use the portlet
485
ComponentConfigurationMetaData configurationMD = (ComponentConfigurationMetaData)configurations.get("Portlet");
486
487       // Look if we have an override
488
Element JavaDoc portletElt = (Element JavaDoc)jbossPortletElts.get(portletName);
489       if (portletElt != null)
490       {
491          Element JavaDoc configNameElt = XML.getUniqueChild(portletElt, "config-name", false);
492          if (configNameElt != null)
493          {
494             String JavaDoc configName = XML.asString(configNameElt);
495             log.debug("Using specific configuration for portlet " + portletName + " : " + configName);
496             ComponentConfigurationMetaData tmp = (ComponentConfigurationMetaData)configurations.get(configName);
497             if (tmp != null)
498             {
499                configurationMD = tmp;
500             }
501             else
502             {
503                log.error("No config for the name " + configName + " will use the default configuration");
504             }
505          }
506       }
507
508       //
509
InterceptorListMetaData interceptorList = configurationMD.getInterceptorList();
510       return interceptorList;
511    }
512
513    /**
514     * <complexType name="portletType">
515     * <annotation>
516     * <documentation>
517     * The portlet element contains the declarative data of a portlet.
518     * Used in: portlet-app
519     * </documentation>
520     * </annotation>
521     * <sequence>
522     * <element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
523     * <element name="portlet-name" type="portlet:portlet-nameType"/>
524     * <element name="display-name" type="portlet:display-nameType" minOccurs="0" maxOccurs="unbounded"/>
525     * <element name="portlet-class" type="portlet:portlet-classType"/>
526     * <element name="init-param" type="portlet:init-paramType" minOccurs="0" maxOccurs="unbounded"/>
527     * <element name="expiration-cache" type="portlet:expiration-cacheType" minOccurs="0"/>
528     * <element name="supports" type="portlet:supportsType" maxOccurs="unbounded"/>
529     * <element name="supported-locale" type="portlet:supported-localeType" minOccurs="0" maxOccurs="unbounded"/>
530     * <choice>
531     * <sequence>
532     * <element name="resource-bundle" type="portlet:resource-bundleType"/>
533     * <element name="portlet-info" type="portlet:portlet-infoType" minOccurs="0"/>
534     * </sequence>
535     * <element name="portlet-info" type="portlet:portlet-infoType"/>
536     * </choice>
537     * <element name="portlet-preferences" type="portlet:portlet-preferencesType" minOccurs="0"/>
538     * <element name="security-role-ref" type="portlet:security-role-refType" minOccurs="0" maxOccurs="unbounded"/>
539     * </sequence>
540     * </complexType>
541     */

542    protected PortletMetaData buildPortletMetaData(final Element JavaDoc portletElt)
543    {
544       //
545
Element JavaDoc portletNameElt = XML.getUniqueChild(portletElt, "portlet-name", true);
546       String JavaDoc portletName = XML.asString(portletNameElt);
547       log.debug("Creating portlet " + portletName + " metadata");
548
549       //
550
PortletMetaData portletMD = new PortletMetaData(appName, portletName);
551
552       // Configuration, could be overriden
553
InterceptorListMetaData interceptorList = buildComponentConfiguration(portletName);
554       portletMD.setInterceptorList(interceptorList); // Perhaps perform a clone later ?
555

556       // 1:1
557
Element JavaDoc portletClassElt = XML.getUniqueChild(portletElt, "portlet-class", true);
558       portletMD.setClassName(XML.asString(portletClassElt));
559
560       // 0:1
561
Element JavaDoc expirationCacheElt = XML.getUniqueChild(portletElt, "expiration-cache", false);
562       if (expirationCacheElt != null)
563       {
564          portletMD.setExpirationCache(XML.asString(expirationCacheElt));
565       }
566
567       // 0:1
568
Element JavaDoc portletPreferencesElt = XML.getUniqueChild(portletElt, "portlet-preferences", false);
569       PortletPreferencesMetaData preferencesMD = new PortletPreferencesMetaData();
570       if (portletPreferencesElt != null)
571       {
572          for (Iterator JavaDoc i = buildPreferencesMetaData(portletPreferencesElt).values().iterator(); i.hasNext();)
573          {
574             PreferenceMetaData preferenceMD = (PreferenceMetaData)i.next();
575             preferencesMD.addPreference(preferenceMD);
576          }
577          Element JavaDoc preferenceValidatorElt = XML.getUniqueChild(portletPreferencesElt, "preferences-validator", false);
578          preferencesMD.setPreferenceValidator(preferenceValidatorElt != null ? XML.asString(preferenceValidatorElt) : null);
579       }
580       portletMD.setPreferences(preferencesMD);
581
582       // 0:n
583
ContentTypesMetaData contentTypesMD = new ContentTypesMetaData();
584       for (Iterator JavaDoc i = buildContentTypesMetaData(XML.getChildren(portletElt, "supports")).iterator(); i.hasNext();)
585       {
586          ContentTypeMetaData contentTypeMD = (ContentTypeMetaData)i.next();
587          contentTypesMD.addContentType(contentTypeMD);
588       }
589       portletMD.setContentTypes(contentTypesMD);
590       portletMD.getDescriptions().putAll(buildDescriptionsMetaData(XML.getChildren(portletElt, "description")));
591       // TODO
592
portletMD.setLanguages(buildLanguagesMetaData(XML.getChildren(portletElt, "supported-locale"),
593          XML.getUniqueChild(portletElt, "resource-bundle", false),
594          XML.getUniqueChild(portletElt, "portlet-info", false)));
595       portletMD.getParameters().putAll(buildParametersMetaData(XML.getChildren(portletElt, "init-param")));
596       portletMD.getDisplayNames().addAll(buildDisplayNames(XML.getChildren(portletElt, "display-name")));
597       portletMD.getSecurityRoleRefs().addAll(buildSecurityRolesRefsMetaData(XML.getChildren(portletElt, "security-role-ref")));
598       return portletMD;
599    }
600
601    private LanguagesMetaData buildLanguagesMetaData(List JavaDoc supportedLocaleElts, Element JavaDoc resourceBundleElt, Element JavaDoc portletInfoElt)
602    {
603       LanguagesMetaData languages = new LanguagesMetaData();
604       LinkedHashSet JavaDoc supportedLocales = new LinkedHashSet JavaDoc();
605       for (int i = 0; i < supportedLocaleElts.size(); i++)
606       {
607          String JavaDoc name = XML.asString((Element JavaDoc)supportedLocaleElts.get(i));
608          LocaleInfo info = LocaleInfo.decodeLocaleInfo(name);
609          if (info != null)
610          {
611             if (!supportedLocales.add(info.getLocale()))
612             {
613                log.warn("Portlet locale " + name + " is declared twice");
614             }
615          }
616          else
617          {
618             log.warn("Portlet declared locale " + name + " does not exist on this platform, will be ignored");
619          }
620       }
621       languages.getSupportedLocales().addAll(supportedLocales);
622       if (resourceBundleElt != null)
623       {
624          languages.setResourceBundle(XML.asString(resourceBundleElt));
625          if (portletInfoElt != null)
626          {
627             languages.setInfo(buildInfoMetaData(portletInfoElt));
628          }
629       }
630       else
631       {
632          languages.setResourceBundle(null);
633          languages.setInfo(buildInfoMetaData(portletInfoElt));
634       }
635       return languages;
636    }
637
638    /**
639     * <complexType name="portlet-infoType">
640     * <sequence>
641     * <element name="title" type="portlet:titleType"/>
642     * <element name="short-title" type="portlet:short-titleType" minOccurs="0"/>
643     * <element name="keywords" type="portlet:keywordsType" minOccurs="0"/>
644     * </sequence>
645     * </complexType>
646     */

647    private LanguagesMetaData.InfoMetaData buildInfoMetaData(Element JavaDoc portletInfoElt)
648    {
649       LanguagesMetaData.InfoMetaData infoMD = new LanguagesMetaData.InfoMetaData();
650       Element JavaDoc shortTitleElt = XML.getUniqueChild(portletInfoElt, "short-title", false);
651       Element JavaDoc keywordsElt = XML.getUniqueChild(portletInfoElt, "keywords", false);
652       infoMD.setTitle(XML.asString(XML.getUniqueChild(portletInfoElt, "title", true)));
653       infoMD.setShortTitle(shortTitleElt != null ? XML.asString(shortTitleElt) : null);
654       infoMD.setKeywords(keywordsElt != null ? XML.asString(keywordsElt) : null);
655       return infoMD;
656    }
657
658    /**
659     */

660    private List JavaDoc buildSecurityRolesRefsMetaData(List JavaDoc securityRoleRefElts)
661    {
662       List JavaDoc securityRoleRefsMD = new ArrayList JavaDoc();
663       for (int i = 0; i < securityRoleRefElts.size(); i++)
664       {
665          Element JavaDoc securityRoleRefElt = (Element JavaDoc)securityRoleRefElts.get(i);
666          SecurityRoleRefMetaData securityRoleRefMD = buildSecurityRoleRefMetaData(securityRoleRefElt);
667          securityRoleRefsMD.add(securityRoleRefMD);
668       }
669       return securityRoleRefsMD;
670    }
671
672    /**
673     * <complexType name="security-role-refType">
674     * <annotation>
675     * <documentation>
676     * The security-role-ref element contains the declaration of a
677     * security role reference in the code of the web application. The
678     * declaration consists of an optional description, the security
679     * role name used in the code, and an optional link to a security
680     * role. If the security role is not specified, the Deployer must
681     * choose an appropriate security role.
682     * The value of the role name element must be the String used
683     * as the parameter to the
684     * EJBContext.isCallerInRole(String roleName) method
685     * or the HttpServletRequest.isUserInRole(String role) method.
686     * Used in: portlet
687     * </documentation>
688     * </annotation>
689     * <sequence>
690     * <element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
691     * <element name="role-name" type="portlet:role-nameType"/>
692     * <element name="role-link" type="portlet:role-linkType" minOccurs="0"/>
693     * </sequence>
694     * </complexType>
695     */

696    private SecurityRoleRefMetaData buildSecurityRoleRefMetaData(Element JavaDoc securityRoleRefElt)
697    {
698       List JavaDoc descriptionElts = XML.getChildren(securityRoleRefElt, "description");
699       Element JavaDoc roleNameElt = XML.getUniqueChild(securityRoleRefElt, "role-name", true);
700       Element JavaDoc roleLinkElt = XML.getUniqueChild(securityRoleRefElt, "role-link", false);
701       String JavaDoc roleName = XML.asString(roleNameElt);
702       String JavaDoc roleLink = roleLinkElt != null ? XML.asString(roleLinkElt) : null;
703       Map JavaDoc descriptionsMD = buildDescriptionsMetaData(descriptionElts);
704       SecurityRoleRefMetaData securityRoleRefMD = new SecurityRoleRefMetaData(roleName, roleLink, descriptionsMD);
705       return securityRoleRefMD;
706    }
707
708    /**
709     * <complexType name="init-paramType">
710     * <annotation>
711     * <documentation>
712     * The init-param element contains a name/value pair as an
713     * initialization param of the portlet
714     * Used in:portlet
715     * </documentation>
716     * </annotation>
717     * <sequence>
718     * <element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
719     * <element name="name" type="portlet:nameType"/>
720     * <element name="value" type="portlet:valueType"/>
721     * </sequence>
722     * </complexType>
723     */

724    private ParameterMetaData buildParameterMetadata(Element JavaDoc parameterElt)
725    {
726       ParameterMetaData parameterMD = new ParameterMetaData();
727       parameterMD.setName(XML.asString(XML.getUniqueChild(parameterElt, "name", true)));
728       parameterMD.setValue(XML.asString(XML.getUniqueChild(parameterElt, "value", true)));
729       parameterMD.setDescriptions(buildDescriptionsMetaData(XML.getChildren(parameterElt, "description")));
730       return parameterMD;
731    }
732
733    private Map JavaDoc buildParametersMetaData(List JavaDoc parameterElts)
734    {
735       Map JavaDoc parametersMD = new HashMap JavaDoc();
736       for (int i = 0; i < parameterElts.size(); i++)
737       {
738          ParameterMetaData parameter = buildParameterMetadata((Element JavaDoc)parameterElts.get(i));
739          parametersMD.put(parameter.getName(), parameter);
740       }
741       return parametersMD;
742    }
743
744    public static Map JavaDoc buildDescriptionsMetaData(List JavaDoc descriptionElts)
745    {
746       Map JavaDoc descriptions = new HashMap JavaDoc();
747       for (int i = 0; i < descriptionElts.size(); i++)
748       {
749          DescriptionMetaData description = buildDescriptionMetaData((Element JavaDoc)descriptionElts.get(i));
750          if (descriptions.put(description.getLocale(), description) != null)
751          {
752             // log.debug("Duplicate locale " + description.getLocale().getLanguage());
753
}
754       }
755       return descriptions;
756    }
757
758    /**
759     * <complexType name="descriptionType">
760     * <annotation>
761     * <documentation>
762     * The description element is used to provide text describing the
763     * parent element. The description element should include any
764     * information that the portlet application war file producer wants
765     * to provide to the consumer of the portlet application war file
766     * (i.e., to the Deployer). Typically, the tools used by the
767     * portlet application war file consumer will display the
768     * description when processing the parent element that contains the
769     * description. It has an optional attribute xml:lang to indicate
770     * which language is used in the description according to
771     * RFC 1766 (http://www.ietf.org/rfc/rfc1766.txt). The default
772     * value of this attribute is English(̉enÓ).
773     * Used in: init-param, portlet, portlet-app, security-role
774     * </documentation>
775     * </annotation>
776     * <simpleContent>
777     * <extension base="string">
778     * <attribute ref="xml:lang"/>
779     * </extension>
780     * </simpleContent>
781     * </complexType>
782     */

783    public static DescriptionMetaData buildDescriptionMetaData(Element JavaDoc descriptionElt)
784    {
785       String JavaDoc lang = descriptionElt.getAttribute("xml:lang");
786       LocaleInfo info = LocaleInfo.decodeLocaleInfo(lang);
787       if (info == null)
788       {
789          // This is the default locale when it does not exist
790
info = LocaleInfo.decodeLocaleInfo(Locale.ENGLISH);
791       }
792       DescriptionMetaData descriptionMD = new DescriptionMetaData();
793       descriptionMD.setDescription(XML.asString(descriptionElt));
794       descriptionMD.setLocale(info.getLocale());
795       return descriptionMD;
796    }
797
798    /**
799     * <complexType name="supportsType">
800     * <annotation>
801     * <documentation>
802     * Supports indicates the portlet modes a
803     * portlet supports for a specific content type. All portlets must
804     * support the view mode.
805     * Used in: portlet
806     * </documentation>
807     * </annotation>
808     * <sequence>
809     * <element name="mime-type" type="portlet:mime-typeType"/>
810     * <element name="portlet-mode" type="portlet:portlet-modeType" minOccurs="0" maxOccurs="unbounded"/>
811     * </sequence>
812     * </complexType>
813     */

814    public static Set JavaDoc buildContentTypesMetaData(List JavaDoc supportsElts)
815    {
816       Map JavaDoc contentTypes = new HashMap JavaDoc();
817       for (int i = 0; i < supportsElts.size(); i++)
818       {
819          Element JavaDoc supportsElt = (Element JavaDoc)supportsElts.get(i);
820          HashSet JavaDoc modes = new HashSet JavaDoc();
821          List JavaDoc portletModeElts = XML.getChildren(supportsElt, "portlet-mode");
822          for (int j = 0; j < portletModeElts.size(); j++)
823          {
824             Element JavaDoc portletModeElt = (Element JavaDoc)portletModeElts.get(j);
825             String JavaDoc portletMode = XML.asString(portletModeElt);
826             if (modes.add(Mode.create(portletMode)))
827             {
828                // log.debug("Duplicate portlet mode " + portletMode);
829
}
830          }
831          ContentTypeMetaData contentTypeMD = new ContentTypeMetaData();
832          contentTypeMD.setContentType(XML.asString(XML.getUniqueChild(supportsElt, "mime-type", true)));
833          contentTypeMD.setModes(modes);
834          if (contentTypes.put(contentTypeMD.getContentType(), contentTypeMD) != null)
835          {
836             // log.debug("Deplicate content type " + contentType.getContentType());
837
}
838       }
839       return new HashSet JavaDoc(contentTypes.values());
840    }
841
842    /**
843     * <complexType name="portlet-preferencesType">
844     * <annotation>
845     * <documentation>
846     * PortletMetaData persistent preference commit.
847     * Used in: portlet
848     * </documentation>
849     * </annotation>
850     * <sequence>
851     * <element name="preference" type="portlet:preferenceType" minOccurs="0" maxOccurs="unbounded"/>
852     * <element name="preferences-validator" type="portlet:preferences-validatorType" minOccurs="0"/>
853     * </sequence>
854     * </complexType>
855     * <p/>
856     * <simpleType name="preferences-validatorType">
857     * <annotation>
858     * <documentation>
859     * The class specified under preferences-validator implements
860     * the PreferencesValidator interface to validate the
861     * preferences settings.
862     * Used in: portlet-preferences
863     * </documentation>
864     * </annotation>
865     * <restriction base="portlet:fully-qualified-classType"/>
866     * </simpleType>
867     * <p/>
868     * <simpleType name="fully-qualified-classType">
869     * <annotation>
870     * <documentation>
871     * The elements that use this type designate the name of a
872     * Java class or interface.
873     * </documentation>
874     * </annotation>
875     * <restriction base="portlet:string"/>
876     * </simpleType>
877     */

878    public static Map JavaDoc buildPreferencesMetaData(Element JavaDoc portletPreferencesElt)
879    {
880       Map JavaDoc preferences = new HashMap JavaDoc();
881       List JavaDoc preferenceElts = XML.getChildren(portletPreferencesElt, "preference");
882       for (int i = 0; i < preferenceElts.size(); i++)
883       {
884          Element JavaDoc preferenceElt = (Element JavaDoc)preferenceElts.get(i);
885          PreferenceMetaData preference = buildPreferenceMetaData(preferenceElt);
886          preferences.put(preference.getName(), preference);
887       }
888       return preferences;
889    }
890
891    /**
892     * <complexType name="preferenceType">
893     * <annotation>
894     * <documentation>
895     * Persistent preference values that may be used for customization
896     * and personalization by the portlet.
897     * Used in: portlet-preferences
898     * </documentation>
899     * </annotation>
900     * <sequence>
901     * <element name="name" type="portlet:nameType"/>
902     * <element name="value" type="portlet:valueType" minOccurs="0" maxOccurs="unbounded"/>
903     * <element name="read-only" type="portlet:read-onlyType" minOccurs="0"/>
904     * </sequence>
905     * </complexType>
906     * <p/>
907     * <simpleType name="read-onlyType">
908     * <annotation>
909     * <documentation>
910     * read-only indicates that a setting cannot
911     * be changed in any of the standard portlet modes
912     * ("view","edit" or "help").
913     * Per default all preferences are modifiable.
914     * Valid values are:
915     * - true for read-only
916     * - false for modifiable
917     * Used in: preferences
918     * </documentation>
919     * </annotation>
920     * <restriction base="portlet:string">
921     * <enumeration value="true"/>
922     * <enumeration value="false"/>
923     * </restriction>
924     * </simpleType>
925     */

926    public static PreferenceMetaData buildPreferenceMetaData(Element JavaDoc preferenceElt)
927    {
928       PreferenceMetaData preferenceMD = new PreferenceMetaData();
929       List JavaDoc valuesElt = XML.getChildren(preferenceElt, "value");
930       String JavaDoc[] values = new String JavaDoc[valuesElt.size()];
931       for (int i = 0; i < valuesElt.size(); i++)
932       {
933          values[i] = XML.asString((Element JavaDoc)valuesElt.get(i));
934       }
935       Element JavaDoc readOnlyElt = XML.getUniqueChild(preferenceElt, "read-only", false);
936       boolean readOnly = false;
937       if (readOnlyElt != null)
938       {
939          String JavaDoc value = XML.asString(readOnlyElt);
940          if ("true".equals(value))
941          {
942             readOnly = true;
943          }
944          else if ("false".equals(value))
945          {
946             readOnly = false;
947          }
948          else
949          {
950             // log.debug("Unrecognized value for read only " + value);
951
readOnly = false;
952          }
953       }
954       else
955       {
956          readOnly = false;
957       }
958       preferenceMD.setName(XML.asString(XML.getUniqueChild(preferenceElt, "name", true)));
959       preferenceMD.setReadOnly(readOnly);
960       preferenceMD.setValues(values);
961       return preferenceMD;
962    }
963
964    /**
965     * <complexType name="display-nameType">
966     * <annotation>
967     * <documentation>
968     * The display-name type contains a short name that is intended
969     * to be displayed by tools. It is used by display-name
970     * elements. The display name need not be unique.
971     * Example:
972     * ...
973     * <display-name xml:lang="en">Employee Self Service</display-name>
974     * It has an optional attribute xml:lang to indicate
975     * which language is used in the description according to
976     * RFC 1766 (http://www.ietf.org/rfc/rfc1766.txt). The default
977     * value of this attribute is English(̉enÓ).
978     * </documentation>
979     * </annotation>
980     * <simpleContent>
981     * <extension base="portlet:string">
982     * <attribute ref="xml:lang"/>
983     * </extension>
984     * </simpleContent>
985     * </complexType>
986     */

987    public static List JavaDoc buildDisplayNames(List JavaDoc displayNameElts)
988    {
989       List JavaDoc displayNames = new ArrayList JavaDoc();
990       for (int i = 0; i < displayNameElts.size(); i++)
991       {
992          Element JavaDoc displayNameElt = (Element JavaDoc)displayNameElts.get(i);
993          String JavaDoc lang = displayNameElt.getAttributeNS(XML.XML_LANG_NAMESPACE_URI, "lang");
994          LocaleInfo info = LocaleInfo.decodeLocaleInfo(lang);
995          if (info == null)
996          {
997             // log.debug("Cannot get locale for " + lang);
998
info = LocaleInfo.decodeLocaleInfo(Locale.getDefault());
999          }
1000         DisplayNameMetaData displayName = new DisplayNameMetaData();
1001         displayName.setDisplayName(XML.asString(displayNameElt));
1002         displayName.setLocale(info.getLocale());
1003         displayNames.add(displayName);
1004// if (displayNames.put(displayName.getLocale(), displayName) != null)
1005
// {
1006
// log.debug("Adding duplicate display name " + displayName.getLocale().getLanguage());
1007
// }
1008
}
1009      return displayNames;
1010   }
1011
1012   protected void readJBossDescriptor()
1013   {
1014      ServletContext JavaDoc servletContext = (ServletContext JavaDoc)pwa.getServletContext();
1015      String JavaDoc contextPath = pwa.getContextPath();
1016      InputStream JavaDoc in = null;
1017      try
1018      {
1019         in = servletContext.getResourceAsStream("/WEB-INF/jboss-portlet.xml");
1020         if (in != null)
1021         {
1022            log.debug("Parsing jboss-portlet.xml" + contextPath);
1023            Document JavaDoc doc = XML.getDocumentBuilderFactory().newDocumentBuilder().parse(in);
1024            Element JavaDoc jbossPortletAppElt = doc.getDocumentElement();
1025
1026            //
1027
Map JavaDoc jbossPortletElts = new HashMap JavaDoc();
1028            List JavaDoc portletElts = XML.getChildren(jbossPortletAppElt, "portlet");
1029            for (int i = 0; i < portletElts.size(); i++)
1030            {
1031               Element JavaDoc portletElt = (Element JavaDoc)portletElts.get(i);
1032               Element JavaDoc portletNameElt = XML.getUniqueChild(portletElt, "portlet-name", true);
1033               String JavaDoc portletName = XML.asString(portletNameElt);
1034               log.debug("Found specific deployment descriptor fragment for portlet " + portletName);
1035               jbossPortletElts.put(portletName, portletElt);
1036            }
1037
1038            //
1039
this.jbossPortletElts = jbossPortletElts;
1040         }
1041         else
1042         {
1043            this.jbossPortletElts = Collections.EMPTY_MAP;
1044         }
1045      }
1046      catch (Exception JavaDoc e)
1047      {
1048         e.printStackTrace();
1049      }
1050      finally
1051      {
1052         Tools.safeClose(in);
1053      }
1054   }
1055
1056   // ******************************************************************************************************************
1057

1058   /**
1059    * Load the interceptor configuration.
1060    */

1061   public static void loadInterceptorSetMetaData(InterceptorListMetaData interceptorListMD, Element JavaDoc interceptorsElt)
1062   {
1063      NodeList JavaDoc interceptorElts = interceptorsElt.getElementsByTagName("interceptor");
1064      for (int i = 0; i < interceptorElts.getLength(); i++)
1065      {
1066         Element JavaDoc interceptorElt = (Element JavaDoc)interceptorElts.item(i);
1067         Element JavaDoc interceptorClassElt = XML.getUniqueChild(interceptorElt,
1068            "interceptor-class",
1069            true);
1070         String JavaDoc className = XML.asString(interceptorClassElt);
1071         InterceptorMetaData interceptorMD = new InterceptorMetaData(className);
1072         NodeList JavaDoc interceptorParamElts = interceptorElt.getElementsByTagName("interceptor-param");
1073         for (int j = 0; j < interceptorParamElts.getLength(); j++)
1074         {
1075            Element JavaDoc interceptorParamElt = (Element JavaDoc)interceptorParamElts.item(j);
1076            String JavaDoc paramName = XML.asString(XML.getUniqueChild(interceptorParamElt,
1077               "param-name",
1078               true));
1079            String JavaDoc paramValue = XML.asString(XML.getUniqueChild(interceptorParamElt,
1080               "param-value",
1081               true));
1082            interceptorMD.setParamValue(paramName, paramValue);
1083         }
1084         interceptorListMD.add(interceptorMD);
1085      }
1086   }
1087}
1088
Popular Tags