package com.intellij.coverage;

import com.intellij.execution.configurations.RunConfigurationBase;
import com.intellij.javaee.run.configuration.CommonModel;
import com.intellij.javaee.web.WebUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassOwner;
import com.intellij.psi.PsiFile;
import com.intellij.psi.jsp.WebDirectoryElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashSet;
import java.util.Set;

/**
 * User: anna
 * Date: 12/21/10
 */
public class J2EECoverageEngine extends JavaCoverageEngine {
  @Override
  public boolean isApplicableTo(@Nullable RunConfigurationBase conf) {
    return conf instanceof CommonModel && ((CommonModel)conf).isLocal();
  }

  @Override
  public boolean canHavePerTestCoverage(@Nullable RunConfigurationBase conf) {
    return false;
  }

  @NotNull
  @Override
  public Set<String> getQualifiedNames(@NotNull final PsiFile sourceFile) {
    if (getPackageName(sourceFile).length() == 0) {
      return ApplicationManager.getApplication().runReadAction(new Computable<Set<String>>() {
        public Set<String> compute() {
          final PsiClass[] classes = ((PsiClassOwner)sourceFile).getClasses();
          if (classes.length == 1 && classes[0].getQualifiedName() == null) {
            final Set<String> result = new HashSet<String>();
            final VirtualFile virtualFile = sourceFile.getVirtualFile();
            if (virtualFile != null) {
              final WebDirectoryElement webDirectoryElement = WebUtil.findWebDirectoryByFile(virtualFile, sourceFile.getProject());
              if (webDirectoryElement != null) {
                final WebDirectoryElement parentDirectory = webDirectoryElement.getParentDirectory();
                String webRoot = parentDirectory != null ? parentDirectory.getPath() : "/";
                if (!webRoot.endsWith("/")) {
                  webRoot += "/";
                }
                result.add("org.apache.jsp" + webRoot.replace('/', '.') + virtualFile.getNameWithoutExtension() + "_" + virtualFile.getExtension());
                return result;
              }
            }
          }
          return J2EECoverageEngine.super.getQualifiedNames(sourceFile);
        }
      });
    }
    return super.getQualifiedNames(sourceFile);
  }
}

@@ -246,24 +246,69 @@
 ionManager;%0A
+import com.intellij.openapi.project.Project;%0A
 import com.i
@@ -336,24 +336,24 @@
 Computable;%0A
-
 import com.i
@@ -381,24 +381,63 @@
 irtualFile;%0A
+import com.intellij.psi.JavaPsiFacade;%0A
 import com.i
@@ -2210,126 +2210,121 @@
 add(
-%22org.apache.jsp%22 + webRoot.replace('/', '.') + virtualFile.getNameWithoutExtension() + %22_%22 + virtualFile.getExtension(
+%0A                  %22org.apache.jsp%22 + makeJavaIdentifier(webRoot + virtualFile.getName(), sourceFile.getProject()
 ));%0A
@@ -2491,24 +2491,24 @@
   %7D);%0A    %7D%0A
-
     return s
@@ -2546,11 +2546,1492 @@
 le);%0A  %7D
+%0A%0A  /**%0A   * Converts the given identifier to a legal Java identifier%0A   * %7B@see org.apache.jasper.compiler.JspUtil%7D%0A   */%0A  public static String makeJavaIdentifier(String identifier, Project project) %7B%0A    StringBuffer modifiedIdentifier =%0A      new StringBuffer(identifier.length());%0A    if (!Character.isJavaIdentifierStart(identifier.charAt(0)) && identifier.charAt(0) != '/') %7B%0A      modifiedIdentifier.append('_');%0A    %7D%0A    for (int i = 0; i %3C identifier.length(); i++) %7B%0A      char ch = identifier.charAt(i);%0A      if (ch == '/') %7B%0A        modifiedIdentifier.append('.');%0A      %7D%0A      else if (Character.isJavaIdentifierPart(ch) && ch != '_') %7B%0A        modifiedIdentifier.append(ch);%0A      %7D else if (ch == '.') %7B%0A        modifiedIdentifier.append('_');%0A      %7D%0A      else %7B%0A        modifiedIdentifier.append(mangleChar(ch));%0A      %7D%0A    %7D%0A    if (JavaPsiFacade.getInstance(project).getNameHelper().isKeyword(modifiedIdentifier.toString())) %7B%0A      modifiedIdentifier.append('_');%0A    %7D%0A    return modifiedIdentifier.toString();%0A  %7D%0A%0A  /**%0A   * Mangle the specified character to create a legal Java class name.%0A   */%0A  public static String mangleChar(char ch) %7B%0A    char%5B%5D result = new char%5B5%5D;%0A    result%5B0%5D = '_';%0A    result%5B1%5D = Character.forDigit((ch %3E%3E 12) & 0xf, 16);%0A    result%5B2%5D = Character.forDigit((ch %3E%3E 8) & 0xf, 16);%0A    result%5B3%5D = Character.forDigit((ch %3E%3E 4) & 0xf, 16);%0A    result%5B4%5D = Character.forDigit(ch & 0xf, 16);%0A    return new String(result);%0A  %7D
 %0A%7D%0A

convert jsp name to class name according to JspUtil from jasper compiler (IDEA-65421)