/* * Copyright (C) 2003-2008 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. */ package org.exoplatform.ecm.webui.utils; import java.io.InputStream; import java.util.*; import javax.jcr.Node; import javax.jcr.PathNotFoundException; import javax.jcr.Property; import javax.jcr.PropertyType; import org.exoplatform.commons.utils.HTMLSanitizer; import org.exoplatform.commons.utils.IOUtil; import org.exoplatform.ecm.utils.text.Text; import org.exoplatform.ecm.webui.form.UIDialogForm; import org.exoplatform.ecm.webui.form.UIFormUploadInputNoUploadButton; import org.exoplatform.ecm.webui.form.validator.*; import org.exoplatform.services.cms.JcrInputProperty; import org.exoplatform.upload.UploadResource; import org.exoplatform.wcm.webui.Utils; import org.exoplatform.webui.core.UIComponent; import org.exoplatform.webui.form.UIFormDateTimeInput; import org.exoplatform.webui.form.UIFormInputBase; import org.exoplatform.webui.form.UIFormMultiValueInputSet; import org.exoplatform.webui.form.UIFormSelectBox; import org.exoplatform.webui.form.input.UICheckBoxInput; import org.exoplatform.webui.form.input.UIUploadInput; import org.exoplatform.webui.form.validator.*; /* * Created by The eXo Platform SAS * @author : Hoa.Pham * hoa.pham@exoplatform.com * Jun 23, 2008 */ /** * The Class DialogFormUtil. */ public class DialogFormUtil { public static String VALIDATOR_PARAM_BEGIN = "("; public static String VALIDATOR_PARAM_END = ")"; public static String VALIDATOR_PARAM_SEPERATOR = ";"; public static String SANITIZATION_FLAG = "noSanitization"; /** * Type of parameters which were passed for the validator TODO: Please add all * the possible type here and parser it in side the function * parserValidatorParam. If any question, ask for VinhNT from Content's team. */ public static String TYPE_FLOAT = "Float"; public static String TYPE_DOUBLE = "Double"; public static String TYPE_INTEGER = "Int"; public static String TYPE_STRING = "String"; /** * Prepare map. * * @param inputs the inputs * @param properties the properties * @return the map of string and jcr input property * @throws Exception the exception */ public static Map<String, JcrInputProperty> prepareMap(List inputs, Map properties) throws Exception { return prepareMap(inputs, properties, null); } @SuppressWarnings("unchecked") public static Map<String, JcrInputProperty> prepareMap(List inputs, Map properties, Map options) throws Exception { Map<String, String> changeInJcrPathParamMap = new HashMap<String, String>(); Map<String, JcrInputProperty> rawinputs = new HashMap<String, JcrInputProperty>(); HashMap<String, JcrInputProperty> hasMap = new HashMap<String, JcrInputProperty>(); String inputName = null; String mimeTypeJcrPath = null; InputStream inputStream = null; Map<String, JcrInputProperty> mimeTypes = new HashMap<String, JcrInputProperty>(); for (int i = 0; i < inputs.size(); i++) { JcrInputProperty property = null; String option = null; if (inputs.get(i) instanceof UIFormMultiValueInputSet) { UIFormMultiValueInputSet inputI = (UIFormMultiValueInputSet) inputs.get(i); inputName = (inputI).getName(); if (!hasMap.containsKey(inputName)) { List<UIComponent> inputChild = inputI.getChildren(); property = (JcrInputProperty) properties.get(inputName); if (inputChild != null && inputChild.size() > 0 && inputChild.get(0) instanceof UIUploadInput) { Map<String, List> uploadDataMap = new TreeMap<String, List>(); for (UIComponent child : inputChild) { UIUploadInput uploadInput = (UIUploadInput) child; String uploadId = uploadInput.getUploadIds()[0]; String uploadDataName = null; String uploadMimeType = null; byte[] uploadData = null; if (uploadInput instanceof UIFormUploadInputNoUploadButton) { uploadDataName = ((UIFormUploadInputNoUploadButton) uploadInput).getFileName(); uploadMimeType = ((UIFormUploadInputNoUploadButton) uploadInput).getMimeType(); uploadData = ((UIFormUploadInputNoUploadButton) uploadInput).getByteValue(); } else { UploadResource uploadResource = (uploadInput).getUploadResource(uploadId); if (uploadResource != null) { String location = uploadResource.getStoreLocation(); uploadDataName = uploadResource.getFileName(); uploadData = IOUtil.getFileContentAsBytes(location); uploadMimeType = uploadResource.getMimeType(); } } if (uploadDataName != null && uploadData != null) { List<Object> data = new ArrayList<Object>(); data.add(uploadMimeType); data.add(uploadData); if (!uploadDataMap.containsKey(uploadDataName)) { uploadDataMap.put(uploadDataName, data); } else { int count = 1; while (uploadDataMap.containsKey(uploadDataName + count)) { count++; } uploadDataMap.put(uploadDataName + count, data); } } } property.setValue(uploadDataMap); } else { List<String> values = (List<String>) (inputI).getValue(); if (property != null) { property.setValue(values.toArray(new String[values.size()])); } } } hasMap.put(inputName, property); } else { UIFormInputBase input = (UIFormInputBase) inputs.get(i); property = (JcrInputProperty) properties.get(input.getName()); if (options != null && options.get(input.getName()) != null) option = (String) options.get(input.getName()); if (property != null) { if (input instanceof UIUploadInput) { String uploadId = ((UIUploadInput) input).getUploadIds()[0]; UploadResource uploadResource = ((UIUploadInput) input).getUploadResource(uploadId); if (uploadResource == null) { if (property.getChangeInJcrPathParam() != null) changeInJcrPathParamMap.put(property.getChangeInJcrPathParam(), ""); continue; } String location = uploadResource.getStoreLocation(); byte[] uploadData = IOUtil.getFileContentAsBytes(location); property.setValue(uploadData); // change param in jcr path if (property.getChangeInJcrPathParam() != null) changeInJcrPathParamMap.put(property.getChangeInJcrPathParam(), Text.escapeIllegalJcrChars(uploadResource.getFileName())); mimeTypeJcrPath = property.getJcrPath().replace("jcr:data", "jcr:mimeType"); JcrInputProperty mimeTypeInputPropertyTmp = new JcrInputProperty(); mimeTypeInputPropertyTmp.setJcrPath(mimeTypeJcrPath); mimeTypeInputPropertyTmp.setValue(((UIUploadInput) input).getUploadResource(uploadId).getMimeType()); mimeTypes.put(mimeTypeJcrPath, mimeTypeInputPropertyTmp); } else if (input instanceof UIFormDateTimeInput) { property.setValue(((UIFormDateTimeInput) input).getCalendar()); } else if (input instanceof UIFormSelectBox) { UIFormSelectBox uiSelectBox = (UIFormSelectBox) input; if (!uiSelectBox.isMultiple()) { property.setValue(uiSelectBox.getValue()); } else { property.setValue(uiSelectBox.getSelectedValues()); } } else if (input instanceof UICheckBoxInput) { property.setValue(((UICheckBoxInput) input).isChecked()); } else { if (input.getValue() != null) { String inputValue = input.getValue().toString().trim(); boolean isEmpty = Utils.isEmptyContent(inputValue); if (isEmpty) inputValue = ""; else if (option == null || option.indexOf(SANITIZATION_FLAG) < 0) inputValue = HTMLSanitizer.sanitize(inputValue); if (input.getName().equals("name") && input.getAncestorOfType(UIDialogForm.class).isAddNew() && properties.get("title") == null) { JcrInputProperty jcrExoTitle = new JcrInputProperty(); jcrExoTitle.setJcrPath("/node/exo:title"); jcrExoTitle.setValue(inputValue); properties.put("/node/exo:title", jcrExoTitle); } property.setValue(inputValue); } else { property.setValue(input.getValue()); } } } } } Iterator iter = properties.values().iterator(); JcrInputProperty property; while (iter.hasNext()) { property = (JcrInputProperty) iter.next(); rawinputs.put(property.getJcrPath(), property); } for (String jcrPath : mimeTypes.keySet()) { if (!rawinputs.containsKey(jcrPath)) { rawinputs.put(jcrPath, mimeTypes.get(jcrPath)); } } List<UIUploadInput> formUploadList = new ArrayList<UIUploadInput>(); for (Object input : inputs) { if (input instanceof UIFormMultiValueInputSet) { UIFormMultiValueInputSet uiSet = (UIFormMultiValueInputSet) input; if (uiSet.getId() != null && uiSet.getUIFormInputBase().equals(UIUploadInput.class) && uiSet.getId().equals("attachment__")) { List<UIComponent> list = uiSet.getChildren(); for (UIComponent component : list) { if (!formUploadList.contains(component)) formUploadList.add((UIUploadInput) component); } } } else if (input instanceof UIUploadInput) { if (!formUploadList.contains(input)) formUploadList.add((UIUploadInput) input); } } if (formUploadList.size() > 0) { List<String> keyListToRemove = new ArrayList<String>(); Map<String, JcrInputProperty> jcrPropertiesToAdd = new HashMap<String, JcrInputProperty>(); for (Object inputJCRKeyTmp : rawinputs.keySet()) { String inputJCRKey = (String) inputJCRKeyTmp; if (inputJCRKey.contains("attachment__")) { JcrInputProperty jcrInputProperty = rawinputs.get(inputJCRKey); for (UIUploadInput uploadInput : formUploadList) { String uploadId = uploadInput.getUploadIds()[0]; JcrInputProperty newJcrInputProperty = clone(jcrInputProperty); if (uploadInput == null || uploadInput.getUploadResource(uploadId) == null || uploadInput.getUploadResource(uploadId).getFileName() == null) continue; String fileName = uploadInput.getUploadResource(uploadId).getFileName(); String newJCRPath = inputJCRKey.replace("attachment__", fileName); newJcrInputProperty.setJcrPath(newJCRPath); if (inputJCRKey.endsWith("attachment__")) { newJcrInputProperty.setValue(fileName); JcrInputProperty mimeTypeInputPropertyTmp = new JcrInputProperty(); mimeTypeInputPropertyTmp.setJcrPath(newJCRPath + "/jcr:content/jcr:mimeType"); mimeTypeInputPropertyTmp.setValue(uploadInput.getUploadResource(uploadId).getMimeType()); jcrPropertiesToAdd.put(mimeTypeInputPropertyTmp.getJcrPath(), mimeTypeInputPropertyTmp); } if (inputJCRKey.endsWith("jcr:data")) { inputStream = uploadInput.getUploadDataAsStream(uploadId); newJcrInputProperty.setValue(inputStream); } jcrPropertiesToAdd.put(newJCRPath, newJcrInputProperty); } keyListToRemove.add(inputJCRKey); keyListToRemove.add(inputJCRKey.replace("jcr:data", "jcr:mimeType")); } } for (String keyToRemove : keyListToRemove) { rawinputs.remove(keyToRemove); } rawinputs.putAll(jcrPropertiesToAdd); } if (changeInJcrPathParamMap.isEmpty()) { return rawinputs; } Map<String, JcrInputProperty> ret = new HashMap<String, JcrInputProperty>(); Set<String> removedKeys = new HashSet<String>(); for (Map.Entry<String, String> changeEntry : changeInJcrPathParamMap.entrySet()) { for (Map.Entry<String, JcrInputProperty> entry : rawinputs.entrySet()) { if (entry.getKey().contains(changeEntry.getKey())) { removedKeys.add(entry.getKey()); JcrInputProperty value = entry.getValue(); if (value.getJcrPath() != null) { value.setJcrPath(value.getJcrPath().replace(changeEntry.getKey(), changeEntry.getValue())); } if (value.getValue() != null && value.getValue() instanceof String) { value.setValue(((String) value.getValue()).replace(changeEntry.getKey(), changeEntry.getValue())); } if (value != null && !"".equals(value) && changeEntry.getValue() != null && !"".equals(changeEntry.getValue())) { ret.put(entry.getKey().replace(changeEntry.getKey(), changeEntry.getValue()), value); } } } } for (Map.Entry<String, JcrInputProperty> entry : rawinputs.entrySet()) { if (!removedKeys.contains(entry.getKey())) { ret.put(entry.getKey(), entry.getValue()); } } return ret; } private static JcrInputProperty clone(JcrInputProperty fileNodeInputProperty) { JcrInputProperty jcrInputProperty = new JcrInputProperty(); jcrInputProperty.setJcrPath(fileNodeInputProperty.getJcrPath()); jcrInputProperty.setMixintype(fileNodeInputProperty.getMixintype()); jcrInputProperty.setNodetype(fileNodeInputProperty.getNodetype()); jcrInputProperty.setType(fileNodeInputProperty.getType()); jcrInputProperty.setValue(fileNodeInputProperty.getValue()); jcrInputProperty.setValueType(fileNodeInputProperty.getValueType()); return jcrInputProperty; } /** * Creates the form input. * * @param type the type * @param name the name * @param label the label * @param validateType the validate type * @param valueType the value type * @return the t * @throws Exception the exception */ public static <T extends UIFormInputBase> T createFormInput(Class<T> type, String name, String label, String validateType, Class valueType) throws Exception { Object[] args = { name, null, valueType }; UIFormInputBase formInput = type.getConstructor().newInstance(args); addValidators(formInput, validateType); if (label != null && label.length() != 0) { formInput.setLabel(label); } return type.cast(formInput); } /** * Gets the property value as string. * * @param node the node * @param propertyName the property name * @return the property value as string * @throws Exception the exception */ public static String getPropertyValueAsString(Node node, String propertyName) throws Exception { Property property = null; try { property = node.getProperty(propertyName); } catch (PathNotFoundException e) { return ""; } int valueType = property.getType(); switch (valueType) { case PropertyType.STRING: // String return property.getString(); case PropertyType.LONG: // Long return Long.toString(property.getLong()); case PropertyType.DOUBLE: // Double return Double.toString(property.getDouble()); case PropertyType.DATE: // Date return property.getDate().getTime().toString(); case PropertyType.BOOLEAN: // Boolean return Boolean.toString(property.getBoolean()); case PropertyType.NAME: // Name return property.getName(); case 8: // Path case 9: // References case 0: // Undifine } return ""; } public static Class getValidator(String validatorType) throws ClassNotFoundException { if (validatorType.equals("name")) { return ECMNameValidator.class; } else if (validatorType.equals("email")) { return EmailAddressValidator.class; } else if (validatorType.equals("number")) { return NumberFormatValidator.class; } else if (validatorType.equals("empty")) { return MandatoryValidator.class; } else if (validatorType.equals("null")) { return NullFieldValidator.class; } else if (validatorType.equals("datetime")) { return DateTimeValidator.class; } else if (validatorType.equals("date")) { return DateValidator.class; } else if (validatorType.equals("cronExpressionValidator")) { return CronExpressionValidator.class; } else if (validatorType.equals("repeatCountValidator")) { return RepeatCountValidator.class; } else if (validatorType.equals("repeatIntervalValidator")) { return RepeatIntervalValidator.class; } else if (validatorType.equals("length")) { return StringLengthValidator.class; } else if (validatorType.equals("category")) { return CategoryValidator.class; } else if (validatorType.equals("XSSValidator")) { return XSSValidator.class; } else if (validatorType.equals("phone")) { return PhoneFormatValidator.class; } else { ClassLoader cl = Thread.currentThread().getContextClassLoader(); return cl.loadClass(validatorType); } } @SuppressWarnings("unchecked") public static void addValidators(UIFormInputBase uiInput, String validators) throws Exception { String[] validatorList = null; if (validators.indexOf(',') > -1) validatorList = validators.split(","); else validatorList = new String[] { validators }; for (String validator : validatorList) { Object[] params; String s_param = null; int p_begin, p_end; p_begin = validator.indexOf(VALIDATOR_PARAM_BEGIN); p_end = validator.indexOf(VALIDATOR_PARAM_END); if (p_begin > 0 && p_end > p_begin) { String v_name; s_param = validator.substring(p_begin + 1, p_end); params = s_param.split(VALIDATOR_PARAM_SEPERATOR); params = parserValidatorParam(params, params.length - 1, params[params.length - 1].toString()); v_name = validator.substring(0, p_begin); uiInput.addValidator(getValidator(v_name.trim()), params); } else { uiInput.addValidator(getValidator(validator.trim())); } } } /** * @param params * @param length * @param type * @return the conversion of the input parameters with the new type. * @throws Exception */ public static Object[] parserValidatorParam(Object[] params, int length, String type) throws Exception { int i; Object[] newParams; if (length < 1) return params; newParams = new Object[length]; if (type.equalsIgnoreCase(TYPE_INTEGER)) { for (i = 0; i < length; i++) newParams[i] = Integer.parseInt(params[i].toString()); } else if (type.equalsIgnoreCase(TYPE_FLOAT)) { for (i = 0; i < length; i++) newParams[i] = Float.parseFloat(params[i].toString()); } else if (type.equalsIgnoreCase(TYPE_DOUBLE)) { for (i = 0; i < length; i++) newParams[i] = Double.parseDouble(params[i].toString()); } else return params;// Do not convert, let those parameters are the Objec type return newParams; } }