blob: 2db93f05467aace60d217cd0eefc61cdf296bbff [file] [log] [blame]
/*
* 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.roots.ProjectRootManager;
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<Object> dependencies = ContainerUtil.newArrayList();
dependencies.add(ProjectRootManager.getInstance(module.getProject()));
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);
}
}