-
Notifications
You must be signed in to change notification settings - Fork 884
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial support for XEP-0447: Stateless File Sharing
- Loading branch information
1 parent
e80c983
commit e3b0fd7
Showing
7 changed files
with
382 additions
and
0 deletions.
There are no files selected for viewing
88 changes: 88 additions & 0 deletions
88
.../main/java/org/jivesoftware/smackx/stateless_file_sharing/element/FileSharingElement.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/** | ||
* | ||
* 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.stateless_file_sharing.element; | ||
|
||
import javax.xml.namespace.QName; | ||
|
||
import org.jivesoftware.smack.packet.ExtensionElement; | ||
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.file_metadata.element.FileMetadataElement; | ||
|
||
public class FileSharingElement implements ExtensionElement { | ||
|
||
public static final String ELEMENT = "file-sharing"; | ||
public static final String NAMESPACE = "urn:xmpp:sfs:0"; | ||
public static final QName QNAME = new QName(NAMESPACE, ELEMENT); | ||
|
||
private final FileMetadataElement metadataElement; | ||
private final SourcesElement sourcesElement; | ||
|
||
public FileSharingElement(FileMetadataElement metadata, SourcesElement sources) { | ||
this.metadataElement = metadata; | ||
this.sourcesElement = sources; | ||
} | ||
|
||
public FileMetadataElement getMetadata() { | ||
return metadataElement; | ||
} | ||
|
||
public SourcesElement getSources() { | ||
return sourcesElement; | ||
} | ||
|
||
@Override | ||
public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { | ||
return new XmlStringBuilder(this) | ||
.rightAngleBracket() | ||
.append(getMetadata()) | ||
.append(getSources()) | ||
.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(getMetadata()) | ||
.append(getSources()) | ||
.build(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
return EqualsUtil.equals(this, obj, (equalsBuilder, other) -> | ||
equalsBuilder | ||
.append(getElementName(), other.getElementName()) | ||
.append(getNamespace(), other.getNamespace()) | ||
.append(getMetadata(), other.getMetadata()) | ||
.append(getSources(), other.getSources())); | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
.../src/main/java/org/jivesoftware/smackx/stateless_file_sharing/element/SourcesElement.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** | ||
* | ||
* 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.stateless_file_sharing.element; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
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.XmlStringBuilder; | ||
import org.jivesoftware.smackx.url_address_information.element.UrlDataElement; | ||
|
||
public class SourcesElement implements NamedElement { | ||
|
||
public static final String ELEMENT = "sources"; | ||
|
||
private final List<UrlDataElement> urlDataElements = new ArrayList<>(); | ||
private final List<ExtensionElement> otherSourceElements = new ArrayList<>(); | ||
|
||
public SourcesElement(List<UrlDataElement> urlDataElements, List<ExtensionElement> otherSourceElements) { | ||
this.urlDataElements.addAll(urlDataElements); | ||
this.otherSourceElements.addAll(otherSourceElements); | ||
} | ||
|
||
@Override | ||
public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { | ||
return new XmlStringBuilder(this) | ||
.rightAngleBracket() | ||
.append(getUrlDataElements()) | ||
.append(getOtherSourceElements()) | ||
.closeElement(this); | ||
} | ||
|
||
public List<UrlDataElement> getUrlDataElements() { | ||
return Collections.unmodifiableList(urlDataElements); | ||
} | ||
|
||
public List<ExtensionElement> getOtherSourceElements() { | ||
return Collections.unmodifiableList(otherSourceElements); | ||
} | ||
|
||
@Override | ||
public String getElementName() { | ||
return ELEMENT; | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
...al/src/main/java/org/jivesoftware/smackx/stateless_file_sharing/element/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
*/ | ||
/** | ||
* Element classes for XEP-0447: Stateless File Sharing. | ||
* | ||
* @see <a href="https://xmpp.org/extensions/xep-0447.html">XEP-0447: Stateless File Sharing</a> | ||
*/ | ||
package org.jivesoftware.smackx.stateless_file_sharing.element; |
22 changes: 22 additions & 0 deletions
22
...perimental/src/main/java/org/jivesoftware/smackx/stateless_file_sharing/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
*/ | ||
/** | ||
* Smack's API for XEP-0447: Stateless File Sharing. | ||
* | ||
* @see <a href="https://xmpp.org/extensions/xep-0447.html">XEP-0447: Stateless File Sharing</a> | ||
*/ | ||
package org.jivesoftware.smackx.stateless_file_sharing; |
82 changes: 82 additions & 0 deletions
82
...a/org/jivesoftware/smackx/stateless_file_sharing/provider/FileSharingElementProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* | ||
* 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.stateless_file_sharing.provider; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.jivesoftware.smack.packet.ExtensionElement; | ||
import org.jivesoftware.smack.packet.XmlEnvironment; | ||
import org.jivesoftware.smack.parsing.SmackParsingException; | ||
import org.jivesoftware.smack.parsing.StandardExtensionElementProvider; | ||
import org.jivesoftware.smack.provider.ExtensionElementProvider; | ||
import org.jivesoftware.smack.provider.ProviderManager; | ||
import org.jivesoftware.smack.xml.XmlPullParser; | ||
import org.jivesoftware.smack.xml.XmlPullParserException; | ||
import org.jivesoftware.smackx.file_metadata.element.FileMetadataElement; | ||
import org.jivesoftware.smackx.file_metadata.provider.FileMetadataElementProvider; | ||
import org.jivesoftware.smackx.stateless_file_sharing.element.FileSharingElement; | ||
import org.jivesoftware.smackx.stateless_file_sharing.element.SourcesElement; | ||
import org.jivesoftware.smackx.url_address_information.element.UrlDataElement; | ||
import org.jivesoftware.smackx.url_address_information.provider.UrlDataElementProvider; | ||
|
||
public class FileSharingElementProvider extends ExtensionElementProvider<FileSharingElement> { | ||
|
||
public static final FileSharingElementProvider INSTANCE = new FileSharingElementProvider(); | ||
|
||
@Override | ||
public FileSharingElement parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) | ||
throws XmlPullParserException, IOException, SmackParsingException { | ||
FileMetadataElement fileMetadataElement = null; | ||
SourcesElement sourcesElement = null; | ||
List<UrlDataElement> urlDataElements = new ArrayList<>(); | ||
List<ExtensionElement> otherSourceElements = new ArrayList<>(); | ||
do { | ||
XmlPullParser.TagEvent event = parser.nextTag(); | ||
String name = parser.getName(); | ||
|
||
if (event == XmlPullParser.TagEvent.START_ELEMENT) { | ||
if (name.equals(FileMetadataElement.ELEMENT)) { | ||
fileMetadataElement = FileMetadataElementProvider.TEST_INSTANCE.parse(parser, xmlEnvironment); | ||
} else if (name.equals(SourcesElement.ELEMENT)) { | ||
int innerDepth = parser.getDepth(); | ||
do { | ||
XmlPullParser.TagEvent innerEvent = parser.nextTag(); | ||
String innerName = parser.getName(); | ||
if (innerEvent.equals(XmlPullParser.TagEvent.START_ELEMENT)) { | ||
if (innerName.equals(UrlDataElement.ELEMENT)) { | ||
urlDataElements.add(UrlDataElementProvider.INSTANCE.parse(parser)); | ||
} else { | ||
ExtensionElementProvider<?> provider = ProviderManager.getExtensionProvider(innerName, parser.getNamespace()); | ||
if (provider == null) { | ||
provider = new StandardExtensionElementProvider(); | ||
} | ||
otherSourceElements.add(provider.parse(parser)); | ||
} | ||
} else { | ||
if (innerName.equals(SourcesElement.ELEMENT)) { | ||
sourcesElement = new SourcesElement(urlDataElements, otherSourceElements); | ||
} | ||
} | ||
} while (parser.getDepth() != innerDepth); | ||
} | ||
} | ||
} while (parser.getDepth() != initialDepth); | ||
return new FileSharingElement(fileMetadataElement, sourcesElement); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
...l/src/main/java/org/jivesoftware/smackx/stateless_file_sharing/provider/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
*/ | ||
/** | ||
* Provider classes for XEP-0447: Stateless File Sharing. | ||
* | ||
* @see <a href="https://xmpp.org/extensions/xep-0447.html">XEP-0447: Stateless File Sharing</a> | ||
*/ | ||
package org.jivesoftware.smackx.stateless_file_sharing.provider; |
84 changes: 84 additions & 0 deletions
84
.../src/test/java/org/jivesoftware/smackx/stateless_file_sharing/FileSharingElementTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package org.jivesoftware.smackx.stateless_file_sharing; | ||
|
||
import static org.jivesoftware.smack.test.util.XmlAssertUtil.assertXmlSimilar; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
import java.io.IOException; | ||
import java.util.Collections; | ||
|
||
import org.jivesoftware.smack.packet.StandardExtensionElement; | ||
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.file_metadata.element.FileMetadataElement; | ||
import org.jivesoftware.smackx.hashes.HashManager; | ||
import org.jivesoftware.smackx.hashes.element.HashElement; | ||
import org.jivesoftware.smackx.stateless_file_sharing.element.FileSharingElement; | ||
import org.jivesoftware.smackx.stateless_file_sharing.element.SourcesElement; | ||
import org.jivesoftware.smackx.stateless_file_sharing.provider.FileSharingElementProvider; | ||
import org.jivesoftware.smackx.url_address_information.element.UrlDataElement; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
public class FileSharingElementTest extends SmackTestSuite { | ||
|
||
@Test | ||
public void simpleElementTest() throws XmlPullParserException, IOException, SmackParsingException { | ||
FileSharingElement fileSharingElement = new FileSharingElement( | ||
FileMetadataElement.builder() | ||
.setMediaType("image/jpeg") | ||
.setName("summit.jpg") | ||
.setSize(3032449) | ||
.setDimensions(4096, 2160) | ||
.addHash(new HashElement(HashManager.ALGORITHM.SHA3_256, "2XarmwTlNxDAMkvymloX3S5+VbylNrJt/l5QyPa+YoU=")) | ||
.addHash(new HashElement(HashManager.ALGORITHM.BLAKE2B256, "2AfMGH8O7UNPTvUVAM9aK13mpCY=")) | ||
.addDescription("Photo from the summit.") | ||
.addOtherChildElement( | ||
StandardExtensionElement.builder("thumbnail", "urn:xmpp:thumbs:1") | ||
.addAttribute("uri", "cid:[email protected]") | ||
.addAttribute("media-type", "image/png") | ||
.addAttribute("width", "128") | ||
.addAttribute("height", "96") | ||
.build()) | ||
.build(), | ||
new SourcesElement(Collections.singletonList( | ||
new UrlDataElement( | ||
"https://download.montague.lit/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/summit.jpg", | ||
null | ||
) | ||
), Collections.singletonList( | ||
StandardExtensionElement.builder("jinglepub", "urn:xmpp:jinglepub:1") | ||
.addAttribute("from", "[email protected]/resource") | ||
.addAttribute("id", "9559976B-3FBF-4E7E-B457-2DAA225972BB") | ||
.addElement(new StandardExtensionElement("description", "urn:xmpp:jingle:apps:file-transfer:5")) | ||
.build() | ||
))); | ||
|
||
final String expectedXml = "" + | ||
" <file-sharing xmlns='urn:xmpp:sfs:0'>\n" + | ||
" <file xmlns='urn:xmpp:file:metadata:0'>\n" + | ||
" <media-type>image/jpeg</media-type>\n" + | ||
" <name>summit.jpg</name>\n" + | ||
" <size>3032449</size>\n" + | ||
" <dimensions>4096x2160</dimensions>\n" + | ||
" <hash xmlns='urn:xmpp:hashes:2' algo='sha3-256'>2XarmwTlNxDAMkvymloX3S5+VbylNrJt/l5QyPa+YoU=</hash>\n" + | ||
" <hash xmlns='urn:xmpp:hashes:2' algo='id-blake2b256'>2AfMGH8O7UNPTvUVAM9aK13mpCY=</hash>\n" + | ||
" <desc>Photo from the summit.</desc>\n" + | ||
" <thumbnail xmlns='urn:xmpp:thumbs:1' uri='cid:[email protected]' media-type='image/png' width='128' height='96'/>\n" + | ||
" </file>\n" + | ||
" <sources>\n" + | ||
" <url-data xmlns='http://jabber.org/protocol/url-data' target='https://download.montague.lit/4a771ac1-f0b2-4a4a-9700-f2a26fa2bb67/summit.jpg' />\n" + | ||
" <jinglepub xmlns='urn:xmpp:jinglepub:1' from='[email protected]/resource' id='9559976B-3FBF-4E7E-B457-2DAA225972BB'>" + | ||
" <description xmlns='urn:xmpp:jingle:apps:file-transfer:5' />\n" + | ||
" </jinglepub>\n" + | ||
" </sources>\n" + | ||
" </file-sharing>"; | ||
assertXmlSimilar(expectedXml, fileSharingElement.toXML().toString()); | ||
|
||
FileSharingElement parsed = FileSharingElementProvider.INSTANCE.parse(TestUtils.getParser(expectedXml)); | ||
// While I'd rather test for equality here, we have to compare XML instead, as thumbnail is not implemented | ||
// and we have to fall back to a StandardExtensionElement which has a non-ideal equals() implementation. | ||
assertXmlSimilar(expectedXml, parsed.toXML().toString()); | ||
} | ||
} |