001/** 002 * 003 * Copyright 2017 Florian Schmaus 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.jingle.provider; 018 019import java.util.logging.Logger; 020 021import org.jivesoftware.smack.packet.StandardExtensionElement; 022import org.jivesoftware.smack.parsing.StandardExtensionElementProvider; 023import org.jivesoftware.smack.provider.IQProvider; 024import org.jivesoftware.smack.util.ParserUtils; 025 026import org.jivesoftware.smackx.jingle.element.Jingle; 027import org.jivesoftware.smackx.jingle.element.JingleAction; 028import org.jivesoftware.smackx.jingle.element.JingleContent; 029import org.jivesoftware.smackx.jingle.element.JingleContentDescription; 030import org.jivesoftware.smackx.jingle.element.JingleContentTransport; 031import org.jivesoftware.smackx.jingle.element.JingleReason; 032import org.jivesoftware.smackx.jingle.element.JingleReason.Reason; 033import org.jivesoftware.smackx.jingle.element.UnknownJingleContentDescription; 034import org.jivesoftware.smackx.jingle.element.UnknownJingleContentTransport; 035 036import org.jxmpp.jid.FullJid; 037import org.xmlpull.v1.XmlPullParser; 038 039public class JingleProvider extends IQProvider<Jingle> { 040 041 private static final Logger LOGGER = Logger.getLogger(JingleProvider.class.getName()); 042 043 @Override 044 public Jingle parse(XmlPullParser parser, int initialDepth) throws Exception { 045 Jingle.Builder builder = Jingle.getBuilder(); 046 047 String actionString = parser.getAttributeValue("", Jingle.ACTION_ATTRIBUTE_NAME); 048 if (actionString != null) { 049 JingleAction action = JingleAction.fromString(actionString); 050 builder.setAction(action); 051 } 052 053 FullJid initiator = ParserUtils.getFullJidAttribute(parser, Jingle.INITIATOR_ATTRIBUTE_NAME); 054 builder.setInitiator(initiator); 055 056 FullJid responder = ParserUtils.getFullJidAttribute(parser, Jingle.RESPONDER_ATTRIBUTE_NAME); 057 builder.setResponder(responder); 058 059 String sessionId = parser.getAttributeValue("", Jingle.SESSION_ID_ATTRIBUTE_NAME); 060 builder.setSessionId(sessionId); 061 062 063 outerloop: while (true) { 064 int eventType = parser.next(); 065 switch (eventType) { 066 case XmlPullParser.START_TAG: 067 String tagName = parser.getName(); 068 switch (tagName) { 069 case JingleContent.ELEMENT: 070 JingleContent content = parseJingleContent(parser, parser.getDepth()); 071 builder.addJingleContent(content); 072 break; 073 case JingleReason.ELEMENT: 074 parser.next(); 075 String reasonString = parser.getName(); 076 JingleReason reason; 077 if (reasonString.equals("alternative-session")) { 078 parser.next(); 079 String sid = parser.nextText(); 080 reason = new JingleReason.AlternativeSession(sid); 081 } else { 082 reason = new JingleReason(Reason.fromString(reasonString)); 083 } 084 builder.setReason(reason); 085 break; 086 default: 087 LOGGER.severe("Unknown Jingle element: " + tagName); 088 break; 089 } 090 break; 091 case XmlPullParser.END_TAG: 092 if (parser.getDepth() == initialDepth) { 093 break outerloop; 094 } 095 } 096 } 097 098 return builder.build(); 099 } 100 101 public static JingleContent parseJingleContent(XmlPullParser parser, final int initialDepth) 102 throws Exception { 103 JingleContent.Builder builder = JingleContent.getBuilder(); 104 105 String creatorString = parser.getAttributeValue("", JingleContent.CREATOR_ATTRIBUTE_NAME); 106 JingleContent.Creator creator = JingleContent.Creator.valueOf(creatorString); 107 builder.setCreator(creator); 108 109 String disposition = parser.getAttributeValue("", JingleContent.DISPOSITION_ATTRIBUTE_NAME); 110 builder.setDisposition(disposition); 111 112 String name = parser.getAttributeValue("", JingleContent.NAME_ATTRIBUTE_NAME); 113 builder.setName(name); 114 115 String sendersString = parser.getAttributeValue("", JingleContent.SENDERS_ATTRIBUTE_NAME); 116 if (sendersString != null) { 117 JingleContent.Senders senders = JingleContent.Senders.valueOf(sendersString); 118 builder.setSenders(senders); 119 } 120 121 outerloop: while (true) { 122 int eventType = parser.next(); 123 switch (eventType) { 124 case XmlPullParser.START_TAG: 125 String tagName = parser.getName(); 126 String namespace = parser.getNamespace(); 127 switch (tagName) { 128 case JingleContentDescription.ELEMENT: { 129 JingleContentDescription description; 130 JingleContentDescriptionProvider<?> provider = JingleContentProviderManager.getJingleContentDescriptionProvider(namespace); 131 if (provider == null) { 132 StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser); 133 description = new UnknownJingleContentDescription(standardExtensionElement); 134 } 135 else { 136 description = provider.parse(parser); 137 } 138 builder.setDescription(description); 139 break; 140 } 141 case JingleContentTransport.ELEMENT: { 142 JingleContentTransport transport; 143 JingleContentTransportProvider<?> provider = JingleContentProviderManager.getJingleContentTransportProvider(namespace); 144 if (provider == null) { 145 StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser); 146 transport = new UnknownJingleContentTransport(standardExtensionElement); 147 } 148 else { 149 transport = provider.parse(parser); 150 } 151 builder.setTransport(transport); 152 break; 153 } 154 default: 155 LOGGER.severe("Unknown Jingle content element: " + tagName); 156 break; 157 } 158 break; 159 case XmlPullParser.END_TAG: 160 if (parser.getDepth() == initialDepth) { 161 break outerloop; 162 } 163 } 164 } 165 166 return builder.build(); 167 } 168}