1
14
15 package com.liferay.portal.model;
16
17 import com.liferay.portal.kernel.log.Log;
18 import com.liferay.portal.kernel.log.LogFactoryUtil;
19 import com.liferay.portal.kernel.util.GetterUtil;
20 import com.liferay.portal.kernel.util.ListUtil;
21 import com.liferay.portal.kernel.util.PropsKeys;
22 import com.liferay.portal.kernel.util.StringUtil;
23 import com.liferay.portal.kernel.util.Tuple;
24 import com.liferay.portal.kernel.xml.Document;
25 import com.liferay.portal.kernel.xml.Element;
26 import com.liferay.portal.kernel.xml.SAXReader;
27 import com.liferay.portal.service.ClassNameLocalServiceUtil;
28 import com.liferay.portal.util.PropsUtil;
29
30 import java.io.InputStream;
31
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.LinkedHashMap;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Set;
40 import java.util.TreeSet;
41
42
47 public class ModelHintsImpl implements ModelHints {
48
49 public void afterPropertiesSet() {
50 _hintCollections = new HashMap<String, Map<String, String>>();
51 _defaultHints = new HashMap<String, Map<String, String>>();
52 _modelFields = new HashMap<String, Object>();
53 _models = new TreeSet<String>();
54
55 try {
56 ClassLoader classLoader = getClass().getClassLoader();
57
58 String[] configs = StringUtil.split(
59 PropsUtil.get(PropsKeys.MODEL_HINTS_CONFIGS));
60
61 for (int i = 0; i < configs.length; i++) {
62 read(classLoader, configs[i]);
63 }
64 }
65 catch (Exception e) {
66 _log.error(e, e);
67 }
68 }
69
70 public Map<String, String> getDefaultHints(String model) {
71 return _defaultHints.get(model);
72 }
73
74 public com.liferay.portal.kernel.xml.Element getFieldsEl(
75 String model, String field) {
76
77 Map<String, Object> fields =
78 (Map<String, Object>)_modelFields.get(model);
79
80 if (fields == null) {
81 return null;
82 }
83 else {
84 Element fieldsEl = (Element)fields.get(field + _ELEMENTS_SUFFIX);
85
86 if (fieldsEl == null) {
87 return null;
88 }
89 else {
90 return fieldsEl;
91 }
92 }
93 }
94
95 public Map<String, String> getHints(String model, String field) {
96 Map<String, Object> fields =
97 (Map<String, Object>)_modelFields.get(model);
98
99 if (fields == null) {
100 return null;
101 }
102 else {
103 return (Map<String, String>)fields.get(field + _HINTS_SUFFIX);
104 }
105 }
106
107 public List<String> getModels() {
108 return ListUtil.fromCollection(_models);
109 }
110
111 public Tuple getSanitizeTuple(String model, String field) {
112 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
113 model);
114
115 if (fields == null) {
116 return null;
117 }
118 else {
119 return (Tuple)fields.get(field + _SANITIZE_SUFFIX);
120 }
121 }
122
123 public List<Tuple> getSanitizeTuples(String model) {
124 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
125 model);
126
127 if (fields == null) {
128 return Collections.EMPTY_LIST;
129 }
130 else {
131 List<Tuple> sanitizeTuples = new ArrayList<Tuple>();
132
133 for (String key : fields.keySet()) {
134 if (key.endsWith(_SANITIZE_SUFFIX)) {
135 Tuple sanitizeTuple = (Tuple)fields.get(key);
136
137 sanitizeTuples.add(sanitizeTuple);
138 }
139 }
140
141 return sanitizeTuples;
142 }
143 }
144
145 public String getType(String model, String field) {
146 Map<String, Object> fields =
147 (Map<String, Object>)_modelFields.get(model);
148
149 if (fields == null) {
150 return null;
151 }
152 else {
153 return (String)fields.get(field + _TYPE_SUFFIX);
154 }
155 }
156
157 public boolean isLocalized(String model, String field) {
158 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
159 model);
160
161 if (fields == null) {
162 return false;
163 }
164 else {
165 return (Boolean)fields.get(field + _LOCALIZATION_SUFFIX);
166 }
167 }
168
169 public void read(ClassLoader classLoader, String source) throws Exception {
170 InputStream is = classLoader.getResourceAsStream(source);
171
172 if (is == null) {
173 if (_log.isWarnEnabled()) {
174 _log.warn("Cannot load " + source);
175 }
176 return;
177 }
178 else {
179 if (_log.isDebugEnabled()) {
180 _log.debug("Loading " + source);
181 }
182 }
183
184 Document doc = _saxReader.read(is);
185
186 Element root = doc.getRootElement();
187
188 Iterator<Element> itr1 = root.elements("hint-collection").iterator();
189
190 while (itr1.hasNext()) {
191 Element hintCollection = itr1.next();
192
193 String name = hintCollection.attributeValue("name");
194
195 Map<String, String> hints = _hintCollections.get(name);
196
197 if (hints == null) {
198 hints = new HashMap<String, String>();
199
200 _hintCollections.put(name, hints);
201 }
202
203 Iterator<Element> itr2 = hintCollection.elements("hint").iterator();
204
205 while (itr2.hasNext()) {
206 Element hint = itr2.next();
207
208 String hintName = hint.attributeValue("name");
209 String hintValue = hint.getText();
210
211 hints.put(hintName, hintValue);
212 }
213 }
214
215 itr1 = root.elements("model").iterator();
216
217 while (itr1.hasNext()) {
218 Element model = itr1.next();
219
220 String name = model.attributeValue("name");
221
222 if (classLoader != ModelHintsImpl.class.getClassLoader()) {
223 ClassNameLocalServiceUtil.getClassName(name);
224 }
225
226 Map<String, String> defaultHints = new HashMap<String, String>();
227
228 _defaultHints.put(name, defaultHints);
229
230 Element defaultHintsEl = model.element("default-hints");
231
232 if (defaultHintsEl != null) {
233 Iterator<Element> itr2 = defaultHintsEl.elements(
234 "hint").iterator();
235
236 while (itr2.hasNext()) {
237 Element hint = itr2.next();
238
239 String hintName = hint.attributeValue("name");
240 String hintValue = hint.getText();
241
242 defaultHints.put(hintName, hintValue);
243 }
244 }
245
246 Map<String, Object> fields =
247 (Map<String, Object>)_modelFields.get(name);
248
249 if (fields == null) {
250 fields = new LinkedHashMap<String, Object>();
251
252 _modelFields.put(name, fields);
253 }
254
255 _models.add(name);
256
257 Iterator<Element> itr2 = model.elements("field").iterator();
258
259 while (itr2.hasNext()) {
260 Element field = itr2.next();
261
262 String fieldName = field.attributeValue("name");
263 String fieldType = field.attributeValue("type");
264 boolean fieldLocalized = GetterUtil.getBoolean(
265 field.attributeValue("localized"));
266
267 Map<String, String> fieldHints = new HashMap<String, String>();
268
269 fieldHints.putAll(defaultHints);
270
271 Iterator<Element> itr3 = field.elements(
272 "hint-collection").iterator();
273
274 while (itr3.hasNext()) {
275 Element hintCollection = itr3.next();
276
277 Map<String, String> hints = _hintCollections.get(
278 hintCollection.attributeValue("name"));
279
280 fieldHints.putAll(hints);
281 }
282
283 itr3 = field.elements("hint").iterator();
284
285 while (itr3.hasNext()) {
286 Element hint = itr3.next();
287
288 String hintName = hint.attributeValue("name");
289 String hintValue = hint.getText();
290
291 fieldHints.put(hintName, hintValue);
292 }
293
294 Tuple fieldSanitize = null;
295
296 Element sanitize = field.element("sanitize");
297
298 if (sanitize != null) {
299 String contentType = sanitize.attributeValue(
300 "content-type");
301 String modes = sanitize.attributeValue("modes");
302
303 fieldSanitize = new Tuple(fieldName, contentType, modes);
304 }
305
306 fields.put(fieldName + _ELEMENTS_SUFFIX, field);
307 fields.put(fieldName + _TYPE_SUFFIX, fieldType);
308 fields.put(fieldName + _LOCALIZATION_SUFFIX, fieldLocalized);
309 fields.put(fieldName + _HINTS_SUFFIX, fieldHints);
310
311 if (fieldSanitize != null) {
312 fields.put(fieldName + _SANITIZE_SUFFIX, fieldSanitize);
313 }
314 }
315 }
316 }
317
318 public void setSAXReader(SAXReader saxReader) {
319 _saxReader = saxReader;
320 }
321
322 public String trimString(String model, String field, String value) {
323 if (value == null) {
324 return value;
325 }
326
327 Map<String, String> hints = getHints(model, field);
328
329 if (hints == null) {
330 return value;
331 }
332
333 int maxLength = GetterUtil.getInteger(
334 ModelHintsConstants.TEXT_MAX_LENGTH);
335
336 maxLength = GetterUtil.getInteger(hints.get("max-length"), maxLength);
337
338 if (value.length() > maxLength) {
339 return value.substring(0, maxLength);
340 }
341 else {
342 return value;
343 }
344 }
345
346 private static final String _ELEMENTS_SUFFIX = "_ELEMENTS";
347
348 private static final String _HINTS_SUFFIX = "_HINTS";
349
350 private static final String _LOCALIZATION_SUFFIX = "_LOCALIZATION";
351
352 private static final String _SANITIZE_SUFFIX = "_SANITIZE_SUFFIX";
353
354 private static final String _TYPE_SUFFIX = "_TYPE";
355
356 private static Log _log = LogFactoryUtil.getLog(ModelHintsImpl.class);
357
358 private Map<String, Map<String, String>> _defaultHints;
359 private Map<String, Map<String, String>> _hintCollections;
360 private Map<String, Object> _modelFields;
361 private Set<String> _models;
362 private SAXReader _saxReader;
363
364 }