private void processFileChange(final PsiFile file) {
   if (file != null && StdFileTypes.XML.equals(file.getFileType()) && file instanceof XmlFile) {
     for (final DomEvent event : recomputeFileElement((XmlFile) file)) {
       fireEvent(event);
     }
   }
 }
  @Nullable
  private String fetchOneFile(
      final ProgressIndicator indicator,
      final String resourceUrl,
      final Project project,
      String extResourcesPath,
      @Nullable String refname)
      throws IOException {
    SwingUtilities.invokeLater(
        () -> indicator.setText(XmlBundle.message("fetching.progress.indicator", resourceUrl)));

    FetchResult result = fetchData(project, resourceUrl, indicator);
    if (result == null) return null;

    if (!resultIsValid(project, indicator, resourceUrl, result)) {
      return null;
    }

    int slashIndex = resourceUrl.lastIndexOf('/');
    String resPath = extResourcesPath + File.separatorChar;

    if (refname != null) { // resource is known under ref.name so need to save it
      resPath += refname;
      int refNameSlashIndex = resPath.lastIndexOf('/');
      if (refNameSlashIndex != -1) {
        final File parent = new File(resPath.substring(0, refNameSlashIndex));
        if (!parent.mkdirs() || !parent.exists()) {
          LOG.warn("Unable to create: " + parent);
        }
      }
    } else {
      resPath +=
          Integer.toHexString(resourceUrl.hashCode()) + "_" + resourceUrl.substring(slashIndex + 1);
    }

    final int lastDoPosInResourceUrl = resourceUrl.lastIndexOf('.', slashIndex);
    if (lastDoPosInResourceUrl == -1
        || FileTypeManager.getInstance()
                .getFileTypeByExtension(resourceUrl.substring(lastDoPosInResourceUrl + 1))
            == FileTypes.UNKNOWN) {
      // remote url does not contain file with extension
      final String extension =
          result.contentType != null && result.contentType.contains(HTML_MIME)
              ? StdFileTypes.HTML.getDefaultExtension()
              : StdFileTypes.XML.getDefaultExtension();
      resPath += "." + extension;
    }

    File res = new File(resPath);

    FileUtil.writeToFile(res, result.bytes);
    return resPath;
  }
  static {
    STRUTS_CONFIG_FILE.setIcon(StdFileTypes.XML.getIcon(), 0);
    STRUTS_CONFIG_FILE.setIcon(Struts2Icons.Action_small, 1, 0, OVERLAY_Y_OFFSET);

    VALIDATION_CONFIG_FILE.setIcon(StdFileTypes.XML.getIcon(), 0);
    VALIDATION_CONFIG_FILE.setIcon(Struts2Icons.Edit_small, 1, 0, OVERLAY_Y_OFFSET);

    ACTION_CLASS.setIcon(AllIcons.Nodes.Class, 0);
    ACTION_CLASS.setIcon(Struts2Icons.Action_small, 1, 0, OVERLAY_Y_OFFSET);

    STRUTS_VARIABLE.setIcon(AllIcons.Nodes.Variable, 0);
    STRUTS_VARIABLE.setIcon(Struts2Icons.Action_small, 1, 0, OVERLAY_Y_OFFSET);

    STRUTS_PACKAGE.setIcon(AllIcons.Nodes.Folder, 0);
    STRUTS_PACKAGE.setIcon(Struts2Icons.Action_small, 1, 0, OVERLAY_Y_OFFSET);

    createGlobalIcon(GLOBAL_RESULT, AllIcons.Vcs.Arrow_right);
    createGlobalIcon(GLOBAL_EXCEPTION_MAPPING, AllIcons.Nodes.ExceptionClass);

    createDefaultIcon(DEFAULT_ACTION_REF, Struts2Icons.Action);
    createDefaultIcon(DEFAULT_CLASS_REF, AllIcons.Nodes.Class);
    createDefaultIcon(DEFAULT_INTERCEPTOR_REF, AllIcons.Nodes.Plugin);
    createDefaultIcon(RESULT_TYPE_DEFAULT, AllIcons.Debugger.Console);
  }