package com.cedricziel.idea.typo3.util; import com.cedricziel.idea.typo3.domain.TYPO3ExtensionDefinition; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.StreamUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.file.PsiDirectoryFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.List; import java.util.Map; public class ExtensionFileGenerationUtil { /** * @param templateFile Name of the generated file * @param context Template Context variables */ public static String readTemplateToString(@NotNull String templateFile, @NotNull Map<String, String> context) { String template = getFileTemplateContent("/resources/fileTemplates/" + templateFile); if (template == null) { // empty template file, this should never happen. return ""; } for (Map.Entry<String, String> entry : context.entrySet()) { String variableValue = entry.getValue(); if (variableValue == null) { variableValue = ""; } template = template.replace("{{ " + entry.getKey() + " }}", variableValue); } return template; } /** * @param templateFile Name of the generated file * @param destinationPath Relative path to the target file system entry * @param extensionDefinition Extension definition containing all relevant metadata * @param context Template Context variables * @param project Project in context */ public static PsiElement fromTemplate(@NotNull String templateFile, @NotNull String destinationPath, @NotNull String destinationFileName, @NotNull TYPO3ExtensionDefinition extensionDefinition, @NotNull Map<String, String> context, Project project) { String template = readTemplateToString(templateFile, context); VirtualFile targetDirectory = getOrCreateDestinationPath(extensionDefinition.getRootDirectory(), destinationPath); PsiFile fileFromText = PsiFileFactory.getInstance(project).createFileFromText(destinationFileName, FileTypes.PLAIN_TEXT, template); CodeStyleManager.getInstance(project).reformat(fileFromText); return PsiDirectoryFactory .getInstance(project) .createDirectory(targetDirectory) .add(fileFromText); } /** * Appends a string to a new or existing file * * @param templateString The string to append. Variables with '{{ varname }}' syntax are substituted from context * @param destinationPath Relative path inside the extension directory folder * @param destinationFileName The file name * @param extensionDefinition The containing extension * @param context Template variable map * @param project Current project * @return The created or modified file */ public static VirtualFile appendOrCreate(@NotNull String templateString, @NotNull String destinationPath, @NotNull String destinationFileName, @NotNull TYPO3ExtensionDefinition extensionDefinition, @NotNull Map<String, String> context, Project project) { for (Map.Entry<String, String> entry : context.entrySet()) { templateString = templateString.replace("{{ " + entry.getKey() + " }}", entry.getValue()); } VirtualFile targetDirectory = getOrCreateDestinationPath(extensionDefinition.getRootDirectory(), destinationPath); if (targetDirectory == null) { return null; } VirtualFile[] children = targetDirectory.getChildren(); VirtualFile targetFile = null; for (VirtualFile file : children) { if (!file.isDirectory() && file.getName().equals(destinationFileName)) { targetFile = file; } } if (targetFile == null) { PsiFile fileFromText = PsiFileFactory.getInstance(project).createFileFromText(destinationFileName, FileTypes.PLAIN_TEXT, templateString); CodeStyleManager.getInstance(project).reformat(fileFromText); PsiDirectoryFactory .getInstance(project) .createDirectory(targetDirectory) .add(fileFromText); return fileFromText.getVirtualFile(); } PsiFile file = PsiManager.getInstance(project).findFile(targetFile); if (file == null) { return null; } PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); Document document = documentManager.getDocument(file); if (document == null) { return null; } String content = document.getText(); StringBuilder contentSb = new StringBuilder(content); contentSb .append("\n") .append(templateString); document.setText(contentSb); return file.getVirtualFile(); } private static VirtualFile getOrCreateDestinationPath(VirtualFile rootDirectory, String destinationPath) { try { return VfsUtil.createDirectoryIfMissing(rootDirectory, destinationPath); } catch (IOException e) { e.printStackTrace(); } return null; } @Nullable private static String getFileTemplateContent(@NotNull String filename) { try { return StreamUtil .readText(ExtensionFileGenerationUtil.class.getResourceAsStream(filename), "UTF-8") .replace("\r\n", "\n"); } catch (IOException e) { return null; } } public static boolean extensionHasFile(TYPO3ExtensionDefinition extensionDefinition, String filename) { List<VirtualFile> childFiles = VfsUtil.collectChildrenRecursively(extensionDefinition.getRootDirectory()); for (VirtualFile file : childFiles) { if (file.getPath().contains(filename)) { return true; } } return false; } }