You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devicemap.apache.org by wk...@apache.org on 2015/11/30 00:36:19 UTC
svn commit: r1717136 [1/4] - in /devicemap/trunk/clients/1.0/java: ./
client/ client/src/ client/src/main/ client/src/main/java/
client/src/main/java/org/ client/src/main/java/org/apache/
client/src/main/java/org/apache/devicemap/ client/src/main/java/...
Author: wkeil
Date: Sun Nov 29 23:36:18 2015
New Revision: 1717136
URL: http://svn.apache.org/viewvc?rev=1717136&view=rev
Log:
DMAP-54: Improve Console example
Task-Url: https://issues.apache.org/jira/browse/DMAP-54
DMAP-155: UA changes with Windows 10 update
Task-Url: https://issues.apache.org/jira/browse/DMAP-155
Added:
devicemap/trunk/clients/1.0/java/client/ (with props)
devicemap/trunk/clients/1.0/java/client/pom.xml
devicemap/trunk/clients/1.0/java/client/src/
devicemap/trunk/clients/1.0/java/client/src/main/
devicemap/trunk/clients/1.0/java/client/src/main/java/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapClient.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapFactory.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/cmd/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/cmd/Main.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Device.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/DeviceType.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Pattern.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/PatternSet.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Loader.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderFactory.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderOption.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Resource.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/DDRLoader.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/NoopLoader.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/UninitializedLoader.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/JsonParser.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/XMLParser.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/FileResource.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/JarResource.java
devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/URLResource.java
devicemap/trunk/clients/1.0/java/client/src/test/
devicemap/trunk/clients/1.0/java/client/src/test/java/
devicemap/trunk/clients/1.0/java/client/src/test/java/org/
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientFileTestOptional.java
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientJarTest.java
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientTest.java
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientUnitTest.java
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientUrlTestOptional.java
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/loader/
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/loader/parser/
devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/loader/parser/XMLParserTest.java
devicemap/trunk/clients/1.0/java/client/src/test/resources/
devicemap/trunk/clients/1.0/java/client/src/test/resources/uas.data
devicemap/trunk/clients/1.0/java/console/ (with props)
devicemap/trunk/clients/1.0/java/console/pom.xml
devicemap/trunk/clients/1.0/java/console/src/
devicemap/trunk/clients/1.0/java/console/src/main/
devicemap/trunk/clients/1.0/java/console/src/main/java/
devicemap/trunk/clients/1.0/java/console/src/main/java/org/
devicemap/trunk/clients/1.0/java/console/src/main/java/org/apache/
devicemap/trunk/clients/1.0/java/console/src/main/java/org/apache/devicemap/
devicemap/trunk/clients/1.0/java/console/src/main/java/org/apache/devicemap/console/
devicemap/trunk/clients/1.0/java/console/src/main/java/org/apache/devicemap/console/Main.java
Removed:
devicemap/trunk/clients/1.0/java/src/
Modified:
devicemap/trunk/clients/1.0/java/pom.xml
Propchange: devicemap/trunk/clients/1.0/java/client/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sun Nov 29 23:36:18 2015
@@ -0,0 +1,4 @@
+target
+.settings
+.classpath
+.project
Added: devicemap/trunk/clients/1.0/java/client/pom.xml
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/pom.xml?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/pom.xml (added)
+++ devicemap/trunk/clients/1.0/java/client/pom.xml Sun Nov 29 23:36:18 2015
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.devicemap</groupId>
+ <artifactId>devicemap-java</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.apache.devicemap</groupId>
+ <artifactId>devicemap-client</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache DeviceMap Java Client</name>
+ <description>Apache DeviceMap Java API</description>
+ <url>http://devicemap.apache.org/</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/devicemap/trunk/devicemap/java/classifier</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/devicemap/trunk/devicemap/java/classifier</developerConnection>
+ <url>http://svn.apache.org/viewvc/devicemap/trunk/devicemap/java/classifier</url>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.devicemap</groupId>
+ <artifactId>devicemap-data</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ <debug>true</debug>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapClient.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapClient.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapClient.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapClient.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,198 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.devicemap.data.Device;
+import org.apache.devicemap.loader.LoaderOption;
+import org.apache.devicemap.data.DeviceType;
+import org.apache.devicemap.data.Pattern;
+import org.apache.devicemap.loader.LoaderFactory;
+
+public class DeviceMapClient {
+
+ private final static Logger LOG = Logger.getLogger(DeviceMapClient.class.getName());
+ private final static java.util.regex.Pattern TEXT_SPLIT_PATTERN = java.util.regex.Pattern.compile(" |-|_|/|\\\\|\\[|\\]|\\(|\\)|;");
+
+ private static long initCount = 0;
+
+ //indexes
+ private Map<String, DeviceType> devices;
+ private Map<String, List<DeviceType>> patterns;
+
+ private final Device unknown;
+
+ public DeviceMapClient() {
+ devices = null;
+ patterns = null;
+ Map<String, String> uAttributes = new HashMap<String, String>();
+ uAttributes.put("id", Device.UNKNOWN_ID);
+ uAttributes = Collections.unmodifiableMap(uAttributes);
+ unknown = new Device(Device.UNKNOWN_ID, uAttributes);
+ }
+
+ public void initDeviceData(LoaderOption option) throws IOException {
+ initDeviceData(option, null);
+ }
+
+ public synchronized void initDeviceData(LoaderOption option, String path) throws IOException {
+ devices = LoaderFactory.getLoader(option, path).getData();
+
+ initCount++;
+
+ if (initCount % 1000 == 0) {
+ LOG.log(Level.WARNING, "Possible device data over-initialization detected");
+ }
+
+ if (devices == null) {
+ patterns = null;
+ return;
+ }
+
+ createIndex();
+ }
+
+ private void createIndex() {
+ patterns = new HashMap<String, List<DeviceType>>(8000);
+
+ for (DeviceType device : devices.values()) {
+ for (Pattern pattern : device.getPatternSet().getPatterns()) {
+ for (int i = 0; i < pattern.getPatternParts().size(); i++) {
+ String part = pattern.getPatternParts().get(i);
+
+ //duplicate
+ if (patterns.get(part) != null) {
+ if (i == (pattern.getPatternParts().size() - 1) && !patterns.get(part).contains(device)) {
+ patterns.get(part).add(device);
+ }
+ } else {
+ List<DeviceType> single = new ArrayList<DeviceType>();
+ single.add(device);
+ patterns.put(part, single);
+ }
+ }
+ }
+ }
+ }
+
+ public Map<String, String> classify(String text) {
+ if (devices == null) {
+ throw new RuntimeException("Uninitialized device index");
+ }
+
+ if (text == null) {
+ return null;
+ }
+
+ Set<String> hitPatterns = new HashSet<String>();
+ Set<DeviceType> hitDevices = new HashSet<DeviceType>();
+ DeviceType winner = null;
+ Pattern winnerPattern = null;
+
+ LOG.log(Level.FINE, "classify: ''{0}''", text);
+
+ List<String> parts = split(text);
+
+ //generate ngrams upto size 4
+ for (int i = 0; i < parts.size(); i++) {
+ String pattern = "";
+ for (int j = 0; j < 4 && (j + i) < parts.size(); j++) {
+ pattern += parts.get(i + j);
+ List<DeviceType> dlist = patterns.get(pattern);
+ if (dlist != null) {
+ hitPatterns.add(pattern);
+ hitDevices.addAll(dlist);
+ for (DeviceType device : dlist) {
+ LOG.log(Level.FINER, "Hit found: ''{0}'' => id: ''{1}'' {2}", new Object[]{pattern, device.getId(), device.getPatternSet()});
+ }
+ }
+ }
+ }
+
+ //look for the strongest hit
+ for (DeviceType device : hitDevices) {
+ Pattern pattern = device.getPatternSet().isValid(hitPatterns);
+ if (pattern == null) {
+ continue;
+ }
+
+ LOG.log(Level.FINER, "Hit candidate: ''{0}'' => ({1},{2})", new Object[]{device.getId(), pattern.getType(), pattern.getRank()});
+
+ if (winnerPattern == null || pattern.getRank() > winnerPattern.getRank()) {
+ winner = device;
+ winnerPattern = pattern;
+ }
+ }
+
+ if (winner != null) {
+ LOG.log(Level.FINE, "Result: {0}", winner);
+ return winner.getAttributes();
+ } else {
+ return null;
+ }
+ }
+
+ private static List<String> split(String text) {
+ String[] parts = TEXT_SPLIT_PATTERN.split(text);
+ List<String> nonemptyParts = new ArrayList<String>();
+ for (String part : parts) {
+ String normalizedPart = Pattern.normalize(part);
+ if (normalizedPart != null && !normalizedPart.isEmpty())
+ nonemptyParts.add(normalizedPart);
+ }
+ return nonemptyParts;
+ }
+
+ public Device classifyDevice(String text) {
+ Map<String, String> m = classify(text);
+ if (m == null) {
+ return unknown;
+ }
+ return new Device(m.get("id"), m);
+ }
+
+ public int getDeviceCount() {
+ if (devices == null) {
+ return -1;
+ }
+ return devices.size();
+ }
+
+ public int getPatternCount() {
+ if (patterns == null) {
+ return -1;
+ }
+ return patterns.size();
+ }
+
+ public long getNodeCount() {
+ if (patterns == null) {
+ return -1;
+ }
+ long count = 0;
+ for (List<DeviceType> pDevices : patterns.values()) {
+ count += pDevices.size();
+ }
+ return count;
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapFactory.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapFactory.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapFactory.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/DeviceMapFactory.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,62 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap;
+
+import java.io.IOException;
+import org.apache.devicemap.loader.LoaderOption;
+
+public class DeviceMapFactory {
+
+ private static DeviceMapClient client = null;
+ private static volatile boolean initialized = false;
+
+ private static final LoaderOption DEFAULT = LoaderOption.JAR;
+
+ private DeviceMapFactory() {
+ }
+
+ public static DeviceMapClient getClient() {
+ return getClient(DEFAULT, null);
+ }
+
+ public static DeviceMapClient getClient(LoaderOption option) {
+ return getClient(option, null);
+ }
+
+ public static DeviceMapClient getClient(LoaderOption option, String path) {
+ if (!initialized) {
+ synchronized (DeviceMapFactory.class) {
+ if (!initialized) {
+ client = new DeviceMapClient();
+ try {
+ client.initDeviceData(option, path);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ initialized = true;
+ }
+ }
+ }
+ return client;
+ }
+
+ public static void resetClient() {
+ initialized = false;
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/cmd/Main.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/cmd/Main.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/cmd/Main.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/cmd/Main.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,153 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.cmd;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.devicemap.DeviceMapClient;
+import org.apache.devicemap.data.Device;
+import org.apache.devicemap.loader.LoaderOption;
+import org.apache.devicemap.loader.impl.DDRLoader;
+
+/**
+ * @author Reza Naghibi
+ * @author Werner Keil
+ */
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+
+ System.out.println("DeviceMap Java Console " + DeviceMapClient.class.getPackage().getImplementationVersion());
+
+ if(args.length == 0) {
+ System.out.println("Usage: -h for help");
+ }
+
+ String loaderPath = null;
+ LoaderOption option = LoaderOption.UNINITIALIZED;
+ String parameter = null;
+ boolean debug = true;
+
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].equals("-f")) {
+ option = LoaderOption.FOLDER;
+ if (args.length > (++i)) {
+ loaderPath = args[i];
+ }
+ } else if (args[i].equals("-u")) {
+ option = LoaderOption.URL;
+ if (args.length > (++i)) {
+ loaderPath = args[i];
+ }
+ } else if (args[i].equals("-j")) {
+ option = LoaderOption.JAR;
+ } else if (args[i].equals("-d")) {
+ debug = false;
+ } else if (args[i].startsWith("-h") || args[i].startsWith("--h")) {
+ System.out.println("Usage: " + Main.class.getName() + " [OPTIONS] [FILE|STRING]\n");
+ System.out.println(" -f <path> load DeviceMap resouces from folder or \"default\"");
+ System.out.println(" -j load DeviceMap resouces from jar file in classpath");
+ System.out.println(" -u <url> load DeviceMap resouces from URL or \"default\"");
+ System.out.println(" -d no debug logging");
+ System.out.println(" FILE text file of strings");
+ System.out.println(" STRING test string");
+
+ return;
+ } //[test string] | [test file]
+ else if(!args[i].isEmpty()) {
+ parameter = args[i];
+ }
+ }
+
+ if(debug) {
+ Logger.getLogger(DeviceMapClient.class.getName()).setLevel(Level.ALL);
+ Logger.getLogger(DDRLoader.class.getName()).setLevel(Level.ALL);
+ for (Handler h : Logger.getLogger(DeviceMapClient.class.getName()).getParent().getHandlers()) {
+ if (h instanceof ConsoleHandler) {
+ h.setLevel(Level.ALL);
+ }
+ }
+ }
+
+ if ("default".equals(loaderPath)) {
+ loaderPath = null;
+ }
+
+ DeviceMapClient client = new DeviceMapClient();
+ final long start = System.currentTimeMillis();
+ client.initDeviceData(option, loaderPath);
+ long diff = System.currentTimeMillis() - start;
+
+ System.out.println("Loaded " + client.getDeviceCount() + " devices with " + client.getPatternCount() +
+ " patterns and " + client.getNodeCount() + " nodes in " + diff + "ms");
+
+ final String test = "Mozilla/5.0 (Linux; U; Android 2.2; en; HTC Aria A6380 Build/ERE27) AppleWebKit/540.13+ (KHTML, like Gecko) Version/3.1 Mobile Safari/524.15.0";
+ long startn = System.nanoTime();
+ Device device = client.classifyDevice(test);
+ long diffn = (System.nanoTime() - startn) / 1000;
+
+ System.out.println("Test lookup: '" + device.getId() + "' time: " + diffn + "usec");
+
+ if (parameter == null) {
+ } else if ((new File(parameter)).exists()) {
+ System.out.println("Text file: " + parameter);
+
+ int count = 0;
+ int total = 0;
+
+ BufferedReader in = new BufferedReader(new FileReader(parameter));
+ String line;
+
+ while ((line = in.readLine()) != null) {
+ System.out.println("Text: '" + line + "'");
+ startn = System.nanoTime();
+ device = client.classifyDevice(line);
+ diffn = System.nanoTime() - startn;
+ total += diffn;
+ count++;
+
+ System.out.println("Text lookup " + count + ": '" + device.getId() + "' time: " + (diffn / 1000) + "usec");
+ }
+
+ in.close();
+
+ if (count == 0) {
+ count = 1;
+ }
+
+ total /= count;
+
+ System.out.println("TOTAL lookups: " + count + ", average time: " + (total / 1000) + "usec");
+ } else {
+ System.out.println("Text: '" + parameter + "'");
+
+ startn = System.nanoTime();
+ device = client.classifyDevice(parameter);
+ diffn = System.nanoTime() - startn;
+ System.out.println("Text lookup: '" + device.getId() + "' time: " + (diffn / 1000) + "usec");
+ System.out.println("DeviceMap JSON => " + device.toString());
+ }
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Device.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Device.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Device.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Device.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,60 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.data;
+
+import java.util.Map;
+import org.apache.devicemap.loader.parser.JsonParser;
+
+public class Device {
+
+ public static final String UNKNOWN_ID = "unknown";
+
+ private final String id;
+
+ private final Map<String, String> attributes;
+
+ public Device(String id, Map<String, String> attributes) {
+ this.id = id;
+ this.attributes = attributes;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append('{');
+ sb.append(JsonParser.outputKeyValue("id",id)).append(',');
+ sb.append(JsonParser.outputString("attributes")).append(':').append(JsonParser.outputMap(attributes));
+ sb.append('}');
+
+ return sb.toString();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getAttribute(String key) {
+ return attributes.get(key);
+ }
+
+ public Map<String, String> getAttributes() {
+ return attributes;
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/DeviceType.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/DeviceType.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/DeviceType.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/DeviceType.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,84 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.data;
+
+import java.util.Collections;
+import java.util.Map;
+import org.apache.devicemap.loader.parser.JsonParser;
+
+public class DeviceType {
+
+ private String id;
+
+ private String parentId;
+
+ private final PatternSet pattern;
+
+ private Map<String, String> attributes;
+
+ public DeviceType() {
+ pattern = new PatternSet();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append('{');
+ sb.append(JsonParser.outputKeyValue("id", id)).append(',');
+ sb.append(JsonParser.outputKeyValue("parentId", parentId)).append(',');
+ sb.append(JsonParser.outputString("pattern")).append(':').append(pattern.toString()).append(',');
+ sb.append(JsonParser.outputString("attributes")).append(':').append(JsonParser.outputMap(attributes));
+ sb.append('}');
+
+ return sb.toString();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getParentId() {
+ return parentId;
+ }
+
+ public void setParentId(String parentId) {
+ this.parentId = parentId;
+ }
+
+ public PatternSet getPatternSet() {
+ return pattern;
+ }
+
+ public Map<String, String> getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map<String, String> attributes) {
+ this.attributes = attributes;
+ }
+
+ public void lockAttributes() {
+ attributes = Collections.unmodifiableMap(attributes);
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Pattern.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Pattern.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Pattern.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/Pattern.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,121 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.data;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import org.apache.devicemap.loader.parser.JsonParser;
+
+public class Pattern {
+
+ private final List<String> pattern;
+
+ private final String type;
+
+ private final int rank;
+
+ private final int boost;
+
+ public Pattern(String pattern, String type, int boost) {
+ this(Arrays.asList(pattern), type, boost);
+ }
+
+ public Pattern(List<String> pattern, String type, int boost) {
+ this.pattern = pattern;
+ this.type = type;
+ this.boost = boost;
+ rank = genRank();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append('{');
+ sb.append(JsonParser.outputKeyValue("type", type)).append(',');
+ sb.append(JsonParser.outputKeyRValue("rank", rank)).append(',');
+ sb.append(JsonParser.outputKeyRValue("boost", boost)).append(',');
+ sb.append(JsonParser.outputString("pattern")).append(':').append(JsonParser.outputList(pattern, true));
+ sb.append('}');
+
+ return sb.toString();
+ }
+
+ private int genRank() {
+ int r = 0;
+
+ if ("weak".equals(type)) {
+ r += 1000;
+ }
+
+ r += pattern.size() * 100;
+
+ for (String part : pattern) {
+ r += part.length();
+ }
+
+ return r;
+ }
+
+ public int getRank() {
+ return rank + boost;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public List<String> getPatternParts() {
+ return pattern;
+ }
+
+ public boolean isValid(Set<String> patternsToMatch) {
+ for (String part : pattern) {
+ if (!patternsToMatch.contains(part)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * normalizes a pattern
+ */
+ public static String normalize(String p) {
+ if (p == null) {
+ return p;
+ }
+
+ p = p.toLowerCase().trim();
+
+ p = p.replaceAll("\\[bb\\]", "b");
+
+ StringBuilder ret = new StringBuilder();
+
+ for (int i = 0; i < p.length(); i++) {
+ Character c = p.charAt(i);
+ if (Character.isLetter(c) || Character.isDigit(c)) {
+ ret.append(c);
+ }
+ }
+
+ return ret.toString();
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/PatternSet.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/PatternSet.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/PatternSet.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/data/PatternSet.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,87 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.data;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import org.apache.devicemap.loader.parser.JsonParser;
+
+public class PatternSet {
+
+ private final List<Pattern> patterns;
+
+ public PatternSet() {
+ patterns = new ArrayList<Pattern>();
+ }
+
+ @Override
+ public String toString() {
+ List<String> orPatterns = new ArrayList<String>();
+ for (Pattern pattern : patterns) {
+ orPatterns.add(pattern.toString());
+ }
+ return JsonParser.outputList(orPatterns, false);
+ }
+
+ /*
+ * add the patterns together as an inner list (AND)
+ */
+ public void setAndPattern(List<String> patterns, String type) {
+ this.patterns.add(new Pattern(patterns, type, 0));
+ }
+
+ /*
+ * add each pattern on its own list (OR)
+ */
+ public void setOrPattern(List<String> patterns, String type) {
+ for (String pattern : patterns) {
+ setPattern(pattern, type);
+ }
+ }
+
+ /*
+ * add a single pattern (OR)
+ */
+ public void setPattern(String pattern, String type) {
+ patterns.add(new Pattern(pattern, type, 0));
+ }
+
+ public List<Pattern> getPatterns() {
+ return patterns;
+ }
+
+ /*
+ * does a pattern match
+ */
+ public Pattern isValid(Set<String> patternsToMatch) {
+ Pattern winner = null;
+
+ for (Pattern pattern : this.patterns) {
+ if (!pattern.isValid(patternsToMatch)) {
+ continue;
+ }
+ if (winner == null || pattern.getRank() > winner.getRank()) {
+ winner = pattern;
+ }
+ }
+
+ return winner;
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Loader.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Loader.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Loader.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Loader.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,29 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.devicemap.data.DeviceType;
+
+public interface Loader {
+
+ public Map<String, DeviceType> getData() throws IOException;
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderFactory.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderFactory.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderFactory.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderFactory.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,48 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+package org.apache.devicemap.loader;
+
+import org.apache.devicemap.loader.impl.DDRLoader;
+import org.apache.devicemap.loader.resource.JarResource;
+import org.apache.devicemap.loader.resource.FileResource;
+import org.apache.devicemap.loader.impl.NoopLoader;
+import org.apache.devicemap.loader.resource.URLResource;
+import org.apache.devicemap.loader.impl.UninitializedLoader;
+
+public class LoaderFactory {
+
+ public static Loader getLoader(LoaderOption option, String path) {
+ switch (option) {
+ case JAR: {
+ return new DDRLoader(new JarResource(path));
+ }
+ case FOLDER: {
+ return new DDRLoader(new FileResource(path));
+ }
+ case URL: {
+ return new DDRLoader(new URLResource(path));
+ }
+ case NOOP: {
+ return new NoopLoader();
+ }
+ }
+ return new UninitializedLoader();
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderOption.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderOption.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderOption.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/LoaderOption.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,23 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader;
+
+public enum LoaderOption {
+ JAR, FOLDER, URL, NOOP, UNINITIALIZED;
+};
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Resource.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Resource.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Resource.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/Resource.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,27 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public interface Resource {
+
+ public InputStream getResource(String file) throws IOException;
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/DDRLoader.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/DDRLoader.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/DDRLoader.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/DDRLoader.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,255 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader.impl;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.devicemap.data.DeviceType;
+import org.apache.devicemap.data.Pattern;
+import org.apache.devicemap.loader.Loader;
+import org.apache.devicemap.loader.Resource;
+import org.apache.devicemap.loader.parser.XMLParser;
+
+public class DDRLoader implements Loader {
+
+ private final static Logger LOG = Logger.getLogger(DDRLoader.class.getName());
+
+ private static final String DEVICE_DATA = "DeviceDataSource.xml";
+ private static final String DEVICE_DATA_PATCH = "DeviceDataSourcePatch.xml";
+ private static final String BUILDER_DATA = "BuilderDataSource.xml";
+ private static final String BUILDER_DATA_PATCH = "BuilderDataSourcePatch.xml";
+
+ private final Map<String, DeviceType> devices;
+
+ private final Resource resourceLoader;
+
+ public DDRLoader(Resource resourceLoader) {
+ devices = new HashMap<String, DeviceType>(5000);
+ this.resourceLoader = resourceLoader;
+ }
+
+ @Override
+ public Map<String, DeviceType> getData() throws IOException {
+ long start = System.currentTimeMillis();
+
+ BufferedReader ddin = new BufferedReader(new InputStreamReader(resourceLoader.getResource(DEVICE_DATA), "UTF-8"));
+ loadDeviceData(ddin);
+ ddin.close();
+
+ long diff = System.currentTimeMillis() - start;
+ LOG.log(Level.FINE, "Loaded " + DEVICE_DATA + " in {0}ms", diff);
+
+ try {
+ start = System.currentTimeMillis();
+
+ BufferedReader ddpin = new BufferedReader(new InputStreamReader(resourceLoader.getResource(DEVICE_DATA_PATCH), "UTF-8"));
+ loadDeviceData(ddpin);
+ ddpin.close();
+
+ diff = System.currentTimeMillis() - start;
+ LOG.log(Level.FINE, "Loaded " + DEVICE_DATA_PATCH + " in {0}ms", diff);
+ } catch (FileNotFoundException ex) {
+ LOG.log(Level.WARNING, "File not found " + DEVICE_DATA_PATCH + ": {0}", ex.toString());
+ }
+
+ setParentAttributes();
+
+ start = System.currentTimeMillis();
+
+ BufferedReader bin = new BufferedReader(new InputStreamReader(resourceLoader.getResource(BUILDER_DATA), "UTF-8"));
+ loadDevicePatterns(bin);
+ bin.close();
+
+ diff = System.currentTimeMillis() - start;
+ LOG.log(Level.FINE, "Loaded " + BUILDER_DATA + " in {0}ms", diff);
+
+ try {
+ start = System.currentTimeMillis();
+
+ BufferedReader bpin = new BufferedReader(new InputStreamReader(resourceLoader.getResource(BUILDER_DATA_PATCH), "UTF-8"));
+ loadDevicePatterns(bpin);
+ bpin.close();
+
+ diff = System.currentTimeMillis() - start;
+ LOG.log(Level.FINE, "Loaded " + BUILDER_DATA_PATCH + " in {0}ms", diff);
+ } catch (FileNotFoundException ex) {
+ LOG.log(Level.WARNING, "File not found " + BUILDER_DATA_PATCH + ": {0}", ex.toString());
+ }
+
+ return getDevices();
+ }
+
+ /*
+ * loads device data from an InputStreamReader
+ */
+ private void loadDeviceData(Reader in) throws IOException {
+ XMLParser parser = new XMLParser(in);
+ String tag;
+ DeviceType device = new DeviceType();
+ Map<String, String> attributes = new HashMap<String, String>();
+
+ while (!(tag = parser.getNextTag()).isEmpty()) {
+ //new device found
+ if (tag.startsWith("<device ")) {
+ device.setId(XMLParser.getAttribute(tag, "id"));
+ device.setParentId(XMLParser.getAttribute(tag, "parentId"));
+ } else if (tag.equals("</device>")) {
+
+ //add the device
+ if (device.getId() != null && !device.getId().isEmpty()) {
+ attributes.put("id", device.getId());
+ device.setAttributes(attributes);
+ devices.put(device.getId(), device);
+ }
+
+ //reset the device
+ device = new DeviceType();
+ attributes = new HashMap<String, String>();
+ } else if (tag.startsWith("<property ")) {
+ //add the property to the device
+ String key = XMLParser.getAttribute(tag, "name");
+ String value = XMLParser.getAttribute(tag, "value");
+
+ attributes.put(key, value);
+ }
+ }
+ }
+
+ /*
+ * loads patterns from an InputStreamReader
+ */
+ private void loadDevicePatterns(Reader in) throws IOException {
+ XMLParser parser = new XMLParser(in);
+ String tag;
+ String builder = "";
+ String type = "";
+ DeviceType device = null;
+ String id = "";
+ List<String> patterns = new ArrayList<String>();
+
+ while (!(tag = parser.getNextTag()).isEmpty()) {
+ //new builder found
+ if (tag.startsWith("<builder ")) {
+ builder = XMLParser.getAttribute(tag, "class");
+
+ if (builder.lastIndexOf(".") >= 0) {
+ builder = builder.substring(builder.lastIndexOf(".") + 1);
+ }
+
+ type = "weak";
+ if (builder.equals("SimpleDeviceBuilder")) {
+ type = "simple";
+ }
+ } else if (tag.startsWith("<device ")) {
+ //new device found
+ id = XMLParser.getAttribute(tag, "id");
+ device = devices.get(id);
+ } else if (tag.equals("</device>")) {
+ //add the device
+ if (device != null) {
+ //TwoStep is an AND pattern, also index the unigram
+ if (builder.equals("TwoStepDeviceBuilder")) {
+ device.getPatternSet().setAndPattern(patterns, type);
+
+ String unigram = "";
+
+ for (String pattern : patterns) {
+ if (pattern.contains(unigram)) {
+ unigram = pattern;
+ } else {
+ unigram += pattern;
+ }
+ }
+
+ device.getPatternSet().setPattern(unigram, type);
+ } else {
+ device.getPatternSet().setOrPattern(patterns, type);
+ }
+ } else {
+ LOG.log(Level.FINE, "ERROR: device not found: ''{0}''", id);
+ }
+
+ //reset the device
+ device = null;
+ id = "";
+ patterns = new ArrayList<String>();
+ } else if (tag.equals("<value>")) {
+ //add the pattern to the device
+ String pattern = Pattern.normalize(parser.getTagValue());
+
+ if (pattern.isEmpty()) {
+ continue;
+ }
+
+ patterns.add(pattern);
+ }
+ }
+ }
+
+ /**
+ * Sets attributes from parents
+ */
+ private void setParentAttributes() {
+ for (DeviceType device : devices.values()) {
+ mergeParent(device);
+ device.lockAttributes();
+ }
+ }
+
+ private void mergeParent(DeviceType device) {
+ String parentId = device.getParentId();
+
+ if (parentId == null) {
+ return;
+ }
+
+ DeviceType parent = devices.get(parentId);
+
+ if (parent == null) {
+ return;
+ }
+
+ mergeParent(parent);
+
+ for (String key : parent.getAttributes().keySet()) {
+ String value = parent.getAttributes().get(key);
+
+ if (!device.getAttributes().containsKey(key)) {
+ device.getAttributes().put(key, value);
+ }
+ }
+ }
+
+ /**
+ * @return the devices
+ */
+ private Map<String, DeviceType> getDevices() {
+ return devices;
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/NoopLoader.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/NoopLoader.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/NoopLoader.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/NoopLoader.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,34 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader.impl;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.devicemap.data.DeviceType;
+import org.apache.devicemap.loader.Loader;
+
+public class NoopLoader implements Loader {
+
+ @Override
+ public Map<String, DeviceType> getData() throws IOException {
+ return Collections.emptyMap();
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/UninitializedLoader.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/UninitializedLoader.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/UninitializedLoader.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/impl/UninitializedLoader.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,33 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader.impl;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.devicemap.data.DeviceType;
+import org.apache.devicemap.loader.Loader;
+
+public class UninitializedLoader implements Loader {
+
+ @Override
+ public Map<String, DeviceType> getData() throws IOException {
+ return null;
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/JsonParser.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/JsonParser.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/JsonParser.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/JsonParser.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,81 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader.parser;
+
+import java.util.List;
+import java.util.Map;
+
+public class JsonParser {
+
+ public static String outputString(String s) {
+ if (s == null) {
+ return "null";
+ }
+ return "\"" + s.replace("\"", "\\\"").replace("\n", " ") + "\"";
+ }
+
+ public static String outputKeyValue(String key, String value) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(outputString(key));
+ sb.append(':');
+ sb.append(outputString(value));
+ return sb.toString();
+ }
+
+ public static String outputKeyRValue(String key, Object value) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(outputString(key));
+ sb.append(':');
+ sb.append(value);
+ return sb.toString();
+ }
+
+ public static String outputMap(Map<String, String> map) {
+ StringBuilder sb = new StringBuilder();
+ for (String key : map.keySet()) {
+ String value = map.get(key);
+ if (sb.length() == 0) {
+ sb.append('{');
+ } else {
+ sb.append(',');
+ }
+ sb.append(outputKeyValue(key, value));
+ }
+ sb.append('}');
+ return sb.toString();
+ }
+
+ public static String outputList(List<String> list, boolean format) {
+ StringBuilder sb = new StringBuilder();
+ for (String value : list) {
+ if (sb.length() == 0) {
+ sb.append('[');
+ } else {
+ sb.append(',');
+ }
+ if (format) {
+ sb.append(outputString(value));
+ } else {
+ sb.append(value);
+ }
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/XMLParser.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/XMLParser.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/XMLParser.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/parser/XMLParser.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,129 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader.parser;
+
+import java.io.IOException;
+import java.io.Reader;
+
+public class XMLParser {
+
+ private final Reader in;
+
+ private char pre;
+
+ public XMLParser(Reader in) {
+ this.in = in;
+ pre = 0;
+ }
+
+ public String getNextTag() throws IOException {
+ StringBuilder ret = new StringBuilder();
+
+ int i;
+ boolean start = false;
+
+ if (pre == '<') {
+ ret.append(pre);
+ pre = 0;
+ start = true;
+ }
+
+ while ((i = in.read()) != -1) {
+ char c = (char) i;
+ if (c == '<') {
+ start = true;
+ ret.append(c);
+ } else if (start) {
+ ret.append(c);
+ }
+
+ if(c == '>') {
+ if(ret.lastIndexOf("<!--") == 0 && (ret.lastIndexOf("-->") + 3) != ret.length()) {
+ continue;
+ }
+ break;
+ }
+ }
+
+ if(ret.lastIndexOf("<!--") == 0) {
+ if((ret.lastIndexOf("-->") + 3) == ret.length()) {
+ return getNextTag();
+ } else {
+ return "";
+ }
+ }
+
+ return ret.toString();
+ }
+
+ public String getTagValue() throws IOException {
+ StringBuilder ret = new StringBuilder();
+
+ int i;
+
+ while ((i = in.read()) != -1) {
+ char c = (char) i;
+ if (c == '<') {
+ pre = '<';
+ break;
+ } else {
+ ret.append(c);
+ }
+ }
+
+ return parseEntities(ret.toString().trim());
+ }
+
+ public static String getAttribute(String tag, String name) {
+ int retpos = tag.toLowerCase().indexOf(name.toLowerCase() + "=");
+
+ if (retpos == -1) {
+ return "";
+ }
+
+ String ret = tag.substring(retpos + name.length() + 1);
+
+ if (ret.startsWith("\"")) {
+ ret = ret.substring(1);
+ int endpos = ret.indexOf("\"");
+
+ if (endpos == -1) {
+ return "";
+ }
+
+ ret = ret.substring(0, endpos);
+ } else {
+ int endpos = ret.indexOf(" ");
+
+ if (endpos == -1) {
+ return "";
+ }
+
+ ret = ret.substring(0, endpos);
+ }
+
+ return parseEntities(ret);
+ }
+
+ private static String parseEntities(String s) {
+ return s.replace(""", "\"").replace("&", "&")
+ .replace("'", "'").replace("<", "<")
+ .replace(">", ">");
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/FileResource.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/FileResource.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/FileResource.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/FileResource.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,50 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader.resource;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.devicemap.loader.Resource;
+
+public class FileResource implements Resource {
+
+ private static final String DEFAULT_PATH = "";
+
+ private final String path;
+
+ public FileResource(String path) {
+ if (path == null) {
+ this.path = DEFAULT_PATH;
+ } else if (path.isEmpty()) {
+ this.path = "";
+ } else {
+ this.path = path + File.separatorChar;
+ }
+ }
+
+ @Override
+ public InputStream getResource(String file) throws IOException {
+ String rpath = path + file;
+ return new FileInputStream(rpath);
+ }
+
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/JarResource.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/JarResource.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/JarResource.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/JarResource.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,53 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader.resource;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.devicemap.loader.Resource;
+
+public class JarResource implements Resource {
+
+ private static final String DEFAULT_PATH = "/devicedata/";
+
+ private final String path;
+
+ public JarResource(String path) {
+ if (path == null) {
+ this.path = DEFAULT_PATH;
+ } else {
+ this.path = path;
+ }
+ }
+
+ @Override
+ public InputStream getResource(String file) throws IOException {
+ String rpath = path + file;
+
+ InputStream in = JarResource.class.getResourceAsStream(rpath);
+
+ if (in == null) {
+ throw new FileNotFoundException("Jar resource not found: " + path);
+ }
+
+ return in;
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/URLResource.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/URLResource.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/URLResource.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/main/java/org/apache/devicemap/loader/resource/URLResource.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,48 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap.loader.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.devicemap.loader.Resource;
+
+public class URLResource implements Resource {
+
+ //TODO: put on CDN of some kind
+ private static final String DEFAULT_PATH = "http://devicemap-vm.apache.org/data/latest";
+
+ private final String path;
+
+ public URLResource(String path) {
+ if (path == null) {
+ this.path = DEFAULT_PATH;
+ } else {
+ this.path = path;
+ }
+ }
+
+ @Override
+ public InputStream getResource(String file) throws IOException {
+ String rpath = path + "/" + file;
+ return new URL(rpath).openStream();
+ }
+
+}
Added: devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientFileTestOptional.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientFileTestOptional.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientFileTestOptional.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientFileTestOptional.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,69 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap;
+
+import java.io.FileNotFoundException;
+import org.apache.devicemap.data.Device;
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.devicemap.loader.LoaderOption;
+
+public class DeviceMapClientFileTestOptional {
+
+ @Test
+ public void deviceMapClientFolderTest() throws Exception {
+ DeviceMapClient client = new DeviceMapClient();
+
+ client.initDeviceData(LoaderOption.FOLDER, "../../../data/device-data/src/main/resources/devicedata");
+
+ String test = "Mozilla/5.0 (Linux; U; Android 2.2; en; HTC Aria A6380 Build/ERE27) AppleWebKit/540.13+ (KHTML, like Gecko) Version/3.1 Mobile Safari/524.15.0";
+
+ Device device = client.classifyDevice(test);
+
+ Assert.assertEquals("test ua not htc aria", "HTC Aria", device.getId());
+ }
+
+ @Test
+ public void deviceMapClientFolderFailureTest() throws Exception {
+ DeviceMapClient client = new DeviceMapClient();
+
+ try {
+ client.initDeviceData(LoaderOption.FOLDER,"fail");
+ Assert.fail("FileNotFoundException expected with invalid folder path");
+ } catch(FileNotFoundException fnf) {
+ //pass
+ } catch(Exception ex) {
+ Assert.fail("FileNotFoundException expected with invalid folder path, got: "+ex.toString());
+ }
+ }
+
+ @Test
+ public void deviceMapFactoryFileTest() throws Exception {
+ String test = "Mozilla/5.0 (Linux; U; Android 2.2; en; HTC Aria A6380 Build/ERE27) AppleWebKit/540.13+ (KHTML, like Gecko) Version/3.1 Mobile Safari/524.15.0";
+
+ Device device = DeviceMapFactory.getClient(LoaderOption.FOLDER, "../../../data/device-data/src/main/resources/devicedata").classifyDevice(test);
+
+ Assert.assertEquals("test ua not htc aria", "HTC Aria", device.getId());
+
+ device = DeviceMapFactory.getClient(LoaderOption.FOLDER, "../../../data/device-data/src/main/resources/devicedata").classifyDevice(test);
+
+ Assert.assertEquals("2nd test ua not htc aria", "HTC Aria", device.getId());
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientJarTest.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientJarTest.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientJarTest.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientJarTest.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,69 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap;
+
+import java.io.FileNotFoundException;
+import org.apache.devicemap.data.Device;
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.devicemap.loader.LoaderOption;
+
+public class DeviceMapClientJarTest {
+
+ @Test
+ public void deviceMapClientJarTest() throws Exception {
+ DeviceMapClient client = new DeviceMapClient();
+
+ client.initDeviceData(LoaderOption.JAR);
+
+ String test = "Mozilla/5.0 (Linux; U; Android 2.2; en; HTC Aria A6380 Build/ERE27) AppleWebKit/540.13+ (KHTML, like Gecko) Version/3.1 Mobile Safari/524.15.0";
+
+ Device device = client.classifyDevice(test);
+
+ Assert.assertEquals("test ua not htc aria", "HTC Aria", device.getId());
+ }
+
+ @Test
+ public void deviceMapClientJarFailureTest() throws Exception {
+ DeviceMapClient client = new DeviceMapClient();
+
+ try {
+ client.initDeviceData(LoaderOption.JAR,"fail");
+ Assert.fail("FileNotFoundException expected with invalid JAR path");
+ } catch(FileNotFoundException fnf) {
+ //pass
+ } catch(Exception ex) {
+ Assert.fail("FileNotFoundException expected with invalid JAR path, got: "+ex.toString());
+ }
+ }
+
+ @Test
+ public void deviceMapFactoryJarTest() throws Exception {
+ String test = "Mozilla/5.0 (Linux; U; Android 2.2; en; HTC Aria A6380 Build/ERE27) AppleWebKit/540.13+ (KHTML, like Gecko) Version/3.1 Mobile Safari/524.15.0";
+
+ Device device = DeviceMapFactory.getClient(LoaderOption.JAR).classifyDevice(test);
+
+ Assert.assertEquals("test ua not htc aria", "HTC Aria", device.getId());
+
+ device = DeviceMapFactory.getClient(LoaderOption.JAR).classifyDevice(test);
+
+ Assert.assertEquals("2nd test ua not htc aria", "HTC Aria", device.getId());
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientTest.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientTest.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientTest.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientTest.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,76 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import org.apache.devicemap.data.Device;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import org.apache.devicemap.loader.LoaderOption;
+
+@RunWith(value = Parameterized.class)
+public class DeviceMapClientTest {
+
+ private static DeviceMapClient client;
+
+ @BeforeClass
+ public static void setupDeviceMapClient() throws Exception {
+ client = new DeviceMapClient();
+ client.initDeviceData(LoaderOption.JAR);
+ }
+
+ @Parameters
+ public static Collection<Object[]> data() throws Exception {
+ Collection<Object[]> params = new ArrayList<Object[]>();
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(DeviceMapClientTest.class.getResourceAsStream("/uas.data")));
+ String line;
+
+ while ((line = reader.readLine()) != null) {
+ params.add(line.split("\\|\\|"));
+ }
+
+ reader.close();
+
+ return params;
+ }
+
+ private final String testString;
+ private final String resultId;
+
+ public DeviceMapClientTest(String testString, String resultId) {
+ this.testString = testString;
+ this.resultId = resultId;
+ }
+
+ @Test
+ public void testDeviceMapClient() throws Exception {
+ Device device = client.classifyDevice(testString);
+
+ Assert.assertEquals("classification failed for '" + testString + "'", resultId, device.getId());
+ }
+}
Added: devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientUnitTest.java
URL: http://svn.apache.org/viewvc/devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientUnitTest.java?rev=1717136&view=auto
==============================================================================
--- devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientUnitTest.java (added)
+++ devicemap/trunk/clients/1.0/java/client/src/test/java/org/apache/devicemap/DeviceMapClientUnitTest.java Sun Nov 29 23:36:18 2015
@@ -0,0 +1,84 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.devicemap;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.apache.devicemap.data.Device;
+
+public class DeviceMapClientUnitTest {
+ @Test
+ public void deviceMapClientUninitializedTest() throws Exception {
+ DeviceMapClient uninit = new DeviceMapClient();
+
+ try {
+ uninit.classifyDevice("");
+ Assert.fail("Uninitialized device index exception expected");
+ } catch (RuntimeException re) {
+ //pass
+ } catch (Exception ex) {
+ Assert.fail("Uninitialized device index exception expected, got: " + ex.toString());
+ }
+ }
+
+ @Test
+ public void deviceMapClientUnknownTest() throws Exception {
+ Device device = DeviceMapFactory.getClient().classifyDevice("");
+
+ Assert.assertEquals("test ua not unknown", Device.UNKNOWN_ID, device.getId());
+
+ device = DeviceMapFactory.getClient().classifyDevice(null);
+
+ Assert.assertEquals("test ua not unknown", Device.UNKNOWN_ID, device.getId());
+ }
+
+ @Test
+ public void deviceMapClientMutateTest() throws Exception {
+ String test = "Mozilla/5.0 (Linux; U; Android 2.2; en; HTC Aria A6380 Build/ERE27) AppleWebKit/540.13+ (KHTML, like Gecko) Version/3.1 Mobile Safari/524.15.0";
+
+ Device device = DeviceMapFactory.getClient().classifyDevice(test);
+
+ Assert.assertEquals("test ua not htc aria", "HTC Aria", device.getId());
+
+ try {
+ device.getAttributes().put("mutate", "true");
+ Assert.fail("UnsupportedOperationException expected when changing result map");
+ } catch (UnsupportedOperationException uoe) {
+ //pass
+ } catch (Exception ex) {
+ Assert.fail("UnsupportedOperationException expected when changing result map, got: " + ex.toString());
+ }
+ }
+
+ @Test
+ public void deviceMapClientMutateUnknownTest() throws Exception {
+ Device device = DeviceMapFactory.getClient().classifyDevice("unknown");
+
+ Assert.assertEquals("test ua not unknown", Device.UNKNOWN_ID, device.getId());
+
+ try {
+ device.getAttributes().put("mutate", "true");
+ Assert.fail("UnsupportedOperationException expected when changing result map");
+ } catch (UnsupportedOperationException uoe) {
+ //pass
+ } catch (Exception ex) {
+ Assert.fail("UnsupportedOperationException expected when changing result map, got: " + ex.toString());
+ }
+ }
+}