in velocity-tools-view/src/main/java/org/apache/velocity/tools/view/UAParser.java [264:613]
public static UserAgent parseUserAgent(String userAgentString, Logger log)
{
UserAgent ua = null;
try
{
ua = new UserAgent();
Matcher matcher = versionPattern.matcher(userAgentString);
String merge = null;
EntityType mergeTarget = null;
boolean maybeBrowser = true;
boolean maybeOS = true;
boolean maybeRobot = false;
boolean forcedBrowser = false;
boolean forcedOS = false;
while (matcher.find())
{
String entity = matcher.group(1);
String separator = matcher.group(2);
String major = matcher.group(3);
String minor = matcher.group(4);
char next = userAgentString.length() == matcher.end(1) ? ';' : userAgentString.charAt(matcher.end(1));
if (entity != null)
{
if (merge != null)
{
String merged = merge + " " + entity;
if (mergeTarget == null)
{
entity = merged;
}
else
{
Pair<EntityType,DeviceType> pair = entityMap.get(merged.toLowerCase());
EntityType mergedType = pair == null ? null : pair.getLeft();
if (mergedType != null && (
mergeTarget == mergedType ||
mergeTarget == EntityType.BROWSER && (mergedType == EntityType.MAYBE_BROWSER || mergedType == EntityType.FORCE_BROWSER) ||
mergeTarget == EntityType.OS && (mergedType == EntityType.MAYBE_OS || mergedType == EntityType.FORCE_OS)
))
{
entity = merged;
}
else
{
/* It means the merge failed, so revert it */
switch (mergeTarget)
{
case BROWSER:
ua.setBrowser(merge, null, null);
break;
case OS:
ua.setOperatingSystem(merge, null, null);
break;
default:
throw new VelocityException("BrowserTool: unhandled case!");
}
}
}
merge = null;
mergeTarget = null;
}
Pair<EntityType, DeviceType> identity = entityMap.get(entity.toLowerCase());
EntityType entityType = null;
DeviceType deviceType = null;
if (identity == null)
{
/* try again with major version appended */
String alternateEntity = entity + separator + major;
identity = entityMap.get((entity + separator + major).toLowerCase());
if (identity != null)
{
entity = alternateEntity;
}
}
if (identity != null)
{
entityType = identity.getLeft();
deviceType = identity.getRight();
DeviceType previousDeviceType = ua.getDeviceType();
/* only overwrite device types of lower precedence */
if (deviceType != null && (previousDeviceType == null || deviceType.compareTo(previousDeviceType) > 0))
{
ua.setDeviceType(deviceType); // may be overwritten by 'robot' device type
}
}
if (entityType != null)
{
switch (entityType)
{
case BROWSER:
{
if (ua.getBrowser() == null || !forcedBrowser)
{
ua.setBrowser(entity, major, minor);
maybeBrowser = false;
}
break;
}
case BROWSER_OS:
{
ua.setBrowser(entity, major, minor);
maybeBrowser = false;
ua.setOperatingSystem(entity, major, minor);
maybeOS = false;
break;
}
case ENGINE:
{
if (!"KHTML".equals(entity) || major != null || ua.getRenderingEngine() == null)
{
ua.setRenderingEngine(entity, major, minor);
}
break;
}
case FORCE_BROWSER:
{
if (!forcedBrowser)
{
ua.setBrowser(entity, major, minor);
maybeBrowser = false;
forcedBrowser = true;
}
break;
}
case FORCE_OS:
{
if (!forcedOS)
{
ua.setOperatingSystem(entity, major, minor);
maybeOS = false;
forcedOS = true;
}
break;
}
case IGNORE:
{
break;
}
case MAYBE_BROWSER:
{
if (maybeBrowser)
{
if ("rv".equals(entity))
{
if (ua.getBrowser() != null && ua.getBrowser().getName().equals("Mozilla"))
{
entity = "Mozilla";
} else
{
entity = null;
}
} else if ("Version".equals(entity))
{
if (ua.getBrowser() != null && ua.getBrowser().getName().startsWith("Opera"))
{
entity = ua.getBrowser().getName();
} else if (ua.getBrowser() != null && ua.getBrowser().getName().equals("Mozilla"))
{
entity = "Safari";
} else
{
entity = null;
}
} else if ("Safari".equals(entity) && ua.getBrowser() != null && "Safari".equals(ua.getBrowser().getName()))
{
entity = null;
}
if (entity != null)
{
ua.setBrowser(entity, major, minor);
}
}
break;
}
case MAYBE_OS:
{
if (maybeOS)
{
ua.setOperatingSystem(entity, major, minor);
}
break;
}
case MAYBE_ROBOT:
{
maybeRobot = true;
break;
}
case MERGE:
{
if (major == null)
{
if (nonMergeSep.indexOf(next) == -1)
{
merge = merge == null ? entity : merge + " " + entity;
} else
{
if ("Mobile".equals(entity) && ua.getOperatingSystem() != null)
{
if (ua.getOperatingSystem().getName().equals("Ubuntu"))
{
ua.setOperatingSystem("Ubuntu Mobile", String.valueOf(ua.getOperatingSystem().getMajorVersion()), String.valueOf(ua.getOperatingSystem().getMinorVersion()));
} else if (ua.getOperatingSystem().getName().equals("Linux"))
{
ua.setOperatingSystem("Android", null, null);
}
}
}
}
break;
}
case MERGE_OR_BROWSER:
{
if (!forcedBrowser)
{
if (major != null || nonMergeSep.indexOf(next) != -1)
{
ua.setBrowser(entity, major, minor);
} else
{
merge = entity;
mergeTarget = EntityType.BROWSER;
}
}
break;
}
case MERGE_OR_OS:
{
if (!forcedOS)
{
if (major != null || nonMergeSep.indexOf(next) != -1)
{
ua.setOperatingSystem(entity, major, minor);
} else
{
merge = entity;
mergeTarget = EntityType.OS;
}
}
break;
}
case OS:
{
if (ua.getOperatingSystem() == null || !forcedOS)
{
ua.setOperatingSystem(entity, major, minor);
maybeOS = false;
}
break;
}
case ROBOT:
{
ua.setDeviceType(DeviceType.ROBOT);
break;
}
default:
{
throw new VelocityException("BrowserTool: unhandled case: " + entityType);
}
}
}
else
{
if (entity.startsWith("Linux") && !forcedOS)
{
ua.setOperatingSystem("Linux", null, null);
}
else if (isRobotToken(entity))
{
ua.setDeviceType(DeviceType.ROBOT);
}
else if (entity.startsWith("MID") && !entity.startsWith("MIDP") && (ua.getDeviceType() == null || DeviceType.TABLET.compareTo(ua.getDeviceType()) > 0 ))
{
ua.setDeviceType(DeviceType.TABLET);
}
else if (entity.startsWith("CoolPad") && (ua.getDeviceType() == null || DeviceType.MOBILE.compareTo(ua.getDeviceType()) > 0 ))
{
ua.setDeviceType(DeviceType.MOBILE);
}
else if (entity.startsWith("LG-") && (ua.getDeviceType() == null || DeviceType.MOBILE.compareTo(ua.getDeviceType()) > 0 ))
{
ua.setDeviceType(DeviceType.MOBILE);
}
else if (entity.startsWith("SonyEricsson"))
{
ua.setDeviceType(DeviceType.MOBILE);
}
}
}
}
if (ua.getOperatingSystem() != null && "Windows".equals(ua.getOperatingSystem().getName()) && (ua.getOperatingSystem().getMajorVersion() == 98 || ua.getOperatingSystem().getMajorVersion() == 2000))
{
if (ua.getOperatingSystem().getMajorVersion() == 98)
{
ua.setOperatingSystem("Windows 98", "4", "90");
}
else if (ua.getOperatingSystem().getMajorVersion() == 2000)
{
ua.setOperatingSystem("Windows 2000", "5", "0");
}
}
if (ua.getBrowser() == null)
{
if (ua.getDeviceType() == DeviceType.ROBOT || maybeRobot)
{
ua.setBrowser("robot", "0", "0");
ua.setDeviceType(DeviceType.ROBOT);
}
else if (ua.getOperatingSystem() != null && ua.getOperatingSystem().getName().equals("Symbian"))
{
ua.setBrowser("Nokia Browser", String.valueOf(ua.getOperatingSystem().getMajorVersion()), String.valueOf(ua.getOperatingSystem().getMinorVersion()));
}
else
{
ua.setBrowser("unknown", "0", "0");
}
}
if (ua.getOperatingSystem() == null)
{
if (ua.getDeviceType() == DeviceType.ROBOT || maybeRobot)
{
ua.setOperatingSystem("robot", "0", "0");
ua.setDeviceType(DeviceType.ROBOT);
}
else
{
ua.setOperatingSystem("unknown", "0", "0");
}
}
if (ua.getDeviceType() == null)
{
if (ua.getOperatingSystem() != null && "Android".equals(ua.getOperatingSystem().getName()))
{
ua.setDeviceType(DeviceType.MOBILE);
}
else
{
/* make Desktop the default device */
ua.setDeviceType(DeviceType.DESKTOP);
}
}
}
catch (Exception e)
{
log.error("Could not parse browser for User-Agent: {}", userAgentString, e);
ua = null;
}
return ua;
}