1 /** 2 * Copyright 2013 Georg Lukas 3 * 4 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.jivesoftware.smackx.forward; 18 19 import org.jivesoftware.smack.packet.Packet; 20 import org.jivesoftware.smack.packet.PacketExtension; 21 import org.jivesoftware.smack.provider.PacketExtensionProvider; 22 import org.jivesoftware.smack.util.PacketParserUtils; 23 import org.jivesoftware.smackx.packet.DelayInfo; 24 import org.jivesoftware.smackx.provider.DelayInfoProvider; 25 import org.xmlpull.v1.XmlPullParser; 26 27 /** 28 * Packet extension for XEP-0297: Stanza Forwarding. This class implements 29 * the packet extension and a {@link PacketExtensionProvider} to parse 30 * forwarded messages from a packet. The extension 31 * <a href="http://xmpp.org/extensions/xep-0297.html">XEP-0297</a> is 32 * a prerequisite for XEP-0280 (Message Carbons). 33 * 34 * <p>The {@link Forwarded.Provider} must be registered in the 35 * <b>smack.properties</b> file for the element <b>forwarded</b> with 36 * namespace <b>urn:xmpp:forwarded:0</b></p> to be used. 37 * 38 * @author Georg Lukas 39 */ 40 public class Forwarded implements PacketExtension { 41 public static final String NAMESPACE = "urn:xmpp:forward:0"; 42 public static final String ELEMENT_NAME = "forwarded"; 43 44 private DelayInfo delay; 45 private Packet forwardedPacket; 46 47 /** 48 * Creates a new Forwarded packet extension. 49 * 50 * @param delay an optional {@link DelayInfo} timestamp of the packet. 51 * @param fwdPacket the packet that is forwarded (required). 52 */ Forwarded(DelayInfo delay, Packet fwdPacket)53 public Forwarded(DelayInfo delay, Packet fwdPacket) { 54 this.delay = delay; 55 this.forwardedPacket = fwdPacket; 56 } 57 58 @Override getElementName()59 public String getElementName() { 60 return ELEMENT_NAME; 61 } 62 63 @Override getNamespace()64 public String getNamespace() { 65 return NAMESPACE; 66 } 67 68 @Override toXML()69 public String toXML() { 70 StringBuilder buf = new StringBuilder(); 71 buf.append("<").append(getElementName()).append(" xmlns=\"") 72 .append(getNamespace()).append("\">"); 73 74 if (delay != null) 75 buf.append(delay.toXML()); 76 buf.append(forwardedPacket.toXML()); 77 78 buf.append("</").append(getElementName()).append(">"); 79 return buf.toString(); 80 } 81 82 /** 83 * get the packet forwarded by this stanza. 84 * 85 * @return the {@link Packet} instance (typically a message) that was forwarded. 86 */ getForwardedPacket()87 public Packet getForwardedPacket() { 88 return forwardedPacket; 89 } 90 91 /** 92 * get the timestamp of the forwarded packet. 93 * 94 * @return the {@link DelayInfo} representing the time when the original packet was sent. May be null. 95 */ getDelayInfo()96 public DelayInfo getDelayInfo() { 97 return delay; 98 } 99 100 public static class Provider implements PacketExtensionProvider { 101 DelayInfoProvider dip = new DelayInfoProvider(); 102 parseExtension(XmlPullParser parser)103 public PacketExtension parseExtension(XmlPullParser parser) throws Exception { 104 DelayInfo di = null; 105 Packet packet = null; 106 107 boolean done = false; 108 while (!done) { 109 int eventType = parser.next(); 110 if (eventType == XmlPullParser.START_TAG) { 111 if (parser.getName().equals("delay")) 112 di = (DelayInfo)dip.parseExtension(parser); 113 else if (parser.getName().equals("message")) 114 packet = PacketParserUtils.parseMessage(parser); 115 else throw new Exception("Unsupported forwarded packet type: " + parser.getName()); 116 } 117 else if (eventType == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME)) 118 done = true; 119 } 120 if (packet == null) 121 throw new Exception("forwarded extension must contain a packet"); 122 return new Forwarded(di, packet); 123 } 124 } 125 } 126