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.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.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 int size() {
202                    Map<String, Preference> preferences = getPreferences();
203    
204                    return preferences.size();
205            }
206    
207            public abstract void store() throws IOException, ValidatorException;
208    
209            protected String getActualValue(String value) {
210                    if ((value == null) || value.equals(_NULL_VALUE)) {
211                            return null;
212                    }
213                    else {
214                            return XMLFormatter.fromCompactSafe(value);
215                    }
216            }
217    
218            protected String[] getActualValues(String[] values) {
219                    if (values == null) {
220                            return null;
221                    }
222    
223                    if (values.length == 1) {
224                            String actualValue = getActualValue(values[0]);
225    
226                            if (actualValue == null) {
227                                    return null;
228                            }
229                            else {
230                                    return new String[] {actualValue};
231                            }
232                    }
233    
234                    String[] actualValues = new String[values.length];
235    
236                    for (int i = 0; i < actualValues.length; i++) {
237                            actualValues[i] = getActualValue(values[i]);
238                    }
239    
240                    return actualValues;
241            }
242    
243            protected long getCompanyId() {
244                    return _companyId;
245            }
246    
247            protected Map<String, Preference> getModifiedPreferences() {
248                    if (_modifiedPreferences == null) {
249                            _modifiedPreferences = new ConcurrentHashMap<String, Preference>();
250    
251                            for (Map.Entry<String, Preference> entry :
252                                            _originalPreferences.entrySet()) {
253    
254                                    String key = entry.getKey();
255                                    Preference preference = entry.getValue();
256    
257                                    _modifiedPreferences.put(key, (Preference)preference.clone());
258                            }
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    }