/******************************************************************************* * Copyright (c) 2005, 2012 eBay Inc. * 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 * *******************************************************************************/ package org.eclipse.vjet.eclipse.core; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.AssertionFailedException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.dltk.mod.core.DLTKCore; import org.eclipse.dltk.mod.core.IBuildpathEntry; import org.eclipse.dltk.mod.core.IScriptProject; import org.eclipse.dltk.mod.core.ModelException; import org.eclipse.dltk.mod.core.environment.EnvironmentPathUtils; import org.eclipse.dltk.mod.core.environment.IEnvironment; import org.eclipse.dltk.mod.core.internal.environment.LocalEnvironment; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.vjet.dsf.jst.ts.util.ISdkEnvironment; import org.eclipse.vjet.eclipse.codeassist.CodeassistUtils; import org.eclipse.vjet.eclipse.core.sdk.VJetSdkEnvironment; import org.eclipse.vjet.vjo.tool.typespace.SourcePathInfo; import org.osgi.service.prefs.BackingStoreException; public class PiggyBackClassPathUtil { public static final String PREFERENCE_SCRIPTPROJECT_INITIALIZED = "initialized_project_from_v4classpath"; private static List<String> noneVjoFileList = new ArrayList<String>(); private static List<String> vjoFileList = new ArrayList<String>(); public static List<URL> getProjectDependencyUrls_bak( IJavaProject javaProject) throws JavaModelException, MalformedURLException { URL[] urls = getProjectDependencyUrlsInternal(javaProject); List<URL> urlsString = new ArrayList<URL>(urls.length); for (URL u : urls) { urlsString.add(u); } return urlsString; } private static URL[] getProjectDependencyUrlsInternal( IJavaProject javaProject) throws JavaModelException, MalformedURLException { List<IJavaProject> jps = new ArrayList<IJavaProject>(1); jps.add(javaProject); return getProjectDependencyUrls_bak(jps, null, new HashMap<String, String>()); } public static URL[] getProjectDependencyUrls_bak( List<IJavaProject> javaProjectList, List<URL> currentUrlList, HashMap<String, String> projectMap) throws JavaModelException, MalformedURLException { List<URL> projectDependencyUrlList = currentUrlList; if (projectDependencyUrlList == null) { projectDependencyUrlList = new ArrayList<URL>(); } for (IJavaProject project : javaProjectList) { if (projectMap.containsKey(project.getElementName()) == true) { continue; } else { projectMap.put(project.getElementName(), project .getElementName()); } // Add the dependencies to the URL list // IClasspathEntry[] entries; // entries = project.getResolvedClasspath(true); IClasspathEntry[] entries2; entries2 = project.getRawClasspath(); for (IClasspathEntry entry : entries2) { IPath path = entry.getPath(); File f = path.toFile(); URL entryUrl; entryUrl = f.toURL(); switch (entry.getEntryKind()) { case IClasspathEntry.CPE_VARIABLE: case IClasspathEntry.CPE_LIBRARY: addEntryToList(entry, projectDependencyUrlList); case IClasspathEntry.CPE_PROJECT: List<IJavaProject> subjavaProjectList = new ArrayList<IJavaProject>(); IResource subResource = ResourcesPlugin.getWorkspace() .getRoot().findMember(entry.getPath()); if (subResource == null) { String projectName = entry.getPath().toString(); String parentProjectName = project.getElementName(); } if (subResource != null && subResource.getType() == IResource.PROJECT) { IProject subProject = (IProject) subResource; IJavaProject subJavaProject = JavaCore .create(subProject); if (subJavaProject != null && subJavaProject.exists()) { subjavaProjectList.add(subJavaProject); // Recursively call our selves to populate the // project // dependency's for the sub projects. getProjectDependencyUrls_bak(subjavaProjectList, projectDependencyUrlList, projectMap); } } break; case IClasspathEntry.CPE_CONTAINER: if (!JavaRuntime.JRE_CONTAINER.equals(path.toOSString())) { IClasspathContainer container = JavaCore .getClasspathContainer(entry.getPath(), project); if (container != null) { IClasspathEntry[] entries = container .getClasspathEntries(); for (int i = 0; i < entries.length; i++) { addEntryToList(entries[i], projectDependencyUrlList); } } } break; default: break; } } // // IPath path = project.getOutputLocation(); // IPath projectResourceLocation = // project.getResource().getLocation(); // File projectFilePath = projectResourceLocation.append( // path.removeFirstSegments(1)).toFile(); // URL projectOutputUrl; // projectOutputUrl = projectFilePath.toURL(); // // if (projectDependencyUrlList.contains(projectOutputUrl) == false) // { // projectDependencyUrlList.add(projectOutputUrl); // } } URL[] arrayList = new URL[projectDependencyUrlList.size()]; URL[] returnURLArray = projectDependencyUrlList.toArray(arrayList); return returnURLArray; } private static void addEntryToList(IClasspathEntry entry, List<URL> projectDependencyUrlList) { try { IClasspathEntry resolvedEntry = JavaCore .getResolvedClasspathEntry(entry); if (resolvedEntry != null) { File f = resolvedEntry.getPath().toFile(); if (!f.exists() || !isVjoJar(f)) { return; } URL entryUrl = f.toURL(); if (!projectDependencyUrlList.contains(entryUrl)) { projectDependencyUrlList.add(entryUrl); } } } catch (AssertionFailedException e) { // Catch the assertion failure // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55992 e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } } private static IBuildpathEntry[] getResolvedBuildpath( IScriptProject vProject) { try { return vProject.getResolvedBuildpath(true); } catch (ModelException e) { VjetPlugin.error("Failed to get build path from <" + vProject.getElementName() + ">", e, IStatus.WARNING); return new IBuildpathEntry[0]; } } public static SourcePathInfo getProjectSrcPath_DLTK(IScriptProject vProject) { SourcePathInfo srcPaths = new SourcePathInfo(); String name = vProject.getProject().getName(); IBuildpathEntry[] entries = getResolvedBuildpath(vProject); for (IBuildpathEntry entry : entries) { if (entry.getEntryKind() != IBuildpathEntry.BPE_SOURCE) { continue; } for(IPath inclusion : entry.getInclusionPatterns()){ srcPaths.addInclusionRule(inclusion.toPortableString()); } for(IPath exclusion : entry.getExclusionPatterns()){ srcPaths.addExclusionRule(exclusion.toPortableString()); } String portableString = entry.getPath().toPortableString(); if (portableString.lastIndexOf(name) != -1) { if (portableString.equals(name)) { portableString = ""; } else { portableString = portableString.substring(portableString .indexOf(name) + name.length()); } } srcPaths.addSourcePath(portableString); } return srcPaths; } public static List<URL> getProjectDependantJars_DLTK(IScriptProject vProject) { IBuildpathEntry[] entries = getResolvedBuildpath(vProject); List<URL> urlsString = new ArrayList<URL>(entries.length); for (int i = 0; i < entries.length; i++) { IBuildpathEntry entry = entries[i]; if (entry.getEntryKind() == IBuildpathEntry.BPE_LIBRARY) { IPath path = entry.getPath(); File file = getFile(path); if (file!=null && file.exists() && file.isFile()) { URL url = getURL(file); if (url != null) { urlsString.add(url); } } } } return urlsString; } /** * @param path * @return */ private static File getFile(IPath path) { path = EnvironmentPathUtils.getLocalPath(path); File file = path.toFile(); if (!file.exists()) { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IResource member = root.findMember(path); if (member != null && member.exists() && member.getLocation()!=null) { file = member.getLocation().toFile(); }else if(member != null && member.exists() && member.getLocation()==null){ if(member.isLinked()){ return null; } } } return file; } private static URL getURL(File file) { try { return file.toURI().toURL(); } catch (MalformedURLException e) { e.printStackTrace(); return null; } } private static void addEntryToVJETEntry(IClasspathEntry entry, List<IBuildpathEntry> vEntries, List<String> duplicateChecker) { try { IClasspathEntry resolvedEntry = JavaCore .getResolvedClasspathEntry(entry); if (resolvedEntry != null) { File f = resolvedEntry.getPath().toFile(); IFile ifile = null; if (!f.exists()) { IWorkspace workspace = ResourcesPlugin.getWorkspace(); ifile = workspace.getRoot().getFile(resolvedEntry.getPath()); if (ifile.exists()) { f = ifile.getLocation().toFile(); } if (!f.exists()) { return; } } String s = f.toString(); if (duplicateChecker.contains(s)) { return; } else { duplicateChecker.add(s); } IBuildpathEntry eEntry = null; if (!isVjoJar(f)) { // The file is not a vjo file return; } if (ifile != null) { eEntry = DLTKCore .newLibraryEntry(resolvedEntry.getPath()); } else { IEnvironment env = LocalEnvironment.getInstance(); eEntry = DLTKCore .newExtLibraryEntry(EnvironmentPathUtils.getFullPath( env, new Path(f.toURI().toURL().getFile()))); } // IBuildpathEntry eEntry = DLTKCore.newLibraryEntry(new // Path(LocalEnvironment.ENVIRONMENT_ID, "/" + s), true, true); vEntries.add(eEntry); } } catch (Exception e) { // Catch the assertion failure // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55992 e.printStackTrace(); } } public static boolean isVjoJar(File libFile) { String toString = libFile.toString(); if (noneVjoFileList.contains(toString)) { return false; } else if (vjoFileList.contains(toString)) { return true; } String libFileName = libFile.getName().toLowerCase(); if (CodeassistUtils.isBinaryPath(libFileName)) { ZipFile jarFile = null; try { jarFile = new ZipFile(libFile); Enumeration<? extends ZipEntry> enumeration = jarFile.entries(); while (enumeration.hasMoreElements()) { ZipEntry elem = enumeration.nextElement(); if (!elem.isDirectory()) { String typeName = elem.getName(); if (CodeassistUtils.isVjetFileName(typeName)) { vjoFileList.add(toString); return true; } } } } catch (IOException e) { } finally { try { jarFile.close(); } catch (IOException e) { e.printStackTrace(); } } } noneVjoFileList.add(toString); return false; } /** * Check if the script project has been initialized from java project * * @see org.eclipse.vjet.eclipse.core.PiggyBackClassPathUtil#initializeScriptProjectFromJavProject(IScriptProject * project) * @param project * @return */ public static boolean ifScriptProjectInitializedFromJavaProject( IScriptProject vProject) { IProject project = vProject.getProject(); IEclipsePreferences prefs = getProjectPreference(project, VjetPlugin.PLUGIN_ID); if (prefs == null) { return false; } return prefs.getBoolean(PREFERENCE_SCRIPTPROJECT_INITIALIZED, false); } private static IEclipsePreferences getProjectPreference(IProject project, String pluginId) { IScopeContext projectContext = new ProjectScope(project); // if (!projectContext.getLocation().toFile().exists()) { // return null; // } IEclipsePreferences prefs = projectContext .getNode(VjetPlugin.PLUGIN_ID); return prefs; } /** * Way to initialize ScriptProject from Java. "run setup option" in EDE only * generates java build path. VJET need analyze Java class path and build up * it own path, in this way, VJET can kick off many none DLTK related paths. * * @param project */ public static void initializeScriptProjectFromJavProject( IScriptProject project) { IJavaProject javaProject = JavaCore.create(project.getProject()); if (!javaProject.exists()) { return; } List<IBuildpathEntry> vEntries = fetchBuildEntryFromJavaProject(javaProject); savaVJetEntries(vEntries, project); } public static List<IBuildpathEntry> fetchBuildEntryFromJavaProject( IJavaProject javaProject) { // Project entry List<IBuildpathEntry> vEntries = new ArrayList<IBuildpathEntry>(); List<String> duplicateChecker = new ArrayList<String>(); IClasspathEntry[] entries2; try { entries2 = javaProject.getRawClasspath(); } catch (JavaModelException e) { VjetPlugin.error("Failed to resolve Java prjoect classpath: " + javaProject.getElementName(), e, IStatus.WARNING); return Collections.emptyList(); } for (IClasspathEntry entry : entries2) { IPath path = entry.getPath(); String sPath = path.toString(); switch (entry.getEntryKind()) { case IClasspathEntry.CPE_VARIABLE: case IClasspathEntry.CPE_LIBRARY: addEntryToVJETEntry(entry, vEntries, duplicateChecker); case IClasspathEntry.CPE_PROJECT: IResource subResource = ResourcesPlugin.getWorkspace() .getRoot().findMember(entry.getPath()); if (subResource != null && subResource.getType() == IResource.PROJECT) { addProjectEntry(entry.getPath(), vEntries, duplicateChecker); } break; case IClasspathEntry.CPE_CONTAINER: if (!JavaRuntime.JRE_CONTAINER.equals(path.segment(0))) { IClasspathContainer container; try { container = JavaCore.getClasspathContainer(path, javaProject); if (container != null) { IClasspathEntry[] entries = container .getClasspathEntries(); for (int i = 0; i < entries.length; i++) { addEntryToVJETEntry(entries[i], vEntries, duplicateChecker); } } } catch (JavaModelException e) { VjetPlugin.error( "Failed to resolve Java classpath container: " + sPath, e, IStatus.WARNING); } } break; default: break; } } return vEntries; } /** * TODO, save entries into .buildpath Save new entry into Vjet project * * @param entries * @param project */ private static void savaVJetEntries(List<IBuildpathEntry> entries, IScriptProject project) { try { IBuildpathEntry[] oEntries = project.getRawBuildpath(); for (int i = 0; i < oEntries.length; i++) { if (oEntries[i].getEntryKind() != IBuildpathEntry.BPE_LIBRARY && oEntries[i].getEntryKind() != IBuildpathEntry.BPE_PROJECT) { entries.add(0, oEntries[i]); } } project.setRawBuildpath(entries.toArray(new IBuildpathEntry[] {}), null); setProjectInitialized(project.getProject()); } catch (ModelException e) { e.printStackTrace(); VjetPlugin.getDefault().error("Failed to update project build path.", e); //Do nothing and skip } } /** * Set that the VJet project has been initialized from java project * * @param vProject */ public static void setProjectInitialized(IProject project) { IEclipsePreferences prefs = getProjectPreference(project, VjetPlugin.PLUGIN_ID); if (prefs == null) { return; } prefs.putBoolean(PREFERENCE_SCRIPTPROJECT_INITIALIZED, true); try { prefs.flush(); } catch (BackingStoreException e) { VjetPlugin.error("Failed to save preference for " + project.getName(), e, IStatus.WARNING); } } /** * Add project dependency as entry * * @param path * @param vEntries * @param duplicateChecker */ private static void addProjectEntry(IPath path, List<IBuildpathEntry> vEntries, List<String> duplicateChecker) { String str = path.toString(); if (duplicateChecker.contains(str)) { // exists, do nothing return; } else { IProject project = ResourcesPlugin.getWorkspace().getRoot() .getProject(str); IScriptProject vProject = getScriptProject(project); if (project.exists() && vProject.exists()) { duplicateChecker.add(str); IBuildpathEntry pEntry = DLTKCore.newProjectEntry(path, true); vEntries.add(pEntry); } } } private static IScriptProject getScriptProject(IProject project) { IScriptProject vProject = DLTKCore.create(project); return vProject; } /*public static boolean ifContainSourceFolder(IResource resource) { IScriptProject vProject = getScriptProject(resource.getProject()); List<String> list = getProjectSrcPath_DLTK(vProject); if (list != null) { for (String path : list) { // check that if (resource.getProjectRelativePath().toOSString().startsWith(path.substring(1))) { return true; } } } return false; }*/ /** * Returns true if file is in source folder. * * @param file * {@link IFile} object. * @return true if file is in source folder. */ public static boolean isInSourceFolder(IResource resource) { List<String> list = PiggyBackClassPathUtil .getProjectSrcPath_DLTK(getScriptProject(resource.getProject())).getSourcePaths(); boolean isInSourceFolder = false; if (list != null) { for (String path : list) { if(path == null || path.equalsIgnoreCase("")) continue; // check that if (resource.getProjectRelativePath().toOSString().startsWith(path.substring(1))) { isInSourceFolder = true; break; } } } return isInSourceFolder; } public static ISdkEnvironment getSdkEnvironment() { return new VJetSdkEnvironment(new String[0], "DefaultSdk"); } }