JingleFileTransferProvider.java

  1. /**
  2.  *
  3.  * Copyright 2017 Paul Schaub, 2019 Florian Schmaus
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smackx.jingle_filetransfer.provider;

  18. import java.io.IOException;
  19. import java.text.ParseException;
  20. import java.util.ArrayList;

  21. import org.jivesoftware.smack.packet.XmlEnvironment;
  22. import org.jivesoftware.smack.parsing.SmackParsingException;
  23. import org.jivesoftware.smack.util.ParserUtils;
  24. import org.jivesoftware.smack.xml.XmlPullParser;
  25. import org.jivesoftware.smack.xml.XmlPullParserException;

  26. import org.jivesoftware.smackx.hashes.element.HashElement;
  27. import org.jivesoftware.smackx.hashes.provider.HashElementProvider;
  28. import org.jivesoftware.smackx.jingle.element.JingleContentDescription;
  29. import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionChildElement;
  30. import org.jivesoftware.smackx.jingle.provider.JingleContentDescriptionProvider;
  31. import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransfer;
  32. import org.jivesoftware.smackx.jingle_filetransfer.element.JingleFileTransferChild;
  33. import org.jivesoftware.smackx.jingle_filetransfer.element.Range;

  34. import org.jxmpp.util.XmppDateTime;

  35. /**
  36.  * Provider for JingleContentDescriptionFileTransfer elements.
  37.  */
  38. public class JingleFileTransferProvider
  39.         extends JingleContentDescriptionProvider<JingleFileTransfer> {

  40.     @Override
  41.     public JingleFileTransfer parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException, ParseException {
  42.         ArrayList<JingleContentDescriptionChildElement> payloads = new ArrayList<>();
  43.         JingleFileTransferChild.Builder builder = JingleFileTransferChild.getBuilder();


  44.         String elementName;
  45.         while (true) {

  46.             XmlPullParser.TagEvent tag = parser.nextTag();

  47.             switch (tag) {
  48.             case START_ELEMENT:
  49.                 elementName = parser.getName();
  50.                 switch (elementName) {
  51.                     case JingleFileTransferChild.ELEM_DATE:
  52.                         builder.setDate(XmppDateTime.parseXEP0082Date(parser.nextText()));
  53.                         break;

  54.                     case JingleFileTransferChild.ELEM_DESC:
  55.                         builder.setDescription(parser.nextText());
  56.                         break;

  57.                     case JingleFileTransferChild.ELEM_MEDIA_TYPE:
  58.                         builder.setMediaType(parser.nextText());
  59.                         break;

  60.                     case JingleFileTransferChild.ELEM_NAME:
  61.                         builder.setName(parser.nextText());
  62.                         break;

  63.                     case JingleFileTransferChild.ELEM_SIZE:
  64.                         builder.setSize(Integer.parseInt(parser.nextText()));
  65.                         break;

  66.                     case Range.ELEMENT:
  67.                         Range range = parseRangeElement(parser);
  68.                         builder.setRange(range);

  69.                         break;

  70.                     case HashElement.ELEMENT:
  71.                         HashElement hashElement = HashElementProvider.INSTANCE.parse(parser);
  72.                         builder.setHash(hashElement);
  73.                         break;
  74.                 }
  75.                 break;
  76.             case END_ELEMENT:
  77.                 elementName = parser.getName();
  78.                 switch (elementName) {
  79.                     case JingleFileTransferChild.ELEMENT:
  80.                         payloads.add(builder.build());
  81.                         builder = JingleFileTransferChild.getBuilder();
  82.                         break;

  83.                     case JingleContentDescription.ELEMENT:
  84.                         return new JingleFileTransfer(payloads);
  85.                 }
  86.                 break;
  87.             }
  88.         }
  89.     }

  90.     public static Range parseRangeElement(XmlPullParser parser) throws IOException, XmlPullParserException, SmackParsingException {
  91.         final int initialDepth = parser.getDepth();
  92.         final Integer offset = ParserUtils.getIntegerAttribute(parser, Range.ATTR_OFFSET);
  93.         final Integer length = ParserUtils.getIntegerAttribute(parser, Range.ATTR_LENGTH);

  94.         HashElement hashElement = null;
  95.         outerloop: while (true) {
  96.             String element;
  97.             XmlPullParser.Event event = parser.next();
  98.             switch (event) {
  99.             case START_ELEMENT:
  100.                 element = parser.getName();
  101.                 switch (element) {
  102.                 case HashElement.ELEMENT:
  103.                     hashElement = HashElementProvider.INSTANCE.parse(parser);
  104.                     break;
  105.                 }
  106.                 break;
  107.             case END_ELEMENT:
  108.                 element = parser.getName();
  109.                 if (element.equals(Range.ELEMENT) && parser.getDepth() == initialDepth) {
  110.                     break outerloop;
  111.                 }
  112.                 break;
  113.             default:
  114.                 // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
  115.                 break;
  116.             }
  117.         }

  118.         return new Range(offset, length, hashElement);
  119.     }

  120. }