| /* |
| * Copyright 2000-2011 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.framework.detection.impl; |
| |
| import com.intellij.facet.*; |
| import com.intellij.framework.detection.DetectedFrameworkDescription; |
| import com.intellij.framework.detection.FacetBasedFrameworkDetector; |
| import com.intellij.framework.detection.FrameworkDetector; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.roots.ModifiableModelsProvider; |
| import com.intellij.openapi.roots.ModifiableRootModel; |
| import com.intellij.openapi.util.Condition; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.util.text.UniqueNameGenerator; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.util.Collection; |
| import java.util.Set; |
| |
| /** |
| * @author nik |
| */ |
| public abstract class FacetBasedDetectedFrameworkDescription<F extends Facet, C extends FacetConfiguration> extends DetectedFrameworkDescription { |
| private static final Logger LOG = Logger.getInstance("#com.intellij.framework.detection.impl.FacetBasedDetectedFrameworkDescription"); |
| private final FacetBasedFrameworkDetector<F, C> myDetector; |
| private final C myConfiguration; |
| private final Set<VirtualFile> myRelatedFiles; |
| private final FacetType<F,C> myFacetType; |
| |
| public FacetBasedDetectedFrameworkDescription(FacetBasedFrameworkDetector<F, C> detector, |
| @NotNull C configuration, |
| Set<VirtualFile> files) { |
| myDetector = detector; |
| myConfiguration = configuration; |
| myRelatedFiles = files; |
| myFacetType = detector.getFacetType(); |
| } |
| |
| @NotNull |
| @Override |
| public Collection<? extends VirtualFile> getRelatedFiles() { |
| return myRelatedFiles; |
| } |
| |
| public C getConfiguration() { |
| return myConfiguration; |
| } |
| |
| @NotNull |
| @Override |
| public String getSetupText() { |
| return "'" + myFacetType.getPresentableName() + "' facet will be added to '" + getModuleName() + "' module"; |
| } |
| |
| @NotNull |
| @Override |
| public FrameworkDetector getDetector() { |
| return myDetector; |
| } |
| |
| protected abstract String getModuleName(); |
| |
| @Override |
| public boolean canSetupFramework(@NotNull Collection<? extends DetectedFrameworkDescription> allDetectedFrameworks) { |
| final FacetTypeId<?> underlyingId = myFacetType.getUnderlyingFacetType(); |
| if (underlyingId == null) { |
| return true; |
| } |
| |
| final Collection<? extends Facet> facets = getExistentFacets(underlyingId); |
| for (Facet facet : facets) { |
| if (myDetector.isSuitableUnderlyingFacetConfiguration(facet.getConfiguration(), myConfiguration, myRelatedFiles)) { |
| return true; |
| } |
| } |
| for (DetectedFrameworkDescription framework : allDetectedFrameworks) { |
| if (framework instanceof FacetBasedDetectedFrameworkDescription<?, ?>) { |
| final FacetBasedDetectedFrameworkDescription<?, ?> description = (FacetBasedDetectedFrameworkDescription<?, ?>)framework; |
| if (underlyingId.equals(description.myFacetType.getId()) && |
| myDetector.isSuitableUnderlyingFacetConfiguration(description.getConfiguration(), myConfiguration, myRelatedFiles)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| @NotNull |
| protected abstract Collection<? extends Facet> getExistentFacets(FacetTypeId<?> underlyingFacetType); |
| |
| protected void doSetup(ModifiableModelsProvider modifiableModelsProvider, final Module module) { |
| final ModifiableFacetModel model = modifiableModelsProvider.getFacetModifiableModel(module); |
| final String name = UniqueNameGenerator.generateUniqueName(myFacetType.getDefaultFacetName(), new Condition<String>() { |
| @Override |
| public boolean value(String s) { |
| return FacetManager.getInstance(module).findFacet(myFacetType.getId(), s) == null; |
| } |
| }); |
| final F facet = FacetManager.getInstance(module).createFacet(myFacetType, name, myConfiguration, |
| findUnderlyingFacet(module)); |
| model.addFacet(facet); |
| modifiableModelsProvider.commitFacetModifiableModel(module, model); |
| final ModifiableRootModel rootModel = modifiableModelsProvider.getModuleModifiableModel(module); |
| myDetector.setupFacet(facet, rootModel); |
| modifiableModelsProvider.commitModuleModifiableModel(rootModel); |
| } |
| |
| @Nullable |
| private Facet findUnderlyingFacet(Module module) { |
| final FacetTypeId<?> underlyingTypeId = myFacetType.getUnderlyingFacetType(); |
| if (underlyingTypeId == null) return null; |
| |
| final Collection<? extends Facet> parentFacets = FacetManager.getInstance(module).getFacetsByType(underlyingTypeId); |
| for (Facet facet : parentFacets) { |
| if (myDetector.isSuitableUnderlyingFacetConfiguration(facet.getConfiguration(), myConfiguration, myRelatedFiles)) { |
| return facet; |
| } |
| } |
| LOG.error("Cannot find suitable underlying facet in " + parentFacets); |
| return null; |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (!(obj instanceof FacetBasedDetectedFrameworkDescription)) { |
| return false; |
| } |
| final FacetBasedDetectedFrameworkDescription other = (FacetBasedDetectedFrameworkDescription)obj; |
| return getModuleName().equals(other.getModuleName()) && myFacetType.equals(other.myFacetType) && myRelatedFiles.equals(other.myRelatedFiles); |
| } |
| |
| @Override |
| public int hashCode() { |
| return getModuleName().hashCode() + 31*myFacetType.hashCode() + 239*myRelatedFiles.hashCode(); |
| } |
| } |