diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index 79de1f49d941..1dc60a099310 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -276,6 +276,7 @@ abstract class ComponentStoreImpl : IComponentStore { // todo "ProjectModuleManager" investigate why after loadState we get empty state on getState, test CMakeWorkspaceContentRootsTest // use.loaded.state.as.existing used in upsource val stateGetter = if (isUseLoadedStateAsExisting(storage) && + name != "AntConfiguration" && name != "ProjectModuleManager" && name != "DeprecatedModuleOptionManager" /* doesn't make sense to check it */ && SystemPropertyUtil.getBoolean("use.loaded.state.as.existing", true)) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/AntConfiguration.java b/plugins/ant/src/com/intellij/lang/ant/config/AntConfiguration.java index e27d23434fef..dbfeb209eba5 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/AntConfiguration.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/AntConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -23,10 +23,12 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.SimpleModificationTracker; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public abstract class AntConfiguration extends SimpleModificationTracker { +import java.util.List; +public abstract class AntConfiguration extends SimpleModificationTracker { private final Project myProject; @NonNls public static final String ACTION_ID_PREFIX = "Ant_"; @@ -62,6 +64,8 @@ public abstract class AntConfiguration extends SimpleModificationTracker { public abstract AntBuildFile[] getBuildFiles(); + public abstract List getBuildFileList(); + public abstract AntBuildFile addBuildFile(final VirtualFile file) throws AntNoFileException; public abstract void removeBuildFile(final AntBuildFile file); @@ -75,9 +79,9 @@ public abstract class AntConfiguration extends SimpleModificationTracker { public abstract void updateBuildFile(final AntBuildFile buildFile); @Nullable - public abstract AntBuildModel getModelIfRegistered(final AntBuildFile buildFile); + public abstract AntBuildModelBase getModelIfRegistered(@NotNull AntBuildFileBase buildFile); - public abstract AntBuildModel getModel(final AntBuildFile buildFile); + public abstract AntBuildModel getModel(@NotNull AntBuildFile buildFile); @Nullable public abstract AntBuildFile findBuildFileByActionId(final String id); diff --git a/plugins/ant/src/com/intellij/lang/ant/config/AntConfigurationBase.java b/plugins/ant/src/com/intellij/lang/ant/config/AntConfigurationBase.java index 479979fa9eff..0b1228cdb3b9 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/AntConfigurationBase.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/AntConfigurationBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -34,7 +34,7 @@ public abstract class AntConfigurationBase extends AntConfiguration { super(project); } - public static AntConfigurationBase getInstance(final Project project) { + public static AntConfigurationBase getInstance(@NotNull Project project) { return (AntConfigurationBase)AntConfiguration.getInstance(project); } @@ -73,12 +73,12 @@ public abstract class AntConfigurationBase extends AntConfiguration { @Nullable public abstract XmlFile getContextFile(@Nullable XmlFile file); - + @Nullable public abstract XmlFile getEffectiveContextFile(@Nullable XmlFile file); @Nullable public abstract AntBuildFileBase getAntBuildFile(@NotNull PsiFile file); - - public abstract AntBuildFileBase[] getBuildFiles(); + + public abstract AntBuildFile[] getBuildFiles(); } diff --git a/plugins/ant/src/com/intellij/lang/ant/config/AntConfigurationListener.java b/plugins/ant/src/com/intellij/lang/ant/config/AntConfigurationListener.java index 67d81c87e3db..6702e3669d47 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/AntConfigurationListener.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/AntConfigurationListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -19,11 +19,15 @@ package com.intellij.lang.ant.config; import java.util.EventListener; public interface AntConfigurationListener extends EventListener { - void configurationLoaded(); + default void configurationLoaded() { + } - void buildFileChanged(final AntBuildFile buildFile); + default void buildFileChanged(final AntBuildFile buildFile) { + } - void buildFileAdded(final AntBuildFile buildFile); + default void buildFileAdded(final AntBuildFile buildFile) { + } - void buildFileRemoved(final AntBuildFile buildFile); + default void buildFileRemoved(final AntBuildFile buildFile) { + } } diff --git a/plugins/ant/src/com/intellij/lang/ant/config/actions/AddAntBuildFile.java b/plugins/ant/src/com/intellij/lang/ant/config/actions/AddAntBuildFile.java index e04862f19835..50881e5c6277 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/actions/AddAntBuildFile.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/actions/AddAntBuildFile.java @@ -54,7 +54,7 @@ public class AddAntBuildFile extends AnAction { final Set files = new HashSet(); files.addAll(Arrays.asList(contextFiles)); - for (AntBuildFile buildFile : antConfiguration.getBuildFiles()) { + for (AntBuildFile buildFile : antConfiguration.getBuildFileList()) { files.remove(buildFile.getVirtualFile()); } diff --git a/plugins/ant/src/com/intellij/lang/ant/config/actions/AntBuildGroup.java b/plugins/ant/src/com/intellij/lang/ant/config/actions/AntBuildGroup.java index 9feca4fd9e25..67a2e573cc8e 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/actions/AntBuildGroup.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/actions/AntBuildGroup.java @@ -45,7 +45,7 @@ public final class AntBuildGroup extends ActionGroup implements DumbAware { final List children = new ArrayList(); final AntConfigurationBase antConfiguration = AntConfigurationBase.getInstance(project); - for (final AntBuildFile buildFile : antConfiguration.getBuildFiles()) { + for (final AntBuildFile buildFile : antConfiguration.getBuildFileList()) { final String name = buildFile.getPresentableName(); DefaultActionGroup subgroup = new DefaultActionGroup(); subgroup.getTemplatePresentation().setText(name, false); diff --git a/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetAction.java b/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetAction.java index 60c1d996abfc..ef4330497bcc 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetAction.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetAction.java @@ -21,7 +21,6 @@ import com.intellij.lang.ant.config.AntBuildFileBase; import com.intellij.lang.ant.config.AntBuildListener; import com.intellij.lang.ant.config.AntConfiguration; import com.intellij.lang.ant.config.execution.ExecutionHandler; -import com.intellij.lang.ant.config.impl.BuildFileProperty; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.DumbAwareAction; @@ -56,11 +55,11 @@ public final class TargetAction extends DumbAwareAction { Project project = e.getProject(); if (project == null) return; - for (final AntBuildFile buildFile : AntConfiguration.getInstance(project).getBuildFiles()) { + for (final AntBuildFile buildFile : AntConfiguration.getInstance(project).getBuildFileList()) { final String name = buildFile.getPresentableName(); if (name != null && myBuildName.equals(name)) { String[] targets = myTargets.length == 1 && DEFAULT_TARGET_NAME.equals(myTargets[0]) ? ArrayUtil.EMPTY_STRING_ARRAY : myTargets; - ExecutionHandler.runBuild((AntBuildFileBase)buildFile, targets, null, e.getDataContext(), Collections.emptyList(), AntBuildListener.NULL); + ExecutionHandler.runBuild((AntBuildFileBase)buildFile, targets, null, e.getDataContext(), Collections.emptyList(), AntBuildListener.NULL); return; } } diff --git a/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetActionStub.java b/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetActionStub.java index c6496d4d74d8..eea6ff110aeb 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetActionStub.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/actions/TargetActionStub.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -16,7 +16,6 @@ package com.intellij.lang.ant.config.actions; -import com.intellij.lang.ant.config.AntBuildFile; import com.intellij.lang.ant.config.AntConfiguration; import com.intellij.lang.ant.config.AntConfigurationListener; import com.intellij.openapi.Disposable; @@ -60,10 +59,6 @@ public class TargetActionStub extends AnAction implements Disposable { config.removeAntConfigurationListener(this); invokeAction(e); } - - public void buildFileChanged(final AntBuildFile buildFile) {/*empty*/} - public void buildFileAdded(final AntBuildFile buildFile) {/*empty*/} - public void buildFileRemoved(final AntBuildFile buildFile) {/*empty*/} }; config.addAntConfigurationListener(listener); Disposer.register(myProject, new ListenerRemover(config, listener)); diff --git a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java index b05b116cd220..6939f27fc9b2 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -49,6 +49,7 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.ui.*; @@ -65,6 +66,7 @@ import com.intellij.util.xml.DomManager; import com.intellij.util.xml.events.DomEvent; import icons.AntIcons; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -94,7 +96,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, public boolean canExpand() { final AntConfiguration config = myConfig; - return config != null && config.getBuildFiles().length != 0; + return config != null && !config.getBuildFileList().isEmpty(); } public void collapseAll() { @@ -288,7 +290,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, if (buildFile != null) { final TreePath[] paths = myTree.getSelectionPaths(); final String[] targets = getTargetNamesFromPaths(paths); - ExecutionHandler.runBuild(buildFile, targets, null, dataContext, Collections.emptyList(), AntBuildListener.NULL); + ExecutionHandler.runBuild(buildFile, targets, null, dataContext, Collections.emptyList(), AntBuildListener.NULL); } } @@ -473,7 +475,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, return virtualFiles == null ? null : virtualFiles.toArray(new VirtualFile[virtualFiles.size()]); } else if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) { - final List elements = collectAntFiles(buildFile -> buildFile.getAntFile()); + final List elements = collectAntFiles(AntBuildFile::getAntFile); return elements == null ? null : elements.toArray(new PsiElement[elements.size()]); } return super.getData(dataId); @@ -501,7 +503,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, } } final List result = new ArrayList(); - ContainerUtil.addAllNotNull(result, ContainerUtil.map(antFiles, buildFile -> function.fun(buildFile))); + ContainerUtil.addAllNotNull(result, ContainerUtil.map(antFiles, function)); return result.isEmpty() ? null : result; } @@ -518,7 +520,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, } private static final class NodeRenderer extends ColoredTreeCellRenderer { - public void customizeCellRenderer(JTree tree, + public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, @@ -658,7 +660,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, public boolean isSelected(AnActionEvent event) { final Project project = myProject; - return project != null? AntConfigurationBase.getInstance(project).isFilterTargets() : false; + return project != null && AntConfigurationBase.getInstance(project).isFilterTargets(); } public void setSelected(AnActionEvent event, boolean flag) { @@ -698,7 +700,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, myBuilder.queueUpdate(); } - public void update(AnActionEvent e) { + public void update(@NotNull AnActionEvent e) { super.update(e); final AntBuildFile buildFile = myTarget.getModel().getBuildFile(); e.getPresentation().setEnabled(buildFile != null && buildFile.exists()); @@ -894,6 +896,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, } private void updateTree() { + //noinspection deprecation myBuilder.updateFromRoot(); } @@ -931,7 +934,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, } } - return VfsUtil.toVirtualFileArray(virtualFileList); + return VfsUtilCore.toVirtualFileArray(virtualFileList); } } } diff --git a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorerTreeStructure.java b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorerTreeStructure.java index 10a722f55f86..db3925f11d79 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorerTreeStructure.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorerTreeStructure.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -83,8 +83,7 @@ final class AntExplorerTreeStructure extends AbstractTreeStructure { if (!configuration.isInitialized()) { return new Object[] {AntBundle.message("loading.ant.config.progress")}; } - final AntBuildFile[] buildFiles = configuration.getBuildFiles(); - return buildFiles.length != 0 ? buildFiles : new Object[]{AntBundle.message("ant.tree.structure.no.build.files.message")}; + return configuration.getBuildFileList().isEmpty() ? new Object[]{AntBundle.message("ant.tree.structure.no.build.files.message")} : configuration.getBuildFiles(); } if (element instanceof AntBuildFile) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBuildFileImpl.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBuildFileImpl.java index c4ec2d0d4aed..bf47fb399e17 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBuildFileImpl.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBuildFileImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; @@ -193,7 +194,7 @@ public class AntBuildFileImpl implements AntBuildFileBase { public String getPresentableName() { AntBuildModel model = myAntConfiguration.getModelIfRegistered(this); String name = model != null ? model.getName() : null; - if (name == null || name.trim().length() == 0) { + if (StringUtil.isEmptyOrSpaces(name)) { name = myVFile.getName(); } return name; @@ -212,7 +213,7 @@ public class AntBuildFileImpl implements AntBuildFileBase { @Nullable public AntBuildModelBase getModelIfRegistered() { - return (AntBuildModelBase)myAntConfiguration.getModelIfRegistered(this); + return myAntConfiguration.getModelIfRegistered(this); } public boolean isRunInBackground() { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java index 741e25173853..cc7ccf49e955 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntConfigurationImpl.java @@ -66,15 +66,12 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; -@State( - name = "AntConfiguration", - storages = @Storage("ant.xml") -) +@State(name = "AntConfiguration", storages = @Storage("ant.xml")) public class AntConfigurationImpl extends AntConfigurationBase implements PersistentStateComponent { - public static final ValueProperty DEFAULT_ANT = new ValueProperty("defaultAnt", AntReference.BUNDLED_ANT); - public static final ValueProperty INSTANCE = new ValueProperty("$instance", null); + private static final ValueProperty INSTANCE = new ValueProperty("$instance", null); public static final AbstractProperty DEFAULT_JDK_NAME = new AbstractProperty() { public String getName() { return "$defaultJDKName"; @@ -86,8 +83,11 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis } @Nullable - public String get(final AbstractPropertyContainer container) { - if (!container.hasProperty(this)) return null; + public String get(@NotNull AbstractPropertyContainer container) { + if (!container.hasProperty(this)) { + return null; + } + AntConfiguration antConfiguration = INSTANCE.get(container); return ProjectRootManager.getInstance(antConfiguration.getProject()).getProjectSdkName(); } @@ -109,8 +109,9 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis private final PsiManager myPsiManager; private final Map> myEventToTargetMap = new HashMap>(); - private final List myBuildFiles = new ArrayList(); - private volatile AntBuildFileBase[] myBuildFilesArray = null; // cached result of call to myBuildFiles.toArray() + + private final List myBuildFiles = new CopyOnWriteArrayList<>(); + private final Map myModelToBuildFileMap = new HashMap(); private final Map myAntFileToContextFileMap = new java.util.HashMap(); private final EventDispatcher myEventDispatcher = EventDispatcher.create(AntConfigurationListener.class); @@ -144,6 +145,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis daemon.restart(); } else { + //noinspection SSBasedInspection SwingUtilities.invokeLater(daemon::restart); } } @@ -174,8 +176,9 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis final Element state = new Element("state"); getProperties().writeExternal(state); ApplicationManager.getApplication().runReadAction(() -> { - for (final AntBuildFileBase buildFile : getBuildFiles()) { + for (final AntBuildFileBase buildFile : myBuildFiles) { final Element element = new Element(BUILD_FILE); + //noinspection ConstantConditions element.setAttribute(URL, buildFile.getVirtualFile().getUrl()); buildFile.writeProperties(element); saveEvents(element, buildFile); @@ -202,36 +205,171 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis } public void loadState(Element state) { + myIsInitialized = Boolean.FALSE; try { - myIsInitialized = Boolean.FALSE; myAntWorkspaceConfiguration.loadFromProjectSettings(state); - getProperties().readExternal(state); - runWhenInitialized(() -> loadBuildFileProjectProperties(state)); } catch (InvalidDataException e) { LOG.error(e); + return; } + + List> files = new ArrayList>(); + for (Iterator iterator = state.getChildren(BUILD_FILE).iterator(); iterator.hasNext(); ) { + Element element = iterator.next(); + iterator.remove(); + String url = element.getAttributeValue(URL); + if (url != null) { + files.add(Pair.create(element, url)); + } + } + + final VirtualFileManager vfManager = VirtualFileManager.getInstance(); + // contexts + myAntFileToContextFileMap.clear(); + for (Element element : state.getChildren(CONTEXT_MAPPING)) { + String url = element.getAttributeValue(URL); + String contextUrl = element.getAttributeValue(CONTEXT); + VirtualFile file = vfManager.findFileByUrl(url); + VirtualFile contextFile = vfManager.findFileByUrl(contextUrl); + if (file != null && contextFile != null) { + myAntFileToContextFileMap.put(file, contextFile); + } + } + + getProperties().readExternal(state); + runWhenInitialized(() -> { + String title = AntBundle.message("loading.ant.config.progress"); + queueLater(new Task.Backgroundable(getProject(), title, false) { + public void run(@NotNull final ProgressIndicator indicator) { + if (getProject().isDisposed()) { + return; + } + + indicator.setIndeterminate(true); + indicator.pushState(); + try { + indicator.setText(title); + ApplicationManager.getApplication().runReadAction(() -> { + try { + myInitThread = Thread.currentThread(); + // first, remove existing files + for (AntBuildFile file : myBuildFiles) { + removeBuildFileImpl(file); + } + myBuildFiles.clear(); + + // then fill the configuration with the files configured in xml + List> buildFiles = new ArrayList>(files.size()); + for (Pair pair : files) { + final Element element = pair.getFirst(); + final VirtualFile file = vfManager.findFileByUrl(pair.getSecond()); + if (file == null) { + continue; + } + try { + final AntBuildFileBase buildFile = addBuildFileImpl(file); + buildFile.readProperties(element); + buildFiles.add(Pair.create(element, buildFile)); + } + catch (AntNoFileException ignored) { + } + catch (InvalidDataException e) { + LOG.error(e); + } + } + + // updating properties separately to avoid unnecessary building of PSI after clearing caches + for (Pair pair : buildFiles) { + final AntBuildFileBase buildFile = pair.getSecond(); + buildFile.updateProperties(); + final VirtualFile vFile = buildFile.getVirtualFile(); + final String buildFileUrl = vFile != null? vFile.getUrl() : null; + + for (Element e : pair.getFirst().getChildren(EXECUTE_ON_ELEMENT)) { + final String eventId = e.getAttributeValue(EVENT_ELEMENT); + ExecutionEvent event = null; + final String targetName = e.getAttributeValue(TARGET_ELEMENT); + if (ExecuteBeforeCompilationEvent.TYPE_ID.equals(eventId)) { + event = ExecuteBeforeCompilationEvent.getInstance(); + } + else if (ExecuteAfterCompilationEvent.TYPE_ID.equals(eventId)) { + event = ExecuteAfterCompilationEvent.getInstance(); + } + else if ("beforeRun".equals(eventId)) { + /* + for compatibility with previous format + + + + + */ + final String configType = e.getAttributeValue("runConfigurationType"); + final String configName = e.getAttributeValue("runConfigurationName"); + convertToBeforeRunTask(myProject, buildFileUrl, targetName, configType, configName); + } + else if (ExecuteCompositeTargetEvent.TYPE_ID.equals(eventId)) { + try { + event = new ExecuteCompositeTargetEvent(targetName); + } + catch (WrongNameFormatException e1) { + LOG.info(e1); + event = null; + } + } + if (event != null) { + try { + event.readExternal(e, getProject()); + setTargetForEvent(buildFile, targetName, event); + } + catch (InvalidDataException readFailed) { + LOG.info(readFailed.getMessage()); + } + } + } + } + AntWorkspaceConfiguration.getInstance(getProject()).loadFileProperties(); + } + catch (InvalidDataException e) { + LOG.error(e); + } + finally { + try { + incModificationCount(); + updateRegisteredActions(); + } + finally { + myInitThread = null; + myIsInitialized = Boolean.TRUE; + ApplicationManager.getApplication().invokeLater(() -> myEventDispatcher.getMulticaster().configurationLoaded(), ModalityState.any()); + } + } + }); + } + finally { + indicator.popState(); + } + } + }); + }); } - private volatile Boolean myIsInitialized = null; - private volatile Thread myInitThread = null; + private volatile Boolean myIsInitialized; + private volatile Thread myInitThread; public boolean isInitialized() { final Boolean initialized = myIsInitialized; return initialized == null || initialized.booleanValue(); } - public AntBuildFileBase[] getBuildFiles() { - AntBuildFileBase[] result = myBuildFilesArray; - if (result == null) { - synchronized (myBuildFiles) { - result = myBuildFilesArray; - if (result == null) { - myBuildFilesArray = result = myBuildFiles.toArray(new AntBuildFileBase[myBuildFiles.size()]); - } - } - } - return result; + public AntBuildFile[] getBuildFiles() { + //noinspection SuspiciousToArrayCall + return myBuildFiles.toArray(new AntBuildFileBase[myBuildFiles.size()]); + } + + @Override + public List getBuildFileList() { + return myBuildFiles; } public AntBuildFile addBuildFile(final VirtualFile file) throws AntNoFileException { @@ -274,9 +412,10 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis return result[0]; } - public void removeBuildFile(final AntBuildFile file) { + public void removeBuildFile(@NotNull AntBuildFile file) { incModificationCount(); removeBuildFileImpl(file); + myBuildFiles.remove(((AntBuildFileBase)file)); updateRegisteredActions(); } @@ -334,10 +473,9 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis return null; } final AntBuildFileBase buildFile = (AntBuildFileBase)pair.first; - synchronized (myBuildFiles) { - if (!myBuildFiles.contains(buildFile)) { - return null; // file was removed - } + if (!myBuildFiles.contains(buildFile)) { + // file was removed + return null; } final String targetName = pair.second; @@ -389,13 +527,8 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis } @Nullable - public AntBuildModel getModelIfRegistered(final AntBuildFile buildFile) { - synchronized (myBuildFiles) { - if (!myBuildFiles.contains(buildFile)) { - return null; - } - } - return getModel(buildFile); + public AntBuildModelBase getModelIfRegistered(@NotNull AntBuildFileBase buildFile) { + return myBuildFiles.contains(buildFile) ? getModel(buildFile) : null; } private void runWhenInitialized(final Runnable runnable) { @@ -439,7 +572,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis } } - public AntBuildModel getModel(final AntBuildFile buildFile) { + public AntBuildModelBase getModel(@NotNull AntBuildFile buildFile) { AntBuildModelBase model = myModelToBuildFileMap.get(buildFile); if (model == null) { model = createModel(buildFile); @@ -450,7 +583,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis @Nullable public AntBuildFile findBuildFileByActionId(final String id) { - for (AntBuildFile buildFile : getBuildFiles()) { + for (AntBuildFile buildFile : myBuildFiles) { AntBuildModelBase model = (AntBuildModelBase)buildFile.getModel(); if (id.equals(model.getDefaultTargetActionId())) { return buildFile; @@ -478,10 +611,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis throw new AntNoFileException("the file is not recognized as an ANT file", file); } final AntBuildFileImpl buildFile = new AntBuildFileImpl((XmlFile)xmlFile, this); - synchronized (myBuildFiles) { - myBuildFilesArray = null; - myBuildFiles.add(buildFile); - } + myBuildFiles.add(buildFile); return buildFile; } @@ -491,7 +621,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis return; } final List> actionList = new ArrayList>(); - for (final AntBuildFile buildFile : getBuildFiles()) { + for (final AntBuildFile buildFile : myBuildFiles) { final AntBuildModelBase model = (AntBuildModelBase)buildFile.getModel(); String defaultTargetActionId = model.getDefaultTargetActionId(); if (defaultTargetActionId != null) { @@ -504,6 +634,7 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis collectTargetActions(getMetaTargets(buildFile), actionList, buildFile); } + //noinspection SynchronizeOnThis synchronized (this) { // unregister Ant actions ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); @@ -539,15 +670,12 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis } } - private void removeBuildFileImpl(AntBuildFile buildFile) { - final XmlFile antFile = buildFile.getAntFile(); + private void removeBuildFileImpl(@NotNull AntBuildFile buildFile) { + XmlFile antFile = buildFile.getAntFile(); if (antFile != null) { AntSupport.markFileAsAntFile(antFile.getOriginalFile().getVirtualFile(), antFile.getProject(), false); } - synchronized (myBuildFiles) { - myBuildFilesArray = null; - myBuildFiles.remove(buildFile); - } + myModelToBuildFileMap.remove(buildFile); myEventDispatcher.getMulticaster().buildFileRemoved(buildFile); } @@ -621,139 +749,6 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis return list; } - private void loadBuildFileProjectProperties(@NotNull Element parentNode) { - final List> files = new ArrayList>(); - final VirtualFileManager vfManager = VirtualFileManager.getInstance(); - for (final Element element : parentNode.getChildren(BUILD_FILE)) { - final String url = element.getAttributeValue(URL); - if (url != null) { - files.add(Pair.create(element, url)); - } - } - - // contexts - myAntFileToContextFileMap.clear(); - for (final Element element : parentNode.getChildren(CONTEXT_MAPPING)) { - final String url = element.getAttributeValue(URL); - final String contextUrl = element.getAttributeValue(CONTEXT); - final VirtualFile file = vfManager.findFileByUrl(url); - final VirtualFile contextFile = vfManager.findFileByUrl(contextUrl); - if (file != null && contextFile != null) { - myAntFileToContextFileMap.put(file, contextFile); - } - } - - final String title = AntBundle.message("loading.ant.config.progress"); - queueLater(new Task.Backgroundable(getProject(), title, false) { - public void run(@NotNull final ProgressIndicator indicator) { - if (getProject().isDisposed()) { - return; - } - - indicator.setIndeterminate(true); - indicator.pushState(); - try { - indicator.setText(title); - ApplicationManager.getApplication().runReadAction(() -> { - try { - myInitThread = Thread.currentThread(); - // first, remove existing files - for (AntBuildFile file : getBuildFiles()) { - removeBuildFileImpl(file); - } - // then fill the configuration with the files configured in xml - List> buildFiles = new ArrayList>(files.size()); - for (Pair pair : files) { - final Element element = pair.getFirst(); - final VirtualFile file = vfManager.findFileByUrl(pair.getSecond()); - if (file == null) { - continue; - } - try { - final AntBuildFileBase buildFile = addBuildFileImpl(file); - buildFile.readProperties(element); - buildFiles.add(Pair.create(element, buildFile)); - } - catch (AntNoFileException ignored) { - } - catch (InvalidDataException e) { - LOG.error(e); - } - } - // updating properties separately to avoid unnecessary building of PSI after clearing caches - for (Pair pair : buildFiles) { - final AntBuildFileBase buildFile = pair.getSecond(); - buildFile.updateProperties(); - final VirtualFile vFile = buildFile.getVirtualFile(); - final String buildFileUrl = vFile != null? vFile.getUrl() : null; - - for (Element e : pair.getFirst().getChildren(EXECUTE_ON_ELEMENT)) { - final String eventId = e.getAttributeValue(EVENT_ELEMENT); - ExecutionEvent event = null; - final String targetName = e.getAttributeValue(TARGET_ELEMENT); - if (ExecuteBeforeCompilationEvent.TYPE_ID.equals(eventId)) { - event = ExecuteBeforeCompilationEvent.getInstance(); - } - else if (ExecuteAfterCompilationEvent.TYPE_ID.equals(eventId)) { - event = ExecuteAfterCompilationEvent.getInstance(); - } - else if ("beforeRun".equals(eventId)) { - /* - for compatibility with previous format - - - - - */ - final String configType = e.getAttributeValue("runConfigurationType"); - final String configName = e.getAttributeValue("runConfigurationName"); - convertToBeforeRunTask(myProject, buildFileUrl, targetName, configType, configName); - } - else if (ExecuteCompositeTargetEvent.TYPE_ID.equals(eventId)) { - try { - event = new ExecuteCompositeTargetEvent(targetName); - } - catch (WrongNameFormatException e1) { - LOG.info(e1); - event = null; - } - } - if (event != null) { - try { - event.readExternal(e, getProject()); - setTargetForEvent(buildFile, targetName, event); - } - catch (InvalidDataException readFailed) { - LOG.info(readFailed.getMessage()); - } - } - } - } - AntWorkspaceConfiguration.getInstance(getProject()).loadFileProperties(); - } - catch (InvalidDataException e) { - LOG.error(e); - } - finally { - try { - incModificationCount(); - updateRegisteredActions(); - } - finally { - myInitThread = null; - myIsInitialized = Boolean.TRUE; - ApplicationManager.getApplication().invokeLater(() -> myEventDispatcher.getMulticaster().configurationLoaded(), ModalityState.any()); - } - } - }); - } - finally { - indicator.popState(); - } - } - }); - } - private static void convertToBeforeRunTask(Project project, String buildFileUrl, String targetName, String configType, String configName) { if (buildFileUrl == null || targetName == null || configType == null) { return; @@ -832,9 +827,9 @@ public class AntConfigurationImpl extends AntConfigurationBase implements Persis public AntBuildFileBase getAntBuildFile(@NotNull PsiFile file) { final VirtualFile vFile = file.getVirtualFile(); if (vFile != null) { - for (AntBuildFileBase bFile : getBuildFiles()) { + for (AntBuildFile bFile : myBuildFiles) { if (vFile.equals(bFile.getVirtualFile())) { - return bFile; + return (AntBuildFileBase)bFile; } } } diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntWorkspaceConfiguration.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntWorkspaceConfiguration.java index af38da22f48b..0b5b68d6e5b4 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntWorkspaceConfiguration.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntWorkspaceConfiguration.java @@ -75,7 +75,7 @@ public class AntWorkspaceConfiguration implements PersistentStateComponent return null; } final AntConfigurationImpl antConfiguration = (AntConfigurationImpl)AntConfiguration.getInstance(project); - for (AntBuildFile buildFile : antConfiguration.getBuildFiles()) { + for (AntBuildFile buildFile : antConfiguration.getBuildFileList()) { if (vFile.equals(buildFile.getVirtualFile())) { final AntBuildTarget target = buildFile.getModel().findTarget(targetName); if (target != null) { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/TargetChooserDialog.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/TargetChooserDialog.java index 9014aa3ccfb1..8ac5b47a8f4b 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/TargetChooserDialog.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/TargetChooserDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -122,8 +122,7 @@ public class TargetChooserDialog extends DialogWrapper { DefaultMutableTreeNode selectedNode = null; final AntConfiguration antConfiguration = AntConfigurationImpl.getInstance(myProject); - final AntBuildFile[] antBuildFiles = antConfiguration.getBuildFiles(); - for (AntBuildFile buildFile : antBuildFiles) { + for (AntBuildFile buildFile : antConfiguration.getBuildFileList()) { final DefaultMutableTreeNode buildFileNode = new DefaultMutableTreeNode(buildFile); DefaultMutableTreeNode selection = processFileTargets(antConfiguration.getMetaTargets(buildFile), buildFile, buildFileNode); if (selection != null){ diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactProperties.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactProperties.java index a39f4fca9882..3ec2be85b0cf 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactProperties.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -129,8 +129,7 @@ public class AntArtifactProperties extends ArtifactProperties 0) { + if (!StringUtil.isEmptyOrSpaces(jdkName)) { return ProjectJdkTable.getInstance().findJdk(jdkName); } } @@ -265,14 +266,11 @@ public abstract class AntDomProject extends AntDomNamedElement implements Proper try { basedir = new File(containigFileDir, basedir).getCanonicalPath(); } - catch (IOException e) { - // ignore + catch (IOException ignored) { } } } - if (basedir != null) { - appendProperty(destination, "basedir", FileUtil.toSystemIndependentName(basedir)); - } + appendProperty(destination, "basedir", FileUtil.toSystemIndependentName(basedir)); final AntInstallation installation = getAntInstallation(); final String homeDir = installation.getHomeDir(); diff --git a/resources-en/src/messages/AntBundle.properties b/resources-en/src/messages/AntBundle.properties index 287d330abd11..d5e3fb301ab2 100644 --- a/resources-en/src/messages/AntBundle.properties +++ b/resources-en/src/messages/AntBundle.properties @@ -61,7 +61,7 @@ ant.execution.next.error.warning.action.name=Next Error/Warning ant.execution.previous.error.warning.action.name=Previous Error/Warning ant.explorer.expand.all.nodes.action.description=Expand all build file nodes ant.explorer.collapse.all.nodes.action.description=Collapse all build file nodes -select.ant.build.file.dialog.title=Select Ant build file +select.ant.build.file.dialog.title=Select Ant Build File select.ant.build.file.dialog.description=Select one or more build.xml files to be added to the list cannot.add.ant.files.dialog.title=Cannot Add Files remove.the.reference.to.file.confirmation.text=Do you want to remove the reference to\n{0}?