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