📄 wbxmltools.java
字号:
/** * Copyright (C) 2003-2004 Funambol * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package sync4j.framework.tools;import java.io.*;import java.util.Vector;import org.kxml.parser.ParseEvent;import org.kxml.parser.XmlParser;import org.kxml.parser.Tag;import org.kxml.wap.SyncMLWriter;import org.kxml.wap.SyncMLParser;import org.kxml.Xml;import org.kxml.Attribute;import sync4j.framework.core.SyncML;import sync4j.framework.core.Util;import sync4j.framework.core.Sync4jException;import org.jibx.runtime.*;import org.jibx.runtime.impl.*;import org.apache.commons.lang.StringUtils;/** * Utility class for WBXML stuff * * @author Stefano Fornari * @version $Id: WBXMLTools.java,v 1.12 2004/06/01 19:50:48 luigiafassina Exp $ */public class WBXMLTools { // --------------------------------------------------------------- Constants public static final String WELL_KNOWN_NS = ",DevInf,"; // ------------------------------------------------------------ Private data private static String verDTD; // ---------------------------------------------------------- Public methods /** * Converts a string to a WBXML message. * * @param s the String to convert - NOT NULL * * @return the WBXML message * * @throws Sync4jException in case of parser errors */ public static byte[] toWBXML(final String s) throws Sync4jException { SyncMLWriter writer = null; try { writer = new SyncMLWriter(verDTD); XmlParser xml = new XmlParser(new StringReader(s)); traverseXML(xml, writer); } catch (IOException e) { throw new Sync4jException(e.getMessage(), e); } finally { if (writer != null) try {writer.close();} catch (Exception e) {} } return writer.getBytes(); } /** * Encodes a <i>Message</i> to WBXML * <p> * The message is fixed before encoding in order to get a converted message * that makes sense. For instance, the Meta type of a Results element (if * there is any), must be changed from <code>application/vnd.syncml-devinf+xml</code> * to <code>application/vnd.syncml-devinf+wbxml</code> * * @param msg the message to encode * * @return the encoded stream of bytes (as a byte[] buffer). * * @throws Sync4jException in case of errors */ public static byte[] toWBXML(SyncML msg) throws Sync4jException { verDTD = msg.getSyncHdr().getVerDTD().getValue(); try { ByteArrayOutputStream bout = new ByteArrayOutputStream(); IBindingFactory f = BindingDirectory.getFactory(SyncML.class); IMarshallingContext c = f.createMarshallingContext(); c.setIndent(0); c.marshalDocument(msg, "UTF-8", null, bout); String inputXml = new String(bout.toByteArray()); return toWBXML(inputXml); } catch(Exception e) { e.printStackTrace(); } return null; } /** * Converts a WBXML message into the corresponding XML message. * * @param msg the message to convert - NOT NULL * * @return the XML message or NULL if an error occurred * * @throws Sync4jException in case of parser errors */ public static String wbxmlToXml(final byte[] msg) throws Sync4jException { ByteArrayInputStream in = null; try { in = new ByteArrayInputStream(msg); SyncMLParser parser = new SyncMLParser(in); return parseWBXML(parser); } catch (Throwable t) { throw new Sync4jException(t.getMessage(), t); } } public static boolean isWellKnownNamespace(String ns) { return (WELL_KNOWN_NS.indexOf(',' + ns + ',') >= 0); } // --------------------------------------------------------- Private methods private static void traverseXML(XmlParser parser, SyncMLWriter writer) throws IOException { // // NOTE: when the namespace changes in one of the namespaces listed // in WELL_KNOWN_NS, a well known document must be inserted; // therefore a new inner writer is created when the tag is opened // and its content flushed in the original writer when the tag is // closed // boolean leave = false; do { ParseEvent event = parser.read(); switch (event.getType()) { case Xml.START_TAG: SyncMLWriter tagWriter = null; String name = event.getName(); if (isWellKnownNamespace(name)) { tagWriter = new SyncMLWriter(((Tag)event).getNamespace(), verDTD); } else { tagWriter = writer; } // see API doc of StartTag for more access methods tagWriter.startTag(name); traverseXML(parser, tagWriter); // recursion if (tagWriter != writer) { tagWriter.close(); writer.writeOpaque(new String(tagWriter.getBytes())); tagWriter = null; } break; case Xml.END_TAG: writer.endTag(); leave = true; break; case Xml.END_DOCUMENT: leave = true; break; case Xml.TEXT: writer.write(event.getText()); break; case Xml.WHITESPACE: break; default: } } while (!leave); } private static String parseWBXML(SyncMLParser parser) throws IOException { boolean[] inTag = new boolean[3]; return parseWBXML(parser, inTag); } private static String parseWBXML(SyncMLParser parser, boolean[] inTag) throws IOException{ StringBuffer buf=new StringBuffer(); boolean leave = false; String tagName = null; String text = null; do { ParseEvent event = parser.read(); switch (event.getType()) { case Xml.START_TAG: tagName = event.getName(); buf.append("<"); buf.append(tagName); Vector attrs=event.getAttributes(); if(attrs!=null){ for(int i=0;i<attrs.size();i++){ Attribute attr=(Attribute)attrs.elementAt(i); buf.append(" "); buf.append(attr.getName()); buf.append("='"); buf.append(attr.getValue()); buf.append("'"); } } buf.append(">"); if (!inTag[0]) { inTag[0] = ("Put".equals(tagName) || "Results".equals(tagName)); } if (!inTag[0]) { if (!inTag[1]) { inTag[1] = "Item".equals(tagName); } else if (inTag[1]) { inTag[2] = "Data".equals(tagName); } } text = parseWBXML(parser, inTag); buf.append(text); break; case Xml.END_TAG: buf.append("</"); buf.append(event.getName()); buf.append(">"); leave = true; break; case Xml.END_DOCUMENT: leave = true; break; case Xml.TEXT: buf.append(event.getText()); break; case Xml.WAP_EXTENSION: text = event.getText(); if (!inTag[0] && inTag[1] && inTag[2]) { text = replaceDataContent(text); } buf.append(text); break; case Xml.WHITESPACE: break; default: } } while (!leave); return buf.toString(); } /** * Replace not permitted characters with their HTML codification. * * @param text the data content * * @return text the data content modified */ private static String replaceDataContent(String text) { text = StringUtils.replace(text, "&", "&"); text = StringUtils.replace(text, "<", "<"); text = StringUtils.replace(text, ">", ">"); text = StringUtils.replace(text, "\"", """); return text; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -