/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This 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 2.1 of
* the License, or (at your option) any later version.
*
* This software 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 this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.controller.registry;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.operations.common.Util;
import org.jboss.as.controller.transform.TransformationContext;
import org.jboss.as.controller.transform.Transformers;
import org.jboss.dmr.ModelNode;
/**
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
*/
public abstract class AliasEntry {
private final ManagementResourceRegistration target;
private volatile PathAddress aliasAddress;
private volatile PathAddress targetAddress;
protected AliasEntry(final ManagementResourceRegistration target) {
this.target = target;
}
ManagementResourceRegistration getTarget() {
return target;
}
void setAddresses(PathAddress targetAddress, PathAddress aliasAddress) {
this.targetAddress = targetAddress;
this.aliasAddress = aliasAddress;
}
/**
* Gets the address to which this alias is registered
*
* @return the alias address
*/
protected PathAddress getAliasAddress() {
return aliasAddress;
}
/**
* Gets the address to which this alias should convert
*
* @return the target address
*/
protected PathAddress getTargetAddress() {
return targetAddress;
}
/**
* Convert the alias address to the target address
*
* @param aliasAddress the alias address
* @return the target address
* @deprecated This will be removed in WildFly Core 3; override convertToTargetAddress(PathAddress, AliasContext) instead
*/
@Deprecated
public PathAddress convertToTargetAddress(PathAddress aliasAddress) {
throw new UnsupportedOperationException("convertToTargetAddress");
}
/**
* Convert the alias address to the target address.
*
* @param aliasAddress the alias address
* @param aliasAddress the alias address
* @return the target address
*/
public PathAddress convertToTargetAddress(PathAddress aliasAddress, AliasContext aliasContext) {
return convertToTargetAddress(aliasAddress);
}
/**
* A wrapper around {@link OperationContext} for the requested alias address, allowing extra
* contextual information when converting alias addresses.
*/
public static class AliasContext {
public static final String RECURSIVE_GLOBAL_OP = "recursive-global-op";
final ResourceProvider delegate;
final ModelNode operation;
private AliasContext(final ModelNode operation, final ResourceProvider delegate) {
this.delegate = delegate;
this.operation = operation.clone();
this.operation.protect();
}
static AliasContext create(final ModelNode operation, final OperationContext delegate) {
return new AliasContext(operation, new ResourceProvider() {
@Override
public Resource readResourceFromRoot(PathAddress address) {
return delegate.readResourceFromRoot(address);
}
@Override
public Resource readResourceFromRoot(PathAddress address, boolean recursive) {
return delegate.readResourceFromRoot(address, recursive);
}
});
}
public static AliasContext create(final PathAddress address, final OperationContext delegate) {
return create(Util.createEmptyOperation(RECURSIVE_GLOBAL_OP, address), delegate);
}
public static AliasContext create(final ModelNode operation, final TransformationContext delegate) {
return new AliasContext(operation, new ResourceProvider() {
@Override
public Resource readResourceFromRoot(PathAddress address) {
return delegate.readResourceFromRoot(address);
}
@Override
public Resource readResourceFromRoot(PathAddress address, boolean recursive) {
return delegate.readResourceFromRoot(address); //I think this is always recursive
}
});
}
public static AliasContext create(ModelNode operation, Transformers.TransformationInputs transformationInputs) {
return new AliasContext(operation, new ResourceProvider() {
@Override
public Resource readResourceFromRoot(PathAddress address) {
return readResourceFromRoot(address, false);
}
@Override
public Resource readResourceFromRoot(PathAddress address, boolean recursive) {
Resource resource = transformationInputs.getRootResource().navigate(address);
if (resource == null) {
return resource;
}
if (recursive) {
return resource.clone();
}
final Resource copy = Resource.Factory.create();
copy.writeModel(resource.getModel());
for(final String childType : resource.getChildTypes()) {
for(final Resource.ResourceEntry child : resource.getChildren(childType)) {
copy.registerChild(child.getPathElement(), PlaceholderResource.INSTANCE);
}
}
return copy;
}
});
}
/**
* @see OperationContext#readResourceFromRoot(PathAddress)
*/
public Resource readResourceFromRoot(final PathAddress address) {
return delegate.readResourceFromRoot(address);
}
/**
* @see OperationContext#readResource(PathAddress, boolean)
*/
public Resource readResourceFromRoot(final PathAddress address, final boolean recursive) {
return delegate.readResourceFromRoot(address, recursive);
}
/**
* Gets the operation being called. The operation is protected, so you cannot modify it.
* For the global operations when processing children recurively it will be a placeholder operation whose name is
* {@link #RECURSIVE_GLOBAL_OP} and the address is the address of the requested aliased resource.
*
* @return the operation
*/
public ModelNode getOperation() {
return operation;
}
}
private interface ResourceProvider {
Resource readResourceFromRoot(final PathAddress address);
Resource readResourceFromRoot(final PathAddress address, final boolean recursive);
}
}