You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devicemap.apache.org by re...@apache.org on 2014/07/04 22:01:36 UTC
svn commit: r1607924 - in
/incubator/devicemap/trunk/devicemap/java/classifier/src: main/ main/java/
main/java/org/ main/java/org/apache/ main/java/org/apache/devicemap/
main/java/org/apache/devicemap/cmd/ main/java/org/apache/devicemap/data/
main/java...
Author: rezan
Date: Fri Jul 4 20:01:35 2014
New Revision: 1607924
URL: http://svn.apache.org/r1607924
Log:
refactored paths
Added:
incubator/devicemap/trunk/devicemap/java/classifier/src/main/
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Constants.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/DeviceMapClient.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Util.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/cmd/
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/cmd/Main.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Device.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Pattern.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/FileLoader.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/JarLoader.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/Loader.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/LoaderFactory.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/NOOPLoader.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/ResourceLoader.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/URLLoader.java
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/parser/
incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/parser/XMLParser.java
incubator/devicemap/trunk/devicemap/java/classifier/src/test/
incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/
incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/org/
incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/org/apache/
incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/org/apache/devicemap/
incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/org/apache/devicemap/client/
incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/org/apache/devicemap/client/DeviceMapClientTest.java
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Constants.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Constants.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Constants.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Constants.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,30 @@
+/*
+ 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;
+
+/**
+ *
+ * @author Reza Naghibi
+ */
+public class Constants {
+
+ public static final String version="0.9";
+
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/DeviceMapClient.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/DeviceMapClient.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/DeviceMapClient.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/DeviceMapClient.java Fri Jul 4 20:01:35 2014
@@ -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;
+
+import org.apache.devicemap.data.Device;
+import org.apache.devicemap.loaders.LoaderFactory;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author Reza Naghibi
+ * @author Werner Keil
+ */
+public class DeviceMapClient {
+
+ //indexes
+ Map<String,Device> devices;
+ final Map<String,List<Device>> patterns;
+
+ public DeviceMapClient() {
+ devices=new HashMap<String,Device>();
+ patterns=new HashMap<String,List<Device>>();
+ }
+
+ public void loadFromResource(String option, String res) throws IOException{
+ devices = LoaderFactory.getLoader(option).getData(res);
+ createIndex();
+ }
+
+ //load DDR indexes from a folder
+ public void loadFromFolder(String folder) throws IOException {
+ devices=LoaderFactory.getLoader("-l").getData(folder);
+
+ createIndex();
+ }
+
+ private void createIndex() {
+ for(Device device:devices.values()) {
+ for(List<String> patternset:device.getPatterns().getPatterns()) {
+ for(int i=0;i<patternset.size();i++) {
+ String pattern=patternset.get(i);
+
+ //duplicate
+ if(patterns.get(pattern)!=null) {
+ if(i==(patternset.size()-1) && !patterns.get(pattern).contains(device)) {
+ patterns.get(pattern).add(device);
+ }
+ } else {
+ List<Device> single=new ArrayList<Device>();
+ single.add(device);
+ patterns.put(pattern, single);
+ }
+ }
+ }
+ }
+ }
+
+ public Map<String,String> classify(String text) {
+ Map<String,List<Device>> hits=new HashMap<String,List<Device>>();
+ Device winner=null;
+ String winnerStr="";
+
+ if(text==null) {
+ return null;
+ }
+
+ Util.debugLog("classify: '"+text+"'");
+
+ String[] parts=text.split(" |-|_|/|\\\\|\\[|\\]|\\(|\\)|;");
+
+ //generate ngrams upto size 4
+ for(int i=0;i<parts.length;i++) {
+ if(parts[i].isEmpty()) {
+ continue;
+ }
+ String pattern="";
+ for(int j=0;j<4 && (j+i)<parts.length;j++) {
+ pattern+=Util.normalize(parts[i+j]);
+
+ List<Device> dlist=patterns.get(pattern);
+
+ if(dlist!=null) {
+ hits.put(pattern, dlist);
+
+ for(Device device:dlist) {
+ Util.debugLog("Hit found: "+pattern+" => "+device.getId()+" "+device.getPatterns());
+ }
+ }
+ }
+ }
+
+ //look for the strongest hit
+ for(String hit:hits.keySet()) {
+ for(Device device:hits.get(hit)) {
+ if(!device.getPatterns().isValid(hits.keySet())) {
+ continue;
+ }
+
+ Util.debugLog("Hit candidate: "+hit+" => "+device.getId());
+
+ if(winner!=null) {
+ if("simple".equals(winner.getType()) && !"simple".equals(device.getType())) {
+ winner=device;
+ winnerStr=hit;
+ } else if(hit.length()>winnerStr.length() && !"simple".equals(device.getType())) {
+ winner=device;
+ winnerStr=hit;
+ }
+ } else {
+ winner=device;
+ winnerStr=hit;
+ }
+ }
+ }
+
+ if(winner!=null) {
+ Util.debugLog("Result: "+winner);
+
+ return winner.getAttributes();
+ } else {
+ return null;
+ }
+ }
+
+ public int getDeviceCount() {
+ return devices.size();
+ }
+
+ public int getPatternCount() {
+ return patterns.size();
+ }
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Util.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Util.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Util.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/Util.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,72 @@
+/*
+ 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.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ *
+ * @author Reza Naghibi
+ */
+public class Util {
+
+ /*
+ * 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();
+ }
+
+ public static void debugLog(String msg) {
+ debugLog(msg, null);
+ }
+
+ public static void debugLog(String msg, Exception e) {
+ if(System.getProperty("debug") == null) {
+ return;
+ }
+
+ String date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS").format(new Date());
+
+ System.out.println(date+" [dmapjclient] "+msg);
+
+ if(e!=null) {
+ e.printStackTrace();
+ }
+ }
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/cmd/Main.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/cmd/Main.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/cmd/Main.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/cmd/Main.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,155 @@
+/*
+ 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.Map;
+import org.apache.devicemap.Constants;
+import org.apache.devicemap.DeviceMapClient;
+
+/**
+ *
+ * @author Reza Naghibi
+ */
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+
+ System.out.println("DeviceMap Java Client "+Constants.version);
+
+ System.setProperty("debug","true");
+
+ String resourceFolder=null;
+ String parameter=null;
+ String option=null;
+
+ for(int i=0;i<args.length;i++)
+ {
+ //-l [resource folder]
+ if((args[i].equals("-l") || args[i].equals("-u")) && args.length>(i+1)) {
+ option=args[i];
+ i++;
+ resourceFolder=args[i];
+ } else if(args[i].equals("-j")) {
+ option=args[i];
+ resourceFolder="";
+ } else if(args[i].startsWith("-h") || args[i].startsWith("--h")) {
+ System.out.println("Usage: "+Main.class.getName()+" [OPTIONS] [FILE|STRING]\n");
+ System.out.println(" -l <path> load Device Map resouces from folder");
+ System.out.println(" -j load Device Map resouces from jar file in classpath");
+ System.out.println(" -u <url> load Device Map resouces from URL");
+ System.out.println(" FILE text file of strings");
+ System.out.println(" STRING test string");
+
+ return;
+ }
+ //[test string] | [test file]
+ else
+ parameter=args[i];
+ }
+
+ DeviceMapClient client=new DeviceMapClient();
+ Map<String,String> m;
+
+ if(option!=null && !option.isEmpty()) {
+ long start=System.currentTimeMillis();
+
+ client.loadFromResource(option,resourceFolder);
+
+ long diff=System.currentTimeMillis()-start;
+
+ System.out.println("Loaded "+client.getDeviceCount()+" devices with "+client.getPatternCount()+" patterns in "+diff+"ms");
+ }
+
+ 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();
+
+ m=client.classify(test);
+
+ long diffn=(System.nanoTime()-startn)/1000;
+
+ System.out.println("Test lookup: '"+(m!=null?m.get("id"):"unknown")+"' 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();
+
+ m=client.classify(line);
+
+ diffn=System.nanoTime()-startn;
+
+ total+=diffn;
+ count++;
+
+ System.out.println("Text lookup "+count+": '"+(m!=null?m.get("id"):"unknown")+"' time: "+(diffn/1000)+"usec");
+ }
+
+ in.close();
+
+ if(count==0) {
+ count=1;
+ }
+
+ total/=count;
+
+ System.out.println("TOTAL lookups: "+count+", average time: "+(diffn/1000)+"usec");
+ }
+ else
+ {
+ System.out.println("Text: '"+parameter+"'");
+
+ startn=System.nanoTime();
+
+ m=client.classify(parameter);
+
+ diffn=System.nanoTime()-startn;
+
+ System.out.println("Text lookup: '"+(m!=null?m.get("id"):"unknown")+"' time: "+(diffn/1000)+"usec");
+
+ if(m!=null) {
+ System.out.print("DeviceMap attributes => ");
+
+ for(String key:m.keySet())
+ {
+ String value=m.get(key);
+ System.out.print(key+": '"+value+"' ");
+ }
+
+ System.out.println("");
+ }
+ }
+ }
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Device.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Device.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Device.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Device.java Fri Jul 4 20:01:35 2014
@@ -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.Map;
+
+/**
+ *
+ * @author Reza Naghibi
+ */
+public class Device {
+
+ private String id;
+
+ private String parentId;
+
+ private String type;
+
+ private Pattern pattern;
+
+ private Map<String,String> attributes;
+
+ public Device() {
+ pattern=new Pattern();
+ }
+
+ public String toString() {
+ return "id='"+id+"'," +
+ "parentId='"+parentId+"',"+
+ "type='"+type+"',"+
+ "pattern="+pattern+","+
+ "attribytes="+attributes+".";
+ }
+
+ 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 String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public Pattern getPatterns() {
+ return pattern;
+ }
+
+ public Map<String,String> getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map<String,String> attributes) {
+ this.attributes = attributes;
+ }
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Pattern.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Pattern.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Pattern.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/data/Pattern.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,92 @@
+/*
+ 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;
+
+/**
+ *
+ * @author Reza Naghibi
+ */
+public class Pattern {
+
+ //all patterns strings in the inner list need to match (AND)
+ //only 1 outer list of patterns need to match (OR)
+ private List<List<String>> patterns;
+
+ public Pattern() {
+ patterns=new ArrayList<List<String>>();
+ }
+
+ public String toString() {
+ return patterns.toString();
+ }
+
+ /*
+ * add the patterns together as an inner list (AND)
+ */
+ public void setAndPattern(List<String> patterns) {
+ this.patterns.add(patterns);
+ }
+
+ /*
+ * add each pattern on its own list (OR)
+ */
+ public void setOrPattern(List<String> patterns) {
+ for(String pattern:patterns) {
+ setPattern(pattern);
+ }
+ }
+
+ /*
+ * add a single pattern (OR)
+ */
+ public void setPattern(String pattern) {
+ List<String> single=new ArrayList<String>();
+ single.add(pattern);
+ patterns.add(single);
+ }
+
+ public List<List<String>> getPatterns() {
+ return patterns;
+ }
+
+ /*
+ * does the set of patterns match this object?
+ */
+ public boolean isValid(Set<String> patterns) {
+ boolean found=false;
+ patterns:
+ for(List<String> patternset:getPatterns()) {
+ for(String pattern:patternset) {
+ if(!patterns.contains(pattern)) {
+ continue patterns;
+ }
+ }
+ found=true;
+ break;
+ }
+
+ return found;
+ }
+
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/FileLoader.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/FileLoader.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/FileLoader.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/FileLoader.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,109 @@
+/*
+ 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.loaders;
+
+import org.apache.devicemap.loaders.Loader;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Map;
+import org.apache.devicemap.data.Device;
+import org.apache.devicemap.Util;
+
+/**
+ *
+ * @author Reza Naghibi
+ */
+public class FileLoader implements ResourceLoader{
+
+ private final Loader loader;
+
+
+ public FileLoader(Loader loader){
+ this.loader = loader;
+ }
+
+ /**
+ *
+ * @param folder which contains device map data
+ * @return map of devices
+ * @throws IOException
+ */
+ public Map<String,Device> getData(String folder) throws IOException {
+
+
+ String ddpath=folder+File.separatorChar+"DeviceDataSource.xml";
+ String ddppath=folder+File.separatorChar+"DeviceDataSourcePatch.xml";
+ String bpath=folder+File.separatorChar+"BuilderDataSource.xml";
+ String bppath=folder+File.separatorChar+"BuilderDataSourcePatch.xml";
+
+ long start=System.currentTimeMillis();
+
+ BufferedReader ddin=new BufferedReader(new InputStreamReader(new FileInputStream(ddpath), "UTF-8"));
+ loader.loadDeviceData(ddin);
+ ddin.close();
+
+ long diff=System.currentTimeMillis()-start;
+ Util.debugLog("Loaded "+ddpath+" in "+diff+"ms");
+
+ try {
+ start=System.currentTimeMillis();
+
+ BufferedReader ddpin=new BufferedReader(new InputStreamReader(new FileInputStream(ddppath), "UTF-8"));
+ loader.loadDeviceData(ddpin);
+ ddpin.close();
+
+ diff=System.currentTimeMillis()-start;
+ Util.debugLog("Loaded "+ddppath+" in "+diff+"ms");
+ } catch(FileNotFoundException ex) {
+ Util.debugLog("WARNING: file not found "+ddppath+": "+ex.toString());
+ }
+
+ loader.setParentAttributes();
+
+ start=System.currentTimeMillis();
+
+ BufferedReader bin=new BufferedReader(new InputStreamReader(new FileInputStream(bpath), "UTF-8"));
+ loader.loadDevicePatterns(bin);
+ bin.close();
+
+ diff=System.currentTimeMillis()-start;
+ Util.debugLog("Loaded "+bpath+" in "+diff+"ms");
+
+ try {
+ start=System.currentTimeMillis();
+
+ BufferedReader bpin=new BufferedReader(new InputStreamReader(new FileInputStream(bppath), "UTF-8"));
+ loader.loadDevicePatterns(bpin);
+ bpin.close();
+
+ diff=System.currentTimeMillis()-start;
+ Util.debugLog("Loaded "+bppath+" in "+diff+"ms");
+ } catch(FileNotFoundException ex) {
+ Util.debugLog("WARNING: file not found "+bppath+": "+ex.toString());
+ }
+
+ return loader.getDevices();
+ }
+
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/JarLoader.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/JarLoader.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/JarLoader.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/JarLoader.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,100 @@
+/*
+ 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.loaders;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Map;
+
+import org.apache.devicemap.Util;
+import org.apache.devicemap.data.Device;
+
+/**
+ *
+ * @author kalyanar
+ * @author Reza Naghibi
+ */
+public class JarLoader implements ResourceLoader {
+
+ private final Loader loader;
+
+ public JarLoader(Loader loader) {
+ this.loader = loader;
+ }
+
+ @Override
+ public Map<String, Device> getData(String path) throws IOException {
+ if(path==null) {
+ path="";
+ }
+
+ String ddpath = path+"/devicedata/DeviceDataSource.xml";
+ String ddppath = path+"/devicedata/DeviceDataSourcePatch.xml";
+ String bpath = path+"/devicedata/BuilderDataSource.xml";
+ String bppath = path+"/devicedata/BuilderDataSourcePatch.xml";
+
+ long start = System.currentTimeMillis();
+ BufferedReader ddin = new BufferedReader(new InputStreamReader(JarLoader.class.getResourceAsStream(ddpath), "UTF-8"));
+ loader.loadDeviceData(ddin);
+ ddin.close();
+
+ long diff = System.currentTimeMillis() - start;
+ Util.debugLog("Loaded " + ddpath + " in " + diff + "ms");
+ try {
+ start = System.currentTimeMillis();
+
+ BufferedReader ddpin = new BufferedReader(new InputStreamReader(JarLoader.class.getResourceAsStream(ddppath), "UTF-8"));
+ loader.loadDeviceData(ddpin);
+ ddpin.close();
+
+ diff = System.currentTimeMillis() - start;
+ Util.debugLog("Loaded " + ddppath + " in " + diff + "ms");
+ } catch (FileNotFoundException ex) {
+ Util.debugLog("WARNING: file not found " + ddppath + ": " + ex.toString());
+ }
+
+ loader.setParentAttributes();
+
+ start = System.currentTimeMillis();
+
+ BufferedReader bin = new BufferedReader(new InputStreamReader(JarLoader.class.getResourceAsStream(bpath), "UTF-8"));
+ loader.loadDevicePatterns(bin);
+ bin.close();
+
+ diff = System.currentTimeMillis() - start;
+ Util.debugLog("Loaded " + bpath + " in " + diff + "ms");
+
+ try {
+ start = System.currentTimeMillis();
+
+ BufferedReader bpin = new BufferedReader(new InputStreamReader(JarLoader.class.getResourceAsStream(bppath), "UTF-8"));
+ loader.loadDevicePatterns(bpin);
+ bpin.close();
+
+ diff = System.currentTimeMillis() - start;
+ Util.debugLog("Loaded " + bppath + " in " + diff + "ms");
+ } catch (FileNotFoundException ex) {
+ Util.debugLog("WARNING: file not found " + bppath + ": " + ex.toString());
+ }
+
+ return loader.getDevices();
+ }
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/Loader.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/Loader.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/Loader.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/Loader.java Fri Jul 4 20:01:35 2014
@@ -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.loaders;
+
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.devicemap.data.Device;
+import org.apache.devicemap.Util;
+import org.apache.devicemap.parser.XMLParser;
+
+/**
+ *
+ * @author Reza Naghibi
+ */
+public class Loader {
+
+ private Map<String,Device> devices;
+
+ public Loader() {
+ devices=new HashMap<String,Device>();
+ }
+
+ /*
+ * loads device data from an InputStreamReader
+ */
+ public void loadDeviceData(Reader in) {
+ XMLParser parser=new XMLParser(in);
+ String tag;
+
+ try {
+ Device device=new Device();
+ 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 Device();
+ 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);
+ }
+ }
+ } catch(Exception ex) {
+ Util.debugLog("ERROR: "+ex.toString(),ex);
+ }
+ }
+
+ /*
+ * loads patterns from an InputStreamReader
+ */
+ public void loadDevicePatterns(Reader in) {
+ XMLParser parser=new XMLParser(in);
+ String tag;
+
+ try {
+ String builder="";
+ Device 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);
+ }
+ } else if(tag.startsWith("<device ")) {
+ //new device found
+ device=devices.get(XMLParser.getAttribute(tag,"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.getPatterns().setAndPattern(patterns);
+
+ String unigram="";
+
+ for(String pattern:patterns) {
+ if(pattern.contains(unigram)) {
+ unigram=pattern;
+ } else {
+ unigram+=pattern;
+ }
+ }
+
+ device.getPatterns().setPattern(unigram);
+ } else {
+ device.getPatterns().setOrPattern(patterns);
+ }
+
+ if(builder.equals("SimpleDeviceBuilder")) {
+ device.setType("simple");
+ } else {
+ device.setType("weak");
+ }
+ } else {
+ Util.debugLog("ERROR: device not found: '"+id+"'");
+ }
+
+ //reset the device
+ device=null;
+ id="";
+ patterns=new ArrayList<String>();
+ } else if(tag.equals("<value>")) {
+ //add the pattern to the device
+ String pattern=Util.normalize(parser.getTagValue());
+
+ if(pattern.isEmpty()) {
+ continue;
+ }
+
+ patterns.add(pattern);
+ }
+ }
+ } catch(Exception ex) {
+ Util.debugLog("ERROR: "+ex.toString(),ex);
+ }
+ }
+
+ /**
+ * Sets attributes from parents
+ */
+ public void setParentAttributes() {
+ for(Device device:devices.values()) {
+ mergeParent(device);
+ }
+ }
+
+ private void mergeParent(Device device) {
+ String parentId=device.getParentId();
+
+ if(parentId==null) {
+ return;
+ }
+
+ Device 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
+ */
+ public Map<String,Device> getDevices() {
+ return devices;
+ }
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/LoaderFactory.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/LoaderFactory.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/LoaderFactory.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/LoaderFactory.java Fri Jul 4 20:01:35 2014
@@ -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.loaders;
+
+public class LoaderFactory {
+ private static enum LoaderOption{
+ JAR("-j"),FOLDER("-l"),URL("-u"),NOOP("-n");
+ private String loaderType;
+ LoaderOption(String loaderType){
+ this.loaderType = loaderType;
+ }
+ String type(){
+ return this.loaderType;
+ }
+ };
+
+
+public static final ResourceLoader getLoader(String option){
+ LoaderOption lOption = getLoaderOption(option);
+ switch(lOption){
+ case JAR:{
+ return new JarLoader(new Loader());
+ }
+ case FOLDER:{
+ return new FileLoader(new Loader());
+ }
+ case URL:{
+ return new URLLoader(new Loader());
+ }
+ case NOOP:{
+ return new NOOPLoader();
+ }
+ }
+ return new NOOPLoader();
+}
+private static LoaderOption getLoaderOption(String option){
+ for(LoaderOption lOption:LoaderOption.values()){
+ if(lOption.type().equals(option)){
+ return lOption;
+ }
+ }
+ return LoaderOption.NOOP;
+}
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/NOOPLoader.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/NOOPLoader.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/NOOPLoader.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/NOOPLoader.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,17 @@
+package org.apache.devicemap.loaders;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.devicemap.data.Device;
+
+public class NOOPLoader implements ResourceLoader {
+
+ @Override
+ public Map<String, Device> getData(String path) throws IOException {
+
+ return Collections.emptyMap();
+ }
+
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/ResourceLoader.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/ResourceLoader.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/ResourceLoader.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/ResourceLoader.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,10 @@
+package org.apache.devicemap.loaders;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.devicemap.data.Device;
+
+public interface ResourceLoader {
+ public Map<String,Device> getData(String path) throws IOException ;
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/URLLoader.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/URLLoader.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/URLLoader.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/loaders/URLLoader.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,84 @@
+package org.apache.devicemap.loaders;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Map;
+
+import org.apache.devicemap.Util;
+import org.apache.devicemap.data.Device;
+/**
+ *
+ * @author kalyanar
+ * @author Reza Naghibi
+ *
+ */
+public class URLLoader implements ResourceLoader {
+ private final Loader loader;
+
+
+ public URLLoader(Loader loader){
+ this.loader = loader;
+ }
+
+ @Override
+ public Map<String, Device> getData(String path) throws IOException {
+ String ddpath=path+"/DeviceDataSource.xml";
+ String ddppath=path+"/DeviceDataSourcePatch.xml";
+ String bpath=path+"/BuilderDataSource.xml";
+ String bppath=path+"/BuilderDataSourcePatch.xml";
+ long start=System.currentTimeMillis();
+
+ BufferedReader ddin=new BufferedReader(new InputStreamReader(new URL(ddpath).openStream(), "UTF-8"));
+ loader.loadDeviceData(ddin);
+ ddin.close();
+
+ long diff=System.currentTimeMillis()-start;
+ Util.debugLog("Loaded "+ddpath+" in "+diff+"ms");
+
+ try {
+ start=System.currentTimeMillis();
+
+ BufferedReader ddpin=new BufferedReader(new InputStreamReader(new URL(ddppath).openStream(), "UTF-8"));
+ loader.loadDeviceData(ddpin);
+ ddpin.close();
+
+ diff=System.currentTimeMillis()-start;
+ Util.debugLog("Loaded "+ddppath+" in "+diff+"ms");
+ } catch(FileNotFoundException ex) {
+ Util.debugLog("WARNING: file not found "+ddppath+": "+ex.toString());
+ }
+
+ loader.setParentAttributes();
+
+ start=System.currentTimeMillis();
+
+ BufferedReader bin=new BufferedReader(new InputStreamReader(new URL(bpath).openStream(), "UTF-8"));
+ loader.loadDevicePatterns(bin);
+ bin.close();
+
+ diff=System.currentTimeMillis()-start;
+ Util.debugLog("Loaded "+bpath+" in "+diff+"ms");
+
+ try {
+ start=System.currentTimeMillis();
+
+ BufferedReader bpin=new BufferedReader(new InputStreamReader(new URL(bppath).openStream(), "UTF-8"));
+ loader.loadDevicePatterns(bpin);
+ bpin.close();
+
+ diff=System.currentTimeMillis()-start;
+ Util.debugLog("Loaded "+bppath+" in "+diff+"ms");
+ } catch(FileNotFoundException ex) {
+ Util.debugLog("WARNING: file not found "+bppath+": "+ex.toString());
+ }
+
+ return loader.getDevices();
+
+ }
+
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/parser/XMLParser.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/parser/XMLParser.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/parser/XMLParser.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/main/java/org/apache/devicemap/parser/XMLParser.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,119 @@
+/*
+ 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.parser;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ *
+ * @author Reza Naghibi
+ * @author Werner Keil
+ */
+public class XMLParser {
+
+ private Reader in;
+
+ private char pre;
+
+ @SuppressWarnings("unused")
+ private XMLParser() {}
+
+ 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(c=='>') {
+ ret.append(c);
+ break;
+ } else if(start) {
+ ret.append(c);
+ }
+ }
+
+ 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 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 ret;
+ }
+}
Added: incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/org/apache/devicemap/client/DeviceMapClientTest.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/org/apache/devicemap/client/DeviceMapClientTest.java?rev=1607924&view=auto
==============================================================================
--- incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/org/apache/devicemap/client/DeviceMapClientTest.java (added)
+++ incubator/devicemap/trunk/devicemap/java/classifier/src/test/java/org/apache/devicemap/client/DeviceMapClientTest.java Fri Jul 4 20:01:35 2014
@@ -0,0 +1,43 @@
+/*
+ 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.client;
+
+import org.apache.devicemap.DeviceMapClient;
+import java.util.Map;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class DeviceMapClientTest {
+
+ @Test
+ public void DeviceMapClientTest() throws Exception {
+ System.out.println("Testing device map");
+ DeviceMapClient client=new DeviceMapClient();
+ client.loadFromResource("-j","");
+
+ 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";
+
+ Map<String,String> m=client.classify(test);
+
+ Assert.assertEquals("test ua not htc aria", "HTC Aria", m.get("id"));
+ }
+}