/*******************************************************************************
* Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc.
* All rights reserved. This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: Red Hat, Inc.
******************************************************************************/
package com.openshift.internal.util;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
/**
* Helper extensions to those provided
* by JBoss DMR library
*
* @author Jeff Cantrill
*/
public class JBossDmrExtentions {
private JBossDmrExtentions (){
}
/**
* Serialize a node and sanitize the output
* by removing nulls
* @param node
* @param compact
* @return
*/
public static String toJsonString(ModelNode node, boolean compact) {
sanitize(node);
StringWriter writer = new StringWriter();
node.writeJSONString(new PrintWriter(writer,true), compact);
return writer.toString();
}
private static void sanitize(ModelNode node) {
if(node.getType() == ModelType.OBJECT) {
Collection<String> emptyKeys = new ArrayList<>(node.keys().size());
for (String key : node.keys()) {
ModelNode child = node.get(key);
if(child.getType() == ModelType.UNDEFINED) {
emptyKeys.add(key);
}else {
sanitize(child);
}
if(child.getType() == ModelType.LIST) {
List<ModelNode> entries = child.asList();
if(entries.isEmpty()) {
emptyKeys.add(key);
} else {
final int listSize = entries.size();
List<Integer> nulls = new ArrayList<>(listSize);
for (int i=0; i < listSize; ++i) {
ModelNode e = entries.get(i);
if(!e.isDefined()) {
nulls.add(i);
}else {
sanitize(e);
}
}
Collections.reverse(nulls);
nulls.stream().forEach((i)->child.remove(i));
if(child.asList().size() == 0) {
emptyKeys.add(key);
}
}
}
}
emptyKeys.stream().forEach((key)->node.remove(key));
}
}
public static void set(ModelNode node, Map<String, String []> propertyKeys, String key, boolean value){
if(propertyKeys == null) return;
ModelNode modelNode = node.get(getPath(propertyKeys, key));
modelNode.set(value);
}
public static void set(ModelNode node, Map<String, String []> propertyKeys, String key, String value){
if(propertyKeys == null) return;
set(node, getPath(propertyKeys, key), value);
}
public static void set(ModelNode node, String [] path, String value){
if(value == null) return;
ModelNode modelNode = node.get(path);
modelNode.set(value);
}
public static void set(ModelNode node, Map<String, String []> propertyKeys, String key, int value) {
if(propertyKeys == null) return;
ModelNode modelNode = node.get(getPath(propertyKeys, key));
modelNode.set(value);
}
public static void set(ModelNode node, Map<String, String []> propertyKeys, String key, Map<String, String> values) {
if(propertyKeys == null) return;
ModelNode modelNode = node.get(getPath(propertyKeys, key));
for (Entry<String, String> entry : values.entrySet()) {
modelNode.get(entry.getKey()).set(entry.getValue());
}
}
/**
*
* @param root
* @param propertyKeys
* @param key
* @return
* @throws UnregisteredPropertyException if the property is not found in the property map
*/
public static Map<String, String> asMap(ModelNode root, Map<String, String []> propertyKeys, String key){
HashMap<String, String> map = new HashMap<String, String>();
if(propertyKeys != null){
String [] path = getPath(propertyKeys, key);
if(root.has(path)) {
ModelNode node = root.get(path);
if( !node.isDefined())
return map;
for (String k : node.keys()) {
map.put(k, node.get(k).asString());
}
}
}
return map;
}
/**
* <T> the type to return which are valid DMR types (e.g. asString()).
* String is currently only supported. Add more as needed
* @param root
* @param propertyKeys
* @param key
* @param type
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static Set asSet(ModelNode root, Map<String, String []> propertyKeys, String key, ModelType type){
Set set = new HashSet();
String [] path = getPath(propertyKeys, key);
if(root.has(path)){
ModelNode node = root.get(path);
if( !node.isDefined())
return set;
for (ModelNode entry : node.asList()) {
Object instance = null;
switch(type) {
case STRING:
instance = entry.asString();
break;
case BOOLEAN:
instance = entry.asBoolean();
break;
case INT:
instance = entry.asInt();
default:
}
set.add(instance);
}
}
return set;
}
/**
* <T> Returns an ordered List for items that need to be ordered
* such as command Args for containers.
*
* @param root
* @param propertyKeys
* @param key
* @param type
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static List asList(ModelNode root, Map<String, String []> propertyKeys, String key, ModelType type){
List list = new ArrayList();
String [] path = getPath(propertyKeys, key);
if(root.has(path)){
ModelNode node = root.get(path);
if( !node.isDefined())
return list;
for (ModelNode entry : node.asList()) {
Object instance = null;
switch(type) {
case STRING:
instance = entry.asString();
break;
case BOOLEAN:
instance = entry.asBoolean();
break;
case INT:
instance = entry.asInt();
default:
}
list.add(instance);
}
}
return list;
}
public static void set(ModelNode root, Map<String, String []> propertyKeys, String key, Set<String> values) {
String [] path = getPath(propertyKeys, key);
ModelNode node = root.get(path);
for (String entry : values) {
node.add(entry);
}
}
public static void set(ModelNode root, Map<String, String []> propertyKeys, String key, String... values) {
String [] path = getPath(propertyKeys, key);
ModelNode node = root.get(path);
for (String value : values) {
node.add(value);
}
}
/**
*
* @param node
* @param propertyKeys
* @param key
* @return
* @throws UnregisteredPropertyException if the property is not found in the property map
*/
public static int asInt(ModelNode node, Map<String, String []> propertyKeys, String key){
String [] path = getPath(propertyKeys, key);
if(node.has(path)) {
ModelNode modelNode = node.get(path);
if( !modelNode.isDefined()){
return 0;
}
return modelNode.asInt();
}
return 0;
}
/**
*
* @param node
* @param propertyKeys
* @param key
* @return
* @throws UnregisteredPropertyException if the property is not found in the property map
*/
public static String asString(ModelNode node, Map<String, String []> propertyKeys, String key){
String[] path = getPath(propertyKeys, key);
if(!node.has(path)) return "";
ModelNode modelNode = node.get(path);
if( !modelNode.isDefined()){
return "";
}
return modelNode.asString();
}
/**
*
* @param node
* @param propertyKeys
* @param key
* @return
* @throws UnregisteredPropertyException if the property is not found in the property map
*/
public static boolean asBoolean(ModelNode node, Map<String, String []> propertyKeys, String key) {
String [] path = getPath(propertyKeys, key);
if(!node.has(path)) return false;
ModelNode modelNode = node.get(path);
if( !modelNode.isDefined()){
return false;
}
return modelNode.asBoolean();
}
public static ModelNode get(ModelNode node, Map<String, String []> propertyKeys, String key){
return node.get(getPath(propertyKeys,key));
}
public static String[] getPath(Map<String, String []> propertyKeys, String key) {
if(propertyKeys != null && propertyKeys.containsKey(key)) {
return propertyKeys.get(key); //allow override
}
return key.split("\\.");
}
@SuppressWarnings("unchecked")
public static String[] getPath(String key) {
return getPath(Collections.EMPTY_MAP, key);
}
}