001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.dynamicdatamapping.validator;
016    
017    import com.liferay.portal.kernel.bean.BeanPropertiesUtil;
018    import com.liferay.portal.kernel.util.ArrayUtil;
019    import com.liferay.portal.kernel.util.MapUtil;
020    import com.liferay.portal.kernel.util.StringPool;
021    import com.liferay.portal.kernel.util.Validator;
022    import com.liferay.portlet.dynamicdatamapping.DDMFormValidationException;
023    import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
024    import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
025    import com.liferay.portlet.dynamicdatamapping.model.DDMFormFieldOptions;
026    import com.liferay.portlet.dynamicdatamapping.model.DDMFormFieldType;
027    import com.liferay.portlet.dynamicdatamapping.model.LocalizedValue;
028    
029    import java.util.List;
030    import java.util.Locale;
031    import java.util.Set;
032    import java.util.regex.Matcher;
033    import java.util.regex.Pattern;
034    
035    /**
036     * @author Marcellus Tavares
037     */
038    public class DDMFormValidatorImpl implements DDMFormValidator {
039    
040            @Override
041            public void validate(DDMForm ddmForm) throws DDMFormValidationException {
042                    validateDDMFormLocales(ddmForm);
043    
044                    validateDDMFormFields(
045                            ddmForm.getDDMFormFields(), ddmForm.getAvailableLocales(),
046                            ddmForm.getDefaultLocale());
047            }
048    
049            protected void validateDDMFormAvailableLocales(
050                            Set<Locale> availableLocales, Locale defaultLocale)
051                    throws DDMFormValidationException {
052    
053                    if ((availableLocales == null) || availableLocales.isEmpty()) {
054                            throw new DDMFormValidationException(
055                                    "The available locales property was never set for DDM form");
056                    }
057    
058                    if (!availableLocales.contains(defaultLocale)) {
059                            throw new DDMFormValidationException(
060                                    "The default locale " + defaultLocale + " should be set as a " +
061                                            "valid available locale");
062                    }
063            }
064    
065            protected void validateDDMFormFieldIndexType(DDMFormField ddmFormField)
066                    throws DDMFormValidationException {
067    
068                    if (!ArrayUtil.contains(
069                                    _ddmFormFieldIndexTypes, ddmFormField.getIndexType())) {
070    
071                            throw new DDMFormValidationException(
072                                    "Invalid index type set for field " + ddmFormField.getName());
073                    }
074            }
075    
076            protected void validateDDMFormFieldName(DDMFormField ddmFormField)
077                    throws DDMFormValidationException {
078    
079                    Matcher matcher = _ddmFormFieldNamePattern.matcher(
080                            ddmFormField.getName());
081    
082                    if (!matcher.matches()) {
083                            throw new DDMFormValidationException(
084                                    "Nonalphanumeric characters were defined for field name " +
085                                            ddmFormField.getName());
086                    }
087            }
088    
089            protected void validateDDMFormFieldOptions(
090                            DDMFormField ddmFormField, Set<Locale> ddmFormAvailableLocales,
091                            Locale ddmFormDefaultLocale)
092                    throws DDMFormValidationException {
093    
094                    String fieldType = ddmFormField.getType();
095    
096                    if (!fieldType.equals(DDMFormFieldType.RADIO) &&
097                            !fieldType.equals(DDMFormFieldType.SELECT)) {
098    
099                            return;
100                    }
101    
102                    DDMFormFieldOptions ddmFormFieldOptions =
103                            ddmFormField.getDDMFormFieldOptions();
104    
105                    Set<String> optionValues = ddmFormFieldOptions.getOptionsValues();
106    
107                    if (optionValues.isEmpty()) {
108                            throw new DDMFormValidationException(
109                                    "At least one option should be set for field " +
110                                            ddmFormField.getName());
111                    }
112    
113                    for (String optionValue : ddmFormFieldOptions.getOptionsValues()) {
114                            LocalizedValue localizedValue = ddmFormFieldOptions.getOptionLabels(
115                                    optionValue);
116    
117                            validateDDMFormFieldPropertyValue(
118                                    ddmFormField.getName(), "options", localizedValue,
119                                    ddmFormAvailableLocales, ddmFormDefaultLocale);
120                    }
121            }
122    
123            protected void validateDDMFormFieldPropertyValue(
124                            String fieldName, String propertyName, LocalizedValue propertyValue,
125                            Set<Locale> ddmFormAvailableLocales, Locale ddmFormDefaultLocale)
126                    throws DDMFormValidationException {
127    
128                    if (!ddmFormDefaultLocale.equals(propertyValue.getDefaultLocale())) {
129                            throw new DDMFormValidationException(
130                                    "Invalid default locale set for property \"" + propertyName +
131                                            "\" of field name " + fieldName);
132                    }
133    
134                    if (!ddmFormAvailableLocales.equals(
135                                    propertyValue.getAvailableLocales())) {
136    
137                            throw new DDMFormValidationException(
138                                    "Invalid available locales set for property \"" +
139                                            propertyName + "\" of field name " + fieldName);
140                    }
141            }
142    
143            protected void validateDDMFormFields(
144                            List<DDMFormField> ddmFormFields,
145                            Set<Locale> ddmFormAvailableLocales, Locale ddmFormDefaultLocale)
146                    throws DDMFormValidationException {
147    
148                    for (DDMFormField ddmFormField : ddmFormFields) {
149                            validateDDMFormFieldName(ddmFormField);
150    
151                            validateDDMFormFieldType(ddmFormField);
152    
153                            validateDDMFormFieldIndexType(ddmFormField);
154    
155                            validateDDMFormFieldOptions(
156                                    ddmFormField, ddmFormAvailableLocales, ddmFormDefaultLocale);
157    
158                            validateOptionalDDMFormFieldLocalizedProperty(
159                                    ddmFormField, "label", ddmFormAvailableLocales,
160                                    ddmFormDefaultLocale);
161    
162                            validateOptionalDDMFormFieldLocalizedProperty(
163                                    ddmFormField, "predefinedValue", ddmFormAvailableLocales,
164                                    ddmFormDefaultLocale);
165    
166                            validateOptionalDDMFormFieldLocalizedProperty(
167                                    ddmFormField, "tip", ddmFormAvailableLocales,
168                                    ddmFormDefaultLocale);
169    
170                            validateDDMFormFields(
171                                    ddmFormField.getNestedDDMFormFields(), ddmFormAvailableLocales,
172                                    ddmFormDefaultLocale);
173                    }
174            }
175    
176            protected void validateDDMFormFieldType(DDMFormField ddmFormField)
177                    throws DDMFormValidationException {
178    
179                    if (Validator.isNull(ddmFormField.getType())) {
180                            throw new DDMFormValidationException(
181                                    "Invalid type set for field " + ddmFormField.getName());
182                    }
183            }
184    
185            protected void validateDDMFormLocales(DDMForm ddmForm)
186                    throws DDMFormValidationException {
187    
188                    Locale defaultLocale = ddmForm.getDefaultLocale();
189    
190                    if (defaultLocale == null) {
191                            throw new DDMFormValidationException(
192                                    "The default locale property was never set for DDM form");
193                    }
194    
195                    validateDDMFormAvailableLocales(
196                            ddmForm.getAvailableLocales(), defaultLocale);
197            }
198    
199            protected void validateOptionalDDMFormFieldLocalizedProperty(
200                            DDMFormField ddmFormField, String propertyName,
201                            Set<Locale> ddmFormAvailableLocales, Locale ddmFormDefaultLocale)
202                    throws DDMFormValidationException {
203    
204                    LocalizedValue propertyValue =
205                            (LocalizedValue)BeanPropertiesUtil.getObject(
206                                    ddmFormField, propertyName);
207    
208                    if (MapUtil.isEmpty(propertyValue.getValues())) {
209                            return;
210                    }
211    
212                    validateDDMFormFieldPropertyValue(
213                            ddmFormField.getName(), propertyName, propertyValue,
214                            ddmFormAvailableLocales, ddmFormDefaultLocale);
215            }
216    
217            private final String[] _ddmFormFieldIndexTypes = new String[] {
218                    StringPool.BLANK, "keyword", "text"
219            };
220            private final Pattern _ddmFormFieldNamePattern = Pattern.compile("\\w+");
221    
222    }