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