mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-69867 Support services as an artifact type in Griffon projects
This commit is contained in:
@@ -18,6 +18,8 @@ package org.jetbrains.plugins.groovy.griffon;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.JavaParameters;
|
||||
import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -36,6 +38,8 @@ import com.intellij.openapi.vcs.changes.IgnoredBeanFactory;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -49,7 +53,9 @@ import org.jetbrains.plugins.groovy.mvc.MvcProjectStructure;
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -246,7 +252,7 @@ public class GriffonFramework extends MvcFramework {
|
||||
for (final VirtualFile child : dist.getChildren()) {
|
||||
final String name = child.getName();
|
||||
if (name.endsWith(".jar")) {
|
||||
if (name.startsWith("griffon-cli-") || name.startsWith("griffon-rt-")) {
|
||||
if (name.startsWith("griffon-cli-") || name.startsWith("griffon-rt-") || name.startsWith("griffon-resources-")) {
|
||||
params.getClassPath().add(child);
|
||||
}
|
||||
}
|
||||
@@ -296,6 +302,9 @@ public class GriffonFramework extends MvcFramework {
|
||||
final String confpath = griffonHomePath + GROOVY_STARTER_CONF;
|
||||
params.getVMParametersList().add("-Dgroovy.starter.conf=" + confpath);
|
||||
|
||||
params.getVMParametersList().add(
|
||||
"-Dgroovy.sanitized.stacktraces=\"groovy., org.codehaus.groovy., java., javax., sun., gjdk.groovy., gant., org.codehaus.gant.\"");
|
||||
|
||||
params.getProgramParametersList().add("--main");
|
||||
params.getProgramParametersList().add("org.codehaus.griffon.cli.GriffonScriptRunner");
|
||||
params.getProgramParametersList().add("--conf");
|
||||
@@ -314,7 +323,7 @@ public class GriffonFramework extends MvcFramework {
|
||||
params.getProgramParametersList().add(argsString);
|
||||
|
||||
params.setDefaultCharset(module.getProject());
|
||||
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
@@ -384,6 +393,24 @@ public class GriffonFramework extends MvcFramework {
|
||||
return EP_NAME.findExtension(GriffonFramework.class);
|
||||
}
|
||||
|
||||
public VirtualFile getApplicationPropertiesFile(Module module) {
|
||||
final VirtualFile appRoot = findAppRoot(module);
|
||||
return appRoot != null ? appRoot.findChild("application.properties") : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getApplicationName(Module module) {
|
||||
final VirtualFile appProperties = getApplicationPropertiesFile(module);
|
||||
if (appProperties != null) {
|
||||
final PsiFile file = PsiManager.getInstance(module.getProject()).findFile(appProperties);
|
||||
if (file instanceof PropertiesFile) {
|
||||
final IProperty property = ((PropertiesFile)file).findPropertyByKey("application.name");
|
||||
return property != null ? property.getValue() : super.getApplicationName(module);
|
||||
}
|
||||
}
|
||||
return super.getApplicationName(module);
|
||||
}
|
||||
|
||||
private static class GriffonProjectStructure extends MvcProjectStructure {
|
||||
public GriffonProjectStructure(Module module, final boolean auxModule) {
|
||||
super(module, auxModule, getUserHomeGriffon(), GriffonFramework.getInstance().getSdkWorkDir(module));
|
||||
@@ -395,11 +422,55 @@ public class GriffonFramework extends MvcFramework {
|
||||
}
|
||||
|
||||
public String[] getSourceFolders() {
|
||||
return new String[]{"griffon-app/controllers", "griffon-app/models", "griffon-app/views", "src/main", "griffon-app/services"};
|
||||
List<String> sourceFolders = new ArrayList<String>();
|
||||
|
||||
for (VirtualFile file : ModuleRootManager.getInstance(myModule).getContentRoots()) {
|
||||
handleSrc(file.findChild("src"), sourceFolders);
|
||||
handleGriffonApp(file.findChild("griffon-app"), sourceFolders);
|
||||
List<GriffonSourceInspector.GriffonSource> sources =
|
||||
GriffonSourceInspector.processModuleMetadata(myModule);
|
||||
for (GriffonSourceInspector.GriffonSource source : sources) {
|
||||
sourceFolders.add(source.getPath());
|
||||
}
|
||||
}
|
||||
return sourceFolders.toArray(new String[sourceFolders.size()]);
|
||||
}
|
||||
|
||||
private void handleGriffonApp(VirtualFile griffonApp, List<String> sourceFolders) {
|
||||
if (griffonApp == null) return;
|
||||
// Add standard artifacts, i.e, models, views, controllers, services, conf, lifecycle
|
||||
for (String child : new String[]{"models", "views", "controllers", "services", "conf", "lifecycle"}) {
|
||||
if (griffonApp.findChild(child) != null) {
|
||||
sourceFolders.add("griffon-app/" + child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSrc(VirtualFile src, List<String> sourceFolders) {
|
||||
if (src == null) return;
|
||||
for (String child : new String[]{"main", "cli"}) {
|
||||
if (src.findChild(child) != null) {
|
||||
sourceFolders.add("src/" + child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTest(VirtualFile test, List<String> sourceFolders) {
|
||||
if (test == null) return;
|
||||
for (String child : new String[]{"unit", "integration", "shared"}) {
|
||||
if (test.findChild(child) != null) {
|
||||
sourceFolders.add("test/" + child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getTestFolders() {
|
||||
return new String[]{"test/unit", "test/integration"};
|
||||
List<String> sourceFolders = new ArrayList<String>();
|
||||
|
||||
for (VirtualFile file : ModuleRootManager.getInstance(myModule).getContentRoots()) {
|
||||
handleTest(file.findChild("test"), sourceFolders);
|
||||
}
|
||||
return sourceFolders.toArray(new String[sourceFolders.size()]);
|
||||
}
|
||||
|
||||
public String[] getInvalidSourceFolders() {
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* 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.jetbrains.plugins.groovy.griffon;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author aalmiray
|
||||
*/
|
||||
public class GriffonSourceInspector {
|
||||
public static List<GriffonSource> processModuleMetadata(final Module module) {
|
||||
return CachedValuesManager.getManager(module.getProject()).getCachedValue(module, new CachedValueProvider<List<GriffonSource>>() {
|
||||
@Override
|
||||
public Result<List<GriffonSource>> compute() {
|
||||
List<GriffonSource> sources = new ArrayList<GriffonSource>();
|
||||
List<VirtualFile> dependencies = new ArrayList<VirtualFile>();
|
||||
ContainerUtil.addIfNotNull(dependencies, GriffonFramework.getInstance().getApplicationPropertiesFile(module));
|
||||
String applicationName = GriffonFramework.getInstance().getApplicationName(module);
|
||||
|
||||
File sdkWorkDir = GriffonFramework.getInstance().getSdkWorkDir(module);
|
||||
// construct $griffonWorkDir/projects/$appName/plugins
|
||||
File pluginsDir = new File(sdkWorkDir, "/projects/" + applicationName + "/plugins/");
|
||||
if (pluginsDir.exists() && pluginsDir.canRead() && pluginsDir.isDirectory()) {
|
||||
//noinspection ConstantConditions
|
||||
for (File pluginDir : pluginsDir.listFiles()) {
|
||||
if (!pluginDir.isDirectory() || !pluginDir.canRead()) continue;
|
||||
File srcIdeSupportDir = new File(pluginDir, "src/ide-support");
|
||||
if (!srcIdeSupportDir.exists() || !srcIdeSupportDir.canRead()) continue;
|
||||
File ideaSupport = new File(srcIdeSupportDir, "idea.xml");
|
||||
VirtualFile ideaMetadata = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ideaSupport);
|
||||
if (ideaMetadata != null) {
|
||||
dependencies.add(ideaMetadata);
|
||||
PsiFile psiFile = PsiManager.getInstance(module.getProject()).findFile(ideaMetadata);
|
||||
if (psiFile instanceof XmlFile) {
|
||||
XmlTag rootTag = ((XmlFile)psiFile).getRootTag();
|
||||
if (rootTag == null) continue;
|
||||
/*
|
||||
Metadata file has the following format
|
||||
<idea-griffon>
|
||||
<source-root path="src/commons">
|
||||
<navigation
|
||||
description="Common Sources"
|
||||
icon="groovy-icon"
|
||||
weight="75" />
|
||||
</source-root>
|
||||
</idea-griffon>
|
||||
*/
|
||||
|
||||
for (XmlTag sourceRootTag : rootTag.findSubTags("source-root")) {
|
||||
String path = sourceRootTag.getAttributeValue("path");
|
||||
XmlTag navigationTag = sourceRootTag.findFirstSubTag("navigation");
|
||||
String description = navigationTag == null ? "" : navigationTag.getAttributeValue("description");
|
||||
XmlAttribute iconAttr = navigationTag == null ? null : navigationTag.getAttribute("icon");
|
||||
XmlAttribute weightAttr = navigationTag == null ? null : navigationTag.getAttribute("weight");
|
||||
String icon = iconAttr != null ? iconAttr.getValue() : "groovy-icon";
|
||||
int weight = weightAttr != null ? Integer.parseInt(weightAttr.getValue()) : 75;
|
||||
|
||||
sources.add(new GriffonSource(path, new GriffonSource.Navigation(description, icon, weight)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.create(sources, dependencies);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static class GriffonSource {
|
||||
private final String path;
|
||||
private final Navigation navigation;
|
||||
|
||||
public GriffonSource(String path, Navigation navigation) {
|
||||
this.path = path;
|
||||
this.navigation = navigation;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public Navigation getNavigation() {
|
||||
return navigation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GriffonSource{" + "path='" + path + '\'' + ", navigation=" + navigation + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
GriffonSource that = (GriffonSource)o;
|
||||
|
||||
if (!navigation.equals(that.navigation)) return false;
|
||||
if (!path.equals(that.path)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = path.hashCode();
|
||||
result = 31 * result + navigation.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class Navigation {
|
||||
private final String description;
|
||||
private final String icon;
|
||||
private final int weight;
|
||||
|
||||
public Navigation(String description, String icon, int weight) {
|
||||
this.description = getNaturalName(description);
|
||||
this.icon = icon;
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
String iconStr = icon.endsWith(".png") ? icon : icon + ".png";
|
||||
if (iconStr.startsWith("/")) {
|
||||
return IconLoader.getIcon(iconStr);
|
||||
}
|
||||
else {
|
||||
return IconLoader.getIcon("/icons/griffon/" + iconStr);
|
||||
}
|
||||
}
|
||||
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Navigation{" + "description='" + description + '\'' + ", icon='" + icon + '\'' + ", weight=" + weight + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Navigation)) return false;
|
||||
|
||||
Navigation that = (Navigation)o;
|
||||
|
||||
if (weight != that.weight) return false;
|
||||
if (description != null ? !description.equals(that.description) : that.description != null) return false;
|
||||
if (icon != null ? !icon.equals(that.icon) : that.icon != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = description != null ? description.hashCode() : 0;
|
||||
result = 31 * result + (icon != null ? icon.hashCode() : 0);
|
||||
result = 31 * result + weight;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getNaturalName(String name) {
|
||||
name = getShortName(name);
|
||||
List<String> words = new ArrayList<String>();
|
||||
int i = 0;
|
||||
char[] chars = name.toCharArray();
|
||||
for (int j = 0; j < chars.length; j++) {
|
||||
char c = chars[j];
|
||||
String w;
|
||||
if (i >= words.size()) {
|
||||
w = "";
|
||||
words.add(i, w);
|
||||
}
|
||||
else {
|
||||
w = words.get(i);
|
||||
}
|
||||
|
||||
if (Character.isLowerCase(c) || Character.isDigit(c)) {
|
||||
if (Character.isLowerCase(c) && w.length() == 0) {
|
||||
c = Character.toUpperCase(c);
|
||||
}
|
||||
else if (w.length() > 1 && Character.isUpperCase(w.charAt(w.length() - 1))) {
|
||||
w = "";
|
||||
words.add(++i, w);
|
||||
}
|
||||
|
||||
words.set(i, w + c);
|
||||
}
|
||||
else if (Character.isUpperCase(c)) {
|
||||
if ((i == 0 && w.length() == 0) || Character.isUpperCase(w.charAt(w.length() - 1))) {
|
||||
words.set(i, w + c);
|
||||
}
|
||||
else {
|
||||
words.add(++i, String.valueOf(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (Iterator<String> j = words.iterator(); j.hasNext(); ) {
|
||||
String word = j.next();
|
||||
buf.append(word);
|
||||
if (j.hasNext()) {
|
||||
buf.append(' ');
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static String getShortName(String className) {
|
||||
return StringUtil.getShortName(className);
|
||||
}
|
||||
}
|
||||
+81
-36
@@ -20,16 +20,20 @@ import com.intellij.ide.projectView.ViewSettings;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.Icons;
|
||||
import com.intellij.util.containers.hash.LinkedHashMap;
|
||||
import org.jetbrains.plugins.groovy.GroovyIcons;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.mvc.MvcIcons;
|
||||
import org.jetbrains.plugins.groovy.mvc.projectView.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -42,51 +46,67 @@ public class GriffonToolWindowFactory extends MvcToolWindowDescriptor {
|
||||
@Override
|
||||
public void fillModuleChildren(List<AbstractTreeNode> result, Module module, ViewSettings viewSettings, VirtualFile root) {
|
||||
final Project project = module.getProject();
|
||||
final PsiDirectory domains = findDirectory(project, root, "griffon-app/models");
|
||||
if (domains != null) {
|
||||
result.add(new TopLevelDirectoryNode(module, domains, viewSettings, "Model classes", MvcIcons.DOMAIN_CLASSES_FOLDER, AbstractMvcPsiNodeDescriptor.DOMAIN_CLASSES_FOLDER) {
|
||||
@Override
|
||||
protected AbstractTreeNode createClassNode(final GrTypeDefinition typeDefinition) {
|
||||
return new DomainClassNode(getModule(), typeDefinition, getSettings());
|
||||
|
||||
// process well-known artifact paths
|
||||
for (VirtualFile file : ModuleRootManager.getInstance(module).getSourceRoots()) {
|
||||
PsiDirectory sourceRoot = PsiManager.getInstance(project).findDirectory(file);
|
||||
if (sourceRoot != null) {
|
||||
if ("griffon-app".equals(file.getParent().getName())) {
|
||||
GriffonDirectoryMetadata metadata = DIRECTORY_METADATA.get(file.getName());
|
||||
if (metadata == null) continue;
|
||||
result.add(new TopLevelDirectoryNode(module, sourceRoot, viewSettings, metadata.description, metadata.icon, metadata.weight));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final PsiDirectory conf = findDirectory(project, root, "griffon-app/conf");
|
||||
if (conf != null) {
|
||||
result.add(new TopLevelDirectoryNode(module, conf, viewSettings, "Configuration", MvcIcons.CONFIG_FOLDER, AbstractMvcPsiNodeDescriptor.CONFIG_FOLDER));
|
||||
}
|
||||
|
||||
final PsiDirectory controllers = findDirectory(project, root, "griffon-app/controllers");
|
||||
if (controllers != null) {
|
||||
result.add(new TopLevelDirectoryNode(module, controllers, viewSettings, "Controllers", MvcIcons.CONTROLLERS_FOLDER, AbstractMvcPsiNodeDescriptor.CONTROLLERS_FOLDER));
|
||||
}
|
||||
|
||||
final PsiDirectory services = findDirectory(project, root, "griffon-app/services");
|
||||
if (services != null) {
|
||||
result.add(new TopLevelDirectoryNode(module, services, viewSettings, "Services", MvcIcons.SERVICE, AbstractMvcPsiNodeDescriptor.SERVICES_FOLDER));
|
||||
}
|
||||
|
||||
final PsiDirectory views = findDirectory(project, root, "griffon-app/views");
|
||||
if (views != null) {
|
||||
result.add(new TopLevelDirectoryNode(module, views, viewSettings, "Views", GroovyIcons.GROOVY_ICON_16x16, AbstractMvcPsiNodeDescriptor.VIEWS_FOLDER));
|
||||
}
|
||||
}
|
||||
|
||||
// add standard source folder
|
||||
final PsiDirectory srcMain = findDirectory(project, root, "src/main");
|
||||
if (srcMain != null) {
|
||||
result.add(new TopLevelDirectoryNode(module, srcMain, viewSettings, "Project Sources", GroovyIcons.GROOVY_ICON_16x16, AbstractMvcPsiNodeDescriptor.SRC_FOLDERS));
|
||||
result.add(new TopLevelDirectoryNode(module, srcMain, viewSettings, "Project Sources", GroovyIcons.GROOVY_ICON_16x16,
|
||||
AbstractMvcPsiNodeDescriptor.SRC_FOLDERS));
|
||||
}
|
||||
final PsiDirectory srcCli = findDirectory(project, root, "src/cli");
|
||||
if (srcCli != null) {
|
||||
result.add(new TopLevelDirectoryNode(module, srcCli, viewSettings, "Build Sources", GroovyIcons.GROOVY_ICON_16x16,
|
||||
AbstractMvcPsiNodeDescriptor.SRC_FOLDERS));
|
||||
}
|
||||
|
||||
// add standard test sources
|
||||
final PsiDirectory testsUnit = findDirectory(project, root, "test/unit");
|
||||
if (testsUnit != null) {
|
||||
result.add(new TestsTopLevelDirectoryNode(module, testsUnit, viewSettings, "Unit Tests", PlatformIcons.TEST_SOURCE_FOLDER,
|
||||
PlatformIcons.TEST_SOURCE_FOLDER));
|
||||
result.add(
|
||||
new TestsTopLevelDirectoryNode(module, testsUnit, viewSettings, "Unit Tests", Icons.TEST_SOURCE_FOLDER, Icons.TEST_SOURCE_FOLDER));
|
||||
}
|
||||
|
||||
final PsiDirectory testsIntegration = findDirectory(project, root, "test/integration");
|
||||
if (testsIntegration != null) {
|
||||
result.add(new TestsTopLevelDirectoryNode(module, testsIntegration, viewSettings, "Integration Tests", PlatformIcons.TEST_SOURCE_FOLDER,
|
||||
PlatformIcons.TEST_SOURCE_FOLDER));
|
||||
result.add(new TestsTopLevelDirectoryNode(module, testsIntegration, viewSettings, "Integration Tests", Icons.TEST_SOURCE_FOLDER,
|
||||
Icons.TEST_SOURCE_FOLDER));
|
||||
}
|
||||
final PsiDirectory testsShared = findDirectory(project, root, "test/shared");
|
||||
if (testsShared != null) {
|
||||
result.add(new TestsTopLevelDirectoryNode(module, testsShared, viewSettings, "Shared Test Sources", Icons.TEST_SOURCE_FOLDER,
|
||||
Icons.TEST_SOURCE_FOLDER));
|
||||
}
|
||||
|
||||
// add additional sources provided by plugins
|
||||
for (VirtualFile file : ModuleRootManager.getInstance(module).getContentRoots()) {
|
||||
List<GriffonSourceInspector.GriffonSource> sources = GriffonSourceInspector.processModuleMetadata(module);
|
||||
for (GriffonSourceInspector.GriffonSource source : sources) {
|
||||
final PsiDirectory dir = findDirectory(project, file, source.getPath());
|
||||
if (dir != null) {
|
||||
result.add(
|
||||
new TopLevelDirectoryNode(module, dir, viewSettings, source.getNavigation().getDescription(), source.getNavigation().getIcon(),
|
||||
source.getNavigation().getWeight()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final VirtualFile applicationPropertiesFile = GriffonFramework.getInstance().getApplicationPropertiesFile(module);
|
||||
if (applicationPropertiesFile != null) {
|
||||
PsiFile appProperties = PsiManager.getInstance(module.getProject()).findFile(applicationPropertiesFile);
|
||||
if (appProperties != null) {
|
||||
result.add(new FileNode(module, appProperties, null, viewSettings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,5 +115,30 @@ public class GriffonToolWindowFactory extends MvcToolWindowDescriptor {
|
||||
return GriffonFramework.GRIFFON_ICON;
|
||||
}
|
||||
|
||||
private static final Map<String, GriffonDirectoryMetadata> DIRECTORY_METADATA = new LinkedHashMap<String, GriffonDirectoryMetadata>();
|
||||
|
||||
static {
|
||||
DIRECTORY_METADATA.put("models", new GriffonDirectoryMetadata("Models", loadIcon("folder-models"), 20));
|
||||
DIRECTORY_METADATA.put("views", new GriffonDirectoryMetadata("Views", loadIcon("folder-views"), 30));
|
||||
DIRECTORY_METADATA.put("controllers", new GriffonDirectoryMetadata("Controllers", loadIcon("folder-controllers"), 40));
|
||||
DIRECTORY_METADATA.put("services", new GriffonDirectoryMetadata("Services", loadIcon("folder-services"), 50));
|
||||
DIRECTORY_METADATA.put("lifecycle", new GriffonDirectoryMetadata("Lifecycle", loadIcon("folder-lifecycle"), 60));
|
||||
DIRECTORY_METADATA.put("conf", new GriffonDirectoryMetadata("Configuration", loadIcon("folder-conf"), 65));
|
||||
}
|
||||
|
||||
private static Icon loadIcon(String name) {
|
||||
return IconLoader.getIcon("/icons/griffon/" + name + ".png");
|
||||
}
|
||||
|
||||
private static class GriffonDirectoryMetadata {
|
||||
public final String description;
|
||||
public final Icon icon;
|
||||
public final int weight;
|
||||
|
||||
public GriffonDirectoryMetadata(String description, Icon icon, int weight) {
|
||||
this.description = description;
|
||||
this.icon = icon;
|
||||
this.weight = weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,10 +504,16 @@ public abstract class MvcFramework {
|
||||
final File grailsWorkDir = getSdkWorkDir(module);
|
||||
if (grailsWorkDir == null) return null;
|
||||
|
||||
final String applicationName = getApplicationName(module);
|
||||
if (applicationName == null) return null;
|
||||
|
||||
return new File(grailsWorkDir, "projects/" + applicationName + "/plugins");
|
||||
}
|
||||
|
||||
public String getApplicationName(Module module) {
|
||||
final VirtualFile root = findAppRoot(module);
|
||||
if (root == null) return null;
|
||||
|
||||
return new File(grailsWorkDir, "projects/" + root.getName() + "/plugins");
|
||||
return root.getName();
|
||||
}
|
||||
|
||||
protected abstract String getCommonPluginSuffix();
|
||||
|
||||
@@ -32,23 +32,22 @@ public abstract class MvcProjectStructure {
|
||||
protected final Module myModule;
|
||||
private final boolean myAuxModule;
|
||||
private final String myUserHomeSdkRoot;
|
||||
private final String mySdkWorkDir;
|
||||
private final String mySdkWorkDirPath;
|
||||
|
||||
public MvcProjectStructure(Module module, boolean auxModule, String userHomeSdkRoot, final File sdkWorkDir) {
|
||||
myAuxModule = auxModule;
|
||||
myModule = module;
|
||||
myUserHomeSdkRoot = userHomeSdkRoot;
|
||||
final VirtualFile sdkWorkDirVFile = MvcModuleStructureUtil.refreshAndFind(sdkWorkDir);
|
||||
mySdkWorkDir = sdkWorkDirVFile == null ? "" : sdkWorkDirVFile.getPath() + "/";
|
||||
mySdkWorkDirPath = sdkWorkDirVFile == null ? "" : sdkWorkDirVFile.getPath() + "/";
|
||||
}
|
||||
|
||||
|
||||
public boolean isValidContentRoot(@NotNull VirtualFile file) {
|
||||
if (file.getPath().startsWith(myUserHomeSdkRoot)) {
|
||||
if (!myAuxModule) {
|
||||
return false;
|
||||
}
|
||||
if (!file.getPath().startsWith(mySdkWorkDir)) {
|
||||
if (!file.getPath().startsWith(mySdkWorkDirPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.mvc.projectView;
|
||||
import com.intellij.ide.projectView.ViewSettings;
|
||||
import com.intellij.ide.projectView.PresentationData;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -41,6 +42,11 @@ public class TopLevelDirectoryNode extends AbstractFolderNode {
|
||||
myIcon = icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return super.equals(object) && Comparing.equal(myTitle, ((TopLevelDirectoryNode) object).myTitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateImpl(PresentationData data) {
|
||||
data.setPresentableText(myTitle);
|
||||
|
||||
Reference in New Issue
Block a user