001/* 002 * 003 * Copyright 2005-2007 Jive Software. 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 */ 017 018package org.jivesoftware.smackx.commands.provider; 019 020import java.io.IOException; 021 022import org.jivesoftware.smack.packet.IqData; 023import org.jivesoftware.smack.packet.StanzaError; 024import org.jivesoftware.smack.packet.XmlEnvironment; 025import org.jivesoftware.smack.parsing.SmackParsingException; 026import org.jivesoftware.smack.provider.ExtensionElementProvider; 027import org.jivesoftware.smack.provider.IqProvider; 028import org.jivesoftware.smack.util.PacketParserUtils; 029import org.jivesoftware.smack.xml.XmlPullParser; 030import org.jivesoftware.smack.xml.XmlPullParserException; 031 032import org.jivesoftware.smackx.commands.AdHocCommandNote; 033import org.jivesoftware.smackx.commands.SpecificErrorCondition; 034import org.jivesoftware.smackx.commands.packet.AdHocCommandData; 035import org.jivesoftware.smackx.commands.packet.AdHocCommandData.Action; 036import org.jivesoftware.smackx.commands.packet.AdHocCommandData.AllowedAction; 037import org.jivesoftware.smackx.commands.packet.AdHocCommandDataBuilder; 038import org.jivesoftware.smackx.xdata.packet.DataForm; 039import org.jivesoftware.smackx.xdata.provider.DataFormProvider; 040 041import org.jxmpp.JxmppContext; 042 043/** 044 * The AdHocCommandDataProvider parses AdHocCommandData packets. 045 * 046 * @author Gabriel Guardincerri 047 */ 048public class AdHocCommandDataProvider extends IqProvider<AdHocCommandData> { 049 050 @Override 051 public AdHocCommandData parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) throws XmlPullParserException, IOException, SmackParsingException { 052 String commandNode = parser.getAttributeValue("node"); 053 AdHocCommandDataBuilder builder = AdHocCommandData.builder(commandNode, iqData); 054 DataFormProvider dataFormProvider = new DataFormProvider(); 055 056 String sessionId = parser.getAttributeValue("sessionid"); 057 builder.setSessionId(sessionId); 058 059 // Status 060 String status = parser.getAttributeValue("", "status"); 061 if (AdHocCommandData.Status.executing.toString().equalsIgnoreCase(status)) { 062 builder.setStatus(AdHocCommandData.Status.executing); 063 } 064 else if (AdHocCommandData.Status.completed.toString().equalsIgnoreCase(status)) { 065 builder.setStatus(AdHocCommandData.Status.completed); 066 } 067 else if (AdHocCommandData.Status.canceled.toString().equalsIgnoreCase(status)) { 068 builder.setStatus(AdHocCommandData.Status.canceled); 069 } 070 071 // Action 072 String action = parser.getAttributeValue("", "action"); 073 if (action != null) { 074 Action realAction = Action.valueOf(action); 075 if (realAction == null) { 076 throw new SmackParsingException("Invalid value for action attribute: " + action); 077 } 078 079 builder.setAction(realAction); 080 } 081 082 // TODO: Improve parsing below. Currently, the next actions like <prev/> are not checked for the correct position. 083 outerloop: 084 while (true) { 085 String elementName; 086 XmlPullParser.Event event = parser.next(); 087 String namespace = parser.getNamespace(); 088 switch (event) { 089 case START_ELEMENT: 090 elementName = parser.getName(); 091 switch (elementName) { 092 case "actions": 093 String execute = parser.getAttributeValue("execute"); 094 if (execute != null) { 095 builder.setExecuteAction(AllowedAction.valueOf(execute)); 096 } 097 break; 098 case "next": 099 builder.addAction(AllowedAction.next); 100 break; 101 case "complete": 102 builder.addAction(AllowedAction.complete); 103 break; 104 case "prev": 105 builder.addAction(AllowedAction.prev); 106 break; 107 case "x": 108 if (namespace.equals("jabber:x:data")) { 109 DataForm form = dataFormProvider.parse(parser); 110 builder.setForm(form); 111 } 112 break; 113 case "note": 114 String typeString = parser.getAttributeValue("type"); 115 AdHocCommandNote.Type type; 116 if (typeString != null) { 117 type = AdHocCommandNote.Type.valueOf(typeString); 118 } else { 119 // Type is optional and 'info' if not present. 120 type = AdHocCommandNote.Type.info; 121 } 122 String value = parser.nextText(); 123 builder.addNote(new AdHocCommandNote(type, value)); 124 break; 125 case "error": 126 StanzaError error = PacketParserUtils.parseError(parser, xmlEnvironment, jxmppContext); 127 builder.setError(error); 128 break; 129 } 130 break; 131 case END_ELEMENT: 132 if (parser.getName().equals("command")) { 133 break outerloop; 134 } 135 break; 136 default: 137 // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement. 138 break; 139 } 140 } 141 142 return builder.build(); 143 } 144 145 public static class BadActionError extends ExtensionElementProvider<AdHocCommandData.SpecificError> { 146 @Override 147 public AdHocCommandData.SpecificError parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) { 148 return new AdHocCommandData.SpecificError(SpecificErrorCondition.badAction); 149 } 150 } 151 152 public static class MalformedActionError extends ExtensionElementProvider<AdHocCommandData.SpecificError> { 153 @Override 154 public AdHocCommandData.SpecificError parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) { 155 return new AdHocCommandData.SpecificError(SpecificErrorCondition.malformedAction); 156 } 157 } 158 159 public static class BadLocaleError extends ExtensionElementProvider<AdHocCommandData.SpecificError> { 160 @Override 161 public AdHocCommandData.SpecificError parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) { 162 return new AdHocCommandData.SpecificError(SpecificErrorCondition.badLocale); 163 } 164 } 165 166 public static class BadPayloadError extends ExtensionElementProvider<AdHocCommandData.SpecificError> { 167 @Override 168 public AdHocCommandData.SpecificError parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) { 169 return new AdHocCommandData.SpecificError(SpecificErrorCondition.badPayload); 170 } 171 } 172 173 public static class BadSessionIDError extends ExtensionElementProvider<AdHocCommandData.SpecificError> { 174 @Override 175 public AdHocCommandData.SpecificError parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) { 176 return new AdHocCommandData.SpecificError(SpecificErrorCondition.badSessionid); 177 } 178 } 179 180 public static class SessionExpiredError extends ExtensionElementProvider<AdHocCommandData.SpecificError> { 181 @Override 182 public AdHocCommandData.SpecificError parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment, JxmppContext jxmppContext) { 183 return new AdHocCommandData.SpecificError(SpecificErrorCondition.sessionExpired); 184 } 185 } 186}