/* * RHQ Management Platform * Copyright (C) 2014 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.core.pc.bundle; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.jetbrains.annotations.NotNull; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.measurement.DataType; import org.rhq.core.domain.measurement.MeasurementScheduleRequest; import org.rhq.core.pc.inventory.InventoryManager; import org.rhq.core.pc.inventory.ResourceContainer; import org.rhq.core.pc.measurement.MeasurementManager; /** * A map of variables available in the "connection" string of a destination definition. * * Note that this caches the resource and plugin configuration as well as the list of enabled traits of the resource * so instances of this class should be short-lived. * * @author Lukas Krejci * @since 4.13 */ final class ConnectionStringAvailableProperties extends AbstractMap<String, String> { private final ResourceContainer resourceContainer; private final Map<String, Property> pluginConfiguration; private final Map<String, Property> resourceConfiguration; private final Map<String, String> traits; private final Map<String, Property> deploymentConfiguration; private final MeasurementManager measurementManager; ConnectionStringAvailableProperties(ResourceContainer container, MeasurementManager measurementManager, Configuration deploymentConfiguration) { this.resourceContainer = container; this.measurementManager = measurementManager; this.pluginConfiguration = new HashMap<String, Property>(); for (Property p : container.getResource().getPluginConfiguration().getProperties()) { pluginConfiguration.put("pluginConfiguration." + p.getName(), p); } this.resourceConfiguration = new HashMap<String, Property>(); for (Property p : InventoryManager.getResourceConfiguration(container.getResource()) .getProperties()) { resourceConfiguration.put("resourceConfiguration." + p.getName(), p); } this.traits = new HashMap<String, String>(); for (MeasurementScheduleRequest r : container.getMeasurementSchedule()) { if (r.getDataType() == DataType.TRAIT) { traits.put("measurementTrait." + r.getName(), r.getName()); } } this.deploymentConfiguration = new HashMap<String, Property>(); for (Property p : deploymentConfiguration.getProperties()) { this.deploymentConfiguration.put("deploymentConfiguration." + p.getName(), p); } } @NotNull @Override public Set<Entry<String, String>> entrySet() { return new AbstractSet<Entry<String, String>>() { @NotNull @Override public Iterator<Entry<String, String>> iterator() { return new Iterator<Entry<String, String>>() { Map<String, ?> currentMap = pluginConfiguration; Iterator<? extends Map.Entry<String, ?>> currentIt = currentMap.entrySet().iterator(); @Override public boolean hasNext() { skipToNextMapIfNeeded(); return currentIt.hasNext(); } @Override public Entry<String, String> next() { skipToNextMapIfNeeded(); final Entry<String, ?> entry = currentIt.next(); return new Entry<String, String>() { @Override public String getKey() { return entry.getKey(); } @Override public String getValue() { Object v = entry.getValue(); if (v == null) { return null; } else if (v instanceof String) { //traits here... return measurementManager.getTraitValue(resourceContainer, (String) v); } else if (v instanceof Property) { if (v instanceof PropertySimple) { return ((PropertySimple) v).getStringValue(); } else { // I think it is more appropriate to just return null here instead of bombing // out... return null; //throw new IllegalArgumentException("Key '" + key + // "' matches a non-simple property in the resource configuration. Cannot" + // " get its string value."); } } else { throw new AssertionError( "ResourceBackedValues instance contains a value of unexpected type: " + v.getClass()); } } @Override public String setValue(String value) { throw new UnsupportedOperationException(); } }; } @Override public void remove() { throw new UnsupportedOperationException(); } private void skipToNextMapIfNeeded() { if (!currentIt.hasNext() && currentMap == pluginConfiguration) { currentMap = resourceConfiguration; currentIt = resourceConfiguration.entrySet().iterator(); } if (!currentIt.hasNext() && currentMap == resourceConfiguration) { currentMap = traits; currentIt = traits.entrySet().iterator(); } if (!currentIt.hasNext() && currentMap == traits) { currentMap = deploymentConfiguration; currentIt = deploymentConfiguration.entrySet().iterator(); } } }; } @Override public int size() { return pluginConfiguration.size() + resourceConfiguration.size() + traits.size() + deploymentConfiguration.size(); } }; } }