001/* 002 * 003 * Copyright 2014 Vyacheslav Blinov 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.amp.provider; 018 019import java.io.IOException; 020 021import org.jivesoftware.smack.packet.XmlEnvironment; 022import org.jivesoftware.smack.parsing.SmackParsingException; 023import org.jivesoftware.smack.provider.ExtensionElementProvider; 024import org.jivesoftware.smack.util.StringUtils; 025import org.jivesoftware.smack.xml.XmlPullParser; 026import org.jivesoftware.smack.xml.XmlPullParserException; 027 028import org.jivesoftware.smackx.amp.AMPDeliverCondition; 029import org.jivesoftware.smackx.amp.AMPExpireAtCondition; 030import org.jivesoftware.smackx.amp.AMPMatchResourceCondition; 031import org.jivesoftware.smackx.amp.packet.AMPExtension; 032 033import org.jxmpp.JxmppContext; 034 035 036public class AMPExtensionProvider extends ExtensionElementProvider<AMPExtension> { 037 038 /** 039 * Parses a AMPExtension stanza (extension sub-packet). 040 * 041 * @param parser the XML parser, positioned at the starting element of the extension. 042 * @return a PacketExtension. 043 * @throws IOException if an I/O error occurred. 044 * @throws XmlPullParserException if an error in the XML parser occurred. 045 * @throws SmackParsingException if the Smack parser (provider) encountered invalid input. 046 */ 047 @Override 048 public AMPExtension parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) 049 throws XmlPullParserException, IOException, SmackParsingException { 050 final String from = parser.getAttributeValue(null, "from"); 051 final String to = parser.getAttributeValue(null, "to"); 052 final String statusString = parser.getAttributeValue(null, "status"); 053 AMPExtension.Status status = null; 054 if (statusString != null) { 055 try { 056 status = AMPExtension.Status.valueOf(statusString); 057 } catch (IllegalArgumentException ex) { 058 throw new SmackParsingException("Invalid AMP status: " + statusString, ex); 059 } 060 } 061 062 AMPExtension ampExtension = new AMPExtension(from, to, status); 063 064 String perHopValue = parser.getAttributeValue(null, "per-hop"); 065 if (perHopValue != null) { 066 boolean perHop = Boolean.parseBoolean(perHopValue); 067 ampExtension.setPerHop(perHop); 068 } 069 070 boolean done = false; 071 while (!done) { 072 XmlPullParser.Event eventType = parser.next(); 073 if (eventType == XmlPullParser.Event.START_ELEMENT) { 074 if (parser.getName().equals(AMPExtension.Rule.ELEMENT)) { 075 String actionString = parser.getAttributeValue(null, AMPExtension.Action.ATTRIBUTE_NAME); 076 String conditionName = parser.getAttributeValue(null, AMPExtension.Condition.ATTRIBUTE_NAME); 077 String conditionValue = parser.getAttributeValue(null, "value"); 078 079 AMPExtension.Condition condition = createCondition(conditionName, conditionValue); 080 AMPExtension.Action action = null; 081 if (actionString != null) { 082 try { 083 action = AMPExtension.Action.valueOf(actionString); 084 } catch (IllegalArgumentException ex) { 085 throw new SmackParsingException("Found invalid rule action value " + actionString, ex); 086 } 087 } 088 089 AMPExtension.Rule rule = new AMPExtension.Rule(action, condition); 090 ampExtension.addRule(rule); 091 } 092 } else if (eventType == XmlPullParser.Event.END_ELEMENT) { 093 if (parser.getName().equals(AMPExtension.ELEMENT)) { 094 done = true; 095 } 096 } 097 } 098 099 return ampExtension; 100 } 101 102 private static AMPExtension.Condition createCondition(String name, String value) throws SmackParsingException { 103 if (StringUtils.isNullOrEmpty(name)) { 104 throw new SmackParsingException("Can't have a condition without a name"); 105 } 106 if (StringUtils.isNullOrEmpty(value)) { 107 throw new SmackParsingException("Can't have a condition " + name + " without value"); 108 } 109 110 if (AMPDeliverCondition.NAME.equals(name)) { 111 try { 112 return new AMPDeliverCondition(AMPDeliverCondition.Value.valueOf(value)); 113 } catch (IllegalArgumentException ex) { 114 throw new SmackParsingException("Found invalid rule delivery condition value " + value, ex); 115 } 116 } else if (AMPExpireAtCondition.NAME.equals(name)) { 117 return new AMPExpireAtCondition(value); 118 } else if (AMPMatchResourceCondition.NAME.equals(name)) { 119 try { 120 return new AMPMatchResourceCondition(AMPMatchResourceCondition.Value.valueOf(value)); 121 } catch (IllegalArgumentException ex) { 122 throw new SmackParsingException("Found invalid rule match-resource condition value " + value, ex); 123 } 124 } else { 125 throw new SmackParsingException("Found unknown rule condition name " + name); 126 } 127 } 128}