package com.morcinek.android.codegenerator.plugin.actions; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.vfs.VirtualFile; import com.morcinek.android.codegenerator.codegeneration.providers.ResourceProvidersFactory; import com.morcinek.android.codegenerator.plugin.actions.visibility.ActionVisibilityHelper; import com.morcinek.android.codegenerator.plugin.codegenerator.CodeGeneratorController; import com.morcinek.android.codegenerator.plugin.error.ErrorHandler; import com.morcinek.android.codegenerator.plugin.persistence.Settings; import com.morcinek.android.codegenerator.plugin.ui.CodeDialogBuilder; import com.morcinek.android.codegenerator.plugin.ui.DialogsFactory; import com.morcinek.android.codegenerator.plugin.ui.StringResources; import com.morcinek.android.codegenerator.plugin.utils.ClipboardHelper; import com.morcinek.android.codegenerator.plugin.utils.PackageHelper; import com.morcinek.android.codegenerator.plugin.utils.PathHelper; import com.morcinek.android.codegenerator.plugin.utils.ProjectHelper; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathExpressionException; import java.io.IOException; /** * Copyright 2014 Tomasz Morcinek. All rights reserved. */ public abstract class LayoutAction extends AnAction { private final ErrorHandler errorHandler = new ErrorHandler(); private final PackageHelper packageHelper = new PackageHelper(); private final ProjectHelper projectHelper = new ProjectHelper(); private final PathHelper pathHelper = new PathHelper(); @Override public void actionPerformed(AnActionEvent event) { Project project = getEventProject(event); VirtualFile selectedFile = event.getData(PlatformDataKeys.VIRTUAL_FILE); Settings settings = Settings.getInstance(project); try { showCodeDialog(event, project, selectedFile, settings); } catch (Exception exception) { errorHandler.handleError(project, exception); } } private void showCodeDialog(AnActionEvent event, final Project project, final VirtualFile selectedFile, Settings settings) throws ParserConfigurationException, SAXException, XPathExpressionException, IOException { CodeGeneratorController codeGeneratorController = new CodeGeneratorController(getTemplateName(), getResourceProvidersFactory()); String generatedCode = codeGeneratorController.generateCode(project, selectedFile, event.getData(PlatformDataKeys.EDITOR)); final CodeDialogBuilder codeDialogBuilder = new CodeDialogBuilder(project, String.format(StringResources.TITLE_FORMAT_TEXT, selectedFile.getName()), generatedCode); codeDialogBuilder.addSourcePathSection(projectHelper.getSourceRootPathList(project, event), settings.getSourcePath()); codeDialogBuilder.addPackageSection(packageHelper.getPackageName(project, event)); codeDialogBuilder.addAction(StringResources.COPY_ACTION_LABEL, new Runnable() { @Override public void run() { ClipboardHelper.copy(getFinalCode(codeDialogBuilder)); codeDialogBuilder.closeDialog(); } }); codeDialogBuilder.addAction(StringResources.CREATE_ACTION_LABEL, new Runnable() { @Override public void run() { try { createFileWithGeneratedCode(codeDialogBuilder, selectedFile, project); } catch (IOException exception) { errorHandler.handleError(project, exception); } } }, true); if (codeDialogBuilder.showDialog() == DialogWrapper.OK_EXIT_CODE) { settings.setSourcePath(codeDialogBuilder.getSourcePath()); } } private void createFileWithGeneratedCode(CodeDialogBuilder codeDialogBuilder, VirtualFile selectedFile, Project project) throws IOException { if (codeDialogBuilder.getSourcePath() == null) { DialogsFactory.showMissingSourcePathDialog(project); } else { String folderPath = getFolderPath(codeDialogBuilder); String fileName = pathHelper.getFileName(selectedFile.getName(), getResourceName()); if (!projectHelper.fileExists(project, fileName, folderPath)) { createOrOverrideFileWithGeneratedCode(codeDialogBuilder, project, folderPath, fileName); } else { if (DialogsFactory.openOverrideFileDialog(project, folderPath, fileName)) { createOrOverrideFileWithGeneratedCode(codeDialogBuilder, project, folderPath, fileName); } } } } private void createOrOverrideFileWithGeneratedCode(CodeDialogBuilder codeDialogBuilder, Project project, String folderPath, String fileName) throws IOException { String finalCode = getFinalCode(codeDialogBuilder); VirtualFile createdFile = projectHelper.createOrFindFile(project, fileName, folderPath); projectHelper.setFileContent(project, createdFile, finalCode); codeDialogBuilder.closeDialog(); } protected abstract String getResourceName(); protected abstract String getTemplateName(); protected abstract ResourceProvidersFactory getResourceProvidersFactory(); private String getFolderPath(CodeDialogBuilder codeDialogBuilder) { String sourcePath = codeDialogBuilder.getSourcePath(); String packageName = codeDialogBuilder.getPackage(); return pathHelper.getFolderPath(sourcePath, packageName); } private String getFinalCode(CodeDialogBuilder codeDialogBuilder) { String packageName = codeDialogBuilder.getPackage(); String modifiedCode = codeDialogBuilder.getModifiedCode(); return pathHelper.getMergedCodeWithPackage(packageName, modifiedCode); } @Override public void update(AnActionEvent event) { event.getPresentation().setVisible(new ActionVisibilityHelper("layout", "xml").isVisible(event.getDataContext())); } }