1package im.conversations.android.xmpp.model;
 2
 3import com.google.common.base.Preconditions;
 4import com.google.common.collect.Collections2;
 5import com.google.common.collect.Iterables;
 6import eu.siacs.conversations.xml.Element;
 7import im.conversations.android.xmpp.ExtensionFactory;
 8import java.util.Collection;
 9
10public class Extension extends Element {
11
12    private Extension(final ExtensionFactory.Id id) {
13        super(id.name, id.namespace);
14    }
15
16    public Extension(final Class<? extends Extension> clazz) {
17        this(
18                Preconditions.checkNotNull(
19                        ExtensionFactory.id(clazz),
20                        String.format(
21                                "%s does not seem to be annotated with @XmlElement",
22                                clazz.getName())));
23        Preconditions.checkArgument(
24                getClass().equals(clazz), "clazz passed in constructor must match class");
25    }
26
27    public <E extends Extension> boolean hasExtension(final Class<E> clazz) {
28        return Iterables.any(getChildren(), clazz::isInstance);
29    }
30
31    public <E extends Extension> E getExtension(final Class<E> clazz) {
32        final var extension = Iterables.find(getChildren(), clazz::isInstance, null);
33        if (extension == null) {
34            return null;
35        }
36        return clazz.cast(extension);
37    }
38
39    public <E extends Extension> E getOnlyExtension(final Class<E> clazz) {
40        final var extensions = getExtensions(clazz);
41        if (extensions.size() == 1) {
42            return Iterables.getOnlyElement(extensions);
43        }
44        return null;
45    }
46
47    public <E extends Extension> Collection<E> getExtensions(final Class<E> clazz) {
48        return Collections2.transform(
49                Collections2.filter(getChildren(), clazz::isInstance), clazz::cast);
50    }
51
52    public Collection<ExtensionFactory.Id> getExtensionIds() {
53        return Collections2.transform(
54                getChildren(), c -> new ExtensionFactory.Id(c.getName(), c.getNamespace()));
55    }
56
57    public <T extends Extension> T addExtension(T child) {
58        this.addChild(child);
59        return child;
60    }
61
62    public <T extends Extension> T setExtension(T child) {
63        final var iterator = getChildren().iterator();
64        while (iterator.hasNext()) {
65            if (iterator.next().getClass().isInstance(child)) {
66                iterator.remove();
67            }
68        }
69        return this.addExtension(child);
70    }
71
72    public void addExtensions(final Collection<? extends Extension> extensions) {
73        for (final Extension extension : extensions) {
74            addExtension(extension);
75        }
76    }
77}