001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license 003 * agreements. See the NOTICE file distributed with this work for additional information regarding 004 * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the 005 * "License"); you may not use this file except in compliance with the License. You may obtain a 006 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 007 * law or agreed to in writing, software distributed under the License is distributed on an "AS IS" 008 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License 009 * for the specific language governing permissions and limitations under the License. 010 */ 011 package javax.portlet.faces.component; 012 013 import java.io.Serializable; 014 015 import javax.faces.context.FacesContext; 016 import javax.faces.component.NamingContainer; 017 import javax.faces.component.UIViewRoot; 018 import javax.faces.context.ExternalContext; 019 020 import javax.portlet.faces.annotation.PortletNamingContainer; 021 022 /** 023 * <code>UIViewRoot</code> that implements portlet specific <code>NamingContainer</code> 024 * that ensures the consumer's unique portlet Id is encoded in all tree components. 025 * The class is annotated by <code>javax.portlet.faces.annotation.PortletNamingContainer</code> 026 * allowing the bridge to recognize that this specific <code>UIViewRoot</code> 027 * implements the behavior. 028 */ 029 @PortletNamingContainer 030 public class PortletNamingContainerUIViewRoot extends UIViewRoot implements Serializable, NamingContainer 031 { 032 033 //TODO: This should be regenerated each time this is modified. Can this be added to maven? 034 private static final long serialVersionUID = -4524288011655837711L; 035 private static final String SEPARATOR = (new Character(NamingContainer.SEPARATOR_CHAR)) 036 .toString(); 037 038 public PortletNamingContainerUIViewRoot() 039 { 040 super(); 041 } 042 043 public PortletNamingContainerUIViewRoot(UIViewRoot viewRootToReplace) 044 { 045 super(); 046 setViewId(viewRootToReplace.getViewId()); 047 setLocale(viewRootToReplace.getLocale()); 048 setRenderKitId(viewRootToReplace.getRenderKitId()); 049 } 050 051 /** 052 * Static method that implements NamingContainer semantics. Ensures that the 053 * returned identifier contains the consumer (portal) provided unique portlet id. 054 * This ensures that those components in this NamingContainer generate ids which 055 * will not collide in the consumer page.<p> 056 * This method is provided for existing <code>UIViewRoot</code> implementations 057 * that prefer not to subclass <code>PortletNamingContainerUIViewRoot</code> 058 */ 059 public static String getContainerClientId(FacesContext context, String additionalId) 060 { 061 ExternalContext ec = context.getExternalContext(); 062 String namespace = ec.encodeNamespace(SEPARATOR); 063 064 /* 065 * In servlet world encodeNamespace does nothing -- so if we get back what we sent in then do 066 * not perturn the NamingContainer Id 067 */ 068 if (namespace.length() > 1) 069 { 070 if (additionalId != null) 071 { 072 return namespace + additionalId; 073 } 074 else 075 { 076 return namespace; 077 } 078 } 079 else 080 { 081 return null; 082 } 083 } 084 085 /** 086 * Implements NamingContainer semantics. Ensures that the returned identifier 087 * contains the consumer (portal) provided unique portlet id. This ensures that 088 * those components in this NamingContainer generate ids which will not collide 089 * in the consumer page. Implementation merely calls the static form of this 090 * method. 091 */ 092 093 @Override 094 public String getContainerClientId(FacesContext context) 095 { 096 return PortletNamingContainerUIViewRoot 097 .getContainerClientId( 098 context, 099 super 100 .getContainerClientId(context)); 101 } 102 103 }