├── .gitignore ├── src ├── test │ ├── resources │ │ └── jid-version-tinder1.1.serialized │ └── java │ │ └── org │ │ └── xmpp │ │ ├── component │ │ ├── ThrowExceptionOnGetComponent.java │ │ ├── DummyAbstractComponent.java │ │ ├── SlowRespondingThreadNameComponent.java │ │ ├── AbstractComponentIsConsumerTest.java │ │ ├── AbstractComponentServiceDiscovery.java │ │ └── AbstractComponentRespondsToIQRequestsTest.java │ │ ├── util │ │ └── JIDWeigherTest.java │ │ ├── packet │ │ ├── JIDEqualsHashCodeTest.java │ │ ├── NodePrepTest.java │ │ ├── DomainPrepTest.java │ │ ├── ResourcePrepTest.java │ │ ├── StringPrepCacheTest.java │ │ ├── JIDCreationDomainTest.java │ │ ├── JIDCreationResourceTest.java │ │ ├── JIDCreationNodeTest.java │ │ ├── JIDCachedBareAndFullJIDTest.java │ │ ├── PacketErrorApplicationConditionTest.java │ │ ├── BasicJIDTest.java │ │ ├── JIDSerializabilityTest.java │ │ └── PacketAddressingTest.java │ │ ├── forms │ │ ├── DataFormTest.java │ │ ├── FormFieldGetSetTest.java │ │ └── DataFormAddingFieldsTest.java │ │ └── resultsetmanagement │ │ └── ResultSetTest.java └── main │ └── java │ └── org │ └── xmpp │ ├── muc │ ├── LeaveRoom.java │ ├── JoinRoom.java │ ├── DestroyRoom.java │ ├── Invitation.java │ └── RoomConfiguration.java │ ├── component │ ├── ComponentException.java │ ├── IQResultListener.java │ ├── ComponentManagerFactory.java │ ├── Component.java │ └── ComponentManager.java │ ├── resultsetmanagement │ ├── Result.java │ └── ResultSetImpl.java │ ├── util │ ├── XMPPConstants.java │ ├── JIDWeigher.java │ └── ValueWrapper.java │ └── packet │ └── PacketExtension.java ├── .github ├── dependabot.yml └── workflows │ └── build.yml ├── .editorconfig ├── README.md ├── tinder.doap ├── pom.xml └── LICENSE.html /.gitignore: -------------------------------------------------------------------------------- 1 | # Maven build directory 2 | /target 3 | 4 | # Intellij project files 5 | *.iml 6 | *.idea 7 | -------------------------------------------------------------------------------- /src/test/resources/jid-version-tinder1.1.serialized: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igniterealtime/tinder/HEAD/src/test/resources/jid-version-tinder1.1.serialized -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "monthly" 12 | groups: 13 | github-actions: 14 | patterns: 15 | - '*' 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs. 2 | # 3 | # EditorConfig is awesome: http://EditorConfig.org 4 | 5 | # top-most EditorConfig file 6 | root = true 7 | 8 | [*] 9 | end_of_line = lf 10 | insert_final_newline = true 11 | charset = utf-8 12 | indent_style = space 13 | indent_size = 4 14 | -------------------------------------------------------------------------------- /src/test/java/org/xmpp/component/ThrowExceptionOnGetComponent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.xmpp.component; 17 | 18 | import org.xmpp.packet.IQ; 19 | 20 | /** 21 | * An {@link AbstractComponent} implementation that generates an exception every 22 | * time its {@link #handleIQGet(IQ)} method is called. 23 | *
24 | * This implementation supports the unit tests of Tinder and is not intended for
25 | * production use.
26 | *
27 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
28 | */
29 | public class ThrowExceptionOnGetComponent extends DummyAbstractComponent {
30 |
31 | /**
32 | * Throw an exception
33 | */
34 | @Override
35 | protected IQ handleIQGet(IQ request) throws Exception {
36 | throw new Exception("This exception is expected to be thrown. It is used during unit testing.");
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/util/JIDWeigherTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2019 Ignite Realtime Foundation. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.util;
18 |
19 | import org.junit.Assert;
20 | import org.junit.Test;
21 |
22 | /**
23 | * Various checks that verify the implementation of {@link JIDWeigher}.
24 | *
25 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
26 | */
27 | public class JIDWeigherTest
28 | {
29 | /**
30 | * Asserts that a cache entry of a specific JID has an approximate size.
31 | */
32 | @Test
33 | public void testHappyFlow() {
34 | // Setup fixture.
35 | final JIDWeigher weigher = new JIDWeigher();
36 | final String jid = "jane_john_doe@example.org/this-is-a-resource";
37 | final ValueWrapper
26 | *
27 | * Code example:
28 | *
26 | *
27 | * Code example:
28 | *
30 | *
31 | * When destroying a room it is possible to provide an alternate room which may be replacing the
32 | * room about to be destroyed. It is also possible to provide a reason for the room destruction.
33 | */
34 | @NotThreadSafe
35 | public class DestroyRoom extends IQ {
36 |
37 | /**
38 | * Creates a new DestroyRoom with the reason for the destruction and an alternate room JID.
39 | *
40 | * @param alternateJID JID of the alternate room or
29 | *
30 | * Code example:
31 | *
32 | *
33 | * Code example:
34 | *
62 | *
63 | * The initialization code must not rely on receiving packets from the server since
64 | * the component has not been fully initialized yet. This means that at this point the
65 | * component must not rely on information that is obtained from the server such us
66 | * discovered items.
67 | *
68 | * @param jid the XMPP address that this component is available at.
69 | * @param componentManager the component manager.
70 | * @throws ComponentException if an error occured while initializing the component.
71 | */
72 | void initialize(JID jid, ComponentManager componentManager) throws ComponentException;
73 |
74 | /**
75 | * Notification message indicating that the component will start receiving incoming
76 | * packets. At this time the component may finish pending initialization issues that
77 | * require information obtained from the server.
78 | *
79 | * It is likely that most of the component will leave this method empty.
80 | */
81 | void start();
82 |
83 | /**
84 | * Shuts down this component. All component resources must be released as
85 | * part of shutdown.
86 | */
87 | void shutdown();
88 | }
89 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/NodePrepTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import static org.junit.Assert.assertEquals;
20 |
21 | import org.junit.Test;
22 |
23 | /**
24 | * Verifies {@link JID#nodeprep(String)}.
25 | *
26 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
27 | */
28 | public class NodePrepTest {
29 |
30 | /**
31 | * Basic test that verifies that a string that shouldn't be modified by
32 | * node-prepping gets prepped without a problem.
33 | */
34 | @Test
35 | public void testValidString() throws Exception {
36 | // setup
37 | final String node = "node";
38 |
39 | // do magic
40 | final String result = JID.nodeprep(node);
41 |
42 | // verify
43 | assertEquals(node, result);
44 | }
45 |
46 | /**
47 | * Checks that node-prepping is case insensitive.
48 | */
49 | @Test
50 | public void testCaseSensitivity() throws Exception {
51 | // setup
52 | final String node = "nOdE";
53 |
54 | // do magic
55 | final String result = JID.nodeprep(node);
56 |
57 | // verify
58 | assertEquals(node.toLowerCase(), result);
59 | }
60 |
61 | /**
62 | * Verifies that an input value bigger than 1023 bytes will cause an
63 | * exception to be thrown.
64 | */
65 | @Test(expected = IllegalArgumentException.class)
66 | public void testToLong() throws Exception {
67 | // setup
68 | final StringBuilder builder = new StringBuilder();
69 | for (int i = 0; i < 1024; i++) {
70 | builder.append('a');
71 | }
72 | builder.append('a');
73 | final String toBig = builder.toString();
74 |
75 | // do magic / verify
76 | JID.nodeprep(toBig);
77 | }
78 |
79 | /**
80 | * Verifies that Stringprep mapping is correctly executed. This test uses a
81 | * 'word joiner' character, which is listed on the B1 table of Stringprep.
82 | * Characters on this table must be mapped in resource strings, according to
83 | * RFC 3920. This specific character should be mapped to nothing.
84 | */
85 | @Test
86 | public void testMapping() throws Exception {
87 | // setup;
88 | final String input = "word\u2060joiner";
89 |
90 | // do magic
91 | final String result = JID.nodeprep(input);
92 |
93 | // verify
94 | assertEquals("wordjoiner", result);
95 | }
96 |
97 | /**
98 | * Checks cache usage, by making sure that a subsequent request returns the
99 | * stringprepped answer, not the input data. Input data often equals the
100 | * prepped answer, which allows a bug like this to slip by easily.
101 | */
102 | @Test
103 | public void testCachedResult() throws Exception {
104 | // setup;
105 | final String input = "bword\u2060joiner";
106 |
107 | // do magic
108 | final String result1 = JID.nodeprep(input);
109 | final String result2 = JID.nodeprep(input);
110 |
111 | // verify
112 | assertEquals("bwordjoiner", result1);
113 | assertEquals(result1, result2);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/DomainPrepTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import static org.junit.Assert.assertEquals;
20 |
21 | import org.junit.Test;
22 |
23 | /**
24 | * Verifies {@link JID#domainprep(String)}.
25 | *
26 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
27 | */
28 | public class DomainPrepTest {
29 |
30 | /**
31 | * Basic test that verifies that a string that shouldn't be modified by
32 | * domain-prepping gets prepped without a problem.
33 | */
34 | @Test
35 | public void testValidString() throws Exception {
36 | // setup
37 | final String domain = "domain";
38 |
39 | // do magic
40 | final String result = JID.domainprep(domain);
41 |
42 | // verify
43 | assertEquals(domain, result);
44 | }
45 |
46 | /**
47 | * Checks that domain-prepping is case insensitive.
48 | */
49 | @Test
50 | public void testCaseSensitivity() throws Exception {
51 | // setup
52 | final String domain = "dOmAiN";
53 |
54 | // do magic
55 | final String result = JID.domainprep(domain);
56 |
57 | // verify
58 | assertEquals(domain.toLowerCase(), result);
59 | }
60 |
61 | /**
62 | * Verifies that an input value bigger than 1023 bytes will cause an
63 | * exception to be thrown.
64 | */
65 | @Test(expected = IllegalArgumentException.class)
66 | public void testToLong() throws Exception {
67 | // setup
68 | final StringBuilder builder = new StringBuilder();
69 | for (int i = 0; i < 1023; i++) {
70 | builder.append('a');
71 | }
72 | builder.append(".a");
73 | final String toBig = builder.toString();
74 |
75 | // do magic / verify
76 | JID.domainprep(toBig);
77 | }
78 |
79 | /**
80 | * Verifies that Stringprep mapping is correctly executed. This test uses a
81 | * 'word joiner' character, which is listed on the B1 table of Stringprep.
82 | * Characters on this table must be mapped in resource strings, according to
83 | * RFC 3920. This specific character should be mapped to nothing.
84 | */
85 | @Test
86 | public void testMapping() throws Exception {
87 | // setup;
88 | final String input = "word\u2060joiner";
89 |
90 | // do magic
91 | final String result = JID.domainprep(input);
92 |
93 | // verify
94 | assertEquals("wordjoiner", result);
95 | }
96 |
97 | /**
98 | * Checks cache usage, by making sure that a subsequent request returns the
99 | * stringprepped answer, not the input data. Input data often equals the
100 | * prepped answer, which allows a bug like this to slip by easily.
101 | */
102 | @Test
103 | public void testCachedResult() throws Exception {
104 | // setup;
105 | final String input = "bword\u2060joiner";
106 |
107 | // do magic
108 | final String result1 = JID.domainprep(input);
109 | final String result2 = JID.domainprep(input);
110 |
111 | // verify
112 | assertEquals("bwordjoiner", result1);
113 | assertEquals(result1, result2);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/ResourcePrepTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import static org.junit.Assert.assertEquals;
20 |
21 | import org.junit.Test;
22 |
23 | /**
24 | * Verifies {@link JID#resourceprep(String)}.
25 | *
26 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
27 | */
28 | public class ResourcePrepTest {
29 |
30 | /**
31 | * Basic test that verifies that a string that shouldn't be modified by
32 | * resource-prepping gets prepped without a problem.
33 | */
34 | @Test
35 | public void testValidString() throws Exception {
36 | // setup
37 | final String resource = "resource";
38 |
39 | // do magic
40 | final String result = JID.resourceprep(resource);
41 |
42 | // verify
43 | assertEquals(resource, result);
44 | }
45 |
46 | /**
47 | * Checks that resource-prepping is case sensitive.
48 | */
49 | @Test
50 | public void testCaseSensitivity() throws Exception {
51 | // setup
52 | final String resource = "rEsOuRcE";
53 |
54 | // do magic
55 | final String result = JID.resourceprep(resource);
56 |
57 | // verify
58 | assertEquals(resource, result);
59 | }
60 |
61 | /**
62 | * Verifies that an input value bigger than 1023 bytes will cause an
63 | * exception to be thrown.
64 | */
65 | @Test(expected = IllegalArgumentException.class)
66 | public void testToLong() throws Exception {
67 | // setup
68 | final StringBuilder builder = new StringBuilder();
69 | for (int i = 0; i < 1024; i++) {
70 | builder.append('a');
71 | }
72 | builder.append('a');
73 | final String toBig = builder.toString();
74 |
75 | // do magic / verify
76 | JID.resourceprep(toBig);
77 | }
78 |
79 | /**
80 | * Verifies that Stringprep mapping is correctly executed. This test uses a
81 | * 'word joiner' character, which is listed on the B1 table of Stringprep.
82 | * Characters on this table must be mapped in resource strings, according to
83 | * RFC 3920. This specific character should be mapped to nothing.
84 | */
85 | @Test
86 | public void testMapping() throws Exception {
87 | // setup;
88 | final String input = "word\u2060joiner";
89 |
90 | // do magic
91 | final String result = JID.resourceprep(input);
92 |
93 | // verify
94 | assertEquals("wordjoiner", result);
95 | }
96 |
97 | /**
98 | * Checks cache usage, by making sure that a subsequent request returns the
99 | * stringprepped answer, not the input data. Input data often equals the
100 | * prepped answer, which allows a bug like this to slip by easily.
101 | */
102 | @Test
103 | public void testCachedResult() throws Exception {
104 | // setup;
105 | final String input = "bword\u2060joiner";
106 |
107 | // do magic
108 | final String result1 = JID.resourceprep(input);
109 | final String result2 = JID.resourceprep(input);
110 |
111 | // verify
112 | assertEquals("bwordjoiner", result1);
113 | assertEquals(result1, result2);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/forms/DataFormTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2022 Ignite Realtime Foundation. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.xmpp.forms;
17 |
18 | import org.junit.Test;
19 |
20 | import java.time.LocalDateTime;
21 | import java.time.ZoneId;
22 | import java.time.ZoneOffset;
23 | import java.time.ZonedDateTime;
24 | import java.util.Date;
25 |
26 | import static org.junit.Assert.assertEquals;
27 | import static org.junit.Assert.fail;
28 |
29 | /**
30 | * This test verifies the implementation of {@link DataForm}.
31 | *
32 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
33 | */
34 | public class DataFormTest
35 | {
36 | /**
37 | * Verifies that {@link DataForm#encode(Object)} throws a NullPointerException when the provided input is null.
38 | */
39 | @Test(expected = NullPointerException.class)
40 | public void encodeNull() throws Exception
41 | {
42 | // Set up test fixture.
43 | final Object input = null;
44 |
45 | // Execute System under test.
46 | DataForm.encode(input);
47 |
48 | // Verify results.
49 | fail("A NullPointerException should have been thrown");
50 | }
51 |
52 | /**
53 | * Verifies that {@link DataForm#encode(Object)} returns a String that is equal to a String that is provided as input.
54 | */
55 | @Test
56 | public void encodeString() throws Exception
57 | {
58 | // Set up test fixture.
59 | final Object input = "A string";
60 |
61 | // Execute System under test.
62 | final String result = DataForm.encode(input);
63 |
64 | // Verify results.
65 | assertEquals("A string", result);
66 | }
67 |
68 | /**
69 | * Verifies that {@link DataForm#encode(Object)} returns '1' when the provided input is a boolean 'true'.
70 | */
71 | @Test
72 | public void encodeTrue() throws Exception
73 | {
74 | // Set up test fixture.
75 | final Object input = Boolean.TRUE;
76 |
77 | // Execute System under test.
78 | final String result = DataForm.encode(input);
79 |
80 | // Verify results.
81 | assertEquals("1", result);
82 | }
83 |
84 | /**
85 | * Verifies that {@link DataForm#encode(Object)} returns '0' when the provided input is a boolean 'false'.
86 | */
87 | @Test
88 | public void encodeFalse() throws Exception
89 | {
90 | // Set up test fixture.
91 | final Object input = Boolean.FALSE;
92 |
93 | // Execute System under test.
94 | final String result = DataForm.encode(input);
95 |
96 | // Verify results.
97 | assertEquals("0", result);
98 | }
99 |
100 | /**
101 | * Verifies that {@link DataForm#encode(Object)} returns a String that conforms to a specific format when the input
102 | * that is provided is a Date.
103 | */
104 | @Test
105 | public void encodeDate() throws Exception
106 | {
107 | // Set up test fixture.
108 | final ZonedDateTime zdt = ZonedDateTime.of(1979, 11, 27, 17, 42, 51, 201312, ZoneId.of("+01:00"));
109 | final Object input = Date.from(zdt.toInstant());
110 |
111 | // Execute System under test.
112 | final String result = DataForm.encode(input);
113 |
114 | // Verify results.
115 | assertEquals("19791127T16:42:51", result);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/packet/PacketExtension.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import java.util.Map;
20 | import java.util.concurrent.ConcurrentHashMap;
21 |
22 | import net.jcip.annotations.NotThreadSafe;
23 |
24 | import org.dom4j.DocumentFactory;
25 | import org.dom4j.Element;
26 | import org.dom4j.QName;
27 |
28 | /**
29 | * A packet extension represents a child element of a Packet for a given qualified name. The
30 | * PacketExtension acts as a wrapper on a child element the same way Packet does for a whole
31 | * element. The wrapper provides an easy way to handle the packet extension.
32 | *
33 | * Subclasses of this class can be registered using the static variable
34 | *
24 | * This testcase, amongst others, checks for a bug identified as TINDER-8: If
25 | * the same cache is used to store StringPrep results, a problem might be
26 | * introduced: a particular value might be valid for one identifier of the JID,
27 | * while it is illegal for another identifier of the JID.
28 | *
29 | * Implementation note: do not re-use the same values in different tests. As we
30 | * have no control over the JID cache, we might end up testing against a cached
31 | * value of the cache that's being tested by this JUnit testcase.
32 | *
33 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
34 | * @see Tinder
35 | * bugtracker: TINDER-8
36 | */
37 | public class StringPrepCacheTest {
38 |
39 | /**
40 | * Verifies that when a cached instance is used to construct a JID, no
41 | * unexpected exceptions pop up.
42 | */
43 | @Test
44 | public void testNode() {
45 | new JID("validnode", "validdomain", "validresource");
46 | new JID("validnode", "validdomain", "validresource");
47 | }
48 |
49 | /**
50 | * Verify cache usage, by inserting a value in the cache that's a valid
51 | * node, but an invalid domain identifier. Next, create a JID that uses this
52 | * value for its domain identifier. This JID constructions should fail, but
53 | * will succeed if the cache that was used to store the node-value is the
54 | * same cache that's used to lookup previously stringprepped domain
55 | * identifiers.
56 | */
57 | @Test(expected = IllegalArgumentException.class)
58 | public void testNodeDomainCacheLookup() {
59 | // valid value for node identifier, invalid for domain identifier
60 | final String value = "-test-a-";
61 |
62 | // populate the cache (value is valid in the context of a node)
63 | new JID(value, "validdomain.org", "validresource");
64 |
65 | // verify if the cache gets re-used to lookup value.
66 | new JID("validnode", value, "validresource");
67 | }
68 |
69 | /**
70 | * Verify cache usage, by inserting a value in the cache that's a valid
71 | * resource, but an invalid domain identifier. Next, create a JID that uses
72 | * this value for its domain identifier. This JID constructions should fail,
73 | * but will succeed if the cache that was used to store the resource-value
74 | * is the same cache that's used to lookup previously stringprepped domain
75 | * identifiers.
76 | */
77 | @Test(expected = IllegalArgumentException.class)
78 | public void testResourceDomainCacheLookup() {
79 | // valid value for resource identifier, invalid for domain identifier
80 | final String value = "-test-b-";
81 |
82 | // populate the cache (value is valid in the context of a node)
83 | new JID("validnode", "validdomain.org", value);
84 |
85 | // verify if the cache gets re-used to lookup value.
86 | new JID("validnode", value, "validresource");
87 | }
88 |
89 | /**
90 | * Verify cache usage, by inserting a value in the cache that's a valid
91 | * resource, but an invalid node identifier. Next, create a JID that uses
92 | * this value for its domain identifier. This JID constructions should fail,
93 | * but will succeed if the cache that was used to store the resource-value
94 | * is the same cache that's used to lookup previously stringprepped node
95 | * identifiers.
96 | */
97 | @Test(expected = IllegalArgumentException.class)
98 | public void testResourceNodeCacheLookup() {
99 | // valid value for resource identifier, invalid for nodeidentifier
100 | final String value = "test@c";
101 |
102 | // populate the cache (value is valid in the context of a resource)
103 | new JID("validnode", "validdomain.org", value);
104 |
105 | // verify if the cache gets re-used to lookup value.
106 | new JID(value, "valid_domain", "validresource");
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/JIDCreationDomainTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import static org.junit.Assert.*;
20 |
21 | import org.junit.Test;
22 |
23 | /**
24 | * Tests compliance of {@link JID} with the restrictions defined in RFC-3920 for
25 | * the domain identifier.
26 | *
27 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
28 | * @see RFC 3920 - Extensible
29 | * Messaging and Presence Protocol (XMPP): Core
30 | */
31 | public class JIDCreationDomainTest {
32 |
33 | /**
34 | * A node identifier that's RFC 3920 valid.
35 | */
36 | public static final String NODE = "node";
37 |
38 | /**
39 | * A domain identifier that's RFC 3920 valid.
40 | */
41 | public static final String DOMAIN = "domain";
42 |
43 | /**
44 | * A resource identifier that's RFC 3920 valid.
45 | */
46 | public static final String RESOURCE = "resource";
47 |
48 | /**
49 | * Domain identifiers are a required part of a JID. This testcase
50 | * verifies that node identifiers can be left out of the creation of a JID.
51 | */
52 | @Test
53 | public void testOptionality() throws Exception {
54 | try {
55 | new JID(null);
56 | fail("Domain identifiers should be a required part of "
57 | + "a JID. No exception occurred while trying to "
58 | + "leave out a domain identifier");
59 | } catch (IllegalArgumentException | NullPointerException ex) {
60 | // expected
61 | }
62 |
63 | try {
64 | new JID(null, null, null);
65 | fail("Domain identifiers should be a required part of "
66 | + "a JID. No exception occurred while trying to "
67 | + "leave out a domain identifier");
68 | } catch (IllegalArgumentException | NullPointerException ex) {
69 | // expected
70 | }
71 |
72 | try {
73 | new JID(NODE, null, null);
74 | fail("Domain identifiers should be a required part of "
75 | + "a JID. No exception occurred while trying to "
76 | + "leave out a domain identifier");
77 | } catch (IllegalArgumentException | NullPointerException ex) {
78 | // expected
79 | }
80 |
81 | try {
82 | new JID(null, null, RESOURCE);
83 | fail("Domain identifiers should be a required part of "
84 | + "a JID. No exception occurred while trying to "
85 | + "leave out a domain identifier");
86 | } catch (IllegalArgumentException | NullPointerException ex) {
87 | // expected
88 | }
89 |
90 | try {
91 | new JID(NODE, null, RESOURCE);
92 | fail("Domain identifiers should be a required part of "
93 | + "a JID. No exception occurred while trying to "
94 | + "leave out a domain identifier");
95 | } catch (IllegalArgumentException | NullPointerException ex) {
96 | // expected
97 | }
98 | }
99 |
100 | /**
101 | * The maximum size of the domain identifier is 1023 bytes (note: bytes, not
102 | * characters!). This test verifies that using as much characters as
103 | * possible without crossing the 1023 byte boundry, will not cause a
104 | * problem.
105 | */
106 | @Test
107 | public void testMaximumSize() throws Exception {
108 | // setup
109 | final StringBuilder builder = new StringBuilder("a");
110 | for (int i = 0; i < 511; i++) {
111 | builder.append(".a");
112 | }
113 | final String longestPossibleValue = builder.toString();
114 |
115 | // do magic / verify
116 | new JID(NODE, longestPossibleValue, RESOURCE);
117 | }
118 |
119 | /**
120 | * The maximum size of the domain identifier is 1023 bytes (note: bytes, not
121 | * characters!). This test verifies that using more bytes will cause an
122 | * exception to be thrown.
123 | */
124 | @Test(expected = IllegalArgumentException.class)
125 | public void testOverMaximumSize() throws Exception {
126 | // setup
127 | final StringBuilder builder = new StringBuilder("a");
128 | for (int i = 0; i < 512; i++) {
129 | builder.append(".a");
130 | }
131 | final String toBig = builder.toString();
132 |
133 | // do magic / verify
134 | new JID(NODE, toBig, RESOURCE);
135 | }
136 |
137 | /**
138 | * Verifies that the bare representation of a JID that contains a domain
139 | * name only corresponds to the domain name itself.
140 | */
141 | @Test
142 | public void testBareJID() throws Exception {
143 | // setup
144 | final JID fullJID = new JID(null, DOMAIN, null);
145 |
146 | // do magic
147 | final String bareJID = fullJID.toBareJID();
148 |
149 | // verify
150 | assertEquals(DOMAIN, bareJID);
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/JIDCreationResourceTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import static org.junit.Assert.assertEquals;
20 |
21 | import org.junit.Test;
22 |
23 | /**
24 | * Tests compliance of {@link JID} with the restrictions defined in RFC-3920 for
25 | * the resource identifier.
26 | *
27 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
28 | * @see RFC 3920 - Extensible
29 | * Messaging and Presence Protocol (XMPP): Core
30 | */
31 | public class JIDCreationResourceTest {
32 |
33 | /**
34 | * A node identifier that's RFC 3920 valid.
35 | */
36 | public static final String NODE = "node";
37 |
38 | /**
39 | * A domain identifier that's RFC 3920 valid.
40 | */
41 | public static final String DOMAIN = "domain";
42 |
43 | /**
44 | * A resource identifier that's RFC 3920 valid.
45 | */
46 | public static final String RESOURCE = "resource";
47 |
48 | /**
49 | * Resource identifiers are an optional part of a JID. This testcase
50 | * verifies that resource identifiers can be left out of the creation of a
51 | * JID.
52 | */
53 | @Test
54 | public void testOptionality() throws Exception {
55 | assertEquals(DOMAIN, new JID(DOMAIN).toString());
56 | assertEquals(DOMAIN, new JID(null, DOMAIN, null).toString());
57 | assertEquals(NODE + '@' + DOMAIN, new JID(NODE, DOMAIN, null).toString());
58 | assertEquals(NODE + '@' + DOMAIN, new JID(NODE, DOMAIN, "").toString());
59 | }
60 |
61 | /**
62 | * The maximum size of the resource identifier is 1023 bytes (note: bytes,
63 | * not characters!). This test verifies that using as much characters as
64 | * possible without crossing the 1023 byte boundry, will not cause a
65 | * problem.
66 | */
67 | @Test
68 | public void testMaximumSizeOnByteChar() throws Exception {
69 | // setup
70 | final StringBuilder builder = new StringBuilder();
71 | for (int i = 0; i < 1023; i++) {
72 | builder.append('a');
73 | }
74 | final String longestPossibleValue = builder.toString();
75 |
76 | // do magic / verify
77 | new JID(NODE, DOMAIN, longestPossibleValue);
78 | }
79 |
80 | /**
81 | * The maximum size of the resource identifier is 1023 bytes (note: bytes,
82 | * not characters!). This test verifies that using more bytes will cause an
83 | * exception to be thrown.
84 | */
85 | @Test(expected = IllegalArgumentException.class)
86 | public void testOverMaximumSizeOnByteChar() throws Exception {
87 | // setup
88 | final StringBuilder builder = new StringBuilder();
89 | for (int i = 0; i < 1024; i++) {
90 | builder.append('a');
91 | }
92 | builder.append('a');
93 | final String toBig = builder.toString();
94 |
95 | // do magic / verify
96 | new JID(NODE, DOMAIN, toBig);
97 | }
98 |
99 | /**
100 | * UTF-8 characters use 1 to 4 bytes. The JID implementation should
101 | * correctly identify the length of all UTF-8 characters.
102 | *
103 | * This issue has been filed as TINDER-32
104 | *
105 | * @see Tinder
107 | * bugtracker: TINDER-32Tinder
134 | * bugtracker: TINDER-32RFC 3920 - Extensible
29 | * Messaging and Presence Protocol (XMPP): Core
30 | */
31 | public class JIDCreationNodeTest {
32 |
33 | /**
34 | * A node identifier that's RFC 3920 valid.
35 | */
36 | public static final String NODE = "node";
37 |
38 | /**
39 | * A domain identifier that's RFC 3920 valid.
40 | */
41 | public static final String DOMAIN = "domain";
42 |
43 | /**
44 | * A resource identifier that's RFC 3920 valid.
45 | */
46 | public static final String RESOURCE = "resource";
47 |
48 | /**
49 | * Node identifiers are an optional part of a JID. This testcase verifies
50 | * that node identifiers can be left out of the creation of a JID.
51 | */
52 | @Test
53 | public void testOptionality() throws Exception {
54 | assertEquals(DOMAIN, new JID(DOMAIN).toString());
55 | assertEquals(DOMAIN, new JID(null, DOMAIN, null).toString());
56 | assertEquals(DOMAIN + '/' + RESOURCE, new JID(null, DOMAIN, RESOURCE).toString());
57 | assertEquals(DOMAIN + '/' + RESOURCE, new JID("", DOMAIN, RESOURCE).toString());
58 | }
59 |
60 | /**
61 | * The maximum size of the node identifier is 1023 bytes (note: bytes, not
62 | * characters!). This test verifies that using as much characters as
63 | * possible without crossing the 1023 byte boundry, will not cause a
64 | * problem.
65 | */
66 | @Test
67 | public void testMaximumSizeOneByteChar() throws Exception {
68 | // setup
69 | final StringBuilder builder = new StringBuilder();
70 | for (int i = 0; i < 1023; i++) {
71 | builder.append('a');
72 | }
73 | final String longestPossibleValue = builder.toString();
74 |
75 | // do magic / verify
76 | new JID(longestPossibleValue, DOMAIN, RESOURCE);
77 | }
78 |
79 | /**
80 | * The maximum size of the node identifier is 1023 bytes (note: bytes, not
81 | * characters!). This test verifies that using more bytes will cause an
82 | * exception to be thrown.
83 | */
84 | @Test(expected = IllegalArgumentException.class)
85 | public void testOverMaximumSizeOneByteChar() throws Exception {
86 | // setup
87 | final StringBuilder builder = new StringBuilder();
88 | for (int i = 0; i < 1024; i++) {
89 | builder.append('a');
90 | }
91 | builder.append('a');
92 | final String toBig = builder.toString();
93 |
94 | // do magic / verify
95 | new JID(toBig, DOMAIN, RESOURCE);
96 | }
97 |
98 | /**
99 | * UTF-8 characters use 1 to 4 bytes. The JID implementation should
100 | * correctly identify the length of all UTF-8 characters.
101 | *
102 | * This issue has been filed as TINDER-32
103 | *
104 | * @see Tinder
106 | * bugtracker: TINDER-32Tinder
133 | * bugtracker: TINDER-32Tinder
35 | * bugtracker: TINDER-29
36 | */
37 | public class JIDCachedBareAndFullJIDTest {
38 |
39 | /**
40 | * Verifies that Stringprep mapping results are correctly stored in the
41 | * cache. This test uses a 'word joiner' character, which is listed on the
42 | * B1 table of Stringprep. Characters on this table must be mapped in
43 | * resource strings, according to RFC 3920. This specific character should
44 | * be mapped to nothing. The cached value should not contain this character.
45 | */
46 | @Test
47 | public void testCachedFullJIDisNodePrepped() throws Exception {
48 |
49 | // setup
50 | final String node = "word\u2060joiner";
51 | final String domain = "domain";
52 | final String resource = "resource";
53 |
54 | // do magic
55 | final JID result = new JID(node, domain, resource);
56 | final String fullJID = result.toString();
57 |
58 | // verify
59 | assertEquals("wordjoiner" + "@" + domain + "/" + resource, fullJID);
60 | }
61 |
62 | /**
63 | * Verifies that Stringprep mapping results are correctly stored in the
64 | * cache. This test uses a 'word joiner' character, which is listed on the
65 | * B1 table of Stringprep. Characters on this table must be mapped in
66 | * resource strings, according to RFC 3920. This specific character should
67 | * be mapped to nothing. The cached value should not contain this character.
68 | */
69 | @Test
70 | public void testCachedFullJIDisDomainPrepped() throws Exception {
71 |
72 | // setup
73 | final String node = "node";
74 | final String domain = "word\u2060joiner";
75 | final String resource = "resource";
76 |
77 | // do magic
78 | final JID result = new JID(node, domain, resource);
79 | final String fullJID = result.toString();
80 |
81 | // verify
82 | assertEquals(node + "@" + "wordjoiner" + "/" + resource, fullJID);
83 | }
84 |
85 | /**
86 | * Verifies that Stringprep mapping results are correctly stored in the
87 | * cache. This test uses a 'word joiner' character, which is listed on the
88 | * B1 table of Stringprep. Characters on this table must be mapped in
89 | * resource strings, according to RFC 3920. This specific character should
90 | * be mapped to nothing. The cached value should not contain this character.
91 | */
92 | @Test
93 | public void testCachedFullJIDisResourcePrepped() throws Exception {
94 |
95 | // setup
96 | final String node = "node";
97 | final String domain = "domain";
98 | final String resource = "word\u2060joiner";
99 |
100 | // do magic
101 | final JID result = new JID(node, domain, resource);
102 | final String fullJID = result.toString();
103 |
104 | // verify
105 | assertEquals(node + "@" + domain + "/" + "wordjoiner", fullJID);
106 | }
107 |
108 | /**
109 | * Verifies that Stringprep mapping results are correctly stored in the
110 | * cache. This test uses a 'word joiner' character, which is listed on the
111 | * B1 table of Stringprep. Characters on this table must be mapped in
112 | * resource strings, according to RFC 3920. This specific character should
113 | * be mapped to nothing. The cached value should not contain this character.
114 | */
115 | @Test
116 | public void testCachedBareJIDisNodePrepped() throws Exception {
117 |
118 | // setup
119 | final String node = "word\u2060joiner";
120 | final String domain = "domain";
121 | final String resource = "resource";
122 |
123 | // do magic
124 | final JID result = new JID(node, domain, resource);
125 | final String bareJID = result.toBareJID();
126 |
127 | // verify
128 | assertEquals("wordjoiner" + "@" + domain, bareJID);
129 | }
130 |
131 | /**
132 | * Verifies that Stringprep mapping results are correctly stored in the
133 | * cache. This test uses a 'word joiner' character, which is listed on the
134 | * B1 table of Stringprep. Characters on this table must be mapped in
135 | * resource strings, according to RFC 3920. This specific character should
136 | * be mapped to nothing. The cached value should not contain this character.
137 | */
138 | @Test
139 | public void testCachedBareJIDisDomainPrepped() throws Exception {
140 |
141 | // setup
142 | final String node = "node";
143 | final String domain = "word\u2060joiner";
144 | final String resource = "resource";
145 |
146 | // do magic
147 | final JID result = new JID(node, domain, resource);
148 | final String bareJID = result.toBareJID();
149 |
150 | // verify
151 | assertEquals(node + "@" + "wordjoiner", bareJID);
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/PacketErrorApplicationConditionTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import static org.junit.Assert.*;
20 |
21 | import org.junit.Before;
22 | import org.junit.Test;
23 | import org.xmpp.packet.PacketError.Condition;
24 | import org.xmpp.packet.PacketError.Type;
25 |
26 | /**
27 | * Tests compliance of Application-Specific Conditions provided by
28 | * {@link PacketError} with the restrictions defined in RFC-3920.
29 | *
30 | * @author Günther Nieß, guenther.niess@web.de
31 | * @see RFC 3920 - Extensible
32 | * Messaging and Presence Protocol (XMPP): Core
33 | */
34 | public class PacketErrorApplicationConditionTest {
35 |
36 | /**
37 | * XML namespace name for stanza-related error data.
38 | */
39 | public static final String ERROR_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-stanzas";
40 |
41 | /**
42 | * Fallback namespace for generalized error conditions (see XEP-0182).
43 | */
44 | public static final String GENERAL_ERROR_NAMESPACE = "urn:xmpp:errors";
45 |
46 | /**
47 | * A text describing a sample packet-error.
48 | */
49 | public static final String ERROR_TEXT = "Some special application information...";
50 |
51 | /**
52 | * A simple error for testing application specific error conditions.
53 | */
54 | private PacketError stanzaError;
55 |
56 | /**
57 | * A more complex error for testing application specific error conditions.
58 | */
59 | private PacketError applicationError;
60 |
61 |
62 | /**
63 | * Initialize the used packet-errors.
64 | */
65 | @Before
66 | public void setUp() {
67 | stanzaError = new PacketError(Condition.not_acceptable);
68 | applicationError = new PacketError(
69 | Condition.undefined_condition,
70 | Type.modify,
71 | ERROR_TEXT,
72 | "en");
73 | }
74 |
75 | /**
76 | * Testing the default behavior of the setter and getter methods, when an
77 | * application error is set, without a namespace being provided.
78 | */
79 | @Test
80 | public void testValidBehaviorJustCondition() {
81 | String requestErrorName = "stanza-too-big";
82 | stanzaError.setApplicationCondition(requestErrorName);
83 | if (!requestErrorName.equals(stanzaError.getApplicationConditionName())) {
84 | fail("Don't get the applied name of the application-specific "
85 | + "error condition.");
86 | }
87 | if (!GENERAL_ERROR_NAMESPACE.equals(
88 | stanzaError.getApplicationConditionNamespaceURI())) {
89 | fail("According to the XEP-0182 the default namespace of general "
90 | + "application-specific error conditions is "
91 | + GENERAL_ERROR_NAMESPACE + ". "
92 | + "This namespace should be applied as fallback.");
93 | }
94 | }
95 |
96 | /**
97 | * Testing the default behavior of the setter and getter methods, when an
98 | * application error including a namespace is set.
99 | */
100 | @Test
101 | public void testValidBehaviorConditionAndNamespace() {
102 | String appErrorName = "special-application-condition";
103 | String appNS = "application-ns";
104 | applicationError.setApplicationCondition(appErrorName, appNS);
105 | if (!appNS.equals(applicationError.getApplicationConditionNamespaceURI())) {
106 | fail("Don't get the expected namespace of the application-specific "
107 | + "error condition.");
108 | }
109 | if (Condition.undefined_condition != applicationError.getCondition()) {
110 | fail("The application-specific error condition don't have to modify "
111 | + "the standard error condition.");
112 | }
113 | if (!ERROR_TEXT.equals(applicationError.getText())) {
114 | fail("The application-specific error condition don't have to modify "
115 | + "the text of the packet-error.");
116 | }
117 | }
118 |
119 | /**
120 | * Verifies the valid behavior of this class, even after a previously set condition is removed.
121 | */
122 | @Test
123 | public void testValidBehaviorReset() {
124 | // set error
125 | String appErrorName = "special-application-condition";
126 | String appNS = "application-ns";
127 | applicationError.setApplicationCondition(appErrorName, appNS);
128 |
129 | // unset error
130 | applicationError.setApplicationCondition(null);
131 |
132 | // verify that unsetting the error propagated correctly.
133 | if (applicationError.getApplicationConditionNamespaceURI() != null) {
134 | fail("Removing the application-specific error condition don't "
135 | + "remove the namespace of the application.");
136 | }
137 | if (Condition.undefined_condition != applicationError.getCondition()) {
138 | fail("Removing the application-specific error condition don't have "
139 | + "to modify the standard error condition.");
140 | }
141 | if (!ERROR_TEXT.equals(applicationError.getText())) {
142 | fail("Removing the application-specific error condition don't have "
143 | + "to modify the text of the packet-error.");
144 | }
145 | }
146 |
147 | /**
148 | * Insert an application-specific error, using the namespace
149 | * urn:ietf:params:xml:ns:xmpp-stanzas isn't allowed by RFC 3920.
150 | */
151 | @Test(expected = IllegalArgumentException.class)
152 | public void testInvalidParameters() throws Exception {
153 | // verify
154 | applicationError.setApplicationCondition("invalid-ns", ERROR_NAMESPACE);
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/component/ComponentManager.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.component;
18 |
19 | import org.xmpp.packet.IQ;
20 | import org.xmpp.packet.Packet;
21 |
22 | /**
23 | * Manages components.
24 | *
25 | * @see Component
26 | * @author Matt Tucker
27 | */
28 | public interface ComponentManager {
29 |
30 | /**
31 | * Adds a component. The {@link Component#initialize(org.xmpp.packet.JID, ComponentManager)}
32 | * method will be called on the component. The subdomain specifies the address of
33 | * the component on a server. For example, if the subdomain is "test" and the XMPP
34 | * server is at "example.com", then the component's address would be "test.example.com".
35 | *
36 | * @param subdomain the subdomain of the component's address.
37 | * @param component the component.
38 | * @throws ComponentException if the component connection is lost and the component cannot be added.
39 | */
40 | void addComponent(String subdomain, Component component) throws ComponentException;
41 |
42 | /**
43 | * Removes a component. The {@link Component#shutdown} method will be called on the
44 | * component.
45 | *
46 | * @param subdomain the subdomain of the component's address.
47 | * @throws ComponentException if the component connection is lost and the component cannot be removed.
48 | */
49 | void removeComponent(String subdomain) throws ComponentException;
50 |
51 | /**
52 | * Sends a packet to the XMPP server. The "from" value of the packet must not be null.
53 | * An
54 | *
55 | * Components are trusted by the server and may use any value in from address. Usually
56 | * the from address uses the component's address as the domain but this is not required.
57 | *
58 | * @param component the component sending the packet.
59 | * @param packet the packet to send.
60 | * @throws ComponentException if the component connection is lost or unavialble during the time of sending and
61 | * recieving packets.
62 | */
63 | void sendPacket(Component component, Packet packet) throws ComponentException;
64 |
65 | /**
66 | * Sends an IQ packet to the XMPP server and waits to get an IQ of type result or error.
67 | * The "from" value of the packet must not be null. An
69 | *
70 | * If no answer is received from the server before the specified timeout then
114 | * Normally you don't care much about the detailed structure of serialized
115 | * objects. You just care that whatever format you start out with is
116 | * maintained as the class evolves. Once the class is in more-or-less
117 | * complete shape, write some serialized instances of the class and store
118 | * them where you can use them as references going forward. (You probably do
119 | * want to think at least a little about how you will serialize to ensure
120 | * sufficient flexibility for evolution going forward.)
121 | *
122 | * All you need to do is write a serialized object into a file, and you only
123 | * do that once. It's the file you want to save, not the code that wrote it.
124 | * Your test deserializes the object in the file and then compare its
125 | * properties to their expected values.
126 | */
127 | @Test
128 | public void testDeserializeVersionJIDversion1dot1() throws Exception {
129 | // this JID is build from the String values that were also used to build
130 | // the String that's serialized in the file
131 | // "jid-version-tinder1.1.serialized"
132 | final JID original = new JID("abc", "dom4in.com", "@home", true);
133 |
134 | // deserialize
135 | final InputStream in = getClass().getResourceAsStream(
136 | "/jid-version-tinder1.1.serialized");
137 | final ObjectInputStream ois = new ObjectInputStream(in);
138 | final Object o = ois.readObject();
139 | final JID deserialized = (JID) o;
140 |
141 | // test the result
142 | assertEquals(original.getDomain(), deserialized.getDomain());
143 | assertEquals(original.getResource(), deserialized.getResource());
144 | assertEquals(original.getNode(), deserialized.getNode());
145 | }
146 |
147 | // This code is used to generate serialized JID instances. After every
148 | // change of the JID class, a new serialized object should be created. This
149 | // object should be added (not replace!) the existing objects in the
150 | // /test/resources/ directory, and a new unit test should be written that
151 | // verifies that the object can be correctly deserialized. This way,
152 | // backwards compatibility of the deserialization implementation is checked.
153 | // public static void main(String[] args) throws Exception {
154 | // final File file = new File(
155 | // "src/test/resources/jid-version-tinder1.CHANGEME.serialized");
156 | // final OutputStream fout = new FileOutputStream(file);
157 | //
158 | // final ObjectOutputStream out = new ObjectOutputStream(fout);
159 | //
160 | // final JID jid = new JID("abc", "dom4in.com", "@home");
161 | // out.writeObject(jid);
162 | // out.flush();
163 | // out.close();
164 | // }
165 | }
166 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/forms/FormFieldGetSetTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.forms;
18 |
19 | import static org.junit.Assert.assertEquals;
20 | import static org.junit.Assert.assertTrue;
21 | import static org.junit.Assert.fail;
22 |
23 | import java.util.List;
24 |
25 | import org.dom4j.DocumentFactory;
26 | import org.dom4j.Element;
27 | import org.junit.Before;
28 | import org.junit.Test;
29 | import org.xmpp.forms.FormField.Option;
30 | import org.xmpp.forms.FormField.Type;
31 |
32 | /**
33 | * This test verifies the functionality of the setters and getters of fields in
34 | * the {@link FormField} implementation. Every test in this class works
35 | * according to the same principle: use the setter to set a particular value,
36 | * then use the getter to verify that this value is returned.
37 | *
38 | * This test should identify problems such as TINDER-12
39 | *
40 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
41 | * @see http://www.igniterealtime.org/issues/browse/TINDER-12
42 | */
43 | public class FormFieldGetSetTest {
44 |
45 | private static final DocumentFactory DF = DocumentFactory.getInstance();
46 |
47 | /**
48 | * Every test will be using a new, empty {@link FormField} instance, which
49 | * is set and reset in this field.
50 | */
51 | private FormField field = null;
52 |
53 | @Before
54 | public void setUp() {
55 | // reset the element before every test.
56 | final Element emptyElement = DF.createDocument().addElement("field");
57 | field = new FormField(emptyElement);
58 | }
59 |
60 | /**
61 | * Test method for
62 | * {@link org.xmpp.forms.FormField#addValue(java.lang.Object)} and
63 | * {@link org.xmpp.forms.FormField#getValues()}.
64 | */
65 | @Test
66 | public void testValues_OneValue() {
67 | // setup
68 | final String value = "a value";
69 |
70 | // do magic
71 | field.addValue(value);
72 | final List
29 | * // Join an existing room or create a new one.
30 | * JoinRoom joinRoom = new JoinRoom("john@jabber.org/notebook", "room@conference.jabber.org/nick");
31 | *
32 | * component.sendPacket(joinRoom);
33 | *
34 | *
35 | * @author Gaston Dombiak
36 | */
37 | @NotThreadSafe
38 | public class LeaveRoom extends Presence {
39 |
40 | /**
41 | * Creates a new Presence packet that could be sent to a MUC service in order to leave the room.
42 | *
43 | * @param from the full JID of the user that wants to leave the room.
44 | * @param to the room JID. That is the room address plus the nickname of the user as a resource.
45 | */
46 | public LeaveRoom(String from, String to) {
47 | super();
48 | setFrom(from);
49 | setTo(to);
50 | setType(Type.unavailable);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/component/ComponentException.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.component;
18 |
19 | import org.xmpp.packet.StreamError;
20 |
21 | /**
22 | * Thrown when an exception occors with a Component.
23 | *
24 | * @author Matt Tucker
25 | */
26 | public class ComponentException extends Exception {
27 |
28 | private static final long serialVersionUID = -4133202596762415887L;
29 |
30 | private StreamError streamError;
31 |
32 | public ComponentException() {
33 | super();
34 | }
35 |
36 | public ComponentException(String message) {
37 | super(message);
38 | }
39 |
40 | public ComponentException(String message, Throwable cause) {
41 | super(message, cause);
42 | }
43 |
44 | public ComponentException(Throwable cause) {
45 | super(cause);
46 | }
47 |
48 | public ComponentException(String message, StreamError streamError) {
49 | super(message);
50 | this.streamError = streamError;
51 | }
52 |
53 | public ComponentException(StreamError streamError) {
54 | super(streamError.getCondition().toXMPP());
55 | this.streamError = streamError;
56 | }
57 |
58 | public StreamError getStreamError() {
59 | return streamError;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/component/IQResultListener.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.component;
18 |
19 | import org.xmpp.packet.IQ;
20 |
21 | /**
22 | * An IQResultListener will be invoked when a previously IQ packet sent by the server was answered.
23 | * Use {@code IQRouter#addIQResultListener(String, IQResultListener)} to add a new listener that
24 | * will process the answer to the IQ packet being sent. The listener will automatically be
25 | * removed from the {@code IQRouter} as soon as a reply for the sent IQ packet is received. The
26 | * reply can be of type RESULT or ERROR.
27 | *
28 | * @author Gaston Dombiak
29 | */
30 | public interface IQResultListener {
31 |
32 | /**
33 | * Notification method indicating that a previously sent IQ packet has been answered.
34 | * The received IQ packet might be of type ERROR or RESULT.
35 | *
36 | * @param packet the IQ packet answering a previously sent IQ packet.
37 | */
38 | void receivedAnswer(IQ packet);
39 |
40 | /**
41 | * Notification method indicating that a predefined time has passed without
42 | * receiving answer to a previously sent IQ packet.
43 | *
44 | * @param packetId The packet id of a previously sent IQ packet that wasn't answered.
45 | */
46 | void answerTimeout(String packetId);
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/muc/JoinRoom.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.muc;
18 |
19 | import net.jcip.annotations.NotThreadSafe;
20 |
21 | import org.xmpp.packet.Presence;
22 |
23 | /**
24 | * Initial presence sent when joining an existing room or creating a new room. The JoinRoom presence
25 | * indicates the posibility of the sender to speak MUC.
29 | * // Join an existing room or create a new one.
30 | * JoinRoom joinRoom = new JoinRoom("john@jabber.org/notebook", "room@conference.jabber.org/nick");
31 | *
32 | * component.sendPacket(joinRoom);
33 | *
34 | *
35 | * @author Gaston Dombiak
36 | */
37 | @NotThreadSafe
38 | public class JoinRoom extends Presence {
39 |
40 | /**
41 | * Creates a new Presence packet that could be sent to a MUC service in order to join
42 | * an existing MUC room or create a new one.
43 | *
44 | * @param from the real full JID of the user that will join or create a MUC room.
45 | * @param to a full JID where the bare JID is the MUC room address and the resource is the
46 | * nickname of the user joining the room.
47 | */
48 | public JoinRoom(String from, String to) {
49 | super();
50 | setFrom(from);
51 | setTo(to);
52 | addChildElement("x", "http://jabber.org/protocol/muc");
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/resultsetmanagement/Result.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.resultsetmanagement;
18 |
19 | /**
20 | * Elements from a result set as defined by XEP-0059 have certain
21 | * characteristics. This interface defines these characteristics.
22 | *
23 | * Applying this interface to a class will allow you to use ResultSet operations
24 | * on collections of your class. In other words: you are making collections of
25 | * your class managable/navigable.
26 | *
27 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
28 | * @see XEP-0059: Result Set Management
29 | */
30 | public interface Result {
31 |
32 | /**
33 | * Returns a unique identifier for this Result. Each element in a ResultSet
34 | * must have a distinct UIDs.
35 | *
36 | * XEP-0059 says: (...) the UIDs are
37 | * unique in the context of all possible members of the full result set.
38 | * Each UID MAY be based on part of the content of its associated item (...)
39 | * or on an internal table index. Another possible method is to serialize
40 | * the XML of the item and then hash it to generate the UID. Note: The
41 | * requesting entity MUST treat all UIDs as opaque.
42 | *
43 | * @return Unique ID of the Result
44 | */
45 | String getUID();
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/util/XMPPConstants.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.util;
18 |
19 | /**
20 | * Contains constant values representing various objects in Tinder.
21 | */
22 | public class XMPPConstants {
23 |
24 | /**
25 | * The amount of milliseconds in one second.
26 | */
27 | public static final long SECOND = 1000;
28 |
29 | /**
30 | * The amount of milliseconds in one minute.
31 | */
32 | public static final long MINUTE = 60 * SECOND;
33 |
34 | /**
35 | * The amount of milliseconds in one .
36 | */
37 | public static final long HOUR = 60 * MINUTE;
38 |
39 | /**
40 | * The amount of milliseconds in one .
41 | */
42 | public static final long DAY = 24 * HOUR;
43 |
44 | /**
45 | * The amount of milliseconds in one .
46 | */
47 | public static final long WEEK = 7 * DAY;
48 |
49 | /**
50 | * Date/time format for use by SimpleDateFormat. The format conforms to
51 | * XEP-0082, which defines
52 | * a unified date/time format for XMPP.
53 | */
54 | public static final String XMPP_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
55 |
56 | /**
57 | * Date/time format for use by SimpleDateFormat. The format conforms to the format
58 | * defined in XEP-0091,
59 | * a specialized date format for historical XMPP usage.
60 | */
61 | public static final String XMPP_DELAY_DATETIME_FORMAT = "yyyyMMdd'T'HH:mm:ss";
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/muc/DestroyRoom.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.muc;
18 |
19 | import net.jcip.annotations.NotThreadSafe;
20 |
21 | import org.dom4j.Element;
22 | import org.xmpp.packet.IQ;
23 | import org.xmpp.packet.JID;
24 |
25 | /**
26 | * DestroyRoom is a packet that when sent will ask the server to destroy a given room. The room to
27 | * destroy must be specified in the TO attribute of the IQ packet. The server will send a presence
28 | * unavailable together with the alternate room and reason for the destruction to all the room
29 | * occupants before destroying the room.null if none.
41 | * @param reason reason for the destruction or null if none.
42 | */
43 | public DestroyRoom(JID alternateJID, String reason) {
44 | super();
45 | setType(Type.set);
46 | Element query = setChildElement("query", "http://jabber.org/protocol/muc#owner");
47 | Element destroy = query.addElement("destroy");
48 | if (alternateJID != null) {
49 | destroy.addAttribute("jid", alternateJID.toString());
50 | }
51 | if (reason != null) {
52 | destroy.addElement("reason").setText(reason);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/muc/Invitation.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.muc;
18 |
19 | import net.jcip.annotations.NotThreadSafe;
20 |
21 | import org.dom4j.Element;
22 | import org.xmpp.packet.Message;
23 |
24 | /**
25 | * Represents an invitation to a Multi-User Chat room from a room occupant to a user that is not
26 | * an occupant of the room. The invitation must be sent to the room and it's the room
27 | * responsibility to forward the invitation to the invitee. The sender of the invitation must be
28 | * the real full JID of the inviter.
32 | * // Invite the someone to the room.
33 | * Invitation invitation = new Invitation("invitee@jabber.org", "Join this excellent room");
34 | * invitation.setTo("room@conference.jabber.org");
35 | * invitation.setFrom("inviter@jabber.org/notebook");
36 | *
37 | * component.sendPacket(invitation);
38 | *
39 | *
40 | * @author Gaston Dombiak
41 | */
42 | @NotThreadSafe
43 | public class Invitation extends Message {
44 |
45 | /**
46 | * Creates a new invitation.
47 | *
48 | * @param invitee the XMPP address of the invitee. The room will forward the invitation to this
49 | * address.
50 | * @param reason the reason why the invitation is being sent.
51 | */
52 | public Invitation(String invitee, String reason) {
53 | super();
54 | Element element = addChildElement("x", "http://jabber.org/protocol/muc#user");
55 | Element invite = element.addElement("invite");
56 | invite.addAttribute("to", invitee);
57 | if (reason != null && reason.length() > 0) {
58 | invite.addElement("reason").setText(reason);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/component/DummyAbstractComponent.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.component;
18 |
19 | import java.util.concurrent.BlockingQueue;
20 | import java.util.concurrent.LinkedBlockingQueue;
21 | import java.util.concurrent.TimeUnit;
22 |
23 | import org.xmpp.packet.Packet;
24 |
25 | /**
26 | * A dummy implementation of {@link AbstractComponentTest}, intended to be used
27 | * during unit tests.
28 | *
29 | * Instances store any packets that are delivered to be send using the
30 | * {@link #send(Packet)} method in a blocking queue. The content of this queue
31 | * can be inspected using {@link #getSentPacket()}. Typically these queues are
32 | * used to retrieve a response that was generated by the component.
33 | *
34 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
35 | */
36 | public class DummyAbstractComponent extends AbstractComponent {
37 |
38 | private final BlockingQueue
22 | *
23 | *
31 | *
32 | * @author Matt Tucker
33 | */
34 | public class ComponentManagerFactory {
35 |
36 | private static ComponentManager componentManager;
37 |
38 | /**
39 | * Returns a ComponentManager instance.
40 | *
41 | * @return a ComponentManager instance.
42 | */
43 | public static synchronized ComponentManager getComponentManager() {
44 | if (componentManager != null) {
45 | return componentManager;
46 | }
47 | // ComponentManager is null so we have to try to figure out how to load
48 | // an instance. Look for a Java property.
49 | String className = System.getProperty("whack.componentManagerClass");
50 | if (className != null) {
51 | try {
52 | Class> c = Class.forName(className);
53 | componentManager = (ComponentManager) c.newInstance();
54 | return componentManager;
55 | } catch (Exception e) {
56 | e.printStackTrace();
57 | }
58 | }
59 | // Got here, so throw exception.
60 | throw new NullPointerException("No ComponentManager implementation available.");
61 | }
62 |
63 | /**
64 | * Sets the ComponentManager instance that will be used.
65 | *
66 | * @param manager the ComponentManager instance.
67 | */
68 | public static void setComponentManager(ComponentManager manager) {
69 | componentManager = manager;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/JIDEqualsHashCodeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import junitx.extensions.EqualsHashCodeTestCase;
20 | import org.junit.Assert;
21 |
22 | /**
23 | * Tests functional compliance of {@link JID} with the equals and hashCode
24 | * contract.
25 | *
26 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
27 | */
28 | public class JIDEqualsHashCodeTest extends EqualsHashCodeTestCase {
29 |
30 | public JIDEqualsHashCodeTest(String name) {
31 | super(name);
32 | }
33 |
34 | @Override
35 | protected Object createInstance() throws Exception {
36 | return new JID("node@domain/resource");
37 | }
38 |
39 | @Override
40 | protected Object createNotEqualInstance() throws Exception {
41 | return new JID("edon@niamod/ecrouser");
42 | }
43 |
44 | public void testNullOtherResource() throws Exception {
45 | // Setup fixture.
46 | final JID a = new JID( "node", "domain", "resource" );
47 | final JID b = new JID( "node", "domain", null );
48 |
49 | // Execute system under test.
50 | final boolean areEqual = a.equals( b );
51 |
52 | // Verify results.
53 | Assert.assertFalse( areEqual );
54 | }
55 |
56 | public void testNullResource() throws Exception {
57 | // Setup fixture.
58 | final JID a = new JID( "node", "domain", null );
59 | final JID b = new JID( "node", "domain", "resource" );
60 |
61 | // Execute system under test.
62 | final boolean areEqual = a.equals( b );
63 |
64 | // Verify results.
65 | Assert.assertFalse( areEqual );
66 | }
67 |
68 | public void testNullResources() throws Exception {
69 | // Setup fixture.
70 | final JID a = new JID( "node", "domain", null );
71 | final JID b = new JID( "node", "domain", null );
72 |
73 | // Execute system under test.
74 | final boolean areEqual = a.equals( b );
75 |
76 | // Verify results.
77 | Assert.assertTrue( areEqual );
78 | }
79 |
80 | public void testNullNode() throws Exception {
81 | // Setup fixture.
82 | final JID a = new JID( null, "domain", null );
83 | final JID b = new JID( "node", "domain", null );
84 |
85 | // Execute system under test.
86 | final boolean areEqual = a.equals( b );
87 |
88 | // Verify results.
89 | Assert.assertFalse( areEqual );
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/muc/RoomConfiguration.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.muc;
18 |
19 | import net.jcip.annotations.NotThreadSafe;
20 |
21 | import org.dom4j.Element;
22 | import org.xmpp.packet.IQ;
23 |
24 | import java.util.Collection;
25 | import java.util.Map;
26 | import java.util.Map.Entry;
27 |
28 | /**
29 | * RoomConfiguration is a packet that helps to set the configuration of MUC rooms. RoomConfiguration
30 | * is a speacial IQ packet whose child element contains a data form. The data form holds the fields
31 | * to set together with a list of values.null, the factory will check for
26 | * the Java system property "whack.componentManagerClass". The value of the
27 | * property should be the fully qualified class name of a ComponentManager
28 | * implementation (e.g. com.foo.MyComponentManager). The class must have a default
29 | * constructor.
30 | *
35 | * {@code
36 | * // Set the fields and the values.
37 | * Map
51 | *
52 | * @author Gaston Dombiak
53 | */
54 | @NotThreadSafe
55 | public class RoomConfiguration extends IQ {
56 |
57 | /**
58 | * Creates a new IQ packet that contains the field and values to send for setting the room
59 | * configuration.
60 | *
61 | * @param fieldValues the list of fields associated with the list of values.
62 | */
63 | public RoomConfiguration(Maptinder:debug. If the child element name is
28 | * threadname, a response will be generated that reports the name of
29 | * the thread used to process the stanza, as shown:
30 | *
31 | *
32 | * <iq type='get' id='debug_1'>
33 | * <threadname xmlns='tinder:debug'/>
34 | * </iq>
35 | *
36 | *
37 | *
38 | * <iq type='result' id='debug_1'>
39 | * <threadname xmlns='tinder:debug'>consumer-thread-34</threadname>
40 | * </iq>
41 | *
42 | *
43 | * If the element name is slowresponse, an empty response will be
44 | * generated 4000 milliseconds after the request was delivered to the component.
45 | *
46 | *
47 | * <iq type='get' id='debug_2'>
48 | * <slowresponse xmlns='tinder:debug'/>
49 | * </iq>
50 | *
51 | *
52 | *
53 | * <iq type='result' id='debug_2'/>
54 | *
55 | *
56 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
57 | */
58 | public class SlowRespondingThreadNameComponent extends DummyAbstractComponent {
59 |
60 | public static final String DEBUG_NAMESPACE = "tinder:debug";
61 | public static final String ELEMENTNAME_SLOWRESPONSE = "slowresponse";
62 | public static final String ELEMENTNAME_THREADNAME = "threadname";
63 |
64 | /**
65 | * Processes the tinder:debug requests.
66 | */
67 | @Override
68 | protected IQ handleIQGet(IQ request) throws Exception {
69 | final Element element = request.getChildElement();
70 | if (!DEBUG_NAMESPACE.equals(element.getNamespaceURI())) {
71 | log.debug("Can not process {}", request.toXML());
72 | return null;
73 | }
74 |
75 | if (ELEMENTNAME_SLOWRESPONSE.equals(element.getName())) {
76 | log.debug("Waiting 4000 millis before responding to: {}", request
77 | .toXML());
78 | Thread.sleep(4000);
79 | log.debug("Responding to {} now.", request.toXML());
80 | return IQ.createResultIQ(request);
81 | }
82 |
83 | if (ELEMENTNAME_THREADNAME.equals(element.getName())) {
84 | final String threadName = Thread.currentThread().getName();
85 | final IQ response = IQ.createResultIQ(request);
86 | response.setChildElement(ELEMENTNAME_THREADNAME, DEBUG_NAMESPACE)
87 | .addText(threadName);
88 | log.debug("Responding to {} with {}", request.toXML(), response
89 | .toXML());
90 | return response;
91 | }
92 |
93 | log.debug("Cannot process {}", request.toXML());
94 | return null;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/org/xmpp/component/Component.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.component;
18 |
19 | import org.xmpp.packet.JID;
20 | import org.xmpp.packet.Packet;
21 |
22 | /**
23 | * Components enhance the functionality of an XMPP server. Components receive
24 | * all packets addressed to a particular sub-domain. For example,
25 | * test_component.example.com. So, a packet sent to
26 | * joe@test_component.example.com would be delivered to the component.
27 | * Note that the sub-domains defined as components are unrelated to DNS entries
28 | * for sub-domains. All XMPP routing at the socket level is done using the
29 | * primary server domain (example.com in the example above); sub-domains are
30 | * only used for routing within the XMPP server.
31 | *
32 | * @author Matt Tucker
33 | */
34 | public interface Component {
35 |
36 | /**
37 | * Returns the name of this component.
38 | *
39 | * @return the name of this component.
40 | */
41 | String getName();
42 |
43 | /**
44 | * Returns the description of this component.
45 | *
46 | * @return the description of this component.
47 | */
48 | String getDescription();
49 |
50 | /**
51 | * Processes a packet sent to this Component.
52 | *
53 | * @param packet the packet.
54 | * @see ComponentManager#sendPacket(Component, Packet)
55 | */
56 | void processPacket(Packet packet);
57 |
58 | /**
59 | * Initializes this component with a ComponentManager and the JID
60 | * that this component is available at (e.g. service.example.com). If a
61 | * ComponentException is thrown then the component will not be loaded.registeredExtensions. The registration process associates the new subclass
35 | * with a given qualified name (ie. element name and namespace). This information will be used by
36 | * {@link Packet#getExtension(String, String)} for locating the corresponding PacketExtension
37 | * subclass to return for the requested qualified name. Each PacketExtension must have a public
38 | * constructor that takes an Element instance as an argument.
39 | *
40 | * @author Gaston Dombiak
41 | */
42 | @NotThreadSafe
43 | public class PacketExtension {
44 |
45 | protected static final DocumentFactory docFactory = DocumentFactory.getInstance();
46 | /**
47 | * Subclasses of PacketExtension should register the element name and namespace that the
48 | * subclass is using.
49 | */
50 | protected static final MapUSE_VALUE representation.
104 | *
105 | * @param value
106 | * The value that is wrapped.
107 | */
108 | public ValueWrapper(V value) {
109 | this.representation = Representation.USE_VALUE;
110 | this.value = value;
111 | this.exceptionMessage = null;
112 | }
113 |
114 | /**
115 | * Returns the wrapped value, or null if the representation used in
116 | * this instance is not USE_VALUE;
117 | *
118 | * @return the wrapped value.
119 | */
120 | public V getValue() {
121 | return value;
122 | }
123 |
124 | public Representation getRepresentation() {
125 | return representation;
126 | }
127 |
128 | /**
129 | * Returns the message describing the invalidity of the key that maps
130 | * to this instance.
131 | *
132 | * @return An exception message , possibly null.
133 | */
134 | public String getExceptionMessage() {
135 | return exceptionMessage;
136 | }
137 |
138 | @Override
139 | public String toString()
140 | {
141 | return "ValueWrapper{" +
142 | "value=" + value +
143 | ", representation=" + representation +
144 | ", exceptionMessage='" + exceptionMessage + '\'' +
145 | '}';
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/StringPrepCacheTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import org.junit.Test;
20 |
21 | /**
22 | * A testcase that verifies the effect of stringprep caching in the JID class.
23 | * IllegalArgumentException will be thrown when the "from" value is null.IllegalArgumentException
68 | * will be thrown when the "from" value is null.null will be returned.
71 | *
72 | * Components are trusted by the server and may use any value in from address. Usually
73 | * the from address uses the component's address as the domain but this is not required.
74 | *
75 | * @param component the component sending the packet.
76 | * @param packet the IQ packet to send.
77 | * @param timeout the number of milliseconds to wait before returning an IQ error.
78 | * @return the answer sent by the server. The answer could be an IQ of type result or
79 | * error. null will be returned if there is no response from the server.
80 | * @throws ComponentException if the component connection is lost or unavialble during the time of sending and
81 | * recieving packets.
82 | */
83 | IQ query(Component component, IQ packet, long timeout) throws ComponentException;
84 |
85 | /**
86 | * Sends an IQ packet to the server and returns immediately. The specified IQResultListener
87 | * will be invoked when an answer is received.
88 | *
89 | * @param component the component sending the packet.
90 | * @param packet the IQ packet to send.
91 | * @param listener the listener that will be invoked when an answer is received.
92 | * @throws ComponentException if the component connection is lost or unavialble during the time of sending and
93 | * recieving packets.
94 | */
95 | void query(Component component, IQ packet, IQResultListener listener) throws ComponentException;
96 |
97 | /**
98 | * Returns a property value specified by name. Properties can be used by
99 | * components to store configuration data. It is recommended that each
100 | * component qualify property names to prevent overlap. For example a
101 | * component that broadcasts messages to groups of users, might prepend
102 | * all property names it uses with "broadcast.".
103 | *
104 | * @param name the property name.
105 | * @return the property value.
106 | */
107 | String getProperty(String name);
108 |
109 | /**
110 | * Sets a property value. Properties can be used by components to
111 | * store configuration data. It is recommended that each component
112 | * qualify property names to prevent overlap. For example a component
113 | * that broadcasts messages to groups of users, might prepend all
114 | * property names it uses with "broadcast.".
115 | *
116 | * @param name the property name.
117 | * @param value the property value.
118 | */
119 | void setProperty(String name, String value);
120 |
121 | /**
122 | * Returns the domain of the XMPP server. The domain name may be the IP address or the host
123 | * name.
124 | *
125 | * @return the domain of the XMPP server.
126 | */
127 | String getServerName();
128 |
129 | /**
130 | * Returns true if components managed by this component manager are external
131 | * components connected to the server over a network connection. Otherwise,
132 | * the components are internal to the server.
133 | *
134 | * @return true if the managed components are external components.
135 | */
136 | boolean isExternalMode();
137 | }
138 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/BasicJIDTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2010 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.xmpp.packet;
17 |
18 | import static org.junit.Assert.assertEquals;
19 | import static org.junit.Assert.assertNull;
20 |
21 | import org.junit.Test;
22 |
23 | /**
24 | * Various checks that verify basic JID behaviour.
25 | *
26 | * @author Guus der Kinderen
27 | */
28 | public class BasicJIDTest {
29 |
30 | @Test(expected = IllegalArgumentException.class)
31 | public void testNullArgument() {
32 | new JID(null);
33 | }
34 |
35 | @Test(expected = IllegalArgumentException.class)
36 | public void testEmptyArgument() {
37 | new JID("");
38 | }
39 |
40 | @Test
41 | public void testC1FullJID() {
42 | // setup
43 | final JID jid = new JID("node@domain/resource");
44 |
45 | // verify
46 | assertEquals("node", jid.getNode());
47 | assertEquals("domain", jid.getDomain());
48 | assertEquals("resource", jid.getResource());
49 | }
50 |
51 | @Test
52 | public void testC1BareJID() {
53 | // setup
54 | final JID jid = new JID("node@domain");
55 |
56 | // verify
57 | assertEquals("node", jid.getNode());
58 | assertEquals("domain", jid.getDomain());
59 | assertNull(jid.getResource());
60 | }
61 |
62 | @Test
63 | public void testC1JIDWithoutNode() {
64 | // setup
65 | final JID jid = new JID("domain/resource");
66 |
67 | // verify
68 | assertNull(jid.getNode());
69 | assertEquals("domain", jid.getDomain());
70 | assertEquals("resource", jid.getResource());
71 | }
72 |
73 | @Test
74 | public void testC1BareJIDWithoutNode() {
75 | // setup
76 | final JID jid = new JID("domain");
77 |
78 | // verify
79 | assertNull(jid.getNode());
80 | assertEquals("domain", jid.getDomain());
81 | assertNull(jid.getResource());
82 | }
83 |
84 | @Test
85 | public void testC2FullJID() {
86 | // setup
87 | final JID jid = new JID("node", "domain", "resource");
88 |
89 | // verify
90 | assertEquals("node", jid.getNode());
91 | assertEquals("domain", jid.getDomain());
92 | assertEquals("resource", jid.getResource());
93 | }
94 |
95 | @Test
96 | public void testC2BareJID() {
97 | // setup
98 | final JID jid = new JID("node", "domain", null);
99 |
100 | // verify
101 | assertEquals("node", jid.getNode());
102 | assertEquals("domain", jid.getDomain());
103 | assertNull(jid.getResource());
104 | }
105 |
106 | @Test
107 | public void testC2JIDWithoutNode() {
108 | // setup
109 | final JID jid = new JID(null, "domain", "resource");
110 |
111 | // verify
112 | assertNull(jid.getNode());
113 | assertEquals("domain", jid.getDomain());
114 | assertEquals("resource", jid.getResource());
115 | }
116 |
117 | @Test
118 | public void testC2BareJIDWithoutNode() {
119 | // setup
120 | final JID jid = new JID(null, "domain", null);
121 |
122 | // verify
123 | assertNull(jid.getNode());
124 | assertEquals("domain", jid.getDomain());
125 | assertNull(jid.getResource());
126 | }
127 |
128 | /**
129 | * Verifies that {@link JID#toBareJID()} returns a correct representation of
130 | * the JID instance when the original JID was a full JID.
131 | */
132 | @Test
133 | public void testFullJIDToBareJID() throws Exception {
134 |
135 | // setup
136 | final String node = "node";
137 | final String domain = "domain";
138 | final String resource = "resource";
139 | final JID jid = new JID(node, domain, resource);
140 |
141 | // do magic
142 | final String bare = jid.toBareJID();
143 |
144 | // verify
145 | assertEquals(node + "@" + domain, bare);
146 | }
147 |
148 | /**
149 | * Verifies that {@link JID#toBareJID()} returns a correct representation of
150 | * the JID instance when the original JID was a bare JID.
151 | */
152 | @Test
153 | public void testBareJIDToBareJID() throws Exception {
154 |
155 | // setup
156 | final String node = "node";
157 | final String domain = "domain";
158 | final JID jid = new JID(node, domain, null);
159 |
160 | // do magic
161 | final String bare = jid.toBareJID();
162 |
163 | // verify
164 | assertEquals(node + "@" + domain, bare);
165 | }
166 |
167 | /**
168 | * Verifies that {@link JID#asBareJID()} returns a correct representation of
169 | * the JID instance when the original JID was a full JID.
170 | *
171 | * @see TINDER-68
172 | */
173 | @Test
174 | public void testFullJIDAsBareJID() throws Exception {
175 |
176 | // setup
177 | final String node = "node";
178 | final String domain = "domain";
179 | final String resource = "resource";
180 | final JID jid = new JID(node, domain, resource);
181 |
182 | // do magic
183 | final JID bare = jid.asBareJID();
184 |
185 | // verify
186 | assertEquals(node + "@" + domain, bare.toString());
187 | }
188 |
189 | /**
190 | * Verifies that {@link JID#asBareJID()} returns a correct representation of
191 | * the JID instance when the original JID was a bare JID.
192 | *
193 | * @see TINDER-68
194 | */
195 | @Test
196 | public void tesBareJIDAsBareJID() throws Exception {
197 |
198 | // setup
199 | final String node = "node";
200 | final String domain = "domain";
201 | final JID jid = new JID(node, domain, null);
202 |
203 | // do magic
204 | final JID bare = jid.asBareJID();
205 |
206 | // verify
207 | assertEquals(node + "@" + domain, bare.toString());
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/src/test/java/org/xmpp/packet/JIDSerializabilityTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2004-2009 Jive Software. All rights reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.xmpp.packet;
18 |
19 | import static org.junit.Assert.assertEquals;
20 | import static org.junit.Assert.assertTrue;
21 |
22 | import java.io.ByteArrayInputStream;
23 | import java.io.ByteArrayOutputStream;
24 | import java.io.InputStream;
25 | import java.io.ObjectInputStream;
26 | import java.io.ObjectOutputStream;
27 |
28 | import org.junit.Test;
29 |
30 | /**
31 | * Various tests that verify the serializability of JID instances.
32 | *
33 | * @author Guus der Kinderen, guus.der.kinderen@gmail.com
34 | * @see Based on Testing object serialization
37 | */
38 | public class JIDSerializabilityTest {
39 |
40 | /**
41 | * The first serialization test you usually write is one that verifies
42 | * serialization is possible. Even if a class implements Serializable,
43 | * there's no guarantee that it can be serialized. For instance, if a
44 | * serializable container such as an ArrayList contains a non-serializable
45 | * object such as a Socket, it throws a NotSerializableException when you
46 | * try to serialize it.
47 | *
48 | * Usually for this test, you just write the data onto a
49 | * ByteArrayOutputStream. If no exception is thrown, the test passes. If you
50 | * like, you can also test that some output has been written
51 | *
52 | * @see Testing
54 | * object serialization
55 | */
56 | @Test
57 | public void testIsSerializable() throws Exception {
58 | // setup
59 | JID test = new JID("a", "b.com", "c");
60 | ByteArrayOutputStream out = new ByteArrayOutputStream();
61 |
62 | // do magic
63 | ObjectOutputStream oos = new ObjectOutputStream(out);
64 | oos.writeObject(test);
65 | oos.close();
66 |
67 | // verify
68 | assertTrue(out.toByteArray().length > 0);
69 | }
70 |
71 | /**
72 | * You want to write a test that verifies not only that the output is
73 | * present, but that it's correct. Deserialize the object and compare it to
74 | * the original.
75 | *
76 | * @see Testing
78 | * object serialization
79 | */
80 | @Test
81 | public void testRoundTripSerialization() throws Exception {
82 |
83 | // construct test object
84 | JID original = new JID("a", "b.com", "c");
85 |
86 | // serialize
87 | ByteArrayOutputStream out = new ByteArrayOutputStream();
88 | ObjectOutputStream oos = new ObjectOutputStream(out);
89 | oos.writeObject(original);
90 | oos.close();
91 |
92 | // deserialize
93 | byte[] pickled = out.toByteArray();
94 | InputStream in = new ByteArrayInputStream(pickled);
95 | ObjectInputStream ois = new ObjectInputStream(in);
96 | Object o = ois.readObject();
97 | JID copy = (JID) o;
98 |
99 | // test the result
100 | assertEquals(original.getNode(), copy.getNode());
101 | assertEquals(original.getDomain(), copy.getDomain());
102 | assertEquals(original.getResource(), copy.getResource());
103 | }
104 |
105 | /**
106 | * You usually can't rely on the default serialization format to retain
107 | * file-format compatibility between different versions of a class. You have
108 | * to customize it in a variety of ways using serialPersistentFields,
109 | * readObject() and writeObject() methods, and/or the transient modifier. If
110 | * you do make an incompatible change to the serialization format of a
111 | * class, you should also change the serialVersionUID field to indicate that
112 | * you've done so.
113 | *