/** * $RCSfile$ * $Revision$ * $Date$ * * Copyright 2003-2004 Jive Software. * * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.smackx; import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.SmackConfiguration; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smackx.packet.DefaultPrivateData; import org.jivesoftware.smackx.packet.PrivateData; import org.jivesoftware.smackx.provider.PrivateDataProvider; import org.xmlpull.v1.XmlPullParser; import java.util.Hashtable; import java.util.Map; /** * Manages private data, which is a mechanism to allow users to store arbitrary XML * data on an XMPP server. Each private data chunk is defined by a element name and * XML namespace. Example private data: * *
* <color xmlns="http://example.com/xmpp/color"> * <favorite>blue</blue> * <leastFavorite>puce</leastFavorite> * </color> ** * {@link PrivateDataProvider} instances are responsible for translating the XML into objects. * If no PrivateDataProvider is registered for a given element name and namespace, then * a {@link DefaultPrivateData} instance will be returned.
* * Warning: this is an non-standard protocol documented by * JEP-49. Because this is a * non-standard protocol, it is subject to change. * * @author Matt Tucker */ public class PrivateDataManager { /** * Map of provider instances. */ private static Map privateDataProviders = new Hashtable(); /** * Returns the private data provider registered to the specified XML element name and namespace. * For example, if a provider was registered to the element name "prefs" and the * namespace "http://www.xmppclient.com/prefs", then the following packet would trigger * the provider: * *
* <iq type='result' to='joe@example.com' from='mary@example.com' id='time_1'> * <query xmlns='jabber:iq:private'> * <prefs xmlns='http://www.xmppclient.com/prefs'> * <value1>ABC</value1> * <value2>XYZ</value2> * </prefs> * </query> * </iq>* *
Note: this method is generally only called by the internal Smack classes. * * @param elementName the XML element name. * @param namespace the XML namespace. * @return the PrivateData provider. */ public static PrivateDataProvider getPrivateDataProvider(String elementName, String namespace) { String key = getProviderKey(elementName, namespace); return (PrivateDataProvider)privateDataProviders.get(key); } /** * Adds a private data provider with the specified element name and name space. The provider * will override any providers loaded through the classpath. * * @param elementName the XML element name. * @param namespace the XML namespace. * @param provider the private data provider. */ public static void addPrivateDataProvider(String elementName, String namespace, PrivateDataProvider provider) { String key = getProviderKey(elementName, namespace); privateDataProviders.put(key, provider); } /** * Removes a private data provider with the specified element name and namespace. * * @param elementName The XML element name. * @param namespace The XML namespace. */ public static void removePrivateDataProvider(String elementName, String namespace) { String key = getProviderKey(elementName, namespace); privateDataProviders.remove(key); } private XMPPConnection connection; /** * The user to get and set private data for. In most cases, this value should * be null, as the typical use of private data is to get and set * your own private data and not others. */ private String user; /** * Creates a new private data manager. The connection must have * undergone a successful login before being used to construct an instance of * this class. * * @param connection an XMPP connection which must have already undergone a * successful login. */ public PrivateDataManager(XMPPConnection connection) { if (!connection.isAuthenticated()) { throw new IllegalStateException("Must be logged in to XMPP server."); } this.connection = connection; } /** * Creates a new private data manager for a specific user (special case). Most * servers only support getting and setting private data for the user that * authenticated via the connection. However, some servers support the ability * to get and set private data for other users (for example, if you are the * administrator). The connection must have undergone a successful login before * being used to construct an instance of this class. * * @param connection an XMPP connection which must have already undergone a * successful login. * @param user the XMPP address of the user to get and set private data for. */ public PrivateDataManager(XMPPConnection connection, String user) { if (!connection.isAuthenticated()) { throw new IllegalStateException("Must be logged in to XMPP server."); } this.connection = connection; this.user = user; } /** * Returns the private data specified by the given element name and namespace. Each chunk * of private data is uniquely identified by an element name and namespace pair.
*
* If a PrivateDataProvider is registered for the specified element name/namespace pair then
* that provider will determine the specific object type that is returned. If no provider
* is registered, a {@link DefaultPrivateData} instance will be returned.
*
* @param elementName the element name.
* @param namespace the namespace.
* @return the private data.
* @throws XMPPException if an error occurs getting the private data.
*/
public PrivateData getPrivateData(final String elementName, final String namespace)
throws XMPPException
{
// Create an IQ packet to get the private data.
IQ privateDataGet = new IQ() {
public String getChildElementXML() {
StringBuilder buf = new StringBuilder();
buf.append("