final String attributeName = operation.require(NAME).asString();
final boolean defaults = operation.get(INCLUDE_DEFAULTS).asBoolean(true);
final ModelNode subModel = safeReadModel(context);
final ImmutableManagementResourceRegistration registry = context.getResourceRegistration();
final AttributeAccess attributeAccess = registry.getAttributeAccess(PathAddress.EMPTY_ADDRESS, attributeName);
if (attributeAccess == null) {
final Set<String> children = context.getResourceRegistration().getChildNames(PathAddress.EMPTY_ADDRESS);
if (children.contains(attributeName)) {
throw new OperationFailedException(new ModelNode().set(MESSAGES.attributeRegisteredOnResource(attributeName, operation.get(OP_ADDR))));
} else if (subModel.hasDefined(attributeName)) {
final ModelNode result = subModel.get(attributeName);
context.getResult().set(result);
} else {
// No defined value in the model. See if we should reply with a default from the metadata,
// reply with undefined, or fail because it's a non-existent attribute name
final ModelNode nodeDescription = getNodeDescription(registry, operation);
if (defaults && nodeDescription.get(ATTRIBUTES).hasDefined(attributeName) &&
nodeDescription.get(ATTRIBUTES, attributeName).hasDefined(DEFAULT)) {
final ModelNode result = nodeDescription.get(ATTRIBUTES, attributeName, DEFAULT);
context.getResult().set(result);
} else if (subModel.has(attributeName) || nodeDescription.get(ATTRIBUTES).has(attributeName)) {
// model had no defined value, but we treat its existence in the model or the metadata
// as proof that it's a legit attribute name
context.getResult(); // this initializes the "result" to ModelType.UNDEFINED
} else {
throw new OperationFailedException(new ModelNode().set(MESSAGES.unknownAttribute(attributeName)));
}
}
// Complete the step for the unregistered attribute case
context.completeStep(OperationContext.RollbackHandler.NOOP_ROLLBACK_HANDLER);
} else if (attributeAccess.getReadHandler() == null) {
// We know the attribute name is legit as it's in the registry, so this case is simpler
if (subModel.hasDefined(attributeName) || !defaults) {
final ModelNode result = subModel.get(attributeName);
context.getResult().set(result);
} else {
// It wasn't in the model, but user wants a default value from metadata if there is one
final ModelNode nodeDescription = getNodeDescription(registry, operation);
if (nodeDescription.get(ATTRIBUTES).hasDefined(attributeName) &&
nodeDescription.get(ATTRIBUTES, attributeName).hasDefined(DEFAULT)) {
final ModelNode result = nodeDescription.get(ATTRIBUTES, attributeName, DEFAULT);
context.getResult().set(result);
} else {
context.getResult(); // this initializes the "result" to ModelType.UNDEFINED
}
}
// Complete the step for the "registered attribute but default read handler" case
context.completeStep(OperationContext.RollbackHandler.NOOP_ROLLBACK_HANDLER);
} else {
OperationStepHandler handler = attributeAccess.getReadHandler();
ClassLoader oldTccl = SecurityActions.setThreadContextClassLoader(handler.getClass());
try {
handler.execute(context, operation);
} finally {
SecurityActions.setThreadContextClassLoader(oldTccl);