/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., 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.transform; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.PathElement; import java.util.Iterator; /** * A path address transformation step. This specific type of transformer get registered alongside a resource transformer * entry and can be used to transform the {@linkplain PathAddress} for operation and resource transformations. * * In general this transformer is only responsible for changing the current {@linkplain PathElement} and the delegate * to other address transformers in the chain using {@linkplain Builder#next(org.jboss.as.controller.PathElement...)}. * * @author Emanuel Muckenhuber */ @FunctionalInterface public interface PathAddressTransformer { /** * Transform an address. * * @param current the current path element * @param builder the address builder * @return the path address */ PathAddress transform(PathElement current, Builder builder); PathAddressTransformer DEFAULT = new PathAddressTransformer() { @Override public PathAddress transform(PathElement current, Builder builder) { return builder.next(current); } }; public class BasicPathAddressTransformer implements PathAddressTransformer { private final PathElement swap; public BasicPathAddressTransformer(PathElement swap) { this.swap = swap; } @Override public PathAddress transform(PathElement current, Builder builder) { return builder.next(swap); } } public class ReplaceElementKey implements PathAddressTransformer { private final String newKey; public ReplaceElementKey(String newKey) { this.newKey = newKey; } @Override public PathAddress transform(PathElement current, Builder builder) { final PathElement newElement = PathElement.pathElement(newKey, current.getValue()); return builder.next(newElement); } } public interface Builder { /** * Get the unmodified (original) address. * * @return the original address */ PathAddress getOriginal(); /** * Get the current address, from the builder. * * @return the current address */ PathAddress getCurrent(); /** * Get the remaining elements left for transformation. * * @return the remaining elements for this address */ PathAddress getRemaining(); /** * Append an element to the current address and continue to the next transformer in the chain. * * @param elements the elements to append * @return the transformed address */ PathAddress next(final PathElement... elements); } class BuilderImpl implements Builder { private final Iterator<PathAddressTransformer> transformers; private final PathAddress original; private PathAddress current = PathAddress.EMPTY_ADDRESS; private int idx = 0; protected BuilderImpl(Iterator<PathAddressTransformer> transformers, PathAddress original) { this.transformers = transformers; this.original = original; } @Override public PathAddress getOriginal() { return original; } @Override public PathAddress getCurrent() { return current; } @Override public PathAddress getRemaining() { return original.subAddress(idx); } @Override public PathAddress next(final PathElement... elements) { current = current.append(elements); final int remaining = original.size() - idx; if(remaining == 0) { return current; } if(transformers.hasNext()) { final PathAddressTransformer transformer = transformers.next(); final PathElement next = original.getElement(idx++); return transformer.transform(next, this); } else { // This may not be an error? // return current.append(getRemaining()); throw new IllegalStateException(); } } protected PathAddress start() { if(original == PathAddress.EMPTY_ADDRESS || original.size() == 0) { return PathAddress.EMPTY_ADDRESS; } if(transformers.hasNext()) { final PathAddressTransformer transformer = transformers.next(); final PathElement next = original.getElement(idx++); return transformer.transform(next, this); } else { return original; } }; } }