1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.ecm.webui.utils;
18
19 import java.io.InputStream;
20 import java.net.URLDecoder;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.TreeMap;
29
30 import javax.jcr.Node;
31 import javax.jcr.PathNotFoundException;
32 import javax.jcr.Property;
33 import javax.jcr.PropertyType;
34
35 import org.apache.commons.lang.StringEscapeUtils;
36
37 import org.exoplatform.commons.utils.HTMLSanitizer;
38 import org.exoplatform.commons.utils.IOUtil;
39 import org.exoplatform.ecm.utils.text.Text;
40 import org.exoplatform.ecm.webui.form.UIDialogForm;
41 import org.exoplatform.ecm.webui.form.UIFormUploadInputNoUploadButton;
42 import org.exoplatform.ecm.webui.form.validator.CategoryValidator;
43 import org.exoplatform.ecm.webui.form.validator.CronExpressionValidator;
44 import org.exoplatform.ecm.webui.form.validator.DateValidator;
45 import org.exoplatform.ecm.webui.form.validator.ECMNameValidator;
46 import org.exoplatform.ecm.webui.form.validator.PhoneFormatValidator;
47 import org.exoplatform.ecm.webui.form.validator.RepeatCountValidator;
48 import org.exoplatform.ecm.webui.form.validator.RepeatIntervalValidator;
49 import org.exoplatform.ecm.webui.form.validator.XSSValidator;
50 import org.exoplatform.services.cms.JcrInputProperty;
51 import org.exoplatform.upload.UploadResource;
52 import org.exoplatform.wcm.webui.Utils;
53 import org.exoplatform.webui.core.UIComponent;
54 import org.exoplatform.webui.form.UIFormDateTimeInput;
55 import org.exoplatform.webui.form.UIFormInputBase;
56 import org.exoplatform.webui.form.UIFormMultiValueInputSet;
57 import org.exoplatform.webui.form.UIFormSelectBox;
58 import org.exoplatform.webui.form.input.UICheckBoxInput;
59 import org.exoplatform.webui.form.input.UIUploadInput;
60 import org.exoplatform.webui.form.validator.DateTimeValidator;
61 import org.exoplatform.webui.form.validator.DoubleFormatValidator;
62 import org.exoplatform.webui.form.validator.EmailAddressValidator;
63 import org.exoplatform.webui.form.validator.MandatoryValidator;
64 import org.exoplatform.webui.form.validator.NullFieldValidator;
65 import org.exoplatform.webui.form.validator.NumberFormatValidator;
66 import org.exoplatform.webui.form.validator.StringLengthValidator;
67
68
69
70
71
72
73
74
75
76
77 public class DialogFormUtil {
78
79 public static String VALIDATOR_PARAM_BEGIN = "(";
80
81 public static String VALIDATOR_PARAM_END = ")";
82
83 public static String VALIDATOR_PARAM_SEPERATOR = ";";
84
85 public static String SANITIZATION_FLAG = "noSanitization";
86
87
88
89
90
91
92 public static String TYPE_FLOAT = "Float";
93
94 public static String TYPE_DOUBLE = "Double";
95
96 public static String TYPE_INTEGER = "Int";
97
98 public static String TYPE_STRING = "String";
99
100
101
102
103
104
105
106
107
108 public static Map<String, JcrInputProperty> prepareMap(List inputs, Map properties) throws Exception {
109 return prepareMap(inputs, properties, null);
110 }
111
112 @SuppressWarnings("unchecked")
113 public static Map<String, JcrInputProperty> prepareMap(List inputs, Map properties, Map options) throws Exception {
114 Map<String, String> changeInJcrPathParamMap = new HashMap<String, String>();
115 Map<String, JcrInputProperty> rawinputs = new HashMap<String, JcrInputProperty>();
116 HashMap<String, JcrInputProperty> hasMap = new HashMap<String, JcrInputProperty>();
117 String inputName = null;
118 String mimeTypeJcrPath = null;
119 InputStream inputStream = null;
120 Map<String, JcrInputProperty> mimeTypes = new HashMap<String, JcrInputProperty>();
121 for (int i = 0; i < inputs.size(); i++) {
122 JcrInputProperty property = null;
123 String option = null;
124 if (inputs.get(i) instanceof UIFormMultiValueInputSet) {
125 UIFormMultiValueInputSet inputI = (UIFormMultiValueInputSet) inputs.get(i);
126 inputName = (inputI).getName();
127 if (!hasMap.containsKey(inputName)) {
128 List<UIComponent> inputChild = inputI.getChildren();
129 property = (JcrInputProperty) properties.get(inputName);
130 if (inputChild != null && inputChild.size() > 0 && inputChild.get(0) instanceof UIUploadInput) {
131 Map<String, List> uploadDataMap = new TreeMap<String, List>();
132 for (UIComponent child : inputChild) {
133 UIUploadInput uploadInput = (UIUploadInput) child;
134 String uploadId = uploadInput.getUploadIds()[0];
135 String uploadDataName = null;
136 String uploadMimeType = null;
137 byte[] uploadData = null;
138 if (uploadInput instanceof UIFormUploadInputNoUploadButton) {
139 uploadDataName = ((UIFormUploadInputNoUploadButton) uploadInput).getFileName();
140 uploadMimeType = ((UIFormUploadInputNoUploadButton) uploadInput).getMimeType();
141 uploadData = ((UIFormUploadInputNoUploadButton) uploadInput).getByteValue();
142 } else {
143 UploadResource uploadResource = (uploadInput).getUploadResource(uploadId);
144 if (uploadResource != null) {
145 String location = uploadResource.getStoreLocation();
146 uploadDataName = uploadResource.getFileName();
147 uploadData = IOUtil.getFileContentAsBytes(location);
148 uploadMimeType = uploadResource.getMimeType();
149 }
150 }
151 if (uploadDataName != null && uploadData != null) {
152 List<Object> data = new ArrayList<Object>();
153 data.add(uploadMimeType);
154 data.add(uploadData);
155 if (!uploadDataMap.containsKey(uploadDataName)) {
156 uploadDataMap.put(uploadDataName, data);
157 } else {
158 int count = 1;
159 while (uploadDataMap.containsKey(uploadDataName + count)) {
160 count++;
161 }
162 uploadDataMap.put(uploadDataName + count, data);
163 }
164 }
165 }
166 property.setValue(uploadDataMap);
167 } else {
168 List<String> values = (List<String>) (inputI).getValue();
169 if (property != null) {
170 property.setValue(values.toArray(new String[values.size()]));
171 }
172 }
173 }
174 hasMap.put(inputName, property);
175 } else {
176 UIFormInputBase input = (UIFormInputBase) inputs.get(i);
177 property = (JcrInputProperty) properties.get(input.getName());
178 if (options != null && options.get(input.getName()) != null)
179 option = (String) options.get(input.getName());
180 if (property != null) {
181 if (input instanceof UIUploadInput) {
182 String uploadId = ((UIUploadInput) input).getUploadIds()[0];
183 UploadResource uploadResource = ((UIUploadInput) input).getUploadResource(uploadId);
184 if (uploadResource == null) {
185 if (property.getChangeInJcrPathParam() != null)
186 changeInJcrPathParamMap.put(property.getChangeInJcrPathParam(), "");
187 continue;
188 }
189 String location = uploadResource.getStoreLocation();
190 byte[] uploadData = IOUtil.getFileContentAsBytes(location);
191 property.setValue(uploadData);
192
193 if (property.getChangeInJcrPathParam() != null)
194 changeInJcrPathParamMap.put(property.getChangeInJcrPathParam(),
195 Text.escapeIllegalJcrChars(uploadResource.getFileName()));
196
197 mimeTypeJcrPath = property.getJcrPath().replace("jcr:data", "jcr:mimeType");
198 JcrInputProperty mimeTypeInputPropertyTmp = new JcrInputProperty();
199 mimeTypeInputPropertyTmp.setJcrPath(mimeTypeJcrPath);
200 mimeTypeInputPropertyTmp.setValue(((UIUploadInput) input).getUploadResource(uploadId).getMimeType());
201 mimeTypes.put(mimeTypeJcrPath, mimeTypeInputPropertyTmp);
202 } else if (input instanceof UIFormDateTimeInput) {
203 property.setValue(((UIFormDateTimeInput) input).getCalendar());
204 } else if (input instanceof UIFormSelectBox) {
205 UIFormSelectBox uiSelectBox = (UIFormSelectBox) input;
206 if (!uiSelectBox.isMultiple()) {
207 property.setValue(uiSelectBox.getValue());
208 } else {
209 property.setValue(uiSelectBox.getSelectedValues());
210 }
211 } else if (input instanceof UICheckBoxInput) {
212 property.setValue(((UICheckBoxInput) input).isChecked());
213 } else {
214 if (input.getValue() != null) {
215 String inputValue = input.getValue().toString().trim();
216 boolean isEmpty = Utils.isEmptyContent(inputValue);
217 if (isEmpty)
218 inputValue = "";
219 else if (option == null || option.indexOf(SANITIZATION_FLAG) < 0) {
220 inputValue = HTMLSanitizer.sanitize(inputValue);
221 inputValue = StringEscapeUtils.unescapeHtml(inputValue);
222 }
223 if (input.getName().equals("name") && input.getAncestorOfType(UIDialogForm.class).isAddNew()) {
224 JcrInputProperty titleInputProperty = (JcrInputProperty) properties.get("title");
225 if(titleInputProperty == null) {
226 JcrInputProperty jcrExoTitle = new JcrInputProperty();
227 jcrExoTitle.setJcrPath("/node/exo:title");
228 jcrExoTitle.setValue(inputValue);
229 properties.put("/node/exo:title", jcrExoTitle);
230 } else if(titleInputProperty.getValue() == null){
231 JcrInputProperty jcrExoTitle = new JcrInputProperty();
232 jcrExoTitle.setJcrPath(titleInputProperty.getJcrPath());
233 jcrExoTitle.setValue(inputValue);
234 properties.put("title", jcrExoTitle);
235 }
236 property.setValue(Text.escapeIllegalJcrChars(inputValue));
237 } else {
238 property.setValue(inputValue);
239 }
240 } else {
241
242 if (input.getName() == "title")
243 continue;
244 property.setValue(input.getValue());
245 }
246 }
247 }
248 }
249 }
250 Iterator iter = properties.values().iterator();
251 JcrInputProperty property;
252 while (iter.hasNext()) {
253 property = (JcrInputProperty) iter.next();
254 rawinputs.put(property.getJcrPath(), property);
255 }
256 for (String jcrPath : mimeTypes.keySet()) {
257 if (!rawinputs.containsKey(jcrPath)) {
258 rawinputs.put(jcrPath, mimeTypes.get(jcrPath));
259 }
260 }
261 List<UIUploadInput> formUploadList = new ArrayList<UIUploadInput>();
262 for (Object input : inputs) {
263 if (input instanceof UIFormMultiValueInputSet) {
264 UIFormMultiValueInputSet uiSet = (UIFormMultiValueInputSet) input;
265 if (uiSet.getId() != null && uiSet.getUIFormInputBase().equals(UIUploadInput.class)
266 && uiSet.getId().equals("attachment__")) {
267 List<UIComponent> list = uiSet.getChildren();
268 for (UIComponent component : list) {
269 if (!formUploadList.contains(component))
270 formUploadList.add((UIUploadInput) component);
271 }
272 }
273 } else if (input instanceof UIUploadInput) {
274 if (!formUploadList.contains(input))
275 formUploadList.add((UIUploadInput) input);
276 }
277 }
278 if (formUploadList.size() > 0) {
279 List<String> keyListToRemove = new ArrayList<String>();
280 Map<String, JcrInputProperty> jcrPropertiesToAdd = new HashMap<String, JcrInputProperty>();
281 for (Object inputJCRKeyTmp : rawinputs.keySet()) {
282 String inputJCRKey = (String) inputJCRKeyTmp;
283 if (inputJCRKey.contains("attachment__")) {
284 JcrInputProperty jcrInputProperty = rawinputs.get(inputJCRKey);
285 for (UIUploadInput uploadInput : formUploadList) {
286 String uploadId = uploadInput.getUploadIds()[0];
287 JcrInputProperty newJcrInputProperty = clone(jcrInputProperty);
288 if (uploadInput == null || uploadInput.getUploadResource(uploadId) == null
289 || uploadInput.getUploadResource(uploadId).getFileName() == null)
290 continue;
291 String fileName = uploadInput.getUploadResource(uploadId).getFileName();
292 String newJCRPath = inputJCRKey.replace("attachment__", fileName);
293 newJcrInputProperty.setJcrPath(newJCRPath);
294 if (inputJCRKey.endsWith("attachment__")) {
295 newJcrInputProperty.setValue(fileName);
296 JcrInputProperty mimeTypeInputPropertyTmp = new JcrInputProperty();
297 mimeTypeInputPropertyTmp.setJcrPath(newJCRPath + "/jcr:content/jcr:mimeType");
298 mimeTypeInputPropertyTmp.setValue(uploadInput.getUploadResource(uploadId).getMimeType());
299 jcrPropertiesToAdd.put(mimeTypeInputPropertyTmp.getJcrPath(), mimeTypeInputPropertyTmp);
300 }
301 if (inputJCRKey.endsWith("jcr:data")) {
302 inputStream = uploadInput.getUploadDataAsStream(uploadId);
303 newJcrInputProperty.setValue(inputStream);
304 }
305 jcrPropertiesToAdd.put(newJCRPath, newJcrInputProperty);
306 }
307 keyListToRemove.add(inputJCRKey);
308 keyListToRemove.add(inputJCRKey.replace("jcr:data", "jcr:mimeType"));
309 }
310 }
311 for (String keyToRemove : keyListToRemove) {
312 rawinputs.remove(keyToRemove);
313 }
314 rawinputs.putAll(jcrPropertiesToAdd);
315 }
316
317 if (changeInJcrPathParamMap.isEmpty()) {
318 return rawinputs;
319 }
320
321 Map<String, JcrInputProperty> ret = new HashMap<String, JcrInputProperty>();
322 Set<String> removedKeys = new HashSet<String>();
323 for (Map.Entry<String, String> changeEntry : changeInJcrPathParamMap.entrySet()) {
324 for (Map.Entry<String, JcrInputProperty> entry : rawinputs.entrySet()) {
325 if (entry.getKey().contains(changeEntry.getKey())) {
326 removedKeys.add(entry.getKey());
327 JcrInputProperty value = entry.getValue();
328 if (value.getJcrPath() != null) {
329 value.setJcrPath(value.getJcrPath().replace(changeEntry.getKey(), changeEntry.getValue()));
330 }
331 if (value.getValue() != null && value.getValue() instanceof String) {
332 value.setValue(((String) value.getValue()).replace(changeEntry.getKey(), changeEntry.getValue()));
333 }
334 if (value != null && !"".equals(value) && changeEntry.getValue() != null && !"".equals(changeEntry.getValue())) {
335 ret.put(entry.getKey().replace(changeEntry.getKey(), changeEntry.getValue()), value);
336 }
337 }
338 }
339 }
340 for (Map.Entry<String, JcrInputProperty> entry : rawinputs.entrySet()) {
341 if (!removedKeys.contains(entry.getKey())) {
342 ret.put(entry.getKey(), entry.getValue());
343 }
344 }
345
346 return ret;
347 }
348
349 private static JcrInputProperty clone(JcrInputProperty fileNodeInputProperty) {
350 JcrInputProperty jcrInputProperty = new JcrInputProperty();
351 jcrInputProperty.setJcrPath(fileNodeInputProperty.getJcrPath());
352 jcrInputProperty.setMixintype(fileNodeInputProperty.getMixintype());
353 jcrInputProperty.setNodetype(fileNodeInputProperty.getNodetype());
354 jcrInputProperty.setType(fileNodeInputProperty.getType());
355 jcrInputProperty.setValue(fileNodeInputProperty.getValue());
356 jcrInputProperty.setValueType(fileNodeInputProperty.getValueType());
357 return jcrInputProperty;
358 }
359
360
361
362
363
364
365
366
367
368
369
370
371 public static <T extends UIFormInputBase> T createFormInput(Class<T> type,
372 String name,
373 String label,
374 String validateType,
375 Class valueType) throws Exception {
376 Object[] args = { name, null, valueType };
377 UIFormInputBase formInput = type.getConstructor().newInstance(args);
378 addValidators(formInput, validateType);
379 if (label != null && label.length() != 0) {
380 formInput.setLabel(label);
381 }
382 return type.cast(formInput);
383 }
384
385
386
387
388
389
390
391
392
393 public static String getPropertyValueAsString(Node node, String propertyName) throws Exception {
394 Property property = null;
395 try {
396 property = node.getProperty(propertyName);
397 } catch (PathNotFoundException e) {
398 return "";
399 }
400 int valueType = property.getType();
401 switch (valueType) {
402 case PropertyType.STRING:
403 return property.getString();
404 case PropertyType.LONG:
405 return Long.toString(property.getLong());
406 case PropertyType.DOUBLE:
407 return Double.toString(property.getDouble());
408 case PropertyType.DATE:
409 return property.getDate().getTime().toString();
410 case PropertyType.BOOLEAN:
411 return Boolean.toString(property.getBoolean());
412 case PropertyType.NAME:
413 return property.getName();
414 case 8:
415 case 9:
416 case 0:
417 }
418 return "";
419 }
420
421 public static Class getValidator(String validatorType) throws ClassNotFoundException {
422 if (validatorType.equals("name")) {
423 return ECMNameValidator.class;
424 } else if (validatorType.equals("email")) {
425 return EmailAddressValidator.class;
426 } else if (validatorType.equals("number")) {
427 return NumberFormatValidator.class;
428 } else if (validatorType.equals("double")) {
429 return DoubleFormatValidator.class;
430 } else if (validatorType.equals("empty")) {
431 return MandatoryValidator.class;
432 } else if (validatorType.equals("null")) {
433 return NullFieldValidator.class;
434 } else if (validatorType.equals("datetime")) {
435 return DateTimeValidator.class;
436 } else if (validatorType.equals("date")) {
437 return DateValidator.class;
438 } else if (validatorType.equals("cronExpressionValidator")) {
439 return CronExpressionValidator.class;
440 } else if (validatorType.equals("repeatCountValidator")) {
441 return RepeatCountValidator.class;
442 } else if (validatorType.equals("repeatIntervalValidator")) {
443 return RepeatIntervalValidator.class;
444 } else if (validatorType.equals("length")) {
445 return StringLengthValidator.class;
446 } else if (validatorType.equals("category")) {
447 return CategoryValidator.class;
448 } else if (validatorType.equals("XSSValidator")) {
449 return XSSValidator.class;
450 } else if (validatorType.equals("phone")) {
451 return PhoneFormatValidator.class;
452 } else {
453 ClassLoader cl = Thread.currentThread().getContextClassLoader();
454 return cl.loadClass(validatorType);
455 }
456 }
457
458 @SuppressWarnings("unchecked")
459 public static void addValidators(UIFormInputBase uiInput, String validators) throws Exception {
460 String[] validatorList = null;
461 if (validators.indexOf(',') > -1)
462 validatorList = validators.split(",");
463 else
464 validatorList = new String[] { validators };
465 for (String validator : validatorList) {
466 Object[] params;
467 String s_param = null;
468 int p_begin, p_end;
469 p_begin = validator.indexOf(VALIDATOR_PARAM_BEGIN);
470 p_end = validator.indexOf(VALIDATOR_PARAM_END);
471 if (p_begin > 0 && p_end > p_begin) {
472 String v_name;
473 s_param = validator.substring(p_begin + 1, p_end);
474 params = s_param.split(VALIDATOR_PARAM_SEPERATOR);
475 params = parserValidatorParam(params, params.length - 1, params[params.length - 1].toString());
476 v_name = validator.substring(0, p_begin);
477 uiInput.addValidator(getValidator(v_name.trim()), params);
478 } else {
479 uiInput.addValidator(getValidator(validator.trim()));
480 }
481 }
482 }
483
484
485
486
487
488
489
490
491 public static Object[] parserValidatorParam(Object[] params, int length, String type) throws Exception {
492 int i;
493 Object[] newParams;
494 if (length < 1)
495 return params;
496 newParams = new Object[length];
497 if (type.equalsIgnoreCase(TYPE_INTEGER)) {
498 for (i = 0; i < length; i++)
499 newParams[i] = Integer.parseInt(params[i].toString());
500 } else if (type.equalsIgnoreCase(TYPE_FLOAT)) {
501 for (i = 0; i < length; i++)
502 newParams[i] = Float.parseFloat(params[i].toString());
503 } else if (type.equalsIgnoreCase(TYPE_DOUBLE)) {
504 for (i = 0; i < length; i++)
505 newParams[i] = Double.parseDouble(params[i].toString());
506 } else
507 return params;
508 return newParams;
509 }
510 }