1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.model;
24  
25  import com.liferay.portal.kernel.util.GetterUtil;
26  import com.liferay.portal.kernel.util.StringUtil;
27  import com.liferay.portal.util.InitUtil;
28  import com.liferay.portal.util.PropsUtil;
29  import com.liferay.util.ListUtil;
30  
31  import java.io.StringReader;
32  
33  import java.util.HashMap;
34  import java.util.Iterator;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.Set;
38  import java.util.TreeSet;
39  
40  import org.apache.commons.logging.Log;
41  import org.apache.commons.logging.LogFactory;
42  
43  import org.dom4j.Document;
44  import org.dom4j.Element;
45  import org.dom4j.io.SAXReader;
46  
47  /**
48   * <a href="ModelHintsUtil.java.html"><b><i>View Source</i></b></a>
49   *
50   * @author Brian Wing Shun Chan
51   *
52   */
53  public class ModelHintsUtil {
54  
55      static {
56          InitUtil.init();
57      }
58  
59      public static Map<String, String> getDefaultHints(String model) {
60          return _instance._getDefaultHints(model);
61      }
62  
63      public static Element getFieldsEl(String model, String field) {
64          return _instance._getFieldsEl(model, field);
65      }
66  
67      public static List<String> getModels() {
68          return _instance._getModels();
69      }
70  
71      public static String getType(String model, String field) {
72          return _instance._getType(model, field);
73      }
74  
75      public static Map<String, String> getHints(String model, String field) {
76          return _instance._getHints(model, field);
77      }
78  
79      public static String trimString(String model, String field, String value) {
80          if (value == null) {
81              return value;
82          }
83  
84          Map<String, String> hints = getHints(model, field);
85  
86          if (hints == null) {
87              return value;
88          }
89  
90          int maxLength = GetterUtil.getInteger(
91              ModelHintsDefaults.TEXT_MAX_LENGTH);
92  
93          maxLength = GetterUtil.getInteger(hints.get("max-length"), maxLength);
94  
95          if (value.length() > maxLength) {
96              return value.substring(0, maxLength);
97          }
98          else {
99              return value;
100         }
101     }
102 
103     private ModelHintsUtil() {
104         _hintCollections = new HashMap<String, Map<String, String>>();
105         _defaultHints = new HashMap<String, Map<String, String>>();
106         _modelFields = new HashMap();
107         _models = new TreeSet<String>();
108 
109         try {
110             ClassLoader classLoader = getClass().getClassLoader();
111 
112             String[] configs = StringUtil.split(
113                 PropsUtil.get(PropsUtil.MODEL_HINTS_CONFIGS));
114 
115             for (int i = 0; i < configs.length; i++) {
116                 _read(classLoader, configs[i]);
117             }
118         }
119         catch (Exception e) {
120             _log.error(e, e);
121         }
122     }
123 
124     private Map<String, String> _getDefaultHints(String model) {
125         return _defaultHints.get(model);
126     }
127 
128     private Element _getFieldsEl(String model, String field) {
129         Map fields = (Map)_modelFields.get(model);
130 
131         if (fields == null) {
132             return null;
133         }
134         else {
135             return (Element)fields.get(field + _ELEMENTS_SUFFIX);
136         }
137     }
138 
139     private List<String> _getModels() {
140         return ListUtil.fromCollection(_models);
141     }
142 
143     private String _getType(String model, String field) {
144         Map fields = (Map)_modelFields.get(model);
145 
146         if (fields == null) {
147             return null;
148         }
149         else {
150             return (String)fields.get(field + _TYPE_SUFFIX);
151         }
152     }
153 
154     private Map _getHints(String model, String field) {
155         Map fields = (Map)_modelFields.get(model);
156 
157         if (fields == null) {
158             return null;
159         }
160         else {
161             return (Map)fields.get(field + _HINTS_SUFFIX);
162         }
163     }
164 
165     private void _read(ClassLoader classLoader, String source)
166         throws Exception {
167 
168         String xml = null;
169 
170         try {
171             xml = StringUtil.read(classLoader, source);
172         }
173         catch (Exception e) {
174             _log.warn("Cannot load " + source);
175         }
176 
177         if (xml == null) {
178             return;
179         }
180 
181         if (_log.isDebugEnabled()) {
182             _log.debug("Loading " + source);
183         }
184 
185         SAXReader reader = new SAXReader();
186 
187         Document doc = reader.read(new StringReader(xml));
188 
189         Element root = doc.getRootElement();
190 
191         Iterator<Element> itr1 = root.elements("hint-collection").iterator();
192 
193         while (itr1.hasNext()) {
194             Element hintCollection = itr1.next();
195 
196             String name = hintCollection.attributeValue("name");
197 
198             Map<String, String> hints = _hintCollections.get(name);
199 
200             if (hints == null) {
201                 hints = new HashMap<String, String>();
202 
203                 _hintCollections.put(name, hints);
204             }
205 
206             Iterator<Element> itr2 = hintCollection.elements("hint").iterator();
207 
208             while (itr2.hasNext()) {
209                 Element hint = itr2.next();
210 
211                 String hintName = hint.attributeValue("name");
212                 String hintValue = hint.getText();
213 
214                 hints.put(hintName, hintValue);
215             }
216         }
217 
218         itr1 = root.elements("model").iterator();
219 
220         while (itr1.hasNext()) {
221             Element model = itr1.next();
222 
223             String name = model.attributeValue("name");
224 
225             Map<String, String> defaultHints = new HashMap<String, String>();
226 
227             _defaultHints.put(name, defaultHints);
228 
229             Element defaultHintsEl = model.element("default-hints");
230 
231             if (defaultHintsEl != null) {
232                 Iterator<Element> itr2 = defaultHintsEl.elements(
233                     "hint").iterator();
234 
235                 while (itr2.hasNext()) {
236                     Element hint = itr2.next();
237 
238                     String hintName = hint.attributeValue("name");
239                     String hintValue = hint.getText();
240 
241                     defaultHints.put(hintName, hintValue);
242                 }
243             }
244 
245             Map fields = (Map)_modelFields.get(name);
246 
247             if (fields == null) {
248                 fields = new HashMap();
249 
250                 _modelFields.put(name, fields);
251             }
252 
253             _models.add(name);
254 
255             Iterator<Element> itr2 = model.elements("field").iterator();
256 
257             while (itr2.hasNext()) {
258                 Element field = itr2.next();
259 
260                 String fieldName = field.attributeValue("name");
261                 String fieldType = field.attributeValue("type");
262 
263                 Map<String, String> fieldHints = new HashMap<String, String>();
264 
265                 fieldHints.putAll(defaultHints);
266 
267                 Iterator<Element> itr3 = field.elements(
268                     "hint-collection").iterator();
269 
270                 while (itr3.hasNext()) {
271                     Element hintCollection = itr3.next();
272 
273                     Map<String, String> hints = _hintCollections.get(
274                         hintCollection.attributeValue("name"));
275 
276                     fieldHints.putAll(hints);
277                 }
278 
279                 itr3 = field.elements("hint").iterator();
280 
281                 while (itr3.hasNext()) {
282                     Element hint = itr3.next();
283 
284                     String hintName = hint.attributeValue("name");
285                     String hintValue = hint.getText();
286 
287                     fieldHints.put(hintName, hintValue);
288                 }
289 
290                 fields.put(fieldName + _ELEMENTS_SUFFIX, field);
291                 fields.put(fieldName + _TYPE_SUFFIX, fieldType);
292                 fields.put(fieldName + _HINTS_SUFFIX, fieldHints);
293             }
294         }
295     }
296 
297     private static final String _ELEMENTS_SUFFIX = "_ELEMENTS";
298 
299     private static final String _TYPE_SUFFIX = "_TYPE";
300 
301     private static final String _HINTS_SUFFIX = "_HINTS";
302 
303     private static Log _log = LogFactory.getLog(ModelHintsUtil.class);
304 
305     private static ModelHintsUtil _instance = new ModelHintsUtil();
306 
307     private Map<String, Map<String, String>> _hintCollections;
308     private Map<String, Map<String, String>> _defaultHints;
309     private Map _modelFields;
310     private Set<String> _models;
311 
312 }