/******************************************************************************* * Copyright (c) 2000, 2006 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.rubypeople.rdt.internal.launching; import java.io.File; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.debug.core.ILaunchConfiguration; import org.rubypeople.rdt.core.ILoadpathEntry; import org.rubypeople.rdt.core.IRubyProject; import org.rubypeople.rdt.core.RubyCore; import org.rubypeople.rdt.launching.IRuntimeLoadpathEntry; import org.rubypeople.rdt.launching.IRuntimeLoadpathEntryResolver; import org.rubypeople.rdt.launching.IRuntimeLoadpathEntryResolver2; import org.rubypeople.rdt.launching.IVMInstall; import org.rubypeople.rdt.launching.RubyRuntime; /** * Resolves for RUBYLIB_VARIABLE and RUBY_CONTAINER */ public class RubyVMRuntimeLoadpathEntryResolver implements IRuntimeLoadpathEntryResolver2 { /** * @see IRuntimeLoadpathEntryResolver#resolveRuntimeLoadpathEntry(IRuntimeLoadpathEntry, ILaunchConfiguration) */ public IRuntimeLoadpathEntry[] resolveRuntimeLoadpathEntry(IRuntimeLoadpathEntry entry, ILaunchConfiguration configuration) throws CoreException { IVMInstall rubyVM = null; if (entry.getType() == IRuntimeLoadpathEntry.CONTAINER && entry.getPath().segmentCount() > 1) { // a specific VM rubyVM = RubyContainerInitializer.resolveInterpreter(entry.getPath()); } else { // default VM for config rubyVM = RubyRuntime.computeVMInstall(configuration); } if (rubyVM == null) { // cannot resolve Ruby VM return new IRuntimeLoadpathEntry[0]; } return resolveLibraryLocations(rubyVM, entry.getLoadpathProperty()); } /** * @see IRuntimeLoadpathEntryResolver#resolveRuntimeLoadpathEntry(IRuntimeLoadpathEntry, IRubyProject) */ public IRuntimeLoadpathEntry[] resolveRuntimeLoadpathEntry(IRuntimeLoadpathEntry entry, IRubyProject project) throws CoreException { IVMInstall rubyVM = null; if (entry.getType() == IRuntimeLoadpathEntry.CONTAINER && entry.getPath().segmentCount() > 1) { // a specific VM rubyVM = RubyContainerInitializer.resolveInterpreter(entry.getPath()); } else { // default VM for project rubyVM = RubyRuntime.getVMInstall(project); } if (rubyVM == null) { // cannot resolve RubyVM return new IRuntimeLoadpathEntry[0]; } return resolveLibraryLocations(rubyVM, entry.getLoadpathProperty()); } /** * Resolves libray locations for the given VM install */ protected IRuntimeLoadpathEntry[] resolveLibraryLocations(IVMInstall vm, int kind) { IPath[] libs = vm.getLibraryLocations(); IPath[] defaultLibs = vm.getVMInstallType().getDefaultLibraryLocations(vm.getInstallLocation()); boolean overrideRubydoc = false; if (libs == null) { // default system libs libs = defaultLibs; overrideRubydoc = true; } else if (!isSameArchives(libs, defaultLibs)) { // determine if bootpath should be explicit kind = IRuntimeLoadpathEntry.BOOTSTRAP_CLASSES; } if (kind == IRuntimeLoadpathEntry.BOOTSTRAP_CLASSES) { File vmInstallLocation= vm.getInstallLocation(); if (vmInstallLocation != null) { LibraryInfo libraryInfo= LaunchingPlugin.getLibraryInfo(vm.getVMInstallType(), vmInstallLocation.getAbsolutePath()); if (libraryInfo != null) { // only return endorsed and bootstrap loadpath entries if we have the info // libs in the ext dirs are not loaded by the boot class loader List<IRuntimeLoadpathEntry> resolvedEntries = new ArrayList<IRuntimeLoadpathEntry>(libs.length); for (int i = 0; i < libs.length; i++) { IPath location = libs[i]; IPath libraryPath = location; String dir = libraryPath.toFile().getParent(); resolvedEntries.add(resolveLibraryLocation(vm, location, kind, overrideRubydoc)); } return resolvedEntries.toArray(new IRuntimeLoadpathEntry[resolvedEntries.size()]); } } } List<IRuntimeLoadpathEntry> resolvedEntries = new ArrayList<IRuntimeLoadpathEntry>(libs.length); for (int i = 0; i < libs.length; i++) { IPath systemLibraryPath = libs[i]; if (systemLibraryPath.toFile().exists()) { resolvedEntries.add(resolveLibraryLocation(vm, libs[i], kind, overrideRubydoc)); } } return resolvedEntries.toArray(new IRuntimeLoadpathEntry[resolvedEntries.size()]); } /** * Return whether the given list of libraries refer to the same archives in the same * order. Only considers the binary archive (not source or javadoc locations). * * @param libs * @param defaultLibs * @return whether the given list of libraries refer to the same archives in the same * order */ public static boolean isSameArchives(IPath[] libs, IPath[] defaultLibs) { if (libs.length != defaultLibs.length) { return false; } for (int i = 0; i < defaultLibs.length; i++) { IPath def = defaultLibs[i]; IPath lib = libs[i]; if (!def.equals(lib)) { return false; } } return true; } /** * @see IRuntimeLoadpathEntryResolver#resolveVMInstall(ILoadpathEntry) */ public IVMInstall resolveVMInstall(ILoadpathEntry entry) { switch (entry.getEntryKind()) { case ILoadpathEntry.CPE_VARIABLE: if (entry.getPath().segment(0).equals(RubyRuntime.RUBYLIB_VARIABLE)) { return RubyRuntime.getDefaultVMInstall(); } break; case ILoadpathEntry.CPE_CONTAINER: if (entry.getPath().segment(0).equals(RubyRuntime.RUBY_CONTAINER)) { return RubyContainerInitializer.resolveInterpreter(entry.getPath()); } break; default: break; } return null; } /* (non-Javadoc) * @see org.eclipse.jdt.launching.IRuntimeLoadpathEntryResolver2#isVMInstallReference(org.eclipse.jdt.core.ILoadpathEntry) */ public boolean isVMInstallReference(ILoadpathEntry entry) { switch (entry.getEntryKind()) { case ILoadpathEntry.CPE_VARIABLE: if (entry.getPath().segment(0).equals(RubyRuntime.RUBYLIB_VARIABLE)) { return true; } break; case ILoadpathEntry.CPE_CONTAINER: if (entry.getPath().segment(0).equals(RubyRuntime.RUBY_CONTAINER)) { return true; } break; default: break; } return false; } /** * Returns a runtime classpath entry for the given library in the specified VM. * * @param vm * @param location * @param kind * @return runtime classpath entry * @since 0.9.0 */ private IRuntimeLoadpathEntry resolveLibraryLocation(IVMInstall vm, IPath location, int kind, boolean overrideRubyDoc) { IPath libraryPath = location; ILoadpathEntry cpe = RubyCore.newLibraryEntry(libraryPath, false); IRuntimeLoadpathEntry resolved = new RuntimeLoadpathEntry(cpe); resolved.setLoadpathProperty(kind); return resolved; } }