001
014
015 package com.liferay.portlet;
016
017 import com.liferay.portal.kernel.util.ArrayUtil;
018 import com.liferay.portal.kernel.xml.simple.Element;
019 import com.liferay.util.xml.XMLFormatter;
020
021 import java.io.IOException;
022 import java.io.Serializable;
023
024 import java.util.Collections;
025 import java.util.Enumeration;
026 import java.util.HashMap;
027 import java.util.Map;
028 import java.util.concurrent.ConcurrentHashMap;
029
030 import javax.portlet.ReadOnlyException;
031 import javax.portlet.ValidatorException;
032
033
037 public abstract class BasePreferencesImpl implements Serializable {
038
039 public BasePreferencesImpl(
040 long ownerId, int ownerType, String xml,
041 Map<String, Preference> preferences) {
042
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 (!isNull(values)) {
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 (!isNull(values)) {
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 = null;
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 = (Preference)preference.clone();
171
172 modifiedPreferences.put(key, preference);
173
174 preference.setValues(new String[] {value});
175 }
176 }
177
178 public void setValues(String key, String[] values)
179 throws ReadOnlyException {
180
181 if (key == null) {
182 throw new IllegalArgumentException();
183 }
184
185 values = getXMLSafeValues(values);
186
187 Map<String, Preference> modifiedPreferences = getModifiedPreferences();
188
189 Preference preference = modifiedPreferences.get(key);
190
191 if (preference == null) {
192 preference = new Preference(key, values);
193
194 modifiedPreferences.put(key, preference);
195 }
196
197 if (preference.isReadOnly()) {
198 throw new ReadOnlyException(key);
199 }
200 else {
201 preference = (Preference)preference.clone();
202
203 modifiedPreferences.put(key, preference);
204
205 preference.setValues(values);
206 }
207 }
208
209 public int size() {
210 Map<String, Preference> preferences = getPreferences();
211
212 return preferences.size();
213 }
214
215 public abstract void store() throws IOException, ValidatorException;
216
217 protected String getActualValue(String value) {
218 if ((value == null) || value.equals(_NULL_VALUE)) {
219 return null;
220 }
221 else {
222 return XMLFormatter.fromCompactSafe(value);
223 }
224 }
225
226 protected String[] getActualValues(String[] values) {
227 if (values == null) {
228 return null;
229 }
230
231 if (values.length == 1) {
232 String actualValue = getActualValue(values[0]);
233
234 if (actualValue == null) {
235 return null;
236 }
237 else {
238 return new String[] {actualValue};
239 }
240 }
241
242 String[] actualValues = new String[values.length];
243
244 for (int i = 0; i < actualValues.length; i++) {
245 actualValues[i] = getActualValue(values[i]);
246 }
247
248 return actualValues;
249 }
250
251 protected Map<String, Preference> getModifiedPreferences() {
252 if (_modifiedPreferences == null) {
253 _modifiedPreferences = new ConcurrentHashMap<String, Preference>(
254 _originalPreferences);
255 }
256
257 return _modifiedPreferences;
258 }
259
260 protected Map<String, Preference> getOriginalPreferences() {
261 return _originalPreferences;
262 }
263
264 protected String getOriginalXML() {
265 return _originalXML;
266 }
267
268 protected Map<String, Preference> getPreferences() {
269 if (_modifiedPreferences != null) {
270 return _modifiedPreferences;
271 }
272
273 return _originalPreferences;
274 }
275
276 protected String getXMLSafeValue(String value) {
277 if (value == null) {
278 return _NULL_VALUE;
279 }
280 else {
281 return XMLFormatter.toCompactSafe(value);
282 }
283 }
284
285 protected String[] getXMLSafeValues(String[] values) {
286 if (values == null) {
287 return new String[] {_NULL_VALUE};
288 }
289
290 String[] xmlSafeValues = new String[values.length];
291
292 for (int i = 0; i < xmlSafeValues.length; i++) {
293 xmlSafeValues[i] = getXMLSafeValue(values[i]);
294 }
295
296 return xmlSafeValues;
297 }
298
299 protected boolean isNull(String[] values) {
300 if (ArrayUtil.isEmpty(values) ||
301 ((values.length == 1) && (getActualValue(values[0]) == null))) {
302
303 return true;
304 }
305
306 return false;
307 }
308
309 protected void setOriginalPreferences(
310 Map<String, Preference> originalPreferences) {
311
312 _originalPreferences = originalPreferences;
313 }
314
315 protected void setOriginalXML(String originalXML) {
316 _originalXML = originalXML;
317 }
318
319 protected String toXML() {
320 if ((_modifiedPreferences == null) && (_originalXML != null)) {
321 return _originalXML;
322 }
323
324 Map<String, Preference> preferences = getPreferences();
325
326 Element portletPreferencesElement = new Element(
327 "portlet-preferences", false);
328
329 for (Map.Entry<String, Preference> entry : preferences.entrySet()) {
330 Preference preference = entry.getValue();
331
332 Element preferenceElement = portletPreferencesElement.addElement(
333 "preference");
334
335 preferenceElement.addElement("name", preference.getName());
336
337 for (String value : preference.getValues()) {
338 preferenceElement.addElement("value", value);
339 }
340
341 if (preference.isReadOnly()) {
342 preferenceElement.addElement("read-only", Boolean.TRUE);
343 }
344 }
345
346 return portletPreferencesElement.toXMLString();
347 }
348
349 private static final String _NULL_VALUE = "NULL_VALUE";
350
351 private Map<String, Preference> _modifiedPreferences;
352 private Map<String, Preference> _originalPreferences;
353 private String _originalXML;
354 private long _ownerId;
355 private int _ownerType;
356
357 }