Java tutorial
/* * #%L * Alfresco Repository * %% * Copyright (C) 2005 - 2016 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Alfresco 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.repo.forms.processor.node; import static org.alfresco.repo.forms.processor.node.FormFieldConstants.PROP_DATA_PREFIX; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint; import org.alfresco.repo.dictionary.constraint.RegisteredConstraint; import org.alfresco.repo.domain.node.NodePropertyValue; import org.alfresco.repo.forms.Field; import org.alfresco.repo.forms.FieldGroup; import org.alfresco.repo.forms.PropertyFieldDefinition; import org.alfresco.repo.forms.PropertyFieldDefinition.FieldConstraint; import org.alfresco.repo.forms.processor.FieldProcessor; import org.alfresco.service.cmr.dictionary.Constraint; import org.alfresco.service.cmr.dictionary.ConstraintDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.Period; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.util.ISO8601DateFormat; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.StringUtils; /** * {@link FieldProcessor} implementation that handles properties. * * @since 3.4 * @author Nick Smith */ public class PropertyFieldProcessor extends QNameFieldProcessor<PropertyDefinition> { private static final Log logger = LogFactory.getLog(PropertyFieldProcessor.class); public PropertyFieldProcessor() { // Constructor for Spring. } public PropertyFieldProcessor(NamespaceService namespaceService, DictionaryService dictionaryService) { super(namespaceService, dictionaryService); } @Override protected Log getLogger() { return logger; } @Override protected PropertyDefinition getTypeDefinition(QName fullName, ContentModelItemData<?> itemData, boolean isForcedField) { PropertyDefinition propDef = itemData.getPropertyDefinition(fullName); if (propDef == null) { if (isForcedField) { propDef = dictionaryService.getProperty(fullName); } } return propDef; } /** * {@inheritDoc} */ @Override public Field makeField(PropertyDefinition propDef, Object value, FieldGroup group) { PropertyFieldDefinition fieldDef = makePropertyFieldDefinition(propDef, group); return new ContentModelField(propDef, fieldDef, value); } @Override protected FieldGroup getGroup(PropertyDefinition propDef) { // TODO Need to Implement this once Composite Content is implementd. return null; } @Override public Object getValue(QName name, ContentModelItemData<?> data) { Serializable value = data.getPropertyValue(name); if (value == null) { return getDefaultValue(name, data); } if (value instanceof Collection<?>) { // temporarily add repeating field data as a comma // separated list, this will be changed to using // a separate field for each value once we have full // UI support in place. Collection<?> values = (Collection<?>) value; // if the non empty collection is a List of Date objects // we need to convert each date to a ISO8601 format if (value instanceof List<?> && !values.isEmpty()) { List<?> list = (List<?>) values; if (list.get(0) instanceof Date) { List<String> isoDates = new ArrayList<String>(list.size()); for (Object date : list) { isoDates.add(ISO8601DateFormat.format((Date) date)); } // return the ISO formatted dates as a comma delimited string return StringUtils.collectionToCommaDelimitedString(isoDates); } } // return everything else using toString() return StringUtils.collectionToCommaDelimitedString(values); } else if (value instanceof ContentData) { // for content properties retrieve the info URL rather than the // the object value itself ContentData contentData = (ContentData) value; return contentData.getInfoUrl(); } else if (value instanceof NodeRef) { return ((NodeRef) value).toString(); } return value; } private Object getDefaultValue(QName name, ContentModelItemData<?> data) { PropertyDefinition propDef = data.getPropertyDefinition(name); if (propDef != null) { QName typeQName = propDef.getDataType().getName(); String strDefaultValue = propDef.getDefaultValue(); if (NodePropertyValue.isDataTypeSupported(typeQName)) { // convert to the appropriate type NodePropertyValue pv = new NodePropertyValue(typeQName, strDefaultValue); return pv.getValue(typeQName); } return strDefaultValue; } return null; } private PropertyFieldDefinition makePropertyFieldDefinition(final PropertyDefinition propDef, FieldGroup group) { String name = getPrefixedName(propDef); QName dataType = propDef.getDataType().getName(); PropertyFieldDefinition fieldDef = new PropertyFieldDefinition(name, dataType.getLocalName()); populateFieldDefinition(propDef, fieldDef, group, PROP_DATA_PREFIX); fieldDef.setDefaultValue(propDef.getDefaultValue()); fieldDef.setMandatory(propDef.isMandatory()); fieldDef.setRepeating(propDef.isMultiValued()); fieldDef.setIndexTokenisationMode(propDef.getIndexTokenisationMode()); // any property from the system model (sys prefix) should be protected // the model doesn't // currently enforce this so make sure they are not editable if (NamespaceService.SYSTEM_MODEL_1_0_URI.equals(propDef.getName().getNamespaceURI())) { fieldDef.setProtectedField(true); } // If the property data type is d:period we need to setup a data // type parameters object to represent the options and rules if (dataType.equals(DataTypeDefinition.PERIOD)) { PeriodDataTypeParameters periodOptions = getPeriodOptions(); fieldDef.setDataTypeParameters(periodOptions); } // setup constraints for the property List<FieldConstraint> fieldConstraints = makeFieldConstraints(propDef); fieldDef.setConstraints(fieldConstraints); return fieldDef; } private List<FieldConstraint> makeFieldConstraints(PropertyDefinition propDef) { List<FieldConstraint> fieldConstraints = null; List<ConstraintDefinition> constraints = propDef.getConstraints(); if (constraints != null && constraints.size() > 0) { fieldConstraints = new ArrayList<FieldConstraint>(constraints.size()); for (ConstraintDefinition constraintDef : constraints) { Constraint constraint = constraintDef.getConstraint(); String type = constraint.getType(); Map<String, Object> params = constraint.getParameters(); //ListOfValuesConstraints have special handling for localising their allowedValues. //If the constraint that we are currently handling is a registered constraint then //we need to examine the underlying constraint to see if it is a LIST constraint if (RegisteredConstraint.class.isAssignableFrom(constraint.getClass())) { constraint = ((RegisteredConstraint) constraint).getRegisteredConstraint(); } if (ListOfValuesConstraint.class.isAssignableFrom(constraint.getClass())) { ListOfValuesConstraint lovConstraint = (ListOfValuesConstraint) constraint; List<String> allowedValues = lovConstraint.getAllowedValues(); List<String> localisedValues = new ArrayList<String>(allowedValues.size()); // Look up each localised display-label in turn. for (String value : allowedValues) { String displayLabel = lovConstraint.getDisplayLabel(value, dictionaryService); // Change the allowedValue entry to the format the FormsService expects for localised strings: "value|label" // If there is no localisation defined for any value, then this will give us "value|value". localisedValues.add(value + "|" + displayLabel); } // Now replace the allowedValues param with our localised version. params.put(ListOfValuesConstraint.ALLOWED_VALUES_PARAM, localisedValues); } FieldConstraint fieldConstraint = new FieldConstraint(type, params); fieldConstraints.add(fieldConstraint); } } return fieldConstraints; } private PeriodDataTypeParameters getPeriodOptions() { PeriodDataTypeParameters periodOptions = new PeriodDataTypeParameters(); Set<String> providers = Period.getProviderNames(); for (String provider : providers) { periodOptions.addPeriodProvider(Period.getProvider(provider)); } return periodOptions; } @Override protected String getRegistryKey() { return FormFieldConstants.PROP; } }