| /******************************************************************************* |
| * Copyright (c) 2004, 2005 Richard Hoefter 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: |
| * Richard Hoefter (richard.hoefter@web.de) - initial API and implementation, bug 95300 |
| * IBM Corporation - nlsing and incorporating into Eclipse. |
| * Class created from combination of all utility classes of contribution |
| *******************************************************************************/ |
| |
| package org.eclipse.ant.internal.ui.datatransfer; |
| |
| import java.io.StringWriter; |
| import java.util.Comparator; |
| import java.util.Iterator; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| import javax.xml.transform.OutputKeys; |
| import javax.xml.transform.Result; |
| import javax.xml.transform.Source; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.TransformerFactoryConfigurationError; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.jdt.core.IClasspathContainer; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.IJavaModel; |
| import org.eclipse.jdt.core.IJavaModelMarker; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.w3c.dom.Document; |
| |
| /** |
| * Eclipse API shortcuts. |
| */ |
| public class ExportUtil |
| { |
| private ExportUtil() |
| { |
| } |
| |
| /** |
| * Get resource from selection. |
| */ |
| public static IResource getResource(ISelection selection) |
| { |
| if (selection instanceof IStructuredSelection) |
| { |
| for (Iterator iter = ((IStructuredSelection) selection).iterator(); iter.hasNext();) |
| { |
| IAdaptable adaptable = (IAdaptable) iter.next(); |
| return (IResource) adaptable.getAdapter(IResource.class); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Get Java project from resource. |
| */ |
| public static IJavaProject getJavaProjectByName(String name) |
| { |
| IWorkspaceRoot rootWorkspace = ResourcesPlugin.getWorkspace().getRoot(); |
| IJavaModel javaModel = JavaCore.create(rootWorkspace); |
| IJavaProject[] javaProjects; |
| try |
| { |
| javaProjects = javaModel.getJavaProjects(); |
| } |
| catch (JavaModelException e) |
| { |
| return null; |
| } |
| for (int i = 0; i < javaProjects.length; i++) |
| { |
| IJavaProject javaProject = javaProjects[i]; |
| if (name.equals(javaProject.getProject().getName())) |
| { |
| return javaProject; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Get project root for given project. |
| */ |
| public static String getProjectRoot(IJavaProject project) |
| { |
| return project.getResource().getLocation().toString(); |
| } |
| |
| /** |
| * Convert relative path to absolute path. Path must include project and resource name, otherwise |
| * returns null. |
| * @param path path which is relative to project root. |
| * @return full qualified path including project root |
| */ |
| public static String resolve(IPath path) |
| { |
| if (path == null) |
| { |
| return null; |
| } |
| IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(path); |
| if (folder.exists()) { |
| return folder.getLocation().toString(); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Get Java project for given root. |
| */ |
| public static IJavaProject getJavaProject(String root) |
| { |
| IWorkspaceRoot rootWorkspace = ResourcesPlugin.getWorkspace().getRoot(); |
| IJavaModel javaModel = JavaCore.create(rootWorkspace); |
| IJavaProject[] javaProjects; |
| try |
| { |
| javaProjects = javaModel.getJavaProjects(); |
| } |
| catch (JavaModelException e) |
| { |
| return null; |
| } |
| for (int i = 0; i < javaProjects.length; i++) |
| { |
| IJavaProject javaProject = javaProjects[i]; |
| if (root.equals(javaProject.getPath().toString())) |
| { |
| return javaProject; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Remove project root from given project file. |
| */ |
| public static String removeProjectRoot(String file, IProject project) |
| { |
| String res = removePrefix(file, '/' + project.getName() + '/'); |
| if (res.equals('/' + project.getName())) |
| { |
| return "."; //$NON-NLS-1$ |
| } |
| return res; |
| } |
| |
| /** |
| * Remove project root from given project file. |
| * @param newProjectRoot replace project root, e.g. with a variable ${project.location} |
| */ |
| public static String replaceProjectRoot(String file, IProject project, String newProjectRoot) |
| { |
| String res = removeProjectRoot(file, project); |
| if (res.equals(".")) //$NON-NLS-1$ |
| { |
| return newProjectRoot; |
| } |
| if (!res.equals(file)) |
| { |
| return newProjectRoot + '/' + res; |
| } |
| return res; |
| } |
| |
| /** |
| * Get for given project all directly dependent projects. |
| * |
| * @return set of IJavaProject objects |
| */ |
| public static Set getClasspathProjects(IJavaProject project) throws JavaModelException |
| { |
| Set projects = new TreeSet(getJavaProjectComparator()); |
| IClasspathEntry entries[] = project.getRawClasspath(); |
| addClasspathProjects(projects, project, entries); |
| return projects; |
| } |
| |
| private static void addClasspathProjects(Set projects, IJavaProject project, IClasspathEntry[] entries) throws JavaModelException { |
| for (int i = 0; i < entries.length; i++) |
| { |
| IClasspathEntry classpathEntry = entries[i]; |
| if (classpathEntry.getContentKind() == IPackageFragmentRoot.K_SOURCE) { |
| if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { |
| // found required project on build path |
| String subProjectRoot = classpathEntry.getPath().toString(); |
| IJavaProject subProject = ExportUtil.getJavaProject(subProjectRoot); |
| projects.add(subProject); |
| } else if ( classpathEntry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { |
| IClasspathContainer container = JavaCore.getClasspathContainer(classpathEntry.getPath(), project); |
| IClasspathEntry containerEntries[] = container.getClasspathEntries(); |
| addClasspathProjects(projects, project, containerEntries); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Get for given project all directly and indirectly dependent projects. |
| * |
| * @return set of IJavaProject objects |
| */ |
| public static Set getClasspathProjectsRecursive(IJavaProject project) throws JavaModelException |
| { |
| Set result = new TreeSet(getJavaProjectComparator()); |
| getClasspathProjectsRecursive(project, result); |
| return result; |
| } |
| |
| private static void getClasspathProjectsRecursive(IJavaProject project, Set result) throws JavaModelException |
| { |
| Set projects = getClasspathProjects(project); |
| for (Iterator iter = projects.iterator(); iter.hasNext();) |
| { |
| IJavaProject javaProject = (IJavaProject) iter.next(); |
| if (result.add(javaProject)) { |
| getClasspathProjectsRecursive(javaProject, result); // recursion |
| } |
| } |
| } |
| |
| /** |
| * Check if given project has a cyclic dependency. |
| * |
| * <p>See org.eclipse.jdt.core.tests.model.ClasspathTests.numberOfCycleMarkers. |
| */ |
| public static boolean hasCyclicDependency(IJavaProject javaProject) |
| throws CoreException |
| { |
| IMarker[] markers = javaProject.getProject().findMarkers( |
| IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, |
| IResource.DEPTH_ONE); |
| for (int i = 0; i < markers.length; i++) |
| { |
| IMarker marker = markers[i]; |
| String cycleAttr = (String) marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED); |
| if (cycleAttr != null && cycleAttr.equals("true")) //$NON-NLS-1$ |
| { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Find JUnit tests. Same tests are also returned by Eclipse run configuration wizard. |
| * |
| * <p>NOTE: You might see a dialog flashing up for a very short time. |
| * |
| * @param containerHandle project, package or source folder |
| * |
| * @see org.eclipse.jdt.internal.junit.launcher.JUnitBaseLaunchConfiguration |
| */ |
| public static IType[] findTestsInContainer(String containerHandle) |
| { |
| // IJavaElement container; |
| // try |
| // { |
| // container = JavaCore.create(containerHandle); |
| // } |
| // catch (Exception e) |
| // { |
| // return new IType[0]; |
| // } |
| // try |
| // { |
| // return TestSearchEngine.findTests(new Object[] { container }); |
| // } |
| // catch (Exception e) |
| // { |
| // return new IType[0]; |
| // } |
| return new IType[0]; |
| } |
| |
| /** |
| * Compares projects by project name. |
| */ |
| public static Comparator getJavaProjectComparator() |
| { |
| if (javaProjectComparator == null) |
| { |
| javaProjectComparator = new JavaProjectComparator(); |
| } |
| return javaProjectComparator; |
| } |
| |
| private static Comparator javaProjectComparator; |
| |
| private static class JavaProjectComparator implements Comparator |
| { |
| public int compare(Object o1, Object o2) |
| { |
| IJavaProject j1 = (IJavaProject) o1; |
| IJavaProject j2 = (IJavaProject) o2; |
| return j1.getProject().getName().compareTo(j2.getProject().getName()); |
| } |
| |
| public boolean equals(Object obj) |
| { |
| if (obj == null) |
| { |
| return false; |
| } |
| return compare(this, obj) == 0; |
| } |
| } |
| |
| public static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$ |
| |
| public static String removePrefix(String s, String prefix) |
| { |
| if (s == null) |
| { |
| return null; |
| } |
| if (s.startsWith(prefix)) |
| { |
| return s.substring(prefix.length()); |
| } |
| return s; |
| } |
| |
| public static String removeSuffix(String s, String suffix) |
| { |
| if (s == null) |
| { |
| return null; |
| } |
| if (s.endsWith(suffix)) |
| { |
| return s.substring(0, s.length() - suffix.length()); |
| } |
| return s; |
| } |
| |
| public static String removePrefixAndSuffix(String s, String prefix, String suffix) |
| { |
| return removePrefix(removeSuffix(s, suffix), prefix); |
| } |
| |
| /** |
| * Convert document to formatted XML string. |
| */ |
| public static String toString(Document doc) throws TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException |
| { |
| // NOTE: There are different transformer implementations in the wild, which are configured differently |
| // regarding the indent size: |
| // Java 1.4: org.apache.xalan.transformer.TransformerIdentityImpl |
| // Java 1.5: com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl |
| |
| StringWriter writer = new StringWriter(); |
| Source source = new DOMSource(doc); |
| Result result = new StreamResult(writer); |
| TransformerFactory factory = TransformerFactory.newInstance(); |
| boolean indentFallback = false; |
| try |
| { |
| // indent using TransformerImpl |
| factory.setAttribute("indent-number", "4"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| catch (IllegalArgumentException e) |
| { |
| // option not supported, set indent size below |
| indentFallback = true; |
| } |
| Transformer transformer = factory.newTransformer(); |
| transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ |
| if (indentFallback) |
| { |
| // indent using TransformerIdentityImpl |
| transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| transformer.transform(source, result); |
| return writer.toString(); |
| } |
| |
| /** |
| * Include a file into an XML document by adding an entity reference. |
| * @param doc XML document |
| * @param name name of the entity reference to create |
| * @param file name of file to include |
| * @return XML document with entity reference |
| */ |
| public static String addEntity(Document doc, String name, String file) throws TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException |
| { |
| String xml = toString(doc); |
| return addEntity(xml, name, file); |
| } |
| |
| /** |
| * Include a file into an XML document by adding an entity reference. |
| * @param xml XML document |
| * @param name name of the entity reference to create |
| * @param file name of file to include |
| * @return XML document with entity reference |
| */ |
| public static String addEntity(String xml, String name, String file) |
| { |
| // NOTE: It is not possible to write a DOCTYPE with an internal DTD using transformer. |
| // It is also not possible to write an entity reference with JAXP. |
| StringBuffer xmlBuffer = new StringBuffer(xml); |
| int index = xmlBuffer.indexOf(ExportUtil.NEWLINE) != -1 ? xmlBuffer.indexOf(ExportUtil.NEWLINE) : 0; |
| StringBuffer entity= new StringBuffer(); |
| entity.append(ExportUtil.NEWLINE); |
| entity.append("<!DOCTYPE project [<!ENTITY "); //$NON-NLS-1$ |
| entity.append(name); |
| entity.append(" SYSTEM \"file:"); //$NON-NLS-1$ |
| entity.append(file); |
| entity.append("\">]>"); //$NON-NLS-1$ |
| xmlBuffer.insert(index, entity.toString()); |
| index = xmlBuffer.indexOf("basedir") != -1 ? xmlBuffer.indexOf("basedir") : 0; //$NON-NLS-1$ //$NON-NLS-2$ |
| index = xmlBuffer.indexOf(ExportUtil.NEWLINE, index); |
| if (index != -1) |
| { |
| xmlBuffer.insert(index, ExportUtil.NEWLINE + " &" + name + ';'); //$NON-NLS-1$ |
| } |
| return xmlBuffer.toString(); |
| } |
| } |