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.util.GetterUtil;
020 import com.liferay.portal.kernel.util.ListUtil;
021 import com.liferay.portal.kernel.util.PropsKeys;
022 import com.liferay.portal.kernel.util.StringUtil;
023 import com.liferay.portal.kernel.util.Tuple;
024 import com.liferay.portal.kernel.xml.Document;
025 import com.liferay.portal.kernel.xml.Element;
026 import com.liferay.portal.kernel.xml.SAXReader;
027 import com.liferay.portal.service.ClassNameLocalServiceUtil;
028 import com.liferay.portal.util.PropsUtil;
029
030 import java.io.InputStream;
031
032 import java.util.ArrayList;
033 import java.util.Collections;
034 import java.util.HashMap;
035 import java.util.Iterator;
036 import java.util.LinkedHashMap;
037 import java.util.List;
038 import java.util.Map;
039 import java.util.Set;
040 import java.util.TreeSet;
041
042
045 public class ModelHintsImpl implements ModelHints {
046
047 public void afterPropertiesSet() {
048 _hintCollections = new HashMap<String, Map<String, String>>();
049 _defaultHints = new HashMap<String, Map<String, String>>();
050 _modelFields = new HashMap<String, Object>();
051 _models = new TreeSet<String>();
052
053 try {
054 ClassLoader classLoader = getClass().getClassLoader();
055
056 String[] configs = StringUtil.split(
057 PropsUtil.get(PropsKeys.MODEL_HINTS_CONFIGS));
058
059 for (int i = 0; i < configs.length; i++) {
060 read(classLoader, configs[i]);
061 }
062 }
063 catch (Exception e) {
064 _log.error(e, e);
065 }
066 }
067
068 public Map<String, String> getDefaultHints(String model) {
069 return _defaultHints.get(model);
070 }
071
072 public com.liferay.portal.kernel.xml.Element getFieldsEl(
073 String model, String field) {
074
075 Map<String, Object> fields =
076 (Map<String, Object>)_modelFields.get(model);
077
078 if (fields == null) {
079 return null;
080 }
081 else {
082 Element fieldsEl = (Element)fields.get(field + _ELEMENTS_SUFFIX);
083
084 if (fieldsEl == null) {
085 return null;
086 }
087 else {
088 return fieldsEl;
089 }
090 }
091 }
092
093 public Map<String, String> getHints(String model, String field) {
094 Map<String, Object> fields =
095 (Map<String, Object>)_modelFields.get(model);
096
097 if (fields == null) {
098 return null;
099 }
100 else {
101 return (Map<String, String>)fields.get(field + _HINTS_SUFFIX);
102 }
103 }
104
105 public List<String> getModels() {
106 return ListUtil.fromCollection(_models);
107 }
108
109 public Tuple getSanitizeTuple(String model, String field) {
110 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
111 model);
112
113 if (fields == null) {
114 return null;
115 }
116 else {
117 return (Tuple)fields.get(field + _SANITIZE_SUFFIX);
118 }
119 }
120
121 public List<Tuple> getSanitizeTuples(String model) {
122 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
123 model);
124
125 if (fields == null) {
126 return Collections.EMPTY_LIST;
127 }
128 else {
129 List<Tuple> sanitizeTuples = new ArrayList<Tuple>();
130
131 for (String key : fields.keySet()) {
132 if (key.endsWith(_SANITIZE_SUFFIX)) {
133 Tuple sanitizeTuple = (Tuple)fields.get(key);
134
135 sanitizeTuples.add(sanitizeTuple);
136 }
137 }
138
139 return sanitizeTuples;
140 }
141 }
142
143 public String getType(String model, String field) {
144 Map<String, Object> fields =
145 (Map<String, Object>)_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 public boolean isLocalized(String model, String field) {
156 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
157 model);
158
159 if (fields == null) {
160 return false;
161 }
162 else {
163 Boolean localized = (Boolean)fields.get(
164 field + _LOCALIZATION_SUFFIX);
165
166 if (localized != null) {
167 return localized;
168 }
169 else {
170 return false;
171 }
172 }
173 }
174
175 public void read(ClassLoader classLoader, String source) throws Exception {
176 InputStream is = classLoader.getResourceAsStream(source);
177
178 if (is == null) {
179 if (_log.isWarnEnabled()) {
180 _log.warn("Cannot load " + source);
181 }
182 return;
183 }
184 else {
185 if (_log.isDebugEnabled()) {
186 _log.debug("Loading " + source);
187 }
188 }
189
190 Document doc = _saxReader.read(is);
191
192 Element root = doc.getRootElement();
193
194 Iterator<Element> itr1 = root.elements("hint-collection").iterator();
195
196 while (itr1.hasNext()) {
197 Element hintCollection = itr1.next();
198
199 String name = hintCollection.attributeValue("name");
200
201 Map<String, String> hints = _hintCollections.get(name);
202
203 if (hints == null) {
204 hints = new HashMap<String, String>();
205
206 _hintCollections.put(name, hints);
207 }
208
209 Iterator<Element> itr2 = hintCollection.elements("hint").iterator();
210
211 while (itr2.hasNext()) {
212 Element hint = itr2.next();
213
214 String hintName = hint.attributeValue("name");
215 String hintValue = hint.getText();
216
217 hints.put(hintName, hintValue);
218 }
219 }
220
221 itr1 = root.elements("model").iterator();
222
223 while (itr1.hasNext()) {
224 Element model = itr1.next();
225
226 String name = model.attributeValue("name");
227
228 if (classLoader != ModelHintsImpl.class.getClassLoader()) {
229 ClassNameLocalServiceUtil.getClassName(name);
230 }
231
232 Map<String, String> defaultHints = new HashMap<String, String>();
233
234 _defaultHints.put(name, defaultHints);
235
236 Element defaultHintsEl = model.element("default-hints");
237
238 if (defaultHintsEl != null) {
239 Iterator<Element> itr2 = defaultHintsEl.elements(
240 "hint").iterator();
241
242 while (itr2.hasNext()) {
243 Element hint = itr2.next();
244
245 String hintName = hint.attributeValue("name");
246 String hintValue = hint.getText();
247
248 defaultHints.put(hintName, hintValue);
249 }
250 }
251
252 Map<String, Object> fields =
253 (Map<String, Object>)_modelFields.get(name);
254
255 if (fields == null) {
256 fields = new LinkedHashMap<String, Object>();
257
258 _modelFields.put(name, fields);
259 }
260
261 _models.add(name);
262
263 Iterator<Element> itr2 = model.elements("field").iterator();
264
265 while (itr2.hasNext()) {
266 Element field = itr2.next();
267
268 String fieldName = field.attributeValue("name");
269 String fieldType = field.attributeValue("type");
270 boolean fieldLocalized = GetterUtil.getBoolean(
271 field.attributeValue("localized"));
272
273 Map<String, String> fieldHints = new HashMap<String, String>();
274
275 fieldHints.putAll(defaultHints);
276
277 Iterator<Element> itr3 = field.elements(
278 "hint-collection").iterator();
279
280 while (itr3.hasNext()) {
281 Element hintCollection = itr3.next();
282
283 Map<String, String> hints = _hintCollections.get(
284 hintCollection.attributeValue("name"));
285
286 fieldHints.putAll(hints);
287 }
288
289 itr3 = field.elements("hint").iterator();
290
291 while (itr3.hasNext()) {
292 Element hint = itr3.next();
293
294 String hintName = hint.attributeValue("name");
295 String hintValue = hint.getText();
296
297 fieldHints.put(hintName, hintValue);
298 }
299
300 Tuple fieldSanitize = null;
301
302 Element sanitize = field.element("sanitize");
303
304 if (sanitize != null) {
305 String contentType = sanitize.attributeValue(
306 "content-type");
307 String modes = sanitize.attributeValue("modes");
308
309 fieldSanitize = new Tuple(fieldName, contentType, modes);
310 }
311
312 fields.put(fieldName + _ELEMENTS_SUFFIX, field);
313 fields.put(fieldName + _TYPE_SUFFIX, fieldType);
314 fields.put(fieldName + _LOCALIZATION_SUFFIX, fieldLocalized);
315 fields.put(fieldName + _HINTS_SUFFIX, fieldHints);
316
317 if (fieldSanitize != null) {
318 fields.put(fieldName + _SANITIZE_SUFFIX, fieldSanitize);
319 }
320 }
321 }
322 }
323
324 public void setSAXReader(SAXReader saxReader) {
325 _saxReader = saxReader;
326 }
327
328 public String trimString(String model, String field, String value) {
329 if (value == null) {
330 return value;
331 }
332
333 Map<String, String> hints = getHints(model, field);
334
335 if (hints == null) {
336 return value;
337 }
338
339 int maxLength = GetterUtil.getInteger(
340 ModelHintsConstants.TEXT_MAX_LENGTH);
341
342 maxLength = GetterUtil.getInteger(hints.get("max-length"), maxLength);
343
344 if (value.length() > maxLength) {
345 return value.substring(0, maxLength);
346 }
347 else {
348 return value;
349 }
350 }
351
352 private static final String _ELEMENTS_SUFFIX = "_ELEMENTS";
353
354 private static final String _HINTS_SUFFIX = "_HINTS";
355
356 private static final String _LOCALIZATION_SUFFIX = "_LOCALIZATION";
357
358 private static final String _SANITIZE_SUFFIX = "_SANITIZE_SUFFIX";
359
360 private static final String _TYPE_SUFFIX = "_TYPE";
361
362 private static Log _log = LogFactoryUtil.getLog(ModelHintsImpl.class);
363
364 private Map<String, Map<String, String>> _defaultHints;
365 private Map<String, Map<String, String>> _hintCollections;
366 private Map<String, Object> _modelFields;
367 private Set<String> _models;
368 private SAXReader _saxReader;
369
370 }