mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-12-14 06:51:08 +01:00
Prefix subprojects with 'smack-'
instead of using the old baseName=smack appendix=project.name approach, we are now going convention over configuration and renaming the subprojects directories to the proper name. Having a prefix is actually very helpful, because the resulting libraries will be named like the subproject. And a core-4.0.0-rc1.jar is not as explicit about what it actually *is* as a smack-core-4.0.0-rc1.jar. SMACK-265
This commit is contained in:
parent
b6fb1f3743
commit
91fd15ad86
758 changed files with 42 additions and 42 deletions
|
|
@ -0,0 +1,294 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* 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.iqprivate;
|
||||
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smackx.iqprivate.packet.DefaultPrivateData;
|
||||
import org.jivesoftware.smackx.iqprivate.packet.PrivateData;
|
||||
import org.jivesoftware.smackx.iqprivate.provider.PrivateDataProvider;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* 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:
|
||||
*
|
||||
* <pre>
|
||||
* <color xmlns="http://example.com/xmpp/color">
|
||||
* <favorite>blue</blue>
|
||||
* <leastFavorite>puce</leastFavorite>
|
||||
* </color>
|
||||
* </pre>
|
||||
*
|
||||
* {@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.<p>
|
||||
*
|
||||
* Warning: this is an non-standard protocol documented by
|
||||
* <a href="http://www.jabber.org/jeps/jep-0049.html">JEP-49</a>. Because this is a
|
||||
* non-standard protocol, it is subject to change.
|
||||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public class PrivateDataManager extends Manager {
|
||||
private static final Map<XMPPConnection, PrivateDataManager> instances = new WeakHashMap<XMPPConnection, PrivateDataManager>();
|
||||
|
||||
public static synchronized PrivateDataManager getInstanceFor(XMPPConnection connection) {
|
||||
PrivateDataManager privateDataManager = instances.get(connection);
|
||||
if (privateDataManager == null) {
|
||||
privateDataManager = new PrivateDataManager(connection);
|
||||
}
|
||||
return privateDataManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map of provider instances.
|
||||
*/
|
||||
private static Map<String, PrivateDataProvider> privateDataProviders = new Hashtable<String, PrivateDataProvider>();
|
||||
|
||||
/**
|
||||
* 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:
|
||||
*
|
||||
* <pre>
|
||||
* <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></pre>
|
||||
*
|
||||
* <p>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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new private data manager.
|
||||
*
|
||||
* @param connection an XMPP connection which must have already undergone a
|
||||
* successful login.
|
||||
*/
|
||||
private PrivateDataManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
instances.put(connection, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.<p>
|
||||
*
|
||||
* 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 XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
*/
|
||||
public PrivateData getPrivateData(final String elementName, final String namespace) throws NoResponseException, XMPPErrorException, NotConnectedException
|
||||
{
|
||||
// Create an IQ packet to get the private data.
|
||||
IQ privateDataGet = new IQ() {
|
||||
public String getChildElementXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<query xmlns=\"jabber:iq:private\">");
|
||||
buf.append("<").append(elementName).append(" xmlns=\"").append(namespace).append("\"/>");
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
};
|
||||
privateDataGet.setType(IQ.Type.GET);
|
||||
|
||||
PrivateDataResult response = (PrivateDataResult) connection().createPacketCollectorAndSend(
|
||||
privateDataGet).nextResultOrThrow();
|
||||
return response.getPrivateData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a private data value. Each chunk of private data is uniquely identified by an
|
||||
* element name and namespace pair. If private data has already been set with the
|
||||
* element name and namespace, then the new private data will overwrite the old value.
|
||||
*
|
||||
* @param privateData the private data.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
*/
|
||||
public void setPrivateData(final PrivateData privateData) throws NoResponseException, XMPPErrorException, NotConnectedException {
|
||||
// Create an IQ packet to set the private data.
|
||||
IQ privateDataSet = new IQ() {
|
||||
public String getChildElementXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<query xmlns=\"jabber:iq:private\">");
|
||||
buf.append(privateData.toXML());
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
};
|
||||
privateDataSet.setType(IQ.Type.SET);
|
||||
|
||||
connection().createPacketCollectorAndSend(privateDataSet).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String key for a given element name and namespace.
|
||||
*
|
||||
* @param elementName the element name.
|
||||
* @param namespace the namespace.
|
||||
* @return a unique key for the element name and namespace pair.
|
||||
*/
|
||||
private static String getProviderKey(String elementName, String namespace) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<").append(elementName).append("/><").append(namespace).append("/>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* An IQ provider to parse IQ results containing private data.
|
||||
*/
|
||||
public static class PrivateDataIQProvider implements IQProvider {
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
PrivateData privateData = null;
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
String elementName = parser.getName();
|
||||
String namespace = parser.getNamespace();
|
||||
// See if any objects are registered to handle this private data type.
|
||||
PrivateDataProvider provider = getPrivateDataProvider(elementName, namespace);
|
||||
// If there is a registered provider, use it.
|
||||
if (provider != null) {
|
||||
privateData = provider.parsePrivateData(parser);
|
||||
}
|
||||
// Otherwise, use a DefaultPrivateData instance to store the private data.
|
||||
else {
|
||||
DefaultPrivateData data = new DefaultPrivateData(elementName, namespace);
|
||||
boolean finished = false;
|
||||
while (!finished) {
|
||||
int event = parser.next();
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
String name = parser.getName();
|
||||
// If an empty element, set the value with the empty string.
|
||||
if (parser.isEmptyElementTag()) {
|
||||
data.setValue(name,"");
|
||||
}
|
||||
// Otherwise, get the the element text.
|
||||
else {
|
||||
event = parser.next();
|
||||
if (event == XmlPullParser.TEXT) {
|
||||
String value = parser.getText();
|
||||
data.setValue(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals(elementName)) {
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
privateData = data;
|
||||
}
|
||||
}
|
||||
else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getName().equals("query")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new PrivateDataResult(privateData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An IQ packet to hold PrivateData GET results.
|
||||
*/
|
||||
private static class PrivateDataResult extends IQ {
|
||||
|
||||
private PrivateData privateData;
|
||||
|
||||
PrivateDataResult(PrivateData privateData) {
|
||||
this.privateData = privateData;
|
||||
}
|
||||
|
||||
public PrivateData getPrivateData() {
|
||||
return privateData;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<query xmlns=\"jabber:iq:private\">");
|
||||
if (privateData != null) {
|
||||
privateData.toXML();
|
||||
}
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* 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.iqprivate.packet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Default implementation of the PrivateData interface. Unless a PrivateDataProvider
|
||||
* is registered with the PrivateDataManager class, instances of this class will be
|
||||
* returned when getting private data.<p>
|
||||
*
|
||||
* This class provides a very simple representation of an XML sub-document. Each element
|
||||
* is a key in a Map with its CDATA being the value. For example, given the following
|
||||
* XML sub-document:
|
||||
*
|
||||
* <pre>
|
||||
* <foo xmlns="http://bar.com">
|
||||
* <color>blue</color>
|
||||
* <food>pizza</food>
|
||||
* </foo></pre>
|
||||
*
|
||||
* In this case, getValue("color") would return "blue", and getValue("food") would
|
||||
* return "pizza". This parsing mechanism mechanism is very simplistic and will not work
|
||||
* as desired in all cases (for example, if some of the elements have attributes. In those
|
||||
* cases, a custom {@link org.jivesoftware.smackx.iqprivate.provider.PrivateDataProvider} should be used.
|
||||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public class DefaultPrivateData implements PrivateData {
|
||||
|
||||
private String elementName;
|
||||
private String namespace;
|
||||
private Map<String, String> map;
|
||||
|
||||
/**
|
||||
* Creates a new generic private data object.
|
||||
*
|
||||
* @param elementName the name of the element of the XML sub-document.
|
||||
* @param namespace the namespace of the element.
|
||||
*/
|
||||
public DefaultPrivateData(String elementName, String namespace) {
|
||||
this.elementName = elementName;
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML element name of the private data sub-packet root element.
|
||||
*
|
||||
* @return the XML element name of the packet extension.
|
||||
*/
|
||||
public String getElementName() {
|
||||
return elementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML namespace of the private data sub-packet root element.
|
||||
*
|
||||
* @return the XML namespace of the packet extension.
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<").append(elementName).append(" xmlns=\"").append(namespace).append("\">");
|
||||
for (String name : getNames()) {
|
||||
String value = getValue(name);
|
||||
buf.append("<").append(name).append(">");
|
||||
buf.append(value);
|
||||
buf.append("</").append(name).append(">");
|
||||
}
|
||||
buf.append("</").append(elementName).append(">");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Set of the names that can be used to get
|
||||
* values of the private data.
|
||||
*
|
||||
* @return a Set of the names.
|
||||
*/
|
||||
public synchronized Set<String> getNames() {
|
||||
if (map == null) {
|
||||
return Collections.<String>emptySet();
|
||||
}
|
||||
return Collections.unmodifiableSet(map.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value given a name.
|
||||
*
|
||||
* @param name the name.
|
||||
* @return the value.
|
||||
*/
|
||||
public synchronized String getValue(String name) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
return (String)map.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value given the name.
|
||||
*
|
||||
* @param name the name.
|
||||
* @param value the value.
|
||||
*/
|
||||
public synchronized void setValue(String name, String value) {
|
||||
if (map == null) {
|
||||
map = new HashMap<String,String>();
|
||||
}
|
||||
map.put(name, value);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* 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.iqprivate.packet;
|
||||
|
||||
/**
|
||||
* Interface to represent private data. Each private data chunk is an XML sub-document
|
||||
* with a root element name and namespace.
|
||||
*
|
||||
* @see org.jivesoftware.smackx.iqprivate.PrivateDataManager
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public interface PrivateData {
|
||||
|
||||
/**
|
||||
* Returns the root element name.
|
||||
*
|
||||
* @return the element name.
|
||||
*/
|
||||
public String getElementName();
|
||||
|
||||
/**
|
||||
* Returns the root element XML namespace.
|
||||
*
|
||||
* @return the namespace.
|
||||
*/
|
||||
public String getNamespace();
|
||||
|
||||
/**
|
||||
* Returns the XML reppresentation of the PrivateData.
|
||||
*
|
||||
* @return the private data as XML.
|
||||
*/
|
||||
public String toXML();
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* 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.iqprivate.provider;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.jivesoftware.smackx.iqprivate.packet.PrivateData;
|
||||
|
||||
/**
|
||||
* An interface for parsing custom private data. Each PrivateDataProvider must
|
||||
* be registered with the PrivateDataManager class for it to be used. Every implementation
|
||||
* of this interface <b>must</b> have a public, no-argument constructor.
|
||||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public interface PrivateDataProvider {
|
||||
|
||||
/**
|
||||
* Parse the private data sub-document and create a PrivateData instance. At the
|
||||
* beginning of the method call, the xml parser will be positioned at the opening
|
||||
* tag of the private data child element. At the end of the method call, the parser
|
||||
* <b>must</b> be positioned on the closing tag of the child element.
|
||||
*
|
||||
* @param parser an XML parser.
|
||||
* @return a new PrivateData instance.
|
||||
* @throws Exception if an error occurs parsing the XML.
|
||||
*/
|
||||
public PrivateData parsePrivateData(XmlPullParser parser) throws Exception;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue