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