diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java b/java/compiler/impl/src/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java index 32304df2c309..1d9b5c0e88e4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java +++ b/java/compiler/impl/src/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java @@ -136,7 +136,7 @@ public class LibraryDefinitionsGeneratorFactory { libraryPath.add(new PathElement(path)); } else if (url.startsWith(LocalFileSystem.PROTOCOL_PREFIX)) { - if (library.isJarDirectory(url)) { + if (library.isJarDirectory(url, OrderRootType.CLASSES)) { final FileSet fileSet = new FileSet(path); fileSet.add(new PatternSetRef(BuildProperties.PROPERTY_LIBRARIES_PATTERNS)); libraryPath.add(fileSet); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java index fa390aa0a17f..5a788800b5fc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/DefaultLibraryRootsComponentDescriptor.java @@ -46,8 +46,10 @@ public class DefaultLibraryRootsComponentDescriptor extends LibraryRootsComponen @NotNull @Override public List createAttachButtons() { - return Arrays.asList(new AttachClassesDescriptor(), new AttachJarDirectoriesDescriptor(), new AttachSourcesDescriptor(), - new AttachAnnotationsDescriptor(), new AttachJavadocDescriptor(), new AttachUrlJavadocDescriptor()); + return Arrays.asList(new AttachClassesDescriptor(), new AttachJarDirectoriesDescriptor(), + new AttachSourcesDescriptor(), new AttachJarSourcesDirectoriesDescriptor(), + new AttachAnnotationsDescriptor(), new AttachJavadocDescriptor(), + new AttachUrlJavadocDescriptor()); } public static OrderRootTypePresentation getDefaultPresentation(OrderRootType type) { @@ -105,6 +107,33 @@ public class DefaultLibraryRootsComponentDescriptor extends LibraryRootsComponen } } + private static class AttachJarSourcesDirectoriesDescriptor extends ChooserBasedAttachRootButtonDescriptor { + private AttachJarSourcesDirectoriesDescriptor() { + super(OrderRootType.SOURCES, ProjectBundle.message("module.libraries.attach.jar.sources.directories.button")); + } + + public FileChooserDescriptor createChooserDescriptor() { + return new FileChooserDescriptor(false, true, false, false, false, true); + } + + public boolean addAsJarDirectories() { + return true; + } + + public String getChooserTitle(final String libraryName) { + if (StringUtil.isEmpty(libraryName)) { + return ProjectBundle.message("library.attach.jar.sources.directory.action"); + } + else { + return ProjectBundle.message("library.attach.jar.sources.directory.to.library.action", libraryName); + } + } + + public String getChooserDescription() { + return ProjectBundle.message("library.attach.jar.sources.directory.description"); + } + } + private static class AttachSourcesDescriptor extends ChooserBasedAttachRootButtonDescriptor { private AttachSourcesDescriptor() { super(OrderRootType.SOURCES, ProjectBundle.message("module.libraries.attach.sources.button")); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ExistingLibraryEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ExistingLibraryEditor.java index 6b0c1714db2d..7a87721259bc 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ExistingLibraryEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ExistingLibraryEditor.java @@ -125,6 +125,16 @@ public class ExistingLibraryEditor implements LibraryEditor, Disposable { getModel().addJarDirectory(url, recursive); } + @Override + public void addJarDirectory(VirtualFile file, boolean recursive, OrderRootType rootType) { + getModel().addJarDirectory(file, recursive, rootType); + } + + @Override + public void addJarDirectory(String url, boolean recursive, OrderRootType rootType) { + getModel().addJarDirectory(url, recursive, rootType); + } + @Override public void removeRoot(String url, OrderRootType rootType) { while (getModel().removeRoot(url, rootType)) ; @@ -156,13 +166,18 @@ public class ExistingLibraryEditor implements LibraryEditor, Disposable { } return myLibraryProperties != null && !myLibraryProperties.equals(getOriginalProperties()); } - + @Override public boolean isJarDirectory(String url) { + return isJarDirectory(url, OrderRootType.CLASSES); + } + + @Override + public boolean isJarDirectory(String url, OrderRootType rootType) { if (myModel != null) { - return myModel.isJarDirectory(url); + return myModel.isJarDirectory(url, rootType); } - return myLibrary.isJarDirectory(url); + return myLibrary.isJarDirectory(url, rootType); } @Override @@ -170,6 +185,6 @@ public class ExistingLibraryEditor implements LibraryEditor, Disposable { if (myModel != null) { return myModel.isValid(url, orderRootType); } - return myLibrary.isValid(url, orderRootType); + return myLibrary.isValid(url, orderRootType); } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java index 9a0efca27789..1fd0900aa4af 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryRootsComponent.java @@ -325,7 +325,7 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent final LibraryEditor libraryEditor = getLibraryEditor(); for (VirtualFile file : filesToAttach) { if (isJarDirectories) { - libraryEditor.addJarDirectory(file, false); + libraryEditor.addJarDirectory(file, false, rootType); } else { libraryEditor.addRoot(file, rootType); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeStructure.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeStructure.java index de7eb1e62a4a..b4033f43efcd 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeStructure.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryTreeStructure.java @@ -77,7 +77,7 @@ public class LibraryTreeStructure extends AbstractTreeStructure { final String[] urls = libraryEditor.getUrls(orderRootType).clone(); Arrays.sort(urls, LibraryRootsComponent.ourUrlComparator); for (String url : urls) { - items.add(new ItemElement(rootTypeElement, url, orderRootType, libraryEditor.isJarDirectory(url), libraryEditor.isValid(url, orderRootType))); + items.add(new ItemElement(rootTypeElement, url, orderRootType, libraryEditor.isJarDirectory(url, orderRootType), libraryEditor.isValid(url, orderRootType))); } return items.toArray(); } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java index 7f74f68b1b0e..264a0cb00bc8 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java @@ -16,6 +16,7 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor; import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.impl.libraries.JarDirectories; import com.intellij.openapi.roots.impl.libraries.LibraryImpl; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryProperties; @@ -28,7 +29,9 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; /** * @author nik @@ -36,7 +39,7 @@ import java.util.*; public class NewLibraryEditor implements LibraryEditor { private String myLibraryName; private final MultiMap myRoots; - private final Map myJarDirectories = new HashMap(); + private final JarDirectories myJarDirectories = new JarDirectories(); private final LibraryType myType; private LibraryProperties myProperties; @@ -86,9 +89,9 @@ public class NewLibraryEditor implements LibraryEditor { } if (file.isDirectory()) { - final Boolean recursively = myJarDirectories.get(file.getUrl()); - if (recursively != null) { - LibraryImpl.collectJarFiles(file, result, recursively); + final String url = file.getUrl(); + if (myJarDirectories.contains(rootType, url)) { + LibraryImpl.collectJarFiles(file, result, myJarDirectories.isRecursive(rootType, url)); continue; } } @@ -114,19 +117,29 @@ public class NewLibraryEditor implements LibraryEditor { @Override public void addJarDirectory(VirtualFile file, boolean recursive) { - addJarDirectory(file.getUrl(), recursive); + addJarDirectory(file.getUrl(), recursive, OrderRootType.CLASSES); } @Override public void addJarDirectory(final String url, boolean recursive) { - addRoot(url, OrderRootType.CLASSES); - myJarDirectories.put(url, recursive); + addJarDirectory(url, recursive, OrderRootType.CLASSES); + } + + @Override + public void addJarDirectory(VirtualFile file, boolean recursive, OrderRootType rootType) { + addJarDirectory(file.getUrl(), recursive, rootType); + } + + @Override + public void addJarDirectory(final String url, boolean recursive, OrderRootType rootType) { + addRoot(url, rootType); + myJarDirectories.add(rootType, url, recursive); } @Override public void removeRoot(String url, OrderRootType rootType) { myRoots.removeValue(rootType, new LightFilePointer(url)); - myJarDirectories.remove(url); + myJarDirectories.remove(rootType, url); } @Override @@ -136,7 +149,12 @@ public class NewLibraryEditor implements LibraryEditor { @Override public boolean isJarDirectory(String url) { - return myJarDirectories.containsKey(url); + return isJarDirectory(url, OrderRootType.CLASSES); + } + + @Override + public boolean isJarDirectory(String url, OrderRootType rootType) { + return myJarDirectories.contains(rootType, url); } @Override @@ -161,8 +179,10 @@ public class NewLibraryEditor implements LibraryEditor { model.addRoot(pointer.getUrl(), type); } } - for (Map.Entry entry : myJarDirectories.entrySet()) { - model.addJarDirectory(entry.getKey(), entry.getValue()); + for (OrderRootType rootType : myJarDirectories.getRootTypes()) { + for (String url : myJarDirectories.getDirectories(rootType)) { + model.addJarDirectory(url, myJarDirectories.isRecursive(rootType, url), rootType); + } } } @@ -172,8 +192,10 @@ public class NewLibraryEditor implements LibraryEditor { editor.addRoot(pointer.getUrl(), type); } } - for (Map.Entry entry : myJarDirectories.entrySet()) { - editor.addJarDirectory(entry.getKey(), entry.getValue()); + for (OrderRootType rootType : myJarDirectories.getRootTypes()) { + for (String url : myJarDirectories.getDirectories(rootType)) { + editor.addJarDirectory(url, myJarDirectories.isRecursive(rootType, url), rootType); + } } } } diff --git a/platform/lang-api/src/com/intellij/openapi/roots/libraries/Library.java b/platform/lang-api/src/com/intellij/openapi/roots/libraries/Library.java index ee342b92fa66..4a2f6ae8310f 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/libraries/Library.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/libraries/Library.java @@ -36,7 +36,7 @@ public interface Library extends JDOMExternalizable, Disposable { @NotNull VirtualFile[] getFiles(@NotNull OrderRootType rootType); /** - * As soon as you obtaining modifiable model you will have to commit it or call Disposer.dispose(model)! + * As soon as you obtaining modifiable model you will have to commit it or call Disposer.dispose(model)! */ @NotNull ModifiableModel getModifiableModel(); @@ -45,9 +45,11 @@ public interface Library extends JDOMExternalizable, Disposable { @NotNull RootProvider getRootProvider(); boolean isJarDirectory(@NotNull String url); - + + boolean isJarDirectory(@NotNull String url, @NotNull OrderRootType rootType); + boolean isValid(@NotNull String url, @NotNull OrderRootType rootType); - + interface ModifiableModel extends Disposable { @NotNull String[] getUrls(@NotNull OrderRootType rootType); @@ -56,13 +58,17 @@ public interface Library extends JDOMExternalizable, Disposable { String getName(); void addRoot(@NonNls @NotNull String url, @NotNull OrderRootType rootType); - + void addJarDirectory(@NotNull String url, boolean recursive); + void addJarDirectory(@NotNull String url, boolean recursive, @NotNull OrderRootType rootType); + void addRoot(@NotNull VirtualFile file, @NotNull OrderRootType rootType); - + void addJarDirectory(@NotNull VirtualFile file, boolean recursive); + void addJarDirectory(@NotNull VirtualFile file, boolean recursive, @NotNull OrderRootType rootType); + void moveRootUp(@NotNull String url, @NotNull OrderRootType rootType); void moveRootDown(@NotNull String url, @NotNull OrderRootType rootType); @@ -74,9 +80,11 @@ public interface Library extends JDOMExternalizable, Disposable { @NotNull VirtualFile[] getFiles(@NotNull OrderRootType rootType); boolean isChanged(); - + boolean isJarDirectory(@NotNull String url); - + + boolean isJarDirectory(@NotNull String url, @NotNull OrderRootType rootType); + boolean isValid(@NotNull String url, @NotNull OrderRootType rootType); } } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/JarDirectories.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/JarDirectories.java new file mode 100644 index 000000000000..982136447b05 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/JarDirectories.java @@ -0,0 +1,96 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.impl.libraries; + +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.util.containers.MultiMap; + +import java.util.Collection; + +/** + * @author nik + */ +public class JarDirectories { + private MultiMap myDirectories = new MultiMap(); + private MultiMap myRecursivelyIncluded = new MultiMap(); + + public void copyFrom(JarDirectories other) { + myDirectories.clear(); + myDirectories.putAllValues(other.myDirectories); + myRecursivelyIncluded.clear(); + myRecursivelyIncluded.putAllValues(other.myRecursivelyIncluded); + } + + public boolean contains(OrderRootType rootType, String url) { + return myDirectories.get(rootType).contains(url); + } + + public boolean isRecursive(OrderRootType rootType, String url) { + return myRecursivelyIncluded.get(rootType).contains(url); + } + + public void add(OrderRootType rootType, String url, boolean recursively) { + myDirectories.putValue(rootType, url); + if (recursively) { + myRecursivelyIncluded.putValue(rootType, url); + } + } + + public void remove(OrderRootType rootType, String url) { + myDirectories.removeValue(rootType, url); + myRecursivelyIncluded.removeValue(rootType, url); + } + + public void clear() { + myDirectories.clear(); + myRecursivelyIncluded.clear(); + } + + public Collection getRootTypes() { + return myDirectories.keySet(); + } + + public Collection getDirectories(OrderRootType rootType) { + return myDirectories.get(rootType); + } + + public Collection getAllDirectories() { + return myDirectories.values(); + } + + public boolean isEmpty() { + return myDirectories.isEmpty(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof JarDirectories)) return false; + + JarDirectories that = (JarDirectories)o; + return myDirectories.equals(that.myDirectories) && myRecursivelyIncluded.equals(that.myRecursivelyIncluded); + } + + @Override + public int hashCode() { + return 31 * myDirectories.hashCode() + myRecursivelyIncluded.hashCode(); + } + + @Override + public String toString() { + return "Jar dirs: " + myDirectories.values(); + } +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index cbabc68259f1..649f05317175 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -65,12 +65,14 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { @NonNls private static final String JAR_DIRECTORY_ELEMENT = "jarDirectory"; @NonNls private static final String URL_ATTR = "url"; @NonNls private static final String RECURSIVE_ATTR = "recursive"; + @NonNls private static final String ROOT_TYPE_ATTR = "type"; @NonNls private static final String PROPERTIES_ELEMENT = "properties"; + private static final OrderRootType DEFAULT_JAR_DIRECTORY_TYPE = OrderRootType.CLASSES; private static final SkipDefaultValuesSerializationFilters SERIALIZATION_FILTERS = new SkipDefaultValuesSerializationFilters(); private String myName; private final LibraryTable myLibraryTable; private final Map myRoots; - private final Map myJarDirectories = new HashMap(); + private final JarDirectories myJarDirectories = new JarDirectories(); private final List myWatchRequests = new ArrayList(); private final LibraryImpl mySource; private LibraryType myType; @@ -106,7 +108,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { myRoots = initRoots(); mySource = null; } - + private Set getAllRootTypes() { Set rootTypes = new HashSet(); rootTypes.addAll(Arrays.asList(OrderRootType.getAllTypes())); @@ -114,7 +116,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { rootTypes.addAll(Arrays.asList(myType.getAdditionalRootTypes())); } return rootTypes; - } + } private LibraryImpl(LibraryImpl from, LibraryImpl newSource, ModifiableRootModel rootModel) { assert !from.isDisposed(); @@ -134,7 +136,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { final VirtualFilePointerContainer thatContainer = from.myRoots.get(rootType); thisContainer.addAll(thatContainer); } - myJarDirectories.putAll(from.myJarDirectories); + myJarDirectories.copyFrom(from.myJarDirectories); } public void dispose() { @@ -171,9 +173,8 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { final List expanded = new ArrayList(); for (VirtualFile file : myRoots.get(rootType).getFiles()) { if (file.isDirectory()) { - final Boolean expandRecursively = myJarDirectories.get(file.getUrl()); - if (expandRecursively != null) { - collectJarFiles(file, expanded, expandRecursively.booleanValue()); + if (myJarDirectories.contains(rootType, file.getUrl())) { + collectJarFiles(file, expanded, myJarDirectories.isRecursive(rootType, file.getUrl())); continue; } } @@ -242,7 +243,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { private Map initRoots() { Disposer.register(this, myPointersDisposable); - + Map result = new HashMap(5); for (OrderRootType rootType : getAllRootTypes()) { @@ -301,16 +302,25 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { final Element jarDir = (Element)item; final String url = jarDir.getAttributeValue(URL_ATTR); final String recursive = jarDir.getAttributeValue(RECURSIVE_ATTR); + final OrderRootType rootType = getJarDirectoryRootType(jarDir.getAttributeValue(ROOT_TYPE_ATTR)); if (url != null) { - myJarDirectories.put(url, Boolean.valueOf(Boolean.parseBoolean(recursive))); + myJarDirectories.add(rootType, url, Boolean.valueOf(Boolean.parseBoolean(recursive))); } } } - - //TODO Remove the next two methods as a temporary solution. Sort in OrderRootType. + private static OrderRootType getJarDirectoryRootType(@Nullable String type) { + for (PersistentOrderRootType rootType : OrderRootType.getAllPersistentTypes()) { + if (rootType.name().equals(type)) { + return rootType; + } + } + return DEFAULT_JAR_DIRECTORY_TYPE; + } + + //TODO Remove the next two methods as a temporary solution. Sort in OrderRootType. // - private static List sortRootTypes(List rootTypes) { + private static List sortRootTypes(Collection rootTypes) { List allTypes = new ArrayList(rootTypes); Collections.sort(allTypes, new Comparator() { public int compare(final OrderRootType o1, final OrderRootType o2) { @@ -319,7 +329,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { }); return allTypes; } - + private static String getSortKey(OrderRootType orderRootType) { if (orderRootType instanceof PersistentOrderRootType) { return ((PersistentOrderRootType)orderRootType).getSdkRootName(); @@ -359,17 +369,19 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { roots.writeExternal(rootTypeElement, ROOT_PATH_ELEMENT); element.addContent(rootTypeElement); } - List urls = new ArrayList(myJarDirectories.keySet()); - Collections.sort(urls, new Comparator() { - public int compare(final String url1, final String url2) { - return url1.compareToIgnoreCase(url2); + final List rootTypes = sortRootTypes(myJarDirectories.getRootTypes()); + for (OrderRootType rootType : rootTypes) { + final List urls = new ArrayList(myJarDirectories.getDirectories(rootType)); + Collections.sort(urls, String.CASE_INSENSITIVE_ORDER); + for (String url : urls) { + final Element jarDirElement = new Element(JAR_DIRECTORY_ELEMENT); + jarDirElement.setAttribute(URL_ATTR, url); + jarDirElement.setAttribute(RECURSIVE_ATTR, Boolean.toString(myJarDirectories.isRecursive(rootType, url))); + if (!rootType.equals(DEFAULT_JAR_DIRECTORY_TYPE)) { + jarDirElement.setAttribute(ROOT_TYPE_ATTR, rootType.name()); + } + element.addContent(jarDirElement); } - }); - for (String url : urls) { - final Element jarDirElement = new Element(JAR_DIRECTORY_ELEMENT); - jarDirElement.setAttribute(URL_ATTR, url); - jarDirElement.setAttribute(RECURSIVE_ATTR, myJarDirectories.get(url).toString()); - element.addContent(jarDirElement); } rootElement.addContent(element); } @@ -405,23 +417,35 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { } public void addJarDirectory(@NotNull final String url, final boolean recursive) { - assert !isDisposed(); - LOG.assertTrue(isWritable()); - final VirtualFilePointerContainer container = myRoots.get(OrderRootType.CLASSES); - container.add(url); - myJarDirectories.put(url, Boolean.valueOf(recursive)); + addJarDirectory(url, recursive, DEFAULT_JAR_DIRECTORY_TYPE); } public void addJarDirectory(@NotNull final VirtualFile file, final boolean recursive) { + addJarDirectory(file, recursive, DEFAULT_JAR_DIRECTORY_TYPE); + } + + public void addJarDirectory(@NotNull final String url, final boolean recursive, @NotNull OrderRootType rootType) { assert !isDisposed(); LOG.assertTrue(isWritable()); - final VirtualFilePointerContainer container = myRoots.get(OrderRootType.CLASSES); + final VirtualFilePointerContainer container = myRoots.get(rootType); + container.add(url); + myJarDirectories.add(rootType, url, recursive); + } + + public void addJarDirectory(@NotNull final VirtualFile file, final boolean recursive, @NotNull OrderRootType rootType) { + assert !isDisposed(); + LOG.assertTrue(isWritable()); + final VirtualFilePointerContainer container = myRoots.get(rootType); container.add(file); - myJarDirectories.put(file.getUrl(), Boolean.valueOf(recursive)); + myJarDirectories.add(rootType, file.getUrl(), recursive); } public boolean isJarDirectory(@NotNull final String url) { - return myJarDirectories.containsKey(url); + return isJarDirectory(url, DEFAULT_JAR_DIRECTORY_TYPE); + } + + public boolean isJarDirectory(@NotNull final String url, @NotNull final OrderRootType rootType) { + return myJarDirectories.contains(rootType, url); } public boolean isValid(@NotNull final String url, @NotNull final OrderRootType rootType) { @@ -437,7 +461,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { final VirtualFilePointer byUrl = container.findByUrl(url); if (byUrl != null) { container.remove(byUrl); - myJarDirectories.remove(url); + myJarDirectories.remove(rootType, url); return true; } return false; @@ -510,8 +534,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { if (areRootsChanged(fromModel)) { disposeMyPointers(); copyRootsFrom(fromModel); - myJarDirectories.clear(); - myJarDirectories.putAll(fromModel.myJarDirectories); + myJarDirectories.copyFrom(fromModel.myJarDirectories); updateWatchedRoots(); myRootProvider.fireRootSetChanged(); } @@ -543,12 +566,13 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { } if (!myJarDirectories.isEmpty()) { final VirtualFileManager fm = VirtualFileManager.getInstance(); - for (Map.Entry entry : myJarDirectories.entrySet()) { - String url = entry.getKey(); - if (fm.getFileSystem(VirtualFileManager.extractProtocol(url)) instanceof LocalFileSystem) { - final boolean watchRecursively = entry.getValue().booleanValue(); - final LocalFileSystem.WatchRequest request = fs.addRootToWatch(VirtualFileManager.extractPath(url), watchRecursively); - myWatchRequests.add(request); + for (OrderRootType rootType : myJarDirectories.getRootTypes()) { + for (String url : myJarDirectories.getDirectories(rootType)) { + if (fm.getFileSystem(VirtualFileManager.extractProtocol(url)) instanceof LocalFileSystem) { + final boolean watchRecursively = myJarDirectories.isRecursive(rootType, url); + final LocalFileSystem.WatchRequest request = fs.addRootToWatch(VirtualFileManager.extractPath(url), watchRecursively); + myWatchRequests.add(request); + } } } if (myBusConnection == null) { @@ -599,7 +623,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { } private boolean isUnderJarDirectory(String url) { - for (String rootUrl : myJarDirectories.keySet()) { + for (String rootUrl : myJarDirectories.getAllDirectories()) { if (FileUtil.startsWith(url, rootUrl)) { return true; } @@ -666,7 +690,7 @@ public class LibraryImpl implements LibraryEx.ModifiableModelEx, LibraryEx { @Override public String toString() { - return "Library: name:" + myName + "; jars:" + myJarDirectories.keySet() + "; roots:" + myRoots.values(); + return "Library: name:" + myName + "; jars:" + myJarDirectories + "; roots:" + myRoots.values(); } @Nullable("will return non-null value only for module level libraries") diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java index fb963d9cc85f..3425a3752209 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/LibraryEditor.java @@ -41,12 +41,18 @@ public interface LibraryEditor { void addJarDirectory(String url, boolean recursive); + void addJarDirectory(VirtualFile file, boolean recursive, OrderRootType rootType); + + void addJarDirectory(String url, boolean recursive, OrderRootType rootType); + void removeRoot(String url, OrderRootType rootType); boolean hasChanges(); boolean isJarDirectory(String url); + boolean isJarDirectory(String url, OrderRootType rootType); + boolean isValid(String url, OrderRootType orderRootType); LibraryProperties getProperties(); diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java index 65edbd7699af..8509b9b674d0 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameUtil.java @@ -74,14 +74,6 @@ public class RenameUtil { result.add(new MoveRenameUsageInfo(referenceElement, ref, ref.getRangeInElement().getStartOffset(), ref.getRangeInElement().getEndOffset(), element, ref.resolve() == null)); - if (!isValidName(element.getProject(), ref.getElement(), newName)) { - result.add(new UnresolvableCollisionUsageInfo(ref.getElement(), element) { - @Override - public String getDescription() { - return RefactoringBundle.message("0.is.not.an.identifier", newName, ref.getElement().getText()); - } - }); - } } processor.findCollisions(element, newName, allRenames, result); diff --git a/platform/platform-resources-en/src/messages/ProjectBundle.properties b/platform/platform-resources-en/src/messages/ProjectBundle.properties index daeb0acdff8a..66375fb926c4 100644 --- a/platform/platform-resources-en/src/messages/ProjectBundle.properties +++ b/platform/platform-resources-en/src/messages/ProjectBundle.properties @@ -170,6 +170,9 @@ library.attach.classes.description=Select jar/zip files or directories in which library.attach.jar.directory.to.library.action=Attach Jar Directories to Library \"{0}\" library.attach.jar.directory.action=Attach Jar Directories library.attach.jar.directory.description=Select directories in which jar/zip files are located +library.attach.jar.sources.directory.to.library.action=Attach Source Archive Directories to Library \"{0}\" +library.attach.jar.sources.directory.action=Attach Source Archive Directories +library.attach.jar.sources.directory.description=Select directories in which source jar/zip files are located library.sources.not.found=Sources not found library.sources.not.attached=Sources not attached library.attach.sources.action=Attach Sources @@ -179,6 +182,7 @@ library.attach.javadoc.action=Attach Javadoc library.attach.javadoc.description=Select jar/zip files or directories in which library javadoc documentation is located module.libraries.attach.jar.directories.button=Attach Jar &Directories... +module.libraries.attach.jar.sources.directories.button=Attach Source Archive D&irectories... library.attach.external.annotations.action=Attach external annotations library.attach.external.annotations.description=Select root where external annotations is located @@ -459,7 +463,7 @@ label.text.framework.support.description=This will download all needed libraries file.chooser.directory.for.downloaded.libraries.title=Directory for Downloaded Libraries file.chooser.directory.for.downloaded.libraries.description=Downloaded libraries will be copied to selected directory dialog.title.library.downloading.settings=Library Downloading Settings -directory.roots.copy.label=Copy library content to directory (optional): +directory.roots.copy.label=Copy library content to directory (optional): combobox.item.global.library=Global Library combobox.item.project.library=Project Library combobox.item.module.library=Module Library @@ -481,4 +485,4 @@ project.new.wizard.import.footnote=Import from external model is available from loading.components.for=Loading components for ''{0}'' initializing.components=Initializing components -library.docs.node=Documentation \ No newline at end of file +library.docs.node=Documentation diff --git a/platform/util/src/com/intellij/util/containers/MultiMap.java b/platform/util/src/com/intellij/util/containers/MultiMap.java index fb5a7d93e53b..c993760608a1 100644 --- a/platform/util/src/com/intellij/util/containers/MultiMap.java +++ b/platform/util/src/com/intellij/util/containers/MultiMap.java @@ -206,4 +206,16 @@ public class MultiMap { public static MultiMap emptyInstance() { return EMPTY; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof MultiMap)) return false; + return myMap.equals(((MultiMap)o).myMap); + } + + @Override + public int hashCode() { + return myMap.hashCode(); + } } diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 403b1089820e..f418d324ce57 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -1778,5 +1778,16 @@ public class UIUtil { }); } + @Nullable + public static T findComponentOfType(JComponent parent, Class cls) { + if (parent == null || cls.isAssignableFrom(parent.getClass())) return (T)parent; + for (Component component : parent.getComponents()) { + if (component instanceof JComponent) { + T comp = findComponentOfType((JComponent)component, cls); + if (comp != null) return comp; + } + } + return null; + } }