package rocks.inspectit.shared.cs.cmr.property.configuration; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Properties; import java.util.Set; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlElementRefs; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import org.apache.commons.collections.CollectionUtils; import rocks.inspectit.shared.cs.cmr.property.configuration.validation.PropertyValidation; import rocks.inspectit.shared.cs.cmr.property.configuration.validation.PropertyValidationException; import rocks.inspectit.shared.cs.cmr.property.configuration.validator.IGroupedProperyValidator; import rocks.inspectit.shared.cs.cmr.property.configuration.validator.impl.GreaterOrEqualValidator; import rocks.inspectit.shared.cs.cmr.property.configuration.validator.impl.GreaterValidator; import rocks.inspectit.shared.cs.cmr.property.configuration.validator.impl.LessOrEqualValidator; import rocks.inspectit.shared.cs.cmr.property.configuration.validator.impl.LessValidator; import rocks.inspectit.shared.cs.cmr.property.update.IPropertyUpdate; /** * Property that is consisted out of several {@link SingleProperty}ies. * * @author Ivan Senic * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "group-property") public class GroupedProperty extends AbstractProperty { /** * {@link SingleProperty} set that are forming this group. */ @XmlElementWrapper(name = "properties", required = true) @XmlElementRef private Set<SingleProperty<?>> singleProperties = new LinkedHashSet<>(); /** * Validators for relations in the group. */ @XmlElementWrapper(name = "group-validators") @XmlElementRefs({ @XmlElementRef(type = LessValidator.class), @XmlElementRef(type = LessOrEqualValidator.class), @XmlElementRef(type = GreaterValidator.class), @XmlElementRef(type = GreaterOrEqualValidator.class) }) private List<IGroupedProperyValidator> validators; /** * No-arg constructors. */ public GroupedProperty() { } /** * Default constructor. * * @param name * Display name of the property. Can not be <code>null</code>. * @param description * Description providing more information on property. * @throws IllegalArgumentException * If name or section are <code>null</code>. * @see AbstractProperty#AbstractProperty(String, String) */ public GroupedProperty(String name, String description) throws IllegalArgumentException { super(name, description); } /** * {@inheritDoc} */ @Override public boolean isAdvanced() { if (CollectionUtils.isNotEmpty(singleProperties)) { for (SingleProperty<?> singleProperty : singleProperties) { if (singleProperty.isAdvanced()) { return true; } } } return false; } /** * {@inheritDoc} */ @Override public boolean isServerRestartRequired() { if (CollectionUtils.isNotEmpty(singleProperties)) { for (SingleProperty<?> singleProperty : singleProperties) { if (singleProperty.isServerRestartRequired()) { return true; } } } return false; } /** * {@inheritDoc} */ @Override protected void validate(PropertyValidation propertyValidation) { // first execute validation on all single properties if (CollectionUtils.isNotEmpty(singleProperties)) { for (SingleProperty<?> property : singleProperties) { property.validate(propertyValidation); } } // then execute all grouped property validators if (CollectionUtils.isNotEmpty(validators)) { for (IGroupedProperyValidator validator : validators) { validator.validate(this, propertyValidation); } } } /** * Validates with the group validators this property, based on the changes of the single * properties reported by update list. * * @param propertyUpdates * Information about updates. * @throws PropertyValidationException * If validation fails. */ public void validateForPropertiesUpdate(Collection<IPropertyUpdate<?>> propertyUpdates) throws PropertyValidationException { PropertyValidation propertyValidation = PropertyValidation.createFor(this); for (IGroupedProperyValidator groupedProperyValidator : validators) { groupedProperyValidator.validateForPropertyUpdates(this, propertyUpdates, propertyValidation); } // if has errors raise exception, otherwise create property update if (propertyValidation.hasErrors()) { throw new PropertyValidationException(propertyValidation); } } /** * {@inheritDoc} */ @Override public void register(Properties properties) { if (CollectionUtils.isNotEmpty(singleProperties)) { for (SingleProperty<?> property : singleProperties) { property.register(properties); } } } /** * {@inheritDoc} */ @Override public SingleProperty<?> forLogicalname(String propertyLogicalName) { for (AbstractProperty property : singleProperties) { SingleProperty<?> returnProperty = property.forLogicalname(propertyLogicalName); if (null != returnProperty) { return returnProperty; } } return null; } /** * Gets {@link #singleProperties}. * * @return {@link #singleProperties} */ public Set<SingleProperty<?>> getSingleProperties() { return singleProperties; } /** * Adds {@link SingleProperty} to this group. * * @param property * {@link SingleProperty} to add. */ public void addSingleProperty(SingleProperty<?> property) { singleProperties.add(property); } /** * Adds {@link IGroupedProperyValidator} to be used for validating this group. * * @param validator * Validator. */ public void addValidator(IGroupedProperyValidator validator) { if (null == validators) { validators = new ArrayList<>(); } validators.add(validator); } /** * {@inheritDoc} */ @Override public int hashCode() { final int prime = 31; int result = 1; result = (prime * result) + ((singleProperties == null) ? 0 : singleProperties.hashCode()); return result; } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } GroupedProperty other = (GroupedProperty) obj; if (singleProperties == null) { if (other.singleProperties != null) { return false; } } else if (!singleProperties.equals(other.singleProperties)) { return false; } return true; } }