1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet;
16  
17  import com.liferay.portal.kernel.exception.SystemException;
18  import com.liferay.portal.kernel.log.Log;
19  import com.liferay.portal.kernel.log.LogFactoryUtil;
20  import com.liferay.portal.model.Portlet;
21  import com.liferay.portal.service.PortletLocalServiceUtil;
22  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
23  import com.liferay.portal.util.PortalUtil;
24  import com.liferay.portal.util.PortletKeys;
25  import com.liferay.util.xml.XMLFormatter;
26  
27  import java.io.IOException;
28  import java.io.Serializable;
29  
30  import java.util.Collections;
31  import java.util.Enumeration;
32  import java.util.HashMap;
33  import java.util.Map;
34  
35  import javax.portlet.PortletPreferences;
36  import javax.portlet.PreferencesValidator;
37  import javax.portlet.ReadOnlyException;
38  import javax.portlet.ValidatorException;
39  
40  /**
41   * <a href="PortletPreferencesImpl.java.html"><b><i>View Source</i></b></a>
42   *
43   * @author Brian Wing Shun Chan
44   */
45  public class PortletPreferencesImpl
46      implements Cloneable, PortletPreferences, Serializable {
47  
48      public PortletPreferencesImpl() {
49          this(0, 0, 0, 0, null, new HashMap<String, Preference>());
50      }
51  
52      public PortletPreferencesImpl(
53          long companyId, long ownerId, int ownerType, long plid,
54          String portletId, Map<String, Preference> preferences) {
55  
56          _companyId = companyId;
57          _ownerId = ownerId;
58          _ownerType = ownerType;
59          _plid = plid;
60          _portletId = portletId;
61          _originalPreferences = preferences;
62      }
63  
64      public Object clone() {
65          return new PortletPreferencesImpl(
66              _companyId, _ownerId, _ownerType, _plid, _portletId,
67              _originalPreferences);
68      }
69  
70      public boolean equals(Object obj) {
71          PortletPreferencesImpl portletPreferences = (PortletPreferencesImpl)obj;
72  
73          if (this == portletPreferences) {
74              return true;
75          }
76  
77          if ((getCompanyId() == portletPreferences.getCompanyId()) &&
78              (getOwnerId() == portletPreferences.getOwnerId()) &&
79              (getOwnerType() == portletPreferences.getOwnerType()) &&
80              (getPlid() == portletPreferences.getPlid()) &&
81              (getPortletId().equals(portletPreferences.getPortletId())) &&
82              (getMap().equals(portletPreferences.getMap()))) {
83  
84              return true;
85          }
86          else {
87              return false;
88          }
89      }
90  
91      public Map<String, String[]> getMap() {
92          Map<String, String[]> map = new HashMap<String, String[]>();
93  
94          for (Map.Entry<String, Preference> entry :
95                  getPreferences().entrySet()) {
96  
97              String key = entry.getKey();
98              Preference preference = entry.getValue();
99  
100             map.put(key, _getActualValues(preference.getValues()));
101         }
102 
103         return Collections.unmodifiableMap(map);
104     }
105 
106     public Enumeration<String> getNames() {
107         return Collections.enumeration(getPreferences().keySet());
108     }
109 
110     public String getValue(String key, String def) {
111         if (key == null) {
112             throw new IllegalArgumentException();
113         }
114 
115         Preference preference = getPreferences().get(key);
116 
117         String[] values = null;
118 
119         if (preference != null) {
120             values = preference.getValues();
121         }
122 
123         if ((values != null) && (values.length > 0)) {
124             return _getActualValue(values[0]);
125         }
126         else {
127             return _getActualValue(def);
128         }
129     }
130 
131     public String[] getValues(String key, String[] def) {
132         if (key == null) {
133             throw new IllegalArgumentException();
134         }
135 
136         Preference preference = getPreferences().get(key);
137 
138         String[] values = null;
139         if (preference != null) {
140             values = preference.getValues();
141         }
142 
143         if ((values != null) && (values.length > 0)) {
144             return _getActualValues(values);
145         }
146         else {
147             return _getActualValues(def);
148         }
149     }
150 
151     public boolean isReadOnly(String key) {
152         if (key == null) {
153             throw new IllegalArgumentException();
154         }
155 
156         Preference preference = getPreferences().get(key);
157 
158         if ((preference != null) && preference.isReadOnly()) {
159             return true;
160         }
161         else {
162             return false;
163         }
164     }
165 
166     public void reset() {
167         _getModifiedPreferences().clear();
168     }
169 
170     public void reset(String key) throws ReadOnlyException {
171         if (isReadOnly(key)) {
172             throw new ReadOnlyException(key);
173         }
174 
175         if (_defaultPreferences == null) {
176             try {
177                 if ((_portletId != null) &&
178                     (!_portletId.equals(PortletKeys.LIFERAY_PORTAL))) {
179 
180                     _defaultPreferences = PortletPreferencesLocalServiceUtil.
181                         getDefaultPreferences(_companyId, _portletId);
182                 }
183             }
184             catch (Exception e) {
185                 _log.error(e, e);
186             }
187         }
188 
189         String[] defaultValues = null;
190 
191         if (_defaultPreferences != null) {
192             defaultValues = _defaultPreferences.getValues(key, defaultValues);
193         }
194 
195         if (defaultValues != null) {
196             setValues(key, defaultValues);
197         }
198         else {
199             _getModifiedPreferences().remove(key);
200         }
201     }
202 
203     public void setValue(String key, String value) throws ReadOnlyException {
204         if (key == null) {
205             throw new IllegalArgumentException();
206         }
207 
208         value = _getXmlSafeValue(value);
209 
210         Preference preference = _getModifiedPreferences().get(key);
211 
212         if (preference == null) {
213             preference = new Preference(key, value);
214 
215             _getModifiedPreferences().put(key, preference);
216         }
217 
218         if (preference.isReadOnly()) {
219             throw new ReadOnlyException(key);
220         }
221         else {
222             preference.setValues(new String[] {value});
223         }
224     }
225 
226     public void setValues(String key, String[] values)
227         throws ReadOnlyException {
228 
229         if (key == null) {
230             throw new IllegalArgumentException();
231         }
232 
233         values = _getXmlSafeValues(values);
234 
235         Preference preference = _getModifiedPreferences().get(key);
236 
237         if (preference == null) {
238             preference = new Preference(key, values);
239 
240             _getModifiedPreferences().put(key, preference);
241         }
242 
243         if (preference.isReadOnly()) {
244             throw new ReadOnlyException(key);
245         }
246         else {
247             preference.setValues(values);
248         }
249     }
250 
251     public void store() throws IOException, ValidatorException {
252         if (_portletId == null) {
253             throw new UnsupportedOperationException();
254         }
255 
256         try {
257             Portlet portlet = PortletLocalServiceUtil.getPortletById(
258                 _companyId, _portletId);
259 
260             if (!_portletId.equals(PortletKeys.LIFERAY_PORTAL)) {
261                 PreferencesValidator preferencesValidator =
262                     PortalUtil.getPreferencesValidator(portlet);
263 
264                 if (preferencesValidator != null) {
265                     preferencesValidator.validate(this);
266                 }
267             }
268 
269             PortletPreferencesLocalServiceUtil.updatePreferences(
270                 _ownerId, _ownerType, _plid, _portletId, this);
271         }
272         catch (SystemException se) {
273             throw new IOException(se.getMessage());
274         }
275     }
276 
277     protected long getCompanyId() {
278         return  _companyId;
279     }
280 
281     protected long getOwnerId() {
282         return _ownerId;
283     }
284 
285     protected int getOwnerType() {
286         return _ownerType;
287     }
288 
289     protected long getPlid() {
290         return _plid;
291     }
292 
293     protected String getPortletId() {
294         return _portletId;
295     }
296 
297     protected Map<String, Preference> getPreferences() {
298         if (_modifiedPreferences == null) {
299             return _originalPreferences;
300         }
301         else {
302             return _modifiedPreferences;
303         }
304     }
305 
306     private String _getActualValue(String value) {
307         if ((value == null) || (value.equals(_NULL_VALUE))) {
308             return null;
309         }
310         else {
311             return XMLFormatter.fromCompactSafe(value);
312         }
313     }
314 
315     private String[] _getActualValues(String[] values) {
316         if (values == null) {
317             return null;
318         }
319 
320         if ((values.length == 1) && (_getActualValue(values[0]) == null)) {
321             return null;
322         }
323 
324         String[] actualValues = new String[values.length];
325 
326         System.arraycopy(values, 0, actualValues, 0, values.length);
327 
328         for (int i = 0; i < actualValues.length; i++) {
329             actualValues[i] = _getActualValue(actualValues[i]);
330         }
331 
332         return actualValues;
333     }
334 
335     private Map<String, Preference> _getModifiedPreferences() {
336         if (_modifiedPreferences == null) {
337             _modifiedPreferences = new HashMap<String, Preference>();
338 
339             for (Map.Entry<String, Preference> entry :
340                     _originalPreferences.entrySet()) {
341 
342                 String key = entry.getKey();
343                 Preference preference = entry.getValue();
344 
345                 _modifiedPreferences.put(key, (Preference)preference.clone());
346             }
347         }
348 
349         return _modifiedPreferences;
350     }
351 
352     private String _getXmlSafeValue(String value) {
353         if (value == null) {
354             return _NULL_VALUE;
355         }
356         else {
357             return XMLFormatter.toCompactSafe(value);
358         }
359     }
360 
361     private String[] _getXmlSafeValues(String[] values) {
362         if (values == null) {
363             return new String[] {
364                     _getXmlSafeValue(null)
365                 };
366         }
367 
368         String[] xmlSafeValues = new String[values.length];
369 
370         System.arraycopy(values, 0, xmlSafeValues, 0, values.length);
371 
372         for (int i = 0; i < xmlSafeValues.length; i++) {
373             if (xmlSafeValues[i] == null) {
374                 xmlSafeValues[i] = _getXmlSafeValue(xmlSafeValues[i]);
375             }
376         }
377 
378         return xmlSafeValues;
379     }
380 
381     private static final String _NULL_VALUE = "NULL_VALUE";
382 
383     private static Log _log = LogFactoryUtil.getLog(
384         PortletPreferencesImpl.class);
385 
386     private long _companyId;
387     private PortletPreferences _defaultPreferences;
388     private Map<String, Preference> _modifiedPreferences;
389     private Map<String, Preference> _originalPreferences;
390     private long _ownerId;
391     private int _ownerType;
392     private long _plid;
393     private String _portletId;
394 
395 }