001/** 002 * 003 * Copyright 2003-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.smack.packet; 019 020import java.util.Collection; 021import java.util.Collections; 022import java.util.HashMap; 023import java.util.Map; 024 025import org.jivesoftware.smack.util.XmlStringBuilder; 026 027/** 028 * Default implementation of the ExtensionElement interface. Unless a ExtensionElementProvider 029 * is registered with {@link org.jivesoftware.smack.provider.ProviderManager ProviderManager}, 030 * instances of this class will be returned when getting stanza(/packet) extensions.<p> 031 * 032 * This class provides a very simple representation of an XML sub-document. Each element 033 * is a key in a Map with its CDATA being the value. For example, given the following 034 * XML sub-document: 035 * 036 * <pre> 037 * <foo xmlns="http://bar.com"> 038 * <color>blue</color> 039 * <food>pizza</food> 040 * </foo></pre> 041 * 042 * In this case, getValue("color") would return "blue", and getValue("food") would 043 * return "pizza". This parsing mechanism mechanism is very simplistic and will not work 044 * as desired in all cases (for example, if some of the elements have attributes. In those 045 * cases, a custom ExtensionElementProvider should be used. 046 * 047 * @author Matt Tucker 048 */ 049public class DefaultExtensionElement implements ExtensionElement { 050 051 private String elementName; 052 private String namespace; 053 private Map<String,String> map; 054 055 /** 056 * Creates a new generic stanza(/packet) extension. 057 * 058 * @param elementName the name of the element of the XML sub-document. 059 * @param namespace the namespace of the element. 060 */ 061 public DefaultExtensionElement(String elementName, String namespace) { 062 this.elementName = elementName; 063 this.namespace = namespace; 064 } 065 066 /** 067 * Returns the XML element name of the extension sub-packet root element. 068 * 069 * @return the XML element name of the stanza(/packet) extension. 070 */ 071 public String getElementName() { 072 return elementName; 073 } 074 075 /** 076 * Returns the XML namespace of the extension sub-packet root element. 077 * 078 * @return the XML namespace of the stanza(/packet) extension. 079 */ 080 public String getNamespace() { 081 return namespace; 082 } 083 084 @Override 085 public CharSequence toXML() { 086 XmlStringBuilder buf = new XmlStringBuilder(); 087 buf.halfOpenElement(elementName).xmlnsAttribute(namespace).rightAngleBracket(); 088 for (String name : getNames()) { 089 String value = getValue(name); 090 buf.element(name, value); 091 } 092 buf.closeElement(elementName); 093 return buf; 094 } 095 096 /** 097 * Returns an unmodifiable collection of the names that can be used to get 098 * values of the stanza(/packet) extension. 099 * 100 * @return the names. 101 */ 102 public synchronized Collection<String> getNames() { 103 if (map == null) { 104 return Collections.emptySet(); 105 } 106 return Collections.unmodifiableSet(new HashMap<String,String>(map).keySet()); 107 } 108 109 /** 110 * Returns a stanza(/packet) extension value given a name. 111 * 112 * @param name the name. 113 * @return the value. 114 */ 115 public synchronized String getValue(String name) { 116 if (map == null) { 117 return null; 118 } 119 return map.get(name); 120 } 121 122 /** 123 * Sets a stanza(/packet) extension value using the given name. 124 * 125 * @param name the name. 126 * @param value the value. 127 */ 128 public synchronized void setValue(String name, String value) { 129 if (map == null) { 130 map = new HashMap<String,String>(); 131 } 132 map.put(name, value); 133 } 134}