diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/DescElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/DescElement.java new file mode 100644 index 000000000..255436d3c --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/DescElement.java @@ -0,0 +1,67 @@ +/** + * + * Copyright 2020 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.url_address_information.element; + +import org.jivesoftware.smack.packet.NamedElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.EqualsUtil; +import org.jivesoftware.smack.util.HashCode; +import org.jivesoftware.smack.util.XmlStringBuilder; + +public class DescElement implements NamedElement { + + public static final String ELEMENT = "desc"; + + private final String desc; + + public DescElement(String desc) { + this.desc = desc; + } + + public String getDesc() { + return desc; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this) + .rightAngleBracket() + .append(getDesc()) + .closeElement(this); + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public int hashCode() { + return HashCode.builder() + .append(getElementName()) + .append(getDesc()) + .build(); + } + + @Override + public boolean equals(Object obj) { + return EqualsUtil.equals(this, obj, (equalsBuilder, other) -> + equalsBuilder + .append(getElementName(), other.getElementName()) + .append(getDesc(), other.getDesc())); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/MetaInformationElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/MetaInformationElement.java new file mode 100644 index 000000000..88acf13e4 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/MetaInformationElement.java @@ -0,0 +1,22 @@ +/** + * + * Copyright 2020 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.url_address_information.element; + +import org.jivesoftware.smack.packet.NamedElement; + +public interface MetaInformationElement extends NamedElement { +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/UrlDataElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/UrlDataElement.java new file mode 100644 index 000000000..ad1317068 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/UrlDataElement.java @@ -0,0 +1,156 @@ +/** + * + * Copyright 2020 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.url_address_information.element; + +import java.util.ArrayList; +import java.util.List; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.NamedElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.EqualsUtil; +import org.jivesoftware.smack.util.HashCode; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.url_address_information.http.element.CookieElement; +import org.jivesoftware.smackx.url_address_information.http.element.HeaderElement; +import org.jivesoftware.smackx.url_address_information.http.element.HttpAuthElement; + +public class UrlDataElement implements ExtensionElement { + + public static final String ELEMENT = "url-data"; + public static final String NAMESPACE = "http://jabber.org/protocol/url-data"; + public static final String ATTR_TARGET = "target"; + public static final String ATTR_SID = "sid"; + public static final String XMLNS_HTTP = "xmlns:http"; + + public static final String SCHEME_HTTP = "http://jabber.org/protocol/url-data/scheme/http"; + + private final String target; + private final String sid; + private final List authParamElements = new ArrayList<>(); + private final List cookieElements = new ArrayList<>(); + private final List headerElements = new ArrayList<>(); + + public UrlDataElement(String target, + String sid) { + this(target, sid, null, null, null); + } + + public UrlDataElement(String target, + String sid, + List authParamElements, + List cookieElements, + List headerElements) { + this.target = target; + this.sid = sid; + if (authParamElements != null) { + this.authParamElements.addAll(authParamElements); + } + if (cookieElements != null) { + this.cookieElements.addAll(cookieElements); + } + if (headerElements != null) { + this.headerElements.addAll(headerElements); + } + } + + public String getTarget() { + return target; + } + + /** + * Return the optional stream identifier used for XEP-0095: Stream Initiation. + * + * @return stream identifier or null + */ + public String getSid() { + return sid; + } + + public List getAuthParameters() { + return authParamElements; + } + + public List getCookies() { + return cookieElements; + } + + public List getHeaders() { + return headerElements; + } + + private List getMetaInformationElements() { + List elements = new ArrayList<>(); + elements.addAll(getAuthParameters()); + elements.addAll(getCookies()); + elements.addAll(getHeaders()); + return elements; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + List metaInformation = getMetaInformationElements(); + + XmlStringBuilder sb = new XmlStringBuilder(this); + if (!metaInformation.isEmpty()) { + sb.attribute(XMLNS_HTTP, SCHEME_HTTP); + } + sb.attribute(ATTR_TARGET, getTarget()) + .optAttribute(ATTR_SID, getSid()); + if (metaInformation.isEmpty()) { + return sb.closeEmptyElement(); + } else { + return sb.rightAngleBracket() + .append(metaInformation) + .closeElement(this); + } + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public int hashCode() { + return HashCode.builder() + .append(getElementName()) + .append(getNamespace()) + .append(getTarget()) + .append(getAuthParameters()) + .append(getCookies()) + .append(getHeaders()) + .build(); + } + + @Override + public boolean equals(Object obj) { + return EqualsUtil.equals(this, obj, (equalsBuilder, other) -> + equalsBuilder + .append(getElementName(), other.getElementName()) + .append(getNamespace(), other.getNamespace()) + .append(getTarget(), other.getTarget()) + .append(getAuthParameters(), other.getAuthParameters()) + .append(getCookies(), other.getCookies()) + .append(getHeaders(), other.getHeaders())); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/package-info.java new file mode 100644 index 000000000..634a7f534 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/element/package-info.java @@ -0,0 +1,23 @@ +/** + * + * Copyright 2020 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. + */ + +/** + * Element classes for XEP-0103: URL Address Information. + * + * @see XEP-0103 - URL Address Information. + */ +package org.jivesoftware.smackx.url_address_information.element; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/AuthParamElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/AuthParamElement.java new file mode 100644 index 000000000..5497aab6c --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/AuthParamElement.java @@ -0,0 +1,77 @@ +/** + * + * Copyright 2020 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.url_address_information.http.element; + +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.EqualsUtil; +import org.jivesoftware.smack.util.HashCode; +import org.jivesoftware.smack.util.XmlStringBuilder; + +public class AuthParamElement extends NameValuePairElement { + + public static final String ELEMENT = "auth-param"; + public static final String PREFIX = "http"; + + public static final String NAME_REALM = "realm"; + public static final String NAME_USERNAME = "username"; + public static final String NAME_PASSWORD = "password"; + + public AuthParamElement(String name, String value) { + super(name, value); + } + + public static AuthParamElement realm(String realm) { + return new AuthParamElement(NAME_REALM, realm); + } + + public static AuthParamElement username(String username) { + return new AuthParamElement(NAME_USERNAME, username); + } + + public static AuthParamElement password(String password) { + return new AuthParamElement(NAME_PASSWORD, password); + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return addCommonXml(new XmlStringBuilder(this)) + .closeEmptyElement(); + } + + @Override + public String getElementName() { + return PREFIX + ':' + ELEMENT; + } + + @Override + public int hashCode() { + return HashCode.builder() + .append(getElementName()) + .append(getName()) + .append(getValue()) + .build(); + } + + @Override + public boolean equals(Object obj) { + return EqualsUtil.equals(this, obj, (equalsBuilder, other) -> + equalsBuilder + .append(getElementName(), other.getElementName()) + .append(getName(), other.getName()) + .append(getValue(), other.getValue())); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/CookieElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/CookieElement.java new file mode 100644 index 000000000..d590499a1 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/CookieElement.java @@ -0,0 +1,128 @@ +/** + * + * Copyright 2020 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.url_address_information.http.element; + +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.EqualsUtil; +import org.jivesoftware.smack.util.HashCode; +import org.jivesoftware.smack.util.XmlStringBuilder; + +public class CookieElement extends NameValuePairElement { + + public static final String ELEMENT = "cookie"; + public static final String PREFIX = "http"; + public static final String ATTR_DOMAIN = "domain"; + public static final String ATTR_MAX_AGE = "max-age"; + public static final String ATTR_PATH = "path"; + public static final String ATTR_COMMENT = "comment"; + public static final String ATTR_VERSION = "version"; + public static final String ATTR_SECURE = "secure"; + + private final String domain; + private final Integer maxAge; + private final String path; + private final String comment; + private final String version; + private final Boolean secure; + + public CookieElement(String name, String value) { + this(name, value, null, null, null, null, null, null); + } + + public CookieElement(String name, String value, String domain, Integer maxAge, String path, String comment, String version, Boolean secure) { + super(name, value); + this.domain = domain; + this.maxAge = maxAge; + this.path = path; + this.comment = comment; + this.version = version; + this.secure = secure; + } + + public String getPath() { + return path; + } + + public int getMaxAge() { + return maxAge == null ? 0 : maxAge; + } + + public String getDomain() { + return domain; + } + + public String getComment() { + return comment; + } + + public String getVersion() { + return version == null ? "1.0" : version; + } + + public boolean isSecure() { + return secure != null && secure; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + XmlStringBuilder sb = addCommonXml(new XmlStringBuilder(this)) + .optAttribute(ATTR_DOMAIN, domain) + .optAttribute(ATTR_MAX_AGE, maxAge) + .optAttribute(ATTR_PATH, path) + .optAttribute(ATTR_COMMENT, comment) + .optAttribute(ATTR_VERSION, version); + if (secure != null) { + sb.attribute(ATTR_SECURE, secure); + } + return sb.closeEmptyElement(); + } + + @Override + public String getElementName() { + return PREFIX + ':' + ELEMENT; + } + + @Override + public int hashCode() { + return HashCode.builder() + .append(getElementName()) + .append(getName()) + .append(getValue()) + .append(getDomain()) + .append(getMaxAge()) + .append(getPath()) + .append(getComment()) + .append(getVersion()) + .append(isSecure()) + .build(); + } + + @Override + public boolean equals(Object obj) { + return EqualsUtil.equals(this, obj, (equalsBuilder, other) -> + equalsBuilder + .append(getElementName(), other.getElementName()) + .append(getName(), other.getName()) + .append(getValue(), other.getValue()) + .append(getDomain(), other.getDomain()) + .append(getMaxAge(), other.getMaxAge()) + .append(getPath(), other.getPath()) + .append(getComment(), other.getComment()) + .append(getVersion(), other.getVersion()) + .append(isSecure(), other.isSecure())); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/HeaderElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/HeaderElement.java new file mode 100644 index 000000000..f49c5816c --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/HeaderElement.java @@ -0,0 +1,61 @@ +/** + * + * Copyright 2020 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.url_address_information.http.element; + +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.EqualsUtil; +import org.jivesoftware.smack.util.HashCode; +import org.jivesoftware.smack.util.XmlStringBuilder; + +public class HeaderElement extends NameValuePairElement { + + public static final String ELEMENT = "header"; + public static final String PREFIX = "http"; + + public HeaderElement(String name, String value) { + super(name, value); + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return addCommonXml(new XmlStringBuilder(this)) + .closeEmptyElement(); + } + + @Override + public String getElementName() { + return PREFIX + ':' + ELEMENT; + } + + @Override + public int hashCode() { + return HashCode.builder() + .append(getElementName()) + .append(getName()) + .append(getValue()) + .build(); + } + + @Override + public boolean equals(Object obj) { + return EqualsUtil.equals(this, obj, (equalsBuilder, other) -> + equalsBuilder + .append(getElementName(), other.getElementName()) + .append(getName(), other.getName()) + .append(getValue(), other.getValue())); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/HttpAuthElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/HttpAuthElement.java new file mode 100644 index 000000000..31c84e2cc --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/HttpAuthElement.java @@ -0,0 +1,122 @@ +/** + * + * Copyright 2020 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.url_address_information.http.element; + +import java.util.ArrayList; +import java.util.List; + +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.EqualsUtil; +import org.jivesoftware.smack.util.HashCode; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.url_address_information.element.MetaInformationElement; + +public final class HttpAuthElement implements MetaInformationElement { + + public static final String ELEMENT = "auth"; + public static final String PREFIX = "http"; + public static final String ATTR_SCHEME = "scheme"; + + public static final String SCHEME_BASIC = "basic"; + + private final String scheme; + private final List params = new ArrayList<>(); + + public HttpAuthElement(String scheme, List params) { + this.scheme = scheme; + if (params != null) { + this.params.addAll(params); + } + } + + public static HttpAuthElement basicAuth() { + return basicAuth(null, null); + } + + public static HttpAuthElement basicAuth(String username, String password) { + return basicAuth(null, username, password); + } + + public static HttpAuthElement basicAuth(String realm, String username, String password) { + List params = new ArrayList<>(); + if (realm != null) { + params.add(AuthParamElement.realm(realm)); + } + if (username != null) { + params.add(AuthParamElement.username(username)); + } + if (password != null) { + params.add(AuthParamElement.password(password)); + } + + return new HttpAuthElement(SCHEME_BASIC, params); + } + + public String getScheme() { + return scheme; + } + + public List getParams() { + return params; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + XmlStringBuilder sb = new XmlStringBuilder(this) + .attribute(ATTR_SCHEME, getScheme()); + if (getParams().isEmpty()) { + return sb.closeEmptyElement(); + } else { + return sb.rightAngleBracket() + .append(getParams()) + .closeElement(this); + } + } + + @Override + public String getElementName() { + return PREFIX + ':' + ELEMENT; + } + + public AuthParamElement getParam(String name) { + for (AuthParamElement param : getParams()) { + if (param.getName().equals(name)) { + return param; + } + } + return null; + } + + @Override + public int hashCode() { + return HashCode.builder() + .append(getElementName()) + .append(getScheme()) + .append(getParams()) + .build(); + } + + @Override + public boolean equals(Object obj) { + return EqualsUtil.equals(this, obj, (equalsBuilder, other) -> + equalsBuilder + .append(getElementName(), other.getElementName()) + .append(getScheme(), other.getScheme()) + .append(getParams(), other.getParams())); + } + +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/NameValuePairElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/NameValuePairElement.java new file mode 100644 index 000000000..0b54a2289 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/NameValuePairElement.java @@ -0,0 +1,48 @@ +/** + * + * Copyright 2020 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.url_address_information.http.element; + +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.url_address_information.element.MetaInformationElement; + +public abstract class NameValuePairElement implements MetaInformationElement { + + public static final String ATTR_NAME = "name"; + public static final String ATTR_VALUE = "value"; + + private final String name; + private final String value; + + public NameValuePairElement(String name, String value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + public XmlStringBuilder addCommonXml(XmlStringBuilder sb) { + return sb.attribute(ATTR_NAME, getName()) + .attribute(ATTR_VALUE, getValue()); + } + +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/package-info.java new file mode 100644 index 000000000..dd934e656 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/element/package-info.java @@ -0,0 +1,21 @@ +/** + * + * Copyright 2020 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. + */ + +/** + * Element classes for XEP-0104. + */ +package org.jivesoftware.smackx.url_address_information.http.element; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/package-info.java new file mode 100644 index 000000000..645cd1def --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/http/package-info.java @@ -0,0 +1,23 @@ +/** + * + * Copyright 2020 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-0104: HTTP Scheme for URL Address Information. + * + * @see XEP-0104 - HTTP Scheme for URL Address Information + */ +package org.jivesoftware.smackx.url_address_information.http; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/package-info.java new file mode 100644 index 000000000..0ad64cca1 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/package-info.java @@ -0,0 +1,21 @@ +/** + * + * Copyright 2020 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-0103 - URL Address Information. + */ +package org.jivesoftware.smackx.url_address_information; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/provider/UrlDataElementProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/provider/UrlDataElementProvider.java new file mode 100644 index 000000000..705975047 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/provider/UrlDataElementProvider.java @@ -0,0 +1,101 @@ +/** + * + * Copyright 2020 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.url_address_information.provider; + +import static org.jivesoftware.smackx.url_address_information.element.UrlDataElement.ATTR_SID; +import static org.jivesoftware.smackx.url_address_information.element.UrlDataElement.ATTR_TARGET; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.provider.ExtensionElementProvider; +import org.jivesoftware.smack.util.ParserUtils; +import org.jivesoftware.smack.xml.XmlPullParser; +import org.jivesoftware.smack.xml.XmlPullParserException; +import org.jivesoftware.smackx.url_address_information.element.UrlDataElement; +import org.jivesoftware.smackx.url_address_information.http.element.AuthParamElement; +import org.jivesoftware.smackx.url_address_information.http.element.CookieElement; +import org.jivesoftware.smackx.url_address_information.http.element.HeaderElement; +import org.jivesoftware.smackx.url_address_information.http.element.HttpAuthElement; + +public class UrlDataElementProvider extends ExtensionElementProvider { + + public static UrlDataElementProvider INSTANCE = new UrlDataElementProvider(); + @Override + public UrlDataElement parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { + String target = parser.getAttributeValue(ATTR_TARGET); + String sid = parser.getAttributeValue(ATTR_SID); + List authElements = new ArrayList<>(); + List cookieElements = new ArrayList<>(); + List headerElements = new ArrayList<>(); + do { + XmlPullParser.TagEvent event = parser.nextTag(); + String name = parser.getName(); + + if (event == XmlPullParser.TagEvent.START_ELEMENT) { + switch (name) { + case UrlDataElement.ELEMENT: + continue; + + case HttpAuthElement.ELEMENT: + String scheme = parser.getAttributeValue(HttpAuthElement.ATTR_SCHEME); + List authParamElements = new ArrayList<>(); + int innerDepth = parser.getDepth(); + do { + XmlPullParser.TagEvent innerTag = parser.nextTag(); + String innerName = parser.getName(); + if (innerTag.equals(XmlPullParser.TagEvent.START_ELEMENT)) { + if (innerName.equals(AuthParamElement.ELEMENT)) { + String attrName = ParserUtils.getRequiredAttribute(parser, AuthParamElement.ATTR_NAME); + String attrVal = ParserUtils.getRequiredAttribute(parser, AuthParamElement.ATTR_VALUE); + authParamElements.add(new AuthParamElement(attrName, attrVal)); + } + } + } while (parser.getDepth() != innerDepth); + + authElements.add(new HttpAuthElement(scheme, authParamElements)); + break; + + case CookieElement.ELEMENT: + String cookieName = ParserUtils.getRequiredAttribute(parser, CookieElement.ATTR_NAME); + String cookieValue = ParserUtils.getRequiredAttribute(parser, CookieElement.ATTR_VALUE); + String cookieDomain = parser.getAttributeValue(CookieElement.ATTR_DOMAIN); + Integer cookieMaxAge = ParserUtils.getIntegerAttribute(parser, CookieElement.ATTR_MAX_AGE); + String cookiePath = parser.getAttributeValue(CookieElement.ATTR_PATH); + String cookieComment = parser.getAttributeValue(CookieElement.ATTR_COMMENT); + Boolean cookieSecure = ParserUtils.getBooleanAttribute(parser, CookieElement.ATTR_SECURE); + String cookieVersion = parser.getAttributeValue(CookieElement.ATTR_VERSION); + + cookieElements.add(new CookieElement(cookieName, cookieValue, cookieDomain, cookieMaxAge, cookiePath, cookieComment, cookieVersion, cookieSecure)); + break; + + case HeaderElement.ELEMENT: + String headerName = ParserUtils.getRequiredAttribute(parser, HeaderElement.ATTR_NAME); + String headerValue = ParserUtils.getRequiredAttribute(parser, HeaderElement.ATTR_VALUE); + + headerElements.add(new HeaderElement(headerName, headerValue)); + break; + } + } + } while (parser.getDepth() != initialDepth); + + return new UrlDataElement(target, sid, authElements, cookieElements, headerElements); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/provider/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/provider/package-info.java new file mode 100644 index 000000000..eb2c9a21d --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/url_address_information/provider/package-info.java @@ -0,0 +1,23 @@ +/** + * + * Copyright 2020 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. + */ + +/** + * Provider classes for XEP-0103: URL Address Information. + * + * @see XEP-0103 - URL Address Information. + */ +package org.jivesoftware.smackx.url_address_information.provider; diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/url_address_information/UrlDataElementTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/url_address_information/UrlDataElementTest.java new file mode 100644 index 000000000..8e88ba3d1 --- /dev/null +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/url_address_information/UrlDataElementTest.java @@ -0,0 +1,216 @@ +/** + * + * Copyright 2020 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.url_address_information; + +import static org.jivesoftware.smack.test.util.XmlAssertUtil.assertXmlSimilar; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; + +import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.test.util.SmackTestSuite; +import org.jivesoftware.smack.test.util.TestUtils; +import org.jivesoftware.smack.xml.XmlPullParserException; +import org.jivesoftware.smackx.url_address_information.element.UrlDataElement; +import org.jivesoftware.smackx.url_address_information.http.element.CookieElement; +import org.jivesoftware.smackx.url_address_information.http.element.HeaderElement; +import org.jivesoftware.smackx.url_address_information.http.element.HttpAuthElement; +import org.jivesoftware.smackx.url_address_information.provider.UrlDataElementProvider; + +import org.junit.jupiter.api.Test; + +public class UrlDataElementTest extends SmackTestSuite { + + @Test + public void simpleSerializationTest() throws XmlPullParserException, IOException, SmackParsingException { + UrlDataElement urlDataElement = new UrlDataElement("http://www.jabber.org/members/index.php", + null, + Collections.singletonList(HttpAuthElement.basicAuth()), + null, null); + + final String expectedXml = "" + + "" + + "" + + ""; + assertXmlSimilar(expectedXml, urlDataElement.toXML().toString()); + + UrlDataElement parsed = UrlDataElementProvider.INSTANCE.parse(TestUtils.getParser(expectedXml)); + assertEquals(urlDataElement, parsed); + } + + @Test + public void additionalAuthParamTest() throws XmlPullParserException, IOException, SmackParsingException { + + UrlDataElement urlDataElement = new UrlDataElement("http://www.jabber.org/members/index.php", + null, + Collections.singletonList(HttpAuthElement.basicAuth( + "www.jabber.org", + "defaultuser", + "defaultpwd" + )), + null, + null); + + final String expectedXml = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " "; + assertXmlSimilar(expectedXml, urlDataElement.toXML().toString()); + + UrlDataElement parsed = UrlDataElementProvider.INSTANCE.parse(TestUtils.getParser(expectedXml)); + assertEquals(urlDataElement, parsed); + } + + @Test + public void simpleUrlWithSidTest() throws XmlPullParserException, IOException, SmackParsingException { + UrlDataElement urlDataElement = new UrlDataElement("http://pass.jabber.org:8519/test.txt", "a0"); + + final String expectedXml = ""; + assertXmlSimilar(expectedXml, urlDataElement.toXML().toString()); + + UrlDataElement parsed = UrlDataElementProvider.INSTANCE.parse(TestUtils.getParser(expectedXml)); + assertEquals(urlDataElement, parsed); + } + + @Test + public void simpleUrlNoChildrenTest() throws XmlPullParserException, IOException, SmackParsingException { + UrlDataElement urlDataElement = new UrlDataElement("http://festhall.outer-planes.net/d20M/announce/latest/", null); + + final String expectedXml = ""; + assertXmlSimilar(expectedXml, urlDataElement.toXML().toString()); + + UrlDataElement parsed = UrlDataElementProvider.INSTANCE.parse(TestUtils.getParser(expectedXml)); + assertEquals(urlDataElement, parsed); + } + + @Test + public void simpleCookieTest() throws XmlPullParserException, IOException, SmackParsingException { + UrlDataElement urlDataElement = new UrlDataElement("http://www.jabber.org/members/index.php", + null, + null, + Collections.singletonList(new CookieElement("jsessionid", "1243asd234190sa32ds")), + null); + + final String expectedXml = "" + + "\n" + + " \n" + + ""; + assertXmlSimilar(expectedXml, urlDataElement.toXML().toString()); + + UrlDataElement parsed = UrlDataElementProvider.INSTANCE.parse(TestUtils.getParser(expectedXml)); + assertEquals(urlDataElement, parsed); + } + + @Test + public void additionalParametersCookieTest() throws XmlPullParserException, IOException, SmackParsingException { + UrlDataElement urlDataElement = new UrlDataElement("http://www.jabber.org/members/index.php", + null, + null, + Collections.singletonList(new CookieElement( + "jsessionid", + "1243asd234190sa32ds", + "jabber.org", + 1234000, + "/members", + "Web Session Identifier", + "1.0", + false + )), + null); + + final String expectedXml = "\n" + + " \n" + + ""; + assertXmlSimilar(expectedXml, urlDataElement.toXML().toString()); + + UrlDataElement parsed = UrlDataElementProvider.INSTANCE.parse(TestUtils.getParser(expectedXml)); + assertEquals(urlDataElement, parsed); + } + + @Test + public void simpleHeaderTest() throws XmlPullParserException, IOException, SmackParsingException { + UrlDataElement urlDataElement = new UrlDataElement( + "http://www.jabber.org/members/index.php", + null, + null, + null, + Collections.singletonList(new HeaderElement("Custom-Data", "some custom data"))); + + final String expectedXml = "\n" + + " \n" + + " "; + assertXmlSimilar(expectedXml, urlDataElement.toXML().toString()); + + UrlDataElement parsed = UrlDataElementProvider.INSTANCE.parse(TestUtils.getParser(expectedXml)); + assertEquals(urlDataElement, parsed); + } + + @Test + public void multiChildTest() throws XmlPullParserException, IOException, SmackParsingException { + UrlDataElement urlDataElement = new UrlDataElement( + "https://blog.jabberhead.tk", + null, + Collections.singletonList(HttpAuthElement.basicAuth()), + Arrays.asList( + new CookieElement("jsessionid", "somecookievalue"), + new CookieElement("come2darkSide", "weHaveCookies")), + Arrays.asList( + new HeaderElement("Accept", "text/plain"), + new HeaderElement("Access-Control-Allow-Origin", "*"))); + + final String expectedXml = + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " "; + assertXmlSimilar(expectedXml, urlDataElement.toXML().toString()); + + UrlDataElement parsed = UrlDataElementProvider.INSTANCE.parse(TestUtils.getParser(expectedXml)); + assertEquals(urlDataElement, parsed); + } +}