show invalid facets in Project Structure dialog

This commit is contained in:
nik
2010-10-28 13:06:13 +04:00
parent f4d6f865eb
commit f59db912f9
12 changed files with 374 additions and 64 deletions
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot;
import com.intellij.facet.Facet;
import com.intellij.facet.impl.ProjectFacetsConfigurator;
import com.intellij.facet.impl.invalid.InvalidFacet;
import com.intellij.facet.impl.ui.FacetEditorImpl;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.ProjectBundle;
@@ -38,7 +39,7 @@ public class FacetConfigurable extends NamedConfigurable<Facet> {
private String myFacetName;
public FacetConfigurable(final Facet facet, final ModulesConfigurator modulesConfigurator, final Runnable updateTree) {
super(!facet.getType().isOnlyOneFacetAllowed(), updateTree);
super(!facet.getType().isOnlyOneFacetAllowed() && !(facet instanceof InvalidFacet), updateTree);
myFacet = facet;
myModulesConfigurator = modulesConfigurator;
myFacetName = myFacet.getName();
@@ -17,6 +17,10 @@
package com.intellij.facet;
import com.intellij.facet.impl.*;
import com.intellij.facet.impl.invalid.InvalidFacet;
import com.intellij.facet.impl.invalid.InvalidFacetConfiguration;
import com.intellij.facet.impl.invalid.InvalidFacetManager;
import com.intellij.facet.impl.invalid.InvalidFacetType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
@@ -28,6 +32,7 @@ import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ProjectLoadingErrorsNotifier;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.messages.MessageBus;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -59,7 +64,6 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
private final Module myModule;
private final FacetTypeRegistry myFacetTypeRegistry;
private final FacetManagerModel myModel = new FacetManagerModel();
private final MultiValuesMap<Facet, FacetState> myInvalidFacets = new MultiValuesMap<Facet, FacetState>(true);
private boolean myInsideCommit = false;
private final MessageBus myMessageBus;
private boolean myModuleAdded;
@@ -152,29 +156,24 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
}
}
public void removeInvalidFacet(@Nullable Facet underlyingFacet, @NotNull FacetState facetState) {
myInvalidFacets.remove(underlyingFacet, facetState);
}
private void addFacets(final List<FacetState> facetStates, final Facet underlyingFacet, ModifiableFacetModel model) {
for (FacetState child : facetStates) {
final String typeId = child.getFacetType();
if (typeId == null) {
registerLoadingError(underlyingFacet, child, ProjectBundle.message("error.message.facet.type.isn.t.specified"));
addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.facet.type.isn.t.specified"));
continue;
}
final FacetType<?,?> type = myFacetTypeRegistry.findFacetType(typeId);
if (type == null) {
registerLoadingError(underlyingFacet, child, ProjectBundle.message("error.message.unknown.facet.type.0", typeId));
addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.unknown.facet.type.0", typeId));
continue;
}
ModuleType moduleType = myModule.getModuleType();
if (!type.isSuitableModuleType(moduleType)) {
registerLoadingError(underlyingFacet, child, ProjectBundle.message("error.message.0.facets.are.not.allowed.in.1",
type.getPresentableName(), moduleType.getName()));
addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.0.facets.are.not.allowed.in.1",
type.getPresentableName(), moduleType.getName()));
continue;
}
@@ -183,21 +182,22 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
if (underlyingTypeId != null) {
expectedUnderlyingType = myFacetTypeRegistry.findFacetType(underlyingTypeId);
if (expectedUnderlyingType == null) {
registerLoadingError(underlyingFacet, child, ProjectBundle.message("error.message.cannot.find.underlying.facet.type.for.0", typeId));
addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.cannot.find.underlying.facet.type.for.0", typeId));
continue;
}
}
FacetType actualUnderlyingType = underlyingFacet != null ? underlyingFacet.getType() : null;
if (expectedUnderlyingType != null) {
if (!expectedUnderlyingType.equals(actualUnderlyingType)) {
registerLoadingError(underlyingFacet, child, ProjectBundle.message("error.message.0.facet.must.be.placed.under.1.facet",
type.getPresentableName(), expectedUnderlyingType.getPresentableName()));
addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.0.facet.must.be.placed.under.1.facet",
type.getPresentableName(),
expectedUnderlyingType.getPresentableName()));
continue;
}
}
else if (actualUnderlyingType != null) {
registerLoadingError(underlyingFacet, child, ProjectBundle.message("error.message.0.cannot.be.placed.under.1",
type.getPresentableName(), actualUnderlyingType.getPresentableName()));
addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.0.cannot.be.placed.under.1",
type.getPresentableName(), actualUnderlyingType.getPresentableName()));
continue;
}
@@ -206,14 +206,18 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
}
catch (InvalidDataException e) {
LOG.info(e);
registerLoadingError(underlyingFacet, child, ProjectBundle.message("error.message.cannot.load.facet.condiguration.0", e.getMessage()));
addInvalidFacet(child, model, underlyingFacet, ProjectBundle.message("error.message.cannot.load.facet.condiguration.0", e.getMessage()));
}
}
}
private void registerLoadingError(final Facet underlyingFacet, final FacetState child, final String errorMessage) {
myInvalidFacets.put(underlyingFacet, child);
FacetLoadingErrorDescription description = new FacetLoadingErrorDescription(myModule, errorMessage, underlyingFacet, child);
private void addInvalidFacet(final FacetState state, ModifiableFacetModel model, final Facet underlyingFacet, final String errorMessage) {
final String typeId = StringUtil.notNullize(state.getFacetType());
final InvalidFacetType type = InvalidFacetManager.getInstance(myModule.getProject()).getOrCreateType(typeId);
final InvalidFacetConfiguration configuration = new InvalidFacetConfiguration(state, errorMessage);
final InvalidFacet facet = createFacet(type, StringUtil.notNullize(state.getName()), configuration, underlyingFacet);
model.addFacet(facet);
FacetLoadingErrorDescription description = new FacetLoadingErrorDescription(facet);
ProjectLoadingErrorsNotifier.getInstance(myModule.getProject()).registerError(description);
}
@@ -242,7 +246,6 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
public void loadState(final FacetManagerState state) {
ModifiableFacetModel model = new FacetModelImpl(this);
myInvalidFacets.clear();
addFacets(state.getFacets(), null, model);
commit(model, false);
@@ -267,6 +270,9 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
try {
FacetConfiguration configuration = facet.getConfiguration();
config = FacetUtil.saveFacetConfiguration(configuration);
if (configuration instanceof InvalidFacetConfiguration) {
facetState.getSubFacets().addAll(((InvalidFacetConfiguration)configuration).getSubFacetsStates());
}
if (facet instanceof JDOMExternalizable) {
//todo[nik] remove
((JDOMExternalizable)facet).writeExternal(config);
@@ -278,21 +284,11 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
facetState.setConfiguration(config);
parent.add(facetState);
List<FacetState> subFacets = facetState.getSubFacets();
addInvalidFacets(facet, subFacets);
states.put(facet, subFacets);
states.put(facet, facetState.getSubFacets());
}
addInvalidFacets(null, managerState.getFacets());
return managerState;
}
private void addInvalidFacets(@Nullable Facet facet, final List<FacetState> subFacets) {
Collection<FacetState> invalidFacets = myInvalidFacets.get(facet);
if (invalidFacets != null) {
subFacets.addAll(invalidFacets);
}
}
public void commit(final ModifiableFacetModel model) {
ApplicationManager.getApplication().assertWriteAccessAllowed();
@@ -345,10 +341,6 @@ public class FacetManagerImpl extends FacetManager implements ModuleComponent, P
}
}
for (Facet facet : toRemove) {
myInvalidFacets.removeAll(facet);
}
for (FacetRenameInfo info : toRename) {
info.myFacet.setName(info.myNewName);
}
@@ -16,9 +16,7 @@
package com.intellij.facet.impl;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetManagerImpl;
import com.intellij.openapi.module.Module;
import com.intellij.facet.impl.invalid.InvalidFacet;
import com.intellij.openapi.module.ConfigurationErrorDescription;
import com.intellij.openapi.project.ProjectBundle;
@@ -26,42 +24,25 @@ import com.intellij.openapi.project.ProjectBundle;
* @author nik
*/
public class FacetLoadingErrorDescription extends ConfigurationErrorDescription {
private final Facet myUnderlyingFacet;
private final FacetState myState;
private final Module myModule;
private final InvalidFacet myFacet;
public FacetLoadingErrorDescription(final Module module, final String errorMessage, final Facet underlyingFacet, final FacetState state) {
super(state.getName() + " (" + module.getName() + ")", ProjectBundle.message("element.kind.name.facet"), errorMessage);
myModule = module;
myUnderlyingFacet = underlyingFacet;
myState = state;
}
public Facet getUnderlyingFacet() {
return myUnderlyingFacet;
}
public FacetState getState() {
return myState;
}
public Module getModule() {
return myModule;
public FacetLoadingErrorDescription(final InvalidFacet facet) {
super(facet.getName() + " (" + facet.getModule().getName() + ")", ProjectBundle.message("element.kind.name.facet"), facet.getErrorMessage());
myFacet = facet;
}
@Override
public String getRemoveConfirmationMessage() {
return ProjectBundle.message("confirmation.message.would.you.like.to.remove.facet", myState.getName(), myModule.getName());
return ProjectBundle.message("confirmation.message.would.you.like.to.remove.facet", myFacet.getName(), myFacet.getModule().getName());
}
@Override
public void removeInvalidElement() {
FacetManagerImpl manager = (FacetManagerImpl)FacetManagerImpl.getInstance(myModule);
manager.removeInvalidFacet(myUnderlyingFacet, myState);
FacetUtil.deleteFacet(myFacet);
}
@Override
public boolean isValid() {
return !myModule.isDisposed();
return !myFacet.isDisposed();
}
}
@@ -74,6 +74,7 @@ public class FacetUtil {
public static Element saveFacetConfiguration(final FacetConfiguration configuration) throws WriteExternalException {
if (configuration instanceof PersistentStateComponent) {
Object state = ((PersistentStateComponent)configuration).getState();
if (state instanceof Element) return ((Element)state);
return XmlSerializer.serialize(state, new SkipDefaultValuesSerializationFilters());
}
else {
@@ -0,0 +1,36 @@
/*
* Copyright 2000-2010 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.facet.impl.invalid;
import com.intellij.facet.Facet;
import com.intellij.openapi.module.Module;
/**
* @author nik
*/
public class InvalidFacet extends Facet<InvalidFacetConfiguration> {
public InvalidFacet(InvalidFacetType invalidFacetType,
Module module,
String name,
InvalidFacetConfiguration configuration,
Facet underlyingFacet) {
super(invalidFacetType, module, name, configuration, underlyingFacet);
}
public String getErrorMessage() {
return getConfiguration().getErrorMessage();
}
}
@@ -0,0 +1,74 @@
/*
* Copyright 2000-2010 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.facet.impl.invalid;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.impl.FacetState;
import com.intellij.facet.ui.FacetEditorContext;
import com.intellij.facet.ui.FacetEditorTab;
import com.intellij.facet.ui.FacetValidatorsManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
import java.util.List;
/**
* @author nik
*/
public class InvalidFacetConfiguration implements FacetConfiguration, PersistentStateComponent<Element> {
private FacetState myFacetState;
private final String myErrorMessage;
public InvalidFacetConfiguration(FacetState facetState, String errorMessage) {
myFacetState = facetState;
myErrorMessage = errorMessage;
}
public List<FacetState> getSubFacetsStates() {
return myFacetState.getSubFacets();
}
@Override
public FacetEditorTab[] createEditorTabs(FacetEditorContext editorContext, FacetValidatorsManager validatorsManager) {
return new FacetEditorTab[] {
new InvalidFacetEditor(myErrorMessage)
};
}
@Override
public void readExternal(Element element) throws InvalidDataException {
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
}
public String getErrorMessage() {
return myErrorMessage;
}
@Override
public Element getState() {
return myFacetState.getConfiguration();
}
@Override
public void loadState(Element state) {
myFacetState.setConfiguration(state);
}
}
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.facet.impl.invalid.InvalidFacetEditor">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="c0c37" class="javax.swing.JLabel" binding="myErrorLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Label"/>
</properties>
</component>
<vspacer id="c57a2">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
@@ -0,0 +1,61 @@
/*
* Copyright 2000-2010 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.facet.impl.invalid;
import com.intellij.facet.ui.FacetEditorTab;
import com.intellij.openapi.util.IconLoader;
import org.jetbrains.annotations.Nls;
import javax.swing.*;
/**
* @author nik
*/
public class InvalidFacetEditor extends FacetEditorTab {
private final String myErrorMessage;
private JPanel myMainPanel;
private JLabel myErrorLabel;
public InvalidFacetEditor(String errorMessage) {
myErrorMessage = errorMessage;
}
@Nls
@Override
public String getDisplayName() {
return "";
}
@Override
public JComponent createComponent() {
myErrorLabel.setText(myErrorMessage);
myErrorLabel.setIcon(IconLoader.getIcon("/runConfigurations/configurationWarning.png"));
return myMainPanel;
}
@Override
public boolean isModified() {
return false;
}
@Override
public void reset() {
}
@Override
public void disposeUIResources() {
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2010 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.facet.impl.invalid;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public abstract class InvalidFacetManager {
public static InvalidFacetManager getInstance(@NotNull Project project) {
return ServiceManager.getService(project, InvalidFacetManager.class);
}
@NotNull
public abstract InvalidFacetType getOrCreateType(@NotNull String typeId);
}
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2010 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.facet.impl.invalid;
import com.intellij.util.containers.FactoryMap;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* @author nik
*/
public class InvalidFacetManagerImpl extends InvalidFacetManager {
private Map<String, InvalidFacetType> myTypes = new FactoryMap<String, InvalidFacetType>() {
@Override
protected InvalidFacetType create(String key) {
return new InvalidFacetType(key);
}
};
@NotNull
@Override
public InvalidFacetType getOrCreateType(@NotNull String typeId) {
return myTypes.get(typeId);
}
}
@@ -0,0 +1,66 @@
/*
* Copyright 2000-2010 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.facet.impl.invalid;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeId;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.util.IconLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* @author nik
*/
public class InvalidFacetType extends FacetType<InvalidFacet, InvalidFacetConfiguration> {
private static final Icon ICON = IconLoader.getIcon("/fileTypes/unknown.png");
public InvalidFacetType(String typeId) {
super(new FacetTypeId<InvalidFacet>("invalid:" + typeId), typeId, typeId, null);
}
@Override
public InvalidFacetConfiguration createDefaultConfiguration() {
throw new UnsupportedOperationException();
}
@Override
public InvalidFacet createFacet(@NotNull Module module,
String name,
@NotNull InvalidFacetConfiguration configuration,
@Nullable Facet underlyingFacet) {
return new InvalidFacet(this, module, name, configuration, underlyingFacet);
}
@Override
public boolean isSuitableModuleType(ModuleType moduleType) {
return true;
}
@Override
public boolean isOnlyOneFacetAllowed() {
return false;
}
@Override
public Icon getIcon() {
return ICON;
}
}
@@ -184,7 +184,8 @@
<projectService serviceInterface="com.intellij.facet.ProjectFacetManager"
serviceImplementation="com.intellij.facet.impl.ProjectFacetManagerImpl"/>
<projectService serviceInterface="com.intellij.facet.impl.invalid.InvalidFacetManager"
serviceImplementation="com.intellij.facet.impl.invalid.InvalidFacetManagerImpl"/>
<projectService serviceInterface="com.intellij.openapi.module.ProjectLoadingErrorsNotifier"
serviceImplementation="com.intellij.openapi.module.impl.ProjectLoadingErrorsNotifierImpl"/>