package com.intellij.coldFusion.UI.runner; import com.intellij.coldFusion.CfmlBundle; import com.intellij.coldFusion.model.files.CfmlFileType; import com.intellij.coldFusion.model.files.CfmlFileViewProvider; import com.intellij.execution.Location; import com.intellij.execution.PsiLocation; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.actions.RunConfigurationProducer; import com.intellij.ide.scratch.ScratchFileType; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.PathUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.net.MalformedURLException; import java.net.URL; public class CfmlRunConfigurationProducer extends RunConfigurationProducer<CfmlRunConfiguration> { private static final Logger LOG = Logger.getInstance("#com.intellij.coldFusion.UI.runner.CfmlRunConfigurationProducer"); public final static String WWW_ROOT = "wwwroot"; public final static String DEFAULT_HOST = "http://localhost:8500"; public CfmlRunConfigurationProducer() { super(CfmlRunConfigurationType. getInstance()); } @Override protected boolean setupConfigurationFromContext(CfmlRunConfiguration configuration, ConfigurationContext context, Ref<PsiElement> sourceElement) { final Location location = context.getLocation(); if (!(location instanceof PsiLocation)) return false; final VirtualFile file; PsiElement element = location.getPsiElement(); final PsiFile containingFile = element.getContainingFile(); if (isValid(containingFile)) { file = containingFile.getVirtualFile(); sourceElement.set(containingFile); } else { return false; } if (!FileTypeManager.getInstance().isFileOfType(file, ScratchFileType.INSTANCE)) { final VirtualFile root = ProjectRootManager.getInstance(element.getProject()).getFileIndex().getContentRootForFile(file); if (root == null) return false; } if (configuration == null) { return false; } CfmlRunnerParameters params = configuration.getRunnerParameters(); String urlStr = configuration.getRunnerParameters().getUrl(); String serverUrl; if (!urlStr.isEmpty()) { //generated from default run configuration try { URL url = new URL(urlStr); serverUrl = url.getProtocol() + "://" + url.getAuthority(); } catch (MalformedURLException e) { LOG.error(CfmlBundle.message("cfml.producer.error.url", urlStr)); return false; } } else { // if default configuration is not defined serverUrl = DEFAULT_HOST; configuration.setFromDefaultHost(true); } String path = buildPageUrl(context, file); //check that serverUrl ends with '/' and fix it if neccessary if (StringUtil.endsWith(serverUrl, "/") && !StringUtil.startsWith(path, "/")) { params.setUrl(serverUrl + path); } else if (!StringUtil.endsWith(serverUrl, "/") && !StringUtil.startsWith(path, "/")) { params.setUrl(serverUrl + "/" + path); } else if (!StringUtil.endsWith(serverUrl, "/") && StringUtil.startsWith(path, "/")) { params.setUrl(serverUrl + path); } else if (StringUtil.endsWith(serverUrl, "/") && StringUtil.startsWith(path, "/")) { params.setUrl(serverUrl + path.substring(1, path.length())); } configuration.setName(generateName(containingFile)); return true; } @NotNull private static String generateName(PsiFile containingFile) { return StringUtil.isNotEmpty(containingFile.getVirtualFile().getPath()) ? PathUtil .getFileName(containingFile.getVirtualFile().getPath()) : ""; } @NotNull private static String buildPageUrl(ConfigurationContext context, VirtualFile file) { String result; String absolutePageUrl = file.getUrl(); int wwwrootIndex = absolutePageUrl.indexOf(WWW_ROOT); if (wwwrootIndex == -1) { VirtualFile projectBaseDir = context.getProject().getBaseDir(); String relativePath = FileUtil.getRelativePath(projectBaseDir.getPath(), file.getPath(), '/'); result = projectBaseDir.getName() + "/" + relativePath; } else { result = absolutePageUrl.substring(wwwrootIndex + WWW_ROOT.length()); } return result; } @Override public boolean isConfigurationFromContext(CfmlRunConfiguration configuration, ConfigurationContext context) { final Location location = context.getLocation(); if (location == null) return false; final PsiElement anchor = location.getPsiElement(); final PsiFile containingFile = anchor.getContainingFile(); if (isValid(containingFile)) { final String path; path = buildPageUrl(context, containingFile.getVirtualFile()); URL url; final String urlFromRunnerParameters = configuration.getRunnerParameters().getUrl(); if (urlFromRunnerParameters.isEmpty()) return false; try { url = new URL(urlFromRunnerParameters); return StringUtil.equals(url.getPath(), path); } catch (MalformedURLException e) { LOG.error(CfmlBundle.message("cfml.producer.error.url", urlFromRunnerParameters)); } } return false; } private static boolean isValid(@Nullable PsiFile containingFile) { return containingFile != null && (containingFile.getFileType() == CfmlFileType.INSTANCE || containingFile.getViewProvider() instanceof CfmlFileViewProvider) && containingFile.getVirtualFile() != null; } }