XmlToObject
package com.zx.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import net.sourceforge.wurfl.core.resource.ModelDevice;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.zx.dao.WurflDao;
public class XmlToObject {
private String filePath="wurfl.xml";
public void parseXml()
{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser;
ClassLoader loader=XmlToObject.class.getClassLoader();
URL url =loader.getResource(filePath);
try {
parser = factory.newSAXParser();
InputStream in = new FileInputStream(new File(url.getFile()));
parser.parse(in, new MySAXHandler());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args)
{
XmlToObject xmlToObject=new XmlToObject();
xmlToObject.parseXml();
}
}
class MySAXHandler extends DefaultHandler
{
static int count=0;
// ModelDevicePojo currentDevice=null;
ModelDevice currentDevice=null;
String userAgent;
String id;
String fallBack;
boolean specific;
boolean actualDeviceRoot;
Map<String,String> capabilities=null;
Map<String,String> groupsByCapability=null;
String groupsid;
String capabilityName;
String capabilityValue;
long start=0;
long end=0;
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("==wurfl.xml==");
end=System.currentTimeMillis();
// System.out.println("device:"+deviceList.size());
// System.out.println("first device groups:"+deviceList.get(0).getGroups().size());
// System.out.println("first device first group capabilitys:"+deviceList.get(0).getGroups().get(0).getCapabilitys().size());
//WurflDao.set(deviceList.subList(0,100));
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
// TODO Auto-generated method stub
if(name.equals("device"))
{
// currentDevice=new ModelDevice(userAgent, id, fallBack,
// actualDeviceRoot, capabilities, groupsByCapability);
currentDevice = new ModelDevice.Builder(id, userAgent,
fallBack).setActualDeviceRoot(actualDeviceRoot).setSpecific(specific)
.setCapabilities(capabilities).setCapabilitiesByGroup(
groupsByCapability).build();
System.out.println("-------------------"+(++count)+"---------------");
WurflDao.set(currentDevice);
capabilities=null;
groupsByCapability=null;
currentDevice=null;
}else if(name.equals("group"))
{
}else if(name.equals("capability"))
{
groupsByCapability.put(capabilityName, groupsid);
capabilities.put(capabilityName, capabilityValue);
}
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("==");
start=System.currentTimeMillis();
}
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
System.out.println(name);
int len=attributes.getLength();
if(name.equals("device"))
{
if(groupsByCapability==null)
{
groupsByCapability=new HashMap<String,String>();
}
if(capabilities==null)
{
capabilities=new HashMap<String,String>();
}
for(int i=0;i<len;i++)
{
String attrName=attributes.getQName(i);
String attrValue=attributes.getValue(i);
// System.out.println(attrName+":"+attrValue);
if(attrName.equals("id"))
{
this.id=attrValue;
}else if(attrName.equals("user_agent"))
{
if(attrValue==null)
{
this.userAgent="";
}else
{
this.userAgent=attrValue;
}
}else if(attrName.equals("fall_back"))
{
this.fallBack=attrValue;
}else if(attrName.equals("actual_device_root"))
{
if(attrValue.equals("true"))
{
this.actualDeviceRoot=true;
}else
{
this.actualDeviceRoot=false;
}
}else if(attrName.equals("specific"))
{
// this.specific=specific;
if(attrValue.equals("true"))
{
this.specific=true;
}else
{
this.specific=false;
}
}
}
}else if(name.equals("group"))
{
for(int i=0;i<len;i++)
{
String attrName=attributes.getQName(i);
String attrValue=attributes.getValue(i);
if(attrName.equals("id"))
{
this.groupsid=attrValue;
}
}
}else if(name.equals("capability"))
{
for(int i=0;i<len;i++)
{
String attrName=attributes.getQName(i);
String attrValue=attributes.getValue(i);
if(attrName.equals("name"))
{
capabilityName=attrValue;
}else if(attrName.equals("value"))
{
capabilityValue=attrValue;
}
}
}
}
}
XMLResource
/**
* Copyright (c) 2011 ScientiaMobile Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Refer to the COPYING file distributed with this package.
*/
package net.sourceforge.wurfl.core.resource;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.text.StrBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;
/**
* XMLResource
* <p/>
* <p>
* XMLResource represent a source of wurfl repository backed by XML file. XML
* file can be root file or patch. The XML file can be compresses by gzip or
* zip. In case of zip, the first entry will be processed.
* </p>
* <p/>
* <p>
* The given path can be URL or filesystem path. The URL support classpath
* scheme to load file from java classpath.
* </p>
*
* @author Fantayeneh Asres Gizaw
* @author Filippo De Luca
* @version $Id: XMLResource.java 668 2011-06-14 07:07:44Z ermanno.franco $
*/
public class XMLResource implements WURFLResource {
private static final Logger logger = LoggerFactory.getLogger(XMLResource.class);
private URI uri;
private InputStream stream;
/**
* Build Resource by path. The path can be URI or filesystem path.
*
* @param path The path of source file.
*/
public XMLResource(String path) {
Validate.notEmpty(path, "The path must be not empty");
try {
uri = createURI(path);
} catch (URISyntaxException e) {
throw new WURFLResourceException(this, e);
}
}
/**
* Build resource by File.
*
* @param file The source File
*/
public XMLResource(File file) {
Validate.notNull(file, "The file must be not null");
uri = file.toURI();
}
/**
* Build resource by URI. It handle the 'classpath' schema also.
*
* @param uri The source URI
*/
public XMLResource(URI uri) {
Validate.notNull(uri, "The URI must be not null");
this.uri = uri;
}
/**
* Build resource by InputStream. The builded resource can be reloadable
* only if the given stream is resettable (the maskSupported method returns
* true).
*
* @param stream The source stream.
*/
public XMLResource(InputStream stream) {
Validate.notNull(stream, "The stream must be not null");
this.stream = stream;
}
// Access methods *****************************************************
/**
* {@inheritDoc}
*/
public ResourceData getData() {
if (stream == null) {
if (uri != null) {
stream = openInputStream(uri);
} else {
throw new WURFLResourceException(this,
"The resource can not be read, the stream is null");
}
}
ResourceData data = readData(stream);
if (stream.markSupported()) {
try {
stream.reset();
} catch (IOException e) {
releaseStream();
}
} else {
releaseStream();
}
return data;
}
/**
* {@inheritDoc}
* <p/>
* If this resource is created using InputStream, the info will return
* Stream resource'.
*/
public String getInfo() {
String info = null;
if (uri != null) {
info = uri.toString();
} else {
info = "Stream resource";
}
return info;
}
/**
* {@inheritDoc}
*/
public void release() {
if (stream != null) {
releaseStream();
}
uri = null;
}
/**
* Return if this resource can be reloaded.
*
* @return true if can be reloaded, false otherwise.
*/
public boolean isReloadable() {
boolean isStreamResettable = stream != null && stream.markSupported();
return isStreamResettable || uri != null;
}
// Helper methods *****************************************************
/**
* Creates a URI from the given String. If the path can be an URI
* representation or a filesystem path. It handle the Windows path also.
*/
public static URI createURI(String path) throws URISyntaxException {
assert StringUtils.isNotBlank(path) : "The path must be not blank";
URI createdURI = null;
if (logger.isDebugEnabled()) {
logger.debug("looking for a local file: " + path);
}
File f = new File(path);
if (f.exists() && f.isFile() && f.canRead()) {
createdURI = f.toURI();
} else {
if (logger.isDebugEnabled()) {
logger.debug(path + " not found in local filesystem, looking for other");
}
StrBuilder workingPathBuilder = new StrBuilder(path);
workingPathBuilder.replaceAll(" ", "%20");
// FIXME where the path must be normalized?
if (SystemUtils.IS_OS_WINDOWS && StringUtils.contains(path, "\\")) {
logger.debug("Encoding windows URI");
workingPathBuilder.replaceAll("\\\\", "/");
}
// The path doesn't represent an URI yet, perhaps a Intranet resource?
if (!workingPathBuilder.contains(':')) {
while (workingPathBuilder.startsWith("/")) {
workingPathBuilder = workingPathBuilder.deleteCharAt(0);
}
workingPathBuilder.insert(0, "file:///");
}
// Assumes the path is an URI
createdURI = URI.create(workingPathBuilder.toString());
}
if (logger.isDebugEnabled()) {
logger.debug("Created URI: " + createdURI + " from path: " + path);
}
return createdURI;
}
/**
* Convert spaces to "%20"
*
* @param location Location to convert.
* @return converted location.
* @deprecated use {@link XMLResource#createURI(String)}
*/
public static URI toURI(String location) throws URISyntaxException {
return new URI(StringUtils.replace(location, " ", "%20"));
}
/**
* Opens the InputStream by giving URI. The given URI support the
* 'classpath' schema also.
*
* @param uri The given URI
* @return The InputStream opened from the given URI
*/
protected InputStream openInputStream(URI uri) {
InputStream input = null;
try {
URI resourceURI = resourceURI(uri);
URLConnection connection = resourceURI.toURL().openConnection();
if (resourceURI.getPath().endsWith(".zip")) {
input = fromZipFile(connection.getInputStream());
} else if (resourceURI.getPath().endsWith(".gz")) {
input = new GZIPInputStream(connection.getInputStream());
} else {
input = connection.getInputStream();
}
} catch (IOException e) {
logger.error("Error opening stream URI:" + uri.toString());
throw new WURFLResourceException(this, e);
}
logger.debug("Opened stream from URI: " + uri);
return input;
}
private InputStream fromZipFile(InputStream inputStream) throws IOException {
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
zipInputStream.getNextEntry();
return zipInputStream;
}
private URI resourceURI(final URI uri) throws MalformedURLException {
if (uri.getScheme().equals("classpath")) {
StrBuilder pathBuilder = new StrBuilder();
pathBuilder.append(uri.toString());
pathBuilder.replaceFirst("classpath:", "");
return URI.create(getClass().getResource(pathBuilder.toString())
.toString());
}
return uri;
}
/**
* Read the ResourceData from given stream.
*
* @param input The stream to read data from.
* @return Read ResourceData.
*/
protected ResourceData readData(InputStream input) {
WURFLSAXHandler handler = new WURFLSAXHandler();
try {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(input, handler);
} catch (Exception e) {
throw new WURFLResourceException(this, e);
}
String name = getInfo();
String version = handler.getVer();
boolean patch = handler.isPatch();
ModelDevices devices = handler.getDevices();
ResourceData data = new ResourceData(name, version, patch, devices);
logger.debug("Readed data: " + data);
return data;
}
private void releaseStream() {
try {
stream.close();
} catch (IOException e) {
logger.warn("Error closing stream");
}
stream = null;
}
// Helper classes *****************************************************
static class WURFLSAXHandler extends DefaultHandler {
// XML costants ***************************************************
private static final String ELEM_WURFL = "wurfl";
private static final String ELEM_WURFL_PATCH = "wurfl_patch";
private static final String ELEM_DEVICE = "device";
private static final String ELEM_GROUP = "group";
private static final String ELEM_CAPABILITY = "capability";
private static final String ELEM_VER = "ver";
private static final String ATTR_DEVICE_ID = "id";
private static final String ATTR_DEVICE_FALLBACK = "fall_back";
private static final String ATTR_DEVICE_USERAGENT = "user_agent";
private static final String ATTR_DEVICE_ACTUALDEVICEROOT = "actual_device_root";
private static final String ATTR_DEVICE_SPECIFIC = "specific";
private static final String ATTR_GROUP_ID = "id";
private static final String ATTR_CAPABILITY_NAME = "name";
private static final String ATTR_CAPABILITY_VALUE = "value";
// Memebers *******************************************************
private String userAgent;
private String deviceID;
private String fallBack;
private boolean actualDeviceRoot;
private boolean specific;
private String groupID;
private String capabilityName;
private String capabilityValue;
private Set userAgents;
private Set devicesId;
private Map capabilities;
private Map capabilitiesByGroup;
private ModelDevices devices;
private final Map/*String, ModelDevice*/ rootDevices = new HashMap();
private String ver;
private boolean insideVer = false;
private boolean patch = false;
private boolean root = false;
// Access methods *************************************************
public String getVer() {
return ver;
}
public ModelDevices getDevices() {
return devices;
}
public Set getRootDevices() {
return new HashSet(rootDevices.values());
}
public boolean isPatch() {
return patch;
}
// Parser methods *************************************************
public void startDocument() throws SAXException {
super.startDocument();
userAgents = new HashSet();
devicesId = new HashSet();
devices = new ModelDevices();
}
public void endDocument() throws SAXException {
}
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
if (ELEM_DEVICE.equals(name)) {
deviceStartElement(attributes);
} else if (ELEM_GROUP.equals(name)) {
startGroupElement(attributes);
} else if (ELEM_CAPABILITY.equals(name)) {
startCapabilityElement(attributes);
} else if (ELEM_VER.equals(name)) {
startVerElement();
} else if (ELEM_WURFL_PATCH.equals(name)) {
startWurflPatchElement();
} else if (ELEM_WURFL.equals(name)) {
startWurflElement();
}
}
public void endElement(String uri, String localName, String name)
throws SAXException {
if (ELEM_GROUP.equals(name)) {
endGroupElement();
} else if (ELEM_DEVICE.equals(name)) {
endDeviceElement();
} else if (ELEM_VER.equals(name)) {
endVerElement();
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
if (insideVer) {
charsVer(ch, start, length);
}
}
private void startWurflElement() {
if (patch || root) {
throw new WURFLParsingException(
"Root element already defined: wurfl");
}
root = true;
}
private void startWurflPatchElement() {
if (patch || root) {
throw new WURFLParsingException(
"Root element already defined: wurfl_patch");
}
patch = true;
}
private void startVerElement() {
insideVer = true;
}
public void charsVer(char[] ch, int start, int length) {
StrBuilder verBuilder = new StrBuilder();
verBuilder.append(ch, start, length);
ver = verBuilder.toString();
}
private void endVerElement() {
insideVer = false;
}
private void deviceStartElement(Attributes attributes) {
userAgent = attributes.getValue(ATTR_DEVICE_USERAGENT);
deviceID = attributes.getValue(ATTR_DEVICE_ID);
fallBack = attributes.getValue(ATTR_DEVICE_FALLBACK);
actualDeviceRoot = Boolean.valueOf(
attributes.getValue(ATTR_DEVICE_ACTUALDEVICEROOT))
.booleanValue();
specific = Boolean.valueOf(attributes.getValue(ATTR_DEVICE_SPECIFIC))
.booleanValue();
// check if the user agent and device id are valid values
if (StringUtils.isEmpty(deviceID)) {
throw new WURFLParsingException("device id is not a valid");
}
if (!"generic".equals(deviceID) && StringUtils.isEmpty(userAgent)) {
StringBuffer msg = new StringBuffer();
msg.append("Device with id ").append(deviceID).append(
" has an invalid user agent");
throw new WURFLParsingException(msg.toString());
}
// check if the device id and the user_agent are unique
if (devicesId.contains(deviceID)) {
throw new WURFLParsingException("device id " + deviceID
+ " already defined!!!");
}
if (userAgents.contains(userAgent)) {
throw new WURFLParsingException("user agent [" + userAgent
+ "] already defined");
}
userAgents.add(userAgent);
devicesId.add(deviceID);
capabilities = new HashMap();
capabilitiesByGroup = new HashMap();
}
private void endDeviceElement() {
ModelDevice device = new ModelDevice.Builder(deviceID, userAgent,
fallBack).setActualDeviceRoot(actualDeviceRoot).setSpecific(specific)
.setCapabilities(capabilities).setCapabilitiesByGroup(
capabilitiesByGroup).build();
devices.add(device);
if (device.isActualDeviceRoot()) rootDevices.put(deviceID, device);
}
private void startCapabilityElement(Attributes attributes) {
capabilityName = attributes.getValue(ATTR_CAPABILITY_NAME);
capabilityValue = attributes.getValue(ATTR_CAPABILITY_VALUE);
if (StringUtils.isEmpty(capabilityName) || null == capabilityValue) {
throw new WURFLParsingException("device with id " + deviceID
+ " has capability with name or value not valid");
}
if (capabilities.containsKey(capabilityName)) {
throw new WURFLParsingException("The devices with id "
+ deviceID + " define more " + capabilityName);
}
// intern by Kenny MacLeod
String internCapabilityName = capabilityName.intern();
String internGroupId = groupID.intern();
capabilities.put(internCapabilityName, capabilityValue);
capabilitiesByGroup.put(internCapabilityName, internGroupId);
}
private void startGroupElement(Attributes attributes) {
groupID = attributes.getValue(ATTR_GROUP_ID);
}
private void endGroupElement() {
/* Empty */
}
}
}