001/** 002 * 003 * Copyright 2015 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.smack.parsing; 018 019import java.io.IOException; 020import java.util.LinkedHashMap; 021import java.util.Map; 022 023import org.jivesoftware.smack.packet.StandardExtensionElement; 024import org.jivesoftware.smack.packet.StandardExtensionElement.Builder; 025import org.jivesoftware.smack.provider.ExtensionElementProvider; 026import org.jivesoftware.smack.util.ParserUtils; 027import org.jivesoftware.smack.util.StringUtils; 028 029import org.xmlpull.v1.XmlPullParser; 030import org.xmlpull.v1.XmlPullParserException; 031 032/** 033 * The parser for {@link StandardExtensionElement}s. 034 * 035 * @author Florian Schmaus 036 * 037 */ 038public class StandardExtensionElementProvider extends ExtensionElementProvider<StandardExtensionElement> { 039 040 public static StandardExtensionElementProvider INSTANCE = new StandardExtensionElementProvider(); 041 042 @Override 043 public StandardExtensionElement parse(final XmlPullParser parser, final int initialDepth) 044 throws XmlPullParserException, IOException { 045 // Unlike most (all?) other providers, we don't know the name and namespace of the element 046 // we are parsing here. 047 String name = parser.getName(); 048 String namespace = parser.getNamespace(); 049 Builder builder = StandardExtensionElement.builder(name, namespace); 050 final int namespaceCount = parser.getNamespaceCount(initialDepth); 051 final int attributeCount = parser.getAttributeCount(); 052 final Map<String, String> attributes = new LinkedHashMap<>(namespaceCount + attributeCount); 053 for (int i = 0; i < namespaceCount; i++) { 054 String nsprefix = parser.getNamespacePrefix(i); 055 if (nsprefix == null) { 056 // Skip the default namespace. 057 continue; 058 } 059 // XmlPullParser must either return null or a non-empty String. 060 assert StringUtils.isNotEmpty(nsprefix); 061 String nsuri = parser.getNamespaceUri(i); 062 attributes.put("xmlns:" + nsprefix, nsuri); 063 } 064 for (int i = 0; i < attributeCount; i++) { 065 String attributePrefix = parser.getAttributePrefix(i); 066 String attributeName = parser.getAttributeName(i); 067 String attributeValue = parser.getAttributeValue(i); 068 String attributeKey; 069 if (StringUtils.isNullOrEmpty(attributePrefix)) { 070 attributeKey = attributeName; 071 } 072 else { 073 attributeKey = attributePrefix + ':' + attributeName; 074 } 075 attributes.put(attributeKey, attributeValue); 076 } 077 builder.addAttributes(attributes); 078 079 outerloop: while (true) { 080 int event = parser.next(); 081 switch (event) { 082 case XmlPullParser.START_TAG: 083 builder.addElement(parse(parser, parser.getDepth())); 084 break; 085 case XmlPullParser.TEXT: 086 builder.setText(parser.getText()); 087 break; 088 case XmlPullParser.END_TAG: 089 if (initialDepth == parser.getDepth()) { 090 break outerloop; 091 } 092 break; 093 } 094 } 095 096 ParserUtils.assertAtEndTag(parser); 097 return builder.build(); 098 } 099}