From 46cebe5e9ee479932f020cb04847ac38bf7d8c0e Mon Sep 17 00:00:00 2001 From: rcollier Date: Wed, 28 Oct 2009 22:41:14 +0000 Subject: [PATCH] Added support for SHIM headers git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@11347 b35dd754-fafc-0310-a699-88a17e54d16e --- .../jivesoftware/smackx/packet/Header.java | 59 ++++++++ .../smackx/packet/HeadersExtension.java | 69 +++++++++ .../smackx/provider/HeaderProvider.java | 44 ++++++ .../smackx/provider/HeadersProvider.java | 37 +++++ .../smack/test/SmackTestCase.java | 131 +++++++++++++----- 5 files changed, 306 insertions(+), 34 deletions(-) create mode 100644 source/org/jivesoftware/smackx/packet/Header.java create mode 100644 source/org/jivesoftware/smackx/packet/HeadersExtension.java create mode 100644 source/org/jivesoftware/smackx/provider/HeaderProvider.java create mode 100644 source/org/jivesoftware/smackx/provider/HeadersProvider.java diff --git a/source/org/jivesoftware/smackx/packet/Header.java b/source/org/jivesoftware/smackx/packet/Header.java new file mode 100644 index 000000000..3fa838662 --- /dev/null +++ b/source/org/jivesoftware/smackx/packet/Header.java @@ -0,0 +1,59 @@ +/* + * 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.packet; + +import org.jivesoftware.smack.packet.PacketExtension; + +/** + * Represents a Header entry as specified by the Stanza Headers and Internet Metadata (SHIM) + + * @author Robin Collier + */ +public class Header implements PacketExtension +{ + private String name; + private String value; + + public Header(String name, String value) + { + this.name = name; + this.value = value; + } + + public String getName() + { + return name; + } + + public String getValue() + { + return value; + } + + public String getElementName() + { + return "header"; + } + + public String getNamespace() + { + return HeadersExtension.NAMESPACE; + } + + public String toXML() + { + return "
" + value + "
"; + } + +} diff --git a/source/org/jivesoftware/smackx/packet/HeadersExtension.java b/source/org/jivesoftware/smackx/packet/HeadersExtension.java new file mode 100644 index 000000000..78564dbbf --- /dev/null +++ b/source/org/jivesoftware/smackx/packet/HeadersExtension.java @@ -0,0 +1,69 @@ +/** + * 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.packet; + +import java.util.Collection; +import java.util.Collections; + +import org.jivesoftware.smack.packet.PacketExtension; + +/** + * Extension representing a list of headers as specified in Stanza Headers and Internet Metadata (SHIM) + * + * @see Header + * + * @author Robin Collier + */ +public class HeadersExtension implements PacketExtension +{ + public static final String NAMESPACE = "http://jabber.org/protocol/shim"; + + private Collection
headers = Collections.EMPTY_LIST; + + public HeadersExtension(Collection
headerList) + { + if (headerList != null) + headers = headerList; + } + + public Collection
getHeaders() + { + return headers; + } + + public String getElementName() + { + return "headers"; + } + + public String getNamespace() + { + return NAMESPACE; + } + + public String toXML() + { + StringBuilder builder = new StringBuilder("<" + getElementName() + " xmlns='" + getNamespace() + "'>"); + + for (Header header : headers) + { + builder.append(header.toXML()); + } + builder.append("'); + + return builder.toString(); + } + +} diff --git a/source/org/jivesoftware/smackx/provider/HeaderProvider.java b/source/org/jivesoftware/smackx/provider/HeaderProvider.java new file mode 100644 index 000000000..7344880ab --- /dev/null +++ b/source/org/jivesoftware/smackx/provider/HeaderProvider.java @@ -0,0 +1,44 @@ +/** + * 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.provider; + +import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.provider.PacketExtensionProvider; +import org.jivesoftware.smackx.packet.Header; +import org.xmlpull.v1.XmlPullParser; + +/** + * Parses the header element as defined in Stanza Headers and Internet Metadata (SHIM). + * + * @author Robin Collier + */ +public class HeaderProvider implements PacketExtensionProvider +{ + public PacketExtension parseExtension(XmlPullParser parser) throws Exception + { + String name = parser.getAttributeValue(null, "name"); + String value = null; + + parser.next(); + + if (parser.getEventType() == XmlPullParser.TEXT) + value = parser.getText(); + + while(parser.getEventType() != XmlPullParser.END_TAG) + parser.next(); + + return new Header(name, value); + } + +} diff --git a/source/org/jivesoftware/smackx/provider/HeadersProvider.java b/source/org/jivesoftware/smackx/provider/HeadersProvider.java new file mode 100644 index 000000000..056dd5826 --- /dev/null +++ b/source/org/jivesoftware/smackx/provider/HeadersProvider.java @@ -0,0 +1,37 @@ +/** + * 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.provider; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smackx.packet.Header; +import org.jivesoftware.smackx.packet.HeadersExtension; + +/** + * Parses the headers element as defined in Stanza Headers and Internet Metadata (SHIM). + * + * @author Robin Collier + */ +public class HeadersProvider extends EmbeddedExtensionProvider +{ + @Override + protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map attributeMap, List content) + { + return new HeadersExtension((Collection
)content); + } + +} diff --git a/test/org/jivesoftware/smack/test/SmackTestCase.java b/test/org/jivesoftware/smack/test/SmackTestCase.java index cacb70483..5caef5f7c 100644 --- a/test/org/jivesoftware/smack/test/SmackTestCase.java +++ b/test/org/jivesoftware/smack/test/SmackTestCase.java @@ -23,13 +23,17 @@ import junit.framework.TestCase; import org.jivesoftware.smack.ConnectionConfiguration; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.XMPPError; +import org.jivesoftware.smack.packet.XMPPError.Type; import org.xmlpull.mxp1.MXParser; import org.xmlpull.v1.XmlPullParser; import javax.net.SocketFactory; import java.io.InputStream; import java.net.URL; +import java.util.ArrayList; import java.util.Enumeration; +import java.util.List; /** * Base class for all the test cases which provides a pre-configured execution context. This @@ -52,7 +56,10 @@ public abstract class SmackTestCase extends TestCase { private String host = "localhost"; private String serviceName = "localhost"; private int port = 5222; - private String usernamnePrefix = "user"; + private String usernamePrefix = "user"; + private String passwordPrefix; + private boolean samePassword; + private List createdUserIdx = new ArrayList(); private String chatDomain = "chat"; private String mucDomain = "conference"; @@ -136,7 +143,7 @@ public abstract class SmackTestCase extends TestCase { if (index > getMaxConnections()) { throw new IllegalArgumentException("Index out of bounds"); } - return usernamnePrefix + index; + return usernamePrefix + (index + 1); } /** @@ -209,22 +216,39 @@ public abstract class SmackTestCase extends TestCase { // that will not resolve as a network connection. host = connections[0].getHost(); serviceName = connections[0].getServiceName(); - // Create the test accounts - if (!getConnection(0).getAccountManager().supportsAccountCreation()) - fail("Server does not support account creation"); - + for (int i = 0; i < getMaxConnections(); i++) { - // Create the test account - try { - getConnection(i).getAccountManager().createAccount(usernamnePrefix + i, usernamnePrefix + i); - } catch (XMPPException e) { - // Do nothing if the accout already exists - if (e.getXMPPError() == null || e.getXMPPError().getCode() != 409) { - throw e; - } - } - // Login with the new test account - getConnection(i).login(usernamnePrefix + i, usernamnePrefix + i, "Smack"); + String password = usernamePrefix + (i+1); + String currentUser = password; + + if (passwordPrefix != null) + password = (samePassword ? passwordPrefix : passwordPrefix + (i+1)); + + try + { + getConnection(i).login(currentUser, password, "Smack"); + } + catch (XMPPException e) + { + e.printStackTrace(); + + // Create the test accounts + if (!getConnection(0).getAccountManager().supportsAccountCreation()) + fail("Server does not support account creation"); + + // Create the account and try logging in again as the + // same user. + try + { + createAccount(i, currentUser, password); + } + catch (Exception e1) + { + e1.printStackTrace(); + fail("Could not create user: " + currentUser); + } + i--; + } } // Let the server process the available presences Thread.sleep(150); @@ -235,26 +259,61 @@ public abstract class SmackTestCase extends TestCase { } } - protected void tearDown() throws Exception { + protected void connectAndLogin(int connectionIndex) throws XMPPException + { + String password = usernamePrefix + connectionIndex; + + if (passwordPrefix != null) + password = (samePassword ? passwordPrefix : passwordPrefix + connectionIndex); + + XMPPConnection con = getConnection(connectionIndex); + + if (!con.isConnected()) + con.connect(); + con.login(usernamePrefix + connectionIndex, password, "Smack"); + } + + protected void disconnect(int connectionIndex) throws XMPPException + { + getConnection(connectionIndex).disconnect(); + } + + private void createAccount(int connectionIdx, String username, String password) + { + // Create the test account + try { + getConnection(connectionIdx).getAccountManager().createAccount(username, password); + createdUserIdx.add(connectionIdx); + } catch (XMPPException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + protected void tearDown() throws Exception { super.tearDown(); - for (int i = 0; i < getMaxConnections(); i++) { - try { - // If not connected, connect so that we can delete the account. - if (!getConnection(i).isConnected()) { - XMPPConnection con = getConnection(i); - con.connect(); - con.login(getUsername(i), getUsername(i)); + for (int i = 0; i < getMaxConnections(); i++) + { + if (createdUserIdx.contains(i)) + { + try { + // If not connected, connect so that we can delete the account. + if (!getConnection(i).isConnected()) { + XMPPConnection con = getConnection(i); + con.connect(); + con.login(getUsername(i), getUsername(i)); + } + else if (!getConnection(i).isAuthenticated()) { + getConnection(i).login(getUsername(i), getUsername(i)); + } + // Delete the created account for the test + getConnection(i).getAccountManager().deleteAccount(); } - else if (!getConnection(i).isAuthenticated()) { - getConnection(i).login(getUsername(i), getUsername(i)); + catch (Exception e) { + e.printStackTrace(); } - // Delete the created account for the test - getConnection(i).getAccountManager().deleteAccount(); - } - catch (Exception e) { - e.printStackTrace(); - } + } if (getConnection(i).isConnected()) { // Close the connection getConnection(i).disconnect(); @@ -334,7 +393,11 @@ public abstract class SmackTestCase extends TestCase { mucDomain = parser.nextText(); } else if (parser.getName().equals("username")) { - usernamnePrefix = parser.nextText(); + usernamePrefix = parser.nextText(); + } + else if (parser.getName().equals("password")) { + samePassword = "true".equals(parser.getAttributeValue(0)); + passwordPrefix = parser.nextText(); } } eventType = parser.next();