package org.rhq.core.clientapi.shared;
import java.io.FileNotFoundException;
import java.io.StringReader;
import java.net.URL;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.util.ValidationEventCollector;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.apache.commons.jxpath.JXPathContext;
import org.rhq.core.clientapi.agent.metadata.ConfigurationMetadataParser;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataParser;
import org.rhq.core.clientapi.descriptor.DescriptorPackages;
import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
import org.rhq.core.clientapi.descriptor.plugin.ResourceDescriptor;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
public class PluginDescriptorUtil {
public static PluginDescriptor loadPluginDescriptor(String file) {
URL pluginDescriptorURL = PluginDescriptorUtil.class.getClassLoader().getResource(file);
if (pluginDescriptorURL == null) {
throw new RuntimeException("File " + file + " not found");
}
return loadPluginDescriptor(pluginDescriptorURL);
}
/**
* Loads the plugin descriptor from the specified file. The file path specified should
* be a class path relative path. For example, if the descriptor file is located at
* org.rhq.enterprise.server.configuration.my-descriptor.xml, then you should specify
* /org/rhq/enterprise/server/configuration/my-descriptor.xml.
*
* @param file The class path relative path of the descriptor file
* @return The {@link PluginDescriptor}
*/
public static PluginDescriptor loadPluginDescriptor(URL pluginDescriptorURL) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN);
URL pluginSchemaURL = PluginDescriptorUtil.class.getClassLoader().getResource("rhq-plugin.xsd");
Schema pluginSchema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(
pluginSchemaURL);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
ValidationEventCollector vec = new ValidationEventCollector();
unmarshaller.setEventHandler(vec);
unmarshaller.setSchema(pluginSchema);
return (PluginDescriptor) unmarshaller.unmarshal(pluginDescriptorURL.openStream());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Transforms the given string into a plugin descriptor object.
*
* @param string The plugin descriptor specified as a string
* @return The {@link PluginDescriptor}
*/
public static PluginDescriptor toPluginDescriptor(String string) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN);
URL pluginSchemaURL = PluginMetadataParser.class.getClassLoader().getResource("rhq-plugin.xsd");
Schema pluginSchema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(pluginSchemaURL);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
ValidationEventCollector vec = new ValidationEventCollector();
unmarshaller.setEventHandler(vec);
unmarshaller.setSchema(pluginSchema);
StringReader reader = new StringReader(string);
return (PluginDescriptor) unmarshaller.unmarshal(reader);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Searches for and returns the matching descriptor element (or elements) from the plugin
* descriptor. <code>path</code> should be an XPath-like expression. See
* http://commons.apache.org/jxpath/users-guide.html for more information on supported syntax.
*
* @param descriptor The plugin descriptor
* @param path The XPath-ish search expression
* @return The matching element or elements from the descriptor
*/
public static Object find(PluginDescriptor descriptor, String path) {
JXPathContext context = JXPathContext.newContext(descriptor);
return context.getValue(path);
}
/**
* This method does a few things. It first searches the descriptor with the specified
* <code>path</code>. When a matching element is found, which is presumably either a
* {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor} or a
* {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor}, its plugin
* configuration is retrieved. It then gets parsed and the resulting
* {@link ConfigurationDefinition} is returned.
*
* @param descriptor The plugin descriptor
* @param path The XPath-ish expression that specifies the path to the element from which
* the plugin configuration should be loaded
* @param configName A name to give the configuration definition
* @return The parsed {@link ConfigurationDefinition}
*/
public static ConfigurationDefinition loadPluginConfigDefFor(PluginDescriptor descriptor, String path,
String configName) {
try {
ResourceDescriptor resourceDescriptor = (ResourceDescriptor) find(descriptor, path);
return ConfigurationMetadataParser.parse(configName, resourceDescriptor.getPluginConfiguration());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* This method does a few things. It first searches the descriptor with the specified
* <code>path</code>. When a matching element is found, which is presumably either a
* {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor} or a
* {@link org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor}, its resource
* configuration is retrieved. It then gets parsed and the resulting
* {@link ConfigurationDefinition} is returned.
*
* @param descriptor The plugin descriptor
* @param path The XPath-ish expression that specifies the path to the element from which
* the resource configuration should be loaded
* @param configName A name to give the configuration definition
* @return The parsed {@link ConfigurationDefinition}
*/
public static ConfigurationDefinition loadResourceConfigDefFor(PluginDescriptor descriptor, String path,
String configName) {
try {
ResourceDescriptor resourceDescriptor = (ResourceDescriptor) find(descriptor, path);
return ConfigurationMetadataParser.parse(configName, resourceDescriptor.getResourceConfiguration());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}