2 * Copyright 2000-2012 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.openapi.roots.ui.configuration.projectRoot;
18 import com.intellij.ide.util.projectWizard.WizardContext;
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.openapi.module.Module;
21 import com.intellij.openapi.project.Project;
22 import com.intellij.openapi.roots.*;
23 import com.intellij.openapi.roots.impl.OrderEntryUtil;
24 import com.intellij.openapi.roots.impl.libraries.LibraryEx;
25 import com.intellij.openapi.roots.impl.libraries.LibraryTableBase;
26 import com.intellij.openapi.roots.libraries.Library;
27 import com.intellij.openapi.roots.libraries.LibraryTable;
28 import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
29 import com.intellij.openapi.roots.libraries.LibraryType;
30 import com.intellij.openapi.roots.libraries.ui.OrderRoot;
31 import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider;
32 import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator;
33 import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
34 import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor;
35 import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor;
36 import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor;
37 import com.intellij.openapi.util.Condition;
38 import com.intellij.openapi.util.text.StringUtil;
39 import com.intellij.openapi.vfs.VirtualFile;
40 import com.intellij.util.ArrayUtil;
41 import com.intellij.util.Function;
42 import com.intellij.util.text.UniqueNameGenerator;
43 import org.jetbrains.annotations.NonNls;
44 import org.jetbrains.annotations.NotNull;
45 import org.jetbrains.annotations.Nullable;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collection;
50 import java.util.List;
55 public class LibrariesContainerFactory {
56 private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory");
57 private static final Library[] EMPTY_LIBRARIES_ARRAY = new Library[0];
59 private LibrariesContainerFactory() {
63 public static LibrariesContainer createContainer(@Nullable Project project) {
64 return new LibrariesContainerImpl(project, null, null);
68 public static LibrariesContainer createContainer(@NotNull Module module) {
69 return new LibrariesContainerImpl(module.getProject(), module, null);
73 public static LibrariesContainer createContainer(@NotNull ModifiableRootModel rootModel) {
74 Module module = rootModel.getModule();
75 return new LibrariesContainerImpl(module.getProject(), module, rootModel);
78 public static LibrariesContainer createContainer(StructureConfigurableContext context) {
79 return new StructureConfigurableLibrariesContainer(context);
82 public static Library createLibrary(@Nullable LibrariesContainer container1, @NotNull LibrariesContainer container2,
83 @NotNull @NonNls final NewLibraryEditor editor, @NotNull final LibrariesContainer.LibraryLevel level) {
84 if (container1 != null && container1.canCreateLibrary(level)) {
85 return container1.createLibrary(editor, level);
88 return container2.createLibrary(editor, level);
93 private static Library createLibraryInTable(final @NotNull NewLibraryEditor editor, final LibraryTable table) {
94 LibraryTableBase.ModifiableModelEx modifiableModel = (LibraryTableBase.ModifiableModelEx) table.getModifiableModel();
95 final String name = StringUtil.isEmpty(editor.getName()) ? null : getUniqueLibraryName(editor.getName(), modifiableModel);
96 final LibraryType<?> type = editor.getType();
97 Library library = modifiableModel.createLibrary(name, type == null ? null : type.getKind());
98 final LibraryEx.ModifiableModelEx model = (LibraryEx.ModifiableModelEx)library.getModifiableModel();
99 editor.applyTo(model);
101 modifiableModel.commit();
105 private static String getUniqueLibraryName(final String baseName, final LibraryTable.ModifiableModel model) {
106 return UniqueNameGenerator.generateUniqueName(baseName, "", "", " (", ")", new Condition<String>() {
108 public boolean value(String s) {
109 return model.getLibraryByName(s) == null;
115 public static LibrariesContainer createContainer(@NotNull WizardContext context, @NotNull ModulesProvider modulesProvider) {
116 final LibrariesContainer container;
117 if (modulesProvider instanceof ModulesConfigurator) {
118 ModulesConfigurator configurator = (ModulesConfigurator)modulesProvider;
119 container = createContainer(configurator.getContext());
122 container = createContainer(context.getProject());
128 private abstract static class LibrariesContainerBase implements LibrariesContainer {
129 private UniqueNameGenerator myNameGenerator;
132 public Library createLibrary(@NotNull @NonNls String name,
133 @NotNull LibraryLevel level,
134 @NotNull VirtualFile[] classRoots,
135 @NotNull VirtualFile[] sourceRoots) {
136 NewLibraryEditor editor = new NewLibraryEditor();
137 editor.setName(name);
138 for (VirtualFile classRoot : classRoots) {
139 editor.addRoot(classRoot, OrderRootType.CLASSES);
141 for (VirtualFile sourceRoot : sourceRoots) {
142 editor.addRoot(sourceRoot, OrderRootType.SOURCES);
144 return createLibrary(editor, level);
148 public Library createLibrary(@NotNull @NonNls String name,
149 @NotNull LibraryLevel level,
150 @NotNull Collection<? extends OrderRoot> roots) {
151 final NewLibraryEditor editor = new NewLibraryEditor();
152 editor.setName(name);
153 editor.addRoots(roots);
154 return createLibrary(editor, level);
159 public Library[] getAllLibraries() {
160 Library[] libraries = getLibraries(LibraryLevel.GLOBAL);
161 Library[] projectLibraries = getLibraries(LibraryLevel.PROJECT);
162 if (projectLibraries.length > 0) {
163 libraries = ArrayUtil.mergeArrays(libraries, projectLibraries);
165 Library[] moduleLibraries = getLibraries(LibraryLevel.MODULE);
166 if (moduleLibraries.length > 0) {
167 libraries = ArrayUtil.mergeArrays(libraries, moduleLibraries);
174 public List<LibraryLevel> getAvailableLevels() {
175 final List<LibraryLevel> levels = new ArrayList<LibraryLevel>();
176 for (LibraryLevel level : LibraryLevel.values()) {
177 if (canCreateLibrary(level)) {
186 public String suggestUniqueLibraryName(@NotNull String baseName) {
187 if (myNameGenerator == null) {
188 myNameGenerator = new UniqueNameGenerator(Arrays.asList(getAllLibraries()), new Function<Library, String>() {
190 public String fun(Library o) {
195 return myNameGenerator.generateUniqueName(baseName, "", "", " (", ")");
200 private static class LibrariesContainerImpl extends LibrariesContainerBase {
201 private @Nullable final Project myProject;
202 @Nullable private final Module myModule;
203 @Nullable private final ModifiableRootModel myRootModel;
205 private LibrariesContainerImpl(final @Nullable Project project, final @Nullable Module module, final @Nullable ModifiableRootModel rootModel) {
208 myRootModel = rootModel;
213 public Project getProject() {
219 public Library[] getLibraries(@NotNull final LibraryLevel libraryLevel) {
220 if (libraryLevel == LibraryLevel.MODULE && myModule != null) {
221 return getModuleLibraries();
224 LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance();
225 if (libraryLevel == LibraryLevel.GLOBAL) {
226 return registrar.getLibraryTable().getLibraries();
229 if (libraryLevel == LibraryLevel.PROJECT && myProject != null) {
230 return registrar.getLibraryTable(myProject).getLibraries();
233 return EMPTY_LIBRARIES_ARRAY;
236 private Library[] getModuleLibraries() {
237 if (myRootModel != null) {
238 return myRootModel.getModuleLibraryTable().getLibraries();
240 List<Library> libraries = OrderEntryUtil.getModuleLibraries(ModuleRootManager.getInstance(myModule));
241 return libraries.toArray(new Library[libraries.size()]);
246 public VirtualFile[] getLibraryFiles(@NotNull final Library library, @NotNull final OrderRootType rootType) {
247 return library.getFiles(rootType);
251 public boolean canCreateLibrary(@NotNull final LibraryLevel level) {
252 if (level == LibraryLevel.MODULE) {
253 return myRootModel != null;
255 return level == LibraryLevel.GLOBAL || myProject != null;
259 public Library createLibrary(@NotNull NewLibraryEditor libraryEditor,
260 @NotNull LibraryLevel level) {
261 if (level == LibraryLevel.MODULE && myRootModel != null) {
262 return createLibraryInTable(libraryEditor, myRootModel.getModuleLibraryTable());
265 LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance();
267 if (level == LibraryLevel.GLOBAL) {
268 table = registrar.getLibraryTable();
270 else if (level == LibraryLevel.PROJECT && myProject != null) {
271 table = registrar.getLibraryTable(myProject);
276 return createLibraryInTable(libraryEditor, table);
280 public ExistingLibraryEditor getLibraryEditor(@NotNull Library library) {
285 private static class StructureConfigurableLibrariesContainer extends LibrariesContainerBase {
286 private final StructureConfigurableContext myContext;
288 public StructureConfigurableLibrariesContainer(final StructureConfigurableContext context) {
293 public Library createLibrary(@NotNull NewLibraryEditor libraryEditor,
294 @NotNull LibraryLevel level) {
295 LibraryTableModifiableModelProvider provider = getProvider(level);
296 if (provider == null) {
297 LOG.error("cannot create module library in this context");
300 LibraryTableBase.ModifiableModelEx model = (LibraryTableBase.ModifiableModelEx)provider.getModifiableModel();
301 final LibraryType<?> type = libraryEditor.getType();
302 Library library = model.createLibrary(getUniqueLibraryName(libraryEditor.getName(), model), type == null ? null : type.getKind());
303 ExistingLibraryEditor createdLibraryEditor = ((LibrariesModifiableModel)model).getLibraryEditor(library);
304 createdLibraryEditor.setProperties(libraryEditor.getProperties());
305 libraryEditor.applyTo(createdLibraryEditor);
310 public ExistingLibraryEditor getLibraryEditor(@NotNull Library library) {
311 final LibraryTable table = library.getTable();
312 if (table == null) return null;
314 final LibraryTable.ModifiableModel model = myContext.getModifiableLibraryTable(table);
315 if (model instanceof LibrariesModifiableModel) {
316 return ((LibrariesModifiableModel)model).getLibraryEditor(library);
323 public Project getProject() {
324 return myContext.getProject();
329 public Library[] getLibraries(@NotNull final LibraryLevel libraryLevel) {
330 LibraryTableModifiableModelProvider provider = getProvider(libraryLevel);
331 return provider != null ? provider.getModifiableModel().getLibraries() : EMPTY_LIBRARIES_ARRAY;
335 private LibraryTableModifiableModelProvider getProvider(LibraryLevel libraryLevel) {
336 if (libraryLevel == LibraryLevel.PROJECT) {
337 return myContext.getProjectLibrariesProvider();
339 else if (libraryLevel == LibraryLevel.GLOBAL) {
340 return myContext.getGlobalLibrariesProvider();
348 public boolean canCreateLibrary(@NotNull final LibraryLevel level) {
349 return level == LibraryLevel.GLOBAL || level == LibraryLevel.PROJECT;
354 public VirtualFile[] getLibraryFiles(@NotNull final Library library, @NotNull final OrderRootType rootType) {
355 LibrariesModifiableModel projectLibrariesModel = myContext.getProjectLibrariesProvider().getModifiableModel();
356 if (projectLibrariesModel.hasLibraryEditor(library)) {
357 LibraryEditor libraryEditor = projectLibrariesModel.getLibraryEditor(library);
358 return libraryEditor.getFiles(rootType);
360 LibrariesModifiableModel globalLibraries = myContext.getGlobalLibrariesProvider().getModifiableModel();
361 if (globalLibraries.hasLibraryEditor(library)) {
362 LibraryEditor libraryEditor = globalLibraries.getLibraryEditor(library);
363 return libraryEditor.getFiles(rootType);
365 return library.getFiles(rootType);