org.datanucleus.plugin.OSGiBundleParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datanucleus-core Show documentation
Show all versions of datanucleus-core Show documentation
DataNucleus Core provides the primary components of a heterogenous Java persistence solution.
It supports persistence API's being layered on top of the core functionality.
/**********************************************************************
Copyright (c) 2006 Erik Bengtson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Contributors:
2011 Alexey Sushko - adapted PluginParser code to allow for non-Eclipse OSGi environments
...
**********************************************************************/
package org.datanucleus.plugin;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.List;
import java.util.StringTokenizer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.datanucleus.exceptions.NucleusException;
import org.datanucleus.plugin.PluginParser.Parser;
import org.datanucleus.util.Localiser;
import org.datanucleus.util.NucleusLogger;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class OSGiBundleParser
{
public static Bundle parseManifest(org.osgi.framework.Bundle osgiBundle)
{
Dictionary headers = osgiBundle.getHeaders();
Bundle bundle = null;
try
{
String symbolicName = getBundleSymbolicName(headers, null);
String bundleVersion = getBundleVersion(headers, null);
String bundleName = getBundleName(headers, null);
String bundleVendor = getBundleVendor(headers, null);
bundle = new Bundle(symbolicName, bundleName, bundleVendor, bundleVersion, null);
bundle.setRequireBundle(getRequireBundle(headers));
}
catch (NucleusException ne)
{
NucleusLogger.GENERAL.warn("Plugin at bundle " + osgiBundle.getSymbolicName() + " (" + osgiBundle.getBundleId() + ") failed to parse so is being ignored", ne);
return null;
}
return bundle;
}
/**
* Accessor for the Bundle-Name from the manifest.mf file
* @param headers manifest headers
* @return the Set with BundleDescription
*/
private static List getRequireBundle(Dictionary headers)
{
String str = headers.get("Require-Bundle");
if (str == null || str.length() < 1)
{
return Collections.emptyList();
}
Parser p = new Parser(str);
List requiredBundle = new ArrayList<>();
String bundleSymbolicName = p.parseSymbolicName();
while (bundleSymbolicName != null)
{
Bundle.BundleDescription bd = new Bundle.BundleDescription();
bd.setBundleSymbolicName(bundleSymbolicName);
bd.setParameters(p.parseParameters());
bundleSymbolicName = p.parseSymbolicName();
requiredBundle.add(bd);
}
return requiredBundle;
}
/**
* Method to parse ExtensionPoints from plug-in file
* @param rootElement the root element of the plugin xml
* @param plugin the plugin bundle
* @param osgiBundle The bundle
* @return a List of extensionPoints, if any
* @throws NucleusException if an error occurs during parsing
*/
private static List parseExtensionPoints(Element rootElement, Bundle plugin, org.osgi.framework.Bundle osgiBundle)
{
List extensionPoints = new ArrayList<>();
try
{
NodeList elements = rootElement.getElementsByTagName("extension-point");
for (int i = 0; i < elements.getLength(); i++)
{
Element element = (Element) elements.item(i);
String id = element.getAttribute("id").trim();
String name = element.getAttribute("name");
String schema = element.getAttribute("schema");
extensionPoints.add(new ExtensionPoint(id, name, osgiBundle.getEntry(schema), plugin));
}
}
catch (NucleusException ex)
{
throw ex;
}
return extensionPoints;
}
/**
* Method to parse Extensions from plug-in file
* @param rootElement the root element of the plugin xml
* @param plugin the plugin bundle
* @param osgiBundle the bundle
* @return a List of extensions, if any
* @throws NucleusException if an error occurs during parsing
*/
private static List parseExtensions(Element rootElement, Bundle plugin, org.osgi.framework.Bundle osgiBundle)
{
List extensions = new ArrayList<>();
try
{
NodeList elements = rootElement.getElementsByTagName("extension");
for (int i = 0; i < elements.getLength(); i++)
{
Element element = (Element) elements.item(i);
Extension ex = new Extension(element.getAttribute("point"), plugin);
NodeList elms = element.getChildNodes();
extensions.add(ex);
for (int e = 0; e < elms.getLength(); e++)
{
if (elms.item(e) instanceof Element)
{
ex.addConfigurationElement(PluginParser.parseConfigurationElement(ex, (Element) elms.item(e), null));
}
}
}
}
catch (NucleusException ex)
{
throw ex;
}
return extensions;
}
private static String getHeaderValue(Dictionary headers, String key, String defaultValue)
{
if (headers == null)
{
return defaultValue;
}
String name = headers.get(key);
if (name == null)
{
return defaultValue;
}
return name;
}
/**
* Accessor for the Bundle-SymbolicName from the manifest.mf file
* @param headers Manifest headers
* @param defaultValue a default value, in case no symbolic name found in manifest
* @return the bundle symbolic name
*/
private static String getBundleSymbolicName(Dictionary headers, String defaultValue)
{
String name = getHeaderValue(headers, "Bundle-SymbolicName", defaultValue);
StringTokenizer token = new StringTokenizer(name, ";");
return token.nextToken().trim();
}
/**
* Accessor for the Bundle-Name from the manifest.mf file
* @param headers manifest headers
* @param defaultValue a default value, in case no name found in manifest
* @return the bundle name
*/
private static String getBundleName(Dictionary headers, String defaultValue)
{
return getHeaderValue(headers, "Bundle-Name", defaultValue);
}
/**
* Accessor for the Bundle-Vendor from the manifest.mf file
* @param headers manifest headers
* @param defaultValue a default value, in case no vendor found in manifest
* @return the bundle vendor
*/
private static String getBundleVendor(Dictionary headers, String defaultValue)
{
return getHeaderValue(headers, "Bundle-Vendor", defaultValue);
}
/**
* Accessor for the Bundle-Version from the manifest.mf file
* @param headers the manifest headers
* @param defaultValue a default value, in case no version found in manifest
* @return the bundle version
*/
private static String getBundleVersion(Dictionary headers, String defaultValue)
{
return getHeaderValue(headers, "Bundle-Version", defaultValue);
}
/**
* Method to parse Extensions in plug-in file.
* @param db DocumentBuilder to use for parsing
* @param mgr the PluginManager
* @param fileUrl URL of the plugin.xml file
* @param plugin The Bundle
* @param osgiBundle The OSGi Bundle
* @return array of 2 elements. first element is a List of extensionPoints, and 2nd element is a List of
* Extension
* @throws NucleusException if an error occurs during parsing
*/
public static List[] parsePluginElements(DocumentBuilder db, PluginRegistry mgr, URL fileUrl, Bundle plugin, org.osgi.framework.Bundle osgiBundle)
{
List extensionPoints = Collections.emptyList();
List extensions = Collections.emptyList();
InputStream is = null;
InputStreamReader isr = null;
try
{
is = fileUrl.openStream();
isr = new InputStreamReader(is);
Element rootElement = db.parse(new InputSource(isr)).getDocumentElement();
if (NucleusLogger.GENERAL.isDebugEnabled())
{
NucleusLogger.GENERAL.debug(Localiser.msg("024003", fileUrl.toString()));
}
extensionPoints = parseExtensionPoints(rootElement, plugin, osgiBundle);
extensions = parseExtensions(rootElement, plugin, osgiBundle);
}
catch (NucleusException ex)
{
throw ex;
}
catch (Exception e)
{
NucleusLogger.GENERAL.error(Localiser.msg("024000", fileUrl.getFile()));
}
finally
{
if (isr != null)
{
try
{
isr.close();
}
catch (IOException e)
{
}
}
if (is != null)
{
try
{
is.close();
}
catch (IOException e)
{
}
}
}
return new List[]{extensionPoints, extensions};
}
static DocumentBuilderFactory dbFactory = null;
/**
* Convenience method to create a document builder for parsing.
* @return The document builder
* @throws NucleusException if an error occurs creating the instance
*/
public static DocumentBuilder getDocumentBuilder()
{
try
{
if (dbFactory == null)
{
dbFactory = DocumentBuilderFactory.newInstance();
}
return dbFactory.newDocumentBuilder();
}
catch (ParserConfigurationException e1)
{
throw new NucleusException(Localiser.msg("024016", e1.getMessage()));
}
}
}