replaced <code></code> with more concise {@code}
[idea/community.git] / platform / projectModel-api / src / com / intellij / openapi / roots / OrderEnumerator.java
1 /*
2  * Copyright 2000-2017 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.openapi.roots;
17
18 import com.intellij.openapi.module.Module;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.roots.libraries.Library;
21 import com.intellij.openapi.util.Condition;
22 import com.intellij.openapi.vfs.VirtualFile;
23 import com.intellij.util.NotNullFunction;
24 import com.intellij.util.PathsList;
25 import com.intellij.util.Processor;
26 import org.jetbrains.annotations.NotNull;
27
28 import java.util.List;
29
30 /**
31  * <p>Interface for convenient processing dependencies of a module or a project. Allows to process {@link OrderEntry}s
32  * and collect classes and source roots.</p>
33  *
34  * <p>Use {@link #orderEntries(Module)} or {@link ModuleRootModel#orderEntries()} to process dependencies of a module
35  * and use {@link #orderEntries(Project)} to process dependencies of all modules in a project.</p>
36  *
37  * <p>Note that all configuration methods modify {@link OrderEnumerator} instance instead of creating a new one.</p>
38  *
39  * @author nik
40  * @since 10.0
41  */
42 public abstract class OrderEnumerator {
43   /**
44    * Skip test dependencies
45    *
46    * @return this instance
47    */
48   public abstract OrderEnumerator productionOnly();
49
50   /**
51    * Skip runtime-only dependencies
52    *
53    * @return this instance
54    */
55   public abstract OrderEnumerator compileOnly();
56
57   /**
58    * Skip compile-only dependencies
59    *
60    * @return this instance
61    */
62   public abstract OrderEnumerator runtimeOnly();
63
64   public abstract OrderEnumerator withoutSdk();
65
66   public abstract OrderEnumerator withoutLibraries();
67
68   public abstract OrderEnumerator withoutDepModules();
69
70   /**
71    * Skip root module's entries
72    * @return this
73    */
74   public abstract OrderEnumerator withoutModuleSourceEntries();
75
76   public OrderEnumerator librariesOnly() {
77     return withoutSdk().withoutDepModules().withoutModuleSourceEntries();
78   }
79
80   public OrderEnumerator sdkOnly() {
81     return withoutDepModules().withoutLibraries().withoutModuleSourceEntries();
82   }
83
84   public VirtualFile[] getAllLibrariesAndSdkClassesRoots() {
85     return withoutModuleSourceEntries().withoutDepModules().recursively().exportedOnly().classes().usingCache().getRoots();
86   }
87
88   public VirtualFile[] getAllSourceRoots() {
89     return recursively().exportedOnly().sources().usingCache().getRoots();
90   }
91
92   /**
93    * Recursively process modules on which the module depends. This flag is ignored for modules imported from Maven because for such modules
94    * transitive dependencies are propagated to the root module during importing.
95    *
96    * @return this instance
97    */
98   public abstract OrderEnumerator recursively();
99
100   /**
101    * Skip not exported dependencies. If this method is called after {@link #recursively()} direct non-exported dependencies won't be skipped
102    *
103    * @return this instance
104    */
105   public abstract OrderEnumerator exportedOnly();
106
107   /**
108    * Process only entries which satisfies the specified condition
109    *
110    * @param condition filtering condition
111    * @return this instance
112    */
113   public abstract OrderEnumerator satisfying(Condition<OrderEntry> condition);
114
115   /**
116    * Use {@code provider.getRootModel()} to process module dependencies
117    *
118    * @param provider provider
119    * @return this instance
120    */
121   public abstract OrderEnumerator using(@NotNull RootModelProvider provider);
122
123   /**
124    * Determine if, given the current enumerator settings and handlers for a module, should the
125    * enumerator recurse to further modules based on the given ModuleOrderEntry?
126    *
127    * @param entry the ModuleOrderEntry in question (m1 -> m2)
128    * @param handlers custom handlers registered to the module
129    * @return true if the enumerator would have recursively processed the given ModuleOrderEntry.
130    */
131   public abstract boolean shouldRecurse(@NotNull ModuleOrderEntry entry, @NotNull List<OrderEnumerationHandler> handlers);
132
133   /**
134    * @return {@link OrderRootsEnumerator} instance for processing classes roots
135    */
136   public abstract OrderRootsEnumerator classes();
137
138   /**
139    * @return {@link OrderRootsEnumerator} instance for processing source roots
140    */
141   public abstract OrderRootsEnumerator sources();
142
143   /**
144    * @param rootType root type
145    * @return {@link OrderRootsEnumerator} instance for processing roots of the specified type
146    */
147   public abstract OrderRootsEnumerator roots(@NotNull OrderRootType rootType);
148
149   /**
150    * @param rootTypeProvider custom root type provider
151    * @return {@link OrderRootsEnumerator} instance for processing roots of the provided type
152    */
153   public abstract OrderRootsEnumerator roots(@NotNull NotNullFunction<OrderEntry, OrderRootType> rootTypeProvider);
154
155   /**
156    * @return classes roots for all entries processed by this enumerator
157    */
158   public VirtualFile[] getClassesRoots() {
159     return classes().getRoots();
160   }
161
162   /**
163    * @return source roots for all entries processed by this enumerator
164    */
165   public VirtualFile[] getSourceRoots() {
166     return sources().getRoots();
167   }
168
169   /**
170    * @return list containing classes roots for all entries processed by this enumerator
171    */
172   public PathsList getPathsList() {
173     return classes().getPathsList();
174   }
175
176   /**
177    * @return list containing source roots for all entries processed by this enumerator
178    */
179   public PathsList getSourcePathsList() {
180     return sources().getPathsList();
181   }
182
183   /**
184    * Runs {@code processor.process()} for each entry processed by this enumerator.
185    *
186    * @param processor processor
187    */
188   public abstract void forEach(@NotNull Processor<OrderEntry> processor);
189
190   /**
191    * Runs {@code processor.process()} for each library processed by this enumerator.
192    *
193    * @param processor processor
194    */
195   public abstract void forEachLibrary(@NotNull Processor<Library> processor);
196
197   /**
198    * Runs {@code processor.process()} for each module processed by this enumerator.
199    *
200    * @param processor processor
201    */
202   public abstract void forEachModule(@NotNull Processor<Module> processor);
203
204   /**
205    * Passes order entries to the specified visitor.
206    *
207    * @param policy       the visitor to accept.
208    * @param initialValue the default value to be returned by the visit process.
209    * @return the value returned by the visitor.
210    * @see OrderEntry#accept(RootPolicy, Object)
211    */
212   public abstract <R> R process(@NotNull RootPolicy<R> policy, R initialValue);
213
214   /**
215    * Creates new enumerator instance to process dependencies of {@code module}
216    *
217    * @param module module
218    * @return new enumerator instance
219    */
220   @NotNull
221   public static OrderEnumerator orderEntries(@NotNull Module module) {
222     return ModuleRootManager.getInstance(module).orderEntries();
223   }
224
225   /**
226    * Creates new enumerator instance to process dependencies of all modules in {@code project}. Only first level dependencies of
227    * modules are processed so {@link #recursively()} option is ignored and {@link #withoutDepModules()} option is forced
228    *
229    * @param project project
230    * @return new enumerator instance
231    */
232   @NotNull
233   public static OrderEnumerator orderEntries(@NotNull Project project) {
234     return ProjectRootManager.getInstance(project).orderEntries();
235   }
236 }