nextapp.echo2.webrender.ClientAnalyzerProcessor Maven / Gradle / Ivy
The newest version!
/*
* This file is part of the Echo Web Application Framework (hereinafter "Echo").
* Copyright (C) 2002-2009 NextApp, Inc.
*
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*/
package nextapp.echo2.webrender;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import nextapp.echo2.webrender.service.SynchronizeService;
import nextapp.echo2.webrender.util.DomUtil;
import org.w3c.dom.Element;
/**
* SynchronizeService.ClientMessagePartProcessor
which creates
* a ClientProperties
object based on the client script's
* analysis of its environment.
*/
public class ClientAnalyzerProcessor
implements SynchronizeService.ClientMessagePartProcessor {
/**
* Set
containing valid properties which may be received from
* the client. Property settings received from the client that are not in
* this set are discarded.
*/
private static final Set VALID_PROPERTIES;
static {
Set set = new HashSet();
set.add(ClientProperties.NAVIGATOR_APP_CODE_NAME);
set.add(ClientProperties.NAVIGATOR_APP_NAME);
set.add(ClientProperties.NAVIGATOR_APP_VERSION);
set.add(ClientProperties.NAVIGATOR_COOKIE_ENABLED);
set.add(ClientProperties.NAVIGATOR_JAVA_ENABLED);
set.add(ClientProperties.NAVIGATOR_LANGUAGE);
set.add(ClientProperties.NAVIGATOR_PLATFORM);
set.add(ClientProperties.NAVIGATOR_USER_AGENT);
set.add(ClientProperties.SCREEN_WIDTH);
set.add(ClientProperties.SCREEN_HEIGHT);
set.add(ClientProperties.SCREEN_COLOR_DEPTH);
set.add(ClientProperties.UTC_OFFSET);
set.add(ClientProperties.UNESCAPED_XHR_TEST);
VALID_PROPERTIES = Collections.unmodifiableSet(set);
}
/**
* Analyzes the state of ClientProperties
and adds additional
* inferred data, such as quirk attributes based on browser type.
*
* @param clientProperties the ClientProperties
to analyze
* and update
*/
private void analyze(ClientProperties clientProperties) {
Connection conn = WebRenderServlet.getActiveConnection();
Enumeration localeEnum = conn.getRequest().getLocales();
List localeList = new ArrayList();
while (localeEnum.hasMoreElements()) {
localeList.add(localeEnum.nextElement());
}
clientProperties.setProperty(ClientProperties.LOCALES, localeList.toArray(new Locale[localeList.size()]));
clientProperties.setProperty(ClientProperties.REMOTE_HOST, conn.getRequest().getRemoteHost());
String userAgent = clientProperties.getString(ClientProperties.NAVIGATOR_USER_AGENT).toLowerCase();
boolean browserOpera = userAgent.indexOf("opera") != -1;
boolean browserSafari = userAgent.indexOf("safari") != -1;
boolean browserKonqueror = userAgent.indexOf("konqueror") != -1;
// Note deceptive user agent fields:
// - Konqueror and Safari UA fields contain "like Gecko"
// - Opera UA field typically contains "MSIE"
boolean deceptiveUserAgent = browserOpera || browserSafari || browserKonqueror;
boolean browserMozilla = !deceptiveUserAgent && userAgent.indexOf("gecko") != -1;
boolean browserFireFox = userAgent.indexOf("firefox") != -1;
boolean browserInternetExplorer = !deceptiveUserAgent && userAgent.indexOf("msie") != -1;
int majorVersion = -1, minorVersion = -1;
// Store browser information.
if (browserOpera) {
clientProperties.setProperty(ClientProperties.BROWSER_OPERA, Boolean.TRUE);
if (userAgent.indexOf("opera/9") != -1 || userAgent.indexOf("opera 9") != -1) {
majorVersion = 9;
} else if (userAgent.indexOf("opera/8") != -1 || userAgent.indexOf("opera 8") != -1) {
majorVersion = 8;
} else {
// Assume future version with Opera 9 compatibility.
// (Versions prior to 8 do not provide minimum requirements, i.e., XMLHTTPRequest.)
majorVersion = 9;
}
} else if (browserKonqueror) {
clientProperties.setProperty(ClientProperties.BROWSER_KONQUEROR, Boolean.TRUE);
} else if (browserSafari) {
clientProperties.setProperty(ClientProperties.BROWSER_SAFARI, Boolean.TRUE);
} else if (browserMozilla) {
clientProperties.setProperty(ClientProperties.BROWSER_MOZILLA, Boolean.TRUE);
if (browserFireFox) {
clientProperties.setProperty(ClientProperties.BROWSER_MOZILLA_FIREFOX, Boolean.TRUE);
if (userAgent.indexOf("firefox/3.0") != -1) {
majorVersion = 3;
minorVersion = 0;
}
}
} else if (browserInternetExplorer) {
clientProperties.setProperty(ClientProperties.BROWSER_INTERNET_EXPLORER, Boolean.TRUE);
if (userAgent.indexOf("msie 6.") != -1) {
majorVersion = 6;
} else if (userAgent.indexOf("msie 7.") != -1) {
majorVersion = 7;
}
}
if (majorVersion != -1) {
clientProperties.setProperty(ClientProperties.BROWSER_VERSION_MAJOR, Integer.toString(majorVersion));
}
if (minorVersion != -1) {
clientProperties.setProperty(ClientProperties.BROWSER_VERSION_MINOR, Integer.toString(minorVersion));
}
// Set quirk flags.
if (browserInternetExplorer) {
clientProperties.setProperty(ClientProperties.QUIRK_IE_REPAINT, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_TEXTAREA_CONTENT, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_IE_TEXTAREA_NEWLINE_OBLITERATION, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_IE_SELECT_LIST_DOM_UPDATE, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_CSS_BORDER_COLLAPSE_INSIDE, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_CSS_BORDER_COLLAPSE_FOR_0_PADDING, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.NOT_SUPPORTED_CSS_OPACITY, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_DELAYED_FOCUS_REQUIRED, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.PROPRIETARY_IE_CSS_EXPRESSIONS_SUPPORTED, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.PROPRIETARY_EVENT_MOUSE_ENTER_LEAVE_SUPPORTED, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.PROPRIETARY_IE_OPACITY_FILTER_REQUIRED, Boolean.TRUE);
// The following flaws are verified as present in IE7.0Beta2:
clientProperties.setProperty(ClientProperties.QUIRK_IE_TABLE_PERCENT_WIDTH_SCROLLBAR_ERROR, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_IE_SELECT_PERCENT_WIDTH, Boolean.TRUE);
if (majorVersion < 7) {
// The following flaws are verified as fixed in IE7.0Beta2:
clientProperties.setProperty(ClientProperties.PROPRIETARY_IE_PNG_ALPHA_FILTER_REQUIRED, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_CSS_POSITIONING_ONE_SIDE_ONLY, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_CSS_BACKGROUND_ATTACHMENT_USE_FIXED, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_IE_SELECT_Z_INDEX, Boolean.TRUE);
}
}
if (browserOpera) {
clientProperties.setProperty(ClientProperties.QUIRK_TEXTAREA_CONTENT, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_OPERA_NO_CSS_TEXT, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_SELECT_REQUIRES_NULL_OPTION, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_IE_SELECT_PERCENT_WIDTH, Boolean.TRUE);
if (majorVersion < 9) {
clientProperties.setProperty(ClientProperties.NOT_SUPPORTED_CSS_OPACITY, Boolean.TRUE);
}
}
if (browserMozilla) {
clientProperties.setProperty(ClientProperties.QUIRK_SELECT_REQUIRES_NULL_OPTION, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_MOZILLA_TEXT_INPUT_REPAINT, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_MOZILLA_PERFORMANCE_LARGE_DOM_REMOVE, Boolean.TRUE);
}
if (browserKonqueror) {
clientProperties.setProperty(ClientProperties.QUIRK_SELECT_REQUIRES_NULL_OPTION, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.QUIRK_IE_SELECT_PERCENT_WIDTH, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.NOT_SUPPORTED_CSS_MANIPULATION, Boolean.TRUE);
}
if (browserSafari) {
clientProperties.setProperty(ClientProperties.QUIRK_SELECT_REQUIRES_NULL_OPTION, Boolean.TRUE);
clientProperties.setProperty(ClientProperties.NOT_SUPPORTED_CSS_MANIPULATION, Boolean.TRUE);
String unescapeTest = clientProperties.getString(ClientProperties.UNESCAPED_XHR_TEST);
if (unescapeTest.equals("&")) {
clientProperties.setProperty(ClientProperties.QUIRK_SAFARI_UNESCAPED_XHR, Boolean.TRUE);
}
}
}
/**
* @see nextapp.echo2.webrender.service.SynchronizeService.ClientMessagePartProcessor#getName()
*/
public String getName() {
return "EchoClientAnalyzer";
}
/**
* @see nextapp.echo2.webrender.service.SynchronizeService.ClientMessagePartProcessor#process(
* nextapp.echo2.webrender.UserInstance, org.w3c.dom.Element)
*/
public void process(UserInstance userInstance, Element messagePartElement) {
ClientProperties clientProperties = new ClientProperties();
Element[] propertyElements = DomUtil.getChildElementsByTagName(messagePartElement, "property");
for (int i = 0; i < propertyElements.length; ++i) {
String propertyName = propertyElements[i].getAttribute("name");
if (VALID_PROPERTIES.contains(propertyName)) {
String type = propertyElements[i].getAttribute("type");
if ("text".equals(type)) {
clientProperties.setProperty(propertyName, propertyElements[i].getAttribute("value"));
} else if ("integer".equals(type)) {
try {
clientProperties.setProperty(propertyName,
new Integer(propertyElements[i].getAttribute("value")));
} catch (NumberFormatException ex) { }
} else if ("boolean".equals(type)) {
clientProperties.setProperty(propertyName,
new Boolean("true".equals(propertyElements[i].getAttribute("value"))));
}
}
}
userInstance.setClientProperties(clientProperties);
analyze(clientProperties);
}
}