/* * Copyright 2009-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.groovy.eclipse.dsl.classpath; import static org.eclipse.jdt.core.JavaCore.newLibraryEntry; import java.io.File; import java.util.ArrayList; import java.util.List; import org.codehaus.groovy.eclipse.core.builder.GroovyClasspathContainer; import org.codehaus.groovy.eclipse.core.compiler.CompilerUtils; import org.codehaus.groovy.eclipse.dsl.GroovyDSLCoreActivator; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.ClasspathContainerInitializer; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; /** * Classpath container initializer that grabs all of the DSLDs that live outside of the workspace. */ public class DSLDContainerInitializer extends ClasspathContainerInitializer { private static final IClasspathEntry[] NO_ENTRIES = new IClasspathEntry[0]; /** * The location for global dsld files. Null if the locaiton does not exist and cannot be created */ private static final File globalDsldLocation = getGlobalDsldLocation(); private static final class DSLDClasspathContainer implements IClasspathContainer { private IClasspathEntry[] entries; public IPath getPath() { return GroovyDSLCoreActivator.CLASSPATH_CONTAINER_ID; } public int getKind() { return K_APPLICATION; } public String getDescription() { return "Groovy DSL Support"; } public IClasspathEntry[] getClasspathEntries() { if (entries == null) { entries = calculateEntries(); } return entries; } void reset() { entries = null; } /** * Two entries: the /dsld folder in the groovy bundle and the ~/.groovy/greclipse/dsld folder */ protected IClasspathEntry[] calculateEntries() { if (GroovyDSLCoreActivator.getDefault().isDSLDDisabled()) { return NO_ENTRIES; } List<IClasspathEntry> newEntries = new ArrayList<IClasspathEntry>(); if (globalDsldLocation != null && globalDsldLocation.exists()) { IPath dsldPath = new Path(globalDsldLocation.getAbsolutePath()); newEntries.add(newLibraryEntry(dsldPath, null, null, false)); } try { IPath folder = CompilerUtils.findDSLDFolder(); if (folder != null) { Assert.isTrue(folder.toFile().exists(), "Plugin DSLD location does not exist: " + folder); newEntries.add(newLibraryEntry(folder, null, null)); } } catch (Exception e) { GroovyDSLCoreActivator.logException(e); } return newEntries.toArray(NO_ENTRIES); } } private static File getGlobalDsldLocation() { final String dotGroovyLocation; if (GroovyDSLCoreActivator.getDefault().isDSLDDisabled() || (dotGroovyLocation = CompilerUtils.getDotGroovyLocation()) == null) { return null; } final File globalDsldDir = new File(dotGroovyLocation + "/greclipse/global_dsld_support"); if (!globalDsldDir.exists()) { try { globalDsldDir.mkdirs(); } catch (SecurityException e) { } } if (globalDsldDir.exists()) { return globalDsldDir; } else { GroovyDSLCoreActivator.logWarning("Cannot create DSL support location at " + globalDsldDir.getPath() + ". Location is read-only, or a security manager is preventing it."); return null; } } private IJavaProject javaProject; @Override public void initialize(final IPath containerPath, final IJavaProject javaProject) throws CoreException { this.javaProject = javaProject; IClasspathContainer container = new DSLDClasspathContainer(); JavaCore.setClasspathContainer(containerPath, new IJavaProject[] {javaProject}, new IClasspathContainer[] {container}, null); } @Override public boolean canUpdateClasspathContainer(IPath containerPath, IJavaProject project) { return true; } @Override public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project, IClasspathContainer containerSuggestion) throws CoreException { if (containerSuggestion instanceof DSLDClasspathContainer) { ((DSLDClasspathContainer) containerSuggestion).reset(); } if (javaProject == null) { IClasspathContainer dsld = JavaCore.getClasspathContainer(GroovyClasspathContainer.CONTAINER_ID, javaProject); if (dsld instanceof DSLDClasspathContainer) { ((DSLDClasspathContainer) dsld).reset(); } } } }