| /******************************************************************************* |
| * Copyright (c) 2006, 2017 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * David Knibb initial implementation |
| * Matthew Webster Eclipse 3.2 changes |
| * Heiko Seeberger Enhancements for service dynamics |
| * Martin Lippert extracted weaving and caching service factories |
| *******************************************************************************/ |
| |
| package org.eclipse.equinox.weaving.adaptors; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import org.eclipse.equinox.service.weaving.ICachingService; |
| import org.eclipse.equinox.service.weaving.ICachingServiceFactory; |
| import org.eclipse.equinox.service.weaving.ISupplementerRegistry; |
| import org.eclipse.equinox.service.weaving.IWeavingService; |
| import org.eclipse.equinox.service.weaving.IWeavingServiceFactory; |
| import org.eclipse.osgi.internal.loader.ModuleClassLoader; |
| import org.eclipse.osgi.storage.BundleInfo.Generation; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.Constants; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceEvent; |
| import org.osgi.framework.ServiceListener; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.service.packageadmin.PackageAdmin; |
| import org.osgi.service.startlevel.StartLevel; |
| import org.osgi.util.tracker.ServiceTracker; |
| |
| public class WeavingAdaptorFactory { |
| |
| private static final Collection<String> IGNORE_WEAVING_SERVICE_BUNDLES = Arrays |
| .asList(new String[] { "org.eclipse.equinox.weaving.aspectj", //$NON-NLS-1$ |
| "org.eclipse.equinox.weaving.caching", //$NON-NLS-1$ |
| "org.eclipse.equinox.weaving.caching.j9", //$NON-NLS-1$ |
| "org.eclipse.equinox.simpleconfigurator", //$NON-NLS-1$ |
| "org.eclipse.equinox.common" }); //$NON-NLS-1$ |
| |
| private ServiceTracker<ICachingServiceFactory, ICachingServiceFactory> cachingServiceFactoryTracker; |
| |
| private PackageAdmin packageAdminService; |
| |
| private StartLevel startLevelService; |
| |
| private ISupplementerRegistry supplementerRegistry; |
| |
| private ServiceTracker<IWeavingServiceFactory, IWeavingServiceFactory> weavingServiceFactoryTracker; |
| |
| private ServiceListener weavingServiceListener; |
| |
| private final Map<Bundle, IWeavingService> weavingServices = new ConcurrentHashMap<Bundle, IWeavingService>(); |
| |
| public WeavingAdaptorFactory() { |
| } |
| |
| public void dispose(final BundleContext context) { |
| |
| context.removeServiceListener(weavingServiceListener); |
| if (Debug.DEBUG_WEAVE) |
| Debug.println("> Removed service listener for weaving service."); //$NON-NLS-1$ |
| |
| weavingServiceFactoryTracker.close(); |
| if (Debug.DEBUG_WEAVE) |
| Debug.println("> Closed service tracker for weaving service."); //$NON-NLS-1$ |
| |
| cachingServiceFactoryTracker.close(); |
| if (Debug.DEBUG_CACHE) |
| Debug.println("> Closed service tracker for caching service."); //$NON-NLS-1$ |
| } |
| |
| protected ICachingService getCachingService(final ModuleClassLoader loader, |
| final Bundle bundle, final IWeavingService weavingService) { |
| if (Debug.DEBUG_CACHE) |
| Debug.println("> WeavingAdaptorFactory.getCachingService() bundle=" //$NON-NLS-1$ |
| + bundle + ", weavingService=" + weavingService); //$NON-NLS-1$ |
| ICachingService service = null; |
| String key = ""; //$NON-NLS-1$ |
| |
| if (weavingService != null) { |
| key = weavingService.getKey(); |
| } |
| final ICachingServiceFactory cachingServiceFactory = cachingServiceFactoryTracker |
| .getService(); |
| if (cachingServiceFactory != null) { |
| service = cachingServiceFactory.createCachingService(loader, bundle, |
| key); |
| } |
| if (Debug.DEBUG_CACHE) |
| Debug.println("< WeavingAdaptorFactory.getCachingService() service=" //$NON-NLS-1$ |
| + service + ", key='" + key + "'"); //$NON-NLS-1$ //$NON-NLS-2$ |
| return service; |
| } |
| |
| public Bundle getHost(final Bundle fragment) { |
| if (Debug.DEBUG_GENERAL) Debug.println( |
| "> WeavingAdaptorFactory.getHost() fragment=" + fragment); //$NON-NLS-1$ |
| |
| Bundle host = null; |
| if (packageAdminService != null) |
| host = packageAdminService.getHosts(fragment)[0]; |
| |
| if (Debug.DEBUG_GENERAL) |
| Debug.println("< WeavingAdaptorFactory.getHost() " + host); //$NON-NLS-1$ |
| return host; |
| } |
| |
| protected IWeavingService getWeavingService( |
| final ModuleClassLoader loader) { |
| if (Debug.DEBUG_WEAVE) Debug.println( |
| "> WeavingAdaptorFactory.getWeavingService() baseClassLoader=" //$NON-NLS-1$ |
| + loader); |
| |
| final Generation generation = loader.getClasspathManager() |
| .getGeneration(); |
| final Bundle bundle = loader.getBundle(); |
| |
| IWeavingService weavingService = null; |
| if (!IGNORE_WEAVING_SERVICE_BUNDLES |
| .contains(bundle.getSymbolicName())) { |
| final IWeavingServiceFactory weavingServiceFactory = weavingServiceFactoryTracker |
| .getService(); |
| if (weavingServiceFactory != null) { |
| weavingService = weavingServiceFactory.createWeavingService( |
| loader, bundle, generation.getRevision(), |
| supplementerRegistry); |
| |
| if (weavingService != null) { |
| weavingServices.put(bundle, weavingService); |
| } |
| } |
| } |
| if (Debug.DEBUG_WEAVE) |
| Debug.println("< WeavingAdaptorFactory.getWeavingService() service=" //$NON-NLS-1$ |
| + weavingService); |
| return weavingService; |
| } |
| |
| public void initialize(final BundleContext context, |
| final ISupplementerRegistry supplementerRegistry) { |
| if (Debug.DEBUG_GENERAL) |
| Debug.println("> WeavingAdaptorFactory.initialize() context=" //$NON-NLS-1$ |
| + context); |
| this.supplementerRegistry = supplementerRegistry; |
| |
| initializePackageAdminService(context); |
| initializeStartLevelService(context); |
| |
| // Service tracker for weaving service |
| weavingServiceFactoryTracker = new ServiceTracker<IWeavingServiceFactory, IWeavingServiceFactory>( |
| context, IWeavingServiceFactory.class, null); |
| weavingServiceFactoryTracker.open(); |
| if (Debug.DEBUG_WEAVE) |
| Debug.println("> Opened service tracker for weaving service."); //$NON-NLS-1$ |
| |
| // Service listener for weaving service |
| weavingServiceListener = new ServiceListener() { |
| |
| @Override |
| public void serviceChanged(final ServiceEvent event) { |
| if (event.getType() == ServiceEvent.REGISTERED) { |
| final List<Bundle> bundlesToRefresh = new ArrayList<Bundle>(); |
| |
| synchronized (weavingServices) { |
| final Iterator<Bundle> bundleEntries = weavingServices |
| .keySet().iterator(); |
| while (bundleEntries.hasNext()) { |
| final Bundle bundle = bundleEntries.next(); |
| bundleEntries.remove(); |
| bundlesToRefresh.add(bundle); |
| if (Debug.DEBUG_WEAVE) |
| Debug.println("> Updated bundle " //$NON-NLS-1$ |
| + bundle.getSymbolicName()); |
| } |
| } |
| |
| if (bundlesToRefresh.size() > 0) { |
| supplementerRegistry.refreshBundles(bundlesToRefresh |
| .toArray(new Bundle[bundlesToRefresh.size()])); |
| } |
| } |
| if (event.getType() == ServiceEvent.UNREGISTERING |
| && startLevelService != null |
| && startLevelService.getStartLevel() > 0) { |
| final List<Bundle> bundlesToRefresh = new ArrayList<Bundle>(); |
| |
| synchronized (weavingServices) { |
| final Iterator<Bundle> bundleEntries = weavingServices |
| .keySet().iterator(); |
| while (bundleEntries.hasNext()) { |
| final Bundle bundle = bundleEntries.next(); |
| bundleEntries.remove(); |
| bundlesToRefresh.add(bundle); |
| if (Debug.DEBUG_WEAVE) |
| Debug.println("> Updated bundle " //$NON-NLS-1$ |
| + bundle.getSymbolicName()); |
| } |
| } |
| if (bundlesToRefresh.size() > 0) { |
| supplementerRegistry.refreshBundles(bundlesToRefresh |
| .toArray(new Bundle[bundlesToRefresh.size()])); |
| } |
| } |
| } |
| }; |
| |
| // if (System.getProperty(WEAVING_SERVICE_DYNAMICS_PROPERTY, "false") |
| // .equals("true")) { |
| try { |
| context.addServiceListener(weavingServiceListener, "(" //$NON-NLS-1$ |
| + Constants.OBJECTCLASS + "=" //$NON-NLS-1$ |
| + IWeavingServiceFactory.class.getName() + ")"); //$NON-NLS-1$ |
| } catch (final InvalidSyntaxException e) { // This is correct! |
| } |
| |
| // Service tracker for caching service |
| cachingServiceFactoryTracker = new ServiceTracker<ICachingServiceFactory, ICachingServiceFactory>( |
| context, ICachingServiceFactory.class, null); |
| cachingServiceFactoryTracker.open(); |
| if (Debug.DEBUG_CACHE) |
| Debug.println("> Opened service tracker for caching service."); //$NON-NLS-1$ |
| } |
| |
| private void initializePackageAdminService(final BundleContext context) { |
| if (Debug.DEBUG_GENERAL) Debug.println( |
| "> AdaptorFactory.initializePackageAdminService() context=" //$NON-NLS-1$ |
| + context); |
| |
| final ServiceReference<PackageAdmin> ref = context |
| .getServiceReference(PackageAdmin.class); |
| if (ref != null) { |
| packageAdminService = context.getService(ref); |
| } |
| |
| if (Debug.DEBUG_GENERAL) |
| Debug.println("< AdaptorFactory.initializePackageAdminService() " //$NON-NLS-1$ |
| + packageAdminService); |
| } |
| |
| private void initializeStartLevelService(final BundleContext context) { |
| if (Debug.DEBUG_GENERAL) Debug.println( |
| "> AdaptorFactory.initializeStartLevelService() context=" //$NON-NLS-1$ |
| + context); |
| |
| final ServiceReference<StartLevel> ref = context |
| .getServiceReference(StartLevel.class); |
| if (ref != null) { |
| startLevelService = context.getService(ref); |
| } |
| |
| if (Debug.DEBUG_GENERAL) |
| Debug.println("< AdaptorFactory.initializeStartLevelService() " //$NON-NLS-1$ |
| + startLevelService); |
| } |
| } |