⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 didlparser.java

📁 android_UPNP_DLNA_控制点
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2011 Teleal GmbH, Switzerland * * This program 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, either version 3 of * the License, or (at your option) any later version. * * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. */package org.teleal.cling.support.contentdirectory;import org.teleal.cling.model.types.Datatype;import org.teleal.cling.model.types.InvalidValueException;import org.teleal.cling.support.model.DIDLAttribute;import org.teleal.cling.support.model.DIDLContent;import org.teleal.cling.support.model.DIDLObject;import org.teleal.cling.support.model.DescMeta;import org.teleal.cling.support.model.Person;import org.teleal.cling.support.model.PersonWithRole;import org.teleal.cling.support.model.ProtocolInfo;import org.teleal.cling.support.model.Res;import org.teleal.cling.support.model.StorageMedium;import org.teleal.cling.support.model.WriteStatus;import org.teleal.cling.support.model.container.Container;import org.teleal.cling.support.model.item.Item;import org.teleal.common.io.IO;import org.teleal.common.util.Exceptions;import org.teleal.common.xml.SAXParser;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.Attributes;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.transform.OutputKeys;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import java.io.InputStream;import java.io.StringReader;import java.io.StringWriter;import java.net.URI;import java.util.logging.Level;import java.util.logging.Logger;import static org.teleal.cling.model.XMLUtil.appendNewElement;import static org.teleal.cling.model.XMLUtil.appendNewElementIfNotNull;/** * DIDL parser based on SAX for reading and DOM for writing. * <p> * This parser requires Android platform level 8 (2.2). * </p> * <p> * Override the {@link #createDescMetaHandler(org.teleal.cling.support.model.DescMeta, org.teleal.common.xml.SAXParser.Handler)} * method to read vendor extension content of {@code <desc>} elements. You then should also override the * {@link #populateDescMetadata(org.w3c.dom.Element, org.teleal.cling.support.model.DescMeta)} method for writing. * </p> * <p> * Override the {@link #createItemHandler(org.teleal.cling.support.model.item.Item, org.teleal.common.xml.SAXParser.Handler)} * etc. methods to register custom handlers for vendor-specific elements and attributes within items, containers, * and so on. * </p> * * @author Christian Bauer * @author Mario Franco */public class DIDLParser extends SAXParser {    final private static Logger log = Logger.getLogger(DIDLParser.class.getName());    /**     * Uses the current thread's context classloader to read and unmarshall the given resource.     *     * @param resource The resource on the classpath.     * @return The unmarshalled DIDL content model.     * @throws Exception     */    public DIDLContent parseResource(String resource) throws Exception {        InputStream is = null;        try {            is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);            return parse(IO.readLines(is));        } finally {            if (is != null) is.close();        }    }    /**     * Reads and unmarshalls an XML representation into a DIDL content model.     *     * @param xml The XML representation.     * @return A DIDL content model.     * @throws Exception     */    public DIDLContent parse(String xml) throws Exception {        if (xml == null || xml.length() == 0) {            throw new RuntimeException("Null or empty XML");        }        DIDLContent content = new DIDLContent();        createRootHandler(content, this);        log.fine("Parsing DIDL XML content");        parse(new InputSource(new StringReader(xml)));        return content;    }    protected RootHandler createRootHandler(DIDLContent instance, SAXParser parser) {        return new RootHandler(instance, parser);    }    protected ContainerHandler createContainerHandler(Container instance, Handler parent) {        return new ContainerHandler(instance, parent);    }    protected ItemHandler createItemHandler(Item instance, Handler parent) {        return new ItemHandler(instance, parent);    }    protected ResHandler createResHandler(Res instance, Handler parent) {        return new ResHandler(instance, parent);    }    protected DescMetaHandler createDescMetaHandler(DescMeta instance, Handler parent) {        return new DescMetaHandler(instance, parent);    }    protected Container createContainer(Attributes attributes) {        Container container = new Container();        container.setId(attributes.getValue("id"));        container.setParentID(attributes.getValue("parentID"));        if ((attributes.getValue("childCount") != null))            container.setChildCount(Integer.valueOf(attributes.getValue("childCount")));        try {            Boolean value = (Boolean)Datatype.Builtin.BOOLEAN.getDatatype().valueOf(                    attributes.getValue("restricted")            );            if (value != null)                container.setRestricted(value);            value = (Boolean)Datatype.Builtin.BOOLEAN.getDatatype().valueOf(                    attributes.getValue("searchable")            );            if (value != null)                container.setSearchable(value);        } catch (Exception ex) {            // Ignore        }        return container;    }    protected Item createItem(Attributes attributes) {        Item item = new Item();        item.setId(attributes.getValue("id"));        item.setParentID(attributes.getValue("parentID"));        try {            Boolean value = (Boolean)Datatype.Builtin.BOOLEAN.getDatatype().valueOf(                    attributes.getValue("restricted")            );            if (value != null)                item.setRestricted(value);        } catch (Exception ex) {            // Ignore        }        if ((attributes.getValue("refID") != null))            item.setRefID(attributes.getValue("refID"));        return item;    }    protected Res createResource(Attributes attributes) {        Res res = new Res();        if (attributes.getValue("importUri") != null)            res.setImportUri(URI.create(attributes.getValue("importUri")));        try {            res.setProtocolInfo(                    new ProtocolInfo(attributes.getValue("protocolInfo"))            );        } catch (InvalidValueException ex) {            log.warning("In DIDL content, invalid resource protocol info: " + Exceptions.unwrap(ex));            return null;        }        if (attributes.getValue("size") != null)            res.setSize(Long.valueOf(attributes.getValue("size")));        if (attributes.getValue("duration") != null)            res.setDuration(attributes.getValue("duration"));        if (attributes.getValue("bitrate") != null)            res.setBitrate(Long.valueOf(attributes.getValue("bitrate")));        if (attributes.getValue("sampleFrequency") != null)            res.setSampleFrequency(Long.valueOf(attributes.getValue("sampleFrequency")));        if (attributes.getValue("bitsPerSample") != null)            res.setBitsPerSample(Long.valueOf(attributes.getValue("bitsPerSample")));        if (attributes.getValue("nrAudioChannels") != null)            res.setNrAudioChannels(Long.valueOf(attributes.getValue("nrAudioChannels")));        if (attributes.getValue("colorDepth") != null)            res.setColorDepth(Long.valueOf(attributes.getValue("colorDepth")));        if (attributes.getValue("protection") != null)            res.setProtection(attributes.getValue("protection"));        if (attributes.getValue("resolution") != null)            res.setResolution(attributes.getValue("resolution"));        return res;    }    protected DescMeta createDescMeta(Attributes attributes) {        DescMeta desc = new DescMeta();        desc.setId(attributes.getValue("id"));        if ((attributes.getValue("type") != null))            desc.setType(attributes.getValue("type"));        if ((attributes.getValue("nameSpace") != null))            desc.setNameSpace(URI.create(attributes.getValue("nameSpace")));        return desc;    }    /* ############################################################################################# */    /**     * Generates a XML representation of the content model.     * <p>     * Items inside a container will <em>not</em> be represented in the XML, the containers     * will be rendered flat without children.     * </p>     *     * @param content The content model.     * @return An XML representation.     * @throws Exception     */    public String generate(DIDLContent content) throws Exception {        return generate(content, false);    }    /**     * Generates an XML representation of the content model.     * <p>     * Optionally, items inside a container will be represented in the XML,     * the container elements then have nested item elements. Although this     * parser can read such a structure, it is unclear whether other DIDL     * parsers should and actually do support this XML.     * </p>     *     * @param content     The content model.     * @param nestedItems <code>true</code> if nested item elements should be rendered for containers.     * @return An XML representation.     * @throws Exception     */    public String generate(DIDLContent content, boolean nestedItems) throws Exception {        return documentToString(buildDOM(content, nestedItems), true);    }    // TODO: Yes, this only runs on Android 2.2    protected String documentToString(Document document, boolean omitProlog) throws Exception {        TransformerFactory transFactory = TransformerFactory.newInstance();        // Indentation not supported on Android 2.2        //transFactory.setAttribute("indent-number", 4);        Transformer transformer = transFactory.newTransformer();        if (omitProlog) {            // TODO: UPNP VIOLATION: Terratec Noxon Webradio fails when DIDL content has a prolog            // No XML prolog! This is allowed because it is UTF-8 encoded and required            // because broken devices will stumble on SOAP messages that contain (even            // encoded) XML prologs within a message body.            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");        }        // Again, Android 2.2 fails hard if you try this.        //transformer.setOutputProperty(OutputKeys.INDENT, "yes");        StringWriter out = new StringWriter();        transformer.transform(new DOMSource(document), new StreamResult(out));        return out.toString();    }    protected Document buildDOM(DIDLContent content, boolean nestedItems) throws Exception {        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();        factory.setNamespaceAware(true);        Document d = factory.newDocumentBuilder().newDocument();        generateRoot(content, d, nestedItems);        return d;    }    protected void generateRoot(DIDLContent content, Document descriptor, boolean nestedItems) {        Element rootElement = descriptor.createElementNS(DIDLContent.NAMESPACE_URI, "DIDL-Lite");        descriptor.appendChild(rootElement);        // rootElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:didl", DIDLContent.NAMESPACE_URI);        rootElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:upnp", DIDLObject.Property.UPNP.NAMESPACE.URI);        rootElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:dc", DIDLObject.Property.DC.NAMESPACE.URI);        for (Container container : content.getContainers()) {            if (container == null) continue;            generateContainer(container, descriptor, rootElement, nestedItems);        }        for (Item item : content.getItems()) {            if (item == null) continue;            generateItem(item, descriptor, rootElement);        }        for (DescMeta descMeta : content.getDescMetadata()) {            if (descMeta == null) continue;            generateDescMetadata(descMeta, descriptor, rootElement);        }    }    protected void generateContainer(Container container, Document descriptor, Element parent, boolean nestedItems) {        if (container.getTitle() == null) {            throw new RuntimeException("Missing 'dc:title' element for container: " + container.getId());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -