diff options
Diffstat (limited to 'platform/projectModel-impl/src')
14 files changed, 202 insertions, 194 deletions
diff --git a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java index cce7a68526bd..ac70cb252f10 100644 --- a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java +++ b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java @@ -15,41 +15,40 @@ */ package com.intellij.application.options; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathMacros; -import com.intellij.openapi.components.ExpandMacroToPathMap; -import com.intellij.openapi.components.NamedComponent; +import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.NamedJDOMExternalizable; -import com.intellij.openapi.util.RoamingTypeDisabled; -import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.hash.LinkedHashMap; import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.serialization.JpsGlobalLoader; import org.jetbrains.jps.model.serialization.PathMacroUtil; import java.util.*; import java.util.concurrent.locks.ReentrantReadWriteLock; -/** - * @author dsl - */ -public class PathMacrosImpl extends PathMacros implements NamedComponent, NamedJDOMExternalizable, RoamingTypeDisabled { - private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.PathMacrosImpl"); +@State( + name = "PathMacrosImpl", + storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/path.macros.xml", roamingType = RoamingType.PER_PLATFORM)} +) +public class PathMacrosImpl extends PathMacros implements PersistentStateComponent<Element> { + private static final Logger LOG = Logger.getInstance(PathMacrosImpl.class); + private final Map<String, String> myLegacyMacros = new HashMap<String, String>(); - private final Map<String, String> myMacros = new HashMap<String, String>(); + private final Map<String, String> myMacros = new LinkedHashMap<String, String>(); private int myModificationStamp = 0; private final ReentrantReadWriteLock myLock = new ReentrantReadWriteLock(); private final List<String> myIgnoredMacros = ContainerUtil.createLockFreeCopyOnWriteList(); - public static final String MACRO_ELEMENT = JpsGlobalLoader.PathVariablesSerializer.MACRO_TAG; - public static final String NAME_ATTR = JpsGlobalLoader.PathVariablesSerializer.NAME_ATTRIBUTE; - public static final String VALUE_ATTR = JpsGlobalLoader.PathVariablesSerializer.VALUE_ATTRIBUTE; + private static final String MACRO_ELEMENT = JpsGlobalLoader.PathVariablesSerializer.MACRO_TAG; + private static final String NAME_ATTR = JpsGlobalLoader.PathVariablesSerializer.NAME_ATTRIBUTE; + private static final String VALUE_ATTR = JpsGlobalLoader.PathVariablesSerializer.VALUE_ATTRIBUTE; @NonNls public static final String IGNORED_MACRO_ELEMENT = "ignoredMacro"; @@ -75,6 +74,7 @@ public class PathMacrosImpl extends PathMacros implements NamedComponent, NamedJ SYSTEM_MACROS.add(USER_HOME_MACRO_NAME); } + @SuppressWarnings("SpellCheckingInspection") private static final Set<String> ourToolsMacros = ContainerUtil.immutableSet( "ClasspathEntry", "Classpath", @@ -138,18 +138,7 @@ public class PathMacrosImpl extends PathMacros implements NamedComponent, NamedJ } public static PathMacrosImpl getInstanceEx() { - return (PathMacrosImpl)ApplicationManager.getApplication().getComponent(PathMacros.class); - } - - @Override - @NotNull - public String getComponentName() { - return "PathMacrosImpl"; - } - - @Override - public String getExternalFileName() { - return EXT_FILE_NAME; + return (PathMacrosImpl)getInstance(); } @Override @@ -286,8 +275,37 @@ public class PathMacrosImpl extends PathMacros implements NamedComponent, NamedJ } } + @Nullable + @Override + public Element getState() { + try { + Element element = new Element("state"); + myLock.writeLock().lock(); + + for (Map.Entry<String, String> entry : myMacros.entrySet()) { + String value = entry.getValue(); + if (!StringUtil.isEmptyOrSpaces(value)) { + final Element macro = new Element(MACRO_ELEMENT); + macro.setAttribute(NAME_ATTR, entry.getKey()); + macro.setAttribute(VALUE_ATTR, value); + element.addContent(macro); + } + } + + for (final String macro : myIgnoredMacros) { + final Element macroElement = new Element(IGNORED_MACRO_ELEMENT); + macroElement.setAttribute(NAME_ATTR, macro); + element.addContent(macroElement); + } + return element; + } + finally { + myLock.writeLock().unlock(); + } + } + @Override - public void readExternal(Element element) throws InvalidDataException { + public void loadState(Element element) { try { myLock.writeLock().lock(); @@ -297,7 +315,7 @@ public class PathMacrosImpl extends PathMacros implements NamedComponent, NamedJ final String name = macro.getAttributeValue(NAME_ATTR); String value = macro.getAttributeValue(VALUE_ATTR); if (name == null || value == null) { - throw new InvalidDataException(); + continue; } if (SYSTEM_MACROS.contains(name)) { @@ -326,33 +344,6 @@ public class PathMacrosImpl extends PathMacros implements NamedComponent, NamedJ } } - @Override - public void writeExternal(Element element) throws WriteExternalException { - try { - myLock.writeLock().lock(); - - final Set<Map.Entry<String, String>> entries = myMacros.entrySet(); - for (Map.Entry<String, String> entry : entries) { - final String value = entry.getValue(); - if (value != null && !value.trim().isEmpty()) { - final Element macro = new Element(MACRO_ELEMENT); - macro.setAttribute(NAME_ATTR, entry.getKey()); - macro.setAttribute(VALUE_ATTR, value); - element.addContent(macro); - } - } - - for (final String macro : myIgnoredMacros) { - final Element macroElement = new Element(IGNORED_MACRO_ELEMENT); - macroElement.setAttribute(NAME_ATTR, macro); - element.addContent(macroElement); - } - } - finally { - myLock.writeLock().unlock(); - } - } - public void addMacroReplacements(ReplacePathToMacroMap result) { for (final String name : getUserMacroNames()) { final String value = getValue(name); @@ -360,7 +351,6 @@ public class PathMacrosImpl extends PathMacros implements NamedComponent, NamedJ } } - public void addMacroExpands(ExpandMacroToPathMap result) { for (final String name : getUserMacroNames()) { final String value = getValue(name); diff --git a/platform/projectModel-impl/src/com/intellij/core/CoreModuleManager.java b/platform/projectModel-impl/src/com/intellij/core/CoreModuleManager.java index 7f7e0df4621d..8753b73144d3 100644 --- a/platform/projectModel-impl/src/com/intellij/core/CoreModuleManager.java +++ b/platform/projectModel-impl/src/com/intellij/core/CoreModuleManager.java @@ -26,7 +26,6 @@ import com.intellij.openapi.roots.impl.ModuleRootManagerImpl; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.vfs.StandardFileSystems; import com.intellij.openapi.vfs.VirtualFile; -import org.jdom.Element; import org.jdom.JDOMException; import java.io.IOException; @@ -52,10 +51,10 @@ public class CoreModuleManager extends ModuleManagerImpl { final ModuleEx module = createModule(filePath); VirtualFile vFile = StandardFileSystems.local().findFileByPath(filePath); try { + assert vFile != null; StorageData storageData = CoreProjectLoader.loadStorageFile(module, vFile); - final Element element = storageData.getState("NewModuleRootManager"); ModuleRootManagerImpl.ModuleRootManagerState state = new ModuleRootManagerImpl.ModuleRootManagerState(); - state.readExternal(element); + state.readExternal(storageData.getState("NewModuleRootManager")); ((ModuleRootManagerImpl) ModuleRootManager.getInstance(module)).loadState(state); } catch (JDOMException e) { diff --git a/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java b/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java index 5d8ac1fd4ed2..f05983aff69a 100644 --- a/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java +++ b/platform/projectModel-impl/src/com/intellij/core/CoreProjectLoader.java @@ -27,14 +27,11 @@ import com.intellij.openapi.roots.impl.ProjectRootManagerImpl; import com.intellij.openapi.roots.impl.libraries.LibraryTableBase; import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable; import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.vfs.VirtualFile; -import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; -import java.io.ByteArrayInputStream; import java.io.IOException; /** @@ -56,7 +53,9 @@ public class CoreProjectLoader { private static void loadDirectoryProject(MockProject project, VirtualFile projectDir) throws IOException, JDOMException, InvalidDataException { VirtualFile dotIdea = projectDir.findChild(Project.DIRECTORY_STORE_FOLDER); + assert dotIdea != null; VirtualFile modulesXml = dotIdea.findChild("modules.xml"); + assert modulesXml != null; StorageData storageData = loadStorageFile(project, modulesXml); final Element moduleManagerState = storageData.getState("ProjectModuleManager"); if (moduleManagerState == null) { @@ -66,6 +65,7 @@ public class CoreProjectLoader { moduleManager.loadState(moduleManagerState); VirtualFile miscXml = dotIdea.findChild("misc.xml"); + assert miscXml != null; storageData = loadStorageFile(project, miscXml); final Element projectRootManagerState = storageData.getState("ProjectRootManager"); if (projectRootManagerState == null) { @@ -85,12 +85,10 @@ public class CoreProjectLoader { project.projectOpened(); } - public static StorageData loadStorageFile(ComponentManager componentManager, VirtualFile modulesXml) throws JDOMException, IOException { - final Document document = JDOMUtil.loadDocument(new ByteArrayInputStream(modulesXml.contentsToByteArray())); + @NotNull + public static StorageData loadStorageFile(@NotNull ComponentManager componentManager, @NotNull VirtualFile modulesXml) throws JDOMException, IOException { StorageData storageData = new StorageData("project"); - final Element element = document.getRootElement(); - PathMacroManager.getInstance(componentManager).expandPaths(element); - storageData.load(element); + storageData.load(StorageData.load(modulesXml), PathMacroManager.getInstance(componentManager), false); return storageData; } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroManager.java b/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroManager.java index 8999bb914dea..046da9d799e6 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroManager.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroManager.java @@ -25,12 +25,6 @@ public abstract class PathMacroManager implements PathMacroSubstitutor { return component; } - @Override - public abstract void expandPaths(@NotNull Element element); - - @Override - public abstract void collapsePaths(@NotNull Element element); - public abstract void collapsePathsRecursively(@NotNull Element element); public abstract String collapsePathsRecursively(@NotNull String text); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroSubstitutor.java b/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroSubstitutor.java index c79802533a1d..bcffa0bc34ee 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroSubstitutor.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/PathMacroSubstitutor.java @@ -16,6 +16,7 @@ package com.intellij.openapi.components; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public interface PathMacroSubstitutor { @@ -23,7 +24,7 @@ public interface PathMacroSubstitutor { String collapsePath(@Nullable String path); - void expandPaths(Element element); + void expandPaths(@NotNull Element element); - void collapsePaths(Element element); + void collapsePaths(@NotNull Element element); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/TrackingPathMacroSubstitutor.java b/platform/projectModel-impl/src/com/intellij/openapi/components/TrackingPathMacroSubstitutor.java index 63e3a89431d8..48f33feb7936 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/TrackingPathMacroSubstitutor.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/TrackingPathMacroSubstitutor.java @@ -15,15 +15,22 @@ */ package com.intellij.openapi.components; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Set; public interface TrackingPathMacroSubstitutor extends PathMacroSubstitutor { + @NotNull Collection<String> getUnknownMacros(@Nullable String componentName); - Collection<String> getComponents(final Collection<String> macros); - void addUnknownMacros(String componentName, Collection<String> unknownMacros); - void invalidateUnknownMacros(Set<String> macros); + + @NotNull + Collection<String> getComponents(@NotNull Collection<String> macros); + + void addUnknownMacros(@NotNull String componentName, @NotNull Collection<String> unknownMacros); + + void invalidateUnknownMacros(@NotNull Set<String> macros); + void reset(); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java index 9707364c988b..b3d1edb42b4e 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/BasePathMacroManager.java @@ -31,16 +31,22 @@ import com.intellij.openapi.vfs.StandardFileSystems; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileSystem; -import com.intellij.util.containers.FactoryMap; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; +import com.intellij.util.containers.SmartHashSet; +import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.serialization.PathMacroUtil; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; public class BasePathMacroManager extends PathMacroManager { - private static final CompositePathMacroFilter ourFilter = new CompositePathMacroFilter(Extensions.getExtensions(PathMacrosCollector.MACRO_FILTER_EXTENSION_POINT_NAME)); + private static final CompositePathMacroFilter FILTER = new CompositePathMacroFilter(Extensions.getExtensions(PathMacrosCollector.MACRO_FILTER_EXTENSION_POINT_NAME)); private PathMacrosImpl myPathMacros; @@ -49,20 +55,26 @@ public class BasePathMacroManager extends PathMacroManager { } protected static void addFileHierarchyReplacements(ExpandMacroToPathMap result, String macroName, @Nullable String path) { - if (path == null) return; - addFileHierarchyReplacements(result, getLocalFileSystem().findFileByPath(path), "$" + macroName + "$"); + if (path != null) { + addFileHierarchyReplacements(result, getLocalFileSystem().findFileByPath(path), '$' + macroName + '$'); + } } private static void addFileHierarchyReplacements(ExpandMacroToPathMap result, @Nullable VirtualFile f, String macro) { - if (f == null) return; + if (f == null) { + return; + } + addFileHierarchyReplacements(result, f.getParent(), macro + "/.."); result.put(macro, StringUtil.trimEnd(f.getPath(), "/")); } protected static void addFileHierarchyReplacements(ReplacePathToMacroMap result, String macroName, @Nullable String path, @Nullable String stopAt) { - if (path == null) return; + if (path == null) { + return; + } - String macro = "$" + macroName + "$"; + String macro = '$' + macroName + '$'; path = StringUtil.trimEnd(FileUtil.toSystemIndependentName(path), "/"); boolean overwrite = true; while (StringUtil.isNotEmpty(path) && path.contains("/")) { @@ -140,25 +152,14 @@ public class BasePathMacroManager extends PathMacroManager { if (myPathMacros == null) { myPathMacros = PathMacrosImpl.getInstanceEx(); } - return myPathMacros; } private class MyTrackingPathMacroSubstitutor implements TrackingPathMacroSubstitutor { private final String myLock = new String("MyTrackingPathMacroSubstitutor.lock"); - private final Map<String, Set<String>> myMacroToComponentNames = new FactoryMap<String, Set<String>>() { - @Override - protected Set<String> create(String key) { - return new HashSet<String>(); - } - }; - private final Map<String, Set<String>> myComponentNameToMacros = new FactoryMap<String, Set<String>>() { - @Override - protected Set<String> create(String key) { - return new HashSet<String>(); - } - }; + private final MultiMap<String, String> myMacroToComponentNames = MultiMap.createSet(); + private final MultiMap<String, String> myComponentNameToMacros = MultiMap.createSet(); public MyTrackingPathMacroSubstitutor() { } @@ -182,13 +183,13 @@ public class BasePathMacroManager extends PathMacroManager { } @Override - public void expandPaths(final Element element) { + public void expandPaths(@NotNull final Element element) { getExpandMacroMap().substitute(element, SystemInfo.isFileSystemCaseSensitive); } @Override - public void collapsePaths(final Element element) { - getReplacePathMap().substitute(element, SystemInfo.isFileSystemCaseSensitive, false, ourFilter); + public void collapsePaths(@NotNull final Element element) { + getReplacePathMap().substitute(element, SystemInfo.isFileSystemCaseSensitive, false, FILTER); } public int hashCode() { @@ -196,52 +197,52 @@ public class BasePathMacroManager extends PathMacroManager { } @Override - public void invalidateUnknownMacros(final Set<String> macros) { + public void invalidateUnknownMacros(@NotNull Set<String> macros) { synchronized (myLock) { - for (final String macro : macros) { - final Set<String> components = myMacroToComponentNames.get(macro); - for (final String component : components) { - myComponentNameToMacros.remove(component); + for (String macro : macros) { + Collection<String> componentNames = myMacroToComponentNames.remove(macro); + if (!ContainerUtil.isEmpty(componentNames)) { + for (String component : componentNames) { + myComponentNameToMacros.remove(component); + } } - - myMacroToComponentNames.remove(macro); } } } + @NotNull @Override - public Collection<String> getComponents(final Collection<String> macros) { + public Collection<String> getComponents(@NotNull Collection<String> macros) { synchronized (myLock) { - final Set<String> result = new HashSet<String>(); - for (String macro : myMacroToComponentNames.keySet()) { - if (macros.contains(macro)) { - result.addAll(myMacroToComponentNames.get(macro)); - } + Set<String> result = new SmartHashSet<String>(); + for (String macro : macros) { + result.addAll(myMacroToComponentNames.get(macro)); } - return result; } } + @NotNull @Override - public Collection<String> getUnknownMacros(final String componentName) { + public Collection<String> getUnknownMacros(@Nullable String componentName) { synchronized (myLock) { - final Set<String> result = new HashSet<String>(); - result.addAll(componentName == null ? myMacroToComponentNames.keySet() : myComponentNameToMacros.get(componentName)); - return Collections.unmodifiableCollection(result); + Collection<String> list = componentName == null ? myMacroToComponentNames.keySet() : myComponentNameToMacros.get(componentName); + return ContainerUtil.isEmpty(list) ? Collections.<String>emptyList() : new THashSet<String>(list); } } @Override - public void addUnknownMacros(final String componentName, final Collection<String> unknownMacros) { - if (unknownMacros.isEmpty()) return; + public void addUnknownMacros(@NotNull String componentName, @NotNull Collection<String> unknownMacros) { + if (unknownMacros.isEmpty()) { + return; + } synchronized (myLock) { for (String unknownMacro : unknownMacros) { - myMacroToComponentNames.get(unknownMacro).add(componentName); + myMacroToComponentNames.putValue(unknownMacro, componentName); } - myComponentNameToMacros.get(componentName).addAll(unknownMacros); + myComponentNameToMacros.putValues(componentName, unknownMacros); } } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/ModulePathMacroManager.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/ModulePathMacroManager.java index 704dfec04233..e8cc7bcd040a 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/ModulePathMacroManager.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/ModulePathMacroManager.java @@ -16,7 +16,6 @@ package com.intellij.openapi.components.impl; -import com.intellij.application.options.PathMacrosImpl; import com.intellij.application.options.ReplacePathToMacroMap; import com.intellij.openapi.application.PathMacros; import com.intellij.openapi.components.ExpandMacroToPathMap; @@ -34,25 +33,21 @@ public class ModulePathMacroManager extends BasePathMacroManager { @Override public ExpandMacroToPathMap getExpandMacroMap() { final ExpandMacroToPathMap result = new ExpandMacroToPathMap(); - if (!myModule.isDisposed()) { - addFileHierarchyReplacements(result, PathMacrosImpl.MODULE_DIR_MACRO_NAME, PathMacroUtil.getModuleDir(myModule.getModuleFilePath())); + addFileHierarchyReplacements(result, PathMacroUtil.MODULE_DIR_MACRO_NAME, PathMacroUtil.getModuleDir(myModule.getModuleFilePath())); } result.putAll(super.getExpandMacroMap()); - return result; } @Override public ReplacePathToMacroMap getReplacePathMap() { final ReplacePathToMacroMap result = super.getReplacePathMap(); - if (!myModule.isDisposed()) { final String modulePath = PathMacroUtil.getModuleDir(myModule.getModuleFilePath()); - addFileHierarchyReplacements(result, PathMacrosImpl.MODULE_DIR_MACRO_NAME, modulePath, PathMacroUtil.getUserHomePath()); + addFileHierarchyReplacements(result, PathMacroUtil.MODULE_DIR_MACRO_NAME, modulePath, PathMacroUtil.getUserHomePath()); } - return result; } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java index 608a350d770c..d4f87027191d 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java @@ -40,6 +40,7 @@ class DefaultStateSerializer { private DefaultStateSerializer() { } + @Nullable static Element serializeState(@NotNull Object state, final Storage storage) throws WriteExternalException { if (state instanceof Element) { return (Element)state; @@ -56,12 +57,12 @@ class DefaultStateSerializer { } catch (Throwable e) { LOG.info("Unable to serialize component state!", e); - return new Element("empty"); + return null; } return element; } else { - return XmlSerializer.serialize(state, new SkipDefaultValuesSerializationFilters() { + return XmlSerializer.serialize(state, new SkipDefaultValuesSerializationFilters() { @Override public boolean accepts(final Accessor accessor, final Object bean) { if (!super.accepts(accessor, bean)) return false; diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java index 4a9aaed20af8..8ea0e1ef935f 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DirectoryStorageData.java @@ -23,8 +23,6 @@ import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.PairConsumer; -import com.intellij.util.io.fs.FileSystem; -import com.intellij.util.io.fs.IFile; import gnu.trove.THashMap; import org.jdom.Document; import org.jdom.Element; @@ -37,9 +35,9 @@ import java.io.IOException; import java.util.*; public class DirectoryStorageData { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.DirectoryStorageData"); + private static final Logger LOG = Logger.getInstance(DirectoryStorageData.class); - private Map<String, Map<IFile, Element>> myStates = new HashMap<String, Map<IFile, Element>>(); + private Map<String, Map<File, Element>> myStates = new THashMap<String, Map<File, Element>>(); private long myLastTimestamp = 0; private DirectoryStorageData myOriginalData; @@ -79,7 +77,7 @@ public class DirectoryStorageData { pathMacroSubstitutor.addUnknownMacros(componentName, unknownMacros); } - put(componentName, FileSystem.FILE_SYSTEM.createFile(file.getPath()), element, true); + put(componentName, new File(file.getPath()), element, true); } catch (IOException e) { LOG.info("Unable to load state", e); @@ -90,44 +88,48 @@ public class DirectoryStorageData { } } - public void put(final String componentName, final IFile file, final Element element, final boolean updateTimestamp) { + public void put(final String componentName, File file, final Element element, final boolean updateTimestamp) { LOG.assertTrue(componentName != null, String.format("Component name should not be null for file: %s", file == null ? "NULL!" : file.getPath())); - Map<IFile, Element> stateMap = myStates.get(componentName); + Map<File, Element> stateMap = myStates.get(componentName); if (stateMap == null) { - stateMap = new HashMap<IFile, Element>(); + stateMap = new THashMap<File, Element>(); myStates.put(componentName, stateMap); } stateMap.put(file, element); - if (updateTimestamp) updateLastTimestamp(file); + if (updateTimestamp) { + updateLastTimestamp(file); + } } - public void updateLastTimestamp(final IFile file) { - myLastTimestamp = Math.max(myLastTimestamp, file.getTimeStamp()); - if (myOriginalData != null) myOriginalData.myLastTimestamp = myLastTimestamp; + public void updateLastTimestamp(File file) { + myLastTimestamp = Math.max(myLastTimestamp, file.lastModified()); + if (myOriginalData != null) { + myOriginalData.myLastTimestamp = myLastTimestamp; + } } public long getLastTimeStamp() { return myLastTimestamp; } - public Map<IFile, Long> getAllStorageFiles() { - final Map<IFile, Long> allStorageFiles = new THashMap<IFile, Long>(); + public Map<File, Long> getAllStorageFiles() { + final Map<File, Long> allStorageFiles = new THashMap<File, Long>(); process(new StorageDataProcessor() { @Override - public void process(final String componentName, final IFile file, final Element element) { - allStorageFiles.put(file, file.getTimeStamp()); + public void process(final String componentName, final File file, final Element element) { + allStorageFiles.put(file, file.lastModified()); } }); return allStorageFiles; } - public void processComponent(@NotNull final String componentName, @NotNull final PairConsumer<IFile, Element> consumer) { - final Map<IFile, Element> map = myStates.get(componentName); + public void processComponent(@NotNull final String componentName, @NotNull final PairConsumer<File, Element> consumer) { + final Map<File, Element> map = myStates.get(componentName); if (map != null) { - for (IFile file : map.keySet()) { + for (File file : map.keySet()) { consumer.consume(file, map.get(file)); } } @@ -135,10 +137,10 @@ public class DirectoryStorageData { public void process(@NotNull final StorageDataProcessor processor) { for (final String componentName : myStates.keySet()) { - processComponent(componentName, new PairConsumer<IFile, Element>() { + processComponent(componentName, new PairConsumer<File, Element>() { @Override - public void consume(final IFile iFile, final Element element) { - processor.process(componentName, iFile, element); + public void consume(File file, Element element) { + processor.process(componentName, file, element); } }); } @@ -147,7 +149,7 @@ public class DirectoryStorageData { @Override protected DirectoryStorageData clone() { final DirectoryStorageData result = new DirectoryStorageData(); - result.myStates = new HashMap<String, Map<IFile, Element>>(myStates); + result.myStates = new HashMap<String, Map<File, Element>>(myStates); result.myLastTimestamp = myLastTimestamp; result.myOriginalData = this; return result; @@ -169,9 +171,9 @@ public class DirectoryStorageData { @Nullable public <T> T getMergedState(String componentName, Class<T> stateClass, StateSplitter splitter, @Nullable T mergeInto) { final List<Element> subElements = new ArrayList<Element>(); - processComponent(componentName, new PairConsumer<IFile, Element>() { + processComponent(componentName, new PairConsumer<File, Element>() { @Override - public void consume(final IFile iFile, final Element element) { + public void consume(File file, Element element) { final List children = element.getChildren(); assert children.size() == 1 : JDOMUtil.writeElement(element, File.separator); final Element subElement = (Element)children.get(0); @@ -188,6 +190,6 @@ public class DirectoryStorageData { } interface StorageDataProcessor { - void process(String componentName, IFile file, Element element); + void process(String componentName, File file, Element element); } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java index 82dece3ba5e1..699440e22b54 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/StorageData.java @@ -16,6 +16,7 @@ package com.intellij.openapi.components.impl.stores; import com.intellij.application.options.PathMacrosCollector; +import com.intellij.ide.plugins.IdeaPluginDescriptorImpl; import com.intellij.openapi.components.PathMacroSubstitutor; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; import com.intellij.openapi.components.XmlConfigurationMerger; @@ -23,20 +24,23 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; import gnu.trove.THashMap; import gnu.trove.THashSet; import org.jdom.Attribute; import org.jdom.Element; +import org.jdom.JDOMException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.io.InputStream; import java.util.*; public class StorageData { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.StorageData"); + private static final Logger LOG = Logger.getInstance(StorageData.class); @NonNls public static final String COMPONENT = "component"; @NonNls public static final String NAME = "name"; @@ -44,17 +48,21 @@ public class StorageData { protected final String myRootElementName; private int myHash = -1; - public StorageData(final String rootElementName) { + public StorageData(@NotNull String rootElementName) { myComponentStates = new THashMap<String, Element>(); myRootElementName = rootElementName; } - StorageData(StorageData storageData) { + StorageData(@NotNull StorageData storageData) { myRootElementName = storageData.myRootElementName; myComponentStates = new THashMap<String, Element>(storageData.myComponentStates); } - public void load(@NotNull Element rootElement) throws IOException { + public void load(@NotNull Element rootElement, @Nullable PathMacroSubstitutor pathMacroSubstitutor, boolean intern) { + if (pathMacroSubstitutor != null) { + pathMacroSubstitutor.expandPaths(rootElement); + } + for (Iterator<Element> iterator = rootElement.getChildren(COMPONENT).iterator(); iterator.hasNext(); ) { Element element = iterator.next(); String name = element.getAttributeValue(NAME); @@ -63,33 +71,47 @@ public class StorageData { continue; } - iterator.remove(); - if (element.getAttributes().size() > 1 || !element.getChildren().isEmpty()) { assert element.getAttributeValue(NAME) != null : "No name attribute for component: " + name + " in " + this; - Element existingElement = myComponentStates.get(name); - if (existingElement != null) { - element = mergeElements(name, element, existingElement); + iterator.remove(); + if (intern) { + IdeaPluginDescriptorImpl.internJDOMElement(element); + } + + Element serverElement = myComponentStates.get(name); + if (serverElement != null) { + element = mergeElements(name, element, serverElement); } myComponentStates.put(name, element); } } + + if (pathMacroSubstitutor instanceof TrackingPathMacroSubstitutor) { + for (String componentName : myComponentStates.keySet()) { + ((TrackingPathMacroSubstitutor)pathMacroSubstitutor).addUnknownMacros(componentName, PathMacrosCollector.getMacroNames(myComponentStates.get(componentName))); + } + } } - private static Element mergeElements(final String name, final Element element1, final Element element2) { + @NotNull + private static Element mergeElements(@NotNull String name, @NotNull Element localElement, @NotNull Element serverElement) { ExtensionPoint<XmlConfigurationMerger> point = Extensions.getRootArea().getExtensionPoint("com.intellij.componentConfigurationMerger"); for (XmlConfigurationMerger merger : point.getExtensions()) { if (merger.getComponentName().equals(name)) { - return merger.merge(element1, element2); + return merger.merge(serverElement, localElement); } } - return element1; + return serverElement; } - @NotNull + @Nullable protected Element save() { + if (myComponentStates.isEmpty()) { + return null; + } + Element rootElement = new Element(myRootElementName); String[] componentNames = ArrayUtil.toStringArray(myComponentStates.keySet()); Arrays.sort(componentNames); @@ -101,7 +123,6 @@ public class StorageData { rootElement.addContent(element.clone()); } - return rootElement; } @@ -197,20 +218,18 @@ public class StorageData { return myComponentStates.isEmpty(); } - public boolean hasState(final String componentName) { + public boolean hasState(@NotNull String componentName) { return myComponentStates.containsKey(componentName); } - public void checkUnknownMacros(TrackingPathMacroSubstitutor pathMacroSubstitutor) { - if (pathMacroSubstitutor == null) { - return; + @NotNull + public static Element load(@NotNull VirtualFile file) throws IOException, JDOMException { + InputStream stream = file.getInputStream(); + try { + return JDOMUtil.loadDocument(stream).getRootElement(); } - - for (String componentName : myComponentStates.keySet()) { - final Set<String> unknownMacros = PathMacrosCollector.getMacroNames(myComponentStates.get(componentName)); - if (!unknownMacros.isEmpty()) { - pathMacroSubstitutor.addUnknownMacros(componentName, unknownMacros); - } + finally { + stream.close(); } } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java index bd9531a2d888..a55f2a1e0b00 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java @@ -71,6 +71,13 @@ public class RootIndex { private final TObjectIntHashMap<JpsModuleSourceRootType<?>> myRootTypeId = new TObjectIntHashMap<JpsModuleSourceRootType<?>>(); @NotNull private final Project myProject; private volatile Map<VirtualFile, OrderEntry[]> myOrderEntries; + @SuppressWarnings("UnusedDeclaration") + private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() { + @Override + public void run() { + myNonExistentPackages.clear(); + } + }); // made public for Upsource public RootIndex(@NotNull Project project, @NotNull InfoCache cache) { @@ -90,12 +97,6 @@ public class RootIndex { myProjectExcludedRoots.add(root); } } - LowMemoryWatcher.register(new Runnable() { - @Override - public void run() { - myNonExistentPackages.clear(); - } - }, project); } @NotNull diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/JarDirectories.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/JarDirectories.java index e9e4da53dddd..c4903098fa87 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/JarDirectories.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/JarDirectories.java @@ -106,7 +106,7 @@ public class JarDirectories implements JDOMExternalizable { @Override public String toString() { - return "Jar dirs: " + myDirectories.values(); + return "JAR dirs: " + myDirectories.values(); } diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties index a0fe65ad981a..956bb8a0d2d2 100644 --- a/platform/projectModel-impl/src/messages/ProjectBundle.properties +++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties @@ -112,7 +112,7 @@ module.paths.edit.properties.title=Edit Root Properties module.javadoc.title=JavaDoc module.javadoc.add.url.button=Add JavaDoc URL... module.javadoc.add.path.title=Add Path To JavaDoc -module.javadoc.add.path.prompt=Select jar/zip files or directories in which module javadoc documentation is located +module.javadoc.add.path.prompt=Select JAR/zip files or directories in which module javadoc documentation is located jdk.combo.box.project.item=<No Project SDK> jdk.combo.box.none.item=<None> jdk.combo.box.invalid.item={0} [Invalid] @@ -134,7 +134,7 @@ library.sources.not.found=Sources not found library.sources.not.attached=Sources not attached library.attach.sources.action=Attach Sources library.attach.sources.action.busy.text=Attaching... -library.attach.sources.description=Select jar/zip files or directories in which library sources are located +library.attach.sources.description=Select JAR/zip files or directories in which library sources are located project.sdk.not.defined=Project SDK is not defined project.sdk.setup=Setup SDK |