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