/** * Copyright (c) 2011 committers of YAKINDU 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: * committers of YAKINDU - initial API and implementation * */ package org.yakindu.sct.commons; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.launching.JavaRuntime; import com.google.common.collect.Lists; /** * Factory for {@link ClassLoader}s based on {@link IProject}s inside the * workspace * * @author koenemann - Initial contribution and API * @author holger willebrandt */ public class WorkspaceClassLoaderFactory { private final boolean resolveSimpleProjectReferences; public WorkspaceClassLoaderFactory() { this(false); } /** * @param resolveSimpleProjectReferences * whether project references should be resolved for non-java * projects */ public WorkspaceClassLoaderFactory(boolean resolveSimpleProjectReferences) { this.resolveSimpleProjectReferences = resolveSimpleProjectReferences; } /** * Creates a {@link ClassLoader} that can be used to load resources from the * workspace. * * @deprecated use factory method that takes a parent {@link ClassLoader} */ public ClassLoader createClassLoader(IProject project) { return createClassLoader(project, WorkspaceClassLoaderFactory.class.getClassLoader()); } /** * Creates a {@link ClassLoader} that can be used to load resources from the * workspace. */ public ClassLoader createClassLoader(IProject project, ClassLoader parent) { final List<URL> urls = Lists.newArrayList(); addClasspathEntries(project, urls); return URLClassLoader.newInstance(urls.toArray(new URL[urls.size()]), parent); } protected void addClasspathEntries(IProject project, List<URL> urls) { IJavaProject javaProject = toJavaProject(project); if (javaProject != null) { addJavaClasspathEntries(javaProject, urls); } else { try { urls.add(getFileSystemFile(project).toURI().toURL()); } catch (MalformedURLException e1) { e1.printStackTrace(); } if (resolveSimpleProjectReferences) { addReferencedProjectsClasspaths(project, urls); } } } protected void addReferencedProjectsClasspaths(IProject project, List<URL> urls) { try { IProject[] referencedProjects = project.getReferencedProjects(); for (IProject iProject : referencedProjects) { addClasspathEntries(iProject, urls); } } catch (CoreException e) { e.printStackTrace(); } } protected File getFileSystemFile(IResource resource) { return new File(resource.getWorkspace().getRoot().getRawLocation() .toFile().getAbsolutePath() + File.separator + resource.getFullPath().toFile().getAbsolutePath()); } protected IJavaProject toJavaProject(IProject project) { IJavaProject javaProject = JavaCore.create(project); if (javaProject.exists()) { return javaProject; } return null; } protected void addJavaClasspathEntries(IJavaProject project, List<URL> urls) { try { urls.addAll(Lists.newArrayList(convertClassPath(JavaRuntime .computeDefaultRuntimeClassPath(project)))); } catch (CoreException e) { e.printStackTrace(); } } /** * Converting string classpath to {@link URL}s. */ private static URL[] convertClassPath(String[] classPath) { final URL[] urls = new URL[classPath.length]; for (int i = 0; i < classPath.length; i++) { final String entry = classPath[i]; final IPath path = new Path(entry); try { final URL url = path.toFile().toURI().toURL(); urls[i] = url; } catch (MalformedURLException e) { throw new RuntimeException( "Could not convert classpath entry to URL: " + path.toString(), e); } } return urls; } }