package org.limewire.xmpp.client.impl.messages.filetransfer;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Map;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.provider.IQProvider;
import org.limewire.friend.api.FileMetaData;
import org.limewire.friend.impl.util.PresenceUtils;
import org.limewire.logging.Log;
import org.limewire.logging.LogFactory;
import org.limewire.xmpp.client.impl.messages.InvalidIQException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
public class FileTransferIQ extends IQ {
private static Log LOG = LogFactory.getLog(FileTransferIQ.class);
public enum TransferType {OFFER, REQUEST}
private final FileMetaData fileMetaData;
private final TransferType transferType;
public FileTransferIQ(XmlPullParser parser) throws IOException, XmlPullParserException, InvalidIQException {
FileMetaData parsedMetaData = null;
TransferType parsedTransferType = null;
do {
int eventType = parser.getEventType();
if(eventType == XmlPullParser.START_TAG) {
if(parser.getName().equals("file-transfer")) {
String transferTypeValue = parser.getAttributeValue(null, "type");
if (transferTypeValue == null) {
throw new InvalidIQException("no transfer type specified");
}
try {
parsedTransferType = TransferType.valueOf(transferTypeValue);
} catch (IllegalArgumentException iae) {
throw new InvalidIQException("unknown transfer type: " + transferTypeValue);
}
} else if(parser.getName().equals("file")) {
parsedMetaData = new XMPPFileMetaData(parser);
}
} else if(eventType == XmlPullParser.END_TAG) {
if(parser.getName().equals("file-transfer")) {
break;
}
}
} while (parser.nextTag() != XmlPullParser.END_DOCUMENT);
if (parsedMetaData == null || parsedTransferType == null) {
throw new InvalidIQException(MessageFormat.format("parsedMetaData {0}, parsedTransferType {1}", parsedMetaData, parsedTransferType));
}
this.fileMetaData = parsedMetaData;
this.transferType = parsedTransferType;
}
public FileTransferIQ(FileMetaData fileMetaData, TransferType transferType) {
this.fileMetaData = fileMetaData;
this.transferType = transferType;
}
public FileMetaData getFileMetaData() {
return fileMetaData;
}
public TransferType getTransferType() {
return transferType;
}
@Override
public String getChildElementXML() {
String fileTransfer = "<file-transfer xmlns='jabber:iq:lw-file-transfer' type='" + transferType.toString() + "'>";
if(fileMetaData != null) {
fileTransfer += toXML(fileMetaData.getSerializableMap());
}
fileTransfer += "</file-transfer>";
return fileTransfer;
}
private String toXML(Map<String, String> data) {
StringBuilder fileMetadata = new StringBuilder("<file>");
for(Map.Entry<String, String> entry : data.entrySet()) {
fileMetadata.append("<").append(entry.getKey()).append(">");
fileMetadata.append(PresenceUtils.escapeForXML(entry.getValue()));
fileMetadata.append("</").append(entry.getKey()).append(">");
}
fileMetadata.append("</file>");
return fileMetadata.toString();
}
public static IQProvider getIQProvider() {
return new FileTransferIQProvider();
}
private static class FileTransferIQProvider implements IQProvider {
public IQ parseIQ(XmlPullParser parser) throws Exception {
try {
return new FileTransferIQ(parser);
} catch (InvalidIQException ie) {
LOG.debug("invalid iq", ie);
// throwing would close connection
return null;
}
}
}
}