001
014
015 package com.liferay.portal.model;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
020 import com.liferay.portal.kernel.util.GetterUtil;
021 import com.liferay.portal.kernel.util.ListUtil;
022 import com.liferay.portal.kernel.util.PropsKeys;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.util.Tuple;
026 import com.liferay.portal.kernel.util.Validator;
027 import com.liferay.portal.kernel.xml.Document;
028 import com.liferay.portal.kernel.xml.Element;
029 import com.liferay.portal.kernel.xml.SAXReader;
030 import com.liferay.portal.service.ClassNameLocalServiceUtil;
031 import com.liferay.portal.util.PropsUtil;
032 import com.liferay.util.PwdGenerator;
033
034 import java.io.InputStream;
035
036 import java.util.ArrayList;
037 import java.util.Collections;
038 import java.util.HashMap;
039 import java.util.Iterator;
040 import java.util.LinkedHashMap;
041 import java.util.List;
042 import java.util.Map;
043 import java.util.Set;
044 import java.util.TreeMap;
045 import java.util.TreeSet;
046
047
050 @DoPrivileged
051 public class ModelHintsImpl implements ModelHints {
052
053 public void afterPropertiesSet() {
054 _hintCollections = new HashMap<String, Map<String, String>>();
055 _defaultHints = new HashMap<String, Map<String, String>>();
056 _modelFields = new HashMap<String, Object>();
057 _models = new TreeSet<String>();
058
059 try {
060 ClassLoader classLoader = getClass().getClassLoader();
061
062 String[] configs = StringUtil.split(
063 PropsUtil.get(PropsKeys.MODEL_HINTS_CONFIGS));
064
065 for (int i = 0; i < configs.length; i++) {
066 read(classLoader, configs[i]);
067 }
068 }
069 catch (Exception e) {
070 _log.error(e, e);
071 }
072 }
073
074 @Override
075 public String buildCustomValidatorName(String validatorName) {
076 return validatorName.concat(StringPool.UNDERLINE).concat(
077 PwdGenerator.getPassword(PwdGenerator.KEY3, 4));
078 }
079
080 @Override
081 public Map<String, String> getDefaultHints(String model) {
082 return _defaultHints.get(model);
083 }
084
085 @Override
086 public com.liferay.portal.kernel.xml.Element getFieldsEl(
087 String model, String field) {
088
089 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
090 model);
091
092 if (fields == null) {
093 return null;
094 }
095 else {
096 Element fieldsEl = (Element)fields.get(field + _ELEMENTS_SUFFIX);
097
098 if (fieldsEl == null) {
099 return null;
100 }
101 else {
102 return fieldsEl;
103 }
104 }
105 }
106
107 @Override
108 public Map<String, String> getHints(String model, String field) {
109 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
110 model);
111
112 if (fields == null) {
113 return null;
114 }
115 else {
116 return (Map<String, String>)fields.get(field + _HINTS_SUFFIX);
117 }
118 }
119
120 @Override
121 public int getMaxLength(String model, String field) {
122 Map<String, String> hints = getHints(model, field);
123
124 if (hints == null) {
125 return Integer.MAX_VALUE;
126 }
127
128 int maxLength = GetterUtil.getInteger(
129 ModelHintsConstants.TEXT_MAX_LENGTH);
130
131 maxLength = GetterUtil.getInteger(hints.get("max-length"), maxLength);
132
133 return maxLength;
134 }
135
136 @Override
137 public List<String> getModels() {
138 return ListUtil.fromCollection(_models);
139 }
140
141 @Override
142 public Tuple getSanitizeTuple(String model, String field) {
143 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
144 model);
145
146 if (fields == null) {
147 return null;
148 }
149 else {
150 return (Tuple)fields.get(field + _SANITIZE_SUFFIX);
151 }
152 }
153
154 @Override
155 public List<Tuple> getSanitizeTuples(String model) {
156 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
157 model);
158
159 if (fields == null) {
160 return Collections.emptyList();
161 }
162 else {
163 List<Tuple> sanitizeTuples = new ArrayList<Tuple>();
164
165 for (Map.Entry<String, Object> entry : fields.entrySet()) {
166 String key = entry.getKey();
167
168 if (key.endsWith(_SANITIZE_SUFFIX)) {
169 Tuple sanitizeTuple = (Tuple)entry.getValue();
170
171 sanitizeTuples.add(sanitizeTuple);
172 }
173 }
174
175 return sanitizeTuples;
176 }
177 }
178
179 @Override
180 public String getType(String model, String field) {
181 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
182 model);
183
184 if (fields == null) {
185 return null;
186 }
187 else {
188 return (String)fields.get(field + _TYPE_SUFFIX);
189 }
190 }
191
192 @Override
193 public List<Tuple> getValidators(String model, String field) {
194 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
195 model);
196
197 if ((fields == null) ||
198 (fields.get(field + _VALIDATORS_SUFFIX) == null)) {
199
200 return null;
201 }
202 else {
203 return (List<Tuple>)fields.get(field + _VALIDATORS_SUFFIX);
204 }
205 }
206
207 @Override
208 public boolean isCustomValidator(String validatorName) {
209 if (validatorName.equals("custom")) {
210 return true;
211 }
212
213 return false;
214 }
215
216 @Override
217 public boolean isLocalized(String model, String field) {
218 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
219 model);
220
221 if (fields == null) {
222 return false;
223 }
224 else {
225 Boolean localized = (Boolean)fields.get(
226 field + _LOCALIZATION_SUFFIX);
227
228 if (localized != null) {
229 return localized;
230 }
231 else {
232 return false;
233 }
234 }
235 }
236
237 @Override
238 public void read(ClassLoader classLoader, String source) throws Exception {
239 InputStream is = classLoader.getResourceAsStream(source);
240
241 if (is == null) {
242 if (_log.isWarnEnabled()) {
243 _log.warn("Cannot load " + source);
244 }
245
246 return;
247 }
248 else {
249 if (_log.isDebugEnabled()) {
250 _log.debug("Loading " + source);
251 }
252 }
253
254 Document doc = _saxReader.read(is);
255
256 Element root = doc.getRootElement();
257
258 Iterator<Element> itr1 = root.elements("hint-collection").iterator();
259
260 while (itr1.hasNext()) {
261 Element hintCollection = itr1.next();
262
263 String name = hintCollection.attributeValue("name");
264
265 Map<String, String> hints = _hintCollections.get(name);
266
267 if (hints == null) {
268 hints = new HashMap<String, String>();
269
270 _hintCollections.put(name, hints);
271 }
272
273 Iterator<Element> itr2 = hintCollection.elements("hint").iterator();
274
275 while (itr2.hasNext()) {
276 Element hint = itr2.next();
277
278 String hintName = hint.attributeValue("name");
279 String hintValue = hint.getText();
280
281 hints.put(hintName, hintValue);
282 }
283 }
284
285 itr1 = root.elements("model").iterator();
286
287 while (itr1.hasNext()) {
288 Element model = itr1.next();
289
290 String name = model.attributeValue("name");
291
292 if (classLoader != ModelHintsImpl.class.getClassLoader()) {
293 ClassNameLocalServiceUtil.getClassName(name);
294 }
295
296 Map<String, String> defaultHints = new HashMap<String, String>();
297
298 _defaultHints.put(name, defaultHints);
299
300 Element defaultHintsEl = model.element("default-hints");
301
302 if (defaultHintsEl != null) {
303 Iterator<Element> itr2 = defaultHintsEl.elements(
304 "hint").iterator();
305
306 while (itr2.hasNext()) {
307 Element hint = itr2.next();
308
309 String hintName = hint.attributeValue("name");
310 String hintValue = hint.getText();
311
312 defaultHints.put(hintName, hintValue);
313 }
314 }
315
316 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
317 name);
318
319 if (fields == null) {
320 fields = new LinkedHashMap<String, Object>();
321
322 _modelFields.put(name, fields);
323 }
324
325 _models.add(name);
326
327 Iterator<Element> itr2 = model.elements("field").iterator();
328
329 while (itr2.hasNext()) {
330 Element field = itr2.next();
331
332 String fieldName = field.attributeValue("name");
333 String fieldType = field.attributeValue("type");
334 boolean fieldLocalized = GetterUtil.getBoolean(
335 field.attributeValue("localized"));
336
337 Map<String, String> fieldHints = new HashMap<String, String>();
338
339 fieldHints.putAll(defaultHints);
340
341 Iterator<Element> itr3 = field.elements(
342 "hint-collection").iterator();
343
344 while (itr3.hasNext()) {
345 Element hintCollection = itr3.next();
346
347 Map<String, String> hints = _hintCollections.get(
348 hintCollection.attributeValue("name"));
349
350 fieldHints.putAll(hints);
351 }
352
353 itr3 = field.elements("hint").iterator();
354
355 while (itr3.hasNext()) {
356 Element hint = itr3.next();
357
358 String hintName = hint.attributeValue("name");
359 String hintValue = hint.getText();
360
361 fieldHints.put(hintName, hintValue);
362 }
363
364 Tuple fieldSanitize = null;
365
366 Element sanitize = field.element("sanitize");
367
368 if (sanitize != null) {
369 String contentType = sanitize.attributeValue(
370 "content-type");
371 String modes = sanitize.attributeValue("modes");
372
373 fieldSanitize = new Tuple(fieldName, contentType, modes);
374 }
375
376 Map<String, Tuple> fieldValidators =
377 new TreeMap<String, Tuple>();
378
379 itr3 = field.elements("validator").iterator();
380
381 while (itr3.hasNext()) {
382 Element validator = itr3.next();
383
384 String validatorName = validator.attributeValue("name");
385
386 if (Validator.isNull(validatorName)) {
387 continue;
388 }
389
390 String validatorErrorMessage = GetterUtil.getString(
391 validator.attributeValue("error-message"));
392 String validatorValue = GetterUtil.getString(
393 validator.getText());
394 boolean customValidator = isCustomValidator(validatorName);
395
396 if (customValidator) {
397 validatorName = buildCustomValidatorName(validatorName);
398 }
399
400 Tuple fieldValidator = new Tuple(
401 fieldName, validatorName, validatorErrorMessage,
402 validatorValue, customValidator);
403
404 fieldValidators.put(validatorName, fieldValidator);
405 }
406
407 fields.put(fieldName + _ELEMENTS_SUFFIX, field);
408 fields.put(fieldName + _TYPE_SUFFIX, fieldType);
409 fields.put(fieldName + _LOCALIZATION_SUFFIX, fieldLocalized);
410 fields.put(fieldName + _HINTS_SUFFIX, fieldHints);
411
412 if (fieldSanitize != null) {
413 fields.put(fieldName + _SANITIZE_SUFFIX, fieldSanitize);
414 }
415
416 if (!fieldValidators.isEmpty()) {
417 fields.put(
418 fieldName + _VALIDATORS_SUFFIX,
419 ListUtil.fromMapValues(fieldValidators));
420 }
421 }
422 }
423 }
424
425 public void setSAXReader(SAXReader saxReader) {
426 _saxReader = saxReader;
427 }
428
429 @Override
430 public String trimString(String model, String field, String value) {
431 if (value == null) {
432 return value;
433 }
434
435 int maxLength = getMaxLength(model, field);
436
437 if (value.length() > maxLength) {
438 return value.substring(0, maxLength);
439 }
440 else {
441 return value;
442 }
443 }
444
445 private static final String _ELEMENTS_SUFFIX = "_ELEMENTS";
446
447 private static final String _HINTS_SUFFIX = "_HINTS";
448
449 private static final String _LOCALIZATION_SUFFIX = "_LOCALIZATION";
450
451 private static final String _SANITIZE_SUFFIX = "_SANITIZE_SUFFIX";
452
453 private static final String _TYPE_SUFFIX = "_TYPE";
454
455 private static final String _VALIDATORS_SUFFIX = "_VALIDATORS";
456
457 private static Log _log = LogFactoryUtil.getLog(ModelHintsImpl.class);
458
459 private Map<String, Map<String, String>> _defaultHints;
460 private Map<String, Map<String, String>> _hintCollections;
461 private Map<String, Object> _modelFields;
462 private Set<String> _models;
463 private SAXReader _saxReader;
464
465 }