001: /*
002: * $Id: PortletComponent.java,v 1.3 2005/07/08 08:40:56 dg154973 Exp $
003: */
004:
005: /*
006: * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
007: * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
008: */
009:
010: package com.sun.faces.portlet;
011:
012: import org.apache.commons.logging.Log;
013: import org.apache.commons.logging.LogFactory;
014:
015: import javax.faces.context.FacesContext;
016: import javax.faces.component.NamingContainer;
017: import javax.faces.component.UIComponentBase;
018: import javax.portlet.RenderResponse;
019:
020: /**
021: * <p><strong>PortletComponent</strong> is a {@link UIComponent} that
022: * acts as a container for all JSF components in a portlet page. This component
023: * works around the problem of "id" clashes in a portal environment where same
024: * portlet can be deployed multiple times.This component overrides the
025: * <code>getClientId()</code> method to prepend a unique <code>id</code>
026: * everytime it is invoked, so that no two JSF components with in two
027: * different portlets have the same <code>id</code>. If a <code>portletId</code>
028: * is specified, it has to an EL expression and the application is responsible
029: * for making sure that it is unique. If no <portletId> is specifed,
030: * <code>PortletComponent</code> guarantees <code>id</code> uniqueness.
031: */
032:
033: public class PortletComponent extends UIComponentBase implements
034: NamingContainer {
035:
036: // ------------------------------------------------------ Manifest Constants
037:
038: /**
039: * <p>The standard component type for this component.</p>
040: */
041: public static final String COMPONENT_TYPE = "PortletComponent";
042:
043: /**
044: * <p>The standard component family for this component.</p>
045: */
046: public static final String COMPONENT_FAMILY = "PortletComponent";
047:
048: // ------------------------------------------------------------ Constructors
049:
050: /**
051: * <p>Create a new {@link PortletComponent} instance with default property
052: * values.</p>
053: */
054: public PortletComponent() {
055:
056: super ();
057:
058: }
059:
060: // ------------------------------------------------------ Instance Variables
061:
062: // The Log instance for this class
063: private static final Log log = LogFactory
064: .getLog(PortletComponent.class);
065:
066: // -------------------------------------------------------------- Properties
067:
068: public String getFamily() {
069:
070: return (COMPONENT_FAMILY);
071:
072: }
073:
074: private String portletId = null;
075:
076: // ----------------------------------------------------- UIComponent Methods
077: public String getClientId(FacesContext context) {
078: if (portletId == null) {
079: // generate a unique "id"
080: portletId = createUniquePortletId(context);
081: if (log.isTraceEnabled()) {
082: log.trace("PortletId: " + portletId);
083: }
084: }
085: return portletId;
086: }
087:
088: /**
089: * Returns a unique PortletId for the portlet.
090: * The namespace obtained from RenderResponse of the Portlet is used as its
091: * unique.
092: */
093: private String createUniquePortletId(FacesContext context) {
094: Object response = context.getExternalContext().getResponse();
095: Class portletResponseClass = null;
096: // Class.forName is used instead of instanceof to account for the case
097: // where the porletPage tag is used in a webapp and portlet.jar is not
098: // in classpath. In that scenario it will prevent ClassNotFoundException.
099: try {
100: portletResponseClass = Class
101: .forName("javax.portlet.RenderResponse");
102: } catch (ClassNotFoundException cnfe) {
103: System.err.println(cnfe);
104: }
105:
106: String portletId;
107: if (portletResponseClass != null
108: && portletResponseClass.isInstance(response)) {
109: // Get the Namespace from Portlet RenderResponse as its
110: // unique in the context of the portal page.
111: portletId = ((RenderResponse) response).getNamespace();
112: } else {
113: // If the response is not of that of Portlet, use any value.
114: portletId = "dummy";
115: }
116: return portletId;
117: }
118: }
|