package com.intellij.lang.javascript.flex.projectStructure.model.impl; import com.intellij.flex.model.bc.ComponentSet; import com.intellij.flex.model.bc.LinkageType; import com.intellij.lang.javascript.flex.projectStructure.model.DependencyEntry; import com.intellij.lang.javascript.flex.projectStructure.model.ModifiableDependencies; import com.intellij.lang.javascript.flex.projectStructure.model.ModifiableDependencyEntry; import com.intellij.lang.javascript.flex.projectStructure.model.SdkEntry; import com.intellij.openapi.module.ModulePointerManager; import com.intellij.openapi.project.Project; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.Attribute; import com.intellij.util.xmlb.annotations.Property; import com.intellij.util.xmlb.annotations.Tag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; class DependenciesImpl implements ModifiableDependencies { private static final LinkageType DEFAULT_FRAMEWORK_LINKAGE = LinkageType.Default; @NotNull private String myTargetPlayer = ""; @NotNull private ComponentSet myComponentSet = ComponentSet.SparkAndMx; @NotNull private LinkageType myFrameworkLinkage = DEFAULT_FRAMEWORK_LINKAGE; private final List<ModifiableDependencyEntry> myEntries = new ArrayList<>(); @Nullable private SdkEntryImpl mySdk; @Override @Nullable public SdkEntry getSdkEntry() { return mySdk; } @Override public void setSdkEntry(@Nullable SdkEntry sdk) { mySdk = (SdkEntryImpl)sdk; } @Override public DependencyEntry[] getEntries() { return myEntries.toArray(new DependencyEntry[myEntries.size()]); } @Override public List<ModifiableDependencyEntry> getModifiableEntries() { return myEntries; } @Override @NotNull public LinkageType getFrameworkLinkage() { return myFrameworkLinkage; } @Override public void setFrameworkLinkage(@NotNull LinkageType frameworkLinkage) { myFrameworkLinkage = frameworkLinkage; } @Override @NotNull public String getTargetPlayer() { return myTargetPlayer; } @Override public void setTargetPlayer(@NotNull String targetPlayer) { myTargetPlayer = targetPlayer; } @Override public void setComponentSet(@NotNull ComponentSet componentSet) { myComponentSet = componentSet; } @Override @NotNull public ComponentSet getComponentSet() { return myComponentSet; } public DependenciesImpl getCopy() { DependenciesImpl copy = new DependenciesImpl(); applyTo(copy); return copy; } void applyTo(DependenciesImpl copy) { copy.myTargetPlayer = myTargetPlayer; copy.myComponentSet = myComponentSet; copy.myFrameworkLinkage = myFrameworkLinkage; copy.myEntries.clear(); copy.myEntries.addAll(ContainerUtil.map(myEntries, (Function<ModifiableDependencyEntry, ModifiableDependencyEntry>)e -> { if (e instanceof ModuleLibraryEntryImpl) { return ((ModuleLibraryEntryImpl)e).getCopy(); } else if (e instanceof SharedLibraryEntryImpl) { return ((SharedLibraryEntryImpl)e).getCopy(); } else if (e instanceof BuildConfigurationEntryImpl) { return ((BuildConfigurationEntryImpl)e).getCopy(); } else { throw new RuntimeException("Unexpected entry type: " + e); } })); copy.mySdk = mySdk != null ? mySdk.getCopy() : null; } public boolean isEqual(DependenciesImpl other) { if (!other.myTargetPlayer.equals(myTargetPlayer)) return false; if (other.myComponentSet != myComponentSet) return false; if (other.myFrameworkLinkage != myFrameworkLinkage) return false; if (myEntries.size() != other.myEntries.size()) return false; if (mySdk != null ? (other.mySdk == null || !mySdk.isEqual(other.mySdk)) : other.mySdk != null) return false; for (int i = 0; i < myEntries.size(); i++) { if (!myEntries.get(i).isEqual(other.myEntries.get(i))) { return false; } } return true; } public State getState() { State state = new State(); state.TARGET_PLAYER = myTargetPlayer; state.COMPONENT_SET = myComponentSet; state.FRAMEWORK_LINKAGE = myFrameworkLinkage.getSerializedText(); state.ENTRIES = ContainerUtil.mapNotNull(myEntries.toArray(new ModifiableDependencyEntry[myEntries.size()]), entry -> { if (entry instanceof StatefulDependencyEntry) { return ((StatefulDependencyEntry)entry).getState(); } else { throw new RuntimeException("Unexpected entry type: " + entry); } }, new EntryState[0]); if (mySdk != null) { state.SDK = mySdk.getState(); } return state; } public void loadState(@NotNull State state, Project project) { myTargetPlayer = state.TARGET_PLAYER; myComponentSet = state.COMPONENT_SET; myFrameworkLinkage = LinkageType.valueOf(state.FRAMEWORK_LINKAGE, DEFAULT_FRAMEWORK_LINKAGE); ModulePointerManager pointerManager = ModulePointerManager.getInstance(project); myEntries.clear(); for (EntryState info : state.ENTRIES) { if (info.LIBRARY_ID != null) { ModuleLibraryEntryImpl libraryEntry = new ModuleLibraryEntryImpl(info.LIBRARY_ID); libraryEntry.getDependencyType().loadState(info.DEPENDENCY_TYPE); myEntries.add(libraryEntry); } else if (info.LIBRARY_NAME != null) { SharedLibraryEntryImpl libraryEntry = new SharedLibraryEntryImpl(info.LIBRARY_NAME, info.LIBRARY_LEVEL); libraryEntry.getDependencyType().loadState(info.DEPENDENCY_TYPE); myEntries.add(libraryEntry); } else if (info.BC_NAME != null) { BuildConfigurationEntryImpl bcEntry = new BuildConfigurationEntryImpl(pointerManager.create(info.MODULE_NAME), info.BC_NAME); bcEntry.getDependencyType().loadState(info.DEPENDENCY_TYPE); myEntries.add(bcEntry); } else { throw new RuntimeException("unknown entry"); } } mySdk = state.SDK != null ? new SdkEntryImpl(state.SDK) : null; if (mySdk != null && mySdk.getName().isEmpty()) { mySdk = null; } } @Tag("dependencies") public static class State { @Attribute("target-player") public String TARGET_PLAYER = ""; @Attribute("component-set") public ComponentSet COMPONENT_SET = ComponentSet.SparkAndMx; @Attribute("framework-linkage") public String FRAMEWORK_LINKAGE = DEFAULT_FRAMEWORK_LINKAGE.getSerializedText(); @Tag("entries") @AbstractCollection(surroundWithTag = false) public EntryState[] ENTRIES = new EntryState[0]; @Property(surroundWithTag = false) public SdkEntryImpl.State SDK; } }