1   /**
2    * Copyright (c) 2000-2007 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.CollectionFactory;
30  import com.liferay.util.ListUtil;
31  
32  import java.io.StringReader;
33  
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 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 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 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 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(
94              (String)hints.get("max-length"), maxLength);
95  
96          if (value.length() > maxLength) {
97              return value.substring(0, maxLength);
98          }
99          else {
100             return value;
101         }
102     }
103 
104     private ModelHintsUtil() {
105         _hintCollections = CollectionFactory.getHashMap();
106         _defaultHints = CollectionFactory.getHashMap();
107         _modelFields = CollectionFactory.getHashMap();
108         _models = new TreeSet();
109 
110         try {
111             ClassLoader classLoader = getClass().getClassLoader();
112 
113             String[] configs = StringUtil.split(
114                 PropsUtil.get(PropsUtil.MODEL_HINTS_CONFIGS));
115 
116             for (int i = 0; i < configs.length; i++) {
117                 _read(classLoader, configs[i]);
118             }
119         }
120         catch (Exception e) {
121             _log.error(e, e);
122         }
123     }
124 
125     private Map _getDefaultHints(String model) {
126         return (Map)_defaultHints.get(model);
127     }
128 
129     private Element _getFieldsEl(String model, String field) {
130         Map fields = (Map)_modelFields.get(model);
131 
132         if (fields == null) {
133             return null;
134         }
135         else {
136             return (Element)fields.get(field + _ELEMENTS_SUFFIX);
137         }
138     }
139 
140     private List _getModels() {
141         return ListUtil.fromCollection(_models);
142     }
143 
144     private String _getType(String model, String field) {
145         Map fields = (Map)_modelFields.get(model);
146 
147         if (fields == null) {
148             return null;
149         }
150         else {
151             return (String)fields.get(field + _TYPE_SUFFIX);
152         }
153     }
154 
155     private Map _getHints(String model, String field) {
156         Map fields = (Map)_modelFields.get(model);
157 
158         if (fields == null) {
159             return null;
160         }
161         else {
162             return (Map)fields.get(field + _HINTS_SUFFIX);
163         }
164     }
165 
166     private void _read(ClassLoader classLoader, String source)
167         throws Exception {
168 
169         String xml = null;
170 
171         try {
172             xml = StringUtil.read(classLoader, source);
173         }
174         catch (Exception e) {
175             _log.warn("Cannot load " + source);
176         }
177 
178         if (xml == null) {
179             return;
180         }
181 
182         if (_log.isDebugEnabled()) {
183             _log.debug("Loading " + source);
184         }
185 
186         SAXReader reader = new SAXReader();
187 
188         Document doc = reader.read(new StringReader(xml));
189 
190         Element root = doc.getRootElement();
191 
192         Iterator itr1 = root.elements("hint-collection").iterator();
193 
194         while (itr1.hasNext()) {
195             Element hintCollection = (Element)itr1.next();
196 
197             String name = hintCollection.attributeValue("name");
198 
199             Map hints = (Map)_hintCollections.get(name);
200 
201             if (hints == null) {
202                 hints = CollectionFactory.getHashMap();
203 
204                 _hintCollections.put(name, hints);
205             }
206 
207             Iterator itr2 = hintCollection.elements("hint").iterator();
208 
209             while (itr2.hasNext()) {
210                 Element hint = (Element)itr2.next();
211 
212                 String hintName = hint.attributeValue("name");
213                 String hintValue = hint.getText();
214 
215                 hints.put(hintName, hintValue);
216             }
217         }
218 
219         itr1 = root.elements("model").iterator();
220 
221         while (itr1.hasNext()) {
222             Element model = (Element)itr1.next();
223 
224             String name = model.attributeValue("name");
225 
226             Map defaultHints = CollectionFactory.getHashMap();
227 
228             _defaultHints.put(name, defaultHints);
229 
230             Element defaultHintsEl = model.element("default-hints");
231 
232             if (defaultHintsEl != null) {
233                 Iterator itr2 = defaultHintsEl.elements("hint").iterator();
234 
235                 while (itr2.hasNext()) {
236                     Element hint = (Element)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 = CollectionFactory.getHashMap();
249 
250                 _modelFields.put(name, fields);
251             }
252 
253             _models.add(name);
254 
255             Iterator itr2 = model.elements("field").iterator();
256 
257             while (itr2.hasNext()) {
258                 Element field = (Element)itr2.next();
259 
260                 String fieldName = field.attributeValue("name");
261                 String fieldType = field.attributeValue("type");
262 
263                 Map fieldHints = CollectionFactory.getHashMap();
264 
265                 fieldHints.putAll(defaultHints);
266 
267                 Iterator itr3 = field.elements("hint-collection").iterator();
268 
269                 while (itr3.hasNext()) {
270                     Element hintCollection = (Element)itr3.next();
271 
272                     Map hints = (Map)_hintCollections.get(
273                         hintCollection.attributeValue("name"));
274 
275                     fieldHints.putAll(hints);
276                 }
277 
278                 itr3 = field.elements("hint").iterator();
279 
280                 while (itr3.hasNext()) {
281                     Element hint = (Element)itr3.next();
282 
283                     String hintName = hint.attributeValue("name");
284                     String hintValue = hint.getText();
285 
286                     fieldHints.put(hintName, hintValue);
287                 }
288 
289                 fields.put(fieldName + _ELEMENTS_SUFFIX, field);
290                 fields.put(fieldName + _TYPE_SUFFIX, fieldType);
291                 fields.put(fieldName + _HINTS_SUFFIX, fieldHints);
292             }
293         }
294     }
295 
296     private static final String _ELEMENTS_SUFFIX = "_ELEMENTS";
297 
298     private static final String _TYPE_SUFFIX = "_TYPE";
299 
300     private static final String _HINTS_SUFFIX = "_HINTS";
301 
302     private static Log _log = LogFactory.getLog(ModelHintsUtil.class);
303 
304     private static ModelHintsUtil _instance = new ModelHintsUtil();
305 
306     private Map _hintCollections;
307     private Map _defaultHints;
308     private Map _modelFields;
309     private Set _models;
310 
311 }