001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet;
016    
017    import com.liferay.portal.kernel.xml.simple.Element;
018    import com.liferay.util.xml.XMLFormatter;
019    
020    import java.io.IOException;
021    import java.io.Serializable;
022    
023    import java.util.Collections;
024    import java.util.Enumeration;
025    import java.util.HashMap;
026    import java.util.Map;
027    import java.util.concurrent.ConcurrentHashMap;
028    
029    import javax.portlet.ReadOnlyException;
030    import javax.portlet.ValidatorException;
031    
032    /**
033     * @author Alexander Chow
034     * @author Shuyang Zhou
035     */
036    public abstract class BasePreferencesImpl implements Serializable {
037    
038            public BasePreferencesImpl(
039                    long companyId, long ownerId, int ownerType, String xml,
040                    Map<String, Preference> preferences) {
041    
042                    _companyId = companyId;
043                    _ownerId = ownerId;
044                    _ownerType = ownerType;
045                    _originalXML = xml;
046                    _originalPreferences = preferences;
047            }
048    
049            public Map<String, String[]> getMap() {
050                    Map<String, String[]> map = new HashMap<String, String[]>();
051    
052                    Map<String, Preference> preferences = getPreferences();
053    
054                    for (Map.Entry<String, Preference> entry : preferences.entrySet()) {
055                            String key = entry.getKey();
056                            Preference preference = entry.getValue();
057    
058                            String[] actualValues = getActualValues(preference.getValues());
059    
060                            map.put(key, actualValues);
061                    }
062    
063                    return Collections.unmodifiableMap(map);
064            }
065    
066            public Enumeration<String> getNames() {
067                    Map<String, Preference> preferences = getPreferences();
068    
069                    return Collections.enumeration(preferences.keySet());
070            }
071    
072            public long getOwnerId() {
073                    return _ownerId;
074            }
075    
076            public int getOwnerType() {
077                    return _ownerType;
078            }
079    
080            public String getValue(String key, String def) {
081                    if (key == null) {
082                            throw new IllegalArgumentException();
083                    }
084    
085                    Map<String, Preference> preferences = getPreferences();
086    
087                    Preference preference = preferences.get(key);
088    
089                    String[] values = null;
090    
091                    if (preference != null) {
092                            values = preference.getValues();
093                    }
094    
095                    if ((values != null) && (values.length > 0)) {
096                            return getActualValue(values[0]);
097                    }
098                    else {
099                            return getActualValue(def);
100                    }
101            }
102    
103            public String[] getValues(String key, String[] def) {
104                    if (key == null) {
105                            throw new IllegalArgumentException();
106                    }
107    
108                    Map<String, Preference> preferences = getPreferences();
109    
110                    Preference preference = preferences.get(key);
111    
112                    String[] values = null;
113    
114                    if (preference != null) {
115                            values = preference.getValues();
116                    }
117    
118                    if ((values != null) && (values.length > 0)) {
119                            return getActualValues(values);
120                    }
121                    else {
122                            return getActualValues(def);
123                    }
124            }
125    
126            public boolean isReadOnly(String key) {
127                    if (key == null) {
128                            throw new IllegalArgumentException();
129                    }
130    
131                    Map<String, Preference> preferences = getPreferences();
132    
133                    Preference preference = preferences.get(key);
134    
135                    if ((preference != null) && preference.isReadOnly()) {
136                            return true;
137                    }
138                    else {
139                            return false;
140                    }
141            }
142    
143            public void reset() {
144                    _modifiedPreferences = new ConcurrentHashMap<String, Preference>();
145            }
146    
147            public abstract void reset(String key) throws ReadOnlyException;
148    
149            public void setValue(String key, String value) throws ReadOnlyException {
150                    if (key == null) {
151                            throw new IllegalArgumentException();
152                    }
153    
154                    value = getXMLSafeValue(value);
155    
156                    Map<String, Preference> modifiedPreferences = getModifiedPreferences();
157    
158                    Preference preference = modifiedPreferences.get(key);
159    
160                    if (preference == null) {
161                            preference = new Preference(key, value);
162    
163                            modifiedPreferences.put(key, preference);
164                    }
165    
166                    if (preference.isReadOnly()) {
167                            throw new ReadOnlyException(key);
168                    }
169                    else {
170                            preference = (Preference)preference.clone();
171    
172                            modifiedPreferences.put(key, preference);
173    
174                            preference.setValues(new String[] {value});
175                    }
176            }
177    
178            public void setValues(String key, String[] values)
179                    throws ReadOnlyException {
180    
181                    if (key == null) {
182                            throw new IllegalArgumentException();
183                    }
184    
185                    values = getXMLSafeValues(values);
186    
187                    Map<String, Preference> modifiedPreferences = getModifiedPreferences();
188    
189                    Preference preference = modifiedPreferences.get(key);
190    
191                    if (preference == null) {
192                            preference = new Preference(key, values);
193    
194                            modifiedPreferences.put(key, preference);
195                    }
196    
197                    if (preference.isReadOnly()) {
198                            throw new ReadOnlyException(key);
199                    }
200                    else {
201                            preference = (Preference)preference.clone();
202    
203                            modifiedPreferences.put(key, preference);
204    
205                            preference.setValues(values);
206                    }
207            }
208    
209            public int size() {
210                    Map<String, Preference> preferences = getPreferences();
211    
212                    return preferences.size();
213            }
214    
215            public abstract void store() throws IOException, ValidatorException;
216    
217            protected String getActualValue(String value) {
218                    if ((value == null) || value.equals(_NULL_VALUE)) {
219                            return null;
220                    }
221                    else {
222                            return XMLFormatter.fromCompactSafe(value);
223                    }
224            }
225    
226            protected String[] getActualValues(String[] values) {
227                    if (values == null) {
228                            return null;
229                    }
230    
231                    if (values.length == 1) {
232                            String actualValue = getActualValue(values[0]);
233    
234                            if (actualValue == null) {
235                                    return null;
236                            }
237                            else {
238                                    return new String[] {actualValue};
239                            }
240                    }
241    
242                    String[] actualValues = new String[values.length];
243    
244                    for (int i = 0; i < actualValues.length; i++) {
245                            actualValues[i] = getActualValue(values[i]);
246                    }
247    
248                    return actualValues;
249            }
250    
251            protected long getCompanyId() {
252                    return _companyId;
253            }
254    
255            protected Map<String, Preference> getModifiedPreferences() {
256                    if (_modifiedPreferences == null) {
257                            _modifiedPreferences = new ConcurrentHashMap<String, Preference>(
258                                    _originalPreferences);
259                    }
260    
261                    return _modifiedPreferences;
262            }
263    
264            protected Map<String, Preference> getOriginalPreferences() {
265                    return _originalPreferences;
266            }
267    
268            protected String getOriginalXML() {
269                    return _originalXML;
270            }
271    
272            protected Map<String, Preference> getPreferences() {
273                    if (_modifiedPreferences != null) {
274                            return _modifiedPreferences;
275                    }
276    
277                    return _originalPreferences;
278            }
279    
280            protected String getXMLSafeValue(String value) {
281                    if (value == null) {
282                            return _NULL_VALUE;
283                    }
284                    else {
285                            return XMLFormatter.toCompactSafe(value);
286                    }
287            }
288    
289            protected String[] getXMLSafeValues(String[] values) {
290                    if (values == null) {
291                            return new String[] {_NULL_VALUE};
292                    }
293    
294                    String[] xmlSafeValues = new String[values.length];
295    
296                    for (int i = 0; i < xmlSafeValues.length; i++) {
297                            xmlSafeValues[i] = getXMLSafeValue(values[i]);
298                    }
299    
300                    return xmlSafeValues;
301            }
302    
303            protected String toXML() {
304                    if ((_modifiedPreferences == null) && (_originalXML != null)) {
305                            return _originalXML;
306                    }
307    
308                    Map<String, Preference> preferences = getPreferences();
309    
310                    Element portletPreferencesElement = new Element(
311                            "portlet-preferences", false);
312    
313                    for (Map.Entry<String, Preference> entry : preferences.entrySet()) {
314                            Preference preference = entry.getValue();
315    
316                            Element preferenceElement = portletPreferencesElement.addElement(
317                                    "preference");
318    
319                            preferenceElement.addElement("name", preference.getName());
320    
321                            for (String value : preference.getValues()) {
322                                    preferenceElement.addElement("value", value);
323                            }
324    
325                            if (preference.isReadOnly()) {
326                                    preferenceElement.addElement("read-only", Boolean.TRUE);
327                            }
328                    }
329    
330                    return portletPreferencesElement.toXMLString();
331            }
332    
333            private static final String _NULL_VALUE = "NULL_VALUE";
334    
335            private long _companyId;
336            private Map<String, Preference> _modifiedPreferences;
337            private Map<String, Preference> _originalPreferences;
338            private String _originalXML;
339            private long _ownerId;
340            private int _ownerType;
341    
342    }