diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsFacet.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsFacet.java index 452484494845..648757fddbc9 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsFacet.java +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsFacet.java @@ -1,6 +1,7 @@ package org.jetbrains.jps.model.module; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsNamedElement; import org.jetbrains.jps.model.JpsReferenceableElement; @@ -17,4 +18,13 @@ public interface JpsFacet extends JpsNamedElement, JpsReferenceableElement getType(); void delete(); + + @NotNull + @Override + JpsFacetReference createReference(); + + void setParentFacet(@NotNull JpsFacet facet); + + @Nullable + JpsFacet getParentFacet(); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsFacetReference.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsFacetReference.java new file mode 100644 index 000000000000..e8e122393867 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsFacetReference.java @@ -0,0 +1,9 @@ +package org.jetbrains.jps.model.module; + +import org.jetbrains.jps.model.JpsElementReference; + +/** + * @author nik + */ +public interface JpsFacetReference extends JpsElementReference { +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java index b020d641ca6f..6204da88f0a6 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java @@ -33,7 +33,8 @@ public interface JpsModule extends JpsNamedElement, JpsReferenceableElement type); +

+ JpsFacet addFacet(@NotNull String name, @NotNull JpsFacetType

type, @NotNull P properties); @NotNull List getFacets(); diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetImpl.java index 2932b7721944..8ac665325783 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetImpl.java @@ -1,12 +1,16 @@ package org.jetbrains.jps.model.module.impl; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsElementCollection; -import org.jetbrains.jps.model.JpsElementReference; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.JpsElementProperties; +import org.jetbrains.jps.model.impl.JpsElementKindBase; import org.jetbrains.jps.model.impl.JpsNamedCompositeElementBase; import org.jetbrains.jps.model.impl.JpsTypedDataImpl; import org.jetbrains.jps.model.impl.JpsTypedDataKind; import org.jetbrains.jps.model.module.JpsFacet; +import org.jetbrains.jps.model.module.JpsFacetReference; import org.jetbrains.jps.model.module.JpsFacetType; import org.jetbrains.jps.model.module.JpsModule; @@ -15,10 +19,12 @@ import org.jetbrains.jps.model.module.JpsModule; */ public class JpsFacetImpl extends JpsNamedCompositeElementBase implements JpsFacet { private static final JpsTypedDataKind> TYPED_DATA_KIND = new JpsTypedDataKind>(); + private static final JpsElementKind PARENT_FACET_REFERENCE = new JpsElementKindBase("parent facet"); - public JpsFacetImpl(JpsFacetType facetType, @NotNull String name) { + public

JpsFacetImpl(JpsFacetType facetType, @NotNull String name, @NotNull P properties) { super(name); - myContainer.setChild(TYPED_DATA_KIND, new JpsTypedDataImpl>(facetType, facetType.createDefaultProperties())); + myContainer.setChild(TYPED_DATA_KIND, new JpsTypedDataImpl>(facetType, properties)); + myContainer.setChild(JpsFacetKind.COLLECTION_KIND); } private JpsFacetImpl(JpsNamedCompositeElementBase original) { @@ -37,6 +43,18 @@ public class JpsFacetImpl extends JpsNamedCompositeElementBase imp return myContainer.getChild(TYPED_DATA_KIND).getType(); } + @Override + public void setParentFacet(@NotNull JpsFacet facet) { + myContainer.setChild(PARENT_FACET_REFERENCE, facet.createReference()); + } + + @Override + @Nullable + public JpsFacet getParentFacet() { + final JpsFacetReference reference = myContainer.getChild(PARENT_FACET_REFERENCE); + return reference != null ? reference.resolve() : null; + } + @Override public JpsModule getModule() { return myParent != null ? (JpsModule)myParent.getParent() : null; @@ -44,7 +62,7 @@ public class JpsFacetImpl extends JpsNamedCompositeElementBase imp @NotNull @Override - public JpsElementReference createReference() { + public JpsFacetReference createReference() { return new JpsFacetReferenceImpl(getName(), getModule().createReference()); } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetReferenceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetReferenceImpl.java index 02509bb6472c..0f67615a4f38 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetReferenceImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsFacetReferenceImpl.java @@ -5,12 +5,13 @@ import org.jetbrains.jps.model.JpsElementReference; import org.jetbrains.jps.model.JpsModel; import org.jetbrains.jps.model.impl.JpsNamedElementReferenceBase; import org.jetbrains.jps.model.module.JpsFacet; +import org.jetbrains.jps.model.module.JpsFacetReference; import org.jetbrains.jps.model.module.JpsModuleReference; /** * @author nik */ -public class JpsFacetReferenceImpl extends JpsNamedElementReferenceBase { +public class JpsFacetReferenceImpl extends JpsNamedElementReferenceBase implements JpsFacetReference { public JpsFacetReferenceImpl(String facetName, JpsModuleReference moduleReference) { super(JpsFacetKind.COLLECTION_KIND, facetName, moduleReference); } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java index 27a818ec7182..ba6918f67895 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java @@ -92,10 +92,10 @@ public class JpsModuleImpl extends JpsNamedCompositeElementBase i } } - @Override @NotNull - public JpsFacet addFacet(@NotNull String name, @NotNull JpsFacetType type) { - return myContainer.getChild(JpsFacetKind.COLLECTION_KIND).addChild(new JpsFacetImpl(type, name)); + @Override + public

JpsFacet addFacet(@NotNull String name, @NotNull JpsFacetType

type, @NotNull P properties) { + return myContainer.getChild(JpsFacetKind.COLLECTION_KIND).addChild(new JpsFacetImpl(type, name, properties)); } @NotNull diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsFacetTest.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsFacetTest.java index 09e271aacf79..6c4b9924babb 100644 --- a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsFacetTest.java +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsFacetTest.java @@ -12,12 +12,12 @@ import org.jetbrains.jps.model.module.JpsModule; public class JpsFacetTest extends JpsModelTestCase { public void testAddFacet() { final JpsModule m = myModel.getProject().addModule("m", JpsJavaModuleType.INSTANCE); - m.addFacet("f", MY_FACET_TYPE); + m.addFacet("f", MY_FACET_TYPE, DummyJpsElementProperties.INSTANCE); assertEquals("f", assertOneElement(m.getFacets()).getName()); } public void testCreateReferenceByFacet() { - final JpsFacet facet = myModel.getProject().addModule("m", JpsJavaModuleType.INSTANCE).addFacet("f", MY_FACET_TYPE); + final JpsFacet facet = myModel.getProject().addModule("m", JpsJavaModuleType.INSTANCE).addFacet("f", MY_FACET_TYPE, DummyJpsElementProperties.INSTANCE); final JpsElementReference reference = facet.createReference().asExternal(myModel); assertSame(facet, reference.resolve()); } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java index 420364c6fad7..4778e4fa67e6 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java @@ -4,13 +4,12 @@ import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsCompositeElement; -import org.jetbrains.jps.model.JpsElementProperties; import org.jetbrains.jps.model.JpsElementReference; import org.jetbrains.jps.model.library.JpsOrderRootType; import org.jetbrains.jps.model.library.JpsSdkType; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; -import org.jetbrains.jps.model.module.JpsModuleType; +import org.jetbrains.jps.model.serialization.facet.JpsFacetPropertiesLoader; import java.util.Collections; import java.util.List; @@ -41,16 +40,6 @@ public abstract class JpsModelLoaderExtension { return null; } - @Nullable - public JpsModuleType getModuleType(@NotNull String typeId) { - return null; - } - - @Nullable - public

P loadModuleProperties(JpsModuleType

type, Element moduleRoot) { - return null; - } - @NotNull public List> getModulePropertiesLoaders() { return Collections.emptyList(); @@ -66,6 +55,10 @@ public abstract class JpsModelLoaderExtension { return Collections.emptyList(); } + public List> getFacetPropertiesLoaders() { + return Collections.emptyList(); + } + @Nullable public JpsOrderRootType getSdkRootType(@NotNull String typeId) { return null; diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java index 163327d57733..a079f41e3efb 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java @@ -12,6 +12,7 @@ import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.java.JpsJavaModuleType; import org.jetbrains.jps.model.library.JpsSdkType; import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.serialization.facet.JpsFacetLoader; import org.jetbrains.jps.service.JpsServiceManager; import java.io.File; @@ -134,6 +135,7 @@ public class JpsProjectLoader extends JpsLoaderBase { final JpsModulePropertiesLoader loader = getModulePropertiesLoader(typeId); final JpsModule module = createModule(name, moduleRoot, loader); JpsModuleLoader.loadRootModel(module, findComponent(moduleRoot, "NewModuleRootManager")); + JpsFacetLoader.loadFacets(module, findComponent(moduleRoot, "FacetManager")); return module; } diff --git a/platform/lang-impl/src/com/intellij/facet/impl/FacetManagerState.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/FacetManagerState.java similarity index 95% rename from platform/lang-impl/src/com/intellij/facet/impl/FacetManagerState.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/FacetManagerState.java index a748170b04b1..8a97d3156576 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/FacetManagerState.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/FacetManagerState.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.intellij.facet.impl; +package org.jetbrains.jps.model.serialization.facet; import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.Property; diff --git a/platform/lang-impl/src/com/intellij/facet/impl/FacetState.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/FacetState.java similarity index 87% rename from platform/lang-impl/src/com/intellij/facet/impl/FacetState.java rename to jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/FacetState.java index 74809380cbf5..434a1789544e 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/FacetState.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/FacetState.java @@ -14,9 +14,8 @@ * limitations under the License. */ -package com.intellij.facet.impl; +package org.jetbrains.jps.model.serialization.facet; -import com.intellij.facet.FacetManagerImpl; import com.intellij.util.xmlb.annotations.Attribute; import com.intellij.util.xmlb.annotations.Tag; import com.intellij.util.xmlb.annotations.AbstractCollection; @@ -29,24 +28,24 @@ import java.util.ArrayList; /** * @author nik */ -@Tag(FacetManagerImpl.FACET_ELEMENT) +@Tag(JpsFacetLoader.FACET_ELEMENT) public class FacetState { private String myFacetType; private String myName; private Element myConfiguration; private List mySubFacets = new ArrayList(); - @Attribute(FacetManagerImpl.TYPE_ATTRIBUTE) + @Attribute(JpsFacetLoader.TYPE_ATTRIBUTE) public String getFacetType() { return myFacetType; } - @Attribute(FacetManagerImpl.NAME_ATTRIBUTE) + @Attribute(JpsFacetLoader.NAME_ATTRIBUTE) public String getName() { return myName; } - @Tag(FacetManagerImpl.CONFIGURATION_ELEMENT) + @Tag(JpsFacetLoader.CONFIGURATION_ELEMENT) public Element getConfiguration() { return myConfiguration; } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/JpsFacetLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/JpsFacetLoader.java new file mode 100644 index 000000000000..dec98e54926c --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/JpsFacetLoader.java @@ -0,0 +1,62 @@ +package org.jetbrains.jps.model.serialization.facet; + +import com.intellij.util.xmlb.XmlSerializer; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsElementProperties; +import org.jetbrains.jps.model.module.JpsFacet; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.serialization.JpsModelLoaderExtension; +import org.jetbrains.jps.service.JpsServiceManager; + +import java.util.List; + +/** + * @author nik + */ +public class JpsFacetLoader { + @NonNls public static final String FACET_ELEMENT = "facet"; + @NonNls public static final String TYPE_ATTRIBUTE = "type"; + @NonNls public static final String CONFIGURATION_ELEMENT = "configuration"; + @NonNls public static final String NAME_ATTRIBUTE = "name"; + + public static void loadFacets(JpsModule module, @Nullable Element facetManagerElement) { + if (facetManagerElement == null) return; + final FacetManagerState state = XmlSerializer.deserialize(facetManagerElement, FacetManagerState.class); + if (state != null) { + addFacets(module, state.getFacets(), null); + } + } + + private static void addFacets(JpsModule module, List facets, @Nullable final JpsFacet parentFacet) { + for (FacetState facetState : facets) { + final JpsFacetPropertiesLoader loader = getFacetPropertiesLoader(facetState.getFacetType()); + if (loader != null) { + final JpsFacet facet = addFacet(module, loader, facetState); + if (parentFacet != null) { + facet.setParentFacet(parentFacet); + } + addFacets(module, facetState.getSubFacets(), facet); + } + } + } + + private static

JpsFacet addFacet(JpsModule module, JpsFacetPropertiesLoader

loader, FacetState facet) { + return module.addFacet(facet.getName(), loader.getType(), loader.loadProperties(facet.getConfiguration())); + } + + @Nullable + private static JpsFacetPropertiesLoader getFacetPropertiesLoader(@NotNull String typeId) { + for (JpsModelLoaderExtension extension : JpsServiceManager.getInstance().getExtensions(JpsModelLoaderExtension.class)) { + for (JpsFacetPropertiesLoader loader : extension.getFacetPropertiesLoaders()) { + if (loader.getTypeId().equals(typeId)) { + return loader; + } + } + } + return null; + } + +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/JpsFacetPropertiesLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/JpsFacetPropertiesLoader.java new file mode 100644 index 000000000000..4fb3d5cca0c9 --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/facet/JpsFacetPropertiesLoader.java @@ -0,0 +1,18 @@ +package org.jetbrains.jps.model.serialization.facet; + +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementProperties; +import org.jetbrains.jps.model.module.JpsFacetType; +import org.jetbrains.jps.model.serialization.JpsElementPropertiesLoader; + +/** + * @author nik + */ +public abstract class JpsFacetPropertiesLoader

extends JpsElementPropertiesLoader> { + public JpsFacetPropertiesLoader(JpsFacetType

type, String typeId) { + super(type, typeId); + } + + public abstract P loadProperties(@NotNull Element facetConfigurationElement); +} diff --git a/jps/model-serialization/testData/iprProject/iprProject.iml b/jps/model-serialization/testData/iprProject/iprProject.iml index dbf84a250f51..814115b795e5 100644 --- a/jps/model-serialization/testData/iprProject/iprProject.iml +++ b/jps/model-serialization/testData/iprProject/iprProject.iml @@ -9,7 +9,6 @@ - diff --git a/platform/lang-impl/src/com/intellij/conversion/DetachFacetConversionProcessor.java b/platform/lang-impl/src/com/intellij/conversion/DetachFacetConversionProcessor.java index d49b1d51b49f..42346df7e23a 100644 --- a/platform/lang-impl/src/com/intellij/conversion/DetachFacetConversionProcessor.java +++ b/platform/lang-impl/src/com/intellij/conversion/DetachFacetConversionProcessor.java @@ -19,6 +19,7 @@ package com.intellij.conversion; import com.intellij.facet.FacetManagerImpl; import org.jdom.Element; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.serialization.facet.JpsFacetLoader; import java.util.List; @@ -44,9 +45,9 @@ public class DetachFacetConversionProcessor extends ConversionProcessor getFacetElements(@NotNull String facetTypeId) { final Element facetManager = getComponentElement(FacetManagerImpl.COMPONENT_NAME); final ArrayList elements = new ArrayList(); - for (Element child : JDOMUtil.getChildren(facetManager, FacetManagerImpl.FACET_ELEMENT)) { - if (facetTypeId.equals(child.getAttributeValue(FacetManagerImpl.TYPE_ATTRIBUTE))) { + for (Element child : JDOMUtil.getChildren(facetManager, JpsFacetLoader.FACET_ELEMENT)) { + if (facetTypeId.equals(child.getAttributeValue(JpsFacetLoader.TYPE_ATTRIBUTE))) { elements.add(child); } } diff --git a/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java b/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java index 4cb3f4e56fb9..97d27474d395 100644 --- a/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/facet/FacetManagerImpl.java @@ -38,6 +38,8 @@ import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.serialization.facet.FacetManagerState; +import org.jetbrains.jps.model.serialization.facet.FacetState; import java.util.*; @@ -54,10 +56,6 @@ import java.util.*; ) public class FacetManagerImpl extends FacetManager implements ModuleComponent, PersistentStateComponent { private static final Logger LOG = Logger.getInstance("#com.intellij.facet.FacetManagerImpl"); - @NonNls public static final String FACET_ELEMENT = "facet"; - @NonNls public static final String TYPE_ATTRIBUTE = "type"; - @NonNls public static final String CONFIGURATION_ELEMENT = "configuration"; - @NonNls public static final String NAME_ATTRIBUTE = "name"; @NonNls public static final String COMPONENT_NAME = "FacetManager"; private final Module myModule; diff --git a/platform/lang-impl/src/com/intellij/facet/impl/FacetUtil.java b/platform/lang-impl/src/com/intellij/facet/impl/FacetUtil.java index ea11e8f0d286..8389f5175e55 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/FacetUtil.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/FacetUtil.java @@ -30,6 +30,7 @@ import com.intellij.util.xmlb.XmlSerializer; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.serialization.facet.JpsFacetLoader; import java.lang.reflect.TypeVariable; import java.util.Arrays; @@ -94,7 +95,7 @@ public class FacetUtil { return XmlSerializer.serialize(state, new SkipDefaultValuesSerializationFilters()); } else { - final Element config = new Element(FacetManagerImpl.CONFIGURATION_ELEMENT); + final Element config = new Element(JpsFacetLoader.CONFIGURATION_ELEMENT); configuration.writeExternal(config); return config; } diff --git a/platform/lang-impl/src/com/intellij/facet/impl/invalid/InvalidFacetConfiguration.java b/platform/lang-impl/src/com/intellij/facet/impl/invalid/InvalidFacetConfiguration.java index bf043297d0e8..f0fb40c47b82 100644 --- a/platform/lang-impl/src/com/intellij/facet/impl/invalid/InvalidFacetConfiguration.java +++ b/platform/lang-impl/src/com/intellij/facet/impl/invalid/InvalidFacetConfiguration.java @@ -16,7 +16,7 @@ package com.intellij.facet.impl.invalid; import com.intellij.facet.FacetConfiguration; -import com.intellij.facet.impl.FacetState; +import org.jetbrains.jps.model.serialization.facet.FacetState; import com.intellij.facet.ui.FacetEditorContext; import com.intellij.facet.ui.FacetEditorTab; import com.intellij.facet.ui.FacetValidatorsManager;