| /* |
| * Copyright 2000-2013 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.externalSystem.service.project.manage; |
| |
| import com.intellij.openapi.externalSystem.model.project.AbstractDependencyData; |
| import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange; |
| import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil; |
| import com.intellij.openapi.externalSystem.util.ExternalSystemConstants; |
| import com.intellij.openapi.externalSystem.util.Order; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.roots.*; |
| import com.intellij.util.Consumer; |
| import com.intellij.util.containers.ContainerUtilRt; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.Collection; |
| import java.util.Map; |
| |
| /** |
| * @author Denis Zhdanov |
| * @since 4/14/13 11:21 PM |
| */ |
| @Order(ExternalSystemConstants.BUILTIN_SERVICE_ORDER) |
| public abstract class AbstractDependencyDataService<E extends AbstractDependencyData<?>, I extends ExportableOrderEntry> |
| implements ProjectDataService<E, I> |
| { |
| |
| public void setScope(@NotNull final DependencyScope scope, @NotNull final ExportableOrderEntry dependency, boolean synchronous) { |
| ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(dependency.getOwnerModule()) { |
| @Override |
| public void execute() { |
| doForDependency(dependency, new Consumer<ExportableOrderEntry>() { |
| @Override |
| public void consume(ExportableOrderEntry entry) { |
| entry.setScope(scope); |
| } |
| }); |
| } |
| }); |
| } |
| |
| public void setExported(final boolean exported, @NotNull final ExportableOrderEntry dependency, boolean synchronous) { |
| ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(dependency.getOwnerModule()) { |
| @Override |
| public void execute() { |
| doForDependency(dependency, new Consumer<ExportableOrderEntry>() { |
| @Override |
| public void consume(ExportableOrderEntry entry) { |
| entry.setExported(exported); |
| } |
| }); |
| } |
| }); |
| } |
| |
| private static void doForDependency(@NotNull ExportableOrderEntry entry, @NotNull Consumer<ExportableOrderEntry> consumer) { |
| // We need to get an up-to-date modifiable model to work with. |
| ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(entry.getOwnerModule()); |
| final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); |
| try { |
| // The thing is that intellij created order entry objects every time new modifiable model is created, |
| // that's why we can't use target dependency object as is but need to get a reference to the current |
| // entry object from the model instead. |
| for (OrderEntry e : moduleRootModel.getOrderEntries()) { |
| if (e instanceof ExportableOrderEntry && e.getPresentableName().equals(entry.getPresentableName())) { |
| consumer.consume((ExportableOrderEntry)e); |
| break; |
| } |
| } |
| } |
| finally { |
| moduleRootModel.commit(); |
| } |
| } |
| |
| @Override |
| public void removeData(@NotNull Collection<? extends I> toRemove, @NotNull Project project, boolean synchronous) { |
| if (toRemove.isEmpty()) { |
| return; |
| } |
| |
| Map<Module, Collection<ExportableOrderEntry>> byModule = groupByModule(toRemove); |
| for (Map.Entry<Module, Collection<ExportableOrderEntry>> entry : byModule.entrySet()) { |
| removeData(entry.getValue(), entry.getKey(), synchronous); |
| } |
| } |
| |
| @NotNull |
| private static Map<Module, Collection<ExportableOrderEntry>> groupByModule(@NotNull Collection<? extends ExportableOrderEntry> data) { |
| Map<Module, Collection<ExportableOrderEntry>> result = ContainerUtilRt.newHashMap(); |
| for (ExportableOrderEntry entry : data) { |
| Collection<ExportableOrderEntry> entries = result.get(entry.getOwnerModule()); |
| if (entries == null) { |
| result.put(entry.getOwnerModule(), entries = ContainerUtilRt.newArrayList()); |
| } |
| entries.add(entry); |
| } |
| return result; |
| } |
| |
| public void removeData(@NotNull Collection<? extends ExportableOrderEntry> toRemove, @NotNull final Module module, boolean synchronous) { |
| if (toRemove.isEmpty()) { |
| return; |
| } |
| for (final ExportableOrderEntry dependency : toRemove) { |
| ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new DisposeAwareProjectChange(dependency.getOwnerModule()) { |
| @Override |
| public void execute() { |
| ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); |
| final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel(); |
| try { |
| // The thing is that intellij created order entry objects every time new modifiable model is created, |
| // that's why we can't use target dependency object as is but need to get a reference to the current |
| // entry object from the model instead. |
| for (OrderEntry entry : moduleRootModel.getOrderEntries()) { |
| if (entry instanceof ExportableOrderEntry) { |
| ExportableOrderEntry orderEntry = (ExportableOrderEntry)entry; |
| if (orderEntry.getPresentableName().equals(dependency.getPresentableName()) && |
| orderEntry.getScope().equals(dependency.getScope())) { |
| moduleRootModel.removeOrderEntry(entry); |
| break; |
| } |
| } |
| else if (entry.getPresentableName().equals(dependency.getPresentableName())) { |
| moduleRootModel.removeOrderEntry(entry); |
| break; |
| } |
| } |
| } |
| finally { |
| moduleRootModel.commit(); |
| } |
| } |
| }); |
| } |
| } |
| } |