M portlet-lib/build.xml
copy jsf-portlet.tld to appropriate location.
M portlet-lib/src/conf/META-INF/faces-config.xml
declare PortletComponent.
M portlet-lib/src/java/com/sun/faces/portlet/ExternalContextImpl.java
added setResponse and setRequest methods.
A portlet-lib/src/java/com/sun/faces/portlet/PortletComponent.java
Custom component that guarantees "id" uniqueness when one portlet
is deployed multiple times in a portal environment.
A portlet-lib/src/java/com/sun/faces/portlet/PortletComponentTag.java
Tag handler for PortletComponent.
A portlet-lib/src/java/com/sun/faces/portlet/jsf-portlet.tld
TLD for declare PortletComponentTag.
Index: portlet-lib/build.xml
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-portlet/portlet-lib/build.xml,v
retrieving revision 1.7
diff -u -r1.7 build.xml
--- portlet-lib/build.xml 8 Sep 2004 17:55:59 -0000 1.7
+++ portlet-lib/build.xml 29 Mar 2005 02:50:29 -0000
@@ -69,9 +69,12 @@
<target name="prepare" depends="init">
<mkdir dir="${build.home}"/>
<mkdir dir="${build.home}/classes"/>
+ <mkdir dir="${build.home}/classes/META-INF"/>
<mkdir dir="${build.home}/lib"/>
<mkdir dir="${build.home}/javadocs"/>
+ <copy file="src/java/com/sun/faces/portlet/jsf-portlet.tld"
+ toDir="${build.home}/classes/META-INF"/>
</target>
Index: portlet-lib/src/conf/META-INF/faces-config.xml
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-portlet/portlet-lib/src/conf/META-INF/faces-config.xml,v
retrieving revision 1.5
diff -u -r1.5 faces-config.xml
--- portlet-lib/src/conf/META-INF/faces-config.xml 8 Nov 2004 19:23:05 -0000 1.5
+++ portlet-lib/src/conf/META-INF/faces-config.xml 29 Mar 2005 02:50:30 -0000
@@ -28,4 +28,20 @@
</view-handler>
</application>
+ <component>
+ <component-type>PortletComponent</component-type>
+ <component-class>com.sun.faces.portlet.PortletComponent</component-class>
+ <property>
+ <description>
+ ValueBinding Expression which evaluates to a PortletId for the Portlet
+ </description>
+ <property-name>portletId</property-name>
+ <property-class>java.lang.String</property-class>
+ </property>
+
+ <component-extension>
+ <component-family>PortletComponent</component-family>
+ </component-extension>
+
+ </component>
</faces-config>
Index: portlet-lib/src/java/com/sun/faces/portlet/ExternalContextImpl.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-portlet/portlet-lib/src/java/com/sun/faces/portlet/ExternalContextImpl.java,v
retrieving revision 1.5
diff -u -r1.5 ExternalContextImpl.java
--- portlet-lib/src/java/com/sun/faces/portlet/ExternalContextImpl.java 2 Dec 2004 23:27:09 -0000 1.5
+++ portlet-lib/src/java/com/sun/faces/portlet/ExternalContextImpl.java 29 Mar 2005 02:50:30 -0000
@@ -347,7 +347,18 @@
context.log(message, exception);
}
-
+ public void setResponse(Object response) {
+ if (response instanceof RenderResponse) {
+ this.response = (RenderResponse) response;
+ }
+ }
+
+ public void setRequest(Object request) {
+ if (request instanceof RenderRequest) {
+ this.request = (RenderRequest) request;
+ }
+ }
+
public void redirect(String path) throws IOException {
if (log.isTraceEnabled()) {
log.trace("redirectMessage(" + path + ")");
/*
* $Id: UIForm.java,v 1.45 2004/04/06 18:12:53 eburns Exp $
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.sun.faces.portlet;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponentBase;
import javax.faces.el.ValueBinding;
/**
* <p><strong>PortletComponent</strong> is a {_at_link UIComponent} that
* acts as a container for all JSF components in a portlet page. This component
* works around the problem of "id" clashes in a portal environment where same
* portlet can be deployed multiple times.This component overrides the
* <code>getClientId()</code> method to prepend a unique <code>id</code>
* everytime it is invoked, so that no two JSF components with in two
* different portlets have the same <code>id</code>. If a <code>portletId</code>
* is specified, it has to an EL expression and the application is responsible
* for making sure that it is unique. If no <portletId> is specifed,
* <code>PortletComponent</code> guarantees <code>id</code> uniqueness.
*/
public class PortletComponent extends UIComponentBase implements NamingContainer {
// ------------------------------------------------------ Manifest Constants
/**
* <p>The standard component type for this component.</p>
*/
public static final String COMPONENT_TYPE = "PortletComponent";
/**
* <p>The standard component family for this component.</p>
*/
public static final String COMPONENT_FAMILY = "PortletComponent";
private static final String PORTLET_ID_SERIAL = "PORTLET_ID_SERIAL";
private static final String PORTLET_PAGE = "portletPage";
// ------------------------------------------------------------ Constructors
/**
* <p>Create a new {_at_link PortletComponent} instance with default property
* values.</p>
*/
public PortletComponent() {
super();
}
// ------------------------------------------------------ Instance Variables
// -------------------------------------------------------------- Properties
public String getFamily() {
return (COMPONENT_FAMILY);
}
private String portletId = null;
/**
* <p>Returns the <code>value</code> property of the
* <code>UICommand</code>. This is most often rendered as a label.</p>
*/
public String getPortletId() {
if (this.portletId != null) {
return (this.portletId);
}
ValueBinding vb = getValueBinding("portletId");
if (vb != null) {
return ((String)vb.getValue(getFacesContext()));
} else {
return (null);
}
}
// ----------------------------------------------------- UIComponent Methods
public String getClientId(FacesContext context) {
if (portletId == null) {
// generate a unique "id" and prepend it to "result"
portletId = createUniquePortletId(context);
}
return portletId;
}
/**
* Returns a unique PortletId for the portlet. Since the serial is
* saved in Application scope, it is guaranteed to be unique for the
* life of the application.
*/
private String createUniquePortletId(FacesContext context) {
int portletIdSerial = 1;
Map applicationMap = context.getExternalContext().getApplicationMap();
String porletIdStr = (String) applicationMap.get(PORTLET_ID_SERIAL);
if (porletIdStr != null) {
portletIdSerial = Integer.parseInt(porletIdStr);
portletIdSerial++;
if (portletIdSerial == Integer.MAX_VALUE) {
portletIdSerial = 1;
}
}
applicationMap.put(PORTLET_ID_SERIAL, String.valueOf(portletIdSerial));
return (PORTLET_PAGE + String.valueOf(portletIdSerial));
}
}
/*
* $Id: ExternalContextImpl.java,v 1.5 2004/12/02 23:27:09 jayashri Exp $
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.sun.faces.portlet;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.el.ValueBinding;
import javax.faces.webapp.UIComponentTag;
/**
* This class is the tag handler that evaluates the <code>portletPage</code>
* custom tag. All JSF tags in a portlet should be embedded with this this tag
* if multiple instances of the same portlet can exist within a portal page.
* Otherwise it may result in potential "id" clashes especially if the portlet
* uses JavaScript.
*/
public class PortletComponentTag extends UIComponentTag {
private String portletId = null;
public void setPortletId(String portletId) {
this.portletId = portletId;
}
public String getComponentType() {
return ("PortletComponent");
}
public String getRendererType() {
return null;
}
protected void setProperties(UIComponent component) {
super.setProperties(component);
ValueBinding vb = null;
if (portletId != null) {
if (isValueReference(portletId)) {
vb = getFacesContext().getApplication().createValueBinding(portletId);
component.setValueBinding("portletId", vb);
} else {
throw new
FacesException("portletId attribute must be an ELExpression");
}
}
}
}