This is an automated email from the ASF dual-hosted git repository.

ralaoui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-vysper.git


The following commit(s) were added to refs/heads/master by this push:
     new 0a46416  XEP-0059 Result Set Management (#11)
0a46416 is described below

commit 0a46416bda4fbb26d111caed055d2b0ecc3f31f2
Author: Réda Housni Alaoui <rala...@apache.org>
AuthorDate: Sat Aug 17 09:18:25 2019 +0200

    XEP-0059 Result Set Management (#11)
---
 .../ResultSetManagementModule.java                 |  57 +++++
 .../xep0059_result_set_management/Set.java         | 240 +++++++++++++++++++++
 .../apache/vysper/xmpp/protocol/NamespaceURIs.java |   2 +
 .../org/apache/vysper/xmpp/server/XMPPServer.java  |   2 +
 .../ResultSetManagementTest.java                   |  49 +++++
 5 files changed, 350 insertions(+)

diff --git 
a/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0059_result_set_management/ResultSetManagementModule.java
 
b/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0059_result_set_management/ResultSetManagementModule.java
new file mode 100644
index 0000000..eba188e
--- /dev/null
+++ 
b/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0059_result_set_management/ResultSetManagementModule.java
@@ -0,0 +1,57 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *  
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0059_result_set_management;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.vysper.xmpp.modules.DefaultDiscoAwareModule;
+import org.apache.vysper.xmpp.modules.servicediscovery.management.Feature;
+import org.apache.vysper.xmpp.modules.servicediscovery.management.InfoElement;
+import org.apache.vysper.xmpp.modules.servicediscovery.management.InfoRequest;
+import 
org.apache.vysper.xmpp.modules.servicediscovery.management.ServerInfoRequestListener;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+
+/**
+ * @author Réda Housni Alaoui
+ */
+public class ResultSetManagementModule extends DefaultDiscoAwareModule 
implements ServerInfoRequestListener {
+    @Override
+    public String getName() {
+        return "XEP-0059 Result Set Management";
+    }
+
+    @Override
+    public String getVersion() {
+        return "1.0";
+    }
+
+    @Override
+    public List<InfoElement> getServerInfosFor(InfoRequest request) {
+        if (StringUtils.isNotEmpty(request.getNode())) {
+            return null;
+        }
+
+        List<InfoElement> infoElements = new ArrayList<>();
+        infoElements.add(new 
Feature(NamespaceURIs.XEP0059_RESULT_SET_MANAGEMENT));
+        return infoElements;
+    }
+}
diff --git 
a/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0059_result_set_management/Set.java
 
b/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0059_result_set_management/Set.java
new file mode 100644
index 0000000..680ce68
--- /dev/null
+++ 
b/server/core/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0059_result_set_management/Set.java
@@ -0,0 +1,240 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *  
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0059_result_set_management;
+
+import static java.util.Objects.requireNonNull;
+import static java.util.Optional.ofNullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.OptionalInt;
+
+import org.apache.vysper.xml.fragment.Attribute;
+import org.apache.vysper.xml.fragment.XMLElement;
+import org.apache.vysper.xml.fragment.XMLFragment;
+import org.apache.vysper.xml.fragment.XMLSemanticError;
+import org.apache.vysper.xml.fragment.XMLText;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+
+/**
+ * The Set element as defined by
+ * <a href="https://xmpp.org/extensions/xep-0059.html#schema";>XEP-0059 Result
+ * Set Management</a>
+ * 
+ * @author Réda Housni Alaoui
+ */
+public class Set {
+
+    private static final String ELEMENT_NAME = "set";
+
+    private static final String FIRST = "first";
+
+    private static final String INDEX = "index";
+
+    private final XMLElement element;
+
+    public Set(XMLElement element) {
+        if (!ELEMENT_NAME.equals(element.getName())) {
+            throw new IllegalArgumentException("ResultSetManagement element 
must be named '" + ELEMENT_NAME
+                    + "' instead of '" + element.getName() + "'");
+        }
+        if 
(!NamespaceURIs.XEP0059_RESULT_SET_MANAGEMENT.equals(element.getNamespaceURI()))
 {
+            throw new IllegalArgumentException("ResultSetManagement element 
must be bound to namespace uri '"
+                    + NamespaceURIs.XEP0059_RESULT_SET_MANAGEMENT + "' instead 
of '" + element.getNamespaceURI() + "'");
+        }
+        this.element = element;
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public Optional<String> getAfter() throws XMLSemanticError {
+        return getElementText("after");
+    }
+
+    public Optional<String> getBefore() throws XMLSemanticError {
+        return getElementText("before");
+    }
+
+    public OptionalInt getCount() throws XMLSemanticError {
+        return getElementInt("count");
+    }
+
+    public Optional<First> getFirst() throws XMLSemanticError {
+        return 
ofNullable(element.getSingleInnerElementsNamed(FIRST)).map(First::new);
+    }
+
+    public OptionalInt getIndex() throws XMLSemanticError {
+        return getElementInt(INDEX);
+    }
+
+    public Optional<String> getLast() throws XMLSemanticError {
+        return getElementText("last");
+    }
+
+    public OptionalInt getMax() throws XMLSemanticError {
+        return getElementInt("max");
+    }
+
+    private Optional<String> getElementText(String elementName) throws 
XMLSemanticError {
+        return 
ofNullable(element.getSingleInnerElementsNamed(elementName)).map(XMLElement::getInnerText)
+                .map(XMLText::getText);
+    }
+
+    private OptionalInt getElementInt(String elementName) throws 
XMLSemanticError {
+        return 
getElementText(elementName).map(Integer::parseInt).map(OptionalInt::of).orElse(OptionalInt.empty());
+    }
+
+    public static class First {
+
+        private final XMLElement element;
+
+        private First(XMLElement element) {
+            this.element = element;
+        }
+
+        private XMLElement element() {
+            return element;
+        }
+
+        public String getValue() {
+            return element.getInnerText().getText();
+        }
+
+        public OptionalInt getIndex() {
+            return 
ofNullable(element.getAttributeValue(INDEX)).map(Integer::parseInt).map(OptionalInt::of)
+                    .orElse(OptionalInt.empty());
+        }
+
+    }
+
+    public static class Builder {
+
+        private String after;
+
+        private String before;
+
+        private Integer count;
+
+        private First first;
+
+        private Integer index;
+
+        private String last;
+
+        private Integer max;
+
+        private Builder() {
+
+        }
+
+        public Builder after(String after) {
+            this.after = after;
+            return this;
+        }
+
+        public Builder before(String before) {
+            this.before = before;
+            return this;
+        }
+
+        public Builder count(Integer count) {
+            this.count = count;
+            return this;
+        }
+
+        public FirstBuilder startFirst() {
+            return new FirstBuilder(this);
+        }
+
+        public Builder index(Integer index) {
+            this.index = index;
+            return this;
+        }
+
+        public Builder last(String last) {
+            this.last = last;
+            return this;
+        }
+
+        public Builder max(Integer max) {
+            this.max = max;
+            return this;
+        }
+
+        private XMLFragment createElement(String name, Object innerValue) {
+            return new XMLElement(null, name, null, Collections.emptyList(),
+                    Collections.singletonList(new 
XMLText(String.valueOf(innerValue))));
+        }
+
+        public Set build() {
+            List<XMLFragment> innerFragments = new ArrayList<>();
+            ofNullable(after).map(innerValue -> createElement("after", 
innerValue)).ifPresent(innerFragments::add);
+            ofNullable(before).map(innerValue -> createElement("before", 
innerValue)).ifPresent(innerFragments::add);
+            ofNullable(count).map(innerValue -> createElement("count", 
innerValue)).ifPresent(innerFragments::add);
+            
ofNullable(first).map(First::element).ifPresent(innerFragments::add);
+            ofNullable(index).map(innerValue -> createElement("index", 
innerValue)).ifPresent(innerFragments::add);
+            ofNullable(last).map(innerValue -> createElement("last", 
innerValue)).ifPresent(innerFragments::add);
+            ofNullable(max).map(innerValue -> createElement("max", 
innerValue)).ifPresent(innerFragments::add);
+
+            return new Set(new 
XMLElement(NamespaceURIs.XEP0059_RESULT_SET_MANAGEMENT, ELEMENT_NAME, null,
+                    Collections.emptyList(), innerFragments));
+        }
+
+    }
+
+    public static class FirstBuilder {
+
+        private final Builder builder;
+
+        private String value;
+
+        private Integer index;
+
+        private FirstBuilder(Builder builder) {
+            this.builder = requireNonNull(builder);
+        }
+
+        public FirstBuilder value(String value) {
+            this.value = value;
+            return this;
+        }
+
+        public FirstBuilder index(Integer index) {
+            this.index = index;
+            return this;
+        }
+
+        public Builder endFirst() {
+            List<Attribute> attributes = new ArrayList<>();
+            ofNullable(index).map(value -> new Attribute(INDEX, 
String.valueOf(index))).ifPresent(attributes::add);
+            List<XMLFragment> innerFragments = new ArrayList<>();
+            ofNullable(value).map(XMLText::new).ifPresent(innerFragments::add);
+
+            builder.first = new First(new XMLElement(null, FIRST, null, 
attributes, innerFragments));
+            return builder;
+        }
+
+    }
+
+}
diff --git 
a/server/core/src/main/java/org/apache/vysper/xmpp/protocol/NamespaceURIs.java 
b/server/core/src/main/java/org/apache/vysper/xmpp/protocol/NamespaceURIs.java
index 551a99e..56bc78c 100644
--- 
a/server/core/src/main/java/org/apache/vysper/xmpp/protocol/NamespaceURIs.java
+++ 
b/server/core/src/main/java/org/apache/vysper/xmpp/protocol/NamespaceURIs.java
@@ -109,4 +109,6 @@ public class NamespaceURIs {
     public static final String XEP0124_BOSH = 
"http://jabber.org/protocol/httpbind";;
     
     public static final String XEP0133_SERVICE_ADMIN = 
"http://jabber.org/protocol/admin";;
+    
+    public static final String XEP0059_RESULT_SET_MANAGEMENT = 
"http://jabber.org/protocol/rsm";;
 }
diff --git 
a/server/core/src/main/java/org/apache/vysper/xmpp/server/XMPPServer.java 
b/server/core/src/main/java/org/apache/vysper/xmpp/server/XMPPServer.java
index f22f66b..8f52c4e 100644
--- a/server/core/src/main/java/org/apache/vysper/xmpp/server/XMPPServer.java
+++ b/server/core/src/main/java/org/apache/vysper/xmpp/server/XMPPServer.java
@@ -42,6 +42,7 @@ import org.apache.vysper.xmpp.delivery.StanzaRelayBroker;
 import 
org.apache.vysper.xmpp.delivery.inbound.DeliveringExternalInboundStanzaRelay;
 import 
org.apache.vysper.xmpp.delivery.inbound.DeliveringInternalInboundStanzaRelay;
 import org.apache.vysper.xmpp.modules.Module;
+import 
org.apache.vysper.xmpp.modules.extension.xep0059_result_set_management.ResultSetManagementModule;
 import 
org.apache.vysper.xmpp.modules.extension.xep0160_offline_storage.OfflineStorageProvider;
 import org.apache.vysper.xmpp.modules.roster.RosterModule;
 import org.apache.vysper.xmpp.modules.servicediscovery.ServiceDiscoveryModule;
@@ -108,6 +109,7 @@ public class XMPPServer {
         // add default modules
         initialModules.add(new ServiceDiscoveryModule());
         initialModules.add(new RosterModule());
+        initialModules.add(new ResultSetManagementModule());
     }
 
     public void setSASLMechanisms(List<SASLMechanism> validMechanisms) {
diff --git 
a/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0059_result_set_management/ResultSetManagementTest.java
 
b/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0059_result_set_management/ResultSetManagementTest.java
new file mode 100644
index 0000000..c52dfd6
--- /dev/null
+++ 
b/server/core/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0059_result_set_management/ResultSetManagementTest.java
@@ -0,0 +1,49 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *  
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0059_result_set_management;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.vysper.xml.fragment.XMLSemanticError;
+import org.junit.Test;
+
+/**
+ * @author Réda Housni Alaoui
+ */
+public class ResultSetManagementTest {
+
+    @Test
+    public void parse() throws XMLSemanticError {
+        Set tested = 
Set.builder().after("after-value").before("before-value").count(5)
+                
.index(10).last("last-value").max(15).startFirst().index(20).value("first-value").endFirst().build();
+
+        assertEquals("after-value", tested.getAfter().get());
+        assertEquals("before-value", tested.getBefore().get());
+        assertEquals(5, tested.getCount().getAsInt());
+        assertEquals(10, tested.getIndex().getAsInt());
+        assertEquals("last-value", tested.getLast().get());
+        assertEquals(15, tested.getMax().getAsInt());
+
+        Set.First first = tested.getFirst().get();
+        assertEquals("first-value", first.getValue());
+        assertEquals(20, first.getIndex().getAsInt());
+    }
+
+}
\ No newline at end of file

Reply via email to