2 * Copyright 2000-2007 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
;
18 import com
.intellij
.openapi
.module
.Module
;
19 import com
.intellij
.openapi
.module
.ModuleManager
;
20 import com
.intellij
.openapi
.project
.Project
;
21 import com
.intellij
.openapi
.util
.Key
;
22 import com
.intellij
.openapi
.util
.UserDataHolder
;
23 import com
.intellij
.openapi
.util
.UserDataHolderBase
;
24 import com
.intellij
.openapi
.vfs
.VirtualFile
;
25 import com
.intellij
.util
.PathUtil
;
26 import com
.intellij
.util
.PathsList
;
28 import java
.util
.HashSet
;
29 import java
.util
.List
;
31 public class ProjectRootsTraversing
{
33 public static final RootTraversePolicy LIBRARIES_AND_JDK
=
34 new RootTraversePolicy(null, RootTraversePolicy
.ADD_CLASSES
, RootTraversePolicy
.ADD_CLASSES
, null);
36 public static final RootTraversePolicy PROJECT_SOURCES
=
37 new RootTraversePolicy(RootTraversePolicy
.SOURCES
, null, null, null);
39 public static final RootTraversePolicy PROJECT_LIBRARIES
=
40 new RootTraversePolicy(null, null, RootTraversePolicy
.ADD_CLASSES
, RootTraversePolicy
.RECURSIVE
);
42 private ProjectRootsTraversing() {
45 public static PathsList
collectRoots(Project project
, RootTraversePolicy policy
) {
46 PathsList listBuilder
= new PathsList();
47 collectRoots(project
, policy
, listBuilder
);
51 public static void collectRoots(final Project project
, final RootTraversePolicy policy
, final PathsList listBuilder
) {
52 traverseOrder(project
, policy
, new TraverseState(listBuilder
));
55 public static PathsList
collectRoots(Module module
, RootTraversePolicy policy
) {
56 final PathsList listBuilder
= new PathsList();
57 collectRoots(module
, policy
, listBuilder
);
61 public static void collectRoots(Module module
, RootTraversePolicy policy
, PathsList listBuilder
) {
62 traverseOrder(module
, policy
, new TraverseState(listBuilder
));
65 private static void traverseOrder(Project project
, RootPolicy
<TraverseState
> policy
, TraverseState state
) {
66 final Module
[] sortedModules
= ModuleManager
.getInstance(project
).getSortedModules();
67 for (Module sortedModule
: sortedModules
) {
68 traverseOrder(sortedModule
, policy
, state
);
72 private static void traverseOrder(Module module
, RootPolicy
<TraverseState
> policy
, TraverseState state
) {
73 if (!state
.beforeVisitModule(module
)) {
76 state
.getCurrentModuleManager().processOrder(policy
, state
);
79 public static class TraverseState
implements UserDataHolder
{
80 private final UserDataHolderBase myUserData
= new UserDataHolderBase();
81 private final PathsList myCollectedPath
;
82 private final HashSet
<Module
> myKnownModules
= new HashSet
<Module
>();
83 private ModuleRootManager myCurrentModuleManager
;
85 private TraverseState(PathsList listBuilder
) {
86 myCollectedPath
= listBuilder
;
89 public PathsList
getCollectedPath() {
90 return myCollectedPath
;
93 public boolean beforeVisitModule(Module module
) {
94 if (myKnownModules
.contains(module
)) {
97 myKnownModules
.add(module
);
98 myCurrentModuleManager
= ModuleRootManager
.getInstance(module
);
102 public void addAll(VirtualFile
[] items
) {
103 for (VirtualFile item
: items
) {
108 private void add(VirtualFile item
) {
109 if (item
!= null && item
.isValid()) {
110 myCollectedPath
.add(item
);
114 private void addUrl(String url
) {
116 myCollectedPath
.add(PathUtil
.toPresentableUrl(url
));
120 public ModuleRootManager
getCurrentModuleManager() {
121 return myCurrentModuleManager
;
124 public void restorCurrentModuleManager(ModuleRootManager restored
) {
125 myCurrentModuleManager
= restored
;
128 public <T
> T
getUserData(Key
<T
> key
) {
129 return myUserData
.getUserData(key
);
132 public <T
> void putUserData(Key
<T
> key
, T value
) {
133 myUserData
.putUserData(key
, value
);
136 public void addAllUrls(String
[] urls
) {
137 for (String url
: urls
) addUrl(url
);
140 public void addAllUrls(List
<String
> urls
) {
141 for (String url
: urls
) {
147 public static class RootTraversePolicy
extends RootPolicy
<TraverseState
> {
148 private static final Key
<Boolean
> JDK_PROCESSED
= Key
.create("jdkProcessed");
149 private final Visit
<ModuleSourceOrderEntry
> myVisitSource
;
150 private final Visit
<OrderEntry
> myVisitJdk
;
151 private final Visit
<OrderEntry
> myVisitLibrary
;
152 private final Visit
<ModuleOrderEntry
> myVisitModule
;
154 public RootTraversePolicy(Visit
<ModuleSourceOrderEntry
> visitSource
, Visit
<OrderEntry
> visitJdk
, Visit
<OrderEntry
> visitLibrary
, Visit
<ModuleOrderEntry
> visitModule
) {
155 myVisitSource
= visitSource
;
156 myVisitJdk
= visitJdk
;
157 myVisitLibrary
= visitLibrary
;
158 myVisitModule
= visitModule
;
161 public TraverseState
visitJdkOrderEntry(JdkOrderEntry jdkOrderEntry
, TraverseState state
) {
162 Boolean jdkProcessed
= state
.getUserData(JDK_PROCESSED
);
163 if (jdkProcessed
!= null && jdkProcessed
.booleanValue()) return state
;
164 state
.putUserData(JDK_PROCESSED
, Boolean
.TRUE
);
165 if (myVisitJdk
!= null) myVisitJdk
.visit(jdkOrderEntry
, state
, this);
169 public TraverseState
visitLibraryOrderEntry(LibraryOrderEntry libraryOrderEntry
, TraverseState traverseState
) {
170 if (myVisitLibrary
!= null) myVisitLibrary
.visit(libraryOrderEntry
, traverseState
, this);
171 return traverseState
;
174 public TraverseState
visitModuleSourceOrderEntry(ModuleSourceOrderEntry sourceEntry
,
175 TraverseState traverseState
) {
176 if (myVisitSource
!= null) myVisitSource
.visit(sourceEntry
, traverseState
, this);
177 return traverseState
;
180 public TraverseState
visitModuleOrderEntry(ModuleOrderEntry moduleOrderEntry
, TraverseState traverseState
) {
181 if (myVisitModule
!= null) myVisitModule
.visit(moduleOrderEntry
, traverseState
, this);
182 return traverseState
;
185 public interface Visit
<T
extends OrderEntry
> {
186 void visit(T entry
, TraverseState state
, RootPolicy
<TraverseState
> policy
);
189 public static final AddModuleSource SOURCES
= new AddModuleSource();
190 public static final AddModuleSource PRODUCTION_SOURCES
= new AddModuleSource(true);
192 public static final Visit
<OrderEntry
> ADD_CLASSES
= new Visit
<OrderEntry
>() {
193 public void visit(OrderEntry orderEntry
, TraverseState state
, RootPolicy
<TraverseState
> policy
) {
194 state
.addAllUrls(orderEntry
.getUrls(OrderRootType
.CLASSES
));
198 public static final Visit
<ModuleOrderEntry
> RECURSIVE
= new Visit
<ModuleOrderEntry
>() {
199 public void visit(ModuleOrderEntry moduleOrderEntry
, TraverseState state
, RootPolicy
<TraverseState
> policy
) {
200 Module module
= moduleOrderEntry
.getModule();
201 if (module
== null) return;
202 ModuleRootManager moduleRootManager
= state
.getCurrentModuleManager();
203 traverseOrder(module
, policy
, state
);
204 state
.restorCurrentModuleManager(moduleRootManager
);
208 public static class AddModuleSource
implements Visit
<ModuleSourceOrderEntry
> {
209 private boolean myExcludeTests
;
211 public AddModuleSource() {
215 public AddModuleSource(final boolean excludeTests
) {
216 myExcludeTests
= excludeTests
;
219 public void visit(ModuleSourceOrderEntry orderEntry
, TraverseState state
, RootPolicy
<TraverseState
> policy
) {
220 if (myExcludeTests
) {
221 ContentEntry
[] contentEntries
= ModuleRootManager
.getInstance(orderEntry
.getOwnerModule()).getContentEntries();
222 for (ContentEntry contentEntry
: contentEntries
) {
223 for (SourceFolder folder
: contentEntry
.getSourceFolders()) {
224 VirtualFile root
= folder
.getFile();
225 if (root
!= null && !folder
.isTestSource()) {
232 state
.addAll(orderEntry
.getFiles(OrderRootType
.SOURCES
));