001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet;
016    
017    import com.liferay.util.xml.XMLFormatter;
018    
019    import java.io.IOException;
020    
021    import java.util.Collections;
022    import java.util.Enumeration;
023    import java.util.Map;
024    import java.util.concurrent.ConcurrentHashMap;
025    
026    import javax.portlet.ReadOnlyException;
027    import javax.portlet.ValidatorException;
028    
029    /**
030     * @author Alexander Chow
031     */
032    public abstract class BasePreferencesImpl {
033    
034            public BasePreferencesImpl(
035                    long companyId, long ownerId, int ownerType,
036                    Map<String, Preference> preferences) {
037    
038                    _companyId = companyId;
039                    _ownerId = ownerId;
040                    _ownerType = ownerType;
041                    _originalPreferences = preferences;
042            }
043    
044            public Map<String, String[]> getMap() {
045                    Map<String, String[]> map = new ConcurrentHashMap<String, String[]>();
046    
047                    Map<String, Preference> preferences = getPreferences();
048    
049                    for (Map.Entry<String, Preference> entry : preferences.entrySet()) {
050                            String key = entry.getKey();
051                            Preference preference = entry.getValue();
052    
053                            String[] actualValues = getActualValues(preference.getValues());
054    
055                            if (actualValues != null) {
056                                    map.put(key, actualValues);
057                            }
058                    }
059    
060                    return Collections.unmodifiableMap(map);
061            }
062    
063            public Enumeration<String> getNames() {
064                    Map<String, Preference> preferences = getPreferences();
065    
066                    return Collections.enumeration(preferences.keySet());
067            }
068    
069            public String getValue(String key, String def) {
070                    if (key == null) {
071                            throw new IllegalArgumentException();
072                    }
073    
074                    Map<String, Preference> preferences = getPreferences();
075    
076                    Preference preference = preferences.get(key);
077    
078                    String[] values = null;
079    
080                    if (preference != null) {
081                            values = preference.getValues();
082                    }
083    
084                    if ((values != null) && (values.length > 0)) {
085                            return getActualValue(values[0]);
086                    }
087                    else {
088                            return getActualValue(def);
089                    }
090            }
091    
092            public String[] getValues(String key, String[] def) {
093                    if (key == null) {
094                            throw new IllegalArgumentException();
095                    }
096    
097                    Map<String, Preference> preferences = getPreferences();
098    
099                    Preference preference = preferences.get(key);
100    
101                    String[] values = null;
102    
103                    if (preference != null) {
104                            values = preference.getValues();
105                    }
106    
107                    if ((values != null) && (values.length > 0)) {
108                            return getActualValues(values);
109                    }
110                    else {
111                            return getActualValues(def);
112                    }
113            }
114    
115            public boolean isReadOnly(String key) {
116                    if (key == null) {
117                            throw new IllegalArgumentException();
118                    }
119    
120                    Map<String, Preference> preferences = getPreferences();
121    
122                    Preference preference = preferences.get(key);
123    
124                    if ((preference != null) && preference.isReadOnly()) {
125                            return true;
126                    }
127                    else {
128                            return false;
129                    }
130            }
131    
132            public void reset() {
133                    Map<String, Preference> modifiedPreferences = getModifiedPreferences();
134    
135                    modifiedPreferences.clear();
136            }
137    
138            public abstract void reset(String key) throws ReadOnlyException;
139    
140            public void setValue(String key, String value) throws ReadOnlyException {
141                    if (key == null) {
142                            throw new IllegalArgumentException();
143                    }
144    
145                    value = getXmlSafeValue(value);
146    
147                    Map<String, Preference> modifiedPreferences = getModifiedPreferences();
148    
149                    Preference preference = modifiedPreferences.get(key);
150    
151                    if (preference == null) {
152                            preference = new Preference(key, value);
153    
154                            modifiedPreferences.put(key, preference);
155                    }
156    
157                    if (preference.isReadOnly()) {
158                            throw new ReadOnlyException(key);
159                    }
160                    else {
161                            preference.setValues(new String[] {value});
162                    }
163            }
164    
165            public void setValues(String key, String[] values)
166                    throws ReadOnlyException {
167    
168                    if (key == null) {
169                            throw new IllegalArgumentException();
170                    }
171    
172                    values = getXmlSafeValues(values);
173    
174                    Map<String, Preference> modifiedPreferences = getModifiedPreferences();
175    
176                    Preference preference = modifiedPreferences.get(key);
177    
178                    if (preference == null) {
179                            preference = new Preference(key, values);
180    
181                            modifiedPreferences.put(key, preference);
182                    }
183    
184                    if (preference.isReadOnly()) {
185                            throw new ReadOnlyException(key);
186                    }
187                    else {
188                            preference.setValues(values);
189                    }
190            }
191    
192            public abstract void store() throws IOException, ValidatorException;
193    
194            protected String getActualValue(String value) {
195                    if ((value == null) || (value.equals(_NULL_VALUE))) {
196                            return null;
197                    }
198                    else {
199                            return XMLFormatter.fromCompactSafe(value);
200                    }
201            }
202    
203            protected String[] getActualValues(String[] values) {
204                    if (values == null) {
205                            return null;
206                    }
207    
208                    if ((values.length == 1) && (getActualValue(values[0]) == null)) {
209                            return null;
210                    }
211    
212                    String[] actualValues = new String[values.length];
213    
214                    System.arraycopy(values, 0, actualValues, 0, values.length);
215    
216                    for (int i = 0; i < actualValues.length; i++) {
217                            actualValues[i] = getActualValue(actualValues[i]);
218                    }
219    
220                    return actualValues;
221            }
222    
223            protected long getCompanyId() {
224                    return _companyId;
225            }
226    
227            protected Map<String, Preference> getModifiedPreferences() {
228                    if (_modifiedPreferences == null) {
229                            _modifiedPreferences = new ConcurrentHashMap<String, Preference>();
230    
231                            for (Map.Entry<String, Preference> entry :
232                                            _originalPreferences.entrySet()) {
233    
234                                    String key = entry.getKey();
235                                    Preference preference = entry.getValue();
236    
237                                    _modifiedPreferences.put(key, (Preference)preference.clone());
238                            }
239                    }
240    
241                    return _modifiedPreferences;
242            }
243    
244            protected Map<String, Preference> getOriginalPreferences() {
245                    return _originalPreferences;
246            }
247    
248            protected long getOwnerId() {
249                    return _ownerId;
250            }
251    
252            protected int getOwnerType() {
253                    return _ownerType;
254            }
255    
256            protected Map<String, Preference> getPreferences() {
257                    if (_modifiedPreferences == null) {
258                            if (_originalPreferences ==
259                                            Collections.<String, Preference>emptyMap()) {
260    
261                                    _originalPreferences =
262                                            new ConcurrentHashMap<String, Preference>();
263                            }
264    
265                            return _originalPreferences;
266                    }
267                    else {
268                            return _modifiedPreferences;
269                    }
270            }
271    
272            protected String getXmlSafeValue(String value) {
273                    if (value == null) {
274                            return _NULL_VALUE;
275                    }
276                    else {
277                            return XMLFormatter.toCompactSafe(value);
278                    }
279            }
280    
281            protected String[] getXmlSafeValues(String[] values) {
282                    if (values == null) {
283                            return new String[] {getXmlSafeValue(null)};
284                    }
285    
286                    String[] xmlSafeValues = new String[values.length];
287    
288                    System.arraycopy(values, 0, xmlSafeValues, 0, values.length);
289    
290                    for (int i = 0; i < xmlSafeValues.length; i++) {
291                            if (xmlSafeValues[i] == null) {
292                                    xmlSafeValues[i] = getXmlSafeValue(xmlSafeValues[i]);
293                            }
294                    }
295    
296                    return xmlSafeValues;
297            }
298    
299            private static final String _NULL_VALUE = "NULL_VALUE";
300    
301            private long _companyId;
302            private Map<String, Preference> _modifiedPreferences;
303            private Map<String, Preference> _originalPreferences;
304            private long _ownerId;
305            private int _ownerType;
306    
307    }