/*
* 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.jmx.model;
import static org.jboss.as.jmx.JmxMessages.MESSAGES;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.registry.Resource;
/**
* Utility class to convert between PathAddress and ObjectName
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
*/
class ObjectNameAddressUtil {
private static final EscapedCharacter[] ESCAPED_KEY_CHARACTERS;
private static final EscapedCharacter[] ECAPED_VALUE_CHARACTERS;
static {
List<EscapedCharacter> keys = new ArrayList<EscapedCharacter>();
List<EscapedCharacter> values = new ArrayList<EscapedCharacter>();
keys.add(new EscapedCharacter('*'));
keys.add(new EscapedCharacter('?'));
keys.add(new EscapedCharacter('+'));
keys.add(new EscapedCharacter(':'));
keys.add(new EscapedCharacter('='));
keys.add(new EscapedCharacter(','));
values.add(new EscapedCharacter(':'));
values.add(new EscapedCharacter('='));
values.add(new EscapedCharacter(','));
ESCAPED_KEY_CHARACTERS = keys.toArray(new EscapedCharacter[keys.size()]);
ECAPED_VALUE_CHARACTERS = keys.toArray(new EscapedCharacter[values.size()]);
}
static ObjectName createObjectName(final PathAddress pathAddress) {
if (pathAddress.size() == 0) {
return Constants.ROOT_MODEL_NAME;
}
final StringBuilder sb = new StringBuilder(Constants.DOMAIN);
sb.append(":");
boolean first = true;
for (PathElement element : pathAddress) {
if (first) {
first = false;
} else {
sb.append(",");
}
appendEscapedCharacter(ESCAPED_KEY_CHARACTERS, sb, element.getKey());
sb.append("=");
appendEscapedCharacter(ECAPED_VALUE_CHARACTERS, sb, element.getValue());
}
try {
return ObjectName.getInstance(sb.toString());
} catch (MalformedObjectNameException e) {
throw MESSAGES.cannotCreateObjectName(e, pathAddress);
}
}
/**
* Converts the ObjectName to a PathAddress.
*
* @param name the ObjectName
* @return the PathAddress if it exists in the model, {@code false} otherwise
*/
static PathAddress resolvePathAddress(final Resource rootResource, final ObjectName name) {
if (!name.getDomain().equals(Constants.DOMAIN)) {
return null;
}
if (name.equals(Constants.ROOT_MODEL_NAME)) {
return PathAddress.EMPTY_ADDRESS;
}
Hashtable<String, String> properties = name.getKeyPropertyList();
return searchPathAddress(PathAddress.EMPTY_ADDRESS, rootResource, properties);
}
private static PathAddress searchPathAddress(final PathAddress address, final Resource resource, final Map<String, String> properties) {
if (properties.size() == 0) {
return address;
}
for (Map.Entry<String, String> entry : properties.entrySet()) {
PathElement childElement = PathElement.pathElement(
replaceEscapedCharacters(entry.getKey()),
replaceEscapedCharacters(entry.getValue()));
Resource child = resource.getChild(childElement);
if (child != null) {
Map<String, String> childProps = new HashMap<String, String>(properties);
childProps.remove(entry.getKey());
PathAddress foundAddr = searchPathAddress(address.append(childElement), child, childProps);
if (foundAddr != null) {
return foundAddr;
}
}
}
return null;
}
static boolean isReservedDomain(ObjectName name) {
return name.getDomain().equals(Constants.DOMAIN);
}
private static void appendEscapedCharacter(EscapedCharacter[] escapedCharacters, StringBuilder sb, String value) {
for (EscapedCharacter escapedCharacter : escapedCharacters) {
value = value.replace(escapedCharacter.getChar().toString(), escapedCharacter.getEscaped());
}
sb.append(value);
}
private static String replaceEscapedCharacters(String escaped) {
if (escaped.contains("%x")) {
for (EscapedCharacter escapedCharacter : ESCAPED_KEY_CHARACTERS) {
escaped = escaped.replace(escapedCharacter.getEscaped(), escapedCharacter.getChar());
}
}
return escaped;
}
private static class EscapedCharacter {
private final String ch;
private final String hexPart;
private final String escaped;
EscapedCharacter(Character ch){
this.ch = String.valueOf(ch);
hexPart = Integer.toHexString(ch);
escaped = "%x" + hexPart;
}
String getChar() {
return ch;
}
String getEscaped() {
return escaped;
}
}
}