Tamkovich.com: Телеком/VoIP блог
Современные технологии: Asterisk, SIP, Kamailio, Linux, Cisco, Linksys
Опыт использования OpenDDR
10 июня, 2014 by rius
Программирование java, opensource На днях у меня возникла необходимость получить в java-приложении описание мобильного устройства по содержимому заголовка User-Agent, которым представляется устройство. Выбор пал на библиотеку OpenDDR (OpenDDR official site ).
Лучшая инструкция, которая мне попалась: инструкция
Для свежей версии требуется поправка при установке в локальный репозиторий:
mvn install:install-file -DgroupId=org.openddr.simpleapi.oddr -DartifactId=OpenDDR-Simple-API -Dversion=1.0.0.27 -Dpackaging=jar -Dfile=OpenDDR-Simple-API-1.0.0.27.jar -DgeneratePom=true -DcreateChecksum=true |
Библиотека openddr мне не понравилась по нескольким причинам:
- Ручные шаги по установке: распаковка архива, добавление артифактов в локальный репозиторий мавена, копирование XML файлов
- Громоздкий синтаксис
- Неявная зависимость slf4j, которую надо добавлять в свой pom.xml
- библиотека не находила описания некоторых устройств, хотя они есть в ее XML словаре (например, «bravo»)
Структура XML файла в архиве openddr с официального сайта (содержит описания мобильных устройств) для разбора такая:
<ODDR> <version> <ver>1.27</ver> <last_updated>2014-03-28 09:31:00</last_updated> <official_url>openddr.org</official_url> <maintainers> </maintainers> <authors> </authors> <statement> <![CDATA[ Copyright 2011 OpenDDR LLC This file is made available under the terms of the Open Database License: http://opendatacommons.org/licenses/odbl/1.0/. Any rights in individual contents of the database are licensed under the Database Contents License: http://opendatacommons.org/licenses/dbcl/1.0/ ]]> </statement> </version> <Devices> <device id="SAMSUNG-SGH-i780" parentId="genericSamsung"> <property name="model" value="SGH-i780"/> <property name="displayWidth" value="320"/> <property name="displayHeight" value="320"/> <property name="mobile_browser" value="Microsoft Mobile Explorer"/> <property name="mobile_browser_version" value="7.7"/> <property name="device_os" value="Windows Mobile OS"/> <property name="device_os_version" value="6.0"/> <property name="inputDevices" value="touchscreen"/> <property name="ajax_support_javascript" value="true"/> <property name="xhtml_format_as_css_property" value="true"/> <property name="from" value="open_db_modified"/> </device> … <device id="Nokia5530c" parentId="genericNokia"> <property name="model" value="5530c"/> <property name="marketing_name" value="XpressMusic"/> <property name="displayWidth" value="360"/> <property name="displayHeight" value="640"/> <property name="mobile_browser" value="Safari"/> <property name="dual_orientation" value="true"/> <property name="device_os" value="Symbian OS"/> <property name="device_os_version" value="9.4"/> <property name="nokia_series" value="60"/> <property name="nokia_edition" value="5"/> <property name="inputDevices" value="touchscreen"/> <property name="ajax_support_javascript" value="true"/> <property name="ajax_support_getelementbyid" value="true"/> <property name="ajax_support_inner_html" value="true"/> <property name="ajax_manipulate_dom" value="true"/> <property name="ajax_manipulate_css" value="true"/> <property name="ajax_support_events" value="true"/> <property name="ajax_support_event_listener" value="true"/> <property name="xhtml_format_as_css_property" value="true"/> <property name="from" value="open_db_modified"/> </device> … </Devices> </ODDR> |
Я решил не тащить к себе в приложение все вышеперечисленные недостатки библиотеки и написать свой XML парсер. Он делает проход по файлу и возвращает HashMap
Код парсера:
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; import javax.xml.namespace.QName; import java.util.Map; import java.util.HashMap; /* Парсер обрабатывает файл DeviceDataSource.xml поставляемый в библиотеке OpenDDR. Вам нужно скачать с офф сайта OpenDDR-Java-<version>.zip и скопировать файл из папки /resources */ @SuppressWarnings("unchecked") public class OpenDDRXMLParser { static final String MARKETING_NAME = "marketing_name"; static final String ID = "id"; static final String PROPERTY = "property"; static final String DEVICE = "device"; static final String NAME = "name"; static final String VALUE = "value"; static Map<String, String> parse (String pathToXML){ Map<String, String> dict = new HashMap <String, String>(); try { XMLInputFactory inputFactory = XMLInputFactory.newInstance(); // Setup a new eventReader InputStream in = new FileInputStream(pathToXML); XMLEventReader eventReader = inputFactory.createXMLEventReader(in); // read the XML document String deviceName = ""; String marketingName = ""; while (eventReader.hasNext()) { XMLEvent event = eventReader.nextEvent(); if (event.isStartElement() ) { StartElement startElement = event.asStartElement(); if (startElement.getName().getLocalPart().equals(DEVICE)) { deviceName = startElement.getAttributeByName(new QName(ID)).getValue(); } else if (startElement.getName().getLocalPart().equals(PROPERTY) && startElement.getAttributeByName(new QName(NAME)).getValue().equals(MARKETING_NAME)) { // Мы хотим сохранить marketing_name marketingName = startElement.getAttributeByName(new QName(VALUE)).getValue(); } } // Мы достигли конца элемента <device> </device> и если в нем был marketing_name, то сохраним его if (event.isEndElement()) { EndElement endElement = event.asEndElement(); if (endElement.getName().getLocalPart().equals(DEVICE)) { if (!deviceName.equals("") && !marketingName.equals("")) { String added = dict.put(deviceName, marketingName); if (added != null) { System.out.println("Failed to add, probably this key already exists: <" + deviceName + ", " + marketingName + ">"); } } deviceName = ""; marketingName = ""; } } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (XMLStreamException e) { e.printStackTrace(); } return dict; } } |
Анализ файла DeviceDataSource.xml с описаниями показал, что для трех устройств описания дублированы:
Failed to add, probably this key already exists: LG-SU880, Optimus EX
Failed to add, probably this key already exists: SGH-I257M, Galaxy S4 Mini
Failed to add, probably this key already exists: XT937C, Moto G
Причем в случае устройства XT937C параметр «model» отличается в описаниях.
Программирование java, opensource

Сайт хороший жалко загнулся