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