/******************************************************************************* * Copyright (c) 2004, 2013 BREDEX GmbH. * 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: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.rc.rcp.installer; import java.io.BufferedInputStream; import java.io.IOException; import java.net.URL; import java.util.Collections; import java.util.Enumeration; import java.util.List; import org.eclipse.core.runtime.Platform; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; /** * Helper class for installing OSGi bundles located in a bundle. This class * requires bundle files (*.jar) in the directory named "bundles/" in the given * bundle context. The file names must contain a version between the last '_' * and the file name extension. */ public class BundleIterator { /** The directory to search for bundles. */ private static final String BUNDLES_DIR = "bundles"; //$NON-NLS-1$ /** The file pattern to search for bundles. */ private static final String FILE_PATTERN = "*.jar"; //$NON-NLS-1$ /** The context containing the bundles to install. */ private BundleContext m_context; /** The URL list of the bundles to install. */ private Enumeration<URL> m_urls; /** The current URL of the iterator. */ private URL m_url; /** The current bundle name of the iterator. */ private String m_bundleName; /** The current bundle of the iterator. */ private Bundle m_bundle; /** * @param context * The context containing the bundles to install in the directory * named "bundles/". Each bundle file must end with ".jar". * @param bundleFolderSuffix The suffix for the bundle folder added to "bundles/". */ public BundleIterator(BundleContext context, String bundleFolderSuffix) { this.m_context = context; // store context for later usage m_urls = context.getBundle().findEntries( // the directory searching for bundles BUNDLES_DIR + bundleFolderSuffix, // the file pattern (*.jar) FILE_PATTERN, // false = search not recursively false); if (m_urls == null) { // create an empty enumeration if no bundles have been found final List<URL> emptyList = Collections.emptyList(); m_urls = Collections.enumeration(emptyList); } } /** * Iterator method. * * @return True, if there are one or more bundles left to install, otherwise * false. */ public boolean hasNext() { return m_urls.hasMoreElements(); } /** * Iterate to next bundle. * @return The current bundle, if it is already installed, otherwise null. */ public Bundle next() { m_url = m_urls.nextElement(); m_bundleName = getBundleName(m_url); m_bundle = Platform.getBundle(m_bundleName); return m_bundle; } /** * Installs the current bundle, if it has not been already installed. * @return The already installed or newly installed bundle. * @throws IOException Errors with input stream of bundle. * @see BundleContext#installBundle(String, java.io.InputStream) * for detailed exception description. */ public Bundle installBundle() throws IOException, BundleException, SecurityException, IllegalStateException { if (m_bundle != null) { // bundle exists return m_bundle; } // bundle does not exist, so install it BufferedInputStream inputStream = new BufferedInputStream( m_url.openStream()); try { m_bundle = m_context.installBundle(m_bundleName, inputStream); } finally { inputStream.close(); // installBundle() needs closing of input // stream } return m_bundle; } /** * Stop the current bundle, if it is installed and activated. * @return True, if the bundle was active and has been stopped, otherwise false. */ public boolean uninstallBundle() { if (m_bundle != null) { try { m_bundle.uninstall(); // un-install bundle return true; } catch (Throwable e) { System.err.println(e); } } return false; } /** * Convert e. g. * "bundleentry://6.fwk29851476/bundles/de.test_1.0.0.201301182302.jar" * to "de.test" by using the string between the last char '/' and * '_'. * * @param url * The URL of the bundle. * @return The bundle name. */ private static String getBundleName(URL url) { String urlString = url.getFile(); int indexBegin = urlString.lastIndexOf('/') + 1; int indexEnd = urlString.lastIndexOf('_'); return urlString.substring(indexBegin, indexEnd); } }