/*
* #%~
* org.overture.ide.core
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.ide.core.utility;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.overture.ide.core.ICoreConstants;
public class ClasspathUtils {
public static List<String> collectJars(String bundleId) {
List<String> bundleIds = new ArrayList<String>();
bundleIds.add(bundleId);
final Bundle bundle = Platform.getBundle(bundleId);
if (bundle==null) {
System.out.println("Bundle " + bundleId + " not found.");
return new ArrayList<String>();
}
try {
String requires = (String) bundle.getHeaders().get(Constants.REQUIRE_BUNDLE);
ManifestElement[] elements = ManifestElement.parseHeader(Constants.REQUIRE_BUNDLE, requires);
for (ManifestElement manifestElement : elements) {
String value = manifestElement.getValue();
if (value.startsWith("org.overture"))
bundleIds.add(value);
}
} catch (BundleException e) {
return new ArrayList<String>();
}
List<String> preliminary = new ArrayList<String>();
collectClasspath(bundleIds.toArray(new String[]{}), preliminary);
List<String> filtered = new ArrayList<String>();
for (String s : preliminary) {
if (s.endsWith(".jar"))
filtered.add(s);
}
return filtered;
}
public static void collectClasspath(String[] bundleIds, List<String> entries) {
try {
final boolean developmentMode = Platform.inDevelopmentMode();
ArrayList<File> fileList = new ArrayList<File>();
for (int i = 0; i < bundleIds.length; ++i) {
final String bundleId = bundleIds[i];
getPluginClassPath(bundleId, entries);
final File file = getPluginLocation(bundleId);
fileList.add(file);
for (File f : fileList) {
if (developmentMode && file.isDirectory()) {
final File bin = new File(f, "bin"); //$NON-NLS-1$
if (bin.isDirectory()) {
entries.add(bin.getAbsolutePath());
continue;
}
}
entries.add(f.getAbsolutePath());
}
}
} catch (CoreException e) {
// LaunchingPlugin.error(e);
}
}
private static void getPluginClassPath(String bundleId, List<String> entries) throws CoreException
{
try {
final Bundle bundle = Platform.getBundle(bundleId);
if (bundle == null){
throw new BundleException(bundleId + " cannot be retrieved from the Platform");
}
String requires = (String) bundle.getHeaders().get((Constants.BUNDLE_CLASSPATH));
if (requires == null)
requires = ".";
ManifestElement[] elements = ManifestElement.parseHeader(Constants.REQUIRE_BUNDLE, requires);
for (ManifestElement manifestElement : elements) {
String value = manifestElement.getValue();
if (".".equals(value))
value = "/";
URL url = bundle.getEntry(value);
if (url != null)
{
URL resolvedFile = FileLocator.resolve(url);
if ("file".equals(resolvedFile.getProtocol())) //$NON-NLS-1$
{
File file = new File(resolvedFile.getPath());
// adding jar-files
if (file.isDirectory() == false)
{
entries.add(file.getAbsolutePath());
}
//System.out.println("addedFile" + resolvedFile.getPath() + " isDir: " + file.isDirectory());
}
}
}
} catch (Exception e) {
final String msg = NLS.bind(PLUGIN_LOCATION_ERROR, bundleId);
System.out.println(msg);
throw new CoreException(new Status(IStatus.ERROR, ICoreConstants.PLUGIN_ID, IStatus.ERROR, msg, e));
}
}
private static File getPluginLocation(String bundleId) throws CoreException {
try {
final Bundle bundle = Platform.getBundle(bundleId);
if(bundle==null)
{
final String msg = NLS.bind(PLUGIN_LOCATION_ERROR, bundleId);
throw new CoreException(new Status(IStatus.ERROR, ICoreConstants.PLUGIN_ID, IStatus.ERROR, msg,null));
}
return getBundleFile(bundle);
} catch (IOException e) {
final String msg = NLS.bind(PLUGIN_LOCATION_ERROR, bundleId);
throw new CoreException(new Status(IStatus.ERROR, ICoreConstants.PLUGIN_ID, IStatus.ERROR, msg, e));
}
}
/**
* Returns a file for the contents of the specified bundle. Depending on how
* the bundle is installed the returned file may be a directory or a jar
* file containing the bundle content.
*
* XXX 3.3 compatibility = {@link FileLocator#getBundleFile(Bundle)}
*
* @param bundle
* the bundle
* @return a file with the contents of the bundle
* @throws IOException
* if an error occurs during the resolution
*/
public static File getBundleFile(Bundle bundle) throws IOException {
URL rootEntry = bundle.getEntry("/"); //$NON-NLS-1$
rootEntry = FileLocator.resolve(rootEntry);
if ("file".equals(rootEntry.getProtocol())) //$NON-NLS-1$
return new File(rootEntry.getPath());
if ("jar".equals(rootEntry.getProtocol())) { //$NON-NLS-1$
String path = rootEntry.getPath();
if (path.startsWith("file:")) {
// strip off the file: and the !/
path = path.substring(5, path.length() - 2);
return new File(path);
}
}
throw new IOException("Unknown protocol"); //$NON-NLS-1$
}
// public static String[] getClassPath(IJavaProject myJavaProject) throws IOException, URISyntaxException {
// final List<String> result = new ArrayList<String>();
// // TODO ClasspathUtils.collectClasspath(new String[] { GenericOvertureInstallType.EMBEDDED_VDMJ_BUNDLE_ID, GenericOvertureInstallType.DBGP_FOR_VDMJ_BUNDLE_ID }, result);
// ClasspathUtils.collectClasspath
// (
// new String[]
// {
// "org.overture.ide.generated.vdmj" //TODO put in constant file
// //VDMToolsInstallType.DBGP_FOR_VDMTOOLS_BUNDLE_ID,
// //GenericOvertureInstalltype.DBGP_FOR_VDMTOOLS_BUNDLE_ID,
// //GenericOvertureInstalltype.DBGP_FOR_ABSTRACT_BUNDLE_ID
// },
// result
// );
// try {
// final String[] classPath = computeBaseClassPath(myJavaProject);
// for (int i = 0; i < classPath.length; ++i) {
// result.add(classPath[i]);
// }
// } catch (CoreException e) {
// }
// return (String[]) result.toArray(new String[result.size()]);
// }
//
// protected static String[] computeBaseClassPath(IJavaProject myJavaProject) throws CoreException {
// if (!myJavaProject.exists())
// return CharOperation.NO_STRINGS;
// return JavaRuntime.computeDefaultRuntimeClassPath(myJavaProject);
// }
private static final String PLUGIN_LOCATION_ERROR = "Error determining classpath from bundle {0}"; //$NON-NLS-1$
}