001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    package org.apache.myfaces.tobago.context;
021    
022    /*
023     * Created: 23.07.2002 14:21:58
024     * $Id: ClientProperties.java 1368577 2012-08-02 16:20:31Z lofwyr $
025     */
026    
027    
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import static org.apache.myfaces.tobago.TobagoConstants.ATTR_CLIENT_PROPERTIES;
031    import org.apache.myfaces.tobago.config.TobagoConfig;
032    
033    import javax.faces.component.UIViewRoot;
034    import javax.faces.context.ExternalContext;
035    import javax.faces.context.FacesContext;
036    import java.io.Serializable;
037    import java.util.ArrayList;
038    import java.util.List;
039    import java.util.Locale;
040    
041    public class ClientProperties implements Serializable {
042      private static final long serialVersionUID = -6719319982485268698L;
043      private static final String CLIENT_PROPERTIES_IN_SESSION = ClientProperties.class.getName();
044    
045      private static final Log LOG = LogFactory.getLog(ClientProperties.class);
046    
047      private String contentType = "html";
048      // TODO transient
049      private Theme theme;
050      private UserAgent userAgent = UserAgent.DEFAULT;
051      private boolean debugMode;
052    
053      private String id;
054    
055      private ClientProperties(TobagoConfig tobagoConfig) {
056        theme = tobagoConfig.getDefaultTheme();
057        updateId();
058      }
059    
060      private ClientProperties(FacesContext facesContext) {
061    
062        ExternalContext externalContext = facesContext.getExternalContext();
063    
064        // content type
065        String accept = (String) externalContext.getRequestHeaderMap().get("Accept");
066        if (accept != null) {
067          if (accept.indexOf("text/vnd.wap.wml") > -1) {
068            contentType = "wml";
069          }
070        }
071        if (LOG.isInfoEnabled()) {
072          LOG.info("contentType='" + contentType + "' from header "
073              + "Accept='" + accept + "'");
074        }
075    
076        // user agent
077        String requestUserAgent
078            = (String) externalContext.getRequestHeaderMap().get("User-Agent");
079        this.userAgent = UserAgent.getInstance(requestUserAgent);
080        if (LOG.isInfoEnabled()) {
081          LOG.info("userAgent='" + this.userAgent + "' from header "
082              + "'User-Agent: " + requestUserAgent + "'");
083        }
084        // debug mode
085        // to enable the debug mode for a user, put a
086        // "to-ba-go" custom locale to your browser
087        String acceptLanguage
088            = (String) externalContext.getRequestHeaderMap().get("Accept-Language");
089        if (acceptLanguage != null) {
090          this.debugMode = acceptLanguage.indexOf("to-ba-go") > -1;
091        }
092        if (LOG.isInfoEnabled()) {
093          LOG.info("debug-mode=" + debugMode);
094        }
095        // theme
096        String requestTheme
097            = (String) externalContext.getRequestParameterMap().get("tobago.theme");
098        TobagoConfig config = TobagoConfig.getInstance(facesContext);
099        this.theme = config.getTheme(requestTheme);
100        if (LOG.isInfoEnabled()) {
101          LOG.info("theme='" + theme.getName() + "' from requestParameter "
102              + "tobago.theme='" + requestTheme + "'");
103        }
104        updateId();
105      }
106    
107      private void updateId() {
108    
109        StringBuilder buffer = new StringBuilder();
110        buffer.append(getContentType());
111        buffer.append('/');
112        buffer.append(getTheme().getName());
113        buffer.append('/');
114        buffer.append(getUserAgent());
115        id = buffer.toString();
116        UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
117        if (viewRoot instanceof org.apache.myfaces.tobago.component.UIViewRoot) {
118          ((org.apache.myfaces.tobago.component.UIViewRoot) viewRoot).updateRendererCachePrefix();
119        }
120      }
121    
122      public static ClientProperties getDefaultInstance(FacesContext facesContext) {
123        return new ClientProperties(TobagoConfig.getInstance(facesContext));
124      }
125    
126      public static ClientProperties getInstance(UIViewRoot viewRoot) {
127    
128        ClientProperties instance = (ClientProperties)
129            viewRoot.getAttributes().get(ATTR_CLIENT_PROPERTIES);
130        if (instance == null) {
131          LOG.error("No ClientProperties instance found creating new one");
132          return getInstance(FacesContext.getCurrentInstance());
133        }
134        return instance;
135      }
136    
137      public static ClientProperties getInstance(FacesContext facesContext) {
138    
139        ExternalContext context = facesContext.getExternalContext();
140    
141        boolean hasSession = context.getSession(false) != null;
142    
143        ClientProperties client = null;
144    
145        if (hasSession) {
146          client = (ClientProperties) context.getSessionMap().get(
147              CLIENT_PROPERTIES_IN_SESSION);
148        }
149        if (client == null) {
150          client = new ClientProperties(facesContext);
151          if (hasSession) {
152            context.getSessionMap().put(CLIENT_PROPERTIES_IN_SESSION, client);
153          }
154        }
155        return client;
156      }
157    
158      public static List<String> getLocaleList(
159          Locale locale, boolean propertyPathMode) {
160    
161        String string = locale.toString();
162        String prefix = propertyPathMode ? "" : "_";
163        List<String> locales = new ArrayList<String>(4);
164        locales.add(prefix + string);
165        int underscore;
166        while ((underscore = string.lastIndexOf('_')) > 0) {
167          string = string.substring(0, underscore);
168          locales.add(prefix + string);
169        }
170    
171        locales.add(propertyPathMode ? "default" : ""); // default suffix
172    
173        return locales;
174      }
175    
176      public String getId() {
177        return id;
178      }
179    
180      public String getContentType() {
181        return contentType;
182      }
183    
184      public void setContentType(String contentType) {
185        this.contentType = contentType;
186        updateId();
187      }
188    
189      public Theme getTheme() {
190        return theme;
191      }
192    
193      public void setTheme(Theme theme) {
194        this.theme = theme;
195        updateId();
196      }
197    
198      public UserAgent getUserAgent() {
199        return userAgent;
200      }
201    
202      public void setUserAgent(UserAgent userAgent) {
203        this.userAgent = userAgent;
204        updateId();
205      }
206    
207      public boolean isDebugMode() {
208        return debugMode;
209      }
210    
211      public void setDebugMode(boolean debugMode) {
212        this.debugMode = debugMode;
213      }
214    
215    }