5555import org .eclipse .emf .ecore .EPackage ;
5656import org .eclipse .emf .ecore .impl .EPackageRegistryImpl ;
5757import org .eclipse .emf .ecore .resource .URIConverter ;
58+ import org .osgi .framework .Bundle ;
5859import org .osgi .framework .BundleActivator ;
5960import org .osgi .framework .BundleContext ;
61+ import org .osgi .framework .BundleException ;
6062
6163
6264/**
@@ -586,6 +588,7 @@ public static Map<String, URI> getEPackageNsURIToDynamicModelLocationMap(boolean
586588 */
587589 static public class Implementation extends EclipsePlugin
588590 {
591+ private ManifestEPackageTracker ePackageTracker ;
589592 /**
590593 * Creates the singleton instance.
591594 */
@@ -658,6 +661,26 @@ public void start(BundleContext context) throws Exception
658661 super .start (context );
659662 ExtensionProcessor .internalProcessExtensions ();
660663
664+ ePackageTracker = new ManifestEPackageTracker (context );
665+ ePackageTracker .open ();
666+
667+ for (Bundle bundle : context .getBundles ())
668+ { // Ensure Manifest-declared EPackages are registered for all tracked bundles immediately (Bundle-tracker adds some asynchronously)
669+ if ((bundle .getState () & ManifestEPackageTracker .TRACKED_BUNDLE_STATES ) != 0 )
670+ {
671+ ManifestEPackageTracker .registerManifestEPackagesIfAbsent (bundle );
672+ }
673+ }
674+ }
675+
676+ @ Override
677+ public void stop (BundleContext context ) throws Exception
678+ {
679+ super .stop (context );
680+ if (ePackageTracker != null )
681+ {
682+ ePackageTracker .close ();
683+ }
661684 }
662685
663686 /**
@@ -840,6 +863,8 @@ public IExtensionRegistry getRegistry()
840863 // Process the extension for the registry.
841864 //
842865 ExtensionProcessor .internalProcessExtensions ();
866+
867+ ExtensionProcessor .internalProcessManifests (classLoader );
843868 }
844869 }
845870
@@ -910,12 +935,47 @@ protected boolean readElement(IConfigurationElement element)
910935 new ConversionDelegateFactoryRegistryReader ().readRegistry ();
911936 new AnnotationValidatorRegistryReader ().readRegistry ();
912937 }
938+
939+ private static void internalProcessManifests (ClassLoader classLoader )
940+ {
941+ if (!IS_OSGI_RUNNING )
942+ { // not in a OSGi runtime, process raw MANIFEST.MF
943+ try
944+ {
945+ List <URI > manifests = getManifests (classLoader );
946+ for (URI manifest : manifests )
947+ {
948+ ManifestEPackageTracker .registerManifestEPackagesIfAbsent (manifest , classLoader );
949+ }
950+ }
951+ catch (IOException | BundleException e )
952+ {
953+ INSTANCE .log (e );
954+ }
955+ }
956+ }
913957 }
914958
915959 /**
916960 * Determine all the available plugin.xml resources.
917961 */
918962 private static List <URI > getPluginXMLs (ClassLoader classLoader )
963+ {
964+ return getClasspathResource (classLoader , "plugin.xml" );
965+ }
966+
967+ /**
968+ * Determine all the available {@code META-INF/MANIFEST.MF} resources.
969+ */
970+ private static List <URI > getManifests (ClassLoader classLoader )
971+ {
972+ return getClasspathResource (classLoader , "META-INF/MANIFEST.MF" );
973+ }
974+
975+ /**
976+ * Determine all the available plugin.xml resources.
977+ */
978+ private static List <URI > getClasspathResource (ClassLoader classLoader , String resourcePath )
919979 {
920980 List <URI > result = new ArrayList <URI >();
921981
@@ -958,13 +1018,13 @@ private static List<URI> getPluginXMLs(ClassLoader classLoader)
9581018 {
9591019 // Determine if there is a plugin.xml at the root of the folder.
9601020 //
961- File pluginXML = new File (file , "plugin.xml" );
1021+ File pluginXML = new File (file , resourcePath );
9621022 if (!pluginXML .exists ())
9631023 {
9641024 // If not, check if there is one in the parent folder.
9651025 //
9661026 File parentFile = file .getParentFile ();
967- pluginXML = new File (parentFile , "plugin.xml" );
1027+ pluginXML = new File (parentFile , resourcePath );
9681028 if (pluginXML .isFile ())
9691029 {
9701030 // If there is, then we have plugin.xml files that aren't on the classpath.
@@ -975,7 +1035,7 @@ else if (parentFile != null)
9751035 {
9761036 // The parent has a parent, check if there is one in the parent's parent folder.
9771037 //
978- pluginXML = new File (parentFile .getParentFile (), "plugin.xml" );
1038+ pluginXML = new File (parentFile .getParentFile (), resourcePath );
9791039 if (pluginXML .isFile ())
9801040 {
9811041 // If there is, then we have plugin.xml files that aren't on the classpath.
@@ -1014,7 +1074,7 @@ else if (file.isFile())
10141074 // Look for a plugin.xml entry...
10151075 //
10161076 jarFile = new JarFile (classpathEntry );
1017- ZipEntry entry = jarFile .getEntry ("plugin.xml" );
1077+ ZipEntry entry = jarFile .getEntry (resourcePath );
10181078 if (entry != null )
10191079 {
10201080 // If we find one, create a URI for it.
@@ -1052,7 +1112,7 @@ else if (file.isFile())
10521112 result .clear ();
10531113 try
10541114 {
1055- for (Enumeration <URL > resources = classLoader .getResources ("plugin.xml" ); resources .hasMoreElements (); )
1115+ for (Enumeration <URL > resources = classLoader .getResources (resourcePath ); resources .hasMoreElements (); )
10561116 {
10571117 // Create a URI for each plugin.xml found by the class loader.
10581118 //
0 commit comments