/******************************************************************************* * Copyright (c) 2006, 2013 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.update.configurator", //$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); } }