/** * Enact all of the value definition changes, then call the group listener (if there is one). * * @param groupUpdateAction the group action to enact value changes on. * @param configurationSource will be passed to the {@link * GroupChangeListener#onChange(ConfigurationSource)} method giving it a chance to lookup * other values at runtime. * @throws GroupConfigurationException if any problem occurs with the value updates or listener * invocation. */ public void enactGroupChange( GroupChangeAction groupUpdateAction, ConfigurationSource configurationSource) { ValueDefinitionGroup valueDefinitionGroup = groupUpdateAction.getGroup(); List<ValueChangeAction> actionList = groupUpdateAction.getActionList(); List<ConfigurationException> valueUpdateErrors = new ArrayList<ConfigurationException>(); Object semaphore = valueDefinitionGroup.getSemaphore(); if (semaphore == null) { // Semaphore must be set to something semaphore = new Object(); } /* * Lock on the semaphore, providing an opportunity to atomically update a group of variables. */ synchronized (semaphore) { /* * Make the value updates by calling the listeners. Make an attempt to update all values, in case */ for (ValueChangeAction valueUpdateAction : actionList) { try { enactValueChange(valueUpdateAction); } catch (ConfigurationException e) { valueUpdateErrors.add(e); } } if (!valueUpdateErrors.isEmpty()) { throw new GroupConfigurationException( valueDefinitionGroup.getName(), Phase.VALUE_ASSIGNMENT, valueUpdateErrors); } /* * We are clear to notify of the change */ GroupChangeListener changeListener = valueDefinitionGroup.getChangeListener(); if (changeListener != null) { try { changeListener.onChange(configurationSource); } catch (RuntimeException e) { throw new GroupConfigurationException( valueDefinitionGroup.getName(), Phase.LISTENER_INVOCATION, e); } } } }
/** * Prepares a {@link ValueChangeAction} for each {@link ValueDefinition} in the specified group. * * @param valueDefinitionGroup the group to prepare value changes for * @param configurationSource the source from which to resolve the values of this group * @return the group change action * @throws GroupConfigurationException if there is a problem retrieving values for one or more of * the {@link ValueDefinition}s in the group */ public GroupChangeAction prepareGroupChange( ValueDefinitionGroup valueDefinitionGroup, ConfigurationSource configurationSource) { Collection<ValueDefinition<?, ?>> valueDefinitionList = valueDefinitionGroup.getValues(); List<ValueChangeAction> updateActions = new ArrayList<ValueChangeAction>(valueDefinitionList.size()); List<ConfigurationException> valueResolveErrors = new ArrayList<ConfigurationException>(); try { for (ValueDefinition<?, ?> valueDefinition : valueDefinitionList) { ValueChangeAction valueChangeAction = prepareValueChange(valueDefinition, configurationSource); updateActions.add(valueChangeAction); } } catch (ConfigurationException e) { valueResolveErrors.add(e); } if (!valueResolveErrors.isEmpty()) { throw new GroupConfigurationException( valueDefinitionGroup.getName(), Phase.VALUE_DISCOVERY, valueResolveErrors); } return new GroupChangeAction(valueDefinitionGroup, updateActions); }