/*******************************************************************************
* Copyright (c) 2012 VMWare, 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:
* VMWare, Inc. - initial API and implementation
*******************************************************************************/
package org.grails.ide.eclipse.runtime;
import grails.build.GrailsBuildListener;
import grails.util.BuildSettings;
import grails.util.PluginBuildSettings;
import java.io.File;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.codehaus.groovy.grails.cli.api.BaseSettingsApi;
import org.codehaus.groovy.grails.cli.support.BuildSettingsAware;
import org.codehaus.groovy.grails.io.support.Resource;
import org.codehaus.groovy.grails.plugins.GrailsPluginUtils;
import org.grails.ide.eclipse.runtime.shared.DependencyData;
import org.grails.ide.eclipse.runtime.shared.DependencyFileFormat;
//import org.codehaus.groovy.grails.io.support.Resource;
/**
* This is a replacement of the now obsolete {@link GrailsBuildSettings}.
* <p>
* It does the same thing as GrailsBuildSettings, but differs in the way it gets initialized.
* <p>
* Unlike GrailsBuildSettings, which is responsible for creating its own instance of {@link BuildSettings}this class expects an instance of {@link BuildSettings} from an external source (e.g. by hooking into
* the {@link GrailsBuildListener} interface.
* @author Kris De Volder
* @since 2.5.0
*/
public class GrailsBuildSettingsDependencyExtractor {
private BuildSettings settings = null;
private BaseSettingsApi settingsApi = null;
private boolean initialized = false;
private Set<File> jarFiles;
private String pluginsDirectory;
private SortedSet<File> sourceFolders;
private Set<File> pluginXmlFiles;
public GrailsBuildSettingsDependencyExtractor(BuildSettings settings) {
this.settings = settings;
this.settingsApi = new BaseSettingsApi(settings, false);
}
private File getWorkDir() {
return settings.getGrailsWorkDir();
}
private File getPluginClassesDir() {
return settings.getPluginClassesDir();
}
public synchronized Set<File> getDependencies() throws IOException {
if (!initialized) {
calculateDependencies();
}
return jarFiles;
}
public synchronized String getPluginsDirectory() throws IOException {
if (!initialized) {
calculateDependencies();
}
return pluginsDirectory;
}
public synchronized Set<File> getPluginSourceFolders() throws IOException {
if (!initialized) {
calculateDependencies();
}
return sourceFolders;
}
public synchronized Set<File> getPluginXmlFiles() throws IOException {
if (!initialized) {
calculateDependencies();
}
return pluginXmlFiles;
}
private void calculateDependencies() throws IOException {
jarFiles = new LinkedHashSet<File>();
pluginXmlFiles = new LinkedHashSet<File>();
sourceFolders = new TreeSet<File>();
pluginsDirectory = settings.getProjectPluginsDir().getCanonicalPath();
Resource[] pluginSources = GrailsPluginUtils.getPluginSourceFiles(settings.getProjectPluginsDir()
.getAbsolutePath());
for (Resource sourceFolder : pluginSources) {
if (sourceFolder.getFile().toString().contains("{}")) {
DependencyExtractingBuildListener.debug("SKIPPING strange plugin source folder: "+sourceFolder);
} else {
DependencyExtractingBuildListener.debug("Adding plugin source folder: "+sourceFolder);
sourceFolders.add(sourceFolder.getFile());
}
}
Resource[] plugins = GrailsPluginUtils.getPluginJarFiles(settings.getProjectPluginsDir().getAbsolutePath());
for (Resource plugin : plugins) {
jarFiles.add(plugin.getFile());
}
plugins = GrailsPluginUtils.getPluginJarFiles(settings.getGlobalPluginsDir().getAbsolutePath());
for (Resource plugin : plugins) {
jarFiles.add(plugin.getFile());
}
// make sure that we use the Ivy dependency resolution strategy for Grails >= 1.2
String version = settings.getGrailsVersion();
if (!(version.startsWith("1.0") || version.startsWith("1.1"))) {
jarFiles.addAll(settings.getBuildDependencies());
jarFiles.addAll(settings.getTestDependencies());
jarFiles.addAll(settings.getProvidedDependencies());
PluginBuildSettings pluginSettings = new PluginBuildSettings(settings);
for (Resource resource : pluginSettings.getPluginJarFiles()) {
jarFiles.add(resource.getFile());
}
for (Resource resource : pluginSettings.getPluginSourceFiles()) {
File srcFolder = resource.getFile();
if (srcFolder.toString().contains("{}")) {
DependencyExtractingBuildListener.debug("SKIPPING strange source folder: "+srcFolder);
} else if (srcFolder.isDirectory()) {
DependencyExtractingBuildListener.debug("Adding source folder: "+srcFolder);
//It seems we get passed stuff like '.gitignore' which is not actually a srcFolder. So
//we check here that what we are adding is at least a directory.
sourceFolders.add(resource.getFile());
}
}
for (Resource resource : pluginSettings.getPluginXmlMetadata()) {
File file = resource.getFile();
if (file.toString().contains("{}")) {
//Not sure why these entries are there, but they cause trouble! So skip them.
DependencyExtractingBuildListener.debug("SKIPPING strange plugin.xml file: "+resource.getFile());
} else {
DependencyExtractingBuildListener.debug("Adding plugin.xml file: "+resource.getFile());
pluginXmlFiles.add(file);
}
}
}
else {
if (settings.getGrailsHome() != null) {
File folder = new File(settings.getGrailsHome(), "dist");
if (folder.exists() && folder.canRead() && folder.listFiles() != null) {
for (File file : folder.listFiles()) {
if (file.getName().endsWith(".jar")) {
jarFiles.add(file);
}
}
}
folder = new File(settings.getGrailsHome(), "lib");
if (folder.exists() && folder.canRead() && folder.listFiles() != null) {
for (File file : folder.listFiles()) {
if (file.getName().endsWith(".jar")) {
jarFiles.add(file);
}
}
}
}
if (settings.getBaseDir() != null) {
File folder = new File(settings.getBaseDir(), "lib");
if (folder.exists() && folder.canRead() && folder.listFiles() != null) {
for (File file : folder.listFiles()) {
if (file.getName().endsWith(".jar")) {
jarFiles.add(file);
}
}
}
}
}
initialized = true;
}
/**
* Write out the dependency data to a file that can later be read by STS grails tooling to setup a project's
* classpath, linked source folders etc.
*
* @param dependencyDescriptorName The name of the file to write to.
* @throws IOException
*/
public void writeDependencyFile(String dependencyDescriptorName) throws IOException {
File dependencyDescriptor = new File(dependencyDescriptorName);
DependencyFileFormat.write(dependencyDescriptor, getDependencyData());
}
private DependencyData getDependencyData() throws IOException {
return new DependencyData(
//sources,
getPluginSourceFolders(),
//dependencies,
getDependencies(),
//workDir,
getWorkDir(),
//pluginsDirectory,
new File(getPluginsDirectory()),
//pluginDescriptors
getPluginXmlFiles(),
//pluginClassesDir
getPluginClassesDir(),
//server port
getServerPort()
);
}
private int getServerPort() {
try {
return settingsApi.getServerPort();
} catch (Throwable e) {
return 8080;
}
}
}