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 (Map.Entry<String, Object> entry : fields.entrySet()) {
132 String key = entry.getKey();
133
134 if (key.endsWith(_SANITIZE_SUFFIX)) {
135 Tuple sanitizeTuple = (Tuple)entry.getValue();
136
137 sanitizeTuples.add(sanitizeTuple);
138 }
139 }
140
141 return sanitizeTuples;
142 }
143 }
144
145 public String getType(String model, String field) {
146 Map<String, Object> fields =
147 (Map<String, Object>)_modelFields.get(model);
148
149 if (fields == null) {
150 return null;
151 }
152 else {
153 return (String)fields.get(field + _TYPE_SUFFIX);
154 }
155 }
156
157 public boolean isLocalized(String model, String field) {
158 Map<String, Object> fields = (Map<String, Object>)_modelFields.get(
159 model);
160
161 if (fields == null) {
162 return false;
163 }
164 else {
165 Boolean localized = (Boolean)fields.get(
166 field + _LOCALIZATION_SUFFIX);
167
168 if (localized != null) {
169 return localized;
170 }
171 else {
172 return false;
173 }
174 }
175 }
176
177 public void read(ClassLoader classLoader, String source) throws Exception {
178 InputStream is = classLoader.getResourceAsStream(source);
179
180 if (is == null) {
181 if (_log.isWarnEnabled()) {
182 _log.warn("Cannot load " + source);
183 }
184 return;
185 }
186 else {
187 if (_log.isDebugEnabled()) {
188 _log.debug("Loading " + source);
189 }
190 }
191
192 Document doc = _saxReader.read(is);
193
194 Element root = doc.getRootElement();
195
196 Iterator<Element> itr1 = root.elements("hint-collection").iterator();
197
198 while (itr1.hasNext()) {
199 Element hintCollection = itr1.next();
200
201 String name = hintCollection.attributeValue("name");
202
203 Map<String, String> hints = _hintCollections.get(name);
204
205 if (hints == null) {
206 hints = new HashMap<String, String>();
207
208 _hintCollections.put(name, hints);
209 }
210
211 Iterator<Element> itr2 = hintCollection.elements("hint").iterator();
212
213 while (itr2.hasNext()) {
214 Element hint = itr2.next();
215
216 String hintName = hint.attributeValue("name");
217 String hintValue = hint.getText();
218
219 hints.put(hintName, hintValue);
220 }
221 }
222
223 itr1 = root.elements("model").iterator();
224
225 while (itr1.hasNext()) {
226 Element model = itr1.next();
227
228 String name = model.attributeValue("name");
229
230 if (classLoader != ModelHintsImpl.class.getClassLoader()) {
231 ClassNameLocalServiceUtil.getClassName(name);
232 }
233
234 Map<String, String> defaultHints = new HashMap<String, String>();
235
236 _defaultHints.put(name, defaultHints);
237
238 Element defaultHintsEl = model.element("default-hints");
239
240 if (defaultHintsEl != null) {
241 Iterator<Element> itr2 = defaultHintsEl.elements(
242 "hint").iterator();
243
244 while (itr2.hasNext()) {
245 Element hint = itr2.next();
246
247 String hintName = hint.attributeValue("name");
248 String hintValue = hint.getText();
249
250 defaultHints.put(hintName, hintValue);
251 }
252 }
253
254 Map<String, Object> fields =
255 (Map<String, Object>)_modelFields.get(name);
256
257 if (fields == null) {
258 fields = new LinkedHashMap<String, Object>();
259
260 _modelFields.put(name, fields);
261 }
262
263 _models.add(name);
264
265 Iterator<Element> itr2 = model.elements("field").iterator();
266
267 while (itr2.hasNext()) {
268 Element field = itr2.next();
269
270 String fieldName = field.attributeValue("name");
271 String fieldType = field.attributeValue("type");
272 boolean fieldLocalized = GetterUtil.getBoolean(
273 field.attributeValue("localized"));
274
275 Map<String, String> fieldHints = new HashMap<String, String>();
276
277 fieldHints.putAll(defaultHints);
278
279 Iterator<Element> itr3 = field.elements(
280 "hint-collection").iterator();
281
282 while (itr3.hasNext()) {
283 Element hintCollection = itr3.next();
284
285 Map<String, String> hints = _hintCollections.get(
286 hintCollection.attributeValue("name"));
287
288 fieldHints.putAll(hints);
289 }
290
291 itr3 = field.elements("hint").iterator();
292
293 while (itr3.hasNext()) {
294 Element hint = itr3.next();
295
296 String hintName = hint.attributeValue("name");
297 String hintValue = hint.getText();
298
299 fieldHints.put(hintName, hintValue);
300 }
301
302 Tuple fieldSanitize = null;
303
304 Element sanitize = field.element("sanitize");
305
306 if (sanitize != null) {
307 String contentType = sanitize.attributeValue(
308 "content-type");
309 String modes = sanitize.attributeValue("modes");
310
311 fieldSanitize = new Tuple(fieldName, contentType, modes);
312 }
313
314 fields.put(fieldName + _ELEMENTS_SUFFIX, field);
315 fields.put(fieldName + _TYPE_SUFFIX, fieldType);
316 fields.put(fieldName + _LOCALIZATION_SUFFIX, fieldLocalized);
317 fields.put(fieldName + _HINTS_SUFFIX, fieldHints);
318
319 if (fieldSanitize != null) {
320 fields.put(fieldName + _SANITIZE_SUFFIX, fieldSanitize);
321 }
322 }
323 }
324 }
325
326 public void setSAXReader(SAXReader saxReader) {
327 _saxReader = saxReader;
328 }
329
330 public String trimString(String model, String field, String value) {
331 if (value == null) {
332 return value;
333 }
334
335 Map<String, String> hints = getHints(model, field);
336
337 if (hints == null) {
338 return value;
339 }
340
341 int maxLength = GetterUtil.getInteger(
342 ModelHintsConstants.TEXT_MAX_LENGTH);
343
344 maxLength = GetterUtil.getInteger(hints.get("max-length"), maxLength);
345
346 if (value.length() > maxLength) {
347 return value.substring(0, maxLength);
348 }
349 else {
350 return value;
351 }
352 }
353
354 private static final String _ELEMENTS_SUFFIX = "_ELEMENTS";
355
356 private static final String _HINTS_SUFFIX = "_HINTS";
357
358 private static final String _LOCALIZATION_SUFFIX = "_LOCALIZATION";
359
360 private static final String _SANITIZE_SUFFIX = "_SANITIZE_SUFFIX";
361
362 private static final String _TYPE_SUFFIX = "_TYPE";
363
364 private static Log _log = LogFactoryUtil.getLog(ModelHintsImpl.class);
365
366 private Map<String, Map<String, String>> _defaultHints;
367 private Map<String, Map<String, String>> _hintCollections;
368 private Map<String, Object> _modelFields;
369 private Set<String> _models;
370 private SAXReader _saxReader;
371
372 }