/******************************************************************************* * Copyright (c) 2012 Pivotal Software, 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 * * Contributors: * Pivotal Software, Inc. - initial API and implementation *******************************************************************************/ package org.grails.ide.eclipse.core.workspace; import static org.grails.ide.eclipse.core.internal.classpath.GrailsClasspathContainer.isGrailsClasspathContainer; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaModelException; import org.grails.ide.eclipse.core.internal.classpath.GrailsClasspathContainer; /** * Grails centric view on an Eclipse jdt set of raw classpath entries. This class makes sure that * the typical entries found on a Grails project's class path are kept in the desired order. * * @author Kris De Volder * * @since 2.8 */ public class GrailsClassPath { private LinkedHashSet<IClasspathEntry> entries; private IClasspathEntry grailsClasspathContainer = null; //This entry allways comes last. /** * Extracts relevant info from a given IJavaProject, creating a 'snapshot' of its current classpath. */ GrailsClassPath(GrailsProject project) throws JavaModelException { IJavaProject javaProject = project.getJavaProject(); IClasspathEntry[] rawEntries = javaProject.getRawClasspath(); entries = new LinkedHashSet<IClasspathEntry>(rawEntries.length); for (IClasspathEntry entry : rawEntries) { if (isGrailsClasspathContainer(entry)) { grailsClasspathContainer = entry; } else { entries.add(entry); } } } /** * Creates an empty GrailsClassPath containing no entries. */ public GrailsClassPath() { entries = new LinkedHashSet<IClasspathEntry>(); } /** * convert into an array of {@link IClasspathEntry} acceptable to setRawClasspath method of IJavaProject. * <p> * Note package private: use {@link GrailsProject}.setClasspath instead. */ IClasspathEntry[] toArray() { int size = entries.size(); if (grailsClasspathContainer!=null) { size++; } IClasspathEntry[] result = new IClasspathEntry[size]; int i = 0; for (IClasspathEntry e : entries) { result[i++] = e; } if (grailsClasspathContainer!=null) { result[size-1] = grailsClasspathContainer; } return result; } /** * Adds a new entry. If an equal entry is already present, this method has no effect. */ public void add(IClasspathEntry newEntry) { if (isGrailsClasspathContainer(newEntry)) { //Special treatment for grails container entries Assert.isLegal(grailsClasspathContainer==null || newEntry.equals(grailsClasspathContainer)); grailsClasspathContainer = newEntry; } else { //Adding some other type of entry entries.add(newEntry); } } public void removeAll(List<IClasspathEntry> toRemove) { for (IClasspathEntry e : toRemove) { remove(e); } } public void remove(IClasspathEntry e) { if (e.equals(grailsClasspathContainer)) { grailsClasspathContainer = null; } else { entries.remove(e); } } public void addAll(List<IClasspathEntry> newEntries) { for (IClasspathEntry e : newEntries) { add(e); } } public void removeGrailsClasspathContainer() { grailsClasspathContainer = null; } public void removePluginSourceFolders() { Iterator<IClasspathEntry> iter = entries.iterator(); while (iter.hasNext()) { IClasspathEntry existingEntry = iter.next(); if (isPluginSourceFolder(existingEntry)) { iter.remove(); } } } public static boolean isPluginSourceFolder(IClasspathEntry e) { if (e.getEntryKind() == IClasspathEntry.CPE_SOURCE) { for (IClasspathAttribute attr : e.getExtraAttributes()) { if (attr.getName().equals(GrailsClasspathContainer.PLUGIN_SOURCEFOLDER_ATTRIBUTE_NAME)) { return true; } } } return false; } }