/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source 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. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */ package com.caucho.xmpp.pubsub; import com.caucho.vfs.*; import com.caucho.xmpp.*; import java.io.*; import java.util.*; import java.util.logging.*; import javax.xml.stream.*; /** * pubsub query * * XEP-0060: http://www.xmpp.org/extensions/xep-0060.html * * <code><pre> * namespace = http://jabber.org/protocol/pubsub * * element pubsub { * (create, configure?) * | (subscribe?, options?) * | affiliations * | items * | publish * | retract * | subscription * | subscriptions * | unsubscribe * } * * element affiliation { * attribute affiliation, * attribute node * } * * element affiliations { * affiliation* * } * * element configure { * x{jabber:x:data}? * } * * element create { * attribute node? * } * * element item { * attribute id?, * * other? * } * * element items { * attribute max_items?, * attribute node, * attribute subid?, * * item* * } * * element options { * attribute address, * attribute node?, * attribute subid?, * * x{jabber:x:data}* * } * * element publish { * attribute node, * * item* * } * * element retract { * attribute node, * attribute notify?, * * item+ * } * * element subscribe { * attribute address, * attribute node? * } * * element subscribe-options { * required? * } * * element subscription { * attribute address, * attribute node?, * attribute subid?, * attribute subscription?, * * subscribe-options? * } * * element unsubscribe { * attribute address, * attribute node? * attribute subid? * } * </pre></code> */ public class XmppPubSubQueryMarshal extends AbstractXmppMarshal { private static final Logger log = Logger.getLogger(XmppPubSubQueryMarshal.class.getName()); private static final boolean _isFinest = log.isLoggable(Level.FINEST); /** * Returns the namespace uri for the XMPP stanza value */ public String getNamespaceURI() { return "http://jabber.org/protocol/pubsub"; } /** * Returns the local name for the XMPP stanza value */ public String getLocalName() { return "pubsub"; } /** * Returns the java classname of the object */ public String getClassName() { return null; } /** * Serializes the object to XML */ public void toXml(XmppStreamWriter out, Serializable object) throws IOException, XMLStreamException { throw new UnsupportedOperationException(); } /** * Deserializes the object from XML */ public Serializable fromXml(XmppStreamReader in) throws IOException, XMLStreamException { boolean isFinest = log.isLoggable(Level.FINEST); PubSubQuery query = null; int tag = in.nextTag(); while (tag > 0) { if (isFinest) debug(in); if (XMLStreamReader.END_ELEMENT == tag) { return query; } if (XMLStreamReader.START_ELEMENT == tag && "options".equals(in.getLocalName())) { PubSubOptions options = parseOptions(in); if (query instanceof PubSubSubscribeQuery) { PubSubSubscribeQuery subscribe = (PubSubSubscribeQuery) query; subscribe.setOptions(options); } else log.fine(this + " options with no subscribe: " + query); } else if (XMLStreamReader.START_ELEMENT == tag && "items".equals(in.getLocalName())) { query = parseItems(in); } else if (XMLStreamReader.START_ELEMENT == tag && "publish".equals(in.getLocalName())) { query = parsePublish(in); } else if (XMLStreamReader.START_ELEMENT == tag && "subscribe".equals(in.getLocalName())) { query = parseSubscribe(in); } else if (XMLStreamReader.START_ELEMENT == tag && "unsubscribe".equals(in.getLocalName())) { query = parseUnsubscribe(in); } else if (XMLStreamReader.START_ELEMENT == tag) { log.finer(this + " <" + in.getLocalName() + "> is an unknown tag"); skipToEnd(in, in.getLocalName()); } tag = in.nextTag(); } return null; } /** * Deserializes the object from XML */ public PubSubItemsQuery parseItems(XmppStreamReader in) throws IOException, XMLStreamException { String node = in.getAttributeValue(null, "node"); String subid = in.getAttributeValue(null, "subid"); String maxItemsString = in.getAttributeValue(null, "max-items"); int maxItems = 0; if (maxItemsString != null) maxItems = Integer.parseInt(maxItemsString); PubSubItemsQuery items = new PubSubItemsQuery(node, subid, maxItems); ArrayList<PubSubItem> itemList = new ArrayList<PubSubItem>(); int tag = in.nextTag(); while (tag > 0) { if (_isFinest) debug(in); if (XMLStreamReader.END_ELEMENT == tag) { items.setItemList(itemList); return items; } if (XMLStreamReader.START_ELEMENT == tag && "item".equals(in.getLocalName())) { itemList.add(parseItem(in)); } else if (XMLStreamReader.START_ELEMENT == tag) { log.finer(this + " <" + in.getLocalName() + "> is an unknown tag"); skipToEnd(in, in.getLocalName()); } tag = in.nextTag(); } skipToEnd(in, "items"); return items; } /** * Deserializes the object from XML */ public PubSubPublishQuery parsePublish(XmppStreamReader in) throws IOException, XMLStreamException { String node = in.getAttributeValue(null, "node"); PubSubPublishQuery pubsub = new PubSubPublishQuery(node); /* ArrayList<DataValue> valueList = new ArrayList<DataValue>(); ArrayList<DataOption> optionList = new ArrayList<DataOption>(); */ int tag = in.nextTag(); while (tag > 0) { if (_isFinest) debug(in); if (XMLStreamReader.END_ELEMENT == tag) { return pubsub; } if (XMLStreamReader.START_ELEMENT == tag && "item".equals(in.getLocalName())) { pubsub.setItem(parseItem(in)); } else if (XMLStreamReader.START_ELEMENT == tag) { log.finer(this + " <" + in.getLocalName() + "> is an unknown tag"); skipToEnd(in, in.getLocalName()); } tag = in.nextTag(); } skipToEnd(in, "publish"); return pubsub; } /** * Deserializes the object from XML */ public PubSubSubscribeQuery parseSubscribe(XmppStreamReader in) throws IOException, XMLStreamException { String address = in.getAttributeValue(null, "address"); String node = in.getAttributeValue(null, "node"); PubSubSubscribeQuery subscribe = new PubSubSubscribeQuery(address, node); skipToEnd(in, "subscribe"); return subscribe; } /** * Deserializes the object from XML */ public PubSubUnsubscribeQuery parseUnsubscribe(XmppStreamReader in) throws IOException, XMLStreamException { String address = in.getAttributeValue(null, "address"); String node = in.getAttributeValue(null, "node"); String subid = in.getAttributeValue(null, "subid"); PubSubUnsubscribeQuery unsubscribe = new PubSubUnsubscribeQuery(address, node, subid); skipToEnd(in, "unsubscribe"); return unsubscribe; } /** * Deserializes the object from XML */ public PubSubOptions parseOptions(XmppStreamReader in) throws IOException, XMLStreamException { String address = in.getAttributeValue(null, "address"); String node = in.getAttributeValue(null, "node"); String subid = in.getAttributeValue(null, "subid"); PubSubOptions options = new PubSubOptions(address, node, subid); skipToEnd(in, "options"); return options; } private PubSubItem parseItem(XmppStreamReader in) throws IOException, XMLStreamException { String id = in.getAttributeValue(null, "id"); PubSubItem item = new PubSubItem(id); int tag = in.next(); Serializable value = in.readValue(); item.setValue(value); skipToEnd(in, "item"); return item; } }