View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.context;
21  
22  import org.apache.myfaces.tobago.internal.util.Deprecation;
23  
24  import java.io.Serializable;
25  import java.util.ArrayList;
26  import java.util.Collections;
27  import java.util.EnumSet;
28  import java.util.List;
29  
30  public class UserAgent implements Serializable {
31  
32    private static final long serialVersionUID = 2L;
33  
34    public static final String DEFAULT_NAME = "standard";
35  
36    public static final UserAgent DEFAULT = new UserAgent(null, null);
37  
38    public static final UserAgent MSIE = new UserAgent("msie", null);
39  
40    /**
41     * @deprecated no longer supported, since Tobago 1.5
42     */
43    @Deprecated
44    public static final UserAgent MSIE_5_0 = new UserAgent("msie", "5_0");
45  
46    /**
47     * @deprecated no longer supported, since Tobago 1.5
48     */
49    @Deprecated
50    public static final UserAgent MSIE_5_5 = new UserAgent("msie", "5_5");
51  
52    public static final UserAgent MSIE_6_0 = new UserAgent("msie", "6_0");
53  
54    public static final UserAgent MSIE_7_0 = new UserAgent("msie", "7_0");
55  
56    public static final UserAgent MSIE_7_0_COMPAT
57        = new UserAgent("msie", "7_0", EnumSet.of(Capability.IE_COMPATIBILITY_MODE));
58  
59    /**
60     * @deprecated no longer supported, since Tobago 1.5. Misspelled. Use {@link #MSIE_7_0}
61     */
62    @Deprecated
63    public static final UserAgent MSIE_7_O = MSIE_7_0;
64  
65    public static final UserAgent MSIE_8_0 = new UserAgent("msie", "8_0");
66  
67    public static final UserAgent MSIE_9_0 = new UserAgent("msie", "9_0", EnumSet.of(Capability.CONTENT_TYPE_XHTML));
68  
69    public static final UserAgent MSIE_10_0
70        = new UserAgent("msie", "10_0", EnumSet.of(Capability.CONTENT_TYPE_XHTML), CspHeader.CSP_GECKO);
71  
72    /**
73     * @deprecated no longer supported, since Tobago 1.5
74     */
75    @Deprecated
76    public static final UserAgent MSIE_5_0_MAC = new UserAgent("msie", "5_0_mac");
77  
78    /**
79     * @deprecated no longer supported, since Tobago 1.5
80     */
81    @Deprecated
82    public static final UserAgent MSIE_6_0_MAC = new UserAgent("msie", "6_0_mac");
83  
84  
85    /**
86     * e. g. Opera 10
87     */
88    public static final UserAgent PRESTO = new UserAgent("presto", null, EnumSet.of(Capability.CONTENT_TYPE_XHTML));
89  
90    /**
91     * @deprecated no longer supported, since Tobago 1.5. Please use {@link #PRESTO}.
92     */
93    public static final UserAgent OPERA = new UserAgent("opera", null);
94  
95    /**
96     * @deprecated no longer supported, since Tobago 1.5. Please use {@link #PRESTO}.
97     */
98    @Deprecated
99    public static final UserAgent OPERA_5_0 = new UserAgent("opera", "5_0");
100 
101   /**
102    * @deprecated no longer supported, since Tobago 1.5. Please use {@link #PRESTO}.
103    */
104   @Deprecated
105   public static final UserAgent OPERA_6_0 = new UserAgent("opera", "6_0");
106 
107   /**
108    * @deprecated no longer supported, since Tobago 1.5. Please use {@link #PRESTO}.
109    */
110   @Deprecated
111   public static final UserAgent OPERA_7_11 = new UserAgent("opera", "7_11");
112 
113   /**
114    * @deprecated no longer supported, since Tobago 1.5
115    */
116   @Deprecated
117   public static final UserAgent MOZILLA = new UserAgent("mozilla", null);
118 
119   /**
120    * @deprecated no longer supported, since Tobago 1.5
121    */
122   @Deprecated
123   public static final UserAgent MOZILLA_4_7 = new UserAgent("mozilla", "4_7");
124 
125   /**
126    * @deprecated no longer supported, since Tobago 1.5
127    */
128   @Deprecated
129   public static final UserAgent MOZILLA_5_0 = new UserAgent("mozilla", "5_0");
130 
131   /**
132    * @deprecated no longer supported, since Tobago 1.5
133    */
134   @Deprecated
135   public static final UserAgent MOZILLA_5_0_R1_6 = new UserAgent("mozilla", "5_0_r1_6");
136 
137   /**
138    * e. g. Firefox
139    */
140   public static final UserAgent GECKO
141       = new UserAgent("gecko", null, EnumSet.of(Capability.CONTENT_TYPE_XHTML), CspHeader.CSP_GECKO);
142 
143   /**
144    * e. g. Firefox 2.0
145    */
146   public static final UserAgent GECKO_1_8 = new UserAgent("gecko", "1_8", EnumSet.of(Capability.CONTENT_TYPE_XHTML));
147 
148   /**
149    * e. g. Firefox 3.0, 3.5, 3.6
150    */
151   public static final UserAgent GECKO_1_9 = new UserAgent("gecko", "1_9", EnumSet.of(Capability.CONTENT_TYPE_XHTML));
152 
153   /**
154    * e. g. Firefox 4.0
155    */
156   public static final UserAgent GECKO_2_0
157       = new UserAgent("gecko", "2_0",
158       EnumSet.of(Capability.PLACEHOLDER, Capability.CONTENT_TYPE_XHTML), CspHeader.CSP_GECKO);
159 
160   /**
161    * e. g. Firefox 5.0
162    */
163   public static final UserAgent GECKO_5_0
164       = new UserAgent("gecko", "5_0",
165       EnumSet.of(Capability.PLACEHOLDER, Capability.CONTENT_TYPE_XHTML), CspHeader.CSP_GECKO);
166 
167   /**
168    * e. g. Safari 4, Safari 5, Chrome
169    */
170   public static final UserAgent WEBKIT
171       = new UserAgent("webkit", null,
172       EnumSet.of(Capability.PLACEHOLDER, Capability.CONTENT_TYPE_XHTML), CspHeader.CSP_WEBKIT);
173 
174   private final String name;
175 
176   private final String version;
177 
178   private final EnumSet<Capability> capabilities;
179 
180   private final CspHeader cspHeader;
181 
182   private UserAgent(String name, String version) {
183     this(name, version, EnumSet.of(Capability.CONTENT_TYPE_XHTML));
184   }
185 
186   private UserAgent(String name, String version, EnumSet<Capability> capabilities) {
187     this(name, version, capabilities, CspHeader.CSP_NOT_SUPPORTED);
188   }
189 
190   private UserAgent(String name, String version, EnumSet<Capability> capabilities, CspHeader cspHeader) {
191     this.name = name;
192     this.version = version;
193     this.capabilities = capabilities;
194     this.cspHeader = cspHeader;
195   }
196 
197   public boolean hasCapability(Capability capability) {
198     return capabilities.contains(capability);
199   }
200 
201   public boolean isMsie() {
202     return MSIE.name.equals(name);
203   }
204 
205   public boolean isMsie6() {
206     return MSIE_6_0.name.equals(name) && MSIE_6_0.version.equals(version);
207   }
208 
209   /**
210    * @deprecated no longer supported, since Tobago 1.5
211    */
212   @Deprecated
213   public boolean isMozilla() {
214     return MOZILLA.name.equals(name);
215   }
216 
217   public List<String> getFallbackList() {
218     return getFallbackList(false);
219   }
220 
221   private List<String> getFallbackList(boolean reverseOrder) {
222     List<String> list = new ArrayList<String>(3);
223     if (version != null) {
224       list.add(name + '_' + version);
225     }
226     if (name != null) {
227       list.add(name);
228     }
229     list.add(DEFAULT_NAME);
230     if (reverseOrder) {
231       Collections.reverse(list);
232     }
233     return list;
234   }
235 
236   /**
237    * @return The HTTP header name for Content-Security-Policy.
238    */
239   public String getCspHeader() {
240     return cspHeader.getName();
241   }
242 
243   public static UserAgent getInstance(String header) {
244     if (header == null) {
245       return DEFAULT;
246     }
247 
248     if (header.contains("MSIE")) {
249       if (header.contains("MSIE 6.0")) {
250         return MSIE_6_0;
251       } else if (header.contains("MSIE 7.0")) {
252         if (header.contains("Trident")) {
253           return MSIE_7_0_COMPAT;
254         } else {
255           return MSIE_7_0;
256         }
257       } else if (header.contains("MSIE 8.0")) {
258         return MSIE_8_0;
259       } else if (header.contains("MSIE 9.0")) {
260         return MSIE_9_0;
261       } else if (header.contains("MSIE 10.0")) {
262         return MSIE_10_0;
263       } else {
264         return MSIE;
265       }
266     } else if (header.contains("AppleWebKit")) {
267       return WEBKIT;
268     } else if (header.contains("Gecko")) {
269       if (header.contains("rv:1.8")) {
270         return GECKO_1_8;
271       } else if (header.contains("rv:1.9")) {
272         return GECKO_1_9;
273       } else if (header.contains("rv:2.0")) {
274         return GECKO_2_0;
275       } else if (header.contains("rv:5.0")) {
276         return GECKO_5_0;
277       } else {
278         return GECKO;
279       }
280     } else if (header.contains("Presto")) {
281       return PRESTO;
282     }
283 
284     return DEFAULT;
285   }
286 
287   /**
288    * @deprecated no longer supported, since Tobago 1.5
289    */
290   @Deprecated
291   public static UserAgent getInstanceForId(String id) {
292     Deprecation.LOG.error("Getting the user agent from its id is no longer supported! id='" + id + "'");
293     return DEFAULT;
294   }
295 
296   /**
297    * @deprecated don't use toString() functionality, but for logging!
298    */
299   @Deprecated
300   public String toString() {
301     return version != null
302         ? name + '_' + version
303         : name;
304   }
305 
306   private static enum CspHeader {
307 
308     CSP_NOT_SUPPORTED(null),
309     CSP_GECKO("X-Content-Security-Policy"),
310     CSP_WEBKIT("X-WebKit-CSP"),
311     CSP_STANDARD("Content-Security-Policy");
312 
313     private String name;
314 
315     private CspHeader(String name) {
316       this.name = name;
317     }
318 
319     public String getName() {
320       return name;
321     }
322   }
323 }