/******************************************************************************* * 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); } }