2 * Copyright 2000-2009 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.
17 package com
.intellij
.openapi
.roots
.impl
;
19 import com
.intellij
.ProjectTopics
;
20 import com
.intellij
.openapi
.module
.Module
;
21 import com
.intellij
.openapi
.module
.ModuleManager
;
22 import com
.intellij
.openapi
.module
.impl
.ModuleManagerImpl
;
23 import com
.intellij
.openapi
.project
.ModuleListener
;
24 import com
.intellij
.openapi
.project
.Project
;
25 import com
.intellij
.openapi
.roots
.*;
26 import com
.intellij
.openapi
.util
.Comparing
;
27 import com
.intellij
.openapi
.util
.InvalidDataException
;
28 import com
.intellij
.openapi
.util
.WriteExternalException
;
29 import com
.intellij
.openapi
.vfs
.VirtualFile
;
30 import com
.intellij
.openapi
.vfs
.pointers
.VirtualFilePointerManager
;
31 import com
.intellij
.util
.ArrayUtil
;
32 import com
.intellij
.util
.containers
.HashSet
;
33 import com
.intellij
.util
.messages
.MessageBusConnection
;
34 import org
.jdom
.Element
;
35 import org
.jetbrains
.annotations
.NonNls
;
36 import org
.jetbrains
.annotations
.NotNull
;
37 import org
.jetbrains
.annotations
.Nullable
;
39 import java
.util
.List
;
45 public class ModuleOrderEntryImpl
extends OrderEntryBaseImpl
implements ModuleOrderEntry
, WritableOrderEntry
, ClonableOrderEntry
{
46 @NonNls public static final String ENTRY_TYPE
= "module";
47 @NonNls public static final String MODULE_NAME_ATTR
= "module-name";
48 @NonNls private static final String EXPORTED_ATTR
= "exported";
49 @NonNls private static final String SCOPE_ATTR
= "scope";
51 private Module myModule
;
52 private String myModuleName
; // non-null if myProject is null
53 private boolean myExported
= false;
54 @NotNull private DependencyScope myScope
;
55 private MessageBusConnection myConnection
;
57 ModuleOrderEntryImpl(Module module
, RootModelImpl rootModel
) {
60 myScope
= DependencyScope
.COMPILE
;
63 ModuleOrderEntryImpl(String moduleName
, RootModelImpl rootModel
) {
65 myModuleName
= moduleName
;
67 myScope
= DependencyScope
.COMPILE
;
70 ModuleOrderEntryImpl(Element element
, RootModelImpl rootModel
, ModuleManager moduleManager
) throws InvalidDataException
{
72 myExported
= element
.getAttributeValue(EXPORTED_ATTR
) != null;
73 final String moduleName
= element
.getAttributeValue(MODULE_NAME_ATTR
);
74 if (moduleName
== null) {
75 throw new InvalidDataException();
78 myModule
= moduleManager
.findModuleByName(moduleName
);
79 if (myModule
== null) {
80 myModuleName
= moduleName
;
85 myScope
= DependencyScope
.readExternal(element
);
88 private ModuleOrderEntryImpl(ModuleOrderEntryImpl that
, RootModelImpl rootModel
) {
90 final Module thatModule
= that
.myModule
;
91 if (thatModule
!= null) {
92 if (!thatModule
.isDisposed()) {
93 myModule
= thatModule
;
96 myModuleName
= thatModule
.getUserData(ModuleManagerImpl
.DISPOSED_MODULE_NAME
);
100 myModuleName
= that
.myModuleName
;
102 myExported
= that
.myExported
;
103 myScope
= that
.myScope
;
107 private boolean myListenersAdded
= false;
109 private void addListeners() {
110 myListenersAdded
= true;
111 myConnection
= getRootModel().getProject().getMessageBus().connect();
112 myConnection
.subscribe(ProjectTopics
.MODULES
, new MyModuleListener());
116 public Module
getOwnerModule() {
117 return getRootModel().getModule();
121 public VirtualFile
[] getFiles(OrderRootType type
) {
122 return getFiles(type
, new HashSet
<Module
>());
126 VirtualFile
[] getFiles(OrderRootType type
, Set
<Module
> processed
) {
127 if (myModule
!= null && !processed
.contains(myModule
) && !myModule
.isDisposed()) {
128 processed
.add(myModule
);
129 if (myScope
== DependencyScope
.RUNTIME
&& type
== OrderRootType
.PRODUCTION_COMPILATION_CLASSES
) {
130 return VirtualFile
.EMPTY_ARRAY
;
132 if (myScope
== DependencyScope
.TEST
&& type
== OrderRootType
.PRODUCTION_COMPILATION_CLASSES
) {
133 return VirtualFile
.EMPTY_ARRAY
;
135 if (myScope
== DependencyScope
.PROVIDED
&& type
== OrderRootType
.CLASSES_AND_OUTPUT
) {
136 return VirtualFile
.EMPTY_ARRAY
;
138 return ((ModuleRootManagerImpl
)ModuleRootManager
.getInstance(myModule
)).getFilesForOtherModules(type
, processed
);
141 return VirtualFile
.EMPTY_ARRAY
;
146 public String
[] getUrls(OrderRootType rootType
) {
147 return getUrls(rootType
, new HashSet
<Module
>());
150 public String
[] getUrls (OrderRootType rootType
, Set
<Module
> processed
) {
151 if (myModule
!= null && !processed
.contains(myModule
) && !myModule
.isDisposed()) {
152 processed
.add(myModule
);
153 if (myScope
== DependencyScope
.RUNTIME
&& rootType
== OrderRootType
.PRODUCTION_COMPILATION_CLASSES
) {
154 return ArrayUtil
.EMPTY_STRING_ARRAY
;
156 if (myScope
== DependencyScope
.TEST
&& rootType
== OrderRootType
.PRODUCTION_COMPILATION_CLASSES
) {
157 return ArrayUtil
.EMPTY_STRING_ARRAY
;
159 if (myScope
== DependencyScope
.PROVIDED
&& rootType
== OrderRootType
.CLASSES_AND_OUTPUT
) {
160 return ArrayUtil
.EMPTY_STRING_ARRAY
;
162 return ((ModuleRootManagerImpl
)ModuleRootManager
.getInstance(myModule
)).getUrlsForOtherModules(rootType
, processed
);
165 return ArrayUtil
.EMPTY_STRING_ARRAY
;
170 public boolean isValid() {
171 return !isDisposed() && getModule() != null;
174 public <R
> R
accept(RootPolicy
<R
> policy
, R initialValue
) {
175 return policy
.visitModuleOrderEntry(this, initialValue
);
178 public String
getPresentableName() {
179 if (myModule
!= null) {
180 return myModule
.getName();
187 public boolean isSynthetic() {
192 public Module
getModule() {
193 return getRootModel().getConfigurationAccessor().getModule(myModule
, myModuleName
);
196 public void writeExternal(Element rootElement
) throws WriteExternalException
{
197 final Element element
= OrderEntryFactory
.createOrderEntryElement(ENTRY_TYPE
);
198 element
.setAttribute(MODULE_NAME_ATTR
, getModuleName());
200 element
.setAttribute(EXPORTED_ATTR
, "");
202 myScope
.writeExternal(element
);
203 rootElement
.addContent(element
);
206 public String
getModuleName() {
207 if (myModule
!= null) {
208 return myModule
.getName();
215 public OrderEntry
cloneEntry(RootModelImpl rootModel
,
216 ProjectRootManagerImpl projectRootManager
,
217 VirtualFilePointerManager filePointerManager
) {
218 return new ModuleOrderEntryImpl(this, rootModel
);
221 public void dispose() {
223 if (myListenersAdded
) {
224 myConnection
.disconnect();
228 private void moduleAdded(Module module
) {
229 if (Comparing
.equal(myModuleName
, module
.getName())) {
234 private void setModule(Module module
) {
239 private void moduleRemoved(Module module
) {
240 if (myModule
== module
) {
245 private void unsetModule(Module module
) {
246 myModuleName
= module
.getName();
250 public boolean isExported() {
254 public void setExported(boolean value
) {
255 getRootModel().assertWritable();
260 public DependencyScope
getScope() {
264 public void setScope(@NotNull DependencyScope scope
) {
265 getRootModel().assertWritable();
269 private class MyModuleListener
implements ModuleListener
{
271 public MyModuleListener() {
274 public void moduleAdded(Project project
, Module module
) {
275 final ModuleOrderEntryImpl moduleOrderEntry
= ModuleOrderEntryImpl
.this;
276 moduleOrderEntry
.moduleAdded(module
);
279 public void beforeModuleRemoved(Project project
, Module module
) {
282 public void moduleRemoved(Project project
, Module module
) {
283 final ModuleOrderEntryImpl moduleOrderEntry
= ModuleOrderEntryImpl
.this;
284 moduleOrderEntry
.moduleRemoved(module
);
287 public void modulesRenamed(Project project
, List
<Module
> modules
) {
288 if (myModule
!= null) return;
289 for (Module module
: modules
) {
290 if (module
.getName().equals(myModuleName
)) {
298 protected void projectOpened() {
302 protected void moduleAdded() {
304 if (myModule
== null) {
305 final Module module
= ModuleManager
.getInstance(getRootModel().getModule().getProject()).findModuleByName(myModuleName
);
306 if (module
!= null) {