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.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.xml.Document;
24  import com.liferay.portal.kernel.xml.Element;
25  import com.liferay.portal.kernel.xml.SAXReader;
26  import com.liferay.portal.service.ClassNameLocalServiceUtil;
27  import com.liferay.portal.util.PropsUtil;
28  
29  import java.io.InputStream;
30  
31  import java.util.HashMap;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Set;
36  import java.util.TreeSet;
37  
38  /**
39   * <a href="ModelHintsImpl.java.html"><b><i>View Source</i></b></a>
40   *
41   * @author Brian Wing Shun Chan
42   */
43  public class ModelHintsImpl implements ModelHints {
44  
45      public void afterPropertiesSet() {
46          _hintCollections = new HashMap<String, Map<String, String>>();
47          _defaultHints = new HashMap<String, Map<String, String>>();
48          _modelFields = new HashMap<String, Object>();
49          _models = new TreeSet<String>();
50  
51          try {
52              ClassLoader classLoader = getClass().getClassLoader();
53  
54              String[] configs = StringUtil.split(
55                  PropsUtil.get(PropsKeys.MODEL_HINTS_CONFIGS));
56  
57              for (int i = 0; i < configs.length; i++) {
58                  read(classLoader, configs[i]);
59              }
60          }
61          catch (Exception e) {
62              _log.error(e, e);
63          }
64      }
65  
66      public Map<String, String> getDefaultHints(String model) {
67          return _defaultHints.get(model);
68      }
69  
70      public com.liferay.portal.kernel.xml.Element getFieldsEl(
71          String model, String field) {
72  
73          Map<String, Object> fields =
74              (Map<String, Object>)_modelFields.get(model);
75  
76          if (fields == null) {
77              return null;
78          }
79          else {
80              Element fieldsEl = (Element)fields.get(field + _ELEMENTS_SUFFIX);
81  
82              if (fieldsEl == null) {
83                  return null;
84              }
85              else {
86                  return fieldsEl;
87              }
88          }
89      }
90  
91      public List<String> getModels() {
92          return ListUtil.fromCollection(_models);
93      }
94  
95      public String getType(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 (String)fields.get(field + _TYPE_SUFFIX);
104         }
105     }
106 
107     public Map<String, String> getHints(String model, String field) {
108         Map<String, Object> fields =
109             (Map<String, Object>)_modelFields.get(model);
110 
111         if (fields == null) {
112             return null;
113         }
114         else {
115             return (Map<String, String>)fields.get(field + _HINTS_SUFFIX);
116         }
117     }
118 
119     public boolean isLocalized(String model, String field) {
120         Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
121             model);
122 
123         if (fields == null) {
124             return false;
125         }
126         else {
127             return (Boolean)fields.get(field + _LOCALIZATION_SUFFIX);
128         }
129     }
130 
131     public void read(ClassLoader classLoader, String source) throws Exception {
132         InputStream is = classLoader.getResourceAsStream(source);
133 
134         if (is == null) {
135             if (_log.isWarnEnabled()) {
136                 _log.warn("Cannot load " + source);
137             }
138             return;
139         }
140         else {
141             if (_log.isDebugEnabled()) {
142                 _log.debug("Loading " + source);
143             }
144         }
145 
146         Document doc = _saxReader.read(is);
147 
148         Element root = doc.getRootElement();
149 
150         Iterator<Element> itr1 = root.elements("hint-collection").iterator();
151 
152         while (itr1.hasNext()) {
153             Element hintCollection = itr1.next();
154 
155             String name = hintCollection.attributeValue("name");
156 
157             Map<String, String> hints = _hintCollections.get(name);
158 
159             if (hints == null) {
160                 hints = new HashMap<String, String>();
161 
162                 _hintCollections.put(name, hints);
163             }
164 
165             Iterator<Element> itr2 = hintCollection.elements("hint").iterator();
166 
167             while (itr2.hasNext()) {
168                 Element hint = itr2.next();
169 
170                 String hintName = hint.attributeValue("name");
171                 String hintValue = hint.getText();
172 
173                 hints.put(hintName, hintValue);
174             }
175         }
176 
177         itr1 = root.elements("model").iterator();
178 
179         while (itr1.hasNext()) {
180             Element model = itr1.next();
181 
182             String name = model.attributeValue("name");
183 
184             if (classLoader != ModelHintsImpl.class.getClassLoader()) {
185                 ClassNameLocalServiceUtil.getClassName(name);
186             }
187 
188             Map<String, String> defaultHints = new HashMap<String, String>();
189 
190             _defaultHints.put(name, defaultHints);
191 
192             Element defaultHintsEl = model.element("default-hints");
193 
194             if (defaultHintsEl != null) {
195                 Iterator<Element> itr2 = defaultHintsEl.elements(
196                     "hint").iterator();
197 
198                 while (itr2.hasNext()) {
199                     Element hint = itr2.next();
200 
201                     String hintName = hint.attributeValue("name");
202                     String hintValue = hint.getText();
203 
204                     defaultHints.put(hintName, hintValue);
205                 }
206             }
207 
208             Map<String, Object> fields =
209                 (Map<String, Object>)_modelFields.get(name);
210 
211             if (fields == null) {
212                 fields = new HashMap<String, Object>();
213 
214                 _modelFields.put(name, fields);
215             }
216 
217             _models.add(name);
218 
219             Iterator<Element> itr2 = model.elements("field").iterator();
220 
221             while (itr2.hasNext()) {
222                 Element field = itr2.next();
223 
224                 String fieldName = field.attributeValue("name");
225                 String fieldType = field.attributeValue("type");
226                 boolean fieldLocalized = GetterUtil.getBoolean(
227                     field.attributeValue("localized"));
228 
229                 Map<String, String> fieldHints = new HashMap<String, String>();
230 
231                 fieldHints.putAll(defaultHints);
232 
233                 Iterator<Element> itr3 = field.elements(
234                     "hint-collection").iterator();
235 
236                 while (itr3.hasNext()) {
237                     Element hintCollection = itr3.next();
238 
239                     Map<String, String> hints = _hintCollections.get(
240                         hintCollection.attributeValue("name"));
241 
242                     fieldHints.putAll(hints);
243                 }
244 
245                 itr3 = field.elements("hint").iterator();
246 
247                 while (itr3.hasNext()) {
248                     Element hint = itr3.next();
249 
250                     String hintName = hint.attributeValue("name");
251                     String hintValue = hint.getText();
252 
253                     fieldHints.put(hintName, hintValue);
254                 }
255 
256                 fields.put(fieldName + _ELEMENTS_SUFFIX, field);
257                 fields.put(fieldName + _TYPE_SUFFIX, fieldType);
258                 fields.put(fieldName + _LOCALIZATION_SUFFIX, fieldLocalized);
259                 fields.put(fieldName + _HINTS_SUFFIX, fieldHints);
260             }
261         }
262     }
263 
264     public void setSAXReader(SAXReader saxReader) {
265         _saxReader = saxReader;
266     }
267 
268     public String trimString(String model, String field, String value) {
269         if (value == null) {
270             return value;
271         }
272 
273         Map<String, String> hints = getHints(model, field);
274 
275         if (hints == null) {
276             return value;
277         }
278 
279         int maxLength = GetterUtil.getInteger(
280             ModelHintsConstants.TEXT_MAX_LENGTH);
281 
282         maxLength = GetterUtil.getInteger(hints.get("max-length"), maxLength);
283 
284         if (value.length() > maxLength) {
285             return value.substring(0, maxLength);
286         }
287         else {
288             return value;
289         }
290     }
291 
292     private static final String _ELEMENTS_SUFFIX = "_ELEMENTS";
293 
294     private static final String _TYPE_SUFFIX = "_TYPE";
295 
296     private static final String _LOCALIZATION_SUFFIX = "_LOCALIZATION";
297 
298     private static final String _HINTS_SUFFIX = "_HINTS";
299 
300     private static Log _log = LogFactoryUtil.getLog(ModelHintsImpl.class);
301 
302     private Map<String, Map<String, String>> _hintCollections;
303     private Map<String, Map<String, String>> _defaultHints;
304     private Map<String, Object> _modelFields;
305     private Set<String> _models;
306     private SAXReader _saxReader;
307 
308 }