Skip to content

Commit 3c31f0c

Browse files
committed
XEP-0084: User Avatars
Co-authored-by: vanitasvitae <[email protected]>
1 parent 5b23b9a commit 3c31f0c

File tree

18 files changed

+1543
-1
lines changed

18 files changed

+1543
-1
lines changed

documentation/extensions/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Smack Extensions and currently supported XEPs of smack-extensions
4949
| Advanced Message Processing | [XEP-0079](https://xmpp.org/extensions/xep-0079.html) | n/a | Enables entities to request, and servers to perform, advanced processing of XMPP message stanzas. |
5050
| User Location | [XEP-0080](https://xmpp.org/extensions/xep-0080.html) | n/a | Enabled communicating information about the current geographical or physical location of an entity. |
5151
| XMPP Date Time Profiles | [XEP-0082](https://xmpp.org/extensions/xep-0082.html) | n/a | Standardization of Date and Time representation in XMPP. |
52+
| User Avatar | [XEP-0084](https://xmpp.org/extensions/xep-0084.html) | 1.1.2 | Allows to exchange user avatars, which are small images or icons associated with human users. |
5253
| Chat State Notifications | [XEP-0085](https://xmpp.org/extensions/xep-0085.html) | n/a | Communicating the status of a user in a chat session. |
5354
| [Time Exchange](time.md) | [XEP-0090](https://xmpp.org/extensions/xep-0090.html) | n/a | Allows local time information to be shared between users. |
5455
| Software Version | [XEP-0092](https://xmpp.org/extensions/xep-0092.html) | n/a | Retrieve and announce the software application of an XMPP entity. |
@@ -78,7 +79,6 @@ Smack Extensions and currently supported XEPs of smack-extensions
7879
| [Group Chat Invitations](invitation.md) | n/a | n/a | Send invitations to other users to join a group chat room. |
7980
| [Jive Properties](properties.md) | n/a | n/a | TODO |
8081

81-
8282
Experimental Smack Extensions and currently supported XEPs of smack-experimental
8383
--------------------------------------------------------------------------------
8484

smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.IOException;
2020
import java.io.Writer;
21+
import java.net.URL;
2122
import java.util.Collection;
2223
import java.util.Date;
2324
import java.util.Iterator;
@@ -344,6 +345,13 @@ public XmlStringBuilder optAttribute(String name, Number number) {
344345
return this;
345346
}
346347

348+
public XmlStringBuilder optAttribute(String name, URL url) {
349+
if (url != null) {
350+
attribute(name, url.toExternalForm());
351+
}
352+
return this;
353+
}
354+
347355
/**
348356
* Add the given attribute if {@code value => 0}.
349357
*
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
*
3+
* Copyright 2019 Paul Schaub
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.jivesoftware.smackx.avatar;
18+
19+
import org.jxmpp.jid.EntityBareJid;
20+
21+
/**
22+
* The {@link AvatarMetadataStore} interface defines methods used by the {@link UserAvatarManager} to determine,
23+
* whether the client already has a local copy of a published avatar or if the user needs to be informed about the
24+
* update in order to download the image.
25+
*/
26+
public interface AvatarMetadataStore {
27+
28+
/**
29+
* Determine, if the client already has a copy of the avatar with {@code itemId} available or not.
30+
*
31+
* @param jid {@link EntityBareJid} of the entity that published the avatar.
32+
* @param itemId itemId of the avatar
33+
*
34+
* @return true if the client already has a local copy of the avatar, false otherwise
35+
*/
36+
boolean hasAvatarAvailable(EntityBareJid jid, String itemId);
37+
38+
/**
39+
* Mark the tuple (jid, itemId) as available. This means that the client already has a local copy of the avatar
40+
* available and wishes not to be notified about this particular avatar anymore.
41+
*
42+
* @param jid {@link EntityBareJid} of the entity that published the avatar.
43+
* @param itemId itemId of the avatar
44+
*/
45+
void setAvatarAvailable(EntityBareJid jid, String itemId);
46+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/**
2+
*
3+
* Copyright 2017 Fernando Ramirez, 2019 Paul Schaub
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.jivesoftware.smackx.avatar;
18+
19+
import java.net.URL;
20+
21+
import org.jivesoftware.smack.datatypes.UInt16;
22+
import org.jivesoftware.smack.datatypes.UInt32;
23+
import org.jivesoftware.smack.util.StringUtils;
24+
25+
/**
26+
* User Avatar metadata info model class.
27+
*
28+
* @author Fernando Ramirez
29+
* @author Paul Schaub
30+
* @see <a href="http://xmpp.org/extensions/xep-0084.html">XEP-0084: User
31+
* Avatar</a>
32+
*/
33+
public class MetadataInfo {
34+
35+
public static final int MAX_HEIGHT = 65536;
36+
public static final int MAX_WIDTH = 65536;
37+
38+
private final String id;
39+
private final URL url;
40+
private final UInt32 bytes;
41+
private final String type;
42+
private final UInt16 height;
43+
private final UInt16 width;
44+
45+
/**
46+
* MetadataInfo constructor.
47+
*
48+
* @param id SHA-1 hash of the image data
49+
* @param url http(s) url of the image
50+
* @param bytes size of the image in bytes
51+
* @param type content type of the image
52+
* @param pixelsHeight height of the image in pixels
53+
* @param pixelsWidth width of the image in pixels
54+
*/
55+
public MetadataInfo(String id, URL url, long bytes, String type, int pixelsHeight, int pixelsWidth) {
56+
this.id = StringUtils.requireNotNullNorEmpty(id, "ID is required.");
57+
this.url = url;
58+
this.bytes = UInt32.from(bytes);
59+
this.type = StringUtils.requireNotNullNorEmpty(type, "Content Type is required.");
60+
if (pixelsHeight < 0 || pixelsHeight > MAX_HEIGHT) {
61+
throw new IllegalArgumentException("Image height value must be between 0 and 65536.");
62+
}
63+
if (pixelsWidth < 0 || pixelsWidth > MAX_WIDTH) {
64+
throw new IllegalArgumentException("Image width value must be between 0 and 65536.");
65+
}
66+
this.height = UInt16.from(pixelsHeight);
67+
this.width = UInt16.from(pixelsWidth);
68+
}
69+
70+
/**
71+
* Get the id.
72+
*
73+
* @return the id
74+
*/
75+
public String getId() {
76+
return id;
77+
}
78+
79+
/**
80+
* Get the url of the avatar image.
81+
*
82+
* @return the url
83+
*/
84+
public URL getUrl() {
85+
return url;
86+
}
87+
88+
/**
89+
* Get the amount of bytes.
90+
*
91+
* @return the amount of bytes
92+
*/
93+
public UInt32 getBytes() {
94+
return bytes;
95+
}
96+
97+
/**
98+
* Get the type.
99+
*
100+
* @return the type
101+
*/
102+
public String getType() {
103+
return type;
104+
}
105+
106+
/**
107+
* Get the height in pixels.
108+
*
109+
* @return the height in pixels
110+
*/
111+
public UInt16 getHeight() {
112+
return height;
113+
}
114+
115+
/**
116+
* Get the width in pixels.
117+
*
118+
* @return the width in pixels
119+
*/
120+
public UInt16 getWidth() {
121+
return width;
122+
}
123+
124+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
*
3+
* Copyright 2017 Fernando Ramirez
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.jivesoftware.smackx.avatar;
18+
19+
import java.util.Map;
20+
21+
import org.jivesoftware.smack.util.StringUtils;
22+
23+
/**
24+
* User Avatar metadata pointer model class.
25+
* A pointer element is used to point to an avatar which is not published via PubSub or HTTP, but provided by a
26+
* third-party service.
27+
*
28+
* @author Fernando Ramirez
29+
* @see <a href="https://xmpp.org/extensions/xep-0084.html">XEP-0084: User Avatar</a>
30+
*/
31+
public class MetadataPointer {
32+
33+
private final String namespace;
34+
private final Map<String, Object> fields;
35+
36+
/**
37+
* Metadata Pointer constructor.
38+
*
39+
* The following example
40+
* <pre>
41+
* {@code
42+
* <pointer>
43+
* <x xmlns='http://example.com/virtualworlds'>
44+
* <game>Ancapistan</game>
45+
* <character>Kropotkin</character>
46+
* </x>
47+
* </pointer>
48+
* }
49+
* </pre>
50+
* can be created by constructing the object like this:
51+
* <pre>
52+
* {@code
53+
* Map fields = new HashMap<>();
54+
* fields.add("game", "Ancapistan");
55+
* fields.add("character", "Kropotkin");
56+
* MetadataPointer pointer = new MetadataPointer("http://example.com/virtualworlds", fields);
57+
* }
58+
* </pre>
59+
*
60+
* @param namespace namespace of the child element of the metadata pointer.
61+
* @param fields fields of the child element as key, value pairs.
62+
*/
63+
public MetadataPointer(String namespace, Map<String, Object> fields) {
64+
this.namespace = StringUtils.requireNotNullNorEmpty(namespace, "Namespace MUST NOT be null, nor empty.");
65+
this.fields = fields;
66+
}
67+
68+
/**
69+
* Get the namespace of the pointers child element.
70+
*
71+
* @return the namespace
72+
*/
73+
public String getNamespace() {
74+
return namespace;
75+
}
76+
77+
/**
78+
* Get the fields of the pointers child element.
79+
*
80+
* @return the fields
81+
*/
82+
public Map<String, Object> getFields() {
83+
return fields;
84+
}
85+
86+
}

0 commit comments

Comments
 (0)