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 516215 2007-03-08 22:50:57Z 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        LOG.info("contentType='" + contentType + "' from header "
070            + "Accept='" + accept + "'");
071    
072        // user agent
073        String requestUserAgent
074            = (String) externalContext.getRequestHeaderMap().get("User-Agent");
075        this.userAgent = UserAgent.getInstance(requestUserAgent);
076        LOG.info("userAgent='" + this.userAgent + "' from header "
077            + "'User-Agent: " + requestUserAgent + "'");
078    
079        // debug mode
080        // to enable the debug mode for a user, put a
081        // "to-ba-go" custom locale to your browser
082        String acceptLanguage
083            = (String) externalContext.getRequestHeaderMap().get("Accept-Language");
084        if (acceptLanguage != null) {
085          this.debugMode = acceptLanguage.indexOf("to-ba-go") > -1;
086        }
087        LOG.info("debug-mode=" + debugMode);
088    
089        // theme
090        String requestTheme
091            = (String) externalContext.getRequestParameterMap().get("tobago.theme");
092        TobagoConfig config = TobagoConfig.getInstance(facesContext);
093        this.theme = config.getTheme(requestTheme);
094        LOG.info("theme='" + theme.getName() + "' from requestParameter "
095            + "tobago.theme='" + requestTheme + "'");
096        updateId();
097      }
098    
099      private void updateId() {
100    
101        StringBuilder buffer = new StringBuilder();
102        buffer.append(getContentType());
103        buffer.append('/');
104        buffer.append(getTheme().getName());
105        buffer.append('/');
106        buffer.append(getUserAgent());
107        id = buffer.toString();
108        UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
109        if (viewRoot instanceof org.apache.myfaces.tobago.component.UIViewRoot) {
110          ((org.apache.myfaces.tobago.component.UIViewRoot) viewRoot).updateRendererCachePrefix();
111        }
112      }
113    
114      public static ClientProperties getDefaultInstance(FacesContext facesContext) {
115        return new ClientProperties(TobagoConfig.getInstance(facesContext));
116      }
117    
118      public static ClientProperties getInstance(UIViewRoot viewRoot) {
119    
120        ClientProperties instance = (ClientProperties)
121            viewRoot.getAttributes().get(ATTR_CLIENT_PROPERTIES);
122        if (instance == null) {
123          LOG.error("No ClientProperties instance found creating new one");
124          return getInstance(FacesContext.getCurrentInstance());
125        }
126        return instance;
127      }
128    
129      public static ClientProperties getInstance(FacesContext facesContext) {
130    
131        ExternalContext context = facesContext.getExternalContext();
132    
133        boolean hasSession = context.getSession(false) != null;
134    
135        ClientProperties client = null;
136    
137        if (hasSession) {
138          client = (ClientProperties) context.getSessionMap().get(
139              CLIENT_PROPERTIES_IN_SESSION);
140        }
141        if (client == null) {
142          client = new ClientProperties(facesContext);
143          if (hasSession) {
144            context.getSessionMap().put(CLIENT_PROPERTIES_IN_SESSION, client);
145          }
146        }
147        return client;
148      }
149    
150      public static List<String> getLocaleList(
151          Locale locale, boolean propertyPathMode) {
152    
153        String string = locale.toString();
154        String prefix = propertyPathMode ? "" : "_";
155        List<String> locales = new ArrayList<String>(4);
156        locales.add(prefix + string);
157        int underscore;
158        while ((underscore = string.lastIndexOf('_')) > 0) {
159          string = string.substring(0, underscore);
160          locales.add(prefix + string);
161        }
162    
163        locales.add(propertyPathMode ? "default" : ""); // default suffix
164    
165        return locales;
166      }
167    
168      public String getId() {
169        return id;
170      }
171    
172      public String getContentType() {
173        return contentType;
174      }
175    
176      public void setContentType(String contentType) {
177        this.contentType = contentType;
178        updateId();
179      }
180    
181      public Theme getTheme() {
182        return theme;
183      }
184    
185      public void setTheme(Theme theme) {
186        this.theme = theme;
187        updateId();
188      }
189    
190      public UserAgent getUserAgent() {
191        return userAgent;
192      }
193    
194      public void setUserAgent(UserAgent userAgent) {
195        this.userAgent = userAgent;
196        updateId();
197      }
198    
199      public boolean isDebugMode() {
200        return debugMode;
201      }
202    
203      public void setDebugMode(boolean debugMode) {
204        this.debugMode = debugMode;
205      }
206    
207    }