package com.intellij.lang.javascript.flex.projectStructure.ui;
import com.intellij.flex.FlexCommonUtils;
import com.intellij.lang.javascript.flex.FlexBundle;
import com.intellij.lang.javascript.flex.FlexUtils;
import com.intellij.lang.javascript.flex.sdk.FlexSdkUtils;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.*;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
public class CreateHtmlWrapperTemplateDialog extends DialogWrapper {
public static final String HTML_TEMPLATE_FOLDER_NAME = "html-template";
public static final String TITLE = FlexBundle.message("create.html.wrapper.template.title");
private static final String PLAYER_PRODUCT_INSTALL_SWF = "playerProductInstall.swf";
private static final String USE_BROWSER_HISTORY_MACRO = "${useBrowserHistory}";
private static final String EXPRESS_INSTALL_SWF_MACRO = "${expressInstallSwf}";
private JPanel myMainPanel;
private LabeledComponent<TextFieldWithBrowseButton> myWrapperFolderComponent;
private JCheckBox myEnableHistoryCheckBox;
private JCheckBox myCheckPlayerVersionCheckBox;
private JCheckBox myExpressInstallCheckBox;
private final Module myModule;
private final @NotNull Sdk mySdk;
private final String myOutputPath;
public CreateHtmlWrapperTemplateDialog(final Module module,
final @NotNull Sdk sdk,
final String outputPath,
final @Nullable String initialPath) {
super(module.getProject());
myModule = module;
mySdk = sdk;
myOutputPath = outputPath;
setInitialPath(module, initialPath);
myCheckPlayerVersionCheckBox.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
myExpressInstallCheckBox.setEnabled(myCheckPlayerVersionCheckBox.isSelected());
}
});
myWrapperFolderComponent.getComponent()
.addBrowseFolderListener(null, null, module.getProject(), FileChooserDescriptorFactory.createSingleFolderDescriptor());
setTitle(TITLE);
init();
}
private void setInitialPath(final Module module, final String initialPath) {
if (initialPath != null) {
myWrapperFolderComponent.getComponent().setText(FileUtil.toSystemDependentName(initialPath));
}
else {
final String[] contentRootUrls = ModuleRootManager.getInstance(module).getContentRootUrls();
final String path = contentRootUrls.length > 0
? FileUtil.toSystemDependentName(VfsUtil.urlToPath(contentRootUrls[0]) + "/" + HTML_TEMPLATE_FOLDER_NAME)
: FileUtil.toSystemDependentName(PathUtil.getParentPath(module.getModuleFilePath())
+ "/" + HTML_TEMPLATE_FOLDER_NAME);
myWrapperFolderComponent.getComponent().setText(path);
}
}
public JComponent getPreferredFocusedComponent() {
return myWrapperFolderComponent.getComponent().getTextField();
}
protected JComponent createCenterPanel() {
return myMainPanel;
}
public String getWrapperFolderPath() {
return FileUtil.toSystemIndependentName(myWrapperFolderComponent.getComponent().getText().trim());
}
protected ValidationInfo doValidate() {
final String wrapperFolderPath = getWrapperFolderPath();
for (String url : ModuleRootManager.getInstance(myModule).getContentRootUrls()) {
final String path = VfsUtil.urlToPath(url);
if (FileUtil.isAncestor(wrapperFolderPath, path, false)) {
return new ValidationInfo(
FlexBundle.message("html.wrapper.folder.clash.for.dialog", "module content root", FileUtil.toSystemDependentName(path)),
myWrapperFolderComponent.getComponent());
}
}
for (String url : ModuleRootManager.getInstance(myModule).getSourceRootUrls()) {
final String path = VfsUtil.urlToPath(url);
if (FileUtil.isAncestor(wrapperFolderPath, path, false)) {
return new ValidationInfo(
FlexBundle.message("html.wrapper.folder.clash.for.dialog", "source folder", FileUtil.toSystemDependentName(path)),
myWrapperFolderComponent.getComponent());
}
}
if (!myOutputPath.isEmpty() && FileUtil.isAncestor(wrapperFolderPath, myOutputPath, false)) {
return new ValidationInfo(
FlexBundle.message("html.wrapper.folder.clash.for.dialog", "output folder", FileUtil.toSystemDependentName(myOutputPath)),
myWrapperFolderComponent.getComponent());
}
return null;
}
protected void doOKAction() {
if (createHtmlWrapperTemplate(myModule.getProject(), mySdk, getWrapperFolderPath(),
myEnableHistoryCheckBox.isSelected(), myCheckPlayerVersionCheckBox.isSelected(),
myExpressInstallCheckBox.isEnabled() && myExpressInstallCheckBox.isSelected())) {
super.doOKAction();
}
}
public static boolean createHtmlWrapperTemplate(final Project project,
final Sdk sdk,
final String templateFolderPath,
final boolean enableHistory,
final boolean checkPlayerVersion,
final boolean expressInstall) {
final VirtualFile folder = FlexUtils.createDirIfMissing(project, true, templateFolderPath, TITLE);
return folder != null &&
checkIfEmpty(project, folder) &&
doCreateWrapper(project, sdk, folder, enableHistory, checkPlayerVersion, expressInstall);
}
private static boolean checkIfEmpty(final Project project, final VirtualFile folder) {
final VirtualFile[] children = folder.getChildren();
if (children.length > 0) {
final String[] options = {
FlexBundle.message("folder.not.empty.clear.option"),
FlexBundle.message("folder.not.empty.keep.option"),
FlexBundle.message("folder.not.empty.cancel.option")};
final int choice = Messages.showDialog(project, FlexBundle.message("folder.not.empty.clear.or.overwrite"),
TITLE, options, 0, Messages.getWarningIcon());
switch (choice) {
case 0:
// noinspection ThrowableResultOfMethodCallIgnored
final IOException exception = ApplicationManager.getApplication().runWriteAction(new NullableComputable<IOException>() {
public IOException compute() {
try {
for (VirtualFile child : children) {
child.delete(this);
}
}
catch (IOException e) {
return e;
}
return null;
}
});
if (exception != null) {
Messages.showErrorDialog(project, FlexBundle.message("failed.to.delete", exception.getMessage()), TITLE);
return false;
}
return true;
case 1:
return true;
case 2:
return false;
}
}
return true;
}
private static boolean doCreateWrapper(final Project project,
final Sdk sdk,
final VirtualFile folder,
final boolean enableHistory,
final boolean checkPlayerVersion,
final boolean expressInstall) {
final String wrapperName;
if (!FlexSdkUtils.isAirSdkWithoutFlex(sdk) && StringUtil.compareVersionNumbers(sdk.getVersionString(), "4") < 0) {
final String prefix = checkPlayerVersion
? expressInstall ? "express-installation"
: "client-side-detection"
: "no-player-detection";
wrapperName = prefix + (enableHistory ? "-with-history" : "");
}
else {
wrapperName = "swfobject";
}
final String sdkTemplatePath = sdk.getHomePath() + "/templates/" + wrapperName;
final VirtualFile sdkTemplateFolder = LocalFileSystem.getInstance().findFileByPath(sdkTemplatePath);
if (sdkTemplateFolder == null || !sdkTemplateFolder.isDirectory()) {
Messages.showErrorDialog(project, FlexBundle.message("html.wrapper.in.sdk.not.found", sdkTemplatePath), TITLE);
return false;
}
final boolean swfObjectWrapper = "swfobject".equals(sdkTemplateFolder.getName());
// noinspection ThrowableResultOfMethodCallIgnored
final IOException exception = ApplicationManager.getApplication().runWriteAction(new NullableComputable<IOException>() {
public IOException compute() {
try {
for (VirtualFile file : sdkTemplateFolder.getChildren()) {
if (swfObjectWrapper) {
if (FlexCommonUtils.HTML_WRAPPER_TEMPLATE_FILE_NAME.equals(file.getName())) {
fixAndCopyIndexTemplateHtml(file, folder, enableHistory, checkPlayerVersion, expressInstall);
continue;
}
else if ("history".equals(file.getName())) {
if (!enableHistory) {
continue;
}
}
else if (PLAYER_PRODUCT_INSTALL_SWF.equals(file.getName())) {
if (!checkPlayerVersion || !expressInstall) {
continue;
}
}
file.copy(this, folder, file.getName());
}
else {
file.copy(this, folder, file.getName());
}
}
}
catch (IOException e) {
return e;
}
return null;
}
});
if (exception != null) {
Messages.showErrorDialog(project, FlexBundle.message("html.wrapper.creation.failed", exception.getMessage()), TITLE);
return false;
}
return true;
}
/**
* For "swfobject" template only!
*/
private static void fixAndCopyIndexTemplateHtml(final VirtualFile file,
final VirtualFile folder,
final boolean enableHistory,
final boolean checkPlayerVersion,
final boolean expressInstall) throws IOException {
final String text = VfsUtilCore.loadText(file);
final String useBrowserHistory = enableHistory ? "--" : USE_BROWSER_HISTORY_MACRO;
final String major = checkPlayerVersion ? FlexCommonUtils.VERSION_MAJOR_MACRO : "0";
final String minor = checkPlayerVersion ? FlexCommonUtils.VERSION_MINOR_MACRO : "0";
final String revision = checkPlayerVersion ? FlexCommonUtils.VERSION_REVISION_MACRO : "0";
final String expressInstallSwf = checkPlayerVersion && expressInstall ? PLAYER_PRODUCT_INSTALL_SWF : "";
final String fixedText = StringUtil.replace(text,
new String[]{
USE_BROWSER_HISTORY_MACRO,
FlexCommonUtils.VERSION_MAJOR_MACRO,
FlexCommonUtils.VERSION_MINOR_MACRO,
FlexCommonUtils.VERSION_REVISION_MACRO,
EXPRESS_INSTALL_SWF_MACRO},
new String[]{useBrowserHistory, major, minor, revision, expressInstallSwf});
FlexUtils.addFileWithContent(file.getName(), fixedText, folder);
}
protected String getHelpId() {
return "flex.CreateHtmlWrapperTemplateDialog";
}
}