package com.med.icefaces.style; /* * Copyright 2004-2012 ICEsoft Technologies Canada Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language * governing permissions and limitations under the License. */ import com.icesoft.faces.component.style.OutputStyle; import com.icesoft.faces.context.DOMContext; import com.icesoft.faces.renderkit.dom_html_basic.DomBasicRenderer; import com.icesoft.faces.renderkit.dom_html_basic.HTML; import com.icesoft.faces.util.CoreUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.icefaces.util.EnvUtils; import org.w3c.dom.Element; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import java.beans.Beans; import java.io.File; import java.io.IOException; /** * Created by IntelliJ IDEA. User: rmayhew Date: May 30, 2006 Time: 3:59:37 PM * To change this template use File | Settings | File Templates. */ public class OutputStyleRenderer extends DomBasicRenderer { private static Log log = LogFactory.getLog(OutputStyleRenderer.class); private static final String IE_EXTENTION = "_ie"; private static final String IE_7_EXTENTION = "_ie7"; private static final String IE_8_EXTENSION = "_ie8"; private static final String SAFARI_EXTENTION = "_safari"; private static final String SAFARI_MOBILE_EXTENTION = "_safarimobile"; private static final String CSS_EXTENTION = ".css"; private static final String DT_EXTENTION = "_dt"; private static final String OPERA_EXTENTION = "_opera"; private static final String OPERA_MOBILE_EXTENTION = "_operamobile"; private static final int DEFAULT_TYPE = 0; private static final int IE = 1; private static final int SAFARI = 2; private static final int DT = 3; private static final int IE_7 = 4; private static final int SAFARI_MOBILE = 5; private static final int OPERA = 6; private static final int OPERA_MOBILE = 7; private static final int IE_8 = 8; public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException { validateParameters(facesContext, uiComponent, OutputStyle.class); try { DOMContext domContext = DOMContext.attachDOMContext(facesContext, uiComponent); if (!domContext.isInitialized()) { OutputStyle outputStyle = (OutputStyle) uiComponent; Element styleEle = buildCssElement(domContext); String href = outputStyle.getHref(); styleEle.setAttribute(HTML.HREF_ATTR, getResourceURL(facesContext,href)); domContext.setRootNode(styleEle); int browserType = browserType(facesContext, uiComponent); if (browserType != DEFAULT_TYPE) { if (href.endsWith(CSS_EXTENTION)) { int i = href.indexOf(CSS_EXTENTION); if (i > 0) { // assume we are not going to use the specific file boolean useSpecific=false; // this is the file we are going to verify existence of. String start = href.substring(0, i); String extention = findBrowserSpecificFileExtensionForBrowserType(browserType); String browserSpecificFilename = start + extention + CSS_EXTENTION; String realRoot = facesContext.getExternalContext().getRealPath("/"); if (realRoot != null) { File realParent = new File(realRoot); // first use case of absolute file (/...), // // find our real root path, we need this to determine // existence of the file containing the extension. // // Then append the browser specific filename to the root and find // the file. if (browserSpecificFilename.startsWith("/")) { File browserSpecificFile = null; // can start with /[context_name]/ // if it does, we need to strip it off String contextName = null; Object servletContextObject = FacesContext.getCurrentInstance().getExternalContext().getContext(); if (servletContextObject != null && servletContextObject instanceof ServletContext) { contextName = ((ServletContext)servletContextObject).getContextPath(); } // if context name is available then we need to strip it off of the URL if it // is there otherwise just use href as-is. if (contextName != null) { // starts with context name? String contextRoot = contextName +"/"; if (browserSpecificFilename.startsWith(contextRoot)) { browserSpecificFile = new File (realParent,browserSpecificFilename.substring(contextRoot.length())); } else { browserSpecificFile = new File (realParent,browserSpecificFilename.substring(1)); } } useSpecific=browserSpecificFile != null ? browserSpecificFile.exists(): false; } // second use case of relative file (.../...), // // find the directory of the relative path of the request // // // Then append the browser specific filename to the root and find // the file. else { String pathInfo = facesContext.getExternalContext().getRequestServletPath(); if (pathInfo != null) { pathInfo=new File(pathInfo).getParent(); File realPath = new File (realParent,pathInfo); File browserSpecificFile = new File (realPath,browserSpecificFilename); useSpecific=browserSpecificFile.exists(); } } } // append the specific CSS if it is there if (useSpecific) { Element ieStyleEle = buildCssElement(domContext); // W3C spec: To make a style sheet preferred, set the rel attribute to "stylesheet" and name the style sheet with the title attribute ieStyleEle.setAttribute(HTML.TITLE_ATTR, extention); String hrefURL = CoreUtils.resolveResourceURL(facesContext, browserSpecificFilename); ieStyleEle.setAttribute(HTML.HREF_ATTR, hrefURL); styleEle.getParentNode().appendChild(ieStyleEle); } } else { throw new RuntimeException( "OutputStyle file attribute is too short. " + "Needs at least one character before .css. Current Value is [" + href + "]"); } } else { throw new RuntimeException( "OutputStyle file attribute must end in .css. " + "Current Value is [" + href + "]"); } } } domContext.stepOver(); } catch (Exception e) { log.error("Error in OutputStyleRenderer", e); } } /** * given a browser type, return the extension we will use * @param browserType * @return extension to use. */ public String findBrowserSpecificFileExtensionForBrowserType (int browserType) { switch (browserType) { case IE_7: return IE_7_EXTENTION; case IE_8: return IE_8_EXTENSION; case SAFARI: return SAFARI_EXTENTION; case DT: return DT_EXTENTION; case SAFARI_MOBILE: return SAFARI_MOBILE_EXTENTION; case OPERA: return OPERA_EXTENTION; case OPERA_MOBILE: return OPERA_MOBILE_EXTENTION; default: return IE_EXTENTION; } } private Element buildCssElement(DOMContext domContext) { Element styleEle = domContext.createElement("link"); styleEle.setAttribute(HTML.REL_ATTR, "stylesheet"); styleEle.setAttribute(HTML.TYPE_ATTR, "text/css"); return styleEle; } private int browserType(FacesContext facesContext, UIComponent uiComponent) { int result = DEFAULT_TYPE; String useragent = ((OutputStyle)uiComponent).getUserAgent(); if(useragent != null){ return _browserType(useragent); } Object o = facesContext.getExternalContext().getRequest(); if (o != null) { if (!EnvUtils.instanceofPortletRequest(o)) { HttpServletRequest request = (HttpServletRequest) o; useragent = request.getHeader("user-agent"); if(useragent == null){ useragent = ((OutputStyle)uiComponent).getUserAgent(); } if(useragent == null){ //Get User-Agent for Weblogic/Webshpere useragent = request.getHeader("User-Agent"); } if(useragent == null){ //Get User-Agent for OC4J useragent = request.getHeader("USER-AGENT"); } if(useragent == null){ if (log.isDebugEnabled()) { log.debug("Not able to find user agent. Returning default"); } return DEFAULT_TYPE; } if(((OutputStyle)uiComponent).getUserAgent() == null){ ((OutputStyle)uiComponent).setUserAgent(useragent.toLowerCase()); } String user = useragent.toLowerCase(); result = _browserType( user); } else { if (log.isDebugEnabled()) { log.debug( "OutputStyleRenderer: Request is not HttpServletRequest. Its [" + o.getClass().getName() + "]"); } } } else { if (log.isDebugEnabled()) { log.debug( "IceStyleReader: facesContext.getExternalContext().getRequest() is null"); } } return result; } private int _browserType(String user) { int result = DEFAULT_TYPE; if (Beans.isDesignTime()) { result = DT; } else { if (user.indexOf("opera") < 0 && user.indexOf("msie") != -1) { result = IE; if(user.indexOf("msie 7") != -1){ result = IE_7; } if(user.indexOf("msie 8") != -1){ result = IE_8; } } else if (user.indexOf("safari") != -1) { result = SAFARI; if(user.indexOf("mobile") != -1) { result = SAFARI_MOBILE; } } else if (user.indexOf("opera") != -1) { result = OPERA; if(user.indexOf("240x320") != -1) { result = OPERA_MOBILE; } } } return result; } }