You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devicemap.apache.org by bd...@apache.org on 2012/10/02 15:32:32 UTC

svn commit: r1392911 [2/7] - in /incubator/devicemap/trunk/openddr: ./ java/ java/src/ java/src/org/ java/src/org/openddr/ java/src/org/openddr/simpleapi/ java/src/org/openddr/simpleapi/oddr/ java/src/org/openddr/simpleapi/oddr/builder/ java/src/org/op...

Added: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRService.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRService.java?rev=1392911&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRService.java (added)
+++ incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRService.java Tue Oct  2 13:32:28 2012
@@ -0,0 +1,899 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.openddr.simpleapi.oddr;
+
+import org.openddr.simpleapi.oddr.model.ODDRPropertyValue;
+import org.openddr.simpleapi.oddr.model.ODDRPropertyRef;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.apache.commons.jexl2.Expression;
+import org.apache.commons.jexl2.JexlContext;
+import org.apache.commons.jexl2.JexlEngine;
+import org.apache.commons.jexl2.MapContext;
+import org.openddr.simpleapi.oddr.builder.Builder;
+import org.openddr.simpleapi.oddr.builder.browser.DefaultBrowserBuilder;
+import org.openddr.simpleapi.oddr.builder.device.DeviceBuilder;
+import org.openddr.simpleapi.oddr.builder.os.DefaultOSBuilder;
+import org.openddr.simpleapi.oddr.documenthandler.BrowserDatasourceHandler;
+import org.openddr.simpleapi.oddr.documenthandler.DeviceBuilderHandler;
+import org.openddr.simpleapi.oddr.documenthandler.DeviceDatasourceHandler;
+import org.openddr.simpleapi.oddr.documenthandler.OperatingSystemDatasourceHandler;
+import org.openddr.simpleapi.oddr.identificator.BrowserIdentificator;
+import org.openddr.simpleapi.oddr.identificator.DeviceIdentificator;
+import org.openddr.simpleapi.oddr.identificator.OSIdentificator;
+import org.openddr.simpleapi.oddr.model.BufferedODDRHTTPEvidence;
+import org.openddr.simpleapi.oddr.model.device.Device;
+import org.openddr.simpleapi.oddr.model.ODDRHTTPEvidence;
+import org.openddr.simpleapi.oddr.model.ODDRPropertyName;
+import org.openddr.simpleapi.oddr.model.ODDRPropertyValues;
+import org.openddr.simpleapi.oddr.model.UserAgent;
+import org.openddr.simpleapi.oddr.model.UserAgentFactory;
+import org.openddr.simpleapi.oddr.model.browser.Browser;
+import org.openddr.simpleapi.oddr.model.os.OperatingSystem;
+import org.openddr.simpleapi.oddr.model.vocabulary.Vocabulary;
+import org.openddr.simpleapi.oddr.model.vocabulary.VocabularyProperty;
+import org.openddr.simpleapi.oddr.vocabulary.VocabularyHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.ddr.simple.Evidence;
+import org.w3c.ddr.simple.PropertyName;
+import org.w3c.ddr.simple.PropertyRef;
+import org.w3c.ddr.simple.PropertyValue;
+import org.w3c.ddr.simple.PropertyValues;
+import org.w3c.ddr.simple.Service;
+import org.w3c.ddr.simple.exception.InitializationException;
+import org.w3c.ddr.simple.exception.NameException;
+import org.xml.sax.SAXException;
+
+public class ODDRService implements Service {
+
+    public static final String ASPECT_DEVICE = "device";
+    public static final String ASPECT_WEB_BROWSER = "webBrowser";
+    public static final String ASPECT_OPERATIVE_SYSTEM = "operativeSystem";
+    public static final String ASPECT_GROUP = "group";
+    public static final String ODDR_UA_DEVICE_BUILDER_PATH_PROP = "oddr.ua.device.builder.path";
+    public static final String ODDR_UA_DEVICE_DATASOURCE_PATH_PROP = "oddr.ua.device.datasource.path";
+    public static final String ODDR_UA_DEVICE_BUILDER_PATCH_PATHS_PROP = "oddr.ua.device.builder.patch.paths";
+    public static final String ODDR_UA_DEVICE_DATASOURCE_PATCH_PATHS_PROP = "oddr.ua.device.datasource.patch.paths";
+    public static final String ODDR_UA_BROWSER_DATASOURCE_PATH_PROP = "oddr.ua.browser.datasource.path";
+    public static final String ODDR_UA_OPERATINGSYSTEM_DATASOURCE_PATH_PROP = "oddr.ua.operatingSystem.datasource.path";
+    public static final String ODDR_UA_DEVICE_BUILDER_STREAM_PROP = "oddr.ua.device.builder.stream";
+    public static final String ODDR_UA_DEVICE_DATASOURCE_STREAM_PROP = "oddr.ua.device.datasource.stream";
+    public static final String ODDR_UA_DEVICE_BUILDER_PATCH_STREAMS_PROP = "oddr.ua.device.builder.patch.streams";
+    public static final String ODDR_UA_DEVICE_DATASOURCE_PATCH_STREAMS_PROP = "oddr.ua.device.datasource.patch.streams";
+    public static final String ODDR_UA_BROWSER_DATASOURCE_STREAM_PROP = "oddr.ua.browser.datasource.stream";
+    public static final String ODDR_UA_OPERATINGSYSTEM_DATASOURCE_STREAM_PROP = "oddr.ua.operatingSystem.datasource.stream";
+    public static final String ODDR_THRESHOLD_PROP = "oddr.threshold";
+    public static final String ODDR_VOCABULARY_IRI = "oddr.vocabulary.device";
+    private static final String ODDR_API_VERSION = "1.0.0";
+    private static final String ODDR_DATA_VERSION = "2012";
+    private static final int ODDR_DEFAULT_THRESHOLD = 70;
+    private String defaultVocabularyIRI = null;
+    private DeviceIdentificator deviceIdentificator = null;
+    private BrowserIdentificator browserIdentificator = null;
+    private OSIdentificator osIdentificator = null;
+    private VocabularyHolder vocabularyHolder = null;
+    private int threshold = ODDR_DEFAULT_THRESHOLD;
+    private static final String GROUP_REGEXPR = "\\$([^ ]+)";
+    private Pattern groupRegexprPattern = Pattern.compile(GROUP_REGEXPR);
+    protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+    public void initialize(String defaultVocabularyIRI, Properties prprts) throws NameException, InitializationException {
+        if (defaultVocabularyIRI == null || defaultVocabularyIRI.trim().length() == 0) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new NullPointerException("defaultVocabularyIRI can not be null"));
+        }
+
+        /*Initializing VocabularyHolder*/
+        ODDRVocabularyService oddrVocabularyService = new ODDRVocabularyService();
+        oddrVocabularyService.initialize(prprts);
+
+        vocabularyHolder = oddrVocabularyService.getVocabularyHolder();
+        vocabularyHolder.existVocabulary(defaultVocabularyIRI);
+
+        String oddrUaDeviceBuilderPath = prprts.getProperty(ODDR_UA_DEVICE_BUILDER_PATH_PROP);
+        String oddrUaDeviceDatasourcePath = prprts.getProperty(ODDR_UA_DEVICE_DATASOURCE_PATH_PROP);
+        String oddrUaDeviceBuilderPatchPaths = prprts.getProperty(ODDR_UA_DEVICE_BUILDER_PATCH_PATHS_PROP);
+        String oddrUaDeviceDatasourcePatchPaths = prprts.getProperty(ODDR_UA_DEVICE_DATASOURCE_PATCH_PATHS_PROP);
+        String oddrUaBrowserDatasourcePaths = prprts.getProperty(ODDR_UA_BROWSER_DATASOURCE_PATH_PROP);
+        String oddrUaOperatingSystemDatasourcePaths = prprts.getProperty(ODDR_UA_OPERATINGSYSTEM_DATASOURCE_PATH_PROP);
+
+        InputStream oddrUaDeviceBuilderStream = null;
+        InputStream oddrUaDeviceDatasourceStream = null;
+        InputStream[] oddrUaDeviceBuilderPatchStreams = null;
+        InputStream[] oddrUaDeviceDatasourcePatchStreams = null;
+        InputStream oddrUaBrowserDatasourceStream = null;
+        InputStream oddrUaOperatingSystemDatasourceStream = null;
+
+        try {
+            oddrUaDeviceBuilderStream = (InputStream) prprts.get(ODDR_UA_DEVICE_BUILDER_STREAM_PROP);
+        } catch (Exception ex) {
+            oddrUaDeviceBuilderStream = null;
+        }
+        try {
+            oddrUaDeviceDatasourceStream = (InputStream) prprts.get(ODDR_UA_DEVICE_DATASOURCE_STREAM_PROP);
+        } catch (Exception ex) {
+            oddrUaDeviceDatasourceStream = null;
+        }
+        try {
+            oddrUaDeviceBuilderPatchStreams = (InputStream[]) prprts.get(ODDR_UA_DEVICE_BUILDER_PATCH_STREAMS_PROP);
+        } catch (Exception ex) {
+            oddrUaDeviceBuilderPatchStreams = null;
+        }
+        try {
+            oddrUaDeviceDatasourcePatchStreams = (InputStream[]) prprts.get(ODDR_UA_DEVICE_DATASOURCE_PATCH_STREAMS_PROP);
+        } catch (Exception ex) {
+            oddrUaDeviceDatasourcePatchStreams = null;
+        }
+        try {
+            oddrUaBrowserDatasourceStream = (InputStream) prprts.get(ODDR_UA_BROWSER_DATASOURCE_STREAM_PROP);
+        } catch (Exception ex) {
+            oddrUaBrowserDatasourceStream = null;
+        }
+        try {
+            oddrUaOperatingSystemDatasourceStream = (InputStream) prprts.get(ODDR_UA_OPERATINGSYSTEM_DATASOURCE_STREAM_PROP);
+        } catch (Exception ex) {
+            oddrUaOperatingSystemDatasourceStream = null;
+        }
+
+        String oddrThreshold = prprts.getProperty(ODDR_THRESHOLD_PROP);
+
+        if ((oddrUaDeviceBuilderPath == null || oddrUaDeviceBuilderPath.trim().length() == 0) && oddrUaDeviceBuilderStream == null) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not find property " + ODDR_UA_DEVICE_BUILDER_PATH_PROP));
+        }
+
+        if ((oddrUaDeviceDatasourcePath == null || oddrUaDeviceDatasourcePath.trim().length() == 0) && oddrUaDeviceDatasourceStream == null) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not find property " + ODDR_UA_DEVICE_DATASOURCE_PATH_PROP));
+        }
+
+        String oddrUaDeviceBuilderPatchPathArray[] = null;
+
+        if (oddrUaDeviceBuilderPatchPaths != null && oddrUaDeviceBuilderPatchPaths.trim().length() != 0) {
+            oddrUaDeviceBuilderPatchPathArray = oddrUaDeviceBuilderPatchPaths.split(",");
+
+        } else {
+            oddrUaDeviceBuilderPatchPathArray = new String[0];
+        }
+
+        String ooddrUaDeviceDatasourcePatchPathArray[] = null;
+
+        if (oddrUaDeviceDatasourcePatchPaths != null && oddrUaDeviceDatasourcePatchPaths.trim().length() != 0) {
+            ooddrUaDeviceDatasourcePatchPathArray = oddrUaDeviceDatasourcePatchPaths.split(",");
+
+        } else {
+            ooddrUaDeviceDatasourcePatchPathArray = new String[0];
+        }
+
+//        if (oddrUaDeviceBuilderPatchStreams == null) {
+//            oddrUaDeviceBuilderPatchStreams = new InputStream[0];
+//        }
+//
+//        if (oddrUaDeviceDatasourcePatchStreams == null) {
+//            oddrUaDeviceDatasourcePatchStreams = new InputStream[0];
+//        }
+
+        if ((oddrUaBrowserDatasourcePaths == null || oddrUaBrowserDatasourcePaths.trim().length() == 0) && oddrUaBrowserDatasourceStream == null) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not find property " + ODDR_UA_BROWSER_DATASOURCE_PATH_PROP));
+        }
+
+        if ((oddrUaOperatingSystemDatasourcePaths == null || oddrUaOperatingSystemDatasourcePaths.trim().length() == 0) && oddrUaOperatingSystemDatasourceStream == null) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not find property " + ODDR_UA_OPERATINGSYSTEM_DATASOURCE_PATH_PROP));
+        }
+
+        if (oddrThreshold == null || oddrThreshold.trim().length() == 0) {
+            this.threshold = ODDR_DEFAULT_THRESHOLD;
+
+        } else {
+            try {
+                this.threshold = Integer.parseInt(oddrThreshold);
+                if (this.threshold <= 0) {
+                    this.threshold = ODDR_DEFAULT_THRESHOLD;
+                }
+
+            } catch (NumberFormatException x) {
+                this.threshold = ODDR_DEFAULT_THRESHOLD;
+            }
+        }
+
+        Map<String, Device> devices = new HashMap<String, Device>();
+        DeviceDatasourceHandler deviceDatasourceHandler = new DeviceDatasourceHandler(devices, vocabularyHolder);
+
+        InputStream stream = null;
+        SAXParser parser = null;
+
+        try {
+            if (oddrUaDeviceDatasourceStream != null) {
+                stream = oddrUaDeviceDatasourceStream;
+            } else {
+                stream = new FileInputStream(new File(oddrUaDeviceDatasourcePath));
+            }
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not open " + ODDR_UA_DEVICE_DATASOURCE_PATH_PROP + " " + oddrUaDeviceDatasourcePath));
+        }
+
+        try {
+            parser = SAXParserFactory.newInstance().newSAXParser();
+
+        } catch (ParserConfigurationException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+        }
+
+        try {
+            parser.parse(stream, deviceDatasourceHandler);
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse document: " + oddrUaDeviceDatasourcePath));
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not open " + ODDR_UA_DEVICE_DATASOURCE_PATH_PROP + " :" + oddrUaDeviceDatasourcePath));
+        }
+
+        try {
+            stream.close();
+
+        } catch (IOException ex) {
+            logger.warn("", ex);
+        }
+
+        deviceDatasourceHandler.setPatching(true);
+
+        if (oddrUaDeviceDatasourcePatchStreams != null) {
+            for (int i = 0; i < oddrUaDeviceDatasourcePatchStreams.length; i++) {
+                stream = oddrUaDeviceDatasourcePatchStreams[i];
+
+                try {
+                    parser = SAXParserFactory.newInstance().newSAXParser();
+
+                } catch (ParserConfigurationException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+                } catch (SAXException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+                }
+
+                try {
+                    parser.parse(stream, deviceDatasourceHandler);
+
+                } catch (Exception ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse DeviceDatasource input stream " + i));
+                }
+
+                try {
+                    stream.close();
+
+                } catch (IOException ex) {
+                    logger.warn("", ex);
+                }
+            }
+        } else {
+            for (int i = 0; i < ooddrUaDeviceDatasourcePatchPathArray.length; i++) {
+                try {
+                    stream = new FileInputStream(new File(ooddrUaDeviceDatasourcePatchPathArray[i]));
+
+                } catch (IOException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not open " + ODDR_UA_DEVICE_DATASOURCE_PATH_PROP + " " + ooddrUaDeviceDatasourcePatchPathArray[i]));
+                }
+
+                try {
+                    parser = SAXParserFactory.newInstance().newSAXParser();
+
+                } catch (ParserConfigurationException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+                } catch (SAXException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+                }
+
+                try {
+                    parser.parse(stream, deviceDatasourceHandler);
+
+                } catch (SAXException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse document: " + ooddrUaDeviceDatasourcePatchPathArray[i]));
+
+                } catch (IOException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not open " + ODDR_UA_DEVICE_DATASOURCE_PATH_PROP + " :" + ooddrUaDeviceDatasourcePatchPathArray[i]));
+                }
+
+                try {
+                    stream.close();
+
+                } catch (IOException ex) {
+                    logger.warn("", ex);
+                }
+            }
+
+        }
+
+        List<DeviceBuilder> builders = new ArrayList<DeviceBuilder>();
+        DeviceBuilderHandler deviceBuilderHandler = new DeviceBuilderHandler(builders);
+
+        try {
+            if (oddrUaDeviceBuilderStream != null) {
+                stream = oddrUaDeviceBuilderStream;
+            } else {
+                stream = new FileInputStream(new File(oddrUaDeviceBuilderPath));
+            }
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not open " + ODDR_UA_DEVICE_BUILDER_PATH_PROP + " " + oddrUaDeviceBuilderPath));
+        }
+
+        try {
+            parser = SAXParserFactory.newInstance().newSAXParser();
+
+        } catch (ParserConfigurationException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+        }
+
+        try {
+            parser.parse(stream, deviceBuilderHandler);
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse document: " + oddrUaDeviceBuilderPath));
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not open " + ODDR_UA_DEVICE_DATASOURCE_PATH_PROP + " :" + oddrUaDeviceBuilderPath));
+        }
+
+        try {
+            stream.close();
+
+        } catch (IOException ex) {
+            logger.warn("", ex);
+        }
+
+        if (oddrUaDeviceBuilderPatchStreams != null) {
+            for (int i = 0; i < oddrUaDeviceBuilderPatchStreams.length; i++) {
+                stream = oddrUaDeviceBuilderPatchStreams[i];
+
+                try {
+                    parser = SAXParserFactory.newInstance().newSAXParser();
+
+                } catch (ParserConfigurationException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+                } catch (SAXException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+                }
+
+                try {
+                    parser.parse(stream, deviceBuilderHandler);
+
+                } catch (Exception ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse DeviceBuilder input stream " + i));
+                }
+
+                try {
+                    stream.close();
+
+                } catch (IOException ex) {
+                    logger.warn("", ex);
+                }
+            }
+
+        } else {
+            for (int i = 0; i < oddrUaDeviceBuilderPatchPathArray.length; i++) {
+                try {
+                    stream = new FileInputStream(new File(oddrUaDeviceBuilderPatchPathArray[i]));
+
+                } catch (IOException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not open " + ODDR_UA_DEVICE_BUILDER_PATCH_PATHS_PROP + " " + oddrUaDeviceBuilderPatchPathArray[i]));
+                }
+
+                try {
+                    parser = SAXParserFactory.newInstance().newSAXParser();
+
+                } catch (ParserConfigurationException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+                } catch (SAXException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+                }
+
+                try {
+                    parser.parse(stream, deviceBuilderHandler);
+
+                } catch (SAXException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse document: " + oddrUaDeviceBuilderPatchPathArray[i]));
+
+                } catch (IOException ex) {
+                    throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not open " + ODDR_UA_DEVICE_DATASOURCE_PATH_PROP + " :" + oddrUaDeviceBuilderPatchPathArray[i]));
+                }
+
+                try {
+                    stream.close();
+
+                } catch (IOException ex) {
+                    logger.warn("", ex);
+                }
+            }
+        }
+
+        BrowserDatasourceHandler browserDatasourceHandler = new BrowserDatasourceHandler(vocabularyHolder);
+
+        try {
+            if (oddrUaBrowserDatasourceStream != null) {
+                stream = oddrUaBrowserDatasourceStream;
+            } else {
+                stream = new FileInputStream(new File(oddrUaBrowserDatasourcePaths));
+            }
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not open " + ODDR_UA_BROWSER_DATASOURCE_PATH_PROP + " " + oddrUaBrowserDatasourcePaths));
+        }
+
+        try {
+            parser = SAXParserFactory.newInstance().newSAXParser();
+
+        } catch (ParserConfigurationException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+        }
+
+        try {
+            parser.parse(stream, browserDatasourceHandler);
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse document: " + oddrUaBrowserDatasourcePaths));
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not open " + ODDR_UA_BROWSER_DATASOURCE_PATH_PROP + " :" + oddrUaBrowserDatasourcePaths));
+        }
+
+        try {
+            stream.close();
+
+        } catch (IOException ex) {
+            logger.warn("", ex);
+        }
+
+        OperatingSystemDatasourceHandler operatingSystemDatasourceHandler = new OperatingSystemDatasourceHandler(vocabularyHolder);
+
+        try {
+            if (oddrUaOperatingSystemDatasourceStream != null) {
+                stream = oddrUaOperatingSystemDatasourceStream;
+            } else {
+                stream = new FileInputStream(new File(oddrUaOperatingSystemDatasourcePaths));
+            }
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not open " + ODDR_UA_OPERATINGSYSTEM_DATASOURCE_PATH_PROP + " " + oddrUaOperatingSystemDatasourcePaths));
+        }
+
+        try {
+            parser = SAXParserFactory.newInstance().newSAXParser();
+
+        } catch (ParserConfigurationException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+        }
+
+        try {
+            parser.parse(stream, operatingSystemDatasourceHandler);
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse document: " + oddrUaOperatingSystemDatasourcePaths));
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not open " + ODDR_UA_OPERATINGSYSTEM_DATASOURCE_PATH_PROP + " :" + oddrUaOperatingSystemDatasourcePaths));
+        }
+
+        try {
+            stream.close();
+
+        } catch (IOException ex) {
+            logger.warn("", ex);
+        }
+        
+        deviceIdentificator = new DeviceIdentificator(deviceBuilderHandler.getBuilders(), deviceDatasourceHandler.getDevices());
+        deviceIdentificator.completeInit();
+
+        browserIdentificator = new BrowserIdentificator(new Builder[]{DefaultBrowserBuilder.getInstance()}, browserDatasourceHandler.getBrowsers());
+        browserIdentificator.completeInit();
+
+        osIdentificator = new OSIdentificator(new Builder[]{DefaultOSBuilder.getInstance()}, operatingSystemDatasourceHandler.getOperatingSystems());
+        osIdentificator.completeInit();
+
+        deviceDatasourceHandler = null;
+        deviceBuilderHandler = null;
+        browserDatasourceHandler = null;
+        operatingSystemDatasourceHandler = null;
+
+        this.defaultVocabularyIRI = defaultVocabularyIRI;
+
+        parser = null;
+
+        oddrVocabularyService = null;
+
+        return;
+    }
+
+    public String getAPIVersion() {
+        return ODDR_API_VERSION;
+    }
+
+    public String getDataVersion() {
+        return ODDR_DATA_VERSION;
+    }
+
+    public PropertyRef[] listPropertyRefs() {
+        List<PropertyRef> propertyRefsList = new ArrayList<PropertyRef>();
+        Map<String, Vocabulary> vocabularies = vocabularyHolder.getVocabularies();
+        Set<String> vocabularyKeys = vocabularies.keySet();
+
+        for (String vocabularyKey : vocabularyKeys) {
+            Vocabulary vocabulary = vocabularies.get(vocabularyKey);
+            Map<String, VocabularyProperty> properties = vocabulary.getProperties();
+            Set<String> propertyKeys = properties.keySet();
+            for (String propertyKey : propertyKeys) {
+                PropertyName propertyName = new ODDRPropertyName(propertyKey, vocabularyKey);
+                for (int i = 0; i < properties.get(propertyKey).getAspects().length; i++) {
+                    PropertyRef propertyRef = new ODDRPropertyRef(propertyName, properties.get(propertyKey).getAspects()[i]);
+                    propertyRefsList.add(propertyRef);
+                }
+            }
+        }
+
+        PropertyRef[] propertyRefs = new PropertyRef[propertyRefsList.size()];
+        propertyRefs = propertyRefsList.toArray(propertyRefs);
+
+        return propertyRefs;
+    }
+
+    public PropertyValue getPropertyValue(Evidence evdnc, PropertyRef pr) throws NameException {
+        return getPropertyValues(evdnc, new PropertyRef[]{pr}).getValue(pr);
+    }
+
+    public PropertyValue getPropertyValue(Evidence evdnc, String localPropertyName, String localAspectName, String vocabularyIRI) throws NameException {
+        return getPropertyValue(evdnc, newPropertyRef(newPropertyName(localPropertyName, vocabularyIRI), localAspectName));
+    }
+
+    public PropertyValue getPropertyValue(Evidence evdnc, PropertyName pn) throws NameException {
+        return getPropertyValue(evdnc, newPropertyRef(pn));
+    }
+
+    public PropertyValue getPropertyValue(Evidence evdnc, String localPropertyName) throws NameException {
+        return getPropertyValue(evdnc, newPropertyName(localPropertyName));
+    }
+
+    public PropertyValues getPropertyValues(Evidence evdnc) {
+        Device deviceFound = null;
+        Browser browserFound = null;
+        OperatingSystem osFound = null;
+        boolean deviceIdentified = false;
+        boolean browserIdentified = false;
+        boolean osIdentified = false;
+        UserAgent deviceUA = null;
+        UserAgent browserUA = null;
+
+        JexlEngine jexl = new JexlEngine();
+        ODDRPropertyValues ret = new ODDRPropertyValues();
+        Map<String, Vocabulary> vocabularies = vocabularyHolder.getVocabularies();
+        Set<String> vocabularyKeys = vocabularies.keySet();
+
+        for (String vocabularyKey : vocabularyKeys) {
+            Vocabulary vocabulary = vocabularies.get(vocabularyKey);
+            Map<String, VocabularyProperty> properties = vocabulary.getProperties();
+            Set<String> propertyKeys = properties.keySet();
+            for (String propertyKey : propertyKeys) {
+                PropertyName propertyName = new ODDRPropertyName(propertyKey, vocabularyKey);
+                for (int i = 0; i < properties.get(propertyKey).getAspects().length; i++) {
+                    PropertyRef propertyRef = new ODDRPropertyRef(propertyName, properties.get(propertyKey).getAspects()[i]);
+                    if (ASPECT_DEVICE.equals(propertyRef.getAspectName())) {
+                        if (!deviceIdentified) {
+                            if (deviceUA == null) {
+                                deviceUA = UserAgentFactory.newDeviceUserAgent(evdnc);
+                            }
+                            if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                                deviceFound = ((BufferedODDRHTTPEvidence) evdnc).getDeviceFound();
+                            }
+                            if (deviceFound == null) {
+                                deviceFound = deviceIdentificator.get(deviceUA, this.threshold);
+                            }
+                            if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                                ((BufferedODDRHTTPEvidence) evdnc).setDeviceFound(deviceFound);
+                            }
+                            deviceIdentified = true;
+                        }
+                        String property = null;
+                        if (deviceFound != null) {
+                            property = deviceFound.get(propertyRef.getLocalPropertyName());
+                            ret.addProperty(new ODDRPropertyValue(property, properties.get(propertyKey).getType(), propertyRef));
+
+                        } else {
+                            ret.addProperty(new ODDRPropertyValue(null, properties.get(propertyKey).getType(), propertyRef));
+                        }
+                        continue;
+
+                    } else if (ASPECT_WEB_BROWSER.equals(propertyRef.getAspectName())) {
+                        if (!browserIdentified) {
+                            if (browserUA == null) {
+                                browserUA = UserAgentFactory.newBrowserUserAgent(evdnc);
+                            }
+                            if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                                browserFound = ((BufferedODDRHTTPEvidence) evdnc).getBrowserFound();
+                            }
+                            if (browserFound == null) {
+                                browserFound = browserIdentificator.get(browserUA, this.threshold);
+                            }
+                            if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                                ((BufferedODDRHTTPEvidence) evdnc).setBrowserFound(browserFound);
+                            }
+
+                            browserIdentified = true;
+                        }
+                        String property = null;
+                        if (browserFound != null) {
+                            property = browserFound.get(propertyRef.getLocalPropertyName());
+                            ret.addProperty(new ODDRPropertyValue(property, properties.get(propertyKey).getType(), propertyRef));
+
+                        } else {
+                            ret.addProperty(new ODDRPropertyValue(null, properties.get(propertyKey).getType(), propertyRef));
+                        }
+                        continue;
+
+                    } else if (ASPECT_OPERATIVE_SYSTEM.equals(propertyRef.getAspectName())) {
+                        if (!osIdentified) {
+                            if (deviceUA == null) {
+                                deviceUA = UserAgentFactory.newDeviceUserAgent(evdnc);
+                            }
+                            if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                                osFound = ((BufferedODDRHTTPEvidence) evdnc).getOsFound();
+                            }
+                            if (osFound == null) {
+                                osFound = osIdentificator.get(deviceUA, this.threshold);
+                            }
+                            if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                                ((BufferedODDRHTTPEvidence) evdnc).setOsFound(osFound);
+                            }
+
+                            osIdentified = true;
+                        }
+                        String property = null;
+                        if (osFound != null) {
+                            property = osFound.get(propertyRef.getLocalPropertyName());
+                            ret.addProperty(new ODDRPropertyValue(property, properties.get(propertyKey).getType(), propertyRef));
+
+                        } else {
+                            ret.addProperty(new ODDRPropertyValue(null, properties.get(propertyKey).getType(), propertyRef));
+                        }
+                        continue;
+
+                    } else if (ASPECT_GROUP.equals(propertyRef.getAspectName())) {
+                        try {
+                            String jexlExp = properties.get(propertyKey).getExpr();
+                            Matcher m = groupRegexprPattern.matcher(jexlExp);
+                            while (m.find()) {
+                                String id = m.group(1);
+                                String propertyValueString = null;
+                                PropertyValue propertyValue = getPropertyValue(evdnc, vocabulary.getVocabularyVariables().get(id).getName(), vocabulary.getVocabularyVariables().get(id).getAspect(), vocabulary.getVocabularyVariables().get(id).getVocabulary());
+                                propertyValueString = (propertyValue.exists() ? propertyValue.getString() : "-");
+                                String toReplace = "$" + id;
+                                jexlExp = jexlExp.replaceAll(Matcher.quoteReplacement(toReplace), "'" + propertyValueString + "'");
+                            }
+                            Expression e = jexl.createExpression(jexlExp);
+                            JexlContext jc = new MapContext();
+                            Object o = e.evaluate(jc);
+                            ret.addProperty(new ODDRPropertyValue(o.toString(), properties.get(propertyKey).getType(), propertyRef));
+
+                        } catch (Exception ex) {
+                            throw new RuntimeException(ex);
+                        }
+                    }
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    public PropertyValues getPropertyValues(Evidence evdnc, PropertyRef[] prs) throws NameException {
+        Device deviceFound = null;
+        Browser browserFound = null;
+        OperatingSystem osFound = null;
+        boolean deviceIdentified = false;
+        boolean browserIdentified = false;
+        boolean osIdentified = false;
+        UserAgent deviceUA = null;
+        UserAgent browserUA = null;
+
+        JexlEngine jexl = new JexlEngine();
+        ODDRPropertyValues ret = new ODDRPropertyValues();
+        Map<String, Vocabulary> vocabularies = vocabularyHolder.getVocabularies();
+
+        for (PropertyRef propertyRef : prs) {
+            VocabularyProperty vocabularyProperty = vocabularyHolder.existProperty(propertyRef.getLocalPropertyName(), propertyRef.getAspectName(), propertyRef.getNamespace());
+            Vocabulary vocabulary = vocabularies.get(propertyRef.getNamespace());
+            if (ASPECT_DEVICE.equals(propertyRef.getAspectName())) {
+                if (!deviceIdentified) {
+                    if (deviceUA == null) {
+                        deviceUA = UserAgentFactory.newDeviceUserAgent(evdnc);
+                    }
+                    if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                        deviceFound = ((BufferedODDRHTTPEvidence) evdnc).getDeviceFound();
+                    }
+                    if (deviceFound == null) {
+                        deviceFound = deviceIdentificator.get(deviceUA, this.threshold);
+                    }
+                    if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                        ((BufferedODDRHTTPEvidence) evdnc).setDeviceFound(deviceFound);
+                    }
+
+                    deviceIdentified = true;
+                }
+                String property = null;
+
+                if (deviceFound != null) {
+                    property = deviceFound.get(propertyRef.getLocalPropertyName());
+                    ret.addProperty(new ODDRPropertyValue(property, vocabularyProperty.getType(), propertyRef));
+
+                } else {
+                    ret.addProperty(new ODDRPropertyValue(null, vocabularyProperty.getType(), propertyRef));
+                }
+                continue;
+
+            } else if (ASPECT_WEB_BROWSER.equals(propertyRef.getAspectName())) {
+                //TODO: evaluate ua-pixels header in evidence
+                if (!browserIdentified) {
+                    if (browserUA == null) {
+                        browserUA = UserAgentFactory.newBrowserUserAgent(evdnc);
+                    }
+                    if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                        browserFound = ((BufferedODDRHTTPEvidence) evdnc).getBrowserFound();
+                    }
+                    if (browserFound == null) {
+                        browserFound = browserIdentificator.get(browserUA, this.threshold);
+                    }
+                    if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                        ((BufferedODDRHTTPEvidence) evdnc).setBrowserFound(browserFound);
+                    }
+                    browserIdentified = true;
+                }
+                String property = null;
+                if (browserFound != null) {
+                    property = browserFound.get(propertyRef.getLocalPropertyName());
+                    ret.addProperty(new ODDRPropertyValue(property, vocabularyProperty.getType(), propertyRef));
+
+                } else {
+                    ret.addProperty(new ODDRPropertyValue(null, vocabularyProperty.getType(), propertyRef));
+                }
+                continue;
+
+            } else if (ASPECT_OPERATIVE_SYSTEM.equals(propertyRef.getAspectName())) {
+                //TODO: evaluate ua-os header in evidence
+                if (!osIdentified) {
+                    if (deviceUA == null) {
+                        deviceUA = UserAgentFactory.newDeviceUserAgent(evdnc);
+                    }
+                    if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                        osFound = ((BufferedODDRHTTPEvidence) evdnc).getOsFound();
+                    }
+                    if (osFound == null) {
+                        osFound = osIdentificator.get(deviceUA, this.threshold);
+                    }
+                    if (evdnc instanceof BufferedODDRHTTPEvidence) {
+                        ((BufferedODDRHTTPEvidence) evdnc).setOsFound(osFound);
+                    }
+                    osIdentified = true;
+                }
+                String property = null;
+                if (osFound != null) {
+                    property = osFound.get(propertyRef.getLocalPropertyName());
+                    ret.addProperty(new ODDRPropertyValue(property, vocabularyProperty.getType(), propertyRef));
+
+                } else {
+                    ret.addProperty(new ODDRPropertyValue(null, vocabularyProperty.getType(), propertyRef));
+                }
+                continue;
+
+            } else if (ASPECT_GROUP.equals(propertyRef.getAspectName())) {
+                try {
+                    String jexlExp = vocabularyProperty.getExpr();
+                    Matcher m = groupRegexprPattern.matcher(jexlExp);
+                    while (m.find()) {
+                        String id = m.group(1);
+                        String propertyValueString = null;
+                        PropertyValue propertyValue = getPropertyValue(evdnc, vocabulary.getVocabularyVariables().get(id).getName(), vocabulary.getVocabularyVariables().get(id).getAspect(), vocabulary.getVocabularyVariables().get(id).getVocabulary());
+                        propertyValueString = (propertyValue.exists() ? propertyValue.getString() : "-");
+                        String toReplace = "$" + id;
+                        jexlExp = jexlExp.replaceAll(Matcher.quoteReplacement(toReplace), "'" + propertyValueString + "'");
+                    }
+                    Expression e = jexl.createExpression(jexlExp);
+                    JexlContext jc = new MapContext();
+                    Object o = e.evaluate(jc);
+                    ret.addProperty(new ODDRPropertyValue(o.toString(), vocabularyProperty.getType(), propertyRef));
+
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    public PropertyValues getPropertyValues(Evidence evdnc, String localAspectName) throws NameException {
+        return getPropertyValues(evdnc, localAspectName, defaultVocabularyIRI);
+    }
+
+    public PropertyValues getPropertyValues(Evidence evdnc, String localAspectName, String vocabularyIRI) throws NameException {
+        VocabularyProperty vocabularyProperty = vocabularyHolder.existProperty(localAspectName, null, vocabularyIRI);
+
+        PropertyName propertyName = new ODDRPropertyName(localAspectName, vocabularyIRI);
+        PropertyRef propertyRef = new ODDRPropertyRef(propertyName, vocabularyProperty.getDefaultAspect());
+
+        return getPropertyValues(evdnc, new PropertyRef[]{propertyRef});
+    }
+
+    public PropertyName newPropertyName(String localPropertyName, String vocabularyIRI) throws NameException {
+        vocabularyHolder.existProperty(localPropertyName, null, vocabularyIRI);
+        return new ODDRPropertyName(localPropertyName, vocabularyIRI);
+    }
+
+    public PropertyName newPropertyName(String localPropertyName) throws NameException {
+        return newPropertyName(localPropertyName, defaultVocabularyIRI);
+    }
+
+    public PropertyRef newPropertyRef(PropertyName pn, String localAspectName) throws NameException {
+        vocabularyHolder.existProperty(pn.getLocalPropertyName(), localAspectName, pn.getNamespace());
+        return new ODDRPropertyRef(pn, localAspectName);
+    }
+
+    public PropertyRef newPropertyRef(PropertyName pn) throws NameException {
+        VocabularyProperty vocabularyProperty = vocabularyHolder.existProperty(pn.getLocalPropertyName(), null, pn.getNamespace());
+        return newPropertyRef(pn, vocabularyProperty.getDefaultAspect());
+    }
+
+    public PropertyRef newPropertyRef(String localPropertyName) throws NameException {
+        return newPropertyRef(newPropertyName(localPropertyName));
+    }
+
+    public Evidence newHTTPEvidence() {
+        return new ODDRHTTPEvidence();
+    }
+
+    public Evidence newHTTPEvidence(Map<String, String> map) {
+        return new ODDRHTTPEvidence(map);
+    }
+}

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRService.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRVocabularyService.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRVocabularyService.java?rev=1392911&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRVocabularyService.java (added)
+++ incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRVocabularyService.java Tue Oct  2 13:32:28 2012
@@ -0,0 +1,211 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.openddr.simpleapi.oddr;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.openddr.simpleapi.oddr.documenthandler.VocabularyHandler;
+import org.openddr.simpleapi.oddr.model.vocabulary.Vocabulary;
+import org.openddr.simpleapi.oddr.vocabulary.VocabularyHolder;
+import org.w3c.ddr.simple.exception.InitializationException;
+import org.xml.sax.SAXException;
+
+public class ODDRVocabularyService {
+
+    public static final String DDR_CORE_VOCABULARY_PATH_PROP = "ddr.vocabulary.core.path";
+    public static final String ODDR_VOCABULARY_PATH_PROP = "oddr.vocabulary.path";
+    public static final String ODDR_LIMITED_VOCABULARY_PATH_PROP = "oddr.limited.vocabulary.path";
+    public static final String DDR_CORE_VOCABULARY_STREAM_PROP = "ddr.vocabulary.core.stream";
+    public static final String ODDR_VOCABULARY_STREAM_PROP = "oddr.vocabulary.stream";
+    public static final String ODDR_LIMITED_VOCABULARY_STREAM_PROP = "oddr.limited.vocabulary.stream";
+    public static final String ODDR_LIMITED_VOCABULARY_IRI = "limitedVocabulary";
+    private VocabularyHolder vocabularyHolder = null;
+
+    public void initialize(Properties props) throws InitializationException {
+        Map<String, Vocabulary> vocabularies = new HashMap<String, Vocabulary>();
+
+        String ddrCoreVocabularyPath = props.getProperty(DDR_CORE_VOCABULARY_PATH_PROP);
+        String oddrVocabularyPath = props.getProperty(ODDR_VOCABULARY_PATH_PROP);
+
+        InputStream ddrCoreVocabulayStream = null;
+        InputStream[] oddrVocabularyStream = null;
+        try {
+            ddrCoreVocabulayStream = (InputStream) props.get(DDR_CORE_VOCABULARY_STREAM_PROP);
+        } catch (Exception ex) {
+            ddrCoreVocabulayStream = null;
+        }
+        try {
+            oddrVocabularyStream = (InputStream[]) props.get(ODDR_VOCABULARY_STREAM_PROP);
+        } catch (Exception ex) {
+            oddrVocabularyStream = null;
+        }
+
+        if ((ddrCoreVocabularyPath == null || ddrCoreVocabularyPath.trim().length() == 0) && ddrCoreVocabulayStream == null) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not find property " + DDR_CORE_VOCABULARY_PATH_PROP));
+        }
+
+        if ((oddrVocabularyPath == null || oddrVocabularyPath.trim().length() == 0) && oddrVocabularyStream == null) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not find property " + ODDR_VOCABULARY_PATH_PROP));
+        }
+
+        VocabularyHandler vocabularyHandler = new VocabularyHandler();
+        Vocabulary vocabulary = null;
+
+        if (ddrCoreVocabulayStream != null) {
+            parseVocabularyFromStream(vocabularyHandler, DDR_CORE_VOCABULARY_STREAM_PROP, ddrCoreVocabulayStream);
+        } else {
+            parseVocabularyFromPath(vocabularyHandler, DDR_CORE_VOCABULARY_PATH_PROP, ddrCoreVocabularyPath);
+        }
+        vocabulary = vocabularyHandler.getVocabulary();
+        vocabularies.put(vocabulary.getVocabularyIRI(), vocabulary);
+
+        if (oddrVocabularyStream != null) {
+            for (InputStream stream : oddrVocabularyStream) {
+                vocabularyHandler = new VocabularyHandler();
+                parseVocabularyFromStream(vocabularyHandler, ODDR_VOCABULARY_STREAM_PROP, stream);
+                vocabulary = vocabularyHandler.getVocabulary();
+                vocabularies.put(vocabulary.getVocabularyIRI(), vocabulary);
+            }
+        } else {
+            String[] oddrVocabularyPaths = oddrVocabularyPath.split(",");
+            for (int i = 0; i < oddrVocabularyPaths.length; i++) {
+                oddrVocabularyPaths[i] = oddrVocabularyPaths[i].trim();
+            }
+            for (String oddVocabularyString : oddrVocabularyPaths) {
+                vocabularyHandler = new VocabularyHandler();
+                parseVocabularyFromPath(vocabularyHandler, ODDR_VOCABULARY_PATH_PROP, oddVocabularyString);
+                vocabulary = vocabularyHandler.getVocabulary();
+                vocabularies.put(vocabulary.getVocabularyIRI(), vocabulary);
+            }
+        }
+
+        String oddrLimitedVocabularyPath = props.getProperty(ODDR_LIMITED_VOCABULARY_PATH_PROP);
+        InputStream oddrLimitedVocabularyStream = (InputStream)props.get(ODDR_LIMITED_VOCABULARY_STREAM_PROP);
+
+        if (oddrLimitedVocabularyStream != null) {
+            parseVocabularyFromStream(vocabularyHandler, ODDR_LIMITED_VOCABULARY_STREAM_PROP, oddrLimitedVocabularyStream);
+
+        } else {
+           if (oddrLimitedVocabularyPath != null && oddrLimitedVocabularyPath.trim().length() != 0) {
+                vocabularyHandler = new VocabularyHandler();
+                parseVocabularyFromPath(vocabularyHandler, ODDR_LIMITED_VOCABULARY_PATH_PROP, oddrLimitedVocabularyPath);
+            }
+        }
+        vocabulary = vocabularyHandler.getVocabulary();
+        vocabularies.put(ODDR_LIMITED_VOCABULARY_IRI, vocabulary);
+
+        vocabularyHolder = new VocabularyHolder(vocabularies);
+
+        vocabularyHandler = null;
+        vocabularies = null;
+
+    }
+
+    private void parseVocabularyFromPath(VocabularyHandler vocabularyHandler, String prop, String path) throws InitializationException {
+        InputStream stream = null;
+        SAXParser parser = null;
+
+        try {
+            stream = new FileInputStream(new File(path));
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalArgumentException("Can not open " + prop + " : " + path));
+        }
+
+        try {
+            parser = SAXParserFactory.newInstance().newSAXParser();
+
+        } catch (ParserConfigurationException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+        }
+
+        try {
+            parser.parse(stream, vocabularyHandler);
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse document: " + path));
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not open " + prop + " : " + path));
+        }
+
+        try {
+            stream.close();
+
+        } catch (IOException ex) {
+            Logger.getLogger(ODDRService.class.getName()).log(Level.WARNING, null, ex);
+        }
+
+        parser = null;
+    }
+
+    private void parseVocabularyFromStream(VocabularyHandler vocabularyHandler, String prop, InputStream inputStream) throws InitializationException {
+        InputStream stream = null;
+        SAXParser parser = null;
+        stream = inputStream;
+
+        try {
+            parser = SAXParserFactory.newInstance().newSAXParser();
+
+        } catch (ParserConfigurationException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new IllegalStateException("Can not instantiate SAXParserFactory.newInstance().newSAXParser()"));
+        }
+
+        try {
+            parser.parse(stream, vocabularyHandler);
+
+        } catch (SAXException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not parse document in property: " + prop));
+
+        } catch (IOException ex) {
+            throw new InitializationException(InitializationException.INITIALIZATION_ERROR, new RuntimeException("Can not open " + prop));
+        }
+
+        try {
+            stream.close();
+
+        } catch (IOException ex) {
+            Logger.getLogger(ODDRService.class.getName()).log(Level.WARNING, null, ex);
+        }
+
+        parser = null;
+    }
+
+    public VocabularyHolder getVocabularyHolder() {
+        return vocabularyHolder;
+    }
+}

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRVocabularyService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/ODDRVocabularyService.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/Builder.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/Builder.java?rev=1392911&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/Builder.java (added)
+++ incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/Builder.java Tue Oct  2 13:32:28 2012
@@ -0,0 +1,31 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.openddr.simpleapi.oddr.builder;
+
+import org.openddr.simpleapi.oddr.model.BuiltObject;
+import org.openddr.simpleapi.oddr.model.UserAgent;
+
+public interface Builder {
+
+    public boolean canBuild(UserAgent userAgent);
+
+    public BuiltObject build(UserAgent userAgent, int confidenceTreshold);
+}

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/Builder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/Builder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/AndroidMobileBrowserBuilder.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/AndroidMobileBrowserBuilder.java?rev=1392911&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/AndroidMobileBrowserBuilder.java (added)
+++ incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/AndroidMobileBrowserBuilder.java Tue Oct  2 13:32:28 2012
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.openddr.simpleapi.oddr.builder.browser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.openddr.simpleapi.oddr.model.UserAgent;
+import org.openddr.simpleapi.oddr.model.browser.Browser;
+
+public class AndroidMobileBrowserBuilder extends LayoutEngineBrowserBuilder {
+
+    private static final String VERSION_REGEXP = ".*Version/([0-9\\.]+).*?";
+    private static final String SAFARI_REGEXP = ".*Safari/([0-9\\.]+).*?";
+    private Pattern versionPattern = Pattern.compile(VERSION_REGEXP);
+    private Pattern safariPattern = Pattern.compile(SAFARI_REGEXP);
+
+    public boolean canBuild(UserAgent userAgent) {
+        return (userAgent.containsAndroid());
+    }
+
+    @Override
+    protected Browser buildBrowser(UserAgent userAgent, String layoutEngine, String layoutEngineVersion, int hintedWidth, int hintedHeight) {
+        if (!userAgent.containsAndroid() || !userAgent.hasMozillaPattern() || userAgent.getCompleteUserAgent().contains("Fennec")) {
+            return null;
+        }
+
+        int confidence = 70;
+        Browser identified = new Browser();
+
+        identified.setVendor("Google");
+        identified.setModel("Android Browser");
+
+        Matcher versionMatcher = versionPattern.matcher(userAgent.getCompleteUserAgent());
+        if (versionMatcher.matches()) {
+            if (versionMatcher.group(1) != null) {
+                identified.setVersion(versionMatcher.group(1));
+                String version[] = versionMatcher.group(1).split("\\.");
+
+                if (version.length > 0) {
+                    identified.setMajorRevision(version[0]);
+                }
+
+                if (version.length > 1) {
+                    identified.setMinorRevision(version[1]);
+                    confidence += 10;
+                }
+
+                if (version.length > 2) {
+                    identified.setMicroRevision(version[2]);
+                }
+
+                if (version.length > 3) {
+                    identified.setNanoRevision(version[3]);
+                }
+            }
+
+        } else {
+            //fallback version
+            identified.setVersion("1.0");
+            identified.setMajorRevision("1");
+        }
+
+        if (layoutEngine != null) {
+            identified.setLayoutEngine(layoutEngine);
+            identified.setLayoutEngineVersion(layoutEngineVersion);
+
+            if (layoutEngine.equals(LayoutEngineBrowserBuilder.APPLEWEBKIT)) {
+                confidence += 10;
+            }
+        }
+
+        Matcher safariMatcher = safariPattern.matcher(userAgent.getCompleteUserAgent());
+        if (safariMatcher.matches()) {
+            if (safariMatcher.group(1) != null) {
+                identified.setReferenceBrowser("Safari");
+                identified.setReferenceBrowserVersion(safariMatcher.group(1));
+                confidence += 10;
+            }
+        }
+
+        identified.setDisplayWidth(hintedWidth);
+        identified.setDisplayHeight(hintedHeight);
+        identified.setConfidence(confidence);
+
+        return identified;
+    }
+}

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/AndroidMobileBrowserBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/AndroidMobileBrowserBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/BlackBerryBrowserBuilder.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/BlackBerryBrowserBuilder.java?rev=1392911&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/BlackBerryBrowserBuilder.java (added)
+++ incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/BlackBerryBrowserBuilder.java Tue Oct  2 13:32:28 2012
@@ -0,0 +1,110 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.openddr.simpleapi.oddr.builder.browser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.openddr.simpleapi.oddr.model.UserAgent;
+import org.openddr.simpleapi.oddr.model.browser.Browser;
+
+public class BlackBerryBrowserBuilder extends LayoutEngineBrowserBuilder {
+
+    private static final String BLACKBERRY_VERSION_REGEXP = ".*(?:(?:Version)|(?:[Bb]lack.?[Bb]erry.?(?:[0-9a-z]+)))/([0-9\\.]+).*";//"(?:.*?Version.?([0-9\\.]+).*)|(?:.*?[Bb]lack.?[Bb]erry(?:\\d+)/([0-9\\.]+).*)";
+    private static final String SAFARI_VERSION_REGEXP = ".*Safari/([0-9\\.]+).*";
+    private Pattern blackberryVersionPattern = Pattern.compile(BLACKBERRY_VERSION_REGEXP);
+    private Pattern safariVersionPattern = Pattern.compile(SAFARI_VERSION_REGEXP);
+
+    public boolean canBuild(UserAgent userAgent) {
+        return userAgent.getCompleteUserAgent().contains("BlackBerry");
+    }
+
+    @Override
+    protected Browser buildBrowser(UserAgent userAgent, String layoutEngine, String layoutEngineVersion, int hintedWidth, int hintedHeight) {
+
+        int confidence = 50;
+        Browser identified = new Browser();
+
+        identified.setVendor("RIM");
+        identified.setModel("BlackBerry");
+        identified.setVersion("-");
+        identified.setMajorRevision("-");
+
+        Matcher blackberryBrowserMatcher = blackberryVersionPattern.matcher(userAgent.getCompleteUserAgent());
+        if (blackberryBrowserMatcher.matches()) {
+            if (blackberryBrowserMatcher.group(1) != null) {
+                String totalVersion = "";
+                if (blackberryBrowserMatcher.group(1) != null) {
+                    totalVersion = blackberryBrowserMatcher.group(1);
+                } else if (blackberryBrowserMatcher.group(2) != null) {
+                    totalVersion = blackberryBrowserMatcher.group(2);
+                }
+                if (totalVersion.length() > 0) {
+                    identified.setVersion(totalVersion);
+                    String version[] = totalVersion.split("\\.");
+
+                    if (version.length > 0) {
+                        identified.setMajorRevision(version[0]);
+                        if (identified.getMajorRevision().length() == 0) {
+                            identified.setMajorRevision("1");
+                        }
+                    }
+
+                    if (version.length > 1) {
+                        identified.setMinorRevision(version[1]);
+                        confidence += 10;
+                    }
+
+                    if (version.length > 2) {
+                        identified.setMicroRevision(version[2]);
+                    }
+
+                    if (version.length > 3) {
+                        identified.setNanoRevision(version[3]);
+                    }
+                }
+            }
+
+        }
+
+        if (layoutEngine != null) {
+            identified.setLayoutEngine(layoutEngine);
+            identified.setLayoutEngineVersion(layoutEngineVersion);
+            if (layoutEngine.equals(LayoutEngineBrowserBuilder.APPLEWEBKIT)) {
+                confidence += 10;
+            }
+        }
+
+        Matcher safariMatcher = safariVersionPattern.matcher(userAgent.getCompleteUserAgent());
+        if (safariMatcher.matches()) {
+            if (safariMatcher.group(1) != null) {
+                identified.setReferenceBrowser("Safari");
+                identified.setReferenceBrowserVersion(safariMatcher.group(1));
+                confidence += 10;
+            }
+        }
+
+        identified.setDisplayWidth(hintedWidth);
+        identified.setDisplayHeight(hintedHeight);
+        identified.setConfidence(confidence);
+
+        return identified;
+    }
+}

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/BlackBerryBrowserBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/BlackBerryBrowserBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeBrowserBuilder.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeBrowserBuilder.java?rev=1392911&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeBrowserBuilder.java (added)
+++ incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeBrowserBuilder.java Tue Oct  2 13:32:28 2012
@@ -0,0 +1,109 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.openddr.simpleapi.oddr.builder.browser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.openddr.simpleapi.oddr.model.UserAgent;
+import org.openddr.simpleapi.oddr.model.browser.Browser;
+
+public class ChromeBrowserBuilder extends LayoutEngineBrowserBuilder {
+
+    private static final String CHROME_VERSION_REGEXP = ".*Chrome.([0-9a-z\\.b]+).*";
+    private static final String SAFARI_REGEXP = ".*Safari/([0-9\\.]+).*?";
+    private Pattern chromeVersionPattern = Pattern.compile(CHROME_VERSION_REGEXP);
+    private Pattern safariPattern = Pattern.compile(SAFARI_REGEXP);
+
+    public boolean canBuild(UserAgent userAgent) {
+        return (userAgent.getCompleteUserAgent().contains("Chrome"));
+    }
+
+    @Override
+    protected Browser buildBrowser(UserAgent userAgent, String layoutEngine, String layoutEngineVersion, int hintedWidth, int hintedHeight) {
+        if (!(userAgent.hasMozillaPattern())) {
+            return null;
+        }
+
+        int confidence = 60;
+        Browser identified = new Browser();
+
+        identified.setVendor("Google");
+        identified.setModel("Chrome");
+        identified.setVersion("-");
+        identified.setMajorRevision("-");
+
+        Matcher chromeMatcher = chromeVersionPattern.matcher(userAgent.getCompleteUserAgent());
+        if (chromeMatcher.matches()) {
+            if (chromeMatcher.group(1) != null) {
+                identified.setVersion(chromeMatcher.group(1));
+                String version[] = chromeMatcher.group(1).split("\\.");
+
+                if (version.length > 0) {
+                    identified.setMajorRevision(version[0]);
+                    if (identified.getMajorRevision().length() == 0) {
+                        identified.setMajorRevision("1");
+                    }
+                }
+
+                if (version.length > 1) {
+                    identified.setMinorRevision(version[1]);
+                    confidence += 10;
+                }
+
+                if (version.length > 2) {
+                    identified.setMicroRevision(version[2]);
+                }
+
+                if (version.length > 3) {
+                    identified.setNanoRevision(version[3]);
+                }
+            }
+
+        } else {
+            //fallback version
+            identified.setVersion("1.0");
+            identified.setMajorRevision("1");
+        }
+
+        if (layoutEngine != null) {
+            identified.setLayoutEngine(layoutEngine);
+            identified.setLayoutEngineVersion(layoutEngineVersion);
+            if (layoutEngine.equals(LayoutEngineBrowserBuilder.KHML)) {
+                confidence += 10;
+            }
+        }
+
+        Matcher safariMatcher = safariPattern.matcher(userAgent.getCompleteUserAgent());
+        if (safariMatcher.matches()) {
+            if (safariMatcher.group(1) != null) {
+                identified.setReferenceBrowser("Safari");
+                identified.setReferenceBrowserVersion(safariMatcher.group(1));
+                confidence += 10;
+            }
+        }
+
+        identified.setDisplayWidth(hintedWidth);
+        identified.setDisplayHeight(hintedHeight);
+        identified.setConfidence(confidence);
+
+        return identified;
+    }
+}

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeBrowserBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeBrowserBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeMobileBrowserBuilder.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeMobileBrowserBuilder.java?rev=1392911&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeMobileBrowserBuilder.java (added)
+++ incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeMobileBrowserBuilder.java Tue Oct  2 13:32:28 2012
@@ -0,0 +1,125 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.openddr.simpleapi.oddr.builder.browser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.openddr.simpleapi.oddr.model.UserAgent;
+import org.openddr.simpleapi.oddr.model.browser.Browser;
+
+public class ChromeMobileBrowserBuilder extends LayoutEngineBrowserBuilder {
+
+    private static final String VERSION_REGEXP = "(?:.*Chrome/([0-9\\.]+).*?)|(?:.*CriOS/([0-9\\.]+).*?)";
+    private static final String SAFARI_REGEXP = ".*Safari/([0-9\\.]+).*?";
+    private Pattern versionPattern = Pattern.compile(VERSION_REGEXP);
+    private Pattern safariPattern = Pattern.compile(SAFARI_REGEXP);
+
+    public boolean canBuild(UserAgent userAgent) {
+        return ((userAgent.containsAndroid() || userAgent.containsIOSDevices()) && (userAgent.getCompleteUserAgent().contains("Chrome") || userAgent.getCompleteUserAgent().contains("CriOS")));
+    }
+
+    @Override
+    protected Browser buildBrowser(UserAgent userAgent, String layoutEngine, String layoutEngineVersion, int hintedWidth, int hintedHeight) {
+        if (!userAgent.hasMozillaPattern() || !userAgent.getCompleteUserAgent().contains("Mobile")) {
+            return null;
+        }
+
+        int confidence = 70;
+        Browser identified = new Browser();
+
+        identified.setVendor("Google");
+        identified.setModel("Chrome");
+
+        Matcher versionMatcher = versionPattern.matcher(userAgent.getCompleteUserAgent());
+        if (versionMatcher.matches()) {
+            if (versionMatcher.group(1) != null) {
+                identified.setVersion(versionMatcher.group(1));
+                String version[] = versionMatcher.group(1).split("\\.");
+
+                if (version.length > 0) {
+                    identified.setMajorRevision(version[0]);
+                }
+
+                if (version.length > 1) {
+                    identified.setMinorRevision(version[1]);
+                    confidence += 10;
+                }
+
+                if (version.length > 2) {
+                    identified.setMicroRevision(version[2]);
+                }
+
+                if (version.length > 3) {
+                    identified.setNanoRevision(version[3]);
+                }
+            } else if (versionMatcher.group(2) != null) {
+                identified.setVersion(versionMatcher.group(2));
+                String version[] = versionMatcher.group(2).split("\\.");
+
+                if (version.length > 0) {
+                    identified.setMajorRevision(version[0]);
+                }
+
+                if (version.length > 1) {
+                    identified.setMinorRevision(version[1]);
+                    confidence += 10;
+                }
+
+                if (version.length > 2) {
+                    identified.setMicroRevision(version[2]);
+                }
+
+                if (version.length > 3) {
+                    identified.setNanoRevision(version[3]);
+                }
+            }
+
+        } else {
+            //fallback version
+            identified.setVersion("18.0");
+            identified.setMajorRevision("18");
+        }
+
+        if (layoutEngine != null) {
+            identified.setLayoutEngine(layoutEngine);
+            identified.setLayoutEngineVersion(layoutEngineVersion);
+
+            if (layoutEngine.equals(LayoutEngineBrowserBuilder.APPLEWEBKIT)) {
+                confidence += 10;
+            }
+        }
+
+        Matcher safariMatcher = safariPattern.matcher(userAgent.getCompleteUserAgent());
+        if (safariMatcher.matches()) {
+            if (safariMatcher.group(1) != null) {
+                identified.setReferenceBrowser("Safari");
+                identified.setReferenceBrowserVersion(safariMatcher.group(1));
+                confidence += 10;
+            }
+        }
+
+        identified.setDisplayWidth(hintedWidth);
+        identified.setDisplayHeight(hintedHeight);
+        identified.setConfidence(confidence);
+
+        return identified;
+    }
+}

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeMobileBrowserBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/ChromeMobileBrowserBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/DefaultBrowserBuilder.java
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/DefaultBrowserBuilder.java?rev=1392911&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/DefaultBrowserBuilder.java (added)
+++ incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/DefaultBrowserBuilder.java Tue Oct  2 13:32:28 2012
@@ -0,0 +1,108 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.openddr.simpleapi.oddr.builder.browser;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.openddr.simpleapi.oddr.builder.Builder;
+import org.openddr.simpleapi.oddr.model.UserAgent;
+import org.openddr.simpleapi.oddr.model.browser.Browser;
+
+public class DefaultBrowserBuilder implements Builder {
+
+    private Builder[] builders;
+    private static DefaultBrowserBuilder instance;
+
+    public static synchronized DefaultBrowserBuilder getInstance() {
+        if (instance == null) {
+            instance = new DefaultBrowserBuilder();
+        }
+        return instance;
+    }
+
+    private DefaultBrowserBuilder() {
+
+        builders = new Builder[]{
+                    new OperaMiniBrowserBuilder(),
+                    new ChromeMobileBrowserBuilder(),
+                    new FennecBrowserBuilder(),
+                    new SafariMobileBrowserBuilder(), 
+                    new SilkBrowserBuilder(),
+                    new AndroidMobileBrowserBuilder(),
+                    new NetFrontBrowserBuilder(),
+                    new UPBrowserBuilder(),
+                    new OpenWaveBrowserBuilder(),
+                    new SEMCBrowserBuilder(),
+                    new DolfinBrowserBuilder(),
+                    new JasmineBrowserBuilder(),
+                    new PolarisBrowserBuilder(),
+                    new ObigoBrowserBuilder(),
+                    new OperaBrowserBuilder(),
+                    new IEMobileBrowserBuilder(),
+                    new NokiaBrowserBuilder(),
+                    new BlackBerryBrowserBuilder(),
+                    new WebOsBrowserBuilder(),
+                    new InternetExplorerBrowserBuilder(),
+                    new ChromeBrowserBuilder(),
+                    new FirefoxBrowserBuilder(),
+                    new SafariBrowserBuilder(),
+                    new KonquerorBrowserBuilder()};
+    }
+
+    public boolean canBuild(UserAgent userAgent) {
+        for (Builder browserBuilder : builders) {
+            if (browserBuilder.canBuild(userAgent)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public Browser build(UserAgent userAgent, int confidenceTreshold) {
+        List<Browser> founds = new ArrayList<Browser>();
+        Browser found = null;
+        for (Builder builder : builders) {
+            if (builder.canBuild(userAgent)) {
+                Browser builded = (Browser) builder.build(userAgent, confidenceTreshold);
+                if (builded != null) {
+                    founds.add(builded);
+                    if (builded.getConfidence() >= confidenceTreshold) {
+                        found = builded;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (found != null) {
+            return found;
+
+        } else {
+            if (founds.isEmpty()) {
+                return null;
+            }
+
+            Collections.sort(founds, Collections.reverseOrder());
+            return founds.get(0);
+        }
+    }
+}

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/DefaultBrowserBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/devicemap/trunk/openddr/java/src/org/openddr/simpleapi/oddr/builder/browser/DefaultBrowserBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL