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