mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-09-11 10:09:38 +02:00
Merge branch '4.2'
This commit is contained in:
commit
026f3a2f8c
34 changed files with 2250 additions and 3 deletions
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup.element;
|
||||
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
||||
public class BlockQuoteElement implements MarkupElement.BlockLevelMarkupElement {
|
||||
|
||||
public static final String ELEMENT = "bquote";
|
||||
|
||||
private final int start, end;
|
||||
|
||||
/**
|
||||
* Create a new Block Quote element.
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
*/
|
||||
public BlockQuoteElement(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(this);
|
||||
xml.attribute(ATTR_START, getStart());
|
||||
xml.attribute(ATTR_END, getEnd());
|
||||
xml.closeEmptyElement();
|
||||
return xml;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup.element;
|
||||
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
||||
public class CodeBlockElement implements MarkupElement.BlockLevelMarkupElement {
|
||||
|
||||
public static final String ELEMENT = "bcode";
|
||||
|
||||
private final int start, end;
|
||||
|
||||
/**
|
||||
* Create a new Code Block element.
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
*/
|
||||
public CodeBlockElement(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(this);
|
||||
xml.attribute(ATTR_START, getStart());
|
||||
xml.attribute(ATTR_END, getEnd());
|
||||
xml.closeEmptyElement();
|
||||
return xml;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup.element;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.NamedElement;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
||||
public class ListElement implements MarkupElement.MarkupChildElement {
|
||||
|
||||
public static final String ELEMENT = "list";
|
||||
public static final String ELEM_LI = "li";
|
||||
|
||||
private final int start, end;
|
||||
private final List<ListEntryElement> entries;
|
||||
|
||||
/**
|
||||
* Create a new List element.
|
||||
*
|
||||
* @param start start index of the list
|
||||
* @param end end index of the list
|
||||
* @param entries list entries
|
||||
*/
|
||||
public ListElement(int start, int end, List<ListEntryElement> entries) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.entries = Collections.unmodifiableList(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all list entries.
|
||||
*
|
||||
* @return entries
|
||||
*/
|
||||
public List<ListEntryElement> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(this);
|
||||
xml.attribute(ATTR_START, getStart());
|
||||
xml.attribute(ATTR_END, getEnd());
|
||||
xml.rightAngleBracket();
|
||||
|
||||
for (ListEntryElement li : getEntries()) {
|
||||
xml.append(li.toXML());
|
||||
}
|
||||
|
||||
xml.closeElement(this);
|
||||
return xml;
|
||||
}
|
||||
|
||||
public static class ListEntryElement implements NamedElement {
|
||||
|
||||
private final int start;
|
||||
|
||||
/**
|
||||
* Create a new ListEntry element.
|
||||
*
|
||||
* @param start start index
|
||||
*/
|
||||
public ListEntryElement(int start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the start index of this entry.
|
||||
* @return start index
|
||||
*/
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEM_LI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(this);
|
||||
xml.attribute(ATTR_START, getStart());
|
||||
xml.closeEmptyElement();
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup.element;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.NamedElement;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
||||
public class MarkupElement implements ExtensionElement {
|
||||
|
||||
public static final String NAMESPACE = "urn:xmpp:markup:0";
|
||||
public static final String ELEMENT = "markup";
|
||||
|
||||
private final List<MarkupChildElement> childElements;
|
||||
|
||||
/**
|
||||
* Create a new MarkupElement.
|
||||
*
|
||||
* @param childElements child elements.
|
||||
*/
|
||||
public MarkupElement(List<MarkupChildElement> childElements) {
|
||||
this.childElements = Collections.unmodifiableList(childElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new Builder for Message Markup elements.
|
||||
* @return builder.
|
||||
*/
|
||||
public static Builder getBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all child elements.
|
||||
* @return children
|
||||
*/
|
||||
public List<MarkupChildElement> getChildElements() {
|
||||
return childElements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder(this).rightAngleBracket();
|
||||
|
||||
for (MarkupChildElement child : getChildElements()) {
|
||||
xml.append(child.toXML());
|
||||
}
|
||||
|
||||
xml.closeElement(this);
|
||||
return xml;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
private final List<SpanElement> spans = new ArrayList<>();
|
||||
private final List<BlockQuoteElement> quotes = new ArrayList<>();
|
||||
private final List<CodeBlockElement> codes = new ArrayList<>();
|
||||
private final List<ListElement> lists = new ArrayList<>();
|
||||
|
||||
private Builder() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a section of a message as deleted.
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
* @return builder
|
||||
*/
|
||||
public Builder setDeleted(int start, int end) {
|
||||
return addSpan(start, end, Collections.singleton(SpanElement.SpanStyle.deleted));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a section of a message as emphasized.
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
* @return builder
|
||||
*/
|
||||
public Builder setEmphasis(int start, int end) {
|
||||
return addSpan(start, end, Collections.singleton(SpanElement.SpanStyle.emphasis));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a section of a message as inline code.
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
* @return builder
|
||||
*/
|
||||
public Builder setCode(int start, int end) {
|
||||
return addSpan(start, end, Collections.singleton(SpanElement.SpanStyle.code));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a span element.
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
* @param styles list of text styles for that span
|
||||
* @return builder
|
||||
*/
|
||||
public Builder addSpan(int start, int end, Set<SpanElement.SpanStyle> styles) {
|
||||
verifyStartEnd(start, end);
|
||||
|
||||
for (SpanElement other : spans) {
|
||||
if ((start >= other.getStart() && start <= other.getEnd()) ||
|
||||
(end >= other.getStart() && end <= other.getEnd())) {
|
||||
throw new IllegalArgumentException("Spans MUST NOT overlap each other.");
|
||||
}
|
||||
}
|
||||
|
||||
spans.add(new SpanElement(start, end, styles));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a section of a message as block quote.
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
* @return builder
|
||||
*/
|
||||
public Builder setBlockQuote(int start, int end) {
|
||||
verifyStartEnd(start, end);
|
||||
|
||||
for (BlockQuoteElement other : quotes) {
|
||||
// 1 if out, 0 if on, -1 if in
|
||||
Integer s = start;
|
||||
Integer e = end;
|
||||
int startPos = s.compareTo(other.getStart()) * s.compareTo(other.getEnd());
|
||||
int endPos = e.compareTo(other.getStart()) * e.compareTo(other.getEnd());
|
||||
int allowed = startPos * endPos;
|
||||
|
||||
if (allowed < 1) {
|
||||
throw new IllegalArgumentException("BlockQuotes MUST NOT overlap each others boundaries");
|
||||
}
|
||||
}
|
||||
|
||||
quotes.add(new BlockQuoteElement(start, end));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a section of a message as a code block.
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
* @return builder
|
||||
*/
|
||||
public Builder setCodeBlock(int start, int end) {
|
||||
verifyStartEnd(start, end);
|
||||
|
||||
codes.add(new CodeBlockElement(start, end));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a list.
|
||||
*
|
||||
* @return list builder
|
||||
*/
|
||||
public Builder.ListBuilder beginList() {
|
||||
return new Builder.ListBuilder(this);
|
||||
}
|
||||
|
||||
public static final class ListBuilder {
|
||||
private final Builder markup;
|
||||
private final ArrayList<ListElement.ListEntryElement> entries = new ArrayList<>();
|
||||
private int end = -1;
|
||||
|
||||
private ListBuilder(Builder markup) {
|
||||
this.markup = markup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an entry to the list.
|
||||
* The start index of an entry must correspond to the end index of the previous entry
|
||||
* (if a previous entry exists.)
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
* @return list builder
|
||||
*/
|
||||
public Builder.ListBuilder addEntry(int start, int end) {
|
||||
verifyStartEnd(start, end);
|
||||
|
||||
ListElement.ListEntryElement last = entries.size() == 0 ? null : entries.get(entries.size() - 1);
|
||||
// Entries themselves do not store end values, that's why we store the last entries end value in this.end
|
||||
if (last != null && start != this.end) {
|
||||
throw new IllegalArgumentException("Next entries start must be equal to last entries end (" + this.end + ").");
|
||||
}
|
||||
entries.add(new ListElement.ListEntryElement(start));
|
||||
this.end = end;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* End the list.
|
||||
*
|
||||
* @return builder
|
||||
*/
|
||||
public Builder endList() {
|
||||
if (entries.size() > 0) {
|
||||
ListElement.ListEntryElement first = entries.get(0);
|
||||
ListElement list = new ListElement(first.getStart(), end, entries);
|
||||
markup.lists.add(list);
|
||||
}
|
||||
|
||||
return markup;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Message Markup element.
|
||||
*
|
||||
* @return extension element
|
||||
*/
|
||||
public MarkupElement build() {
|
||||
List<MarkupElement.MarkupChildElement> children = new ArrayList<>();
|
||||
children.addAll(spans);
|
||||
children.addAll(quotes);
|
||||
children.addAll(codes);
|
||||
children.addAll(lists);
|
||||
return new MarkupElement(children);
|
||||
}
|
||||
|
||||
private static void verifyStartEnd(int start, int end) {
|
||||
if (start >= end || start < 0) {
|
||||
throw new IllegalArgumentException("Start value (" + start + ") MUST be greater equal than 0 " +
|
||||
"and MUST be smaller than end value (" + end + ").");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for child elements.
|
||||
*/
|
||||
public interface MarkupChildElement extends NamedElement {
|
||||
|
||||
String ATTR_START = "start";
|
||||
String ATTR_END = "end";
|
||||
|
||||
/**
|
||||
* Return the start index of this element.
|
||||
*
|
||||
* @return start index
|
||||
*/
|
||||
int getStart();
|
||||
|
||||
/**
|
||||
* Return the end index of this element.
|
||||
*
|
||||
* @return end index
|
||||
*/
|
||||
int getEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for block level child elements.
|
||||
*/
|
||||
public interface BlockLevelMarkupElement extends MarkupChildElement {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup.element;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
||||
public class SpanElement implements MarkupElement.MarkupChildElement {
|
||||
|
||||
public static final String ELEMENT = "span";
|
||||
|
||||
private final int start, end;
|
||||
private final Set<SpanStyle> styles;
|
||||
|
||||
/**
|
||||
* Create a new Span element.
|
||||
*
|
||||
* @param start start index
|
||||
* @param end end index
|
||||
* @param styles list of styles that apply to this span
|
||||
*/
|
||||
public SpanElement(int start, int end, Set<SpanStyle> styles) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.styles = Collections.unmodifiableSet(styles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all styles of this span.
|
||||
*
|
||||
* @return styles
|
||||
*/
|
||||
public Set<SpanStyle> getStyles() {
|
||||
return styles;
|
||||
}
|
||||
|
||||
public static final String emphasis = "emphasis";
|
||||
public static final String code = "code";
|
||||
public static final String deleted = "deleted";
|
||||
|
||||
public enum SpanStyle {
|
||||
emphasis,
|
||||
code,
|
||||
deleted
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(this);
|
||||
xml.attribute(ATTR_START, getStart());
|
||||
xml.attribute(ATTR_END, getEnd());
|
||||
xml.rightAngleBracket();
|
||||
|
||||
for (SpanStyle style : getStyles()) {
|
||||
xml.halfOpenElement(style.toString()).closeEmptyElement();
|
||||
}
|
||||
|
||||
xml.closeElement(this);
|
||||
return xml;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* XEP-0394: Message Markup.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0394.html">XEP-0394: Message
|
||||
* Markup</a>
|
||||
*
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup.element;
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* XEP-0394: Message Markup.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0394.html">XEP-0394: Message
|
||||
* Markup</a>
|
||||
*
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup;
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup.provider;
|
||||
|
||||
import static org.xmlpull.v1.XmlPullParser.END_TAG;
|
||||
import static org.xmlpull.v1.XmlPullParser.START_TAG;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
import org.jivesoftware.smack.util.ParserUtils;
|
||||
import org.jivesoftware.smackx.message_markup.element.BlockQuoteElement;
|
||||
import org.jivesoftware.smackx.message_markup.element.CodeBlockElement;
|
||||
import org.jivesoftware.smackx.message_markup.element.ListElement;
|
||||
import org.jivesoftware.smackx.message_markup.element.MarkupElement;
|
||||
import org.jivesoftware.smackx.message_markup.element.SpanElement;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class MarkupElementProvider extends ExtensionElementProvider<MarkupElement> {
|
||||
|
||||
@Override
|
||||
public MarkupElement parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
|
||||
MarkupElement.Builder markup = MarkupElement.getBuilder();
|
||||
|
||||
int spanStart = -1, spanEnd = -1;
|
||||
Set<SpanElement.SpanStyle> spanStyles = new HashSet<>();
|
||||
|
||||
int listStart = -1, listEnd = -1;
|
||||
List<ListElement.ListEntryElement> lis = new ArrayList<>();
|
||||
|
||||
while (true) {
|
||||
int tag = parser.next();
|
||||
String name = parser.getName();
|
||||
int start, end;
|
||||
switch (tag) {
|
||||
case START_TAG:
|
||||
switch (name) {
|
||||
case BlockQuoteElement.ELEMENT:
|
||||
start = ParserUtils.getIntegerAttributeOrThrow(parser, BlockQuoteElement.ATTR_START,
|
||||
"Message Markup BlockQuoteElement MUST contain a 'start' attribute.");
|
||||
end = ParserUtils.getIntegerAttributeOrThrow(parser, BlockQuoteElement.ATTR_END,
|
||||
"Message Markup BlockQuoteElement MUST contain a 'end' attribute.");
|
||||
markup.setBlockQuote(start, end);
|
||||
break;
|
||||
|
||||
case CodeBlockElement.ELEMENT:
|
||||
start = ParserUtils.getIntegerAttributeOrThrow(parser, CodeBlockElement.ATTR_START,
|
||||
"Message Markup CodeBlockElement MUST contain a 'start' attribute.");
|
||||
end = ParserUtils.getIntegerAttributeOrThrow(parser, CodeBlockElement.ATTR_END,
|
||||
"Message Markup CodeBlockElement MUST contain a 'end' attribute.");
|
||||
markup.setCodeBlock(start, end);
|
||||
break;
|
||||
|
||||
case SpanElement.ELEMENT:
|
||||
spanStyles = new HashSet<>();
|
||||
spanStart = ParserUtils.getIntegerAttributeOrThrow(parser, SpanElement.ATTR_START,
|
||||
"Message Markup SpanElement MUST contain a 'start' attribute.");
|
||||
spanEnd = ParserUtils.getIntegerAttributeOrThrow(parser, SpanElement.ATTR_END,
|
||||
"Message Markup SpanElement MUST contain a 'end' attribute.");
|
||||
break;
|
||||
|
||||
case SpanElement.code:
|
||||
spanStyles.add(SpanElement.SpanStyle.code);
|
||||
break;
|
||||
|
||||
case SpanElement.emphasis:
|
||||
spanStyles.add(SpanElement.SpanStyle.emphasis);
|
||||
break;
|
||||
|
||||
case SpanElement.deleted:
|
||||
spanStyles.add(SpanElement.SpanStyle.deleted);
|
||||
break;
|
||||
|
||||
case ListElement.ELEMENT:
|
||||
lis = new ArrayList<>();
|
||||
listStart = ParserUtils.getIntegerAttributeOrThrow(parser, ListElement.ATTR_START,
|
||||
"Message Markup ListElement MUST contain a 'start' attribute.");
|
||||
listEnd = ParserUtils.getIntegerAttributeOrThrow(parser, ListElement.ATTR_END,
|
||||
"Message Markup ListElement MUST contain a 'end' attribute.");
|
||||
break;
|
||||
|
||||
case ListElement.ELEM_LI:
|
||||
start = ParserUtils.getIntegerAttributeOrThrow(parser, ListElement.ATTR_START,
|
||||
"Message Markup ListElement 'li' MUST contain a 'start' attribute.");
|
||||
lis.add(new ListElement.ListEntryElement(start));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case END_TAG:
|
||||
switch (name) {
|
||||
case SpanElement.ELEMENT:
|
||||
markup.addSpan(spanStart, spanEnd, spanStyles);
|
||||
spanStart = -1; spanEnd = -1;
|
||||
break;
|
||||
|
||||
case ListElement.ELEMENT:
|
||||
MarkupElement.Builder.ListBuilder listBuilder = markup.beginList();
|
||||
if (lis.size() > 0 && lis.get(0).getStart() != listStart) {
|
||||
throw new SmackException("Error while parsing incoming MessageMarkup ListElement: " +
|
||||
"'start' attribute of first 'li' element must equal 'start' attribute of list.");
|
||||
}
|
||||
for (int i = 0; i < lis.size(); i++) {
|
||||
int elemStart = lis.get(i).getStart();
|
||||
int elemEnd = i < lis.size() - 1 ? lis.get(i + 1).getStart() : listEnd;
|
||||
listBuilder.addEntry(elemStart, elemEnd);
|
||||
}
|
||||
listBuilder.endList();
|
||||
break;
|
||||
|
||||
case MarkupElement.ELEMENT:
|
||||
return markup.build();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* XEP-0394: Message Markup.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0394.html">XEP-0394: Message
|
||||
* Markup</a>
|
||||
*
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup.provider;
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.StanzaListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
||||
import org.jivesoftware.smack.filter.AndFilter;
|
||||
import org.jivesoftware.smack.filter.MessageTypeFilter;
|
||||
import org.jivesoftware.smack.filter.NotFilter;
|
||||
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
||||
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||
import org.jivesoftware.smack.filter.ToTypeFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.sid.element.OriginIdElement;
|
||||
|
||||
public final class StableUniqueStanzaIdManager extends Manager {
|
||||
|
||||
public static final String NAMESPACE = "urn:xmpp:sid:0";
|
||||
|
||||
private static final Map<XMPPConnection, StableUniqueStanzaIdManager> INSTANCES = new WeakHashMap<>();
|
||||
|
||||
// Filter for outgoing stanzas.
|
||||
private static final StanzaFilter OUTGOING_FILTER = new AndFilter(
|
||||
MessageTypeFilter.NORMAL_OR_CHAT_OR_HEADLINE,
|
||||
ToTypeFilter.ENTITY_FULL_OR_BARE_JID);
|
||||
|
||||
private static final StanzaFilter ORIGIN_ID_FILTER = new StanzaExtensionFilter(OriginIdElement.ELEMENT, NAMESPACE);
|
||||
|
||||
// Listener for outgoing stanzas that adds origin-ids to outgoing stanzas.
|
||||
private final StanzaListener stanzaListener = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza stanza) {
|
||||
OriginIdElement.addOriginId((Message) stanza);
|
||||
}
|
||||
};
|
||||
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor.
|
||||
* @param connection
|
||||
*/
|
||||
private StableUniqueStanzaIdManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the StableUniqueStanzaIdManager for the given connection.
|
||||
*
|
||||
* @param connection xmpp-connection
|
||||
* @return manager instance for the connection
|
||||
*/
|
||||
public static StableUniqueStanzaIdManager getInstanceFor(XMPPConnection connection) {
|
||||
StableUniqueStanzaIdManager manager = INSTANCES.get(connection);
|
||||
if (manager == null) {
|
||||
manager = new StableUniqueStanzaIdManager(connection);
|
||||
INSTANCES.put(connection, manager);
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start appending origin-id elements to outgoing stanzas and add the feature to disco.
|
||||
*/
|
||||
public synchronized void enable() {
|
||||
ServiceDiscoveryManager.getInstanceFor(connection()).addFeature(NAMESPACE);
|
||||
StanzaFilter filter = new AndFilter(OUTGOING_FILTER, new NotFilter(OUTGOING_FILTER));
|
||||
connection().addPacketInterceptor(stanzaListener, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop appending origin-id elements to outgoing stanzas and remove the feature from disco.
|
||||
*/
|
||||
public synchronized void disable() {
|
||||
ServiceDiscoveryManager.getInstanceFor(connection()).removeFeature(NAMESPACE);
|
||||
connection().removePacketInterceptor(stanzaListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if we automatically append origin-id elements to outgoing stanzas.
|
||||
*
|
||||
* @return true if functionality is enabled, otherwise false.
|
||||
*/
|
||||
public synchronized boolean isEnabled() {
|
||||
ServiceDiscoveryManager disco = ServiceDiscoveryManager.getInstanceFor(connection());
|
||||
return disco.includesFeature(NAMESPACE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid.element;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager;
|
||||
|
||||
public class OriginIdElement extends StableAndUniqueIdElement {
|
||||
|
||||
public static final String ELEMENT = "origin-id";
|
||||
|
||||
public OriginIdElement() {
|
||||
super();
|
||||
}
|
||||
|
||||
public OriginIdElement(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an origin-id element to a message and set the stanzas id to the same id as in the origin-id element.
|
||||
*
|
||||
* @param message message.
|
||||
*/
|
||||
public static OriginIdElement addOriginId(Message message) {
|
||||
OriginIdElement originId = new OriginIdElement();
|
||||
message.addExtension(originId);
|
||||
// TODO: Find solution to have both the originIds stanzaId and a nice to look at incremental stanzaID.
|
||||
// message.setStanzaId(originId.getId());
|
||||
return originId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if the message contains a origin-id element.
|
||||
*
|
||||
* @param message message
|
||||
* @return true if the message contains a origin-id, false otherwise.
|
||||
*/
|
||||
public static boolean hasOriginId(Message message) {
|
||||
return getOriginId(message) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the origin-id element of a message or null, if absent.
|
||||
*
|
||||
* @param message message
|
||||
* @return origin-id element
|
||||
*/
|
||||
public static OriginIdElement getOriginId(Message message) {
|
||||
return message.getExtension(OriginIdElement.ELEMENT, StableUniqueStanzaIdManager.NAMESPACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return StableUniqueStanzaIdManager.NAMESPACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML() {
|
||||
return new XmlStringBuilder(this)
|
||||
.attribute(ATTR_ID, getId())
|
||||
.closeEmptyElement();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid.element;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
public abstract class StableAndUniqueIdElement implements ExtensionElement {
|
||||
|
||||
public static final String ATTR_ID = "id";
|
||||
|
||||
private final String id;
|
||||
|
||||
public StableAndUniqueIdElement() {
|
||||
this.id = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public StableAndUniqueIdElement(String id) {
|
||||
if (StringUtils.isNullOrEmpty(id)) {
|
||||
throw new IllegalArgumentException("Argument 'id' cannot be null or empty.");
|
||||
}
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid.element;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager;
|
||||
|
||||
public class StanzaIdElement extends StableAndUniqueIdElement {
|
||||
|
||||
public static final String ELEMENT = "stanza-id";
|
||||
public static final String ATTR_BY = "by";
|
||||
|
||||
private final String by;
|
||||
|
||||
public StanzaIdElement(String by) {
|
||||
super();
|
||||
this.by = by;
|
||||
}
|
||||
|
||||
public StanzaIdElement(String id, String by) {
|
||||
super(id);
|
||||
this.by = by;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if a message contains a stanza-id element.
|
||||
*
|
||||
* @param message message
|
||||
* @return true if message contains stanza-id element, otherwise false.
|
||||
*/
|
||||
public static boolean hasStanzaId(Message message) {
|
||||
return getStanzaId(message) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stanza-id element of a message.
|
||||
*
|
||||
* @param message message
|
||||
* @return stanza-id element of a jid, or null if absent.
|
||||
*/
|
||||
public static StanzaIdElement getStanzaId(Message message) {
|
||||
return message.getExtension(StanzaIdElement.ELEMENT, StableUniqueStanzaIdManager.NAMESPACE);
|
||||
}
|
||||
|
||||
public String getBy() {
|
||||
return by;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return StableUniqueStanzaIdManager.NAMESPACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
return new XmlStringBuilder(this)
|
||||
.attribute(ATTR_ID, getId())
|
||||
.attribute(ATTR_BY, getBy())
|
||||
.closeEmptyElement();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Smack's API for XEP-0359: Stable and Unique Stanza IDs.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid.element;
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Smack's API for XEP-0359: Stable and Unique Stanza IDs.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid;
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid.provider;
|
||||
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
import org.jivesoftware.smackx.sid.element.OriginIdElement;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class OriginIdProvider extends ExtensionElementProvider<OriginIdElement> {
|
||||
|
||||
public static final OriginIdProvider TEST_INSTANCE = new OriginIdProvider();
|
||||
|
||||
@Override
|
||||
public OriginIdElement parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
return new OriginIdElement(parser.getAttributeValue(null, OriginIdElement.ATTR_ID));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid.provider;
|
||||
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
import org.jivesoftware.smackx.sid.element.StanzaIdElement;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class StanzaIdProvider extends ExtensionElementProvider<StanzaIdElement> {
|
||||
|
||||
public static StanzaIdProvider TEST_INSTANCE = new StanzaIdProvider();
|
||||
|
||||
@Override
|
||||
public StanzaIdElement parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
String id = parser.getAttributeValue(null, StanzaIdElement.ATTR_ID);
|
||||
String by = parser.getAttributeValue(null, StanzaIdElement.ATTR_BY);
|
||||
return new StanzaIdElement(id, by);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Smack's API for XEP-0359: Stable and Unique Stanza IDs.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid.provider;
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.spoiler;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
|
||||
public final class SpoilerManager extends Manager {
|
||||
|
||||
public static final String NAMESPACE_0 = "urn:xmpp:spoiler:0";
|
||||
|
||||
private static final Map<XMPPConnection, SpoilerManager> INSTANCES = new WeakHashMap<>();
|
||||
|
||||
private final ServiceDiscoveryManager serviceDiscoveryManager;
|
||||
|
||||
/**
|
||||
* Create a new SpoilerManager and add Spoiler to disco features.
|
||||
*
|
||||
* @param connection xmpp connection
|
||||
*/
|
||||
private SpoilerManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin announcing support for Spoiler messages.
|
||||
*/
|
||||
public void startAnnounceSupport() {
|
||||
serviceDiscoveryManager.addFeature(NAMESPACE_0);
|
||||
}
|
||||
|
||||
/**
|
||||
* End announcing support for Spoiler messages.
|
||||
*/
|
||||
public void stopAnnounceSupport() {
|
||||
serviceDiscoveryManager.removeFeature(NAMESPACE_0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the connections instance of the SpoilerManager.
|
||||
*
|
||||
* @param connection xmpp connection
|
||||
* @return SpoilerManager
|
||||
*/
|
||||
public static SpoilerManager getInstanceFor(XMPPConnection connection) {
|
||||
SpoilerManager manager = INSTANCES.get(connection);
|
||||
if (manager == null) {
|
||||
manager = new SpoilerManager(connection);
|
||||
INSTANCES.put(connection, manager);
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.spoiler.element;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
import org.jivesoftware.smackx.spoiler.SpoilerManager;
|
||||
|
||||
public class SpoilerElement implements ExtensionElement {
|
||||
|
||||
public static final String ELEMENT = "spoiler";
|
||||
public static final String NAMESPACE = SpoilerManager.NAMESPACE_0;
|
||||
|
||||
public static final SpoilerElement EMPTY = new SpoilerElement(null, null);
|
||||
|
||||
private final String hint;
|
||||
private final String language;
|
||||
|
||||
/**
|
||||
* Create a new SpoilerElement with a hint about a content and a language attribute.
|
||||
*
|
||||
* @param language language of the hint.
|
||||
* @param hint hint about the content.
|
||||
*/
|
||||
public SpoilerElement(String language, String hint) {
|
||||
if (StringUtils.isNotEmpty(language) && StringUtils.isNullOrEmpty(hint)) {
|
||||
throw new IllegalArgumentException("Hint cannot be null or empty if language is not empty.");
|
||||
}
|
||||
this.language = language;
|
||||
this.hint = hint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hint text of the spoiler.
|
||||
* May be null.
|
||||
*
|
||||
* @return hint text
|
||||
*/
|
||||
public String getHint() {
|
||||
return hint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a SpoilerElement to a message.
|
||||
*
|
||||
* @param message message to add the Spoiler to.
|
||||
*/
|
||||
public static void addSpoiler(Message message) {
|
||||
message.addExtension(SpoilerElement.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a SpoilerElement with a hint to a message.
|
||||
*
|
||||
* @param message Message to add the Spoiler to.
|
||||
* @param hint Hint about the Spoilers content.
|
||||
*/
|
||||
public static void addSpoiler(Message message, String hint) {
|
||||
message.addExtension(new SpoilerElement(null, hint));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a SpoilerElement with a hint in a certain language to a message.
|
||||
*
|
||||
* @param message Message to add the Spoiler to.
|
||||
* @param lang language of the Spoiler hint.
|
||||
* @param hint hint.
|
||||
*/
|
||||
public static void addSpoiler(Message message, String lang, String hint) {
|
||||
message.addExtension(new SpoilerElement(lang, hint));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true, if the message has at least one spoiler element.
|
||||
*
|
||||
* @param message message
|
||||
* @return true if message has spoiler extension
|
||||
*/
|
||||
public static boolean containsSpoiler(Message message) {
|
||||
return message.hasExtension(SpoilerElement.ELEMENT, NAMESPACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a map of all spoilers contained in a message.
|
||||
* The map uses the language of a spoiler as key.
|
||||
* If a spoiler has no language attribute, its key will be an empty String.
|
||||
*
|
||||
* @param message message
|
||||
* @return map of spoilers
|
||||
*/
|
||||
public static Map<String, String> getSpoilers(Message message) {
|
||||
if (!containsSpoiler(message)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
List<ExtensionElement> spoilers = message.getExtensions(SpoilerElement.ELEMENT, NAMESPACE);
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
||||
for (ExtensionElement e : spoilers) {
|
||||
SpoilerElement s = (SpoilerElement) e;
|
||||
if (s.getLanguage() == null || s.getLanguage().equals("")) {
|
||||
map.put("", s.getHint());
|
||||
} else {
|
||||
map.put(s.getLanguage(), s.getHint());
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the language of the hint.
|
||||
* May be null.
|
||||
*
|
||||
* @return language of hint text
|
||||
*/
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder(this);
|
||||
xml.optXmlLangAttribute(getLanguage());
|
||||
if (getHint() == null) {
|
||||
xml.closeEmptyElement();
|
||||
} else {
|
||||
xml.rightAngleBracket();
|
||||
xml.append(getHint());
|
||||
xml.closeElement(this);
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Smack's API for XEP-0382: Spoiler Messages.
|
||||
*/
|
||||
package org.jivesoftware.smackx.spoiler.element;
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Smack's API for XEP-0382: Spoiler Messages.
|
||||
*/
|
||||
package org.jivesoftware.smackx.spoiler;
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.spoiler.provider;
|
||||
|
||||
import static org.xmlpull.v1.XmlPullParser.END_TAG;
|
||||
import static org.xmlpull.v1.XmlPullParser.TEXT;
|
||||
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
import org.jivesoftware.smack.util.ParserUtils;
|
||||
import org.jivesoftware.smackx.spoiler.element.SpoilerElement;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class SpoilerProvider extends ExtensionElementProvider<SpoilerElement> {
|
||||
|
||||
public static SpoilerProvider INSTANCE = new SpoilerProvider();
|
||||
|
||||
@Override
|
||||
public SpoilerElement parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
String lang = ParserUtils.getXmlLang(parser);
|
||||
String hint = null;
|
||||
|
||||
outerloop: while (true) {
|
||||
int tag = parser.next();
|
||||
switch (tag) {
|
||||
case TEXT:
|
||||
hint = parser.getText();
|
||||
break;
|
||||
case END_TAG:
|
||||
break outerloop;
|
||||
}
|
||||
}
|
||||
return new SpoilerElement(lang, hint);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Smack's API for XEP-0382: Spoiler Messages.
|
||||
*/
|
||||
package org.jivesoftware.smackx.spoiler.provider;
|
|
@ -211,6 +211,18 @@
|
|||
<className>org.jivesoftware.smackx.push_notifications.provider.RemoteDisablingProvider</className>
|
||||
</extensionProvider>
|
||||
|
||||
<!-- XEP-0359: Stable and Unique Stanza IDs -->
|
||||
<extensionProvider>
|
||||
<elementName>stanza-id</elementName>
|
||||
<namespace>urn:xmpp:sid:0</namespace>
|
||||
<className>org.jivesoftware.smackx.sid.provider.StanzaIdProvider</className>
|
||||
</extensionProvider>
|
||||
<extensionProvider>
|
||||
<elementName>origin-id</elementName>
|
||||
<namespace>urn:xmpp:sid:0</namespace>
|
||||
<className>org.jivesoftware.smackx.sid.provider.OriginIdProvider</className>
|
||||
</extensionProvider>
|
||||
|
||||
<!-- XEP-0333: Chat Markers -->
|
||||
<extensionProvider>
|
||||
<elementName>markable</elementName>
|
||||
|
@ -284,4 +296,18 @@
|
|||
<className>org.jivesoftware.smackx.eme.provider.ExplicitMessageEncryptionProvider</className>
|
||||
</extensionProvider>
|
||||
|
||||
<!-- XEP-0382: Spoiler Messages -->
|
||||
<extensionProvider>
|
||||
<elementName>spoiler</elementName>
|
||||
<namespace>urn:xmpp:spoiler:0</namespace>
|
||||
<className>org.jivesoftware.smackx.spoiler.provider.SpoilerProvider</className>
|
||||
</extensionProvider>
|
||||
|
||||
<!-- XEP-0394: Message Markup -->
|
||||
<extensionProvider>
|
||||
<elementName>markup</elementName>
|
||||
<namespace>urn:xmpp:markup:0</namespace>
|
||||
<className>org.jivesoftware.smackx.message_markup.provider.MarkupElementProvider</className>
|
||||
</extensionProvider>
|
||||
|
||||
</smackProviders>
|
||||
|
|
|
@ -6,5 +6,6 @@
|
|||
<className>org.jivesoftware.smackx.iot.provisioning.IoTProvisioningManager</className>
|
||||
<className>org.jivesoftware.smackx.httpfileupload.HttpFileUploadManager</className>
|
||||
<className>org.jivesoftware.smackx.eme.ExplicitMessageEncryptionManager</className>
|
||||
<className>org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager</className>
|
||||
</startupClasses>
|
||||
</smack>
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.message_markup;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smackx.message_markup.element.BlockQuoteElement;
|
||||
import org.jivesoftware.smackx.message_markup.element.CodeBlockElement;
|
||||
import org.jivesoftware.smackx.message_markup.element.ListElement;
|
||||
import org.jivesoftware.smackx.message_markup.element.MarkupElement;
|
||||
import org.jivesoftware.smackx.message_markup.element.SpanElement;
|
||||
import org.jivesoftware.smackx.message_markup.provider.MarkupElementProvider;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class MessageMarkupTest extends SmackTestSuite {
|
||||
|
||||
@Test
|
||||
public void emphasisTest() throws Exception {
|
||||
String xml =
|
||||
"<markup xmlns='urn:xmpp:markup:0'>" +
|
||||
"<span start='9' end='15'>" +
|
||||
"<emphasis/>" +
|
||||
"</span>" +
|
||||
"</markup>";
|
||||
MarkupElement.Builder m = MarkupElement.getBuilder();
|
||||
m.setEmphasis(9, 15);
|
||||
assertXMLEqual(xml, m.build().toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
MarkupElement parsed = new MarkupElementProvider().parse(parser);
|
||||
List<MarkupElement.MarkupChildElement> children = parsed.getChildElements();
|
||||
assertEquals(1, children.size());
|
||||
|
||||
SpanElement spanElement = (SpanElement) children.get(0);
|
||||
assertEquals(9, spanElement.getStart());
|
||||
assertEquals(15, spanElement.getEnd());
|
||||
assertEquals(1, spanElement.getStyles().size());
|
||||
assertEquals(SpanElement.SpanStyle.emphasis, spanElement.getStyles().iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void codeTest() throws Exception {
|
||||
String xml =
|
||||
"<markup xmlns='urn:xmpp:markup:0'>" +
|
||||
"<span start='9' end='15'>" +
|
||||
"<code/>" +
|
||||
"</span>" +
|
||||
"</markup>";
|
||||
MarkupElement.Builder m = MarkupElement.getBuilder();
|
||||
m.setCode(9, 15);
|
||||
assertXMLEqual(xml, m.build().toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
MarkupElement parsed = new MarkupElementProvider().parse(parser);
|
||||
List<MarkupElement.MarkupChildElement> children = parsed.getChildElements();
|
||||
assertEquals(1, children.size());
|
||||
|
||||
SpanElement spanElement = (SpanElement) children.get(0);
|
||||
assertEquals(9, spanElement.getStart());
|
||||
assertEquals(15, spanElement.getEnd());
|
||||
assertEquals(1, spanElement.getStyles().size());
|
||||
assertEquals(SpanElement.SpanStyle.code, spanElement.getStyles().iterator().next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletedTest() throws Exception {
|
||||
String xml =
|
||||
"<markup xmlns='urn:xmpp:markup:0'>" +
|
||||
"<span start='9' end='15'>" +
|
||||
"<deleted/>" +
|
||||
"</span>" +
|
||||
"</markup>";
|
||||
MarkupElement.Builder m = MarkupElement.getBuilder();
|
||||
m.setDeleted(9, 15);
|
||||
assertXMLEqual(xml, m.build().toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
MarkupElement parsed = new MarkupElementProvider().parse(parser);
|
||||
List<MarkupElement.MarkupChildElement> children = parsed.getChildElements();
|
||||
assertEquals(1, children.size());
|
||||
|
||||
SpanElement spanElement = (SpanElement) children.get(0);
|
||||
assertEquals(9, spanElement.getStart());
|
||||
assertEquals(15, spanElement.getEnd());
|
||||
assertEquals(1, spanElement.getStyles().size());
|
||||
assertEquals(SpanElement.SpanStyle.deleted, spanElement.getStyles().iterator().next());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void wrongStartEndTest() {
|
||||
MarkupElement.getBuilder().setEmphasis(12, 10);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void overlappingSpansTest() {
|
||||
MarkupElement.Builder m = MarkupElement.getBuilder();
|
||||
m.setEmphasis(0, 10);
|
||||
m.setDeleted(5, 15);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void codeBlockTest() throws Exception {
|
||||
String xml =
|
||||
"<markup xmlns='urn:xmpp:markup:0'>" +
|
||||
"<bcode start='23' end='48'/>" +
|
||||
"</markup>";
|
||||
MarkupElement.Builder m = MarkupElement.getBuilder();
|
||||
m.setCodeBlock(23, 48);
|
||||
assertXMLEqual(xml, m.build().toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
MarkupElement parsed = new MarkupElementProvider().parse(parser);
|
||||
List<MarkupElement.MarkupChildElement> children = parsed.getChildElements();
|
||||
assertEquals(1, children.size());
|
||||
|
||||
CodeBlockElement codeBlock = (CodeBlockElement) children.get(0);
|
||||
assertEquals(23, codeBlock.getStart());
|
||||
assertEquals(48, codeBlock.getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listTest() throws Exception {
|
||||
String xml =
|
||||
"<markup xmlns='urn:xmpp:markup:0'>" +
|
||||
"<list start='31' end='89'>" +
|
||||
"<li start='31'/>" +
|
||||
"<li start='47'/>" +
|
||||
"<li start='61'/>" +
|
||||
"<li start='69'/>" +
|
||||
"</list>" +
|
||||
"</markup>";
|
||||
MarkupElement.Builder m = MarkupElement.getBuilder();
|
||||
m = m.beginList()
|
||||
.addEntry(31, 47)
|
||||
.addEntry(47, 61)
|
||||
.addEntry(61, 69)
|
||||
.addEntry(69, 89)
|
||||
.endList();
|
||||
assertXMLEqual(xml, m.build().toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
MarkupElement parsed = new MarkupElementProvider().parse(parser);
|
||||
List<MarkupElement.MarkupChildElement> children = parsed.getChildElements();
|
||||
assertEquals(1, children.size());
|
||||
|
||||
ListElement list = (ListElement) children.get(0);
|
||||
assertEquals(31, list.getStart());
|
||||
assertEquals(89, list.getEnd());
|
||||
assertEquals(4, list.getEntries().size());
|
||||
assertEquals(list.getStart(), list.getEntries().get(0).getStart());
|
||||
assertEquals(47, list.getEntries().get(1).getStart());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void listWrongSecondEntryTest() {
|
||||
MarkupElement.Builder m = MarkupElement.getBuilder();
|
||||
m.beginList().addEntry(0,1).addEntry(3,4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void blockQuoteTest() throws Exception {
|
||||
String xml =
|
||||
"<markup xmlns='urn:xmpp:markup:0'>" +
|
||||
"<bquote start='9' end='32'/>" +
|
||||
"</markup>";
|
||||
MarkupElement.Builder m = MarkupElement.getBuilder();
|
||||
m.setBlockQuote(9 ,32);
|
||||
assertXMLEqual(xml, m.build().toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
MarkupElement parsed = new MarkupElementProvider().parse(parser);
|
||||
List<MarkupElement.MarkupChildElement> children = parsed.getChildElements();
|
||||
assertEquals(1, children.size());
|
||||
|
||||
BlockQuoteElement quote = (BlockQuoteElement) children.get(0);
|
||||
assertEquals(9, quote.getStart());
|
||||
assertEquals(32, quote.getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nestedBlockQuoteTest() throws Exception {
|
||||
String xml =
|
||||
"<markup xmlns='urn:xmpp:markup:0'>" +
|
||||
"<bquote start='0' end='57'/>" +
|
||||
"<bquote start='11' end='34'/>" +
|
||||
"</markup>";
|
||||
MarkupElement.Builder m = MarkupElement.getBuilder();
|
||||
m.setBlockQuote(0, 57);
|
||||
m.setBlockQuote(11, 34);
|
||||
assertXMLEqual(xml, m.build().toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
MarkupElement parsed = new MarkupElementProvider().parse(parser);
|
||||
List<MarkupElement.MarkupChildElement> children = parsed.getChildElements();
|
||||
assertEquals(2, children.size());
|
||||
|
||||
BlockQuoteElement q1 = (BlockQuoteElement) children.get(0);
|
||||
BlockQuoteElement q2 = (BlockQuoteElement) children.get(1);
|
||||
|
||||
assertEquals(0, q1.getStart());
|
||||
assertEquals(57, q1.getEnd());
|
||||
|
||||
assertEquals(11, q2.getStart());
|
||||
assertEquals(34, q2.getEnd());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.sid;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertFalse;
|
||||
import static junit.framework.TestCase.assertNotNull;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smackx.sid.element.OriginIdElement;
|
||||
import org.jivesoftware.smackx.sid.element.StanzaIdElement;
|
||||
import org.jivesoftware.smackx.sid.provider.OriginIdProvider;
|
||||
import org.jivesoftware.smackx.sid.provider.StanzaIdProvider;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class StableUniqueStanzaIdTest extends SmackTestSuite {
|
||||
|
||||
@Test
|
||||
public void stanzaIdProviderTest() throws Exception {
|
||||
String xml = "<stanza-id xmlns='urn:xmpp:sid:0' id='de305d54-75b4-431b-adb2-eb6b9e546013' by='alice@wonderland.lit' />";
|
||||
StanzaIdElement element = new StanzaIdElement("de305d54-75b4-431b-adb2-eb6b9e546013", "alice@wonderland.lit");
|
||||
assertEquals("de305d54-75b4-431b-adb2-eb6b9e546013", element.getId());
|
||||
assertEquals("alice@wonderland.lit", element.getBy());
|
||||
assertXMLEqual(xml, element.toXML().toString());
|
||||
|
||||
StanzaIdElement parsed = StanzaIdProvider.TEST_INSTANCE.parse(TestUtils.getParser(xml));
|
||||
assertEquals(element.getId(), parsed.getId());
|
||||
assertEquals(element.getBy(), parsed.getBy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void originIdProviderTest() throws Exception {
|
||||
String xml = "<origin-id xmlns='urn:xmpp:sid:0' id='de305d54-75b4-431b-adb2-eb6b9e546013' />";
|
||||
OriginIdElement element = new OriginIdElement("de305d54-75b4-431b-adb2-eb6b9e546013");
|
||||
assertEquals("de305d54-75b4-431b-adb2-eb6b9e546013", element.getId());
|
||||
assertXMLEqual(xml, element.toXML().toString());
|
||||
|
||||
OriginIdElement parsed = OriginIdProvider.TEST_INSTANCE.parse(TestUtils.getParser(xml));
|
||||
assertEquals(element.getId(), parsed.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createOriginIdTest() {
|
||||
OriginIdElement element = new OriginIdElement();
|
||||
assertNotNull(element);
|
||||
assertEquals(StableUniqueStanzaIdManager.NAMESPACE, element.getNamespace());
|
||||
assertEquals(36, element.getId().length());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromMessageTest() {
|
||||
Message message = new Message();
|
||||
assertFalse(OriginIdElement.hasOriginId(message));
|
||||
assertFalse(StanzaIdElement.hasStanzaId(message));
|
||||
|
||||
OriginIdElement.addOriginId(message);
|
||||
|
||||
assertTrue(OriginIdElement.hasOriginId(message));
|
||||
|
||||
StanzaIdElement stanzaId = new StanzaIdElement("alice@wonderland.lit");
|
||||
message.addExtension(stanzaId);
|
||||
assertTrue(StanzaIdElement.hasStanzaId(message));
|
||||
assertEquals(stanzaId, StanzaIdElement.getStanzaId(message));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2018 Paul Schaub
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.spoiler;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertNull;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smackx.spoiler.element.SpoilerElement;
|
||||
import org.jivesoftware.smackx.spoiler.provider.SpoilerProvider;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class SpoilerTest extends SmackTestSuite {
|
||||
|
||||
@Test
|
||||
public void emptySpoilerTest() throws Exception {
|
||||
final String xml = "<spoiler xmlns='urn:xmpp:spoiler:0'/>";
|
||||
|
||||
Message message = new Message();
|
||||
SpoilerElement.addSpoiler(message);
|
||||
|
||||
SpoilerElement empty = message.getExtension(SpoilerElement.ELEMENT, SpoilerManager.NAMESPACE_0);
|
||||
|
||||
assertNull(empty.getHint());
|
||||
assertNull(empty.getLanguage());
|
||||
|
||||
assertXMLEqual(xml, empty.toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
SpoilerElement parsed = SpoilerProvider.INSTANCE.parse(parser);
|
||||
assertXMLEqual(xml, parsed.toXML().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hintSpoilerTest() throws Exception {
|
||||
final String xml = "<spoiler xmlns='urn:xmpp:spoiler:0'>Love story end</spoiler>";
|
||||
|
||||
Message message = new Message();
|
||||
SpoilerElement.addSpoiler(message, "Love story end");
|
||||
|
||||
SpoilerElement withHint = message.getExtension(SpoilerElement.ELEMENT, SpoilerManager.NAMESPACE_0);
|
||||
|
||||
assertEquals("Love story end", withHint.getHint());
|
||||
assertNull(withHint.getLanguage());
|
||||
|
||||
assertXMLEqual(xml, withHint.toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
SpoilerElement parsed = SpoilerProvider.INSTANCE.parse(parser);
|
||||
|
||||
assertXMLEqual(xml, parsed.toXML().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void i18nHintSpoilerTest() throws Exception {
|
||||
final String xml = "<spoiler xml:lang='de' xmlns='urn:xmpp:spoiler:0'>Der Kuchen ist eine Lüge!</spoiler>";
|
||||
|
||||
Message message = new Message();
|
||||
SpoilerElement.addSpoiler(message, "de", "Der Kuchen ist eine Lüge!");
|
||||
|
||||
SpoilerElement i18nHint = message.getExtension(SpoilerElement.ELEMENT, SpoilerManager.NAMESPACE_0);
|
||||
|
||||
assertEquals("Der Kuchen ist eine Lüge!", i18nHint.getHint());
|
||||
assertEquals("de", i18nHint.getLanguage());
|
||||
|
||||
assertXMLEqual(xml, i18nHint.toXML().toString());
|
||||
|
||||
XmlPullParser parser = TestUtils.getParser(xml);
|
||||
SpoilerElement parsed = SpoilerProvider.INSTANCE.parse(parser);
|
||||
assertEquals(i18nHint.getLanguage(), parsed.getLanguage());
|
||||
|
||||
assertXMLEqual(xml, parsed.toXML().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSpoilersTest() {
|
||||
Message m = new Message();
|
||||
assertTrue(SpoilerElement.getSpoilers(m).isEmpty());
|
||||
|
||||
SpoilerElement.addSpoiler(m);
|
||||
assertTrue(SpoilerElement.containsSpoiler(m));
|
||||
|
||||
Map<String, String> spoilers = SpoilerElement.getSpoilers(m);
|
||||
assertEquals(1, spoilers.size());
|
||||
assertEquals(null, spoilers.get(""));
|
||||
|
||||
final String spoilerText = "Spoiler Text";
|
||||
|
||||
SpoilerElement.addSpoiler(m, "de", spoilerText);
|
||||
spoilers = SpoilerElement.getSpoilers(m);
|
||||
assertEquals(2, spoilers.size());
|
||||
assertEquals(spoilerText, spoilers.get("de"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void spoilerCheckArgumentsNullTest() {
|
||||
@SuppressWarnings("unused")
|
||||
SpoilerElement spoilerElement = new SpoilerElement("de", null);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void spoilerCheckArgumentsEmptyTest() {
|
||||
@SuppressWarnings("unused")
|
||||
SpoilerElement spoilerElement = new SpoilerElement("de", "");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue