/* * ModeShape (http://www.modeshape.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.modeshape.jboss.subsystem; import javax.jcr.RepositoryException; import org.jboss.as.controller.AbstractWriteAttributeHandler; import org.jboss.as.controller.AttributeDefinition; import org.jboss.as.controller.OperationContext; import org.jboss.as.controller.OperationFailedException; import org.jboss.as.controller.OperationStepHandler; import org.jboss.as.controller.registry.ManagementResourceRegistration; import org.jboss.dmr.ModelNode; import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceName; import org.modeshape.jboss.service.RepositoryService; /** * An {@link OperationStepHandler} implementation that automatically handles all write-attribute operations against * {@link org.jboss.as.controller.registry.AttributeAccess.Flag#RESTART_NONE RESTART_NONE} {@link AttributeDefinition}s so that * the changes are immediately reflected in the repository configuration. */ public abstract class AbstractRepositoryConfigWriteAttributeHandler extends AbstractWriteAttributeHandler<Void> { private final AttributeDefinition[] attributes; protected AbstractRepositoryConfigWriteAttributeHandler( AttributeDefinition[] attributes ) { super(attributes); this.attributes = attributes; } @Override protected boolean applyUpdateToRuntime( OperationContext context, ModelNode operation, String attributeName, ModelNode resolvedValue, ModelNode currentValue, HandbackHolder<Void> handbackHolder ) throws OperationFailedException { try { boolean changedImmediately = changeConfiguration(context, operation, attributeName, resolvedValue, currentValue); return !changedImmediately; } catch (RepositoryException t) { final String repositoryName = repositoryName(operation); throw new OperationFailedException("Unable to set attribute '" + attributeName + "' on the '" + repositoryName + "' repository from " + currentValue + " to " + resolvedValue + ": " + t.getMessage(), t); } } @Override protected void revertUpdateToRuntime( OperationContext context, ModelNode operation, String attributeName, ModelNode valueToRestore, ModelNode valueToRevert, Void handback ) throws OperationFailedException { try { changeConfiguration(context, operation, attributeName, valueToRestore, valueToRevert); } catch (RepositoryException t) { final String repositoryName = repositoryName(operation); throw new OperationFailedException("Unable to restore attribute '" + attributeName + "' on the '" + repositoryName + "' repository from " + valueToRevert + " to " + valueToRestore + ": " + t.getMessage(), t); } } protected final String repositoryName( ModelNode operation ) { AddressContext addressContext = AddressContext.forOperation(operation); return addressContext.repositoryName(); } protected boolean changeConfiguration( OperationContext context, ModelNode operation, String attributeName, ModelNode newValue, ModelNode existingValue ) throws RepositoryException, OperationFailedException { AttributeDefinition attribute = getAttributeDefinition(attributeName); if (attribute instanceof MappedAttributeDefinition) { MappedAttributeDefinition mappedDefn = (MappedAttributeDefinition)attribute; // Find the repository service ... final String repositoryName = repositoryName(operation); ServiceName repositoryServiceName = ModeShapeServiceNames.repositoryServiceName(repositoryName); ServiceController<?> sc = context.getServiceRegistry(true).getRequiredService(repositoryServiceName); RepositoryService repositoryService = RepositoryService.class.cast(sc.getService()); // And set the value (with immediate effect) ... return changeField(context, operation, repositoryService, mappedDefn, newValue); } // The field cannot be updated immediately and requires restart ... return false; } public void registerAttributes( final ManagementResourceRegistration registry ) { for (AttributeDefinition attr : attributes) { registry.registerReadWriteAttribute(attr, null, this); } } protected boolean changeField( OperationContext context, ModelNode operation, RepositoryService repositoryService, MappedAttributeDefinition defn, ModelNode newValue ) throws RepositoryException, OperationFailedException { repositoryService.changeField(defn, newValue); return true; } }