Merge remote branch 'origin/master'

This commit is contained in:
Dmitry Jemerov
2012-01-30 17:03:34 +01:00
103 changed files with 1501 additions and 500 deletions
+14 -7
View File
@@ -5,14 +5,21 @@
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-1.0.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-cglib-1.0.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/easymockclassextension.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-junit4-2.3.0-RC2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-2.3.0-RC2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/objenesis-1.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/mockobjects-core-0.09.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-library-1.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-api-1.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/mockobjects-core-0.09.jar!/ " />
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-core-1.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-library-1.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-2.5.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-junit4-2.5.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-legacy-2.5.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
<JAVADOC/>
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-core-1.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/hamcrest-library-1.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-2.5.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-junit4-2.5.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-legacy-2.5.1.jar!/" />
</SOURCES>
</library>
</component>
@@ -695,13 +695,13 @@ public class CompileServerManager implements ApplicationComponent{
@Override
public void sessionTerminated() {
String statusMessage = "Auto make completed";
String statusMessage = null/*"Auto make completed"*/;
switch (myBuildStatus) {
case SUCCESS:
statusMessage = "Auto make completed successfully";
//statusMessage = "Auto make completed successfully";
break;
case UP_TO_DATE:
statusMessage = "All files are up-to-date";
//statusMessage = "All files are up-to-date";
break;
case ERRORS:
statusMessage = "Auto make completed with errors";
@@ -710,9 +710,11 @@ public class CompileServerManager implements ApplicationComponent{
statusMessage = "Auto make has been canceled";
break;
}
final Notification notification = CompilerManager.NOTIFICATION_GROUP.createNotification(statusMessage, MessageType.INFO);
if (!myProject.isDisposed()) {
notification.notify(myProject);
if (statusMessage != null) {
final Notification notification = CompilerManager.NOTIFICATION_GROUP.createNotification(statusMessage, MessageType.INFO);
if (!myProject.isDisposed()) {
notification.notify(myProject);
}
}
}
@@ -73,22 +73,20 @@ public class DebuggerManagerThreadImpl extends InvokeAndWaitThread<DebuggerComma
}
}
public void pushBack(DebuggerCommandImpl managerCommand) {
if(myEvents.isClosed()) {
public boolean pushBack(DebuggerCommandImpl managerCommand) {
final boolean pushed = super.pushBack(managerCommand);
if (!pushed) {
managerCommand.notifyCancelled();
}
else {
super.pushBack(managerCommand);
}
return pushed;
}
public void schedule(DebuggerCommandImpl managerCommand) {
if(myEvents.isClosed()) {
public boolean schedule(DebuggerCommandImpl managerCommand) {
final boolean scheduled = super.schedule(managerCommand);
if (!scheduled) {
managerCommand.notifyCancelled();
}
else {
super.schedule(managerCommand);
}
return scheduled;
}
/**
@@ -45,36 +45,42 @@ public class EventQueue<E> {
}
}
public void pushBack(@NotNull E event, int priority) {
public boolean pushBack(@NotNull E event, int priority) {
if(LOG.isDebugEnabled()) {
LOG.debug("pushBack event " + event);
}
myLock.lock();
try {
assertOpen();
if (isClosed()) {
return false;
}
getEventsList(priority).addFirst(event);
myEventsAvailable.signalAll();
}
finally {
myLock.unlock();
}
return true;
}
public void put(@NotNull E event, int priority) {
public boolean put(@NotNull E event, int priority) {
if(LOG.isDebugEnabled()) {
LOG.debug("put event " + event);
}
myLock.lock();
try {
assertOpen();
if (isClosed()) {
return false;
}
getEventsList(priority).offer(event);
myEventsAvailable.signalAll();
}
finally {
myLock.unlock();
}
return true;
}
private LinkedList<E> getEventsList(final int priority) {
@@ -84,7 +90,6 @@ public class EventQueue<E> {
public void close(){
myLock.lock();
try {
assertOpen();
myIsClosed = true;
myEventsAvailable.signalAll();
}
@@ -93,10 +98,6 @@ public class EventQueue<E> {
}
}
private void assertOpen() {
if (myIsClosed) throw new AssertionError("Already closed");
}
private E getEvent() throws EventQueueClosedException {
myLock.lock();
try {
@@ -19,4 +19,8 @@ package com.intellij.debugger.impl;
* @author lex
*/
public class EventQueueClosedException extends Exception {
@Override
public Throwable fillInStackTrace() {
return this;
}
}
@@ -28,12 +28,12 @@ public abstract class InvokeAndWaitThread<E extends DebuggerTask> extends Invoke
* !!! Do not remove this code !!!
* Otherwise it will be impossible to override schedule method
*/
public void schedule(E e) {
super.schedule(e);
public boolean schedule(E e) {
return super.schedule(e);
}
public void pushBack(E e) {
super.pushBack(e);
public boolean pushBack(E e) {
return super.pushBack(e);
}
public void invokeAndWait(final E runnable) {
@@ -172,18 +172,18 @@ public abstract class InvokeThread<E extends PrioritizedTask> {
return request != null? request.getOwner() : null;
}
public void schedule(E r) {
public boolean schedule(E r) {
if(LOG.isDebugEnabled()) {
LOG.debug("schedule " + r + " in " + this);
}
myEvents.put(r, r.getPriority().ordinal());
return myEvents.put(r, r.getPriority().ordinal());
}
public void pushBack(E r) {
public boolean pushBack(E r) {
if(LOG.isDebugEnabled()) {
LOG.debug("pushBack " + r + " in " + this);
}
myEvents.pushBack(r, r.getPriority().ordinal());
return myEvents.pushBack(r, r.getPriority().ordinal());
}
protected void switchToRequest(WorkerThreadRequest newWorkerThread) {
@@ -24,6 +24,7 @@ import com.intellij.execution.junit.RefactoringListeners;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.util.JavaParametersUtil;
import com.intellij.execution.util.ProgramParametersUtil;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
@@ -31,7 +32,6 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.options.SettingsEditorGroup;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
@@ -138,19 +138,13 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
}
public void checkConfiguration() throws RuntimeConfigurationException {
if (ALTERNATIVE_JRE_PATH_ENABLED){
if (ALTERNATIVE_JRE_PATH == null ||
ALTERNATIVE_JRE_PATH.length() == 0 ||
!JavaSdkImpl.checkForJre(ALTERNATIVE_JRE_PATH)){
throw new RuntimeConfigurationWarning(ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", ALTERNATIVE_JRE_PATH));
}
}
JavaParametersUtil.checkAlternativeJRE(this);
final JavaRunConfigurationModule configurationModule = getConfigurationModule();
final PsiClass psiClass = configurationModule.checkModuleAndClassName(MAIN_CLASS_NAME, ExecutionBundle.message("no.main.class.specified.error.text"));
if (!PsiMethodUtil.hasMainMethod(psiClass)) {
throw new RuntimeConfigurationWarning(ExecutionBundle.message("main.method.not.found.in.class.error.message", MAIN_CLASS_NAME));
}
ProgramParametersUtil.checkWorkingDirectoryExist(this, getProject(), configurationModule.getModule());
JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this);
}
@@ -17,9 +17,11 @@ package com.intellij.execution.util;
import com.intellij.execution.CantRunException;
import com.intellij.execution.CommonJavaRunConfigurationParameters;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.execution.configurations.RunConfigurationModule;
import com.intellij.execution.configurations.RuntimeConfigurationWarning;
import com.intellij.execution.configurations.SimpleJavaParameters;
import com.intellij.execution.junit.JUnitUtil;
import com.intellij.openapi.module.Module;
@@ -122,4 +124,15 @@ public class JavaParametersUtil {
if (jdk == null) throw CantRunException.noJdkConfigured();
return jdk;
}
public static void checkAlternativeJRE(CommonJavaRunConfigurationParameters configuration) throws RuntimeConfigurationWarning {
if (configuration.isAlternativeJrePathEnabled()) {
if (configuration.getAlternativeJrePath() == null ||
configuration.getAlternativeJrePath().length() == 0 ||
!JavaSdk.checkForJre(configuration.getAlternativeJrePath())) {
throw new RuntimeConfigurationWarning(
ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", configuration.getAlternativeJrePath()));
}
}
}
}
@@ -39,8 +39,12 @@ public class ProjectJdksEditor extends DialogWrapper {
public ProjectJdksEditor(final Sdk jdk, Project project, Component parent) {
this(jdk, parent, new ProjectJdksConfigurable(project));
}
public ProjectJdksEditor(final Sdk jdk, Component parent, ProjectJdksConfigurable configurable) {
super(parent, true);
myConfigurable = new ProjectJdksConfigurable(project);
myConfigurable = configurable;
SwingUtilities.invokeLater(new Runnable(){
public void run() {
myConfigurable.selectNodeInTree(jdk != null ? jdk.getName() : null);
@@ -18,7 +18,6 @@ package com.intellij.openapi.roots.ui.configuration;
import com.intellij.ide.DataManager;
import com.intellij.ide.util.projectWizard.ProjectJdkListRenderer;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.projectRoots.Sdk;
@@ -47,8 +46,7 @@ import java.util.Comparator;
* @author Eugene Zhuravlev
* @since May 18, 2005
*/
class JdkComboBox extends ComboBoxWithWidePopup {
private final JButton myEditButton = new JButton(ApplicationBundle.message("button.edit"));
public class JdkComboBox extends ComboBoxWithWidePopup {
public JdkComboBox(@NotNull final ProjectSdksModel jdkModel) {
super(new JdkComboBoxModel(jdkModel));
@@ -101,17 +99,22 @@ class JdkComboBox extends ComboBoxWithWidePopup {
return minSize;
}
public JButton createSetupButton(final Project project, final ProjectSdksModel jdksModel, final JdkComboBoxItem firstItem) {
return createSetupButton(project, jdksModel, firstItem, null, false);
public void setSetupButton(final JButton setUpButton,
final Project project,
final ProjectSdksModel jdksModel,
final JdkComboBoxItem firstItem,
@Nullable final Condition<Sdk> additionalSetup,
final boolean moduleJdkSetup) {
setSetupButton(setUpButton, project, jdksModel, firstItem, additionalSetup,
ProjectBundle.message("project.roots.set.up.jdk.title", moduleJdkSetup ? 1 : 2));
}
public JButton createSetupButton(final Project project,
final ProjectSdksModel jdksModel,
final JdkComboBoxItem firstItem,
@Nullable final Condition<Sdk> additionalSetup,
final boolean moduleJdkSetup) {
final JButton setUpButton = new JButton(ApplicationBundle.message("button.new"));
public void setSetupButton(final JButton setUpButton,
final Project project,
final ProjectSdksModel jdksModel,
final JdkComboBoxItem firstItem,
@Nullable final Condition<Sdk> additionalSetup,
final String actionGroupTitle) {
setUpButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final JdkListConfigurable configurable = JdkListConfigurable.getInstance(project);
@@ -129,16 +132,16 @@ class JdkComboBox extends ComboBoxWithWidePopup {
}
});
JBPopupFactory.getInstance()
.createActionGroupPopup(ProjectBundle.message("project.roots.set.up.jdk.title", moduleJdkSetup ? 1 : 2), group,
DataManager.getInstance().getDataContext(JdkComboBox.this), JBPopupFactory.ActionSelectionAid.MNEMONICS, false)
.createActionGroupPopup(actionGroupTitle, group,
DataManager.getInstance().getDataContext(JdkComboBox.this), JBPopupFactory.ActionSelectionAid.MNEMONICS,
false)
.showUnderneathOf(setUpButton);
}
});
return setUpButton;
}
public void appendEditButton(final Project project, final JPanel panel, GridBagConstraints gc, final Computable<Sdk> retrieveJDK){
myEditButton.addActionListener(new ActionListener() {
public void setEditButton(final JButton editButton, final Project project, final Computable<Sdk> retrieveJDK){
editButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final Sdk projectJdk = retrieveJDK.compute();
if (projectJdk != null) {
@@ -146,17 +149,17 @@ class JdkComboBox extends ComboBoxWithWidePopup {
}
}
});
addActionListener(new ActionListener(){
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final JdkComboBoxItem selectedItem = getSelectedItem();
if (selectedItem instanceof ProjectJdkComboBoxItem) {
myEditButton.setEnabled(ProjectStructureConfigurable.getInstance(project).getProjectJdksModel().getProjectSdk() != null);
} else {
myEditButton.setEnabled(!(selectedItem instanceof InvalidJdkComboBoxItem) && selectedItem != null && selectedItem.getJdk() != null);
editButton.setEnabled(ProjectStructureConfigurable.getInstance(project).getProjectJdksModel().getProjectSdk() != null);
}
else {
editButton.setEnabled(!(selectedItem instanceof InvalidJdkComboBoxItem) && selectedItem != null && selectedItem.getJdk() != null);
}
}
});
panel.add(myEditButton, gc);
}
public JdkComboBoxItem getSelectedItem() {
@@ -260,6 +263,11 @@ class JdkComboBox extends ComboBoxWithWidePopup {
return myJdk;
}
@Nullable
public String getSdkName() {
return myJdk != null ? myJdk.getName() : null;
}
public String toString() {
return myJdk.getName();
}
@@ -286,15 +294,19 @@ class JdkComboBox extends ComboBoxWithWidePopup {
}
private static class InvalidJdkComboBoxItem extends JdkComboBoxItem {
private final String myName;
private final String mySdkName;
public InvalidJdkComboBoxItem(String name) {
super(null);
myName = ProjectBundle.message("jdk.combo.box.invalid.item", name);
mySdkName = name;
}
public String getSdkName() {
return mySdkName;
}
public String toString() {
return myName;
return ProjectBundle.message("jdk.combo.box.invalid.item", mySdkName);
}
}
}
@@ -17,6 +17,7 @@
package com.intellij.openapi.roots.ui.configuration;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
@@ -119,17 +120,18 @@ public abstract class ModuleJdkConfigurable implements Disposable {
GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(6, 6, 12, 0), 0, 0));
final Project project = getRootModel().getModule().getProject();
final JButton setUpButton = myCbModuleJdk
.createSetupButton(project, myJdksModel, new JdkComboBox.ProjectJdkComboBoxItem(), new Condition<Sdk>(){
final JButton setUpButton = new JButton(ApplicationBundle.message("button.new"));
myCbModuleJdk
.setSetupButton(setUpButton, project, myJdksModel, new JdkComboBox.ProjectJdkComboBoxItem(), new Condition<Sdk>() {
public boolean value(Sdk jdk) {
final Sdk projectJdk = myJdksModel.getProjectSdk();
if (projectJdk == null){
if (projectJdk == null) {
final int res =
Messages.showYesNoDialog(myJdkPanel,
ProjectBundle.message("project.roots.no.jdk.on.project.message"),
ProjectBundle.message("project.roots.no.jdk.on.projecct.title"),
ProjectBundle.message("project.roots.no.jdk.on.project.title"),
Messages.getInformationIcon());
if (res == DialogWrapper.OK_EXIT_CODE){
if (res == DialogWrapper.OK_EXIT_CODE) {
myJdksModel.setProjectSdk(jdk);
return true;
}
@@ -140,12 +142,16 @@ public abstract class ModuleJdkConfigurable implements Disposable {
myJdkPanel.add(setUpButton, new GridBagConstraints(2, 0, 1, 1, 0, 0,
GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 4, 7, 0), 0, 0));
myCbModuleJdk.appendEditButton(getRootModel().getModule().getProject(), myJdkPanel, new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 1.0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 7, 0), 0, 0) , new Computable<Sdk>() {
final JButton editButton = new JButton(ApplicationBundle.message("button.edit"));
myCbModuleJdk.setEditButton(editButton, getRootModel().getModule().getProject(), new Computable<Sdk>() {
@Nullable
public Sdk compute() {
return getRootModel().getSdk();
}
});
myJdkPanel.add(editButton,
new GridBagConstraints(GridBagConstraints.RELATIVE, 0, 1, 1, 1.0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE,
new Insets(0, 4, 7, 0), 0, 0));
}
private void clearCaches() {
@@ -16,6 +16,7 @@
package com.intellij.openapi.roots.ui.configuration;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.project.Project;
@@ -90,14 +91,19 @@ public class ProjectJdkConfigurable implements UnnamedConfigurable {
});
myJdkPanel.add(new JLabel(ProjectBundle.message("module.libraries.target.jdk.project.radio")), new GridBagConstraints(0, 0, 3, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 4, 0), 0, 0));
myJdkPanel.add(myCbProjectJdk, new GridBagConstraints(0, 1, 1, 1, 0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0));
final JButton setUpButton = myCbProjectJdk.createSetupButton(myProject, myJdksModel, new JdkComboBox.NoneJdkComboBoxItem());
final JButton setUpButton = new JButton(ApplicationBundle.message("button.new"));
myCbProjectJdk.setSetupButton(setUpButton, myProject, myJdksModel, new JdkComboBox.NoneJdkComboBoxItem(), null, false);
myJdkPanel.add(setUpButton, new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0));
myCbProjectJdk.appendEditButton(myProject, myJdkPanel, new GridBagConstraints(GridBagConstraints.RELATIVE, 1, 1, 1, 1.0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0), new Computable<Sdk>() {
final JButton editButton = new JButton(ApplicationBundle.message("button.edit"));
myCbProjectJdk.setEditButton(editButton, myProject, new Computable<Sdk>() {
@Nullable
public Sdk compute() {
return myJdksModel.getProjectSdk();
}
});
myJdkPanel.add(editButton, new GridBagConstraints(GridBagConstraints.RELATIVE, 1, 1, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0));
}
return myJdkPanel;
}
@@ -57,13 +57,16 @@ public class ProjectJdksConfigurable extends MasterDetailsComponent {
private final ProjectSdksModel myProjectJdksModel;
private final Project myProject;
@NonNls
@NonNls
private static final String SPLITTER_PROPORTION = "project.jdk.splitter";
public ProjectJdksConfigurable(Project project) {
super();
this(project, ProjectStructureConfigurable.getInstance(project).getProjectJdksModel());
}
public ProjectJdksConfigurable(Project project, ProjectSdksModel sdksModel) {
myProject = project;
myProjectJdksModel = ProjectStructureConfigurable.getInstance(project).getProjectJdksModel();
myProjectJdksModel = sdksModel;
initTree();
}
@@ -186,7 +186,7 @@ public abstract class ImportClassFixBase<T extends PsiElement & PsiReference> im
&& (JspPsiUtil.isInJspFile(psiFile) ?
CodeInsightSettings.getInstance().JSP_ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY :
CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY)
&& codeAnalyzer.canChangeFileSilently(psiFile)
&& (ApplicationManager.getApplication().isUnitTestMode() || codeAnalyzer.canChangeFileSilently(psiFile))
&& !autoImportWillInsertUnexpectedCharacters(classes[0])
) {
CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
@@ -43,6 +43,7 @@ import java.util.List;
*/
public class JavaAnonymousClassesNodeProvider implements FileStructureNodeProvider<JavaAnonymousClassTreeElement>, PropertyOwner {
public static final String ID = "SHOW_ANONYMOUS";
public static final String JAVA_ANONYMOUS_PROPERTY_NAME = "java.anonymous.provider";
@Override
public Collection<JavaAnonymousClassTreeElement> provideNodes(TreeElement node) {
@@ -87,6 +88,6 @@ public class JavaAnonymousClassesNodeProvider implements FileStructureNodeProvid
@NotNull
@Override
public String getPropertyName() {
return "java.anonymous.provider";
return JAVA_ANONYMOUS_PROPERTY_NAME;
}
}
@@ -68,7 +68,9 @@ public class JavaCodeBlockModificationListener implements PsiTreeChangePreproces
private void processChange(final PsiElement parent, final PsiElement child1, final PsiElement child2) {
try {
if (!isInsideCodeBlock(parent)) {
if (parent != null && isClassOwner(parent.getContainingFile()) || isClassOwner(child1) || isClassOwner(child2) || isSourceDir(parent)) {
if (parent != null && isClassOwner(parent.getContainingFile()) ||
isClassOwner(child1) || isClassOwner(child2) || isSourceDir(parent) ||
(parent != null && isClassOwner(parent.getParent()))) {
myModificationTracker.incCounter();
}
else {
@@ -17,7 +17,10 @@ package com.intellij.refactoring.memberPullUp;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.statistics.StatisticsInfo;
import com.intellij.psi.statistics.StatisticsManager;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.RefactoringBundle;
@@ -57,6 +60,7 @@ public class PullUpDialog extends RefactoringDialog {
private List<MemberInfo> myMemberInfos;
private DocCommentPanel myJavaDocPanel;
private JComboBox myClassCombo;
private static final String PULL_UP_STATISTICS_KEY = "pull.up##";
public interface Callback {
boolean checkConflicts(PullUpDialog dialog);
@@ -127,11 +131,10 @@ public class PullUpDialog extends RefactoringDialog {
myClassCombo.setRenderer(new ClassCellRenderer(myClassCombo.getRenderer()));
classComboLabel.setText(RefactoringBundle.message("pull.up.members.to", UsageViewUtil.getLongName(myClass)));
classComboLabel.setLabelFor(myClassCombo);
PsiClass nearestBase = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false);
final PsiClass preselection = getPreselection();
int indexToSelect = 0;
if (nearestBase != null) {
indexToSelect = mySuperClasses.indexOf(nearestBase);
if (preselection != null) {
indexToSelect = mySuperClasses.indexOf(preselection);
}
myClassCombo.setSelectedIndex(indexToSelect);
myClassCombo.addItemListener(new ItemListener() {
@@ -152,6 +155,27 @@ public class PullUpDialog extends RefactoringDialog {
return panel;
}
private PsiClass getPreselection() {
PsiClass preselection = RefactoringHierarchyUtil.getNearestBaseClass(myClass, false);
final String statKey = PULL_UP_STATISTICS_KEY + myClass.getQualifiedName();
for (StatisticsInfo info : StatisticsManager.getInstance().getAllValues(statKey)) {
final String superClassName = info.getValue();
PsiClass superClass = null;
for (PsiClass aClass : mySuperClasses) {
if (Comparing.strEqual(superClassName, aClass.getQualifiedName())) {
superClass = aClass;
break;
}
}
if (superClass != null && StatisticsManager.getInstance().getUseCount(info) > 0) {
preselection = superClass;
break;
}
}
return preselection;
}
protected void doHelpAction() {
HelpManager.getInstance().invokeHelp(HelpID.MEMBERS_PULL_UP);
}
@@ -168,7 +192,9 @@ public class PullUpDialog extends RefactoringDialog {
protected void doAction() {
if (!myCallback.checkConflicts(this)) return;
JavaRefactoringSettings.getInstance().PULL_UP_MEMBERS_JAVADOC = myJavaDocPanel.getPolicy();
StatisticsManager
.getInstance().incUseCount(new StatisticsInfo(PULL_UP_STATISTICS_KEY + myClass.getQualifiedName(), getSuperClass().getQualifiedName()));
invokeRefactoring(new PullUpHelper(myClass, getSuperClass(), getSelectedMemberInfos(),
new DocCommentPolicy(getJavaDocPolicy())));
close(OK_EXIT_CODE);
@@ -21,10 +21,12 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.Nullable;
public class ResolveClassUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.resolve.ResolveClassUtil");
@Nullable
public static PsiClass resolveClass(PsiJavaCodeReferenceElement ref) {
if (ref instanceof PsiJavaCodeReferenceElementImpl && ((PsiJavaCodeReferenceElementImpl)ref).getKind() == PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND){
PsiElement parent = ref.getParent();
@@ -138,7 +138,7 @@ public class PsiScopesUtil {
}
}
public static boolean resolveAndWalk(PsiScopeProcessor processor, PsiJavaCodeReferenceElement ref, PsiElement maxScope) {
public static boolean resolveAndWalk(PsiScopeProcessor processor, PsiJavaCodeReferenceElement ref, @Nullable PsiElement maxScope) {
return resolveAndWalk(processor, ref, maxScope, false);
}
@@ -0,0 +1,7 @@
class Constructor {
int num1;
int num2;
Constructor() {<caret>}
void foo() {}
}
@@ -0,0 +1,6 @@
-Constructor.java
-Constructor
[Constructor()]
foo():void
num1:int
num2:int
@@ -0,0 +1,7 @@
class Field {
int num1;
int <caret>num2;
Field() {}
void foo() {}
}
@@ -0,0 +1,6 @@
-Field.java
-Field
Field()
foo():void
num1:int
[num2:int]
@@ -0,0 +1,7 @@
class InsideClass {
int num1;
int num2;
<caret>
InsideClass() {}
void foo() {}
}
@@ -0,0 +1,6 @@
-InsideClass.java
-[InsideClass]
InsideClass()
foo():void
num1:int
num2:int
@@ -0,0 +1,7 @@
class Method {
int num1;
int num2;
Method() {}
void foo() {<caret>}
}
@@ -0,0 +1,6 @@
-Method.java
-Method
Method()
[foo():void]
num1:int
num2:int
@@ -0,0 +1,31 @@
/*
* Copyright 2000-2012 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.fileStructure;
/**
* @author Konstantin Bulenkov
*/
public class JavaFileStructureSelectionTest extends JavaFileStructureTestCase {
@Override
protected String getTestDataFolderName() {
return "selection";
}
public void testField() throws Exception {checkTree();}
public void testMethod() throws Exception {checkTree();}
public void testConstructor() throws Exception {checkTree();}
public void testInsideClass() throws Exception {checkTree();}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2012 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.fileStructure;
import com.intellij.JavaTestUtil;
import com.intellij.ide.structureView.impl.java.JavaAnonymousClassesNodeProvider;
import com.intellij.ide.util.FileStructurePopup;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.testFramework.FileStructureTestBase;
/**
* @author Konstantin Bulenkov
*/
public abstract class JavaFileStructureTestCase extends FileStructureTestBase {
private boolean myShowAnonymousByDefault;
protected abstract String getTestDataFolderName();
@Override
public void setUp() throws Exception {
super.setUp();
myShowAnonymousByDefault = PropertiesComponent.getInstance().getBoolean(getAnonymousPropertyName(), false);
}
@Override
protected String getFileExtension() {
return "java";
}
@Override
public void tearDown() throws Exception {
PropertiesComponent.getInstance().setValue(getAnonymousPropertyName(), Boolean.toString(myShowAnonymousByDefault));
super.tearDown();
}
private static String getAnonymousPropertyName() {
return FileStructurePopup.getPropertyName(JavaAnonymousClassesNodeProvider.JAVA_ANONYMOUS_PROPERTY_NAME);
}
@Override
protected String getBasePath() {
return JavaTestUtil.getRelativeJavaTestDataPath() + "/fileStructure/" + getTestDataFolderName();
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -17,6 +17,7 @@ package com.intellij.execution.util;
import com.intellij.execution.CommonProgramRunConfigurationParameters;
import com.intellij.execution.configurations.ModuleBasedConfiguration;
import com.intellij.execution.configurations.RuntimeConfigurationWarning;
import com.intellij.execution.configurations.SimpleProgramParameters;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.module.Module;
@@ -26,6 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
@@ -36,6 +38,19 @@ public class ProgramParametersUtil {
parameters.getProgramParametersList().addParametersString(configuration.getProgramParameters());
parameters.setWorkingDirectory(getWorkingDir(configuration, project, module));
parameters.setupEnvs(configuration.getEnvs(), configuration.isPassParentEnvs());
if (parameters.getEnv() != null) {
Map<String, String> expanded = new HashMap<String, String>();
for (Map.Entry<String, String> each : parameters.getEnv().entrySet()) {
expanded.put(each.getKey(), expandPath(each.getValue(), module, project));
}
parameters.setEnv(expanded);
}
}
public static String getWorkingDir(CommonProgramRunConfigurationParameters configuration, Project project, Module module) {
String workingDirectory = configuration.getWorkingDirectory();
VirtualFile baseDir = project.getBaseDir();
@@ -46,15 +61,14 @@ public class ProgramParametersUtil {
if (!FileUtil.isAbsolute(workingDirectory) && baseDir != null) {
workingDirectory = baseDir.getPath() + "/" + workingDirectory;
}
parameters.setWorkingDirectory(workingDirectory);
return workingDirectory;
}
parameters.setupEnvs(configuration.getEnvs(), configuration.isPassParentEnvs());
if (parameters.getEnv() != null) {
Map<String, String> expanded = new HashMap<String, String>();
for (Map.Entry<String, String> each : parameters.getEnv().entrySet()) {
expanded.put(each.getKey(), expandPath(each.getValue(), module, project));
}
parameters.setEnv(expanded);
public static void checkWorkingDirectoryExist(CommonProgramRunConfigurationParameters configuration, Project project, Module module)
throws RuntimeConfigurationWarning {
final String workingDir = getWorkingDir(configuration, project, module);
if (!new File(workingDir).exists()) {
throw new RuntimeConfigurationWarning("Working directory '" + workingDir + "' doesn't exist");
}
}
@@ -90,7 +90,7 @@ public class ViewStructureAction extends AnAction {
}
@Nullable
private static FileStructurePopup createPopup(final Editor editor, Project project, Navigatable navigatable, final FileEditor fileEditor) {
public static FileStructurePopup createPopup(final Editor editor, Project project, @Nullable Navigatable navigatable, final FileEditor fileEditor) {
final StructureViewBuilder structureViewBuilder = fileEditor.getStructureViewBuilder();
if (structureViewBuilder == null) return null;
StructureView structureView = structureViewBuilder.createStructureView(fileEditor, project);
@@ -149,6 +149,7 @@ public class FileStructurePopup implements Disposable {
myTree = new JBTreeWithHintProvider(new DefaultMutableTreeNode(myTreeStructure.getRootElement())) {
@Override
protected PsiElement getPsiElementForHint(Object selectedValue) {
//noinspection ConstantConditions
return getPsi((FilteringTreeStructure.FilteringNode)((DefaultMutableTreeNode)selectedValue).getUserObject());
}
};
@@ -218,12 +219,13 @@ public class FileStructurePopup implements Disposable {
return current.isEmpty() ? null : findClosestTo(myInitialPsiElement, current);
}
@Nullable
private Object findClosestTo(PsiElement path, ArrayList<ObjectWithWeight> paths) {
if (path == null || myInitialPsiElement == null) {
return paths.get(0).node;
}
final Set<PsiElement> parents = getAllParents(myInitialPsiElement);
Object cur = paths.get(0).node;
ArrayList<TreePath> cur = new ArrayList<TreePath>();
int max = -1;
for (ObjectWithWeight p : paths) {
final Object last = ((TreePath)p.node).getLastPathComponent();
@@ -238,14 +240,21 @@ public class FileStructurePopup implements Disposable {
final int size = ContainerUtil.intersection(parents, elements).size();
if (size > max) {
max = size;
cur = p.node;
} else if (size == max && size == parents.size()) {
cur = p.node;
cur.clear();
cur.add((TreePath)p.node);
} else if (size == max) {
cur.add((TreePath)p.node);
}
}
}
return cur;
Collections.sort(cur, new Comparator<TreePath>() {
@Override
public int compare(TreePath o1, TreePath o2) {
return o2.getPathCount() - o1.getPathCount();
}
});
return cur.isEmpty() ? null : cur.get(0);
}
class ObjectWithWeight {
@@ -285,7 +294,7 @@ public class FileStructurePopup implements Disposable {
mySpeedSearch.setComparator(new SpeedSearchComparator(false, true));
final FileStructurePopupFilter filter = new FileStructurePopupFilter();
myFilteringStructure = new FilteringTreeStructure(filter, myTreeStructure, false);
myFilteringStructure = new FilteringTreeStructure(filter, myTreeStructure, ApplicationManager.getApplication().isUnitTestMode());
myAbstractTreeBuilder = new FilteringTreeBuilder(myTree, filter, myFilteringStructure, null) {
@Override
protected boolean validateNode(Object child) {
@@ -385,35 +394,38 @@ public class FileStructurePopup implements Disposable {
});
}
});
final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myPopup);
alarm.addRequest(new Runnable() {
String filter = "";
if (!ApplicationManager.getApplication().isUnitTestMode()) {
final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myPopup);
alarm.addRequest(new Runnable() {
String filter = "";
@Override
public void run() {
alarm.cancelAllRequests();
String prefix = mySpeedSearch.getEnteredPrefix();
myTree.getEmptyText().setText(StringUtil.isEmpty(prefix) ? "Nothing to show" : "Can't find '" + prefix + "'");
if (prefix == null) prefix = "";
@Override
public void run() {
alarm.cancelAllRequests();
String prefix = mySpeedSearch.getEnteredPrefix();
myTree.getEmptyText().setText(StringUtil.isEmpty(prefix) ? "Nothing to show" : "Can't find '" + prefix + "'");
if (prefix == null) prefix = "";
if (!filter.equals(prefix)) {
filter = prefix;
myAbstractTreeBuilder.refilter(null, false, false).doWhenProcessed(new Runnable() {
@Override
public void run() {
myTree.repaint();
//if (mySpeedSearch.isPopupActive()) {
// mySpeedSearch.refreshSelection();
//}
}
});
if (!filter.equals(prefix)) {
filter = prefix;
myAbstractTreeBuilder.refilter(null, false, false).doWhenProcessed(new Runnable() {
@Override
public void run() {
myTree.repaint();
//if (mySpeedSearch.isPopupActive()) {
// mySpeedSearch.refreshSelection();
//}
}
});
}
alarm.addRequest(this, 300);
}
alarm.addRequest(this, 300);
}
}, 300);
}, 300);
}
}
private void selectPsiElement(PsiElement element) {
@Nullable
public FilteringTreeStructure.FilteringNode selectPsiElement(PsiElement element) {
Set<PsiElement> parents = getAllParents(element);
FilteringTreeStructure.FilteringNode node = (FilteringTreeStructure.FilteringNode)myAbstractTreeBuilder.getRootElement();
@@ -432,11 +444,11 @@ public class FileStructurePopup implements Disposable {
if (myAbstractTreeBuilder.getSelectedElements().isEmpty()) {
TreeUtil.selectFirstNode(myTree);
}
return;
return node;
}
}
TreeUtil.selectFirstNode(myTree);
return null;
}
private static Set<PsiElement> getAllParents(PsiElement element) {
@@ -478,7 +490,7 @@ public class FileStructurePopup implements Disposable {
}
@Nullable
protected PsiElement getCurrentElement(@Nullable final PsiFile psiFile) {
public PsiElement getCurrentElement(@Nullable final PsiFile psiFile) {
if (psiFile == null) return null;
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
@@ -710,7 +722,7 @@ public class FileStructurePopup implements Disposable {
}
}
private static String getPropertyName(String propertyName) {
public static String getPropertyName(String propertyName) {
return propertyName + ".file.structure.state";
}
@@ -718,6 +730,18 @@ public class FileStructurePopup implements Disposable {
myTitle = title;
}
public Tree getTree() {
return myTree;
}
public TreeSpeedSearch getSpeedSearch() {
return mySpeedSearch;
}
public FilteringTreeBuilder getTreeBuilder() {
return myAbstractTreeBuilder;
}
private class FileStructurePopupFilter implements ElementFilter {
private String myLastFilter = null;
private HashSet<Object> myVisibleParents = new HashSet<Object>();
@@ -16,6 +16,7 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleJdkOrderEntry;
@@ -29,6 +30,7 @@ import org.jdom.Attribute;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author dsl
@@ -62,8 +64,7 @@ public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implement
final String jdkName = jdkNameAttribute.getValue();
final String jdkType = element.getAttributeValue(JDK_TYPE_ATTR);
final ProjectJdkTable projectJdkTable = ProjectJdkTable.getInstance();
final Sdk jdkByName = projectJdkTable.findJdk(jdkName, jdkType);
final Sdk jdkByName = findJdk(jdkName, jdkType);
if (jdkByName == null) {
init(null, jdkName, jdkType);
}
@@ -72,6 +73,26 @@ public class ModuleJdkOrderEntryImpl extends LibraryOrderEntryBaseImpl implement
}
}
public abstract static class SdkFinder {
private static final ExtensionPointName<SdkFinder> EP_NAME = ExtensionPointName.create("com.intellij.sdkFinder");
@Nullable
public Sdk findSdk(String name, String sdkType) {
return null;
}
}
@Nullable
private static Sdk findJdk(final String jdkName, final String jdkType) {
for (SdkFinder sdkFinder : SdkFinder.EP_NAME.getExtensions()) {
final Sdk sdk = sdkFinder.findSdk(jdkName, jdkType);
if (sdk != null) {
return sdk;
}
}
final ProjectJdkTable projectJdkTable = ProjectJdkTable.getInstance();
return projectJdkTable.findJdk(jdkName, jdkType);
}
private ModuleJdkOrderEntryImpl(ModuleJdkOrderEntryImpl that, RootModelImpl rootModel, ProjectRootManagerImpl projectRootManager) {
@@ -132,6 +132,8 @@ public class InjectedLanguageUtil {
if (file == null || !file.isPhysical() && file.getOriginalFile() == file) return;
}
if (containingFile.getViewProvider() instanceof InjectedFileViewProvider) return; // no injection inside injection
PsiElement inTree = loadTree(host, containingFile);
if (inTree != host) {
host = inTree;
@@ -2362,7 +2362,7 @@ public class AbstractTreeUi {
final ActionCallback done = new ActionCallback();
invokeLaterIfNeeded(new Runnable() {
final Runnable cancelUpdate = new Runnable() {
public void run() {
if (isReleased()) {
done.setRejected();
@@ -2371,21 +2371,29 @@ public class AbstractTreeUi {
if (myResettingToReadyNow.get()) {
_getReady().notify(done);
} else if (isReady()) {
}
else if (isReady()) {
resetToReadyNow();
done.setDone();
} else {
}
else {
if (isIdle() && hasPendingWork()) {
resetToReadyNow();
done.setDone();
} else {
}
else {
_getReady().notify(done);
}
}
maybeReady();
}
}, false);
};
if (ApplicationManager.getApplication().isUnitTestMode()) {
cancelUpdate.run();
} else {
invokeLaterIfNeeded(cancelUpdate, false);
}
if (isEdt() || isPassthroughMode()) {
maybeReady();
@@ -3680,7 +3688,7 @@ public class AbstractTreeUi {
}
public void userSelect(final Object[] elements, final Runnable onDone, final boolean addToSelection, boolean scroll) {
_select(elements, onDone, addToSelection, true, false, scroll, false, true, true);
_select(elements, onDone, addToSelection, true, false, scroll, false, true, !ApplicationManager.getApplication().isUnitTestMode());
}
void _select(final Object[] elements,
@@ -18,6 +18,7 @@ package com.intellij.ui.treeStructure.filtered;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.speedSearch.ElementFilter;
@@ -120,7 +121,7 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder {
myRefilterQueue.cancelAllUpdates();
}
final ActionCallback callback = new ActionCallback();
getUi().cancelUpdate().doWhenProcessed(new Runnable() {
final Runnable afterCancelUpdate = new Runnable() {
@Override
public void run() {
if (myRefilterQueue == null || now) {
@@ -145,7 +146,12 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder {
});
}
}
});
};
if (!ApplicationManager.getApplication().isUnitTestMode()) {
getUi().cancelUpdate().doWhenProcessed(afterCancelUpdate);
} else {
afterCancelUpdate.run();
}
return callback;
}
@@ -155,7 +161,7 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder {
final ActionCallback selectionDone = new ActionCallback();
getFilteredStructure().refilter();
queueUpdate().doWhenProcessed(new Runnable() {
final Runnable selectionRunnable = new Runnable() {
public void run() {
revalidateTree();
@@ -173,25 +179,36 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder {
selectionDone.setDone();
}
});
} else {
}
else {
TreeUtil.ensureSelection(myTree);
selectionDone.setDone();
}
} else {
}
else {
selectionDone.setDone();
}
}
});
};
if (!ApplicationManager.getApplication().isUnitTestMode()) {
queueUpdate().doWhenProcessed(selectionRunnable);
} else {
selectionRunnable.run();
}
final ActionCallback result = new ActionCallback();
selectionDone.doWhenDone(new Runnable() {
public void run() {
scrollSelectionToVisible(new Runnable() {
public void run() {
getReady(this).notify(result);
}
}, false);
if (!ApplicationManager.getApplication().isUnitTestMode()) {
scrollSelectionToVisible(new Runnable() {
public void run() {
getReady(this).notify(result);
}
}, false);
} else {
result.setDone();
}
}
}).doWhenRejected(new Runnable() {
@Override
@@ -241,7 +241,7 @@ public class FilteringTreeStructure extends AbstractTreeStructure {
}
public Object[] getEqualityObjects() {
return NONE;
return new Object[]{myDelegate};
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -1040,9 +1040,9 @@ public class FSRecords implements Forceable {
}
private static void checkFileIsValid(int fileId) {
assert fileId > 0 : "assert fileId > 0 failed";
assert fileId > 0 : fileId;
// TODO: This assertion is a bit timey, will remove when bug is caught.
assert (getFlags(fileId) & FREE_RECORD_FLAG) == 0 : "Trying to find an attribute of deleted page";
assert (getFlags(fileId) & FREE_RECORD_FLAG) == 0 : "Accessing attribute of a deleted page: " + fileId + ":" + getName(fileId);
}
public static int acquireFileContent(int fileId) {
@@ -528,7 +528,7 @@ exclude.from.imports.no.exclusions=No exclude patterns
inline.elements=Inline elements:
don.t.break.if.inline.content=Don't break if inline content:
edit.code.folding.options=Open code folding options
button.new=&New
button.new=&New...
building.include.indices=Building include indices...
loading.include.indices=Loading include indices...
use.external.annotations=Use &external annotations
@@ -295,9 +295,9 @@ module.library.display.name=Module {0, choice, 1#Library|2#Libraries}
project.roots.library.banner.text= {1} ''{0}''
facet.banner.text=Facet ''{0}''
project.roots.project.banner.text=General Settings for Project ''{0}''
project.roots.set.up.jdk.title=Set up {0, choice, 1#module|2#project} SDK
project.roots.set.up.jdk.title=Set up {0, choice, 1#Module|2#Project} SDK
project.roots.no.jdk.on.project.message=Set up created sdk on project?
project.roots.no.jdk.on.projecct.title=No project sdk set up
project.roots.no.jdk.on.project.title=Create SDK
project.roots.jdks.node.text=JDK stands for the Java Development Kit, a software development package that is required to write, test and debug Java applications. \
JDK also contains classes and runtime environment that are used to execute the target application. <br><br>\
Mobile SDK contains emulator of mobile phone as well as embedded Java SDK to compile/pack/run/debug J2ME applications. <br><br>\
@@ -313,6 +313,8 @@
<extensionPoint name="library.presentationProvider" interface="com.intellij.openapi.roots.libraries.LibraryPresentationProvider"/>
<extensionPoint name="library.type" interface="com.intellij.openapi.roots.libraries.LibraryType"/>
<extensionPoint name="sdkFinder" interface="com.intellij.openapi.roots.impl.ModuleJdkOrderEntryImpl$SdkFinder"/>
<extensionPoint name="lang.implementationTextSelectioner"
beanClass="com.intellij.lang.LanguageExtensionPoint"/>
<extensionPoint name="lang.lineWrapStrategy"
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -57,7 +57,7 @@ public class SymLinkHandlingTest extends LightPlatformLangTestCase {
assertNull(selfLinkVFile);
}
public void testTargetIsWriteable() throws Exception {
public void testTargetIsWritable() throws Exception {
if (!SystemInfo.areSymLinksSupported) return;
final File targetFile = FileUtil.createTempFile("target", "");
@@ -0,0 +1,120 @@
/*
* Copyright 2000-2012 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.testFramework;
import com.intellij.ide.actions.ViewStructureAction;
import com.intellij.ide.util.FileStructurePopup;
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
import com.intellij.util.ui.tree.TreeUtil;
import junit.framework.Assert;
import org.junit.Before;
import java.io.File;
/**
* @author Konstantin Bulenkov
*/
public abstract class FileStructureTestBase extends CodeInsightFixtureTestCase {
FileStructurePopup myPopup;
@Before
public void setUp() throws Exception {
super.setUp();
myFixture.configureByFile(getFileName(getFileExtension()));
myPopup = ViewStructureAction.createPopup(myFixture.getEditor(),
myFixture.getProject(),
null,
TextEditorProvider.getInstance().getTextEditor(myFixture.getEditor()));
update();
}
protected abstract String getFileExtension();
@Override
public void tearDown() throws Exception {
Disposer.dispose(myPopup);
super.tearDown();
}
private String getFileName(String ext) {
return getTestName(false) + (StringUtil.isEmpty(ext) ? "" : "." + ext);
}
protected String getTreeFileName() {
return getFileName("tree");
}
protected void checkTree() throws Exception {
final String expected = FileUtil.loadFile(new File(getTestDataPath() + "/" + getTreeFileName()), true);
Assert.assertEquals(expected.trim(), PlatformTestUtil.print(getTree(), true).trim());
}
private void update() throws InterruptedException {
myPopup.getTreeBuilder().refilter().doWhenProcessed(new Runnable() {
@Override
public void run() {
getStructure().rebuild();
updateTree();
TreeUtil.expandAll(getTree());
final FilteringTreeStructure.FilteringNode node = myPopup.selectPsiElement(myPopup.getCurrentElement(getFile()));
getTree().getSelectionModel().setSelectionPath(getTree().getPath(node));
}
});
}
protected Tree getTree() {
return myPopup.getTree();
}
protected FilteringTreeBuilder getBuilder() {
return myPopup.getTreeBuilder();
}
protected TreeSpeedSearch getSpeedSearch() {
return myPopup.getSpeedSearch();
}
protected void updateTree() {
updateRecursively(getRootNode());
}
protected FilteringTreeStructure getStructure() {
final FilteringTreeStructure structure = (FilteringTreeStructure)getBuilder().getTreeStructure();
assert structure != null;
return structure;
}
protected FilteringTreeStructure.FilteringNode getRootNode() {
return (FilteringTreeStructure.FilteringNode)getStructure().getRootElement();
}
protected void updateRecursively(final FilteringTreeStructure.FilteringNode node) {
node.update();
for (FilteringTreeStructure.FilteringNode child : node.children()) {
updateRecursively(child);
}
}
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.builders.EmptyModuleFixtureBuilder;
import com.intellij.testFramework.builders.ModuleFixtureBuilder;
import org.jetbrains.annotations.NonNls;
import java.io.File;
@@ -29,7 +30,7 @@ import java.io.File;
/**
* @author yole
*/
public abstract class CodeInsightFixtureTestCase extends UsefulTestCase {
public abstract class CodeInsightFixtureTestCase<T extends ModuleFixtureBuilder> extends UsefulTestCase {
protected CodeInsightTestFixture myFixture;
protected Module myModule;
@@ -39,7 +40,7 @@ public abstract class CodeInsightFixtureTestCase extends UsefulTestCase {
final TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder();
myFixture = IdeaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
final EmptyModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(EmptyModuleFixtureBuilder.class);
final T moduleFixtureBuilder = projectBuilder.addModule(getModuleBuilderClass());
moduleFixtureBuilder.addSourceContentRoot(myFixture.getTempDirPath());
tuneFixture(moduleFixtureBuilder);
@@ -48,6 +49,10 @@ public abstract class CodeInsightFixtureTestCase extends UsefulTestCase {
myModule = moduleFixtureBuilder.getFixture().getModule();
}
protected Class<T> getModuleBuilderClass() {
return (Class<T>)EmptyModuleFixtureBuilder.class;
}
@Override
protected void tearDown() throws Exception {
myFixture.tearDown();
@@ -56,7 +61,7 @@ public abstract class CodeInsightFixtureTestCase extends UsefulTestCase {
super.tearDown();
}
protected void tuneFixture(final EmptyModuleFixtureBuilder moduleBuilder) {}
protected void tuneFixture(final T moduleBuilder) {}
/**
* Return relative path to the test data. Path is relative to the
@@ -173,12 +173,23 @@ public class FileUtil {
@NotNull
public static String loadFile(@NotNull File file) throws IOException {
return loadFile(file, null);
return loadFile(file, null, false);
}
@NotNull
public static String loadFile(@NotNull File file, boolean convertLineSeparators) throws IOException {
return loadFile(file, null, convertLineSeparators);
}
@NotNull
public static String loadFile(@NotNull File file, String encoding) throws IOException {
return new String(loadFileText(file, encoding));
return loadFile(file, encoding, false);
}
@NotNull
public static String loadFile(@NotNull File file, String encoding, boolean convertLineSeparators) throws IOException {
final String s = new String(loadFileText(file, encoding));
return convertLineSeparators ? StringUtil.convertLineSeparators(s) : s;
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -92,5 +92,10 @@ public class ConcurrentHashSet<K> implements Set<K> {
public void clear() {
map.clear();
}
@Override
public String toString() {
return map.keySet().toString();
}
}
@@ -49,7 +49,7 @@ public class PagedFileStorage implements Forceable {
static {
final int lower = 100;
final int upper = SystemInfo.is64Bit ? 500 : 200;
final int upper = SystemInfo.is64Bit && !PersistentEnumeratorDelegate.useBtree() ? 500 : 200;
BUFFER_SIZE = Math.max(1, SystemInfo.getIntProperty("idea.paged.storage.page.size", 10)) * MB;
if (ByteBufferWrapper.NO_MMAP) {
@@ -16,7 +16,6 @@
package com.intellij.util.io;
import com.intellij.openapi.Forceable;
import com.intellij.openapi.util.SystemInfo;
import org.jetbrains.annotations.Nullable;
import java.io.Closeable;
@@ -32,7 +31,7 @@ public class PersistentEnumeratorDelegate<Data> implements Closeable, Forceable
new PersistentEnumerator<Data>(file, dataDescriptor, initialSize);
}
private boolean useBtree() {
static boolean useBtree() {
String property = System.getProperty("idea.use.btree");
return !"false".equals(property);
}
@@ -20,7 +20,9 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.DataOutputStream;
import com.intellij.util.io.KeyDescriptor;
import com.intellij.util.io.UnsyncByteArrayInputStream;
import org.jetbrains.annotations.NotNull;
import java.io.*;
@@ -51,7 +53,7 @@ public class SmallMapSerializer<K,V> implements Forceable {
private void init() {
try {
final byte[] bytes = FileUtil.loadFileBytes(myFile);
final DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
final DataInputStream dis = new DataInputStream(new UnsyncByteArrayInputStream(bytes));
final int size = dis.readInt();
for (int i = 0; i < size; i++) {
final KeyWrapper<K> keyWrapper = new KeyWrapper<K>(myKeyDescriptor, myKeyDescriptor.read(dis));
@@ -31,6 +31,7 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -45,25 +46,29 @@ import org.jetbrains.idea.eclipse.config.EclipseModuleManager;
import org.jetbrains.idea.eclipse.importWizard.EclipseProjectFinder;
import org.jetbrains.idea.eclipse.util.ErrorLog;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.io.*;
import java.util.*;
import java.util.jar.Manifest;
import java.util.regex.PatternSyntaxException;
import static org.jetbrains.idea.eclipse.conversion.EPathUtil.*;
import static org.jetbrains.idea.eclipse.conversion.EPathUtil.expandEclipsePath2Url;
public class EclipseClasspathReader {
private final String myRootPath;
private final Project myProject;
@Nullable private final List<String> myCurrentRoots;
private ContentEntry myContentEntry;
@Nullable private final Set<String> myModuleNames;
public EclipseClasspathReader(final String rootPath, final Project project, @Nullable List<String> currentRoots) {
this(rootPath, project, currentRoots, null);
}
public EclipseClasspathReader(final String rootPath, final Project project, @Nullable List<String> currentRoots, @Nullable Set<String> moduleNames) {
myRootPath = FileUtil.toSystemIndependentName(rootPath);
myProject = project;
myCurrentRoots = currentRoots;
myModuleNames = moduleNames;
}
public void init(ModifiableRootModel model) {
@@ -236,6 +241,7 @@ public class EclipseClasspathReader {
}
else if (kind.equals(EclipseXml.CON_KIND)) {
if (path.equals(EclipseXml.ECLIPSE_PLATFORM)) {
readRequiredBundles(rootModel, refsToModules);
addNamedLibrary(rootModel, unknownLibraries, exported, IdeaXml.ECLIPSE_LIBRARY, LibraryTablesRegistrar.APPLICATION_LEVEL);
}
else if (path.startsWith(EclipseXml.JRE_CONTAINER)) {
@@ -276,6 +282,53 @@ public class EclipseClasspathReader {
}
}
private void readRequiredBundles(ModifiableRootModel rootModel, Set<String> refsToModules) throws ConversionException {
if (myModuleNames == null) {
return;
}
final File manifestFile = new File(myRootPath, "META-INF/MANIFEST.MF");
if (!manifestFile.exists()) {
return;
}
InputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(manifestFile));
final Manifest manifest = new Manifest(in);
final String attributes = manifest.getMainAttributes().getValue("Require-Bundle");
if (!StringUtil.isEmpty(attributes)) {
final StringTokenizer tokenizer = new StringTokenizer(attributes, ",");
while (tokenizer.hasMoreTokens()) {
String bundle = tokenizer.nextToken().trim();
if (!bundle.isEmpty()) {
final int constraintIndex = bundle.indexOf(';');
if (constraintIndex != -1) {
bundle = bundle.substring(0, constraintIndex).trim();
}
if (myModuleNames.contains(bundle)) {
refsToModules.add(bundle);
rootModel.addInvalidModuleEntry(bundle);
}
}
}
}
}
catch (IOException e) {
throw new ConversionException(e.getMessage());
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException ignored) {
}
}
}
}
private static int rearrangeOrderEntryOfType(ModifiableRootModel rootModel, Class<? extends OrderEntry> orderEntryClass) {
OrderEntry[] orderEntries = rootModel.getOrderEntries();
int moduleSourcesIdx = 0;
@@ -50,6 +50,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.ModifiableArtifactModel;
import com.intellij.projectImport.ProjectImportBuilder;
import com.intellij.util.Function;
import gnu.trove.THashSet;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
@@ -198,12 +199,14 @@ public class EclipseImportBuilder extends ProjectImportBuilder<String> implement
final ModifiableModuleModel moduleModel = model != null ? model : ModuleManager.getInstance(project).getModifiableModel();
final ModifiableRootModel[] rootModels = new ModifiableRootModel[getParameters().projectsToConvert.size()];
final Set<File> files = new HashSet<File>();
final Set<String> moduleNames = new THashSet<String>(getParameters().projectsToConvert.size());
for (String path : getParameters().projectsToConvert) {
String modulesDirectory = getParameters().converterOptions.commonModulesDirectory;
if (modulesDirectory == null) {
modulesDirectory = path;
}
final String moduleName = EclipseProjectFinder.findProjectName(path);
moduleNames.add(moduleName);
final File imlFile = new File(modulesDirectory + File.separator + moduleName + IdeaXml.IML_EXT);
if (imlFile.isFile()) {
files.add(imlFile);
@@ -266,7 +269,7 @@ public class EclipseImportBuilder extends ProjectImportBuilder<String> implement
rootModels[idx++] = rootModel;
final File classpathFile = new File(path, EclipseXml.DOT_CLASSPATH_EXT);
final EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, getParameters().projectsToConvert);
final EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, project, getParameters().projectsToConvert, moduleNames);
classpathReader.init(rootModel);
if (classpathFile.exists()) {
final Element classpathElement = JDOMUtil.loadDocument(classpathFile).getRootElement();
@@ -37,6 +37,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.intellij.openapi.util.text.StringUtil.pluralize;
/**
* Common class for Git operations with branches aware of multi-root configuration,
* which means showing combined error information, proposing to rollback, etc.
@@ -154,7 +156,7 @@ abstract class GitBranchOperation {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
String description = message + getRollbackProposal();
String description = "<html>" + message + ".<br/>" + getRollbackProposal() + "</html>";
ok.set(Messages.OK ==
MessageManager.showYesNoDialog(myProject, description, title, "Rollback", "Don't rollback", Messages.getErrorIcon()));
}
@@ -190,11 +192,16 @@ abstract class GitBranchOperation {
}
}
@NotNull
protected String repositories() {
return pluralize("repository", getSuccessfulRepositories().size());
}
private void showUnmergedFilesDialogWithRollback() {
final AtomicBoolean ok = new AtomicBoolean();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override public void run() {
String description = "You have to resolve all merge conflicts before checkout.<br/>" + getRollbackProposal();
String description = "<html>You have to resolve all merge conflicts before checkout.<br/>" + getRollbackProposal() + "</html>";
// suppressing: this message looks ugly if capitalized by words
//noinspection DialogTitleCapitalization
ok.set(Messages.OK == MessageManager.showYesNoDialog(myProject, description, UNMERGED_FILES_ERROR_TITLE, "Rollback", "Don't rollback", Messages.getErrorIcon()));
@@ -38,7 +38,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -52,7 +51,7 @@ public final class GitBranchOperationsProcessor {
private static final Logger LOG = Logger.getInstance(GitBranchOperationsProcessor.class);
private final Project myProject;
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
@Nullable private final Runnable myCallInAwtAfterExecution;
private final GitRepository mySelectedRepository;
@@ -61,16 +60,16 @@ public final class GitBranchOperationsProcessor {
}
public GitBranchOperationsProcessor(@NotNull GitRepository repository, @Nullable Runnable callInAwtAfterExecution) {
this(repository.getProject(), Collections.singleton(repository), repository, callInAwtAfterExecution);
this(repository.getProject(), Collections.singletonList(repository), repository, callInAwtAfterExecution);
}
public GitBranchOperationsProcessor(@NotNull Project project, @NotNull Collection<GitRepository> repositories,
public GitBranchOperationsProcessor(@NotNull Project project, @NotNull List<GitRepository> repositories,
@NotNull GitRepository selectedRepository) {
this(project, repositories, selectedRepository, null);
}
public GitBranchOperationsProcessor(@NotNull Project project,
@NotNull Collection<GitRepository> repositories,
@NotNull List<GitRepository> repositories,
@NotNull GitRepository selectedRepository,
@Nullable Runnable callInAwtAfterExecution) {
myProject = project;
@@ -205,7 +204,7 @@ public final class GitBranchOperationsProcessor {
}.runInBackground();
}
private GitCommitCompareInfo loadCommitsToCompare(Collection<GitRepository> repositories, String branchName) {
private GitCommitCompareInfo loadCommitsToCompare(List<GitRepository> repositories, String branchName) {
GitCommitCompareInfo compareInfo = new GitCommitCompareInfo();
for (GitRepository repository : repositories) {
compareInfo.put(repository, loadCommitsToCompare(repository, branchName));
@@ -93,7 +93,7 @@ public class GitCheckoutNewBranchOperation extends GitBranchOperation {
@NotNull
@Override
protected String getRollbackProposal() {
return "However checkout has succeeded for the following repositories:<br/>" +
return "However checkout has succeeded for the following " + repositories() + ":<br/>" +
successfulRepositoriesJoined() +
"<br/>You may rollback (checkout back to " + myPreviousBranch + ") not to let branches diverge.";
}
@@ -104,7 +104,7 @@ public class GitCheckoutNewBranchOperation extends GitBranchOperation {
GitCompoundResult deleteResult = new GitCompoundResult(myProject);
Collection<GitRepository> repositories = getSuccessfulRepositories();
for (GitRepository repository : repositories) {
GitCommandResult result = Git.checkout(repository, myPreviousBranch, null);
GitCommandResult result = Git.checkout(repository, myPreviousBranch, null, true);
checkoutResult.append(repository, result);
if (result.success()) {
deleteResult.append(repository, Git.branchDelete(repository, myNewBranchName, false));
@@ -23,7 +23,6 @@ import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Clock;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
@@ -55,6 +54,7 @@ import javax.swing.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.intellij.openapi.util.text.StringUtil.*;
import static git4idea.commands.GitMessageWithFilesDetector.Event.LOCAL_CHANGES_OVERWRITTEN_BY_CHECKOUT;
import static git4idea.commands.GitMessageWithFilesDetector.Event.UNTRACKED_FILES_OVERWRITTEN_BY;
import static git4idea.util.GitUIUtil.code;
@@ -96,7 +96,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
GitSimpleEventDetector unmergedFiles = new GitSimpleEventDetector(GitSimpleEventDetector.Event.UNMERGED);
GitMessageWithFilesDetector untrackedOverwrittenByCheckout = new GitMessageWithFilesDetector(UNTRACKED_FILES_OVERWRITTEN_BY, root);
GitCommandResult result = Git.checkout(repository, myStartPointReference, myNewBranch,
GitCommandResult result = Git.checkout(repository, myStartPointReference, myNewBranch, false,
localChangesOverwrittenByCheckout, unmergedFiles, untrackedOverwrittenByCheckout);
if (result.success()) {
refresh(repository);
@@ -134,13 +134,14 @@ public class GitCheckoutOperation extends GitBranchOperation {
// get all other conflicting changes
Map<GitRepository, List<Change>> conflictingChangesInRepositories = collectLocalChangesOnAllOtherRepositories(repository);
Set<GitRepository> otherProblematicRepositories = conflictingChangesInRepositories.keySet();
Collection<GitRepository> allConflictingRepositories = new ArrayList<GitRepository>(otherProblematicRepositories);
List<GitRepository> allConflictingRepositories = new ArrayList<GitRepository>(otherProblematicRepositories);
allConflictingRepositories.add(repository);
for (List<Change> changes : conflictingChangesInRepositories.values()) {
affectedChanges.addAll(changes);
}
if (GitWouldBeOverwrittenByCheckoutDialog.showAndGetAnswer(myProject, affectedChanges)) {
int smartCheckoutDecision = GitWouldBeOverwrittenByCheckoutDialog.showAndGetAnswer(myProject, affectedChanges);
if (smartCheckoutDecision == GitWouldBeOverwrittenByCheckoutDialog.SMART_CHECKOUT) {
boolean smartCheckedOutSuccessfully = smartCheckout(allConflictingRepositories, myStartPointReference, myNewBranch, getIndicator());
if (smartCheckedOutSuccessfully) {
GitRepository[] otherRepositories = ArrayUtil.toObjectArray(otherProblematicRepositories, GitRepository.class);
@@ -156,6 +157,9 @@ public class GitCheckoutOperation extends GitBranchOperation {
return false;
}
}
else if (smartCheckoutDecision == GitWouldBeOverwrittenByCheckoutDialog.FORCE_CHECKOUT_EXIT_CODE) {
return checkoutOrNotify(allConflictingRepositories, myStartPointReference, myNewBranch, true);
}
else {
fatalLocalChangesError();
return false;
@@ -203,7 +207,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
String description = UntrackedFilesNotifier.createUntrackedFilesOverwrittenDescription("checkout", true);
final SelectFilesDialog dialog = new UntrackedFilesDialog(myProject, new ArrayList<VirtualFile>(untrackedFiles),
StringUtil.stripHtml(description, true));
stripHtml(description, true));
dialog.setTitle(title);
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
@@ -238,7 +242,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
@NotNull
@Override
protected String getRollbackProposal() {
return "However checkout has succeeded for the following repositories:<br/>" +
return "However checkout has succeeded for the following " + repositories() + ":<br/>" +
successfulRepositoriesJoined() +
"<br/>You may rollback (checkout back to " + myPreviousBranch + ") not to let branches diverge.";
}
@@ -248,7 +252,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
GitCompoundResult checkoutResult = new GitCompoundResult(myProject);
GitCompoundResult deleteResult = new GitCompoundResult(myProject);
for (GitRepository repository : getSuccessfulRepositories()) {
GitCommandResult result = Git.checkout(repository, myPreviousBranch, null);
GitCommandResult result = Git.checkout(repository, myPreviousBranch, null, true);
checkoutResult.append(repository, result);
if (result.success() && myNewBranch != null) {
/*
@@ -310,7 +314,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
}
// stash - checkout - unstash
private boolean smartCheckout(@NotNull final Collection<GitRepository> repositories, @NotNull final String reference, @Nullable final String newBranch, @NotNull ProgressIndicator indicator) {
private boolean smartCheckout(@NotNull final List<GitRepository> repositories, @NotNull final String reference, @Nullable final String newBranch, @NotNull ProgressIndicator indicator) {
final GitChangesSaver saver = configureSaver(reference, indicator);
final AtomicBoolean result = new AtomicBoolean();
@@ -319,7 +323,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
boolean savedSuccessfully = save(repositories, saver);
if (savedSuccessfully) {
try {
result.set(checkoutOrNotify(repositories, reference, newBranch));
result.set(checkoutOrNotify(repositories, reference, newBranch, false));
} finally {
saver.restoreLocalChanges(context);
}
@@ -376,7 +380,7 @@ public class GitCheckoutOperation extends GitBranchOperation {
LOG.info("Couldn't save local changes", e);
notifyError("Couldn't save uncommitted changes.",
String.format("Tried to save uncommitted changes in %s before checkout, but failed with an error.<br/>%s",
saver.getSaverName(), StringUtil.join(e.getMessages())));
saver.getSaverName(), join(e.getMessages())));
return false;
}
}
@@ -384,12 +388,11 @@ public class GitCheckoutOperation extends GitBranchOperation {
/**
* Checks out or shows an error message.
*/
private boolean checkoutOrNotify(@NotNull Collection<GitRepository> repositories,
@NotNull String reference,
@Nullable String newBranch) {
private boolean checkoutOrNotify(@NotNull List<GitRepository> repositories,
@NotNull String reference, @Nullable String newBranch, boolean force) {
GitCompoundResult compoundResult = new GitCompoundResult(myProject);
for (GitRepository repository : repositories) {
compoundResult.append(repository, Git.checkout(repository, reference, newBranch));
compoundResult.append(repository, Git.checkout(repository, reference, newBranch, force));
}
if (compoundResult.totalSuccess()) {
return true;
@@ -137,7 +137,7 @@ class GitDeleteBranchOperation extends GitBranchOperation {
@NotNull
@Override
protected String getRollbackProposal() {
return "However branch deletion has succeeded for the following repositories.:<br/>" +
return "However branch deletion has succeeded for the following " + repositories() + ":<br/>" +
successfulRepositoriesJoined() +
"<br/>You may rollback (recreate " + myBranchName + " in these roots) not to let branches diverge.";
}
@@ -26,8 +26,9 @@ import git4idea.DialogManager;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
* The dialog that is shown when the error "The following files would be overwritten by checkout" happens.
@@ -38,23 +39,26 @@ import java.util.concurrent.atomic.AtomicBoolean;
// TODO "don't ask again" option
class GitWouldBeOverwrittenByCheckoutDialog extends DialogWrapper {
public static final int SMART_CHECKOUT = OK_EXIT_CODE;
public static final int FORCE_CHECKOUT_EXIT_CODE = NEXT_USER_EXIT_CODE;
private final Project myProject;
private final List<Change> myChanges;
/**
* @return true if smart checkout has to be performed, false if user doesn't want to checkout.
*/
static boolean showAndGetAnswer(@NotNull final Project project, @NotNull final List<Change> changes) {
final AtomicBoolean ok = new AtomicBoolean();
static int showAndGetAnswer(@NotNull final Project project, @NotNull final List<Change> changes) {
final AtomicInteger exitCode = new AtomicInteger();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
GitWouldBeOverwrittenByCheckoutDialog dialog = new GitWouldBeOverwrittenByCheckoutDialog(project, changes);
DialogManager.getInstance(project).showDialog(dialog);
ok.set(dialog.isOK());
exitCode.set(dialog.getExitCode());
}
});
return ok.get();
return exitCode.get();
}
private GitWouldBeOverwrittenByCheckoutDialog(@NotNull Project project, @NotNull List<Change> changes) {
@@ -68,8 +72,8 @@ class GitWouldBeOverwrittenByCheckoutDialog extends DialogWrapper {
}
@Override
protected Action getOKAction() {
return super.getOKAction();
protected Action[] createLeftSideActions() {
return new Action[] {new ForceCheckoutAction() };
}
@Override
@@ -93,4 +97,17 @@ class GitWouldBeOverwrittenByCheckoutDialog extends DialogWrapper {
return GitWouldBeOverwrittenByCheckoutDialog.class.getName();
}
private class ForceCheckoutAction extends AbstractAction {
ForceCheckoutAction() {
super("Force checkout");
}
@Override
public void actionPerformed(ActionEvent e) {
close(FORCE_CHECKOUT_EXIT_CODE);
}
}
}
@@ -138,12 +138,17 @@ public class Git {
public static GitCommandResult checkout(@NotNull GitRepository repository,
@NotNull String reference,
@Nullable String newBranch,
boolean force,
@NotNull GitLineHandlerListener... listeners) {
final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECKOUT);
h.setSilent(false);
if (force) {
h.addParameters("--force");
}
if (newBranch == null) { // simply checkout
h.addParameters(reference);
} else { // checkout reference as new branch
}
else { // checkout reference as new branch
h.addParameters("-b", newBranch, reference);
}
for (GitLineHandlerListener listener : listeners) {
@@ -502,8 +502,8 @@ public abstract class GitHandler {
public void setSilent(final boolean silent) {
checkNotStarted();
mySilent = silent;
setStderrSuppressed(true);
setStdoutSuppressed(true);
setStderrSuppressed(silent);
setStdoutSuppressed(silent);
}
/**
@@ -28,7 +28,7 @@ import java.util.regex.Pattern;
*/
class GitPushRejectedDetector implements GitLineHandlerListener {
private static final Pattern REJECTED_PATTERN = Pattern.compile("\\s+! \\[rejected\\]\\s+(\\w+) -> (\\w+) .*");
private static final Pattern REJECTED_PATTERN = Pattern.compile("\\s+! \\[rejected\\]\\s+(\\S+) -> (\\S+) .*");
private final Collection<RejectedRef> myRejectedRefs = new ArrayList<RejectedRef>();
@@ -33,6 +33,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import static git4idea.GitUtil.sortRepositories;
/**
* GitRepositoryManager initializes and stores {@link GitRepository GitRepositories} for Git roots defined in the project.
* @author Kirill Likhodedov
@@ -152,10 +154,10 @@ public final class GitRepositoryManager extends AbstractProjectComponent impleme
* @return all repositories tracked by the manager.
*/
@NotNull
public Collection<GitRepository> getRepositories() {
public List<GitRepository> getRepositories() {
try {
REPO_LOCK.readLock().lock();
return myRepositories.values();
return sortRepositories(myRepositories.values());
}
finally {
REPO_LOCK.readLock().unlock();
@@ -39,7 +39,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.event.HyperlinkEvent;
import java.util.Collection;
import java.util.List;
/**
* <p>
@@ -65,12 +65,9 @@ class GitBranchPopup {
}
/**
*
* @param project
* @param currentRepository Current repository, which means the repository of the currently open or selected file.
* In the case of synchronized branch operations current repository matter much less, but sometimes is used,
* for example, it is preselected in the repositories combobox in the compare branches dialog.
* @return
*/
static GitBranchPopup getInstance(@NotNull Project project, @NotNull GitRepository currentRepository) {
return new GitBranchPopup(project, currentRepository);
@@ -157,7 +154,7 @@ class GitBranchPopup {
}
private void fillWithCommonRepositoryActions(DefaultActionGroup popupGroup, GitRepositoryManager repositoryManager) {
Collection<GitRepository> repositories = repositoryManager.getRepositories();
List<GitRepository> repositories = repositoryManager.getRepositories();
String currentBranch = myMultiRootBranchConfig.getCurrentBranch();
assert currentBranch != null : "Current branch can't be null if branches have not diverged";
popupGroup.add(new GitBranchPopupActions.CurrentBranchAction(currentBranch, " in all roots"));
@@ -33,7 +33,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -56,7 +55,7 @@ class GitBranchPopupActions {
DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
popupGroup.addAction(new CurrentBranchAction(GitBranchUiUtil.getDisplayableBranchText(myRepository), "in root " + GitUIUtil.getShortRepositoryName(myRepository)));
popupGroup.addAction(new NewBranchAction(myProject, Collections.singleton(myRepository), myRepository));
popupGroup.addAction(new NewBranchAction(myProject, Collections.singletonList(myRepository), myRepository));
popupGroup.addAction(new CheckoutRevisionActions(myProject, myRepository));
if (toInsert != null) {
@@ -68,7 +67,7 @@ class GitBranchPopupActions {
Collections.sort(localBranches);
for (GitBranch localBranch : localBranches) {
if (!localBranch.equals(myRepository.getCurrentBranch())) { // don't show current branch in the list
popupGroup.add(new LocalBranchActions(myProject, Collections.singleton(myRepository), localBranch.getName(), myRepository));
popupGroup.add(new LocalBranchActions(myProject, Collections.singletonList(myRepository), localBranch.getName(), myRepository));
}
}
@@ -76,7 +75,7 @@ class GitBranchPopupActions {
List<GitBranch> remoteBranches = new ArrayList<GitBranch>(myRepository.getBranches().getRemoteBranches());
Collections.sort(remoteBranches);
for (GitBranch remoteBranch : remoteBranches) {
popupGroup.add(new RemoteBranchActions(myProject, Collections.singleton(myRepository), remoteBranch.getName(), myRepository));
popupGroup.add(new RemoteBranchActions(myProject, Collections.singletonList(myRepository), remoteBranch.getName(), myRepository));
}
return popupGroup;
@@ -101,10 +100,10 @@ class GitBranchPopupActions {
static class NewBranchAction extends DumbAwareAction {
private final Project myProject;
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
@NotNull private final GitRepository mySelectedRepository;
NewBranchAction(@NotNull Project project, @NotNull Collection<GitRepository> repositories, @NotNull GitRepository selectedRepository) {
NewBranchAction(@NotNull Project project, @NotNull List<GitRepository> repositories, @NotNull GitRepository selectedRepository) {
super("New Branch", "Create and checkout new branch", IconLoader.getIcon("/general/add.png"));
myProject = project;
myRepositories = repositories;
@@ -175,11 +174,11 @@ class GitBranchPopupActions {
static class LocalBranchActions extends ActionGroup {
private final Project myProject;
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
private String myBranchName;
@NotNull private final GitRepository mySelectedRepository;
LocalBranchActions(@NotNull Project project, @NotNull Collection<GitRepository> repositories, @NotNull String branchName,
LocalBranchActions(@NotNull Project project, @NotNull List<GitRepository> repositories, @NotNull String branchName,
@NotNull GitRepository selectedRepository) {
super("", true);
myProject = project;
@@ -202,11 +201,11 @@ class GitBranchPopupActions {
private static class CheckoutAction extends DumbAwareAction {
private final Project myProject;
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
private final String myBranchName;
@NotNull private final GitRepository mySelectedRepository;
CheckoutAction(@NotNull Project project, @NotNull Collection<GitRepository> repositories, @NotNull String branchName,
CheckoutAction(@NotNull Project project, @NotNull List<GitRepository> repositories, @NotNull String branchName,
@NotNull GitRepository selectedRepository) {
super("Checkout");
myProject = project;
@@ -224,11 +223,11 @@ class GitBranchPopupActions {
private static class CheckoutAsNewBranch extends DumbAwareAction {
private final Project myProject;
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
private final String myBranchName;
@NotNull private final GitRepository mySelectedRepository;
CheckoutAsNewBranch(@NotNull Project project, @NotNull Collection<GitRepository> repositories, @NotNull String branchName,
CheckoutAsNewBranch(@NotNull Project project, @NotNull List<GitRepository> repositories, @NotNull String branchName,
@NotNull GitRepository selectedRepository) {
super("Checkout as new branch");
myProject = project;
@@ -254,11 +253,11 @@ class GitBranchPopupActions {
*/
private static class DeleteAction extends DumbAwareAction {
private final Project myProject;
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
private final String myBranchName;
private final GitRepository mySelectedRepository;
DeleteAction(Project project, Collection<GitRepository> repositories, String branchName, GitRepository selectedRepository) {
DeleteAction(Project project, List<GitRepository> repositories, String branchName, GitRepository selectedRepository) {
super("Delete");
myProject = project;
myRepositories = repositories;
@@ -279,11 +278,11 @@ class GitBranchPopupActions {
static class RemoteBranchActions extends ActionGroup {
private final Project myProject;
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
private String myBranchName;
@NotNull private final GitRepository mySelectedRepository;
RemoteBranchActions(@NotNull Project project, @NotNull Collection<GitRepository> repositories, @NotNull String branchName,
RemoteBranchActions(@NotNull Project project, @NotNull List<GitRepository> repositories, @NotNull String branchName,
@NotNull GitRepository selectedRepository) {
super("", true);
myProject = project;
@@ -304,11 +303,11 @@ class GitBranchPopupActions {
private static class CheckoutRemoteBranchAction extends DumbAwareAction {
private final Project myProject;
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
private final String myRemoteBranchName;
@NotNull private final GitRepository mySelectedRepository;
public CheckoutRemoteBranchAction(@NotNull Project project, @NotNull Collection<GitRepository> repositories,
public CheckoutRemoteBranchAction(@NotNull Project project, @NotNull List<GitRepository> repositories,
@NotNull String remoteBranchName, @NotNull GitRepository selectedRepository) {
super("Checkout as new local branch");
myProject = project;
@@ -339,12 +338,12 @@ class GitBranchPopupActions {
private static class CompareAction extends DumbAwareAction {
private final Project myProject;
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
private final String myBranchName;
private final GitRepository mySelectedRepository;
public CompareAction(@NotNull Project project,
@NotNull Collection<GitRepository> repositories,
@NotNull List<GitRepository> repositories,
@NotNull String branchName,
GitRepository selectedRepository) {
super("Compare");
@@ -24,15 +24,16 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author Kirill Likhodedov
*/
public class GitMultiRootBranchConfig {
private final Collection<GitRepository> myRepositories;
private final List<GitRepository> myRepositories;
public GitMultiRootBranchConfig(@NotNull Collection<GitRepository> repositories) {
public GitMultiRootBranchConfig(@NotNull List<GitRepository> repositories) {
myRepositories = repositories;
}
@@ -36,7 +36,7 @@ import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import static git4idea.test.GitExec.*;
@@ -51,7 +51,7 @@ public class GitBranchOperationsTest extends AbstractVcsTestCase {
private static final String NEW_BRANCH = "new_branch";
private static final String MASTER = "master";
private Collection<GitRepository> myRepositories;
private List<GitRepository> myRepositories;
private GitRepository myUltimate;
private GitRepository myCommunity;
private GitRepository myContrib;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 529 B

After

Width:  |  Height:  |  Size: 500 B

+6 -1
View File
@@ -36,7 +36,12 @@
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.remote.GradleApiFacadeManager"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.util.GradleLibraryManager"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangesCalculator"/>
<applicationService serviceInterface="org.jetbrains.plugins.gradle.diff.GradleStructureChangesCalculator"
serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangesCalculator"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleModuleStructureChangesCalculator"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleLibraryDependencyStructureChangesCalculator"/>
<applicationService serviceInterface="org.jetbrains.plugins.gradle.diff.GradleProjectStructureHelper"
serviceImplementation="org.jetbrains.plugins.gradle.diff.GradleProjectStructureHelperImpl"/>
<applicationService serviceInterface="org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager"
serviceImplementation="org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManagerImpl"/>
@@ -15,7 +15,7 @@ import org.jetbrains.plugins.gradle.ui.GradleIcons;
import org.jetbrains.plugins.gradle.util.GradleBundle;
/**
* // TODO den add doc
* Encapsulates initialisation routine of the gradle integration.
*
* @author Denis Zhdanov
* @since 11/3/11 4:01 PM
@@ -42,10 +42,6 @@ public class GradleBootstrap extends AbstractProjectComponent {
}
private void initToolWindow() {
// TODO den don't show tool window if no gradle project is associated with the current project.
if (!Boolean.getBoolean("gradle.show.tool.window")) {
return;
}
final ToolWindowManagerEx manager = ToolWindowManagerEx.getInstanceEx(myProject);
ToolWindow toolWindow = manager.registerToolWindow(GRADLE_TOOL_WINDOW_ID, false, ToolWindowAnchor.RIGHT);
toolWindow.setIcon(GradleIcons.GRADLE_ICON);
@@ -25,11 +25,10 @@ public class GradleDiffUtil {
* Example: particular module has been added at the gradle side. We want to mark that module, its content root(s), dependencies etc
* as gradle-local changes.
*
* @param entity target gradle-local entity
* @return collection of gradle-local changes for the given entity and its interested sub-entities
* @param entity target gradle-local entity
* @param currentChanges holder for the changes built during the current call
*/
public static Set<GradleProjectStructureChange> buildLocalChanges(@NotNull GradleEntity entity) {
final Set<GradleProjectStructureChange> result = new HashSet<GradleProjectStructureChange>();
public static void buildLocalChanges(@NotNull GradleEntity entity, @NotNull final Set<GradleProjectStructureChange> currentChanges) {
entity.invite(new GradleEntityVisitor() {
@Override
public void visit(@NotNull GradleProject project) {
@@ -38,7 +37,7 @@ public class GradleDiffUtil {
@Override
public void visit(@NotNull GradleModule module) {
result.add(new GradleModulePresenceChange(module, null));
currentChanges.add(new GradleModulePresenceChange(module, null));
for (GradleDependency dependency : module.getDependencies()) {
dependency.invite(this);
}
@@ -61,79 +60,52 @@ public class GradleDiffUtil {
@Override
public void visit(@NotNull GradleLibraryDependency dependency) {
result.add(new GradleLibraryDependencyPresenceChange(dependency, null));
currentChanges.add(new GradleLibraryDependencyPresenceChange(dependency, null));
}
});
return result;
}
/**
* Analogues to {@link #buildLocalChanges} but targets intellij entity.
*
* @param module target intellij-local module that doesn't present at the gradle side
* @return collection of intellij-local changes for the given entity and its interested sub-entities
* @param module target intellij-local module that doesn't present at the gradle side
* @param currentChanges holder for the changes built during the current call
*/
public static Set<? extends GradleProjectStructureChange> buildLocalChanges(@NotNull Module module) {
Set<GradleProjectStructureChange> result = new HashSet<GradleProjectStructureChange>();
result.add(new GradleModulePresenceChange(null, module));
public static void buildLocalChanges(@NotNull Module module, @NotNull Set<GradleProjectStructureChange> currentChanges) {
currentChanges.add(new GradleModulePresenceChange(null, module));
// TODO den process module sub-entities here (content roots and dependencies).
return result;
}
/**
* Analogues to {@link #buildLocalChanges} but targets intellij entity.
*
* @param libraryDependency target intellij-local library dependency that doesn't present at the gradle side
* @return collection of intellij-local changes for the given entity and its interested sub-entities
* @param currentChanges holder for the changes built during the current call
*/
public static Set<? extends GradleProjectStructureChange> buildLocalChanges(@NotNull LibraryOrderEntry libraryDependency) {
return Collections.singleton(new GradleLibraryDependencyPresenceChange(null, libraryDependency));
public static void buildLocalChanges(@NotNull LibraryOrderEntry libraryDependency,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
currentChanges.add(new GradleLibraryDependencyPresenceChange(null, libraryDependency));
}
/**
* Performs argument type-based dispatch and delegates to one of strongly typed <code>'buildLocalChanges()'</code> methods.
*
* @param entity target intellij-local entity that doesn't present at the gradle side
* @return collection of intellij-local changes for the given entity and its interested sub-entities
* @param entity target intellij-local entity that doesn't present at the gradle side
* @param currentChanges holder for the changes built during the current call
*/
@NotNull
public static Set<? extends GradleProjectStructureChange> buildLocalChanges(@NotNull Object entity) {
public static void buildLocalChanges(@NotNull Object entity,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
if (entity instanceof GradleEntity) {
return buildLocalChanges((GradleEntity)entity);
buildLocalChanges((GradleEntity)entity, currentChanges);
}
else if (entity instanceof Module) {
return buildLocalChanges((Module)entity);
buildLocalChanges((Module)entity, currentChanges);
}
else if (entity instanceof LibraryOrderEntry) {
return buildLocalChanges((LibraryOrderEntry)entity);
buildLocalChanges((LibraryOrderEntry)entity, currentChanges);
}
else {
return Collections.emptySet();
}
}
/**
* Concatenates given entities into the single collection and returns it.
* <p/>
* The main idea behind this method is that most of the time we don't expect changes at all, hence, corresponding changes calculators
* can use {@link Collections#emptySet()}. However, if some sub-nodes do have changes, attempt
* to {@link Collection#addAll(Collection) merge} them within the empty set mentioned above would cause an exception.
* <p/>
* That's why we provide dedicated method for creating new collection as a merge result.
*
* @param collections collections to merge
* @return merge result
*/
@NotNull
public static Set<GradleProjectStructureChange> concatenate(Collection<? extends GradleProjectStructureChange>... collections) {
Set<GradleProjectStructureChange> result = null;
for (Collection<? extends GradleProjectStructureChange> collection : collections) {
if (result == null) {
result = new HashSet<GradleProjectStructureChange>();
}
result.addAll(collection);
}
return result == null ? Collections.<GradleProjectStructureChange>emptySet() : result;
}
/**
@@ -146,39 +118,34 @@ public class GradleDiffUtil {
* @param gradleEntities entities available at the gradle side
* @param intellijEntities entities available at the intellij side
* @param knownChanges collection that contains known changes about the entities
* @param currentChanges holder for the changes discovered during the current call
* @param <I> target intellij entity type
* @param <G> target gradle entity type
* @return set of changes between the given entity collections
*/
@NotNull
public static <I, G extends GradleEntity> Set<GradleProjectStructureChange> calculate(
public static <I, G extends GradleEntity> void calculate(
@NotNull GradleStructureChangesCalculator<G, I> calculator,
@NotNull Iterable<? extends G> gradleEntities,
@NotNull Iterable<? extends I> intellijEntities,
@NotNull Set<GradleProjectStructureChange> knownChanges)
@NotNull Set<GradleProjectStructureChange> knownChanges,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
Set<GradleProjectStructureChange> result = Collections.emptySet();
Map<Object, I> intellijEntitiesByKeys = new HashMap<Object, I>();
for (I entity : intellijEntities) {
final I previous = intellijEntitiesByKeys.put(calculator.getIntellijKey(entity, knownChanges), entity);
final I previous = intellijEntitiesByKeys.put(calculator.getIntellijKey(entity), entity);
assert previous == null;
}
for (G gradleEntity: gradleEntities) {
I intellijEntity = intellijEntitiesByKeys.remove(calculator.getGradleKey(gradleEntity, knownChanges));
Set<GradleProjectStructureChange> changesToMerge;
if (intellijEntity == null) {
changesToMerge = buildLocalChanges(gradleEntity);
buildLocalChanges(gradleEntity, currentChanges);
}
else {
changesToMerge = calculator.calculate(gradleEntity, intellijEntity, knownChanges);
calculator.calculate(gradleEntity, intellijEntity, knownChanges, currentChanges);
}
result = concatenate(result, changesToMerge);
}
for (I entity : intellijEntitiesByKeys.values()) {
result = concatenate(result, buildLocalChanges(entity));
buildLocalChanges(entity, currentChanges);
}
return result;
}
}
@@ -4,7 +4,6 @@ import com.intellij.openapi.roots.LibraryOrderEntry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.GradleLibraryDependency;
import java.util.Collections;
import java.util.Set;
/**
@@ -14,20 +13,19 @@ import java.util.Set;
public class GradleLibraryDependencyStructureChangesCalculator
implements GradleStructureChangesCalculator<GradleLibraryDependency, LibraryOrderEntry>
{
@NotNull
@Override
public Set<GradleProjectStructureChange> calculate(@NotNull GradleLibraryDependency gradleEntity,
@NotNull LibraryOrderEntry intellijEntity,
@NotNull Set<GradleProjectStructureChange> knownChanges)
public void calculate(@NotNull GradleLibraryDependency gradleEntity,
@NotNull LibraryOrderEntry intellijEntity,
@NotNull Set<GradleProjectStructureChange> knownChanges,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
// TODO den implement
return Collections.emptySet();
}
@NotNull
@Override
public Object getIntellijKey(@NotNull LibraryOrderEntry entity, @NotNull Set<GradleProjectStructureChange> knownChanges) {
// TODO den consider the known changes
public Object getIntellijKey(@NotNull LibraryOrderEntry entity) {
final String result = entity.getLibraryName();
return result == null ? "" : result;
}
@@ -34,24 +34,30 @@ import java.util.Set;
*/
public class GradleModuleStructureChangesCalculator implements GradleStructureChangesCalculator<GradleModule, Module> {
private final GradleLibraryDependencyStructureChangesCalculator myLibraryDependencyCalculator
= new GradleLibraryDependencyStructureChangesCalculator();
@NotNull
private final GradleLibraryDependencyStructureChangesCalculator myLibraryDependencyCalculator;
private final GradleProjectStructureHelper myStructureHelper;
public GradleModuleStructureChangesCalculator(@NotNull GradleLibraryDependencyStructureChangesCalculator libraryDependencyCalculator,
@NotNull GradleProjectStructureHelper structureHelper)
{
myLibraryDependencyCalculator = libraryDependencyCalculator;
myStructureHelper = structureHelper;
}
@Override
public Set<GradleProjectStructureChange> calculate(@NotNull GradleModule gradleEntity,
@NotNull Module intellijEntity,
@NotNull Set<GradleProjectStructureChange> knownChanges)
public void calculate(@NotNull GradleModule gradleEntity,
@NotNull Module intellijEntity,
@NotNull Set<GradleProjectStructureChange> knownChanges,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
//TODO den process module-local settings
//TODO den process content roots
return checkDependencies(gradleEntity, intellijEntity, knownChanges);
//TODO den process content roots
checkDependencies(gradleEntity, intellijEntity, knownChanges, currentChanges);
}
@NotNull
@Override
public Object getIntellijKey(@NotNull Module entity, @NotNull Set<GradleProjectStructureChange> knownChanges) {
// TODO den consider the known changes
public Object getIntellijKey(@NotNull Module entity) {
return entity.getName();
}
@@ -62,9 +68,10 @@ public class GradleModuleStructureChangesCalculator implements GradleStructureCh
return entity.getName();
}
private Set<GradleProjectStructureChange> checkDependencies(@NotNull GradleModule gradleModule,
@NotNull Module intellijModule,
@NotNull Set<GradleProjectStructureChange> knownChanges)
private void checkDependencies(@NotNull GradleModule gradleModule,
@NotNull Module intellijModule,
@NotNull Set<GradleProjectStructureChange> knownChanges,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
// Prepare intellij part.
final List<ModuleOrderEntry> intellijModuleDependencies = new ArrayList<ModuleOrderEntry>();
@@ -82,11 +89,10 @@ public class GradleModuleStructureChangesCalculator implements GradleStructureCh
return libraryOrderEntry;
}
};
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(intellijModule);
for (OrderEntry orderEntry : moduleRootManager.getOrderEntries()) {
for (OrderEntry orderEntry : myStructureHelper.getOrderEntries(intellijModule)) {
orderEntry.accept(policy, null);
}
// Prepare gradle part.
final List<GradleModuleDependency> gradleModuleDependencies = new ArrayList<GradleModuleDependency>();
final List<GradleLibraryDependency> gradleLibraryDependencies = new ArrayList<GradleLibraryDependency>();
@@ -104,12 +110,10 @@ public class GradleModuleStructureChangesCalculator implements GradleStructureCh
for (GradleDependency dependency : gradleModule.getDependencies()) {
dependency.invite(visitor);
}
// Calculate changes.
// TODO den process module dependencies here as well.
final Set<GradleProjectStructureChange> libraryChanges
= GradleDiffUtil.calculate(myLibraryDependencyCalculator, gradleLibraryDependencies, intellijLibraryDependencies, knownChanges);
return libraryChanges;
GradleDiffUtil.calculate(myLibraryDependencyCalculator, gradleLibraryDependencies, intellijLibraryDependencies,
knownChanges, currentChanges);
}
}
@@ -1,21 +1,15 @@
package org.jetbrains.plugins.gradle.diff;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.GradleModule;
import org.jetbrains.plugins.gradle.model.GradleProject;
import java.util.Collections;
import java.util.List;
import java.util.Collection;
import java.util.Set;
import static java.util.Arrays.asList;
import static org.jetbrains.plugins.gradle.diff.GradleDiffUtil.concatenate;
/**
* Encapsulates functionality of calculating changes between Gradle and IntelliJ IDEA project hierarchies.
* <p/>
@@ -26,25 +20,31 @@ import static org.jetbrains.plugins.gradle.diff.GradleDiffUtil.concatenate;
*/
public class GradleProjectStructureChangesCalculator implements GradleStructureChangesCalculator<GradleProject, Project> {
private final GradleModuleStructureChangesCalculator myModuleChangesCalculator = new GradleModuleStructureChangesCalculator();
private final GradleModuleStructureChangesCalculator myModuleChangesCalculator;
private final GradleProjectStructureHelper myStructureHelper;
public GradleProjectStructureChangesCalculator(@NotNull GradleModuleStructureChangesCalculator moduleCalculator,
@NotNull GradleProjectStructureHelper structureHelper) {
myModuleChangesCalculator = moduleCalculator;
myStructureHelper = structureHelper;
}
@NotNull
@Override
public Set<GradleProjectStructureChange> calculate(@NotNull GradleProject gradleEntity,
@NotNull Project intellijEntity,
@NotNull Set<GradleProjectStructureChange> knownChanges)
public void calculate(@NotNull GradleProject gradleEntity,
@NotNull Project intellijEntity,
@NotNull Set<GradleProjectStructureChange> knownChanges,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
final Set<GradleProjectStructureChange> result = calculateProjectChanges(gradleEntity, intellijEntity, knownChanges);
calculateProjectChanges(gradleEntity, intellijEntity, currentChanges);
final Set<? extends GradleModule> gradleSubEntities = gradleEntity.getModules();
final List<Module> intellijSubEntities = asList(ModuleManager.getInstance(intellijEntity).getModules());
return concatenate(result, GradleDiffUtil.calculate(myModuleChangesCalculator, gradleSubEntities, intellijSubEntities, knownChanges));
final Collection<Module> intellijSubEntities = myStructureHelper.getModules(intellijEntity);
GradleDiffUtil.calculate(myModuleChangesCalculator, gradleSubEntities, intellijSubEntities, knownChanges, currentChanges);
}
@NotNull
@Override
public Object getIntellijKey(@NotNull Project entity, @NotNull Set<GradleProjectStructureChange> knownChanges) {
// TODO den consider the known changes
public Object getIntellijKey(@NotNull Project entity) {
return entity.getName();
}
@@ -55,43 +55,33 @@ public class GradleProjectStructureChangesCalculator implements GradleStructureC
return entity.getName();
}
@NotNull
private static Set<GradleProjectStructureChange> calculateProjectChanges(@NotNull GradleProject gradleProject,
@NotNull Project intellijProject,
@NotNull Set<GradleProjectStructureChange> knownChanges)
private void calculateProjectChanges(@NotNull GradleProject gradleProject,
@NotNull Project intellijProject,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
final Set<GradleProjectStructureChange> nameChanges = checkName(gradleProject, intellijProject, knownChanges);
final Set<GradleProjectStructureChange> levelChanges = checkLanguageLevel(gradleProject, intellijProject, knownChanges);
return concatenate(nameChanges, levelChanges);
checkName(gradleProject, intellijProject, currentChanges);
checkLanguageLevel(gradleProject, intellijProject, currentChanges);
}
@NotNull
private static Set<GradleProjectStructureChange> checkName(@NotNull GradleProject gradleProject,
@NotNull Project intellijProject,
@NotNull Set<GradleProjectStructureChange> knownChanges)
private static void checkName(@NotNull GradleProject gradleProject,
@NotNull Project intellijProject,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
String gradleName = gradleProject.getName();
String intellijName = intellijProject.getName();
if (gradleName.equals(intellijName)) {
return Collections.emptySet();
if (!gradleName.equals(intellijName)) {
currentChanges.add(new GradleRenameChange(GradleRenameChange.Entity.PROJECT, gradleName, intellijName));
}
final GradleRenameChange change = new GradleRenameChange(GradleRenameChange.Entity.PROJECT, gradleName, intellijName);
return knownChanges.contains(change) ? Collections.<GradleProjectStructureChange>emptySet()
: Collections.<GradleProjectStructureChange>singleton(change);
}
@NotNull
private static Set<GradleProjectStructureChange> checkLanguageLevel(@NotNull GradleProject gradleProject,
@NotNull Project intellijProject,
@NotNull Set<GradleProjectStructureChange> knownChanges)
private void checkLanguageLevel(@NotNull GradleProject gradleProject,
@NotNull Project intellijProject,
@NotNull Set<GradleProjectStructureChange> currentChanges)
{
LanguageLevel gradleLevel = gradleProject.getLanguageLevel();
LanguageLevel intellijLevel = LanguageLevelProjectExtension.getInstance(intellijProject).getLanguageLevel();
if (gradleLevel == intellijLevel) {
return Collections.emptySet();
LanguageLevel intellijLevel = myStructureHelper.getLanguageLevel(intellijProject);
if (gradleLevel != intellijLevel) {
currentChanges.add(new GradleLanguageLevelChange(gradleLevel, intellijLevel));
}
final GradleLanguageLevelChange change = new GradleLanguageLevelChange(gradleLevel, intellijLevel);
return knownChanges.contains(change) ? Collections.<GradleProjectStructureChange>emptySet()
: Collections.<GradleProjectStructureChange>singleton(change);
}
}
@@ -0,0 +1,37 @@
package org.jetbrains.plugins.gradle.diff;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* IntelliJ code provides a lot of statical bindings to the interested pieces of data. For example we need to execute code
* like below to get list of modules for the target project:
* <pre>
* ModuleManager.getInstance(project).getModules()
* </pre>
* That means that it's not possible to test target classes in isolation if corresponding infrastructure is not set up.
* However, we don't want to set it up if we execute a simple standalone test.
* <p/>
* This interface is intended to encapsulate access to the underlying project infrastructure.
* <p/>
* Implementations of this interface are expected to be thread-safe.
*
* @author Denis Zhdanov
* @since 1/26/12 11:32 AM
*/
public interface GradleProjectStructureHelper {
@NotNull
LanguageLevel getLanguageLevel(@NotNull Project project);
@NotNull
Collection<Module> getModules(@NotNull Project project);
@NotNull
Collection<OrderEntry> getOrderEntries(@NotNull Module module);
}
@@ -0,0 +1,38 @@
package org.jetbrains.plugins.gradle.diff;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collection;
/**
* @author Denis Zhdanov
* @since 1/26/12 11:54 AM
*/
public class GradleProjectStructureHelperImpl implements GradleProjectStructureHelper {
@NotNull
@Override
public LanguageLevel getLanguageLevel(@NotNull Project project) {
return LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
}
@NotNull
@Override
public Collection<Module> getModules(@NotNull Project project) {
return Arrays.asList(ModuleManager.getInstance(project).getModules());
}
@NotNull
@Override
public Collection<OrderEntry> getOrderEntries(@NotNull Module module) {
return Arrays.asList(ModuleRootManager.getInstance(module).getOrderEntries());
}
}
@@ -18,17 +18,60 @@ import java.util.Set;
*/
public interface GradleStructureChangesCalculator<G extends GradleEntity, I> {
// TODO den add doc
@NotNull
Set<GradleProjectStructureChange> calculate(@NotNull G gradleEntity,
@NotNull I intellijEntity,
@NotNull Set<GradleProjectStructureChange> knownChanges);
/**
* Calculates changes between the given entities.
*
* @param gradleEntity target gradle entity
* @param intellijEntity target intellij entity
* @param knownChanges changes between the gradle and intellij project structure that has been known up until now
* @param currentChanges holder for the changes between the given entities discovered by the current call. Note that
* it must contain the change objects that have been known (contained at the <code>'knownChanges'</code>)
* but are still in place
*/
void calculate(@NotNull G gradleEntity,
@NotNull I intellijEntity,
@NotNull Set<GradleProjectStructureChange> knownChanges,
@NotNull Set<GradleProjectStructureChange> currentChanges);
// TODO den add doc
/**
* There are three possible situations when we compare a set of gradle entities with a set of intellij entities:
* <pre>
* <ul>
* <li>particular entity presents only at the gradle side;</li>
* <li>particular entity presents only at the intellij side;</li>
* <li>particular gradle entity is matched to particular intellij entity (they may have difference in their settings though);</li>
* </ul>
* </pre>
* <p/>
* The general idea is to map evey item at the given sets of gradle and intellij entities to particular key (both gradle and
* intellij keys are expected to belong to the same class) and then compare them. Matched keys shows that corresponding
* entities should be {@link #calculate(GradleEntity, Object, Set) compared to each other}; non-matched indicate that corresponding
* entities are gradle- or intellij-local.
* <p/>
* This method allows to match intellij entity to the target key.
*
* @param entity intellij entity to match
* @return key for the given entity
* @see #getGradleKey(GradleEntity, Set)
*/
@NotNull
Object getIntellijKey(@NotNull I entity, @NotNull Set<GradleProjectStructureChange> knownChanges);
// TODO den add doc
Object getIntellijKey(@NotNull I entity);
/**
* Serves the same purpose as {@link #getIntellijKey(Object)} but targets gradle entities.
* <p/>
* There is a possible case that two corresponding gradle and intellij entities differ from each other by the setting that
* affects the resulting key (e.g. we may use module name as a key for 'module' entities and intellij module name differs from
* the name of the corresponding gradle module). We need to match only in one direction then (e.g. consider a situation when
* particular module is named differently at gradle and intellij. We shouldn't consider that change during both
* {@code intellij-entity -> key} and {@code gradle-entity -> key} mappings because that would produce two different keys).
* So, we take into consideration the known changes only during {@code gradle-entity -> key} processing.
*
* @param entity target gradle entity that should be mapped to a key
* @param knownChanges known changes between the gradle and intellij structures
* @return key for the given entity
* @see #getIntellijKey(Object)
*/
@NotNull
Object getGradleKey(@NotNull G entity, @NotNull Set<GradleProjectStructureChange> knownChanges);
}
@@ -18,7 +18,9 @@ public interface GradleProjectStructureChangeListener {
/**
* Notifies current listener on the newly discovered changes between the gradle and intellij project models.
*
* @param changes newly discovered changes between the gradle and intellij project models.
* @param oldChanges changes between the gradle and intellij project models that had been known prior to the current update
* @param currentChanges the most up-to-date changes between the gradle and intellij project models
*/
void onChanges(@NotNull Collection<GradleProjectStructureChange> changes);
void onChanges(@NotNull Collection<GradleProjectStructureChange> oldChanges,
@NotNull Collection<GradleProjectStructureChange> currentChanges);
}
@@ -2,15 +2,15 @@ package org.jetbrains.plugins.gradle.sync;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.util.containers.ConcurrentHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChange;
import org.jetbrains.plugins.gradle.diff.GradleProjectStructureChangesCalculator;
import org.jetbrains.plugins.gradle.diff.GradleStructureChangesCalculator;
import org.jetbrains.plugins.gradle.model.GradleProject;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicReference;
/**
* // TODO den add doc
@@ -23,11 +23,14 @@ import java.util.concurrent.CopyOnWriteArraySet;
public class GradleProjectStructureChangesModel extends AbstractProjectComponent {
private final Set<GradleProjectStructureChangeListener> myListeners = new CopyOnWriteArraySet<GradleProjectStructureChangeListener>();
private final Set<GradleProjectStructureChange> myChanges = new ConcurrentHashSet<GradleProjectStructureChange>();
private final AtomicReference<Set<GradleProjectStructureChange>> myChanges
= new AtomicReference<Set<GradleProjectStructureChange>>(new HashSet<GradleProjectStructureChange>());
private final GradleProjectStructureChangesCalculator myChangesCalculator;
private final GradleStructureChangesCalculator<GradleProject, Project> myChangesCalculator;
public GradleProjectStructureChangesModel(@NotNull Project project, @NotNull GradleProjectStructureChangesCalculator changesCalculator) {
public GradleProjectStructureChangesModel(@NotNull Project project,
@NotNull GradleStructureChangesCalculator<GradleProject, Project> changesCalculator)
{
super(project);
myChangesCalculator = changesCalculator;
}
@@ -44,15 +47,22 @@ public class GradleProjectStructureChangesModel extends AbstractProjectComponent
* </li>
* <li>{@link #addListener(GradleProjectStructureChangeListener) Registered listeners} are notified if any new change is detected;</li>
* </ol>
* <p/>
* <b>Note:</b> it's very important that the listeners are notified <b>after</b> the actual state change, i.e. {@link #getChanges()}
* during the update returns up-to-date data.
*
* @param gradleProject gradle project to sync with
*/
public void update(@NotNull GradleProject gradleProject) {
Set<GradleProjectStructureChange> knownChanges = new HashSet<GradleProjectStructureChange>(myChanges);
final Set<GradleProjectStructureChange> newChanges = myChangesCalculator.calculate(gradleProject, myProject, knownChanges);
myChanges.addAll(newChanges);
Set<GradleProjectStructureChange> knownChanges = new HashSet<GradleProjectStructureChange>(myChanges.get());
Set<GradleProjectStructureChange> currentChanges = new HashSet<GradleProjectStructureChange>();
myChangesCalculator.calculate(gradleProject, myProject, knownChanges, currentChanges);
if (currentChanges.equals(knownChanges)) {
return;
}
myChanges.set(currentChanges);
for (GradleProjectStructureChangeListener listener : myListeners) {
listener.onChanges(newChanges);
listener.onChanges(knownChanges, currentChanges);
}
}
@@ -72,6 +82,6 @@ public class GradleProjectStructureChangesModel extends AbstractProjectComponent
*/
@NotNull
public Set<GradleProjectStructureChange> getChanges() {
return myChanges;
return myChanges.get();
}
}
@@ -8,6 +8,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.RootPolicy;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -25,6 +26,8 @@ import org.jetbrains.plugins.gradle.util.GradleConstants;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
@@ -51,6 +54,9 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
*/
private final Map<String, DefaultMutableTreeNode> myModuleDependencies = new HashMap<String, DefaultMutableTreeNode>();
private final Map<String, DefaultMutableTreeNode> myModules = new HashMap<String, DefaultMutableTreeNode>();
private final TreeNode[] myNodeHolder = new TreeNode[1];
private final int[] myIndexHolder = new int[1];
private final GradleProjectStructureChangesModel myChangesModel;
@@ -62,11 +68,15 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
myChangesModel = model;
myChangesModel.addListener(new GradleProjectStructureChangeListener() {
@Override
public void onChanges(@NotNull final Collection<GradleProjectStructureChange> changes) {
public void onChanges(@NotNull final Collection<GradleProjectStructureChange> oldChanges,
@NotNull final Collection<GradleProjectStructureChange> currentChanges)
{
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
updateTree(changes);
updateTree(currentChanges);
processObsoleteChanges(ContainerUtil.subtract(oldChanges, currentChanges));
}
});
}
@@ -84,6 +94,7 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
constraints.fill = GridBagConstraints.BOTH;
constraints.weightx = constraints.weighty = 1;
myContent.add(tree, constraints);
myContent.setBackground(tree.getBackground());
return treeModel;
}
@@ -237,4 +248,83 @@ public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
});
}
}
/**
* Updates the tree state considering that the given changes are obsolete.
* <p/>
* Example:
* <pre>
* <ol>
* <li>There is a particular intellij-local library (change from the gradle project structure);</li>
* <li>Corresponding node is shown at the current UI;</li>
* <li>The library is removed, i.e. corresponding change has become obsolete;</li>
* <li>This method is notified within the obsolete change and is expected to remove the corresponding node;</li>
* </ol>
* </pre>
*/
private void processObsoleteChanges(Collection<GradleProjectStructureChange> changes) {
for (GradleProjectStructureChange change : changes) {
change.invite(new GradleProjectStructureChangeVisitor() {
@Override
public void visit(@NotNull GradleRenameChange change) {
// TODO den implement
}
@Override
public void visit(@NotNull GradleProjectStructureChange change) {
// TODO den implement
}
@Override
public void visit(@NotNull GradleModulePresenceChange change) {
// TODO den implement
}
@Override
public void visit(@NotNull GradleLibraryDependencyPresenceChange change) {
// We need to remove the corresponding node then.
String moduleName;
Object library;
final GradleLibraryDependency gradleEntity = change.getGradleEntity();
final LibraryOrderEntry intellijEntity = change.getIntellijEntity();
assert gradleEntity != null || intellijEntity != null;
if (gradleEntity == null) {
moduleName = intellijEntity.getOwnerModule().getName();
library = intellijEntity;
}
else {
moduleName = gradleEntity.getOwnerModule().getName();
library = gradleEntity;
}
final DefaultMutableTreeNode holder = myModuleDependencies.get(moduleName);
if (holder == null) {
return;
}
for (DefaultMutableTreeNode node = holder.getFirstLeaf(); node != null; node = node.getNextSibling()) {
GradleProjectStructureNodeDescriptor<?> descriptor = (GradleProjectStructureNodeDescriptor<?>)node.getUserObject();
if (descriptor.getElement().equals(library)) {
removeNode(node);
return;
}
}
}
});
}
}
private void removeNode(@NotNull TreeNode node) {
final MutableTreeNode parent = (MutableTreeNode)node.getParent();
if (parent == null) {
return;
}
int i = parent.getIndex(node);
if (i <= 0) {
assert false : node;
return;
}
parent.remove(i);
myIndexHolder[0] = i;
myNodeHolder[0] = node;
myTreeModel.nodesWereRemoved(parent, myIndexHolder, myNodeHolder);
}
}
@@ -43,7 +43,12 @@ public class GradleResolveProjectTask extends AbstractGradleTask {
return;
}
final GradleProjectStructureChangesModel model = myIntellijProject.getComponent(GradleProjectStructureChangesModel.class);
model.update(project);
if (model != null) {
// This task may be called during the 'import from gradle' processing, hence, no project-level IoC is up.
// Model update is necessary for the correct tool window project structure diff showing but we don't have
// gradle tool window on this stage.
model.update(project);
}
}
@Nullable
@@ -0,0 +1,76 @@
package org.jetbrains.plugins.gradle.sync;
import com.intellij.openapi.project.Project
import org.jetbrains.plugins.gradle.testutil.ChangeBuilder
import org.jetbrains.plugins.gradle.testutil.GradleProjectBuilder
import org.jetbrains.plugins.gradle.testutil.IntellijProjectBuilder
import org.junit.Before
import org.junit.Test
import org.picocontainer.defaults.DefaultPicoContainer
import org.jetbrains.plugins.gradle.diff.*
import static org.junit.Assert.assertEquals
/**
* @author Denis Zhdanov
* @since 01/25/2012
*/
public class GradleProjectStructureChangesModelTest {
private GradleProjectStructureChangesModel myModel;
def gradle;
def intellij;
def changes;
@Before
public void setUp() {
gradle = new GradleProjectBuilder()
intellij = new IntellijProjectBuilder()
changes = new ChangeBuilder()
def container = new DefaultPicoContainer()
container.registerComponentInstance(Project, intellij.project)
container.registerComponentInstance(GradleProjectStructureHelper, intellij.projectStructureHelper as GradleProjectStructureHelper)
container.registerComponentImplementation(GradleProjectStructureChangesModel)
container.registerComponentImplementation(GradleStructureChangesCalculator, GradleProjectStructureChangesCalculator)
container.registerComponentImplementation(GradleModuleStructureChangesCalculator)
container.registerComponentImplementation(GradleLibraryDependencyStructureChangesCalculator)
myModel = container.getComponentInstance(GradleProjectStructureChangesModel.class) as GradleProjectStructureChangesModel
}
@Test
public void mergeGradleLocalToIntellij() {
gradle {
module {
dependencies {
lib(name: "lib1")
lib(name: "lib2")
} } }
intellij {
module {
dependencies {
lib(name: "lib1")
} } }
myModel.update(gradle.project)
checkChanges {
presence {
lib(gradle: gradle.modules.dependencies.flatten().findAll { it.name == "lib2" })
}
}
gradle {
module {
dependencies {
lib(name: "lib1")
} } }
myModel.update(gradle.project)
assertEquals([].toSet(), myModel.changes)
}
private def checkChanges(c) {
c.delegate = changes
assertEquals(c(), myModel.changes)
}
}
@@ -0,0 +1,68 @@
package org.jetbrains.plugins.gradle.testutil
import com.intellij.pom.java.LanguageLevel;
/**
* @author Denis Zhdanov
* @since 1/25/12 4:06 PM
*/
public abstract class AbstractProjectBuilder extends BuilderSupport {
private static final def SAME_TOKEN = "same"
private static int COUNTER
def project
def modules = []
def libraries = [:].withDefault { createLibrary(it.name?: same, it.paths?: [:]) }
def dependencies = [:].withDefault {[]}
@Override
protected void setParent(Object parent, Object child) {
}
@Override
protected Object createNode(Object name) {
switch (name) {
case "call": return createNode("project", [name: same])
case "module": return createNode(name, [name: same])
case "dependencies": return getCurrent() // Assuming that 'current' is a module object
}
}
@Override
protected Object createNode(Object name, Object value) {
return null
}
@Override
protected Object createNode(Object name, Map attributes) {
switch (name) {
case "project":
reset()
return project = createProject(attributes.name?: same, attributes.langLevel?: LanguageLevel.JDK_1_6)
case "module": def module = createModule(attributes.name?: same); modules << module; return module
case "lib":
def module = getCurrent()
def dep = createLibraryDependency(module, libraries[attributes])
dependencies[module] << dep
return dep
}
}
@Override
protected Object createNode(Object name, Map attributes, Object value) {
return null
}
protected abstract def createProject(String name, LanguageLevel languageLevel)
protected abstract def createModule(String name)
protected abstract def createLibrary(String name, Map paths)
protected abstract def createLibraryDependency(module, library)
protected String getUnique() { "./${COUNTER++}" }
protected String getSame() { SAME_TOKEN }
private def reset() {
[modules, dependencies, libraries]*.clear()
}
}
@@ -0,0 +1,47 @@
package org.jetbrains.plugins.gradle.testutil;
import org.jetbrains.plugins.gradle.diff.GradleLibraryDependencyPresenceChange
/**
* @author Denis Zhdanov
* @since 1/26/12 3:25 PM
*/
public class ChangeBuilder extends BuilderSupport {
def changes = []
@Override
protected void setParent(Object parent, Object child) {
}
@Override
protected Object createNode(Object name) {
if (current == null) {
changes = []
}
changes
}
@Override
protected Object createNode(Object name, Object value) { changes }
@Override
protected Object createNode(Object name, Map attributes) {
switch (name) {
case "presence": return changes
case "lib":
changes.addAll attributes.gradle.collect { new GradleLibraryDependencyPresenceChange(it, null)}
changes.addAll attributes.intellij.collect { new GradleLibraryDependencyPresenceChange(null, it)}
return
}
}
@Override
protected Object createNode(Object name, Map attributes, Object value) { changes }
@Override
protected Object postNodeCompletion(Object parent, Object node) {
parent == null ? changes.toSet() : node
}
}
@@ -0,0 +1,46 @@
package org.jetbrains.plugins.gradle.testutil
import org.jetbrains.plugins.gradle.model.GradleProject
import org.jetbrains.plugins.gradle.model.GradleModule
import org.jetbrains.plugins.gradle.model.GradleLibraryDependency
import org.jetbrains.plugins.gradle.model.GradleLibrary
import org.jetbrains.plugins.gradle.model.LibraryPathType
import com.intellij.pom.java.LanguageLevel
/**
* @author Denis Zhdanov
* @since 1/25/12 1:29 PM
*/
class GradleProjectBuilder extends AbstractProjectBuilder {
@Override
protected createProject(String name, LanguageLevel languageLevel) {
def result = new GradleProject(same, same)
result.name = name
result.languageLevel = languageLevel
result
}
@Override
protected createModule(String name) {
def result = new GradleModule(name, unique)
project.addModule(result)
result
}
@Override
protected createLibrary(String name, Map paths) {
def result = new GradleLibrary(name)
(paths.bin?: [same]).each { result.addPath(LibraryPathType.BINARY, it) }
(paths.src?: [same]).each { result.addPath(LibraryPathType.SOURCE, it) }
(paths.doc?: [same]).each { result.addPath(LibraryPathType.DOC, it) }
result
}
@Override
protected createLibraryDependency(module, library) {
def result = new GradleLibraryDependency(module, library)
module.addDependency(result)
result
}
}
@@ -0,0 +1,49 @@
package org.jetbrains.plugins.gradle.testutil
import com.intellij.pom.java.LanguageLevel
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.RootPolicy
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.roots.LibraryOrderEntry
import groovy.mock.interceptor.StubFor
import com.intellij.openapi.project.Project
/**
* @author Denis Zhdanov
* @since 1/25/12 3:09 PM
*/
class IntellijProjectBuilder extends AbstractProjectBuilder {
def projectStub = [:]
def project = projectStub as Project
def projectStructureHelper = [
getModules: { modules },
getOrderEntries: { dependencies[it] }
]
@Override
protected createProject(String name, LanguageLevel languageLevel) {
projectStub.getName = { name }
projectStructureHelper.getLanguageLevel = { languageLevel }
project
}
@Override
protected createModule(String name) {
[ getName: { name } ] as Module
}
@Override
protected createLibrary(String name, Map paths) {
[ getName: { name } ] as Library
}
@Override
protected createLibraryDependency(module, library) {
def stub = [:]
def result = stub as LibraryOrderEntry
stub.accept = { policy, defaultValue -> policy.visitLibraryOrderEntry(result, defaultValue) }
stub.getLibraryName = { library.name }
result
}
}
@@ -16,16 +16,19 @@
package com.intellij.execution.junit;
import com.intellij.execution.CantRunException;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.configurations.*;
import com.intellij.execution.testframework.SourceScope;
import com.intellij.execution.util.JavaParametersUtil;
import com.intellij.execution.util.ProgramParametersUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.JavaDirectoryService;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScopes;
@@ -80,14 +83,8 @@ class TestDirectory extends TestPackage {
@Override
public void checkConfiguration() throws RuntimeConfigurationException {
if (myConfiguration.isAlternativeJrePathEnabled()) {
if (myConfiguration.getAlternativeJrePath() == null ||
myConfiguration.getAlternativeJrePath().length() == 0 ||
!JavaSdk.checkForJre(myConfiguration.getAlternativeJrePath())) {
throw new RuntimeConfigurationWarning(
ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", myConfiguration.getAlternativeJrePath()));
}
}
JavaParametersUtil.checkAlternativeJRE(myConfiguration);
ProgramParametersUtil.checkWorkingDirectoryExist(myConfiguration, myConfiguration.getProject(), myConfiguration.getConfigurationModule().getModule());
final String dirName = myConfiguration.getPersistentData().getDirName();
if (dirName == null || dirName.isEmpty()) {
throw new RuntimeConfigurationError("Directory is not specified");
@@ -36,13 +36,13 @@ import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.testframework.*;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.util.JavaParametersUtil;
import com.intellij.execution.util.ProgramParametersUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.JavaSdkType;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
@@ -179,14 +179,8 @@ public abstract class TestObject implements JavaCommandLine {
};
public void checkConfiguration() throws RuntimeConfigurationException{
if (myConfiguration.isAlternativeJrePathEnabled()){
if (myConfiguration.getAlternativeJrePath() == null ||
myConfiguration.getAlternativeJrePath().length() == 0 ||
!JavaSdk.checkForJre(myConfiguration.getAlternativeJrePath())){
throw new RuntimeConfigurationWarning(
ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", myConfiguration.getAlternativeJrePath()));
}
}
JavaParametersUtil.checkAlternativeJRE(myConfiguration);
ProgramParametersUtil.checkWorkingDirectoryExist(myConfiguration, myConfiguration.getProject(), myConfiguration.getConfigurationModule().getModule());
}
public SourceScope getSourceScope() {
@@ -29,6 +29,8 @@ import com.intellij.execution.configurations.*;
import com.intellij.execution.junit.RefactoringListeners;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testframework.SourceScope;
import com.intellij.execution.util.JavaParametersUtil;
import com.intellij.execution.util.ProgramParametersUtil;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.SettingsEditor;
@@ -338,6 +340,8 @@ public class TestNGConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
}
}
JavaRunConfigurationExtensionManager.checkConfigurationIsValid(this);
ProgramParametersUtil.checkWorkingDirectoryExist(this, getProject(), getConfigurationModule().getModule());
JavaParametersUtil.checkAlternativeJRE(this);
//TODO add various checks here
}
@@ -211,7 +211,7 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn
dups.add(proxy);
}
}
final String testMethodDescriptor = result.getTestClass() + result.getMethod();
final String testMethodDescriptor = TestProxy.toDisplayText(result, project);
if (startedMethods.contains(testMethodDescriptor)) {
total++;
}
@@ -93,6 +93,7 @@ public class TestNGUtil
}
public static final String TEST_ANNOTATION_FQN = Test.class.getName();
public static final String FACTORY_ANNOTATION_FQN = Factory.class.getName();
public static final String[] CONFIG_ANNOTATIONS_FQN = {
Configuration.class.getName(),
Factory.class.getName(),
@@ -199,6 +200,7 @@ public class TestNGUtil
PsiClass psiClass = (PsiClass) element;
for (PsiMethod method : psiClass.getAllMethods()) {
if (AnnotationUtil.isAnnotated(method, TEST_ANNOTATION_FQN, false, true)) return true;
if (AnnotationUtil.isAnnotated(method, FACTORY_ANNOTATION_FQN, false, true)) return true;
if (hasTestJavaDoc(method, checkJavadoc)) return true;
}
} else if (element instanceof PsiMethod) {
@@ -1,18 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.uiDesigner.wizard.BeanStep">
<grid id="2ea7d" binding="myComponent" row-count="7" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="2ea7d" binding="myComponent" layout-manager="GridLayoutManager" row-count="7" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="120" y="88" width="383" height="210"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0"/>
<xy x="120" y="88" width="450" height="210"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="bdf40" class="javax.swing.JRadioButton" binding="myRbBindToNewBean">
<constraints>
<xy x="2" y="2" width="110" height="22"/>
<grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0"/>
<grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/UIDesignerBundle" key="radio.create.new.bean"/>
@@ -20,26 +18,24 @@
</component>
<component id="d00f2" class="javax.swing.JLabel">
<constraints>
<xy x="22" y="32" width="33" height="14"/>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0"/>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="9326f"/>
<text resource-bundle="messages/UIDesignerBundle" key="editbox.class"/>
</properties>
</component>
<component id="9326f" class="javax.swing.JTextField" binding="myTfShortClassName">
<constraints>
<xy x="80" y="29" width="301" height="20"/>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0"/>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<columns value="25"/>
</properties>
</component>
<component id="370ca" class="javax.swing.JLabel">
<component id="370ca" class="javax.swing.JLabel" binding="myPackageLabel">
<constraints>
<xy x="22" y="57" width="48" height="14"/>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0"/>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<inheritsPopupMenu value="true"/>
@@ -48,31 +44,27 @@
</component>
<hspacer id="c7908">
<constraints>
<xy x="2" y="33" width="20" height="11"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0">
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="20" height="-1"/>
</grid>
</constraints>
</hspacer>
<hspacer id="50aef">
<constraints>
<xy x="2" y="130" width="20" height="11"/>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0"/>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="412f8" class="javax.swing.JRadioButton" binding="myRbBindToExistingBean">
<constraints>
<xy x="2" y="99" width="127" height="22"/>
<grid row="4" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0"/>
<grid row="4" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/UIDesignerBundle" key="radio.bind.to.existing.bean"/>
</properties>
</component>
<component id="cc4af" class="javax.swing.JLabel">
<component id="cc4af" class="javax.swing.JLabel" binding="myExistClassLabel">
<constraints>
<xy x="22" y="129" width="33" height="14"/>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0"/>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/UIDesignerBundle" key="editbox.class.2"/>
@@ -80,29 +72,25 @@
</component>
<component id="9b7be" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myTfWitgBtnChooseClass">
<constraints>
<xy x="80" y="126" width="301" height="20"/>
<grid row="5" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0"/>
<grid row="5" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<vspacer id="3b24c">
<constraints>
<xy x="40" y="146" width="11" height="62"/>
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0"/>
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<vspacer id="6822f">
<constraints>
<xy x="40" y="79" width="11" height="20"/>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="2" indent="0">
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false">
<preferred-size width="-1" height="20"/>
</grid>
</constraints>
</vspacer>
<component id="45bb6" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myTfWithBtnChoosePackage">
<constraints>
<xy x="80" y="54" width="301" height="20"/>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0"/>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>

Some files were not shown because too many files have changed in this diff Show More