001/** 002 * 003 * Copyright 2013-2014 Georg Lukas, 2020 Florian Schmaus 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.forward.provider; 018 019import java.io.IOException; 020import java.util.logging.Logger; 021 022import org.jivesoftware.smack.packet.Message; 023import org.jivesoftware.smack.packet.Stanza; 024import org.jivesoftware.smack.packet.XmlEnvironment; 025import org.jivesoftware.smack.parsing.SmackParsingException; 026import org.jivesoftware.smack.provider.ExtensionElementProvider; 027import org.jivesoftware.smack.util.PacketParserUtils; 028import org.jivesoftware.smack.xml.XmlPullParser; 029import org.jivesoftware.smack.xml.XmlPullParserException; 030 031import org.jivesoftware.smackx.delay.packet.DelayInformation; 032import org.jivesoftware.smackx.delay.provider.DelayInformationProvider; 033import org.jivesoftware.smackx.forward.packet.Forwarded; 034 035/** 036 * This class implements the {@link ExtensionElementProvider} to parse 037 * forwarded messages from a packet. It will return a {@link Forwarded} stanza extension. 038 * 039 * @author Georg Lukas 040 */ 041public class ForwardedProvider extends ExtensionElementProvider<Forwarded<?>> { 042 043 public static final ForwardedProvider INSTANCE = new ForwardedProvider(); 044 045 private static final Logger LOGGER = Logger.getLogger(ForwardedProvider.class.getName()); 046 047 @Override 048 public Forwarded<?> parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { 049 DelayInformation di = null; 050 Stanza packet = null; 051 052 outerloop: while (true) { 053 XmlPullParser.Event eventType = parser.next(); 054 switch (eventType) { 055 case START_ELEMENT: 056 String name = parser.getName(); 057 String namespace = parser.getNamespace(); 058 switch (name) { 059 case DelayInformation.ELEMENT: 060 if (DelayInformation.NAMESPACE.equals(namespace)) { 061 di = DelayInformationProvider.INSTANCE.parse(parser, parser.getDepth(), null); 062 } else { 063 LOGGER.warning("Namespace '" + namespace + "' does not match expected namespace '" 064 + DelayInformation.NAMESPACE + "'"); 065 } 066 break; 067 case Message.ELEMENT: 068 packet = PacketParserUtils.parseMessage(parser); 069 break; 070 default: 071 LOGGER.warning("Unsupported forwarded packet type: " + name); 072 } 073 break; 074 case END_ELEMENT: 075 if (parser.getDepth() == initialDepth) { 076 break outerloop; 077 } 078 break; 079 default: 080 // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement. 081 break; 082 } 083 } 084 085 if (packet == null) { 086 // TODO: Should be SmackParseException. 087 throw new IOException("forwarded extension must contain a packet"); 088 } 089 return new Forwarded<>(packet, di); 090 } 091 092 public static Forwarded<Message> parseForwardedMessage(XmlPullParser parser, XmlEnvironment xmlEnvironment) 093 throws XmlPullParserException, IOException, SmackParsingException { 094 return parseForwardedMessage(parser, parser.getDepth(), xmlEnvironment); 095 } 096 097 @SuppressWarnings("unchecked") 098 public static Forwarded<Message> parseForwardedMessage(XmlPullParser parser, int initialDepth, 099 XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { 100 Forwarded<?> forwarded = INSTANCE.parse(parser, initialDepth, xmlEnvironment); 101 if (!forwarded.isForwarded(Message.class)) { 102 throw new SmackParsingException("Expecting a forwarded message, but got " + forwarded); 103 } 104 return (Forwarded<Message>) forwarded; 105 } 106}