| /* |
| * Copyright 2000-2012 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.openapi.roots.ui.configuration.projectRoot; |
| |
| import com.intellij.ide.util.projectWizard.WizardContext; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.roots.*; |
| import com.intellij.openapi.roots.impl.libraries.LibraryEx; |
| import com.intellij.openapi.roots.impl.libraries.LibraryTableBase; |
| import com.intellij.openapi.roots.libraries.Library; |
| import com.intellij.openapi.roots.libraries.LibraryTable; |
| import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; |
| import com.intellij.openapi.roots.libraries.LibraryType; |
| import com.intellij.openapi.roots.libraries.ui.OrderRoot; |
| import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider; |
| import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; |
| import com.intellij.openapi.roots.ui.configuration.ModulesProvider; |
| import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor; |
| import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; |
| import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor; |
| import com.intellij.openapi.util.Condition; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.util.ArrayUtil; |
| import com.intellij.util.Function; |
| import com.intellij.util.text.UniqueNameGenerator; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.List; |
| |
| /** |
| * @author nik |
| */ |
| public class LibrariesContainerFactory { |
| private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory"); |
| private static final Library[] EMPTY_LIBRARIES_ARRAY = new Library[0]; |
| |
| private LibrariesContainerFactory() { |
| } |
| |
| @NotNull |
| public static LibrariesContainer createContainer(@Nullable Project project) { |
| return new LibrariesContainerImpl(project, null, null); |
| } |
| |
| @NotNull |
| public static LibrariesContainer createContainer(@NotNull Module module) { |
| return new LibrariesContainerImpl(module.getProject(), module, null); |
| } |
| |
| @NotNull |
| public static LibrariesContainer createContainer(@NotNull ModifiableRootModel rootModel) { |
| Module module = rootModel.getModule(); |
| return new LibrariesContainerImpl(module.getProject(), module, rootModel); |
| } |
| |
| public static LibrariesContainer createContainer(StructureConfigurableContext context) { |
| return new StructureConfigurableLibrariesContainer(context); |
| } |
| |
| public static Library createLibrary(@Nullable LibrariesContainer container1, @NotNull LibrariesContainer container2, |
| @NotNull @NonNls final NewLibraryEditor editor, @NotNull final LibrariesContainer.LibraryLevel level) { |
| if (container1 != null && container1.canCreateLibrary(level)) { |
| return container1.createLibrary(editor, level); |
| } |
| else { |
| return container2.createLibrary(editor, level); |
| } |
| } |
| |
| @NotNull |
| private static Library createLibraryInTable(final @NotNull NewLibraryEditor editor, final LibraryTable table) { |
| LibraryTableBase.ModifiableModelEx modifiableModel = (LibraryTableBase.ModifiableModelEx) table.getModifiableModel(); |
| final String name = StringUtil.isEmpty(editor.getName()) ? null : getUniqueLibraryName(editor.getName(), modifiableModel); |
| final LibraryType<?> type = editor.getType(); |
| Library library = modifiableModel.createLibrary(name, type == null ? null : type.getKind()); |
| final LibraryEx.ModifiableModelEx model = (LibraryEx.ModifiableModelEx)library.getModifiableModel(); |
| editor.applyTo(model); |
| model.commit(); |
| modifiableModel.commit(); |
| return library; |
| } |
| |
| private static String getUniqueLibraryName(final String baseName, final LibraryTable.ModifiableModel model) { |
| return UniqueNameGenerator.generateUniqueName(baseName, "", "", " (", ")", new Condition<String>() { |
| @Override |
| public boolean value(String s) { |
| return model.getLibraryByName(s) == null; |
| } |
| }); |
| } |
| |
| @NotNull |
| public static LibrariesContainer createContainer(@NotNull WizardContext context, @NotNull ModulesProvider modulesProvider) { |
| final LibrariesContainer container; |
| if (modulesProvider instanceof ModulesConfigurator) { |
| ModulesConfigurator configurator = (ModulesConfigurator)modulesProvider; |
| container = createContainer(configurator.getContext()); |
| } |
| else { |
| container = createContainer(context.getProject()); |
| } |
| return container; |
| } |
| |
| |
| private abstract static class LibrariesContainerBase implements LibrariesContainer { |
| private UniqueNameGenerator myNameGenerator; |
| |
| @Override |
| public Library createLibrary(@NotNull @NonNls String name, |
| @NotNull LibraryLevel level, |
| @NotNull VirtualFile[] classRoots, |
| @NotNull VirtualFile[] sourceRoots) { |
| NewLibraryEditor editor = new NewLibraryEditor(); |
| editor.setName(name); |
| for (VirtualFile classRoot : classRoots) { |
| editor.addRoot(classRoot, OrderRootType.CLASSES); |
| } |
| for (VirtualFile sourceRoot : sourceRoots) { |
| editor.addRoot(sourceRoot, OrderRootType.SOURCES); |
| } |
| return createLibrary(editor, level); |
| } |
| |
| @Override |
| public Library createLibrary(@NotNull @NonNls String name, |
| @NotNull LibraryLevel level, |
| @NotNull Collection<? extends OrderRoot> roots) { |
| final NewLibraryEditor editor = new NewLibraryEditor(); |
| editor.setName(name); |
| editor.addRoots(roots); |
| return createLibrary(editor, level); |
| } |
| |
| @Override |
| @NotNull |
| public Library[] getAllLibraries() { |
| Library[] libraries = getLibraries(LibraryLevel.GLOBAL); |
| Library[] projectLibraries = getLibraries(LibraryLevel.PROJECT); |
| if (projectLibraries.length > 0) { |
| libraries = ArrayUtil.mergeArrays(libraries, projectLibraries); |
| } |
| Library[] moduleLibraries = getLibraries(LibraryLevel.MODULE); |
| if (moduleLibraries.length > 0) { |
| libraries = ArrayUtil.mergeArrays(libraries, moduleLibraries); |
| } |
| return libraries; |
| } |
| |
| @NotNull |
| @Override |
| public List<LibraryLevel> getAvailableLevels() { |
| final List<LibraryLevel> levels = new ArrayList<LibraryLevel>(); |
| for (LibraryLevel level : LibraryLevel.values()) { |
| if (canCreateLibrary(level)) { |
| levels.add(level); |
| } |
| } |
| return levels; |
| } |
| |
| @NotNull |
| @Override |
| public String suggestUniqueLibraryName(@NotNull String baseName) { |
| if (myNameGenerator == null) { |
| myNameGenerator = new UniqueNameGenerator(Arrays.asList(getAllLibraries()), new Function<Library, String>() { |
| @Override |
| public String fun(Library o) { |
| return o.getName(); |
| } |
| }); |
| } |
| return myNameGenerator.generateUniqueName(baseName, "", "", " (", ")"); |
| } |
| } |
| |
| |
| private static class LibrariesContainerImpl extends LibrariesContainerBase { |
| private @Nullable final Project myProject; |
| @Nullable private final Module myModule; |
| @Nullable private final ModifiableRootModel myRootModel; |
| |
| private LibrariesContainerImpl(final @Nullable Project project, final @Nullable Module module, final @Nullable ModifiableRootModel rootModel) { |
| myProject = project; |
| myModule = module; |
| myRootModel = rootModel; |
| } |
| |
| @Override |
| @Nullable |
| public Project getProject() { |
| return myProject; |
| } |
| |
| @Override |
| @NotNull |
| public Library[] getLibraries(@NotNull final LibraryLevel libraryLevel) { |
| if (libraryLevel == LibraryLevel.MODULE && myModule != null) { |
| return getModuleLibraries(); |
| } |
| |
| LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance(); |
| if (libraryLevel == LibraryLevel.GLOBAL) { |
| return registrar.getLibraryTable().getLibraries(); |
| } |
| |
| if (libraryLevel == LibraryLevel.PROJECT && myProject != null) { |
| return registrar.getLibraryTable(myProject).getLibraries(); |
| } |
| |
| return EMPTY_LIBRARIES_ARRAY; |
| } |
| |
| private Library[] getModuleLibraries() { |
| if (myRootModel != null) { |
| return myRootModel.getModuleLibraryTable().getLibraries(); |
| } |
| OrderEntry[] orderEntries = ModuleRootManager.getInstance(myModule).getOrderEntries(); |
| List<Library> libraries = new ArrayList<Library>(); |
| for (OrderEntry orderEntry : orderEntries) { |
| if (orderEntry instanceof LibraryOrderEntry) { |
| final LibraryOrderEntry entry = (LibraryOrderEntry)orderEntry; |
| if (entry.isModuleLevel()) { |
| libraries.add(entry.getLibrary()); |
| } |
| } |
| } |
| return libraries.toArray(new Library[libraries.size()]); |
| } |
| |
| @Override |
| @NotNull |
| public VirtualFile[] getLibraryFiles(@NotNull final Library library, @NotNull final OrderRootType rootType) { |
| return library.getFiles(rootType); |
| } |
| |
| @Override |
| public boolean canCreateLibrary(@NotNull final LibraryLevel level) { |
| if (level == LibraryLevel.MODULE) { |
| return myRootModel != null; |
| } |
| return level == LibraryLevel.GLOBAL || myProject != null; |
| } |
| |
| @Override |
| public Library createLibrary(@NotNull NewLibraryEditor libraryEditor, |
| @NotNull LibraryLevel level) { |
| if (level == LibraryLevel.MODULE && myRootModel != null) { |
| return createLibraryInTable(libraryEditor, myRootModel.getModuleLibraryTable()); |
| } |
| |
| LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance(); |
| LibraryTable table; |
| if (level == LibraryLevel.GLOBAL) { |
| table = registrar.getLibraryTable(); |
| } |
| else if (level == LibraryLevel.PROJECT && myProject != null) { |
| table = registrar.getLibraryTable(myProject); |
| } |
| else { |
| return null; |
| } |
| return createLibraryInTable(libraryEditor, table); |
| } |
| |
| @Override |
| public ExistingLibraryEditor getLibraryEditor(@NotNull Library library) { |
| return null; |
| } |
| } |
| |
| private static class StructureConfigurableLibrariesContainer extends LibrariesContainerBase { |
| private final StructureConfigurableContext myContext; |
| |
| public StructureConfigurableLibrariesContainer(final StructureConfigurableContext context) { |
| myContext = context; |
| } |
| |
| @Override |
| public Library createLibrary(@NotNull NewLibraryEditor libraryEditor, |
| @NotNull LibraryLevel level) { |
| LibraryTableModifiableModelProvider provider = getProvider(level); |
| if (provider == null) { |
| LOG.error("cannot create module library in this context"); |
| } |
| |
| LibraryTableBase.ModifiableModelEx model = (LibraryTableBase.ModifiableModelEx)provider.getModifiableModel(); |
| final LibraryType<?> type = libraryEditor.getType(); |
| Library library = model.createLibrary(getUniqueLibraryName(libraryEditor.getName(), model), type == null ? null : type.getKind()); |
| ExistingLibraryEditor createdLibraryEditor = ((LibrariesModifiableModel)model).getLibraryEditor(library); |
| createdLibraryEditor.setProperties(libraryEditor.getProperties()); |
| libraryEditor.applyTo(createdLibraryEditor); |
| return library; |
| } |
| |
| @Override |
| public ExistingLibraryEditor getLibraryEditor(@NotNull Library library) { |
| final LibraryTable table = library.getTable(); |
| if (table == null) return null; |
| |
| final LibraryTable.ModifiableModel model = myContext.getModifiableLibraryTable(table); |
| if (model instanceof LibrariesModifiableModel) { |
| return ((LibrariesModifiableModel)model).getLibraryEditor(library); |
| } |
| return null; |
| } |
| |
| @Override |
| @Nullable |
| public Project getProject() { |
| return myContext.getProject(); |
| } |
| |
| @Override |
| @NotNull |
| public Library[] getLibraries(@NotNull final LibraryLevel libraryLevel) { |
| LibraryTableModifiableModelProvider provider = getProvider(libraryLevel); |
| return provider != null ? provider.getModifiableModel().getLibraries() : EMPTY_LIBRARIES_ARRAY; |
| } |
| |
| @Nullable |
| private LibraryTableModifiableModelProvider getProvider(LibraryLevel libraryLevel) { |
| if (libraryLevel == LibraryLevel.PROJECT) { |
| return myContext.getProjectLibrariesProvider(); |
| } |
| else if (libraryLevel == LibraryLevel.GLOBAL) { |
| return myContext.getGlobalLibrariesProvider(); |
| } |
| else { |
| return null; |
| } |
| } |
| |
| @Override |
| public boolean canCreateLibrary(@NotNull final LibraryLevel level) { |
| return level == LibraryLevel.GLOBAL || level == LibraryLevel.PROJECT; |
| } |
| |
| @Override |
| @NotNull |
| public VirtualFile[] getLibraryFiles(@NotNull final Library library, @NotNull final OrderRootType rootType) { |
| LibrariesModifiableModel projectLibrariesModel = myContext.getProjectLibrariesProvider().getModifiableModel(); |
| if (projectLibrariesModel.hasLibraryEditor(library)) { |
| LibraryEditor libraryEditor = projectLibrariesModel.getLibraryEditor(library); |
| return libraryEditor.getFiles(rootType); |
| } |
| LibrariesModifiableModel globalLibraries = myContext.getGlobalLibrariesProvider().getModifiableModel(); |
| if (globalLibraries.hasLibraryEditor(library)) { |
| LibraryEditor libraryEditor = globalLibraries.getLibraryEditor(library); |
| return libraryEditor.getFiles(rootType); |
| } |
| return library.getFiles(rootType); |
| } |
| } |
| } |