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.util.xml.XMLFormatter;
018    
019    import java.io.IOException;
020    import java.io.Serializable;
021    
022    import java.util.Collections;
023    import java.util.Enumeration;
024    import java.util.Map;
025    import java.util.concurrent.ConcurrentHashMap;
026    
027    import javax.portlet.ReadOnlyException;
028    import javax.portlet.ValidatorException;
029    
030    /**
031     * @author Alexander Chow
032     */
033    public abstract class BasePreferencesImpl implements Serializable {
034    
035            public BasePreferencesImpl(
036                    long companyId, long ownerId, int ownerType,
037                    Map<String, Preference> preferences) {
038    
039                    _companyId = companyId;
040                    _ownerId = ownerId;
041                    _ownerType = ownerType;
042                    _originalPreferences = preferences;
043            }
044    
045            public Map<String, String[]> getMap() {
046                    Map<String, String[]> map = new ConcurrentHashMap<String, String[]>();
047    
048                    Map<String, Preference> preferences = getPreferences();
049    
050                    for (Map.Entry<String, Preference> entry : preferences.entrySet()) {
051                            String key = entry.getKey();
052                            Preference preference = entry.getValue();
053    
054                            String[] actualValues = getActualValues(preference.getValues());
055    
056                            if (actualValues != null) {
057                                    map.put(key, actualValues);
058                            }
059                    }
060    
061                    return Collections.unmodifiableMap(map);
062            }
063    
064            public Enumeration<String> getNames() {
065                    Map<String, Preference> preferences = getPreferences();
066    
067                    return Collections.enumeration(preferences.keySet());
068            }
069    
070            public long getOwnerId() {
071                    return _ownerId;
072            }
073    
074            public int getOwnerType() {
075                    return _ownerType;
076            }
077    
078            public String getValue(String key, String def) {
079                    if (key == null) {
080                            throw new IllegalArgumentException();
081                    }
082    
083                    Map<String, Preference> preferences = getPreferences();
084    
085                    Preference preference = preferences.get(key);
086    
087                    String[] values = null;
088    
089                    if (preference != null) {
090                            values = preference.getValues();
091                    }
092    
093                    if ((values != null) && (values.length > 0)) {
094                            return getActualValue(values[0]);
095                    }
096                    else {
097                            return getActualValue(def);
098                    }
099            }
100    
101            public String[] getValues(String key, String[] def) {
102                    if (key == null) {
103                            throw new IllegalArgumentException();
104                    }
105    
106                    Map<String, Preference> preferences = getPreferences();
107    
108                    Preference preference = preferences.get(key);
109    
110                    String[] values = null;
111    
112                    if (preference != null) {
113                            values = preference.getValues();
114                    }
115    
116                    if ((values != null) && (values.length > 0)) {
117                            return getActualValues(values);
118                    }
119                    else {
120                            return getActualValues(def);
121                    }
122            }
123    
124            public boolean isReadOnly(String key) {
125                    if (key == null) {
126                            throw new IllegalArgumentException();
127                    }
128    
129                    Map<String, Preference> preferences = getPreferences();
130    
131                    Preference preference = preferences.get(key);
132    
133                    if ((preference != null) && preference.isReadOnly()) {
134                            return true;
135                    }
136                    else {
137                            return false;
138                    }
139            }
140    
141            public void reset() {
142                    Map<String, Preference> modifiedPreferences = getModifiedPreferences();
143    
144                    modifiedPreferences.clear();
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.setValues(new String[] {value});
171                    }
172            }
173    
174            public void setValues(String key, String[] values)
175                    throws ReadOnlyException {
176    
177                    if (key == null) {
178                            throw new IllegalArgumentException();
179                    }
180    
181                    values = getXmlSafeValues(values);
182    
183                    Map<String, Preference> modifiedPreferences = getModifiedPreferences();
184    
185                    Preference preference = modifiedPreferences.get(key);
186    
187                    if (preference == null) {
188                            preference = new Preference(key, values);
189    
190                            modifiedPreferences.put(key, preference);
191                    }
192    
193                    if (preference.isReadOnly()) {
194                            throw new ReadOnlyException(key);
195                    }
196                    else {
197                            preference.setValues(values);
198                    }
199            }
200    
201            public abstract void store() throws IOException, ValidatorException;
202    
203            protected String getActualValue(String value) {
204                    if ((value == null) || (value.equals(_NULL_VALUE))) {
205                            return null;
206                    }
207                    else {
208                            return XMLFormatter.fromCompactSafe(value);
209                    }
210            }
211    
212            protected String[] getActualValues(String[] values) {
213                    if (values == null) {
214                            return null;
215                    }
216    
217                    if ((values.length == 1) && (getActualValue(values[0]) == null)) {
218                            return null;
219                    }
220    
221                    String[] actualValues = new String[values.length];
222    
223                    System.arraycopy(values, 0, actualValues, 0, values.length);
224    
225                    for (int i = 0; i < actualValues.length; i++) {
226                            actualValues[i] = getActualValue(actualValues[i]);
227                    }
228    
229                    return actualValues;
230            }
231    
232            protected long getCompanyId() {
233                    return _companyId;
234            }
235    
236            protected Map<String, Preference> getModifiedPreferences() {
237                    if (_modifiedPreferences == null) {
238                            _modifiedPreferences = new ConcurrentHashMap<String, Preference>();
239    
240                            for (Map.Entry<String, Preference> entry :
241                                            _originalPreferences.entrySet()) {
242    
243                                    String key = entry.getKey();
244                                    Preference preference = entry.getValue();
245    
246                                    _modifiedPreferences.put(key, (Preference)preference.clone());
247                            }
248                    }
249    
250                    return _modifiedPreferences;
251            }
252    
253            protected Map<String, Preference> getOriginalPreferences() {
254                    return _originalPreferences;
255            }
256    
257            protected Map<String, Preference> getPreferences() {
258                    if (_modifiedPreferences == null) {
259                            if (_originalPreferences ==
260                                            Collections.<String, Preference>emptyMap()) {
261    
262                                    _originalPreferences =
263                                            new ConcurrentHashMap<String, Preference>();
264                            }
265    
266                            return _originalPreferences;
267                    }
268                    else {
269                            return _modifiedPreferences;
270                    }
271            }
272    
273            protected String getXmlSafeValue(String value) {
274                    if (value == null) {
275                            return _NULL_VALUE;
276                    }
277                    else {
278                            return XMLFormatter.toCompactSafe(value);
279                    }
280            }
281    
282            protected String[] getXmlSafeValues(String[] values) {
283                    if (values == null) {
284                            return new String[] {getXmlSafeValue(null)};
285                    }
286    
287                    String[] xmlSafeValues = new String[values.length];
288    
289                    System.arraycopy(values, 0, xmlSafeValues, 0, values.length);
290    
291                    for (int i = 0; i < xmlSafeValues.length; i++) {
292                            if (xmlSafeValues[i] == null) {
293                                    xmlSafeValues[i] = getXmlSafeValue(xmlSafeValues[i]);
294                            }
295                    }
296    
297                    return xmlSafeValues;
298            }
299    
300            private static final String _NULL_VALUE = "NULL_VALUE";
301    
302            private long _companyId;
303            private Map<String, Preference> _modifiedPreferences;
304            private Map<String, Preference> _originalPreferences;
305            private long _ownerId;
306            private int _ownerType;
307    
308    }