1/**
2 * $RCSfile$
3 * $Revision$
4 * $Date$
5 *
6 * Copyright 2003-2007 Jive Software.
7 *
8 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *     http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package org.jivesoftware.smackx.packet;
22
23import java.util.Collections;
24import java.util.HashMap;
25import java.util.Iterator;
26import java.util.Map;
27
28/**
29 * Default implementation of the PrivateData interface. Unless a PrivateDataProvider
30 * is registered with the PrivateDataManager class, instances of this class will be
31 * returned when getting private data.<p>
32 *
33 * This class provides a very simple representation of an XML sub-document. Each element
34 * is a key in a Map with its CDATA being the value. For example, given the following
35 * XML sub-document:
36 *
37 * <pre>
38 * &lt;foo xmlns="http://bar.com"&gt;
39 *     &lt;color&gt;blue&lt;/color&gt;
40 *     &lt;food&gt;pizza&lt;/food&gt;
41 * &lt;/foo&gt;</pre>
42 *
43 * In this case, getValue("color") would return "blue", and getValue("food") would
44 * return "pizza". This parsing mechanism mechanism is very simplistic and will not work
45 * as desired in all cases (for example, if some of the elements have attributes. In those
46 * cases, a custom {@link org.jivesoftware.smackx.provider.PrivateDataProvider} should be used.
47 *
48 * @author Matt Tucker
49 */
50public class DefaultPrivateData implements PrivateData {
51
52    private String elementName;
53    private String namespace;
54    private Map<String, String> map;
55
56    /**
57     * Creates a new generic private data object.
58     *
59     * @param elementName the name of the element of the XML sub-document.
60     * @param namespace the namespace of the element.
61     */
62    public DefaultPrivateData(String elementName, String namespace) {
63        this.elementName = elementName;
64        this.namespace = namespace;
65    }
66
67     /**
68     * Returns the XML element name of the private data sub-packet root element.
69     *
70     * @return the XML element name of the packet extension.
71     */
72    public String getElementName() {
73        return elementName;
74    }
75
76    /**
77     * Returns the XML namespace of the private data sub-packet root element.
78     *
79     * @return the XML namespace of the packet extension.
80     */
81    public String getNamespace() {
82        return namespace;
83    }
84
85    public String toXML() {
86        StringBuilder buf = new StringBuilder();
87        buf.append("<").append(elementName).append(" xmlns=\"").append(namespace).append("\">");
88        for (Iterator<String> i=getNames(); i.hasNext(); ) {
89            String name = i.next();
90            String value = getValue(name);
91            buf.append("<").append(name).append(">");
92            buf.append(value);
93            buf.append("</").append(name).append(">");
94        }
95        buf.append("</").append(elementName).append(">");
96        return buf.toString();
97    }
98
99    /**
100     * Returns an Iterator for the names that can be used to get
101     * values of the private data.
102     *
103     * @return an Iterator for the names.
104     */
105    public synchronized Iterator<String> getNames() {
106        if (map == null) {
107            return Collections.<String>emptyList().iterator();
108        }
109        return Collections.unmodifiableSet(map.keySet()).iterator();
110    }
111
112    /**
113     * Returns a value given a name.
114     *
115     * @param name the name.
116     * @return the value.
117     */
118    public synchronized String getValue(String name) {
119        if (map == null) {
120            return null;
121        }
122        return (String)map.get(name);
123    }
124
125    /**
126     * Sets a value given the name.
127     *
128     * @param name the name.
129     * @param value the value.
130     */
131    public synchronized void setValue(String name, String value) {
132        if (map == null) {
133            map = new HashMap<String,String>();
134        }
135        map.put(name, value);
136    }
137}