use CopyOnWriteArrayList instead of syncronized, disable getState after state for Ant

This commit is contained in:
Vladimir Krivosheev
2016-07-11 15:04:16 +02:00
parent c004791685
commit f6f2ed9a4d
19 changed files with 243 additions and 259 deletions
@@ -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)) {
@@ -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<AntBuildFileBase> 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);
@@ -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();
}
@@ -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) {
}
}
@@ -54,7 +54,7 @@ public class AddAntBuildFile extends AnAction {
final Set<VirtualFile> files = new HashSet<VirtualFile>();
files.addAll(Arrays.asList(contextFiles));
for (AntBuildFile buildFile : antConfiguration.getBuildFiles()) {
for (AntBuildFile buildFile : antConfiguration.getBuildFileList()) {
files.remove(buildFile.getVirtualFile());
}
@@ -45,7 +45,7 @@ public final class AntBuildGroup extends ActionGroup implements DumbAware {
final List<AnAction> children = new ArrayList<AnAction>();
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);
@@ -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.<BuildFileProperty>emptyList(), AntBuildListener.NULL);
ExecutionHandler.runBuild((AntBuildFileBase)buildFile, targets, null, e.getDataContext(), Collections.emptyList(), AntBuildListener.NULL);
return;
}
}
@@ -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));
@@ -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.<BuildFileProperty>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<PsiElement> elements = collectAntFiles(buildFile -> buildFile.getAntFile());
final List<PsiElement> 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<T> result = new ArrayList<T>();
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);
}
}
}
@@ -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) {
@@ -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() {
@@ -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<Element> {
public static final ValueProperty<AntReference> DEFAULT_ANT = new ValueProperty<AntReference>("defaultAnt", AntReference.BUNDLED_ANT);
public static final ValueProperty<AntConfiguration> INSTANCE = new ValueProperty<AntConfiguration>("$instance", null);
private static final ValueProperty<AntConfiguration> INSTANCE = new ValueProperty<AntConfiguration>("$instance", null);
public static final AbstractProperty<String> DEFAULT_JDK_NAME = new AbstractProperty<String>() {
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<ExecutionEvent, Pair<AntBuildFile, String>> myEventToTargetMap =
new HashMap<ExecutionEvent, Pair<AntBuildFile, String>>();
private final List<AntBuildFileBase> myBuildFiles = new ArrayList<AntBuildFileBase>();
private volatile AntBuildFileBase[] myBuildFilesArray = null; // cached result of call to myBuildFiles.toArray()
private final List<AntBuildFileBase> myBuildFiles = new CopyOnWriteArrayList<>();
private final Map<AntBuildFile, AntBuildModelBase> myModelToBuildFileMap = new HashMap<AntBuildFile, AntBuildModelBase>();
private final Map<VirtualFile, VirtualFile> myAntFileToContextFileMap = new java.util.HashMap<VirtualFile, VirtualFile>();
private final EventDispatcher<AntConfigurationListener> 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<Pair<Element, String>> files = new ArrayList<Pair<Element, String>>();
for (Iterator<Element> 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<Pair<Element, AntBuildFileBase>> buildFiles = new ArrayList<Pair<Element, AntBuildFileBase>>(files.size());
for (Pair<Element, String> 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<Element, AntBuildFileBase> 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
<buildFile url="file://$PROJECT_DIR$/module/src/support-scripts.xml">
<executeOn event="beforeRun" target="prebuild-steps" runConfigurationType="Application" runConfigurationName="Main" />
</buildFile>
*/
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<AntBuildFileBase> 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<Pair<String, AnAction>> actionList = new ArrayList<Pair<String, AnAction>>();
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<Pair<Element, String>> files = new ArrayList<Pair<Element, String>>();
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<Pair<Element, AntBuildFileBase>> buildFiles = new ArrayList<Pair<Element, AntBuildFileBase>>(files.size());
for (Pair<Element, String> 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<Element, AntBuildFileBase> 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
<buildFile url="file://$PROJECT_DIR$/module/src/support-scripts.xml">
<executeOn event="beforeRun" target="prebuild-steps" runConfigurationType="Application" runConfigurationName="Main" />
</buildFile>
*/
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;
}
}
}
@@ -75,7 +75,7 @@ public class AntWorkspaceConfiguration implements PersistentStateComponent<Eleme
public void writeExternal(Element parentNode) throws WriteExternalException {
DefaultJDOMExternalizer.writeExternal(this, parentNode);
for (final AntBuildFile buildFile : AntConfiguration.getInstance(myProject).getBuildFiles()) {
for (final AntBuildFile buildFile : AntConfiguration.getInstance(myProject).getBuildFileList()) {
Element element = new Element(BUILD_FILE);
element.setAttribute(URL, buildFile.getVirtualFile().getUrl());
((AntBuildFileBase)buildFile).writeWorkspaceProperties(element);
@@ -92,7 +92,7 @@ public class AntWorkspaceConfiguration implements PersistentStateComponent<Eleme
if (properties == null) {
return;
}
for (final AntBuildFile buildFile : AntConfiguration.getInstance(myProject).getBuildFiles()) {
for (final AntBuildFile buildFile : AntConfiguration.getInstance(myProject).getBuildFileList()) {
final Element fileElement = findChildByUrl(properties, buildFile.getVirtualFile().getUrl());
if (fileElement == null) {
continue;
@@ -152,7 +152,7 @@ public class GlobalAntConfiguration implements PersistentStateComponent<Element>
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) {
@@ -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){
@@ -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<AntArtifactExtensi
String targetName = getTargetName();
if (fileUrl == null || targetName == null) return null;
final AntBuildFile[] buildFiles = antConfiguration.getBuildFiles();
for (AntBuildFile buildFile : buildFiles) {
for (AntBuildFile buildFile : antConfiguration.getBuildFileList()) {
final VirtualFile file = buildFile.getVirtualFile();
if (file != null && file.getUrl().equals(fileUrl)) {
final AntBuildModel buildModel = buildFile.getModel();
@@ -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.
@@ -16,7 +16,6 @@
package com.intellij.lang.ant.config.impl.artifacts;
import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.config.AntBuildFile;
import com.intellij.lang.ant.config.AntBuildTarget;
import com.intellij.lang.ant.config.AntConfiguration;
import com.intellij.lang.ant.config.AntConfigurationListener;
@@ -175,18 +174,6 @@ public class AntArtifactPropertiesEditor extends ArtifactPropertiesEditor {
updatePanel();
}
}
@Override
public void buildFileChanged(AntBuildFile buildFile) {
}
@Override
public void buildFileAdded(AntBuildFile buildFile) {
}
@Override
public void buildFileRemoved(AntBuildFile buildFile) {
}
};
antConfiguration.addAntConfigurationListener(myAntConfigurationListener);
}
@@ -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.projectRoots.Sdk;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.references.PomService;
import com.intellij.psi.PsiElement;
@@ -182,10 +183,10 @@ public abstract class AntDomProject extends AntDomNamedElement implements Proper
final AntBuildFileImpl buildFile = (AntBuildFileImpl)AntConfigurationBase.getInstance(containingFile.getProject()).getAntBuildFile(containingFile);
if (buildFile != null) {
String jdkName = AntBuildFileImpl.CUSTOM_JDK_NAME.get(buildFile.getAllOptions());
if (jdkName == null || jdkName.length() == 0) {
if (StringUtil.isEmptyOrSpaces(jdkName)) {
jdkName = AntConfigurationImpl.DEFAULT_JDK_NAME.get(buildFile.getAllOptions());
}
if (jdkName != null && jdkName.length() > 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();
@@ -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}?