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