Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2011-11-17 12:58:59 +04:00
34 changed files with 554 additions and 294 deletions
@@ -0,0 +1,172 @@
/*
* 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 com.intellij.ide.util.importProject;
import com.intellij.ide.util.projectWizard.importSources.DetectedProjectRoot;
import com.intellij.ide.util.projectWizard.importSources.JavaSourceRootDetectionUtil;
import com.intellij.lexer.JavaLexer;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaTokenType;
import com.intellij.util.Consumer;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.text.CharArrayCharSequence;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class JavaModuleInsight extends ModuleInsight {
private final JavaLexer myLexer;
public JavaModuleInsight(@Nullable final ProgressIndicator progress,
Set<String> existingModuleNames,
Set<String> existingProjectLibraryNames) {
super(progress, existingModuleNames, existingProjectLibraryNames);
myLexer = new JavaLexer(LanguageLevel.JDK_1_5);
}
@Override
protected boolean isSourceFile(final File file) {
return StringUtil.endsWithIgnoreCase(file.getName(), ".java");
}
@Override
protected boolean isLibraryFile(final String fileName) {
return StringUtil.endsWithIgnoreCase(fileName, ".jar") || StringUtil.endsWithIgnoreCase(fileName, ".zip");
}
@Override
protected void scanSourceFileForImportedPackages(final char[] chars, final Consumer<String> result) {
myLexer.start(new CharArrayCharSequence(chars));
JavaSourceRootDetectionUtil.skipWhiteSpaceAndComments(myLexer);
if (myLexer.getTokenType() == JavaTokenType.PACKAGE_KEYWORD) {
advanceLexer(myLexer);
if (readPackageName(chars, myLexer) == null) {
return;
}
}
while (true) {
if (myLexer.getTokenType() == JavaTokenType.SEMICOLON) {
advanceLexer(myLexer);
}
if (myLexer.getTokenType() != JavaTokenType.IMPORT_KEYWORD) {
return;
}
advanceLexer(myLexer);
boolean isStaticImport = false;
if (myLexer.getTokenType() == JavaTokenType.STATIC_KEYWORD) {
isStaticImport = true;
advanceLexer(myLexer);
}
final String packageName = readPackageName(chars, myLexer);
if (packageName == null) {
return;
}
if (packageName.endsWith(".*")) {
result.consume(packageName.substring(0, packageName.length() - ".*".length()));
}
else {
int lastDot = packageName.lastIndexOf('.');
if (lastDot > 0) {
String _packageName = packageName.substring(0, lastDot);
if (isStaticImport) {
lastDot = _packageName.lastIndexOf('.');
if (lastDot > 0) {
result.consume(_packageName.substring(0, lastDot));
}
}
else {
result.consume(_packageName);
}
}
}
}
}
@Nullable
private static String readPackageName(final char[] text, final Lexer lexer) {
final StringBuilder buffer = StringBuilderSpinAllocator.alloc();
try {
while (true) {
if (lexer.getTokenType() != JavaTokenType.IDENTIFIER && lexer.getTokenType() != JavaTokenType.ASTERISK) {
break;
}
buffer.append(text, lexer.getTokenStart(), lexer.getTokenEnd() - lexer.getTokenStart());
advanceLexer(lexer);
if (lexer.getTokenType() != JavaTokenType.DOT) {
break;
}
buffer.append('.');
advanceLexer(lexer);
}
String packageName = buffer.toString();
if (packageName.length() == 0 || StringUtil.endsWithChar(packageName, '.') || StringUtil.startsWithChar(packageName, '*')) {
return null;
}
return packageName;
}
finally {
StringBuilderSpinAllocator.dispose(buffer);
}
}
private static void advanceLexer(final Lexer lexer) {
lexer.advance();
JavaSourceRootDetectionUtil.skipWhiteSpaceAndComments(lexer);
}
@Override
protected void scanLibraryForDeclaredPackages(File file, Consumer<String> result) throws IOException {
final ZipFile zip = new ZipFile(file);
try {
final Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
final String entryName = entries.nextElement().getName();
if (StringUtil.endsWithIgnoreCase(entryName, ".class")) {
final int index = entryName.lastIndexOf('/');
if (index > 0) {
final String packageName = entryName.substring(0, index).replace('/', '.');
result.consume(packageName);
}
}
}
}
finally {
zip.close();
}
}
protected ModuleDescriptor createModuleDescriptor(final File moduleContentRoot, final Collection<DetectedProjectRoot> sourceRoots) {
return new ModuleDescriptor(moduleContentRoot, StdModuleTypes.JAVA, sourceRoots);
}
}
@@ -91,7 +91,7 @@ public class LibrariesLayoutPanel extends ProjectLayoutPanel<LibraryDescriptor>{
}
protected String getStepDescriptionText() {
return "Please review libraries found. At this stage you may set library names that will be used in the project,\n" +
return "Please review libraries found. At this stage you can set library names that will be used in the project,\n" +
"exclude particular libraries from the project, or move jar files between the libraries.";
}
}
@@ -16,8 +16,8 @@
package com.intellij.ide.util.importProject;
import com.intellij.ide.highlighter.ModuleFileType;
import com.intellij.ide.util.projectWizard.importSources.JavaModuleSourceRoot;
import com.intellij.ide.util.projectWizard.ModuleBuilder;
import com.intellij.ide.util.projectWizard.importSources.DetectedProjectRoot;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.roots.ModifiableRootModel;
@@ -37,7 +37,7 @@ import java.util.*;
*/
public class ModuleDescriptor {
private String myName;
private final MultiMap<File, JavaModuleSourceRoot> myContentToSourceRoots = new MultiMap<File, JavaModuleSourceRoot>();
private final MultiMap<File, DetectedProjectRoot> myContentToSourceRoots = new MultiMap<File, DetectedProjectRoot>();
private final Set<File> myLibraryFiles = new HashSet<File>();
private final Set<ModuleDescriptor> myDependencies = new HashSet<ModuleDescriptor>();
private static final String[] ourModuleNameStoplist = new String[] {
@@ -47,14 +47,14 @@ public class ModuleDescriptor {
private List<ModuleBuilder.ModuleConfigurationUpdater> myConfigurationUpdaters = new SmartList<ModuleBuilder.ModuleConfigurationUpdater>();
private ModuleType myModuleType;
public ModuleDescriptor(final File contentRoot, final ModuleType moduleType, final Collection<JavaModuleSourceRoot> sourceRoots) {
public ModuleDescriptor(final File contentRoot, final ModuleType moduleType, final Collection<DetectedProjectRoot> sourceRoots) {
myName = suggestModuleName(contentRoot);
myContentToSourceRoots.putValues(contentRoot, sourceRoots);
myModuleType = moduleType;
}
public ModuleDescriptor(final File contentRoot, final ModuleType moduleType,
final JavaModuleSourceRoot sourceRoot) {
final DetectedProjectRoot sourceRoot) {
this(contentRoot, moduleType, Collections.singletonList(sourceRoot));
}
@@ -110,23 +110,23 @@ public class ModuleDescriptor {
return Collections.unmodifiableSet(myContentToSourceRoots.keySet());
}
public Collection<? extends JavaModuleSourceRoot> getSourceRoots() {
public Collection<? extends DetectedProjectRoot> getSourceRoots() {
return myContentToSourceRoots.values();
}
public Collection<JavaModuleSourceRoot> getSourceRoots(File contentRoot) {
public Collection<DetectedProjectRoot> getSourceRoots(File contentRoot) {
return myContentToSourceRoots.get(contentRoot);
}
public void addContentRoot(File contentRoot) {
myContentToSourceRoots.put(contentRoot, new HashSet<JavaModuleSourceRoot>());
myContentToSourceRoots.put(contentRoot, new HashSet<DetectedProjectRoot>());
}
public Collection<JavaModuleSourceRoot> removeContentRoot(File contentRoot) {
public Collection<DetectedProjectRoot> removeContentRoot(File contentRoot) {
return myContentToSourceRoots.remove(contentRoot);
}
public void addSourceRoot(final File contentRoot, JavaModuleSourceRoot sourceRoot) {
public void addSourceRoot(final File contentRoot, DetectedProjectRoot sourceRoot) {
myContentToSourceRoots.putValue(contentRoot, sourceRoot);
}
@@ -156,7 +156,7 @@ public class ModuleDescriptor {
public String toString() {
@NonNls final StringBuilder builder = new StringBuilder();
builder.append("[Module: ").append(getContentRoots()).append(" | ");
for (JavaModuleSourceRoot sourceRoot : getSourceRoots()) {
for (DetectedProjectRoot sourceRoot : getSourceRoots()) {
builder.append(sourceRoot.getDirectory().getName()).append(",");
}
builder.append("]");
@@ -15,48 +15,39 @@
*/
package com.intellij.ide.util.importProject;
import com.intellij.ide.util.projectWizard.importSources.JavaSourceRootDetectionUtil;
import com.intellij.ide.util.projectWizard.importSources.JavaModuleSourceRoot;
import com.intellij.lexer.JavaLexer;
import com.intellij.lexer.Lexer;
import com.intellij.ide.util.projectWizard.importSources.DetectedProjectRoot;
import com.intellij.ide.util.projectWizard.importSources.impl.ProjectFromSourcesBuilderImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.JavaTokenType;
import com.intellij.util.Consumer;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.StringInterner;
import com.intellij.util.text.CharArrayCharSequence;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* @author Eugene Zhuravlev
* Date: Jul 3, 2007
*/
public class ModuleInsight {
public abstract class ModuleInsight {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.importProject.ModuleInsight");
@NotNull private final ProgressIndicatorWrapper myProgress;
private final Set<File> myEntryPointRoots = new HashSet<File>();
private final List<JavaModuleSourceRoot> mySourceRoots = new ArrayList<JavaModuleSourceRoot>();
private final List<DetectedProjectRoot> mySourceRoots = new ArrayList<DetectedProjectRoot>();
private final Set<String> myIgnoredNames = new HashSet<String>();
private final Map<File, Set<String>> mySourceRootToReferencedPackagesMap = new HashMap<File, Set<String>>();
private final Map<File, Set<String>> mySourceRootToPackagesMap = new HashMap<File, Set<String>>();
private final Map<File, Set<String>> myJarToPackagesMap = new HashMap<File, Set<String>>();
private final StringInterner myInterner = new StringInterner();
private final JavaLexer myLexer;
private List<ModuleDescriptor> myModules;
private List<LibraryDescriptor> myLibraries;
@@ -66,12 +57,11 @@ public class ModuleInsight {
public ModuleInsight(@Nullable final ProgressIndicator progress, Set<String> existingModuleNames, Set<String> existingProjectLibraryNames) {
myExistingModuleNames = existingModuleNames;
myExistingProjectLibraryNames = existingProjectLibraryNames;
myLexer = new JavaLexer(LanguageLevel.JDK_1_5);
myProgress = new ProgressIndicatorWrapper(progress);
setRoots(Collections.<File>emptyList(), Collections.<JavaModuleSourceRoot>emptyList(), Collections.<String>emptySet());
setRoots(Collections.<File>emptyList(), Collections.<DetectedProjectRoot>emptyList(), Collections.<String>emptySet());
}
public final void setRoots(final List<File> contentRoots, final List<JavaModuleSourceRoot> sourceRoots, final Set<String> ignoredNames) {
public final void setRoots(final List<File> contentRoots, final List<? extends DetectedProjectRoot> sourceRoots, final Set<String> ignoredNames) {
myModules = null;
myLibraries = null;
@@ -105,8 +95,8 @@ public class ModuleInsight {
try {
myProgress.pushState();
List<JavaModuleSourceRoot> processedRoots = new ArrayList<JavaModuleSourceRoot>();
for (JavaModuleSourceRoot root : mySourceRoots) {
List<DetectedProjectRoot> processedRoots = new ArrayList<DetectedProjectRoot>();
for (DetectedProjectRoot root : mySourceRoots) {
final File sourceRoot = root.getDirectory();
if (myIgnoredNames.contains(sourceRoot.getName())) {
continue;
@@ -119,7 +109,7 @@ public class ModuleInsight {
final HashSet<String> selfPackages = new HashSet<String>();
mySourceRootToPackagesMap.put(sourceRoot, selfPackages);
scanSources(sourceRoot, root.getPackagePrefix(), usedPackages, selfPackages) ;
scanSources(sourceRoot, ProjectFromSourcesBuilderImpl.getPackagePrefix(root), usedPackages, selfPackages) ;
usedPackages.removeAll(selfPackages);
processedRoots.add(root);
}
@@ -127,7 +117,7 @@ public class ModuleInsight {
myProgress.pushState();
myProgress.setText("Building modules layout...");
for (JavaModuleSourceRoot sourceRoot : processedRoots) {
for (DetectedProjectRoot sourceRoot : processedRoots) {
final File srcRoot = sourceRoot.getDirectory();
final File moduleContentRoot = myEntryPointRoots.contains(srcRoot)? srcRoot : srcRoot.getParentFile();
ModuleDescriptor moduleDescriptor = contentRootToModules.get(moduleContentRoot);
@@ -135,7 +125,7 @@ public class ModuleInsight {
moduleDescriptor.addSourceRoot(moduleContentRoot, sourceRoot);
}
else {
moduleDescriptor = new ModuleDescriptor(moduleContentRoot, StdModuleTypes.JAVA, sourceRoot);
moduleDescriptor = createModuleDescriptor(moduleContentRoot, Collections.singletonList(sourceRoot));
contentRootToModules.put(moduleContentRoot, moduleDescriptor);
}
}
@@ -156,6 +146,8 @@ public class ModuleInsight {
}
}
protected abstract ModuleDescriptor createModuleDescriptor(final File moduleContentRoot, Collection<DetectedProjectRoot> sourceRoots);
private void buildModuleDependencies(final Map<File, ModuleDescriptor> contentRootToModules) {
final Set<File> moduleContentRoots = contentRootToModules.keySet();
@@ -170,11 +162,11 @@ public class ModuleInsight {
if (checkedModule.equals(aModule)) {
continue; // avoid self-dependencies
}
final Collection<? extends JavaModuleSourceRoot> aModuleRoots = aModule.getSourceRoots();
final Collection<? extends DetectedProjectRoot> aModuleRoots = aModule.getSourceRoots();
checkModules:
for (JavaModuleSourceRoot srcRoot: checkedModule.getSourceRoots()) {
for (DetectedProjectRoot srcRoot: checkedModule.getSourceRoots()) {
final Set<String> referencedBySourceRoot = mySourceRootToReferencedPackagesMap.get(srcRoot.getDirectory());
for (JavaModuleSourceRoot aSourceRoot : aModuleRoots) {
for (DetectedProjectRoot aSourceRoot : aModuleRoots) {
if (ContainerUtil.intersects(referencedBySourceRoot, mySourceRootToPackagesMap.get(aSourceRoot.getDirectory()))) {
checkedModule.addDependencyOn(aModule);
break checkModules;
@@ -188,7 +180,7 @@ public class ModuleInsight {
private void buildJarDependencies(final ModuleDescriptor module) {
for (File jarFile : myJarToPackagesMap.keySet()) {
final Set<String> jarPackages = myJarToPackagesMap.get(jarFile);
for (JavaModuleSourceRoot srcRoot : module.getSourceRoots()) {
for (DetectedProjectRoot srcRoot : module.getSourceRoots()) {
if (ContainerUtil.intersects(mySourceRootToReferencedPackagesMap.get(srcRoot.getDirectory()), jarPackages)) {
module.addLibraryFile(jarFile);
break;
@@ -238,8 +230,8 @@ public class ModuleInsight {
public void merge(final ModuleDescriptor mainModule, final ModuleDescriptor module) {
for (File contentRoot : module.getContentRoots()) {
final File _contentRoot = appendContentRoot(mainModule, contentRoot);
final Collection<JavaModuleSourceRoot> sources = module.getSourceRoots(contentRoot);
for (JavaModuleSourceRoot source : sources) {
final Collection<DetectedProjectRoot> sources = module.getSourceRoots(contentRoot);
for (DetectedProjectRoot source : sources) {
mainModule.addSourceRoot(_contentRoot, source);
}
}
@@ -279,13 +271,13 @@ public class ModuleInsight {
public ModuleDescriptor splitModule(final ModuleDescriptor descriptor, String newModuleName, final Collection<File> contentsToExtract) {
ModuleDescriptor newModule = null;
for (File root : contentsToExtract) {
final Collection<JavaModuleSourceRoot> sources = descriptor.removeContentRoot(root);
final Collection<DetectedProjectRoot> sources = descriptor.removeContentRoot(root);
if (newModule == null) {
newModule = new ModuleDescriptor(root, StdModuleTypes.JAVA, sources != null ? sources : new HashSet<JavaModuleSourceRoot>());
newModule = createModuleDescriptor(root, sources != null ? sources : new HashSet<DetectedProjectRoot>());
}
else {
if (sources != null && sources.size() > 0) {
for (JavaModuleSourceRoot source : sources) {
for (DetectedProjectRoot source : sources) {
newModule.addSourceRoot(root, source);
}
}
@@ -352,10 +344,10 @@ public class ModuleInsight {
return moduleRoot; // no need to include a separate root
}
if (FileUtil.isAncestor(contentRoot, moduleRoot, true)) {
final Collection<JavaModuleSourceRoot> currentSources = module.getSourceRoots(moduleRoot);
final Collection<DetectedProjectRoot> currentSources = module.getSourceRoots(moduleRoot);
module.removeContentRoot(moduleRoot);
module.addContentRoot(contentRoot);
for (JavaModuleSourceRoot source : currentSources) {
for (DetectedProjectRoot source : currentSources) {
module.addSourceRoot(contentRoot, source);
}
return contentRoot; // no need to include a separate root
@@ -406,9 +398,9 @@ public class ModuleInsight {
scanSources(file, subPackageName, usedPackages, selfPackages);
}
else {
if (StringUtil.endsWithIgnoreCase(file.getName(), ".java")) {
if (isSourceFile(file)) {
includeParentName = true;
scanJavaFile(file, usedPackages);
scanSourceFile(file, usedPackages);
}
}
}
@@ -418,17 +410,25 @@ public class ModuleInsight {
}
}
private void scanJavaFile(File file, final Set<String> usedPackages) {
protected abstract boolean isSourceFile(final File file);
private void scanSourceFile(File file, final Set<String> usedPackages) {
myProgress.setText2(file.getName());
try {
final char[] chars = FileUtil.loadFileText(file);
scanImportStatements(chars, myLexer, usedPackages);
scanSourceFileForImportedPackages(chars, new Consumer<String>() {
public void consume(final String s) {
usedPackages.add(myInterner.intern(s));
}
});
}
catch (IOException e) {
LOG.info(e);
}
}
protected abstract void scanSourceFileForImportedPackages(final char[] chars, Consumer<String> result);
private void scanRootForLibraries(File fromRoot) {
if (myIgnoredNames.contains(fromRoot.getName())) {
return;
@@ -442,137 +442,40 @@ public class ModuleInsight {
}
else {
final String fileName = file.getName();
if (StringUtil.endsWithIgnoreCase(fileName, ".jar") || StringUtil.endsWithIgnoreCase(fileName, ".zip")) {
if (isLibraryFile(fileName)) {
if (!myJarToPackagesMap.containsKey(file)) {
final HashSet<String> libraryPackages = new HashSet<String>();
myJarToPackagesMap.put(file, libraryPackages);
scanLibrary(file, libraryPackages);
}
}
}
}
}
}
private void scanLibrary(File file, Set<String> libraryPackages) {
myProgress.pushState();
myProgress.setText2(file.getName());
try {
final ZipFile zip = new ZipFile(file);
try {
final Enumeration<? extends ZipEntry> entries = zip.entries();
while(entries.hasMoreElements()) {
final String entryName = entries.nextElement().getName();
if (StringUtil.endsWithIgnoreCase(entryName, ".class")) {
final int index = entryName.lastIndexOf('/');
if (index > 0) {
final String packageName = entryName.substring(0, index).replace('/', '.');
if (!libraryPackages.contains(packageName)) {
libraryPackages.add(myInterner.intern(packageName));
myProgress.pushState();
myProgress.setText2(file.getName());
try {
scanLibraryForDeclaredPackages(file, new Consumer<String>() {
public void consume(final String s) {
if (!libraryPackages.contains(s)) {
libraryPackages.add(myInterner.intern(s));
}
}
});
}
catch (IOException e) {
LOG.info(e);
}
catch (InternalError e) { // indicates that file is somehow damaged and cannot be processed
LOG.info(e);
}
finally {
myProgress.popState();
}
}
}
}
}
finally {
zip.close();
}
}
catch (IOException e) {
LOG.info(e);
}
catch (InternalError e) { // indicates that zip file is somehow damaged and cannot be processed
LOG.info(e);
}
finally {
myProgress.popState();
}
}
private void scanImportStatements(char[] text, final Lexer lexer, final Set<String> usedPackages){
lexer.start(new CharArrayCharSequence(text));
protected abstract boolean isLibraryFile(final String fileName);
JavaSourceRootDetectionUtil.skipWhiteSpaceAndComments(lexer);
if (lexer.getTokenType() == JavaTokenType.PACKAGE_KEYWORD) {
advanceLexer(lexer);
if (readPackageName(text, lexer) == null) {
return;
}
}
protected abstract void scanLibraryForDeclaredPackages(File file, Consumer<String> result) throws IOException;
while (true) {
if (lexer.getTokenType() == JavaTokenType.SEMICOLON) {
advanceLexer(lexer);
}
if (lexer.getTokenType() != JavaTokenType.IMPORT_KEYWORD) {
return;
}
advanceLexer(lexer);
boolean isStaticImport = false;
if (lexer.getTokenType() == JavaTokenType.STATIC_KEYWORD) {
isStaticImport = true;
advanceLexer(lexer);
}
final String packageName = readPackageName(text, lexer);
if (packageName == null) {
return;
}
if (packageName.endsWith(".*")) {
usedPackages.add(myInterner.intern(packageName.substring(0, packageName.length() - ".*".length())));
}
else {
int lastDot = packageName.lastIndexOf('.');
if (lastDot > 0) {
String _packageName = packageName.substring(0, lastDot);
if (isStaticImport) {
lastDot = _packageName.lastIndexOf('.');
_packageName = lastDot > 0? _packageName.substring(0, lastDot) : null;
}
if (_packageName != null) {
usedPackages.add(myInterner.intern(_packageName));
}
}
}
}
}
@Nullable
private static String readPackageName(final char[] text, final Lexer lexer) {
final StringBuilder buffer = StringBuilderSpinAllocator.alloc();
try {
while(true){
if (lexer.getTokenType() != JavaTokenType.IDENTIFIER && lexer.getTokenType() != JavaTokenType.ASTERISK) {
break;
}
buffer.append(text, lexer.getTokenStart(), lexer.getTokenEnd() - lexer.getTokenStart());
advanceLexer(lexer);
if (lexer.getTokenType() != JavaTokenType.DOT) {
break;
}
buffer.append('.');
advanceLexer(lexer);
}
String packageName = buffer.toString();
if (packageName.length() == 0 || StringUtil.endsWithChar(packageName, '.') || StringUtil.startsWithChar(packageName, '*') ) {
return null;
}
return packageName;
}
finally {
StringBuilderSpinAllocator.dispose(buffer);
}
}
private static void advanceLexer(final Lexer lexer) {
lexer.advance();
JavaSourceRootDetectionUtil.skipWhiteSpaceAndComments(lexer);
}
}
@@ -107,7 +107,7 @@ public class ModulesLayoutPanel extends ProjectLayoutPanel<ModuleDescriptor>{
}
protected String getStepDescriptionText() {
return "Please review suggested module structure for the project. At this stage you may set module names,\n" +
return "Please review suggested module structure for the project. At this stage you can set module names,\n" +
"exclude particular modules from the project, merge or split individual modules.\n" +
"All dependencies between the modules as well as dependencies on the libraries will be automatically updated.";
}
@@ -16,7 +16,7 @@
package com.intellij.ide.util.importProject;
import com.intellij.ide.util.ElementsChooser;
import com.intellij.ide.util.projectWizard.importSources.JavaModuleSourceRoot;
import com.intellij.ide.util.projectWizard.importSources.DetectedProjectRoot;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.InputValidator;
@@ -263,11 +263,11 @@ abstract class ProjectLayoutPanel<T> extends JPanel {
builder.append(")");
}
final Collection<? extends JavaModuleSourceRoot> sourceRoots = moduleDescriptor.getSourceRoots();
final Collection<? extends DetectedProjectRoot> sourceRoots = moduleDescriptor.getSourceRoots();
if (sourceRoots.size() > 0) {
builder.append(" [");
for (Iterator<? extends JavaModuleSourceRoot> it = sourceRoots.iterator(); it.hasNext();) {
JavaModuleSourceRoot root = it.next();
for (Iterator<? extends DetectedProjectRoot> it = sourceRoots.iterator(); it.hasNext();) {
DetectedProjectRoot root = it.next();
builder.append(root.getDirectory().getName());
if (it.hasNext()) {
builder.append(",");
@@ -77,43 +77,6 @@ public class JavaSourceRootDetectionUtil {
}
@Nullable
public static Pair<File,String> suggestRootForJavaFile(File javaFile, File topmostPossibleRoot, NullableFunction<CharSequence, String> packageNameFetcher) {
if (!javaFile.isFile()) return null;
final CharSequence chars;
try {
chars = new CharArrayCharSequence(FileUtil.loadFileText(javaFile));
}
catch(IOException e){
return null;
}
String packageName = packageNameFetcher.fun(chars);
if (packageName != null) {
File root = javaFile.getParentFile();
int index = packageName.length();
while (index > 0) {
int index1 = packageName.lastIndexOf('.', index - 1);
String token = packageName.substring(index1 + 1, index);
String dirName = root.getName();
final boolean equalsToToken = SystemInfo.isFileSystemCaseSensitive ? dirName.equals(token) : dirName.equalsIgnoreCase(token);
if (!equalsToToken || root.equals(topmostPossibleRoot)) {
return Pair.create(root, packageName.substring(0, index));
}
String parent = root.getParent();
if (parent == null) {
return null;
}
root = new File(parent);
index = index1;
}
return Pair.create(root, "");
}
return null;
}
@Nullable
public static String getPackageName(CharSequence text) {
Lexer lexer = new JavaLexer(LanguageLevel.JDK_1_3);
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.util.projectWizard.importSources;
import com.intellij.ide.util.projectWizard.importSources.util.CommonSourceRootDetectionUtil;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.NullableFunction;
@@ -36,7 +37,8 @@ public abstract class JavaSourceRootDetector extends ProjectStructureDetector {
if (child.isFile()) {
String extension = FileUtil.getExtension(child.getName());
if (extension.equals(fileExtension)) {
Pair<File, String> root = JavaSourceRootDetectionUtil.suggestRootForJavaFile(child, base, getPackageNameFetcher());
Pair<File, String> root = CommonSourceRootDetectionUtil.suggestRootForFileWithPackageStatement(child, base,
getPackageNameFetcher());
if (root != null) {
result.add(new JavaModuleSourceRoot(root.getFirst(), root.getSecond(), getLanguageName()));
return DirectoryProcessingResult.skipChildrenAndParentsUpTo(root.getFirst());
@@ -17,10 +17,7 @@ package com.intellij.ide.util.projectWizard.importSources.impl;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.ide.util.DelegatingProgressIndicator;
import com.intellij.ide.util.importProject.LibrariesDetectionStep;
import com.intellij.ide.util.importProject.ModuleInsight;
import com.intellij.ide.util.importProject.ModulesDetectionStep;
import com.intellij.ide.util.importProject.ProjectDescriptor;
import com.intellij.ide.util.importProject.*;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.ProjectWizardStepFactory;
import com.intellij.ide.util.projectWizard.importSources.JavaSourceRootDetectionUtil;
@@ -55,7 +52,7 @@ public class JavaProjectStructureDetector extends JavaSourceRootDetector {
ProjectDescriptor projectDescriptor,
Icon stepIcon) {
final List<ModuleWizardStep> steps = new ArrayList<ModuleWizardStep>();
final ModuleInsight moduleInsight = new ModuleInsight(new DelegatingProgressIndicator(), builder.getExistingModuleNames(), builder.getExistingProjectLibraryNames());
final ModuleInsight moduleInsight = new JavaModuleInsight(new DelegatingProgressIndicator(), builder.getExistingModuleNames(), builder.getExistingProjectLibraryNames());
steps.add(new LibrariesDetectionStep(this, builder, projectDescriptor, moduleInsight, stepIcon, "reference.dialogs.new.project.fromCode.page1"));
steps.add(new ModulesDetectionStep(this, builder, projectDescriptor, moduleInsight, stepIcon, "reference.dialogs.new.project.fromCode.page2"));
steps.add(ProjectWizardStepFactory.getInstance().createProjectJdkStep(builder.getContext()));
@@ -290,12 +290,12 @@ public class ProjectFromSourcesBuilderImpl extends ProjectBuilder implements Pro
VirtualFile moduleContentRoot = lfs.refreshAndFindFileByPath(FileUtil.toSystemIndependentName(contentRoot.getPath()));
if (moduleContentRoot != null) {
final ContentEntry contentEntry = rootModel.addContentEntry(moduleContentRoot);
final Collection<JavaModuleSourceRoot> sourceRoots = descriptor.getSourceRoots(contentRoot);
for (JavaModuleSourceRoot srcRoot : sourceRoots) {
final Collection<DetectedProjectRoot> sourceRoots = descriptor.getSourceRoots(contentRoot);
for (DetectedProjectRoot srcRoot : sourceRoots) {
final String srcpath = FileUtil.toSystemIndependentName(srcRoot.getDirectory().getPath());
final VirtualFile sourceRoot = lfs.refreshAndFindFileByPath(srcpath);
if (sourceRoot != null) {
contentEntry.addSourceFolder(sourceRoot, shouldBeTestRoot(srcRoot.getDirectory()), srcRoot.getPackagePrefix());
contentEntry.addSourceFolder(sourceRoot, shouldBeTestRoot(srcRoot.getDirectory()), getPackagePrefix(srcRoot));
}
}
}
@@ -321,6 +321,11 @@ public class ProjectFromSourcesBuilderImpl extends ProjectBuilder implements Pro
}
public static String getPackagePrefix(final DetectedProjectRoot srcRoot) {
// TODO we can introduce DetectedProjectRootWithPackagePrefix interface
return srcRoot instanceof JavaModuleSourceRoot ? ((JavaModuleSourceRoot)srcRoot).getPackagePrefix() : "";
}
@NotNull
@Override
public ProjectDescriptor getProjectDescriptor(@NotNull ProjectStructureDetector detector) {
@@ -0,0 +1,71 @@
/*
* 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 com.intellij.ide.util.projectWizard.importSources.util;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.text.CharArrayCharSequence;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
public class CommonSourceRootDetectionUtil {
private CommonSourceRootDetectionUtil() {
}
@Nullable
public static Pair<File,String> suggestRootForFileWithPackageStatement(File file,
File topmostPossibleRoot,
NullableFunction<CharSequence, String> packageNameFetcher) {
if (!file.isFile()) return null;
final CharSequence chars;
try {
chars = new CharArrayCharSequence(FileUtil.loadFileText(file));
}
catch(IOException e){
return null;
}
String packageName = packageNameFetcher.fun(chars);
if (packageName != null) {
File root = file.getParentFile();
int index = packageName.length();
while (index > 0) {
int index1 = packageName.lastIndexOf('.', index - 1);
String token = packageName.substring(index1 + 1, index);
String dirName = root.getName();
final boolean equalsToToken = SystemInfo.isFileSystemCaseSensitive ? dirName.equals(token) : dirName.equalsIgnoreCase(token);
if (!equalsToToken || root.equals(topmostPossibleRoot)) {
return Pair.create(root, packageName.substring(0, index));
}
String parent = root.getParent();
if (parent == null) {
return null;
}
root = new File(parent);
index = index1;
}
return Pair.create(root, "");
}
return null;
}
}
@@ -26,6 +26,9 @@ import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
public final class OpenFileHyperlinkInfo implements FileHyperlinkInfo {
private static final int UNDEFINED_OFFSET = -1;
private final Project myProject;
private final VirtualFile myFile;
private final int myDocumentLine;
@@ -49,7 +52,7 @@ public final class OpenFileHyperlinkInfo implements FileHyperlinkInfo {
public OpenFileDescriptor getDescriptor() {
int offset = calculateOffset(myFile, myDocumentLine, myDocumentColumn);
if (offset != -1) {
if (offset != UNDEFINED_OFFSET) {
return new OpenFileDescriptor(myProject, myFile, offset);
}
// although document position != logical position, it seems better than returning 'null'
@@ -67,6 +70,14 @@ public final class OpenFileHyperlinkInfo implements FileHyperlinkInfo {
});
}
/**
* Calculates an offset, that matches given line and column of the document.
*
* @param file VirtualFile instance
* @param documentLine zero-based line of the document
* @param documentColumn zero-based column of the document
* @return calculated offset or UNDEFINED_OFFSET if it's impossible to calculate
*/
private static int calculateOffset(@NotNull final VirtualFile file,
final int documentLine, final int documentColumn) {
return ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
@@ -83,7 +94,7 @@ public final class OpenFileHyperlinkInfo implements FileHyperlinkInfo {
return lineStartOffset + fixedColumn;
}
}
return -1;
return UNDEFINED_OFFSET;
}
});
}
@@ -18,11 +18,12 @@ package com.intellij.openapi.module;
import com.intellij.openapi.roots.ui.configuration.CommonContentEntriesEditor;
import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationEditorProvider;
import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState;
import com.intellij.openapi.util.Comparing;
public class WebModuleConfigurationEditorProvider implements ModuleConfigurationEditorProvider {
public ModuleConfigurationEditor[] createEditors(final ModuleConfigurationState state) {
Module module = state.getRootModel().getModule();
if (ModuleType.get(module) != WebModuleType.getInstance()) {
if (!Comparing.equal(ModuleType.get(module).getId(), WebModuleTypeBase.WEB_MODULE)) {
return ModuleConfigurationEditor.EMPTY;
}
return new ModuleConfigurationEditor[]{new CommonContentEntriesEditor(module.getName(), state, false, false)};
@@ -675,6 +675,14 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
}
// avoid documents piling up during batch processing
if (FileDocumentManagerImpl.areTooManyDocumentsInTheQueue(myUncommittedDocuments)) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
try {
LOG.error("Too many uncommitted documents for "+myProject + ":\n"+myUncommittedDocuments);
}
finally {
clearUncommitedDocuments();
}
}
commitAllDocuments();
}
}
@@ -22,8 +22,6 @@ import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.event.WindowListener;
/**
* @author Konstantin Bulenkov
*/
@@ -32,7 +30,7 @@ public abstract class DirDiffManager {
return ServiceManager.getService(project, DirDiffManager.class);
}
public abstract void showDiff(@NotNull DiffElement dir1, @NotNull DiffElement dir2, DirDiffSettings settings, Runnable onWindowClose);
public abstract void showDiff(@NotNull DiffElement dir1, @NotNull DiffElement dir2, DirDiffSettings settings, @Nullable Runnable onWindowClose);
public abstract void showDiff(@NotNull DiffElement dir1, @NotNull DiffElement dir2, DirDiffSettings settings);
@@ -103,7 +103,7 @@ public abstract class ToolbarDecorator implements DataProvider, CommonActionsPan
return new ListToolbarDecorator(list).initPositionAndBorder();
}
public static <T> ToolbarDecorator createDecorator(@NotNull TableView<T> table, ElementProducer<T> producer) {
public static <T> ToolbarDecorator createDecorator(@NotNull TableView<T> table, @Nullable ElementProducer<T> producer) {
return new TableToolbarDecorator(table, producer).initPositionAndBorder();
}
@@ -39,7 +39,7 @@
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="button.edit"/>
<text resource-bundle="messages/ApplicationBundle" key="button.edit.dialog"/>
</properties>
</component>
<component id="b8f8f" class="javax.swing.JButton" binding="myRemoveButton">
@@ -22,6 +22,8 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.text.StringTokenizer;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
@@ -63,9 +65,20 @@ public class PathMacroListEditor {
}
});
myPathMacroTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(final ListSelectionEvent e) {
updateButtons();
}
});
fillIgnoredVariables();
}
private void updateButtons() {
myEditButton.setEnabled(myPathMacroTable.getSelectedRowCount() == 1);
myRemoveButton.setEnabled(myPathMacroTable.getSelectedRowCount() > 0);
}
private void fillIgnoredVariables() {
final Collection<String> ignored = PathMacros.getInstance().getIgnoredMacroNames();
myIgnoredVariables.setText(StringUtil.join(ignored, ";"));
@@ -106,6 +119,7 @@ public class PathMacroListEditor {
public void reset() {
myPathMacroTable.reset();
fillIgnoredVariables();
updateButtons();
}
public boolean isModified() {
@@ -78,7 +78,13 @@ public abstract class ResizeToolWindowAction extends AnAction implements DumbAwa
}
Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if (owner == null || !(SwingUtilities.getWindowAncestor(owner) instanceof IdeFrame)) {
if (owner == null) {
setDisabled(e);
return;
}
final Window windowAncestor = SwingUtilities.getWindowAncestor(owner);
if (!(windowAncestor instanceof IdeFrame) || windowAncestor instanceof IdeFrame.Child) {
setDisabled(e);
return;
}
@@ -19,6 +19,8 @@ import com.intellij.CommonBundle;
import com.intellij.ide.GeneralSettings;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.components.impl.stores.IProjectStore;
import com.intellij.openapi.diagnostic.Logger;
@@ -32,10 +34,7 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.FocusCommand;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.*;
import com.intellij.projectImport.ProjectOpenProcessor;
import com.intellij.ui.AppIcon;
import org.jdom.JDOMException;
@@ -119,7 +118,22 @@ public class ProjectUtil {
ProjectOpenProcessor provider = ProjectOpenProcessor.getImportProvider(virtualFile);
if (provider != null) {
return provider.doOpenProject(virtualFile, projectToClose, forceOpenInNewFrame);
final Project project = provider.doOpenProject(virtualFile, projectToClose, forceOpenInNewFrame);
if (project != null) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
if (!project.isDisposed()) {
final ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.PROJECT_VIEW);
if (toolWindow != null) {
toolWindow.activate(null);
}
}
}
}, ModalityState.NON_MODAL);
}
return project;
}
return null;
}
@@ -181,13 +181,27 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
private static final boolean IS_UNDER_TEAMCITY = System.getProperty("bootstrap.testcases") != null;
private static final boolean SHOULD_NOT_PERFORM_ACCESS_CHECK = System.getProperty("should.not.perform.access.check") != null;
private static final boolean IS_UNIT_TESTS = ApplicationManager.getApplication().isUnitTestMode();
private static final Collection<String> additionalRoots = new THashSet<String>();
@TestOnly
public static void allowToAccess(@NotNull String root) { additionalRoots.add(FileUtil.toSystemIndependentName(root)); }
public static void allowToAccess(@NotNull String root) {
additionalRoots.add(FileUtil.toSystemIndependentName(root));
}
@TestOnly
private static void assertAccessInTests(VirtualFileSystemEntry child) {
if (IS_UNIT_TESTS && IS_UNDER_TEAMCITY && ApplicationManager.getApplication() instanceof ApplicationImpl && ((ApplicationImpl)ApplicationManager.getApplication()).isComponentsCreated()) {
if (IS_UNIT_TESTS &&
IS_UNDER_TEAMCITY &&
ApplicationManager.getApplication() instanceof ApplicationImpl &&
((ApplicationImpl)ApplicationManager.getApplication()).isComponentsCreated()
&&
!SHOULD_NOT_PERFORM_ACCESS_CHECK) {
NewVirtualFileSystem fileSystem = child.getFileSystem();
if (fileSystem != LocalFileSystem.getInstance() && fileSystem != JarFileSystem.getInstance()) {
return;
@@ -218,7 +232,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
if (!isUnder) {
if (!allowed.isEmpty()) {
assert false : "File accessed outside allowed roots: " + child +";\n Allowed roots: "+new ArrayList(allowed);
assert false : "File accessed outside allowed roots: " + child + ";\n Allowed roots: " + new ArrayList(allowed);
}
}
}
@@ -271,6 +285,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
}
private static boolean insideGettingRoots;
private static VirtualFile[] getAllRoots(Project project) {
insideGettingRoots = true;
Set<VirtualFile> roots = new THashSet<VirtualFile>();
@@ -366,7 +381,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
for (String name : names) {
findChild(name, false, false, delegate);
}
// important: should return a copy here for safe iterations
return new ArrayList<VirtualFile>(ensureAsMap().values());
}
@@ -378,7 +393,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
return (VirtualFileSystemEntry[])myChildren;
}
Pair<String[],int[]> pair = PersistentFS.listAll(this);
Pair<String[], int[]> pair = PersistentFS.listAll(this);
final int[] childrenIds = pair.second;
VirtualFileSystemEntry[] children;
if (childrenIds.length == 0) {
@@ -417,7 +432,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
if (loaded != null) {
return loaded;
}
String name = ourPersistence.getName(id);
return findChild(name, false, false, getFileSystem());
}
@@ -436,6 +436,7 @@ public final class InternalDecorator extends JPanel implements Queryable, TypeSa
UISettings settings = UISettings.getInstance();
ToolWindowManagerImpl mgr = ((ToolWindowImpl)myWindow).getToolWindowManager();
if (!mgr.isToolWindowRegistered(((ToolWindowImpl)myWindow).getId())) return new Insets(0, 0, 0, 0);
List<String> topIds = mgr.getIdsOn(ToolWindowAnchor.TOP);
boolean topButtons = !settings.HIDE_TOOL_STRIPES && !topIds.isEmpty();
@@ -127,6 +127,10 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
};
private PropertyChangeListener myFocusListener;
public boolean isToolWindowRegistered(String id) {
return myLayout.isToolWindowRegistered(id);
}
private enum KeyState {
waiting, pressed, released, hold
}
@@ -173,7 +173,10 @@ public abstract class WizardPopup extends AbstractPopup implements ActionListene
ScreenUtil.moveRectangleToFitTheScreen(targetBounds);
if (getParent() != null) {
if (getParent().getBounds().intersects(targetBounds)) {
final Rectangle parentBounds = getParent().getBounds();
parentBounds.x += STEP_X_PADDING;
parentBounds.width -= STEP_X_PADDING * 2;
if (parentBounds.intersects(targetBounds)) {
targetBounds.x = getParent().getBounds().x - targetBounds.width - STEP_X_PADDING;
}
}
@@ -505,6 +505,7 @@ title.path.variables=Path Variables
editbox.path.macro.value=Value:
editbox.path.macro.name=Name:
button.edit=&Edit
button.edit.dialog=&Edit...
button.add=&Add...
error.variable.already.exists=Variable with name {0} already exists
column.name=Name
@@ -196,7 +196,7 @@ classpath.add.simple.module.library.action=Jars or directories...
classpath.add.library.action=Library...
classpath.add.module.dependency.action=Module Dependency...
classpath.chooser.title.add.module.dependency=Choose Modules
classpath.chooser.description.add.module.dependency=Select the modules the current module should depend on
classpath.chooser.description.add.module.dependency=Select the modules the current module should depend on:
classpath.title.adding.dependency=Adding dependency
classpath.message.library.already.added=Library ''{0}'' already added to this module
message.no.module.dependency.candidates=Found no modules to depend on
@@ -315,7 +315,7 @@ project.roots.plain.mode.action.text.enabled=Show Module Groups
project.roots.tooltip.library.has.broken.paths=Library ''{0}'' has broken {1, choice, 1#path|2#paths}.
project.roots.error.message.invalid.roots=invalid {0} {1, choice, 1#root|2#roots}
choose.modules.dialog.title=Choose Modules
choose.modules.dialog.description=Library '' {0}'' will be added to the selected modules.
choose.modules.dialog.description=Library ''{0}'' will be added to the selected modules.
project.roots.javadoc.tab.description=Manage external JavaDocs attached to this module. External JavaDoc override JavaDoc annotations you might have in your module.
project.roots.output.compiler.title=Compiler output
project.roots.module.jdk.problem.message=Module SDK is not defined.
@@ -26,7 +26,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
@@ -49,36 +48,30 @@ public class DirDiffManagerImpl extends DirDiffManager {
final DirDiffTableModel model = new DirDiffTableModel(myProject, dir1, dir2, settings);
if (settings.showInFrame) {
DirDiffFrame frame = new DirDiffFrame(myProject, model);
if (onWindowClose != null) {
final JFrame jFrame = frame.getFrame();
jFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
onWindowClose.run();
jFrame.removeWindowListener(this);
}
});
}
setWindowListener(onWindowClose, frame.getFrame());
frame.show();
} else {
DirDiffDialog dirDiffDialog = new DirDiffDialog(myProject, model);
if (myProject == null || myProject.isDefault()) {
dirDiffDialog.setModal(true);
}
if (onWindowClose != null) {
final Window owner = dirDiffDialog.getOwner();
owner.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
onWindowClose.run();
owner.removeWindowListener(this);
}
});
}
setWindowListener(onWindowClose, dirDiffDialog.getOwner());
dirDiffDialog.show();
}
}
private void setWindowListener(final Runnable onWindowClose, final Window window) {
if (onWindowClose != null) {
window.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
onWindowClose.run();
window.removeWindowListener(this);
}
});
}
}
@Override
public void showDiff(@NotNull DiffElement dir1, @NotNull DiffElement dir2, DirDiffSettings settings) {
showDiff(dir1, dir2, settings, null);
@@ -100,7 +93,7 @@ public class DirDiffManagerImpl extends DirDiffManager {
if (obj instanceof VirtualFile) {
final VirtualFile file = (VirtualFile)obj;
return JarFileSystem.PROTOCOL.equalsIgnoreCase(file.getExtension())
? new JarFileDiffElement(file) : new VirtualFileDiffElement(file);
? new JarFileDiffElement(file) : new VirtualFileDiffElement(file);
}
return null;
}
@@ -556,17 +556,18 @@ public class DirDiffTableModel extends AbstractTableModel implements DirDiffMode
private void refreshElementAfterCopyTo(DiffElement newElement, DirDiffElement element) {
if (newElement != null) {
final DTree node = element.getNode();
node.setType(DType.EQUAL);
node.setTarget(newElement);
synchronized (myElements) {
final DTree node = element.getNode();
final int row = myElements.indexOf(element);
if (getSettings().showEqual) {
node.setType(DType.EQUAL);
node.setTarget(newElement);
element.updateSourceFromTarget(newElement);
fireTableRowsUpdated(row, row);
}
else {
removeElement(element);
removeElement(element, false);
}
}
}
@@ -610,40 +611,47 @@ public class DirDiffTableModel extends AbstractTableModel implements DirDiffMode
private void refreshElementAfterCopyFrom(DirDiffElement element, DiffElement newElement) {
if (newElement != null) {
final DTree node = element.getNode();
node.setType(DType.EQUAL);
node.setSource(newElement);
synchronized (myElements) {
final int row = myElements.indexOf(element);
if (getSettings().showEqual) {
node.setType(DType.EQUAL);
node.setSource(newElement);
element.updateTargetFromSource(newElement);
fireTableRowsUpdated(row, row);
}
else {
removeElement(element);
removeElement(element, false);
}
}
}
}
private void removeElement(DirDiffElement element) {
private void removeElement(DirDiffElement element, boolean removeFromTree) {
synchronized (myElements) {
int row = myElements.indexOf(element);
if (row != -1) {
final DTree node = element.getNode();
final DTree parentNode = element.getParentNode();
parentNode.remove(node);
if (removeFromTree) {
final DTree parentNode = element.getParentNode();
parentNode.remove(node);
}
myElements.remove(row);
int start = row;
if (row > 0 && row == myElements.size() && myElements.get(row - 1).isSeparator()) {
final DirDiffElement el = myElements.get(row - 1);
el.getParentNode().remove(el.getNode());
if (removeFromTree) {
el.getParentNode().remove(el.getNode());
}
myElements.remove(row - 1);
start = row - 1;
}
else if (row != myElements.size() && myElements.get(row).isSeparator() && row > 0 && myElements.get(row - 1).isSeparator()) {
final DirDiffElement el = myElements.get(row - 1);
el.getParentNode().remove(el.getNode());
if (removeFromTree) {
el.getParentNode().remove(el.getNode());
}
myElements.remove(row - 1);
start = row - 1;
}
@@ -668,7 +676,7 @@ public class DirDiffTableModel extends AbstractTableModel implements DirDiffMode
else {
synchronized (myElements) {
if (myElements.indexOf(element) != -1) {
removeElement(element);
removeElement(element, true);
}
}
}
@@ -685,7 +693,7 @@ public class DirDiffTableModel extends AbstractTableModel implements DirDiffMode
else {
synchronized (myElements) {
if (myElements.indexOf(element) != -1) {
removeElement(element);
removeElement(element, true);
}
}
final AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass());
@@ -206,6 +206,10 @@ public abstract class ChangesTreeList<T> extends JPanel {
setShowFlatten(PropertiesComponent.getInstance(myProject).isTrueValue(FLATTEN_OPTION_KEY));
String emptyText = StringUtil.capitalize(DiffBundle.message("diff.count.differences.status.text", 0));
setEmptyText(emptyText);
}
public void setEmptyText(@NotNull String emptyText) {
myTree.getEmptyText().setText(emptyText);
myList.getEmptyText().setText(emptyText);
}
@@ -16,12 +16,10 @@
package git4idea.push;
import git4idea.GitBranch;
import git4idea.history.browser.GitCommit;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.*;
/**
* Holds Git commits made in a single repository grouped by branches.
@@ -75,4 +73,12 @@ final class GitCommitsByBranch {
return new GitCommitsByBranch(res);
}
@NotNull
public Collection<GitCommit> getAllCommits() {
Collection<GitCommit> commits = new ArrayList<GitCommit>();
for (GitPushBranchInfo branchInfo : myCommitsByBranch.values()) {
commits.addAll(branchInfo.getCommits());
}
return commits;
}
}
@@ -16,13 +16,11 @@
package git4idea.push;
import git4idea.GitBranch;
import git4idea.history.browser.GitCommit;
import git4idea.repo.GitRepository;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.*;
/**
* Holds Git commits grouped by repositories and by branches.
@@ -83,5 +81,14 @@ final class GitCommitsByRepoAndBranch {
return new GitCommitsByRepoAndBranch(commits);
}
@NotNull
public Collection<GitCommit> getAllCommits() {
Collection<GitCommit> commits = new ArrayList<GitCommit>();
for (GitCommitsByBranch commitsByBranch : myCommitsByRepository.values()) {
commits.addAll(commitsByBranch.getAllCommits());
}
return commits;
}
}
@@ -26,10 +26,13 @@ import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ui.ChangesBrowser;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import git4idea.GitBranch;
import git4idea.GitUtil;
@@ -43,6 +46,7 @@ import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;
import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -61,14 +65,18 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider {
private final DefaultTreeModel myTreeModel;
private final CheckedTreeNode myRootNode;
private final ReentrantReadWriteLock TREE_CONSTRUCTION_LOCK = new ReentrantReadWriteLock();
private final MyTreeCellRenderer myTreeCellRenderer;
GitPushLog(@NotNull Project project, @NotNull Collection<GitRepository> repositories, @NotNull final Consumer<Boolean> checkboxListener) {
myProject = project;
myAllRepositories = repositories;
myRootNode = new CheckedTreeNode(null);
myRootNode.add(new DefaultMutableTreeNode(new FakeCommit()));
myTreeModel = new DefaultTreeModel(myRootNode);
myTree = new CheckboxTree(new MyTreeCellRenderer(), myRootNode) {
myTreeCellRenderer = new MyTreeCellRenderer();
myTree = new CheckboxTree(myTreeCellRenderer, myRootNode) {
@Override
protected void onNodeStateChanged(CheckedTreeNode node) {
Object userObject = node.getUserObject();
@@ -93,10 +101,12 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider {
if (node != null) {
Object nodeInfo = node.getUserObject();
if (nodeInfo instanceof GitCommit) {
myChangesBrowser.getViewer().setEmptyText("No differences");
myChangesBrowser.setChangesToDisplay(((GitCommit)nodeInfo).getChanges());
return;
}
}
setDefaultEmptyText();
myChangesBrowser.setChangesToDisplay(Collections.<Change>emptyList());
}
});
@@ -104,6 +114,7 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider {
myChangesBrowser = new ChangesBrowser(project, null, Collections.<Change>emptyList(), null, false, true, null, ChangesBrowser.MyUseCase.LOCAL_CHANGES, null);
myChangesBrowser.getDiffAction().registerCustomShortcutSet(CommonShortcuts.getDiff(), myTree);
setDefaultEmptyText();
Splitter splitter = new Splitter(false, 0.7f);
splitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myTree));
@@ -113,6 +124,10 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider {
add(splitter);
}
private void setDefaultEmptyText() {
myChangesBrowser.getViewer().setEmptyText("No commits selected");
}
// Make changes available for diff action
@Override
public void calcData(DataKey key, DataSink sink) {
@@ -140,6 +155,7 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider {
createNodes(commits);
myTreeModel.nodeStructureChanged(myRootNode);
myTree.setModel(myTreeModel); // TODO: why doesn't it repaint otherwise?
myTreeCellRenderer.recalculateWidth(commits.getAllCommits());
TreeUtil.expandAll(myTree);
selectFirstCommit();
}
@@ -243,6 +259,21 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider {
}
private static class MyTreeCellRenderer extends CheckboxTree.CheckboxTreeCellRenderer {
private int myDateMaxWidth;
void recalculateWidth(@NotNull Collection<GitCommit> commits) {
for (GitCommit commit : commits) {
int len = getDateString(commit).length();
if (len > myDateMaxWidth) {
myDateMaxWidth = len;
}
}
}
private static String getDateString(GitCommit commit) {
return DateFormatUtil.formatPrettyDateTime(commit.getAuthorTime());
}
@Override
public void customizeRenderer(final JTree tree, final Object value, final boolean selected, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) {
@@ -262,13 +293,14 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider {
if (userObject instanceof GitCommit) {
GitCommit commit = (GitCommit)userObject;
SimpleTextAttributes small = new SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, renderer.getForeground());
renderer.append(commit.getShortHash().toString(), small);
renderer.append(String.format("%15s ", DateFormatUtil.formatPrettyDateTime(commit.getAuthorTime())), small);
SimpleTextAttributes smallGrey = new SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, UIUtil.getInactiveTextColor());
renderer.append(commit.getShortHash().toString(), smallGrey);
renderer.append(String.format(" %" + myDateMaxWidth + "s ", getDateString(commit)), smallGrey);
renderer.append(commit.getSubject(), small);
}
else if (userObject instanceof GitRepository) {
renderer.append(((GitRepository)userObject).getPresentableUrl());
String repositoryPath = calcRootPath((GitRepository)userObject);
renderer.append(repositoryPath, SimpleTextAttributes.GRAY_ATTRIBUTES);
}
else if (userObject instanceof GitBranchPair) {
GitBranchPair branchPair = (GitBranchPair) userObject;
@@ -276,13 +308,35 @@ class GitPushLog extends JPanel implements TypeSafeDataProvider {
GitBranch dest = branchPair.getDest();
assert dest != null : "Destination branch can't be null for branch " + fromBranch;
SimpleTextAttributes attrs = fromBranch.isActive() ? SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES;
renderer.append(fromBranch.getName() + " -> " + dest.getName(), attrs);
renderer.append(fromBranch.getName() + " -> " + dest.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
else if (userObject instanceof FakeCommit) {
int spaces = 6 + 15 + 3 + 30;
String s = String.format("%" + spaces + "s", " ");
renderer.append(s, new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, renderer.getBackground()));
}
else {
renderer.append(userObject == null ? "" : userObject.toString());
}
}
@NotNull
private static String calcRootPath(@NotNull GitRepository repository) {
VirtualFile projectDir = repository.getProject().getBaseDir();
String repositoryPath = repository.getPresentableUrl();
if (projectDir != null) {
String relativePath = VfsUtilCore.getRelativePath(repository.getRoot(), projectDir, File.separatorChar);
if (relativePath != null) {
repositoryPath = relativePath;
}
}
return repositoryPath.isEmpty() ? "<Project>" : "." + File.separator + repositoryPath;
}
}
private static class FakeCommit {
}
}
@@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.mvc;
import com.intellij.ide.util.importProject.ModuleDescriptor;
import com.intellij.ide.util.importProject.ProjectDescriptor;
import com.intellij.ide.util.projectWizard.importSources.DetectedProjectRoot;
import com.intellij.ide.util.projectWizard.importSources.JavaModuleSourceRoot;
import com.intellij.ide.util.projectWizard.importSources.ProjectFromSourcesBuilder;
import com.intellij.openapi.module.StdModuleTypes;
@@ -53,7 +52,7 @@ public class GroovySdkForProjectFromSourcesStep extends GroovySdkWizardStepBase
super.updateDataModel();
List<ModuleDescriptor> modules = new ArrayList<ModuleDescriptor>();
for (DetectedProjectRoot root : myBuilder.getProjectRoots(myDetector)) {
final ModuleDescriptor descriptor = new ModuleDescriptor(root.getDirectory(), StdModuleTypes.JAVA, Collections.<JavaModuleSourceRoot>emptyList());
final ModuleDescriptor descriptor = new ModuleDescriptor(root.getDirectory(), StdModuleTypes.JAVA, Collections.<DetectedProjectRoot>emptyList());
descriptor.addConfigurationUpdater(createModuleConfigurationUpdater());
modules.add(descriptor);
}