01: package com.icesoft.faces.component;
02:
03: import com.icesoft.jasper.Constants;
04: import java.io.Serializable;
05:
06: import javax.faces.component.UIViewRoot;
07: import javax.faces.context.ExternalContext;
08: import javax.faces.context.FacesContext;
09: import java.util.Map;
10:
11: /**
12: * The Sun RI does not call encodeNamespace when it creates unique ID's whereas
13: * MyFaces does. In order to support portlets, component ids must have the
14: * appropriate namespace applied. This custom UIViewRoot class can be used by
15: * our own custom ViewHandler. It simply overrides the createUniqueId method
16: * and, if necessary, prepends the namespace to each component id.
17: */
18: public class NamespacingViewRoot extends UIViewRoot implements
19: Serializable {
20:
21: private ExternalContext extCtxt;
22: private String namespace;
23:
24: public NamespacingViewRoot(FacesContext context) {
25: extCtxt = context.getExternalContext();
26: Map requestMap = extCtxt.getRequestMap();
27: namespace = (String) requestMap.get(Constants.NAMESPACE_KEY);
28: }
29:
30: /**
31: * Overrides the UIViewRoot.createUniqueId method. The parent method is
32: * called and the resulting id has the namespace pre-pended if:
33: * - a namespace has been made available (e.g. portlets)
34: * - the namespace has not already been prepended (e.g. MyFaces)
35: *
36: * @return a unique component id, potentially with a namespace prepended
37: */
38: public String createUniqueId() {
39: String uniqueID = super.createUniqueId();
40:
41: if (namespace == null || uniqueID.startsWith(namespace)) {
42: return uniqueID;
43: }
44:
45: return extCtxt.encodeNamespace(uniqueID);
46: }
47: }
|