001: /*
002: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003: *
004: * "The contents of this file are subject to the Mozilla Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
011: * License for the specific language governing rights and limitations under
012: * the License.
013: *
014: * The Original Code is ICEfaces 1.5 open source software code, released
015: * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
016: * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
017: * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
018: *
019: * Contributor(s): _____________________.
020: *
021: * Alternatively, the contents of this file may be used under the terms of
022: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
023: * License), in which case the provisions of the LGPL License are
024: * applicable instead of those above. If you wish to allow use of your
025: * version of this file only under the terms of the LGPL License and not to
026: * allow others to use your version of this file under the MPL, indicate
027: * your decision by deleting the provisions above and replace them with
028: * the notice and other provisions required by the LGPL License. If you do
029: * not delete the provisions above, a recipient may use your version of
030: * this file under either the MPL or the LGPL License."
031: *
032: */
033:
034: package com.icesoft.faces.webapp.parser;
035:
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038:
039: import javax.faces.FacesException;
040: import javax.faces.context.FacesContext;
041: import javax.servlet.jsp.PageContext;
042: import java.util.List;
043:
044: import com.icesoft.faces.webapp.parser.ComponentRuleSet;
045:
046: /**
047: * For ICEfaces to support JSF-RI, MyFaces, or any other future JSF
048: * implementations, it may require some logic specific to the implementation.
049: * Obviously this is not a good thing but it may be unavoidable if we need to
050: * access something under the hood that isn't available through public API
051: * calls. This class is available to encapsulate implementation specific
052: * anomalies.
053: */
054: public class ImplementationUtil {
055:
056: /**
057: * Logging instance for this class.
058: */
059: protected static Log log = LogFactory
060: .getLog(ImplementationUtil.class);
061:
062: /**
063: * Boolean values to track which implementation we are running under.
064: */
065: private static boolean isRI = false;
066: private static boolean isMyFaces = false;
067: private static boolean isJSF12 = false;
068:
069: /**
070: * Marker classes whose presence we used to detect which implementation we
071: * are running under.
072: */
073: private static String RI_MARKER = "com.sun.faces.application.ApplicationImpl";
074: private static String MYFACES_MARKER = "org.apache.myfaces.application.ApplicationImpl";
075: private static String JSF12_MARKER = "javax.faces.webapp.UIComponentELTag";
076:
077: /**
078: * In a couple of places, we need to access the component stack from the
079: * PageContext and the key used to do this is implemenation dependent. So
080: * here is where we track the keys and provide appropriate value depending
081: * on the implementation we are running under.
082: */
083: private static String RI_COMPONENT_STACK_KEY = "javax.faces.webapp.COMPONENT_TAG_STACK";
084:
085: private static String MYFACES_COMPONENT_STACK_KEY = "javax.faces.webapp.UIComponentTag.COMPONENT_STACK";
086:
087: static {
088: try {
089: Class.forName(RI_MARKER);
090: isRI = true;
091: } catch (ClassNotFoundException e) {
092: }
093:
094: try {
095: Class.forName(MYFACES_MARKER);
096: isMyFaces = true;
097: } catch (ClassNotFoundException e) {
098: }
099:
100: if (log.isTraceEnabled()) {
101: log.trace("JSF-RI: " + isRI + " MyFaces: " + isMyFaces);
102: }
103:
104: //Test for JSF 1.2
105: try {
106: Class.forName(JSF12_MARKER);
107: isJSF12 = true;
108: } catch (Throwable t) {
109: }
110:
111: if (log.isTraceEnabled()) {
112: log.trace("JSF-12: " + isJSF12);
113: }
114:
115: }
116:
117: /**
118: * Identifies if the JSF implementation we are running in is Sun's JSF
119: * reference implemenation (RI).
120: *
121: * @return true if the JSF implementation is Sun's JSF reference
122: * implemenation
123: */
124: public static boolean isRI() {
125: return isRI;
126: }
127:
128: /**
129: * Identifies if the JSF implementation we are running in is Apache's
130: * MyFaces implementation.
131: *
132: * @return true if the JSF implementation is Apache MyFaces.
133: */
134: public static boolean isMyFaces() {
135: return isMyFaces;
136: }
137:
138: /**
139: * Identifies if the JSF implementation we are running in is JSF 1.2
140: *
141: * @return true if the JSF implementation is JSF 1.2
142: */
143: public static boolean isJSF12() {
144: return isJSF12;
145: }
146:
147: /**
148: * Returns the key used to get the component stack from the PageContext. The
149: * key is a private member of UIComponentTag class but differs between the
150: * known JSF implementations. We detect the correct implementation in this
151: * class and provide the proper key.
152: *
153: * @return String
154: */
155: public static String getComponentStackKey() {
156: String key = null;
157: if (isRI) {
158: key = RI_COMPONENT_STACK_KEY;
159: } else if (isMyFaces) {
160: key = MYFACES_COMPONENT_STACK_KEY;
161: }
162:
163: if (key != null) {
164: return key;
165: }
166:
167: if (log.isFatalEnabled()) {
168: log
169: .fatal("cannot detect JSF implementation so cannot determine component stack key");
170: }
171:
172: throw new UnknownJSFImplementationException(
173: "cannot determine component stack key");
174: }
175:
176: /**
177: * Returns the component tag stack, including checking in the current
178: * request as is the strategy of JSF 1.1_02
179: * @param pageContext
180: * @return list being the component tag stack
181: */
182: public static List getComponentStack(PageContext pageContext) {
183: List list = (List) pageContext.getAttribute(
184: getComponentStackKey(), PageContext.REQUEST_SCOPE);
185: if (null == list) {
186: list = (List) FacesContext.getCurrentInstance()
187: .getExternalContext().getRequestMap().get(
188: getComponentStackKey());
189: }
190: return list;
191:
192: }
193: }
194:
195: class UnknownJSFImplementationException extends FacesException {
196:
197: public UnknownJSFImplementationException() {
198: }
199:
200: public UnknownJSFImplementationException(Throwable cause) {
201: super (cause);
202: }
203:
204: public UnknownJSFImplementationException(String message) {
205: super (message);
206: }
207:
208: public UnknownJSFImplementationException(String message,
209: Throwable cause) {
210: super(message, cause);
211: }
212:
213: }
|