Programmatically configured Web facet does not appear in "Web" sidebar

Hello. I am trying to configure Web facet in a project using the code below. I am doing it during project import, right from my cusom ProjectImportBuilder. Everything is ok, except one moment. The facet does not appear in the "Web" sidebar. If I add that facet manually via project structure everything is ok. Am I missing something?

Thanks.

package com.intellij.idea.plugin.hybris.project.configurators.impl;

import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetManager;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeRegistry;
import com.intellij.facet.ModifiableFacetModel;
import com.intellij.idea.plugin.hybris.common.HybrisConstants;
import com.intellij.idea.plugin.hybris.project.settings.HybrisModuleDescriptor;
import com.intellij.javaee.DeploymentDescriptorsConstants;
import com.intellij.javaee.web.facet.WebFacet;
import com.intellij.javaee.web.facet.WebFacetConfigurationImpl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.Arrays;

public class WebFacetConfigurator extends AbstractFacetConfigurator {

@Override
protected void configureInner(@NotNull final ModifiableFacetModel modifiableFacetModel,
@NotNull final HybrisModuleDescriptor moduleDescriptor,
@NotNull final Module javaModule,
@NotNull final ModifiableRootModel modifiableRootModel) {
Validate.notNull(javaModule);
Validate.notNull(modifiableFacetModel);
Validate.notNull(moduleDescriptor);
Validate.notNull(modifiableFacetModel);

final File webRoot = moduleDescriptor.getWebRoot();
if (null == webRoot) {
return;
}

WebFacet webFacet = modifiableFacetModel.getFacetByType(WebFacet.ID);

if (webFacet == null) {
final FacetType<WebFacet, FacetConfiguration> webFacetType = FacetTypeRegistry.getInstance().findFacetType(
WebFacet.ID
);

if (!webFacetType.isSuitableModuleType(ModuleType.get(javaModule))) {
return;
}

webFacet = FacetManager.getInstance(javaModule).createFacet(
webFacetType, webFacetType.getDefaultFacetName(), null
);

modifiableFacetModel.addFacet(webFacet);

} else {
webFacet.removeAllWebRoots();
webFacet.getDescriptorsContainer().getConfiguration().removeConfigFiles(
DeploymentDescriptorsConstants.WEB_XML_META_DATA
);
}

this.setupFacetSourceRoots(webFacet, modifiableRootModel);
this.setupFacetWebRoot(webFacet, webRoot);
this.setupFacetDeploymentDescriptor(webFacet, moduleDescriptor);
}

protected void setupFacetDeploymentDescriptor(@NotNull final WebFacet webFacet,
@NotNull final HybrisModuleDescriptor moduleDescriptor) {
Validate.notNull(webFacet);
Validate.notNull(moduleDescriptor);

webFacet.getDescriptorsContainer().getConfiguration().addConfigFile(
DeploymentDescriptorsConstants.WEB_XML_META_DATA,
new File(moduleDescriptor.getRootDirectory(), HybrisConstants.WEB_XML_DIRECTORY_RELATIVE_PATH).getAbsolutePath()
);
}

protected void setupFacetWebRoot(@NotNull final WebFacet webFacet, @NotNull final File webRoot) {
Validate.notNull(webFacet);
Validate.notNull(webRoot);

final VirtualFile moduleRootVf = VfsUtil.findFileByIoFile(webRoot, true);
if (null != moduleRootVf) {
webFacet.addWebRoot(moduleRootVf, "/");
}
}

public void setupFacetSourceRoots(@NotNull final WebFacet facet, @NotNull final ModuleRootModel model) {
Validate.notNull(facet);
Validate.notNull(model);

final String[] sourceRootUrls = model.getSourceRootUrls(false);
((WebFacetConfigurationImpl)facet.getConfiguration()).setSourceRoots(Arrays.asList(sourceRootUrls));
}
}

 

7 comments
Comment actions Permalink

Hello,

do you invoke 'commit' method on 'modifiableFacetModel' instance after configuring the facet?

0
Comment actions Permalink

Yes, in my AbstractFacetConfigurator

public abstract class AbstractFacetConfigurator implements FacetConfigurator {

@Override
public void configure(@NotNull final ModifiableFacetModel modifiableFacetModel,
@NotNull final HybrisModuleDescriptor moduleDescriptor,
@NotNull final Module javaModule,
@NotNull final ModifiableRootModel modifiableRootModel,
@NotNull final ModifiableModelsProvider modifiableModelsProvider) {
Validate.notNull(modifiableFacetModel);
Validate.notNull(moduleDescriptor);
Validate.notNull(javaModule);
Validate.notNull(modifiableRootModel);
Validate.notNull(modifiableModelsProvider);

ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
configureInner(modifiableFacetModel, moduleDescriptor, javaModule, modifiableRootModel);
modifiableModelsProvider.commitFacetModifiableModel(javaModule, modifiableFacetModel);
}
});
}

protected abstract void configureInner(@NotNull ModifiableFacetModel modifiableFacetModel,
@NotNull HybrisModuleDescriptor moduleDescriptor,
@NotNull Module javaModule,
@NotNull ModifiableRootModel modifiableRootModel);
}

and ProjectImportBuilder

ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
modifiableModelsProvider.commitFacetModifiableModel(javaModule, modifiableFacetModel);
modifiableModelsProvider.commitModuleModifiableModel(modifiableRootModel);
}
});
0
Comment actions Permalink

Hmm, it's strange. Does the problem repeat if you close the project, restart the IDE and then reopen the project?

0
Comment actions Permalink

Yes. After restart the web panel is still empty. Also if I remove the web facet from some module and add it back manually only that facet appears in the panel. It really looks like that panel has a separate list of facets somewhere or for some reason filters out all my automatically configured facets despite that visually configuration is the same. I have tried to debug and find where they are being filtered out but no luck.

0
Comment actions Permalink

The panel invokes com.intellij.facet.ProjectFacetManager.getInstance().getFacets WebFacet.ID) and doesn't filter the returned instances, see com.intellij.javaee.module.view.web.WebView and its superclass com.intellij.javaee.ui.JavaeeToolWindowViewBase. Unfortunately these classes aren't included into IDEA Community Edition, so their sources aren't available, but probably our decompiler will help you to debug though it.

0
Comment actions Permalink

 


Debug there almost unusable all lines are shifted. What I was able to figure out that at this point all elements are present. Also manually added facet has empty name of whatever that is. 

0
Comment actions Permalink

I have found the error. Instead of 

webFacet.getDescriptorsContainer().getConfiguration().addConfigFile(
DeploymentDescriptorsConstants.WEB_XML_META_DATA,
new File(moduleDescriptor.getRootDirectory(), HybrisConstants.WEB_XML_DIRECTORY_RELATIVE_PATH).getAbsolutePath()
);

It should be 

final VirtualFile fileByIoFile = VfsUtil.findFileByIoFile(
new File(moduleDescriptor.getRootDirectory(), HybrisConstants.WEB_XML_DIRECTORY_RELATIVE_PATH), true
);

if (null != fileByIoFile) {
webFacet.getDescriptorsContainer().getConfiguration().addConfigFile(
DeploymentDescriptorsConstants.WEB_XML_META_DATA,
fileByIoFile.getUrl()
);
}

Thanks for the assistance.

0

Please sign in to leave a comment.