package com.atsebak.embeddedlinuxjvm.project; import com.atsebak.embeddedlinuxjvm.localization.EmbeddedLinuxJVMBundle; import com.atsebak.embeddedlinuxjvm.ui.EmbeddedJavaModuleStep; import com.atsebak.embeddedlinuxjvm.utils.FileUtilities; import com.atsebak.embeddedlinuxjvm.utils.ProjectUtils; import com.atsebak.embeddedlinuxjvm.utils.Template; import com.google.common.io.Files; import com.intellij.icons.AllIcons; import com.intellij.ide.util.projectWizard.JavaModuleBuilder; import com.intellij.ide.util.projectWizard.ModuleWizardStep; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.Disposable; import com.intellij.openapi.module.JavaModuleType; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.module.StdModuleTypes; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectType; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.PsiTestUtil; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.SneakyThrows; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.regex.Pattern; @Getter @Setter @NoArgsConstructor public class RPiJavaModuleBuilder extends JavaModuleBuilder { private static final ProjectType PI_PROJECT_TYPE = new ProjectType("PI_JAVA"); private static final String PROJECT_NAME = "Raspberry PI"; private String packageName; @Nullable private File[] jarsToAdd; private boolean noLibrariesNeeded; /** * Used to define the hierachy of the project definition * * @param rootModel * @throws ConfigurationException */ @Override public void setupRootModel(final ModifiableRootModel rootModel) throws ConfigurationException { super.setupRootModel(rootModel); final Project project = rootModel.getProject(); final VirtualFile root = createAndGetContentEntry(); rootModel.addContentEntry(root); if (myJdk != null) { rootModel.setSdk(myJdk); } else { rootModel.inheritSdk(); } createProjectFiles(rootModel, project); } /** * Runs a new thread to create the required files * * @param rootModel * @param project */ private void createProjectFiles(@NotNull final ModifiableRootModel rootModel,@NotNull final Project project) { ProjectUtils.runWhenInitialized(project, new DumbAwareRunnable() { public void run() { String srcPath = project.getBasePath() + File.separator + "src"; addJarFiles(rootModel.getModule()); String[] directoriesToMake = packageName.split(Pattern.quote(".")); for (String directory : directoriesToMake) { try { VfsUtil.createDirectories(srcPath + FileUtilities.SEPARATOR + directory); } catch (IOException e) { } srcPath += FileUtilities.SEPARATOR + directory; } Template.builder().name(getMainClassTemplateName()) .classContext(this.getClass()) .outputFile(srcPath + FileUtilities.SEPARATOR + "Main.java") .data(new HashMap<String, Object>() {{ put("packagename", packageName); }}).build() .toFile(); ProjectUtils.addProjectConfiguration(rootModel.getModule(), packageName + ".Main", getPresentableName()); } }); } /** * Creates directory for project * @return */ private VirtualFile createAndGetContentEntry() { String path = FileUtil.toSystemIndependentName(getContentEntryPath()); new File(path).mkdirs(); return LocalFileSystem.getInstance().refreshAndFindFileByPath(path); } /** * Returns the Module type * @return */ @Override public ModuleType getModuleType() { return StdModuleTypes.JAVA; } /** * Big icon is Java modules * @return */ @Override public Icon getBigIcon() { return AllIcons.Modules.Types.JavaModule; } /** * The icon displayed in the project creator dialog * @return */ @Override public Icon getNodeIcon() { return IconLoader.findIcon("/pi.png"); } /** * Build for module * @return */ @Override public String getBuilderId() { return getClass().getName(); } /** * Module name * @return */ @Override public String getPresentableName() { return PROJECT_NAME; } /** * Parent group in project creator dialog * @return */ @Override public String getParentGroup() { return JavaModuleType.BUILD_TOOLS_GROUP; } /** * get weight * @return */ @Override public int getWeight() { return JavaModuleBuilder.BUILD_SYSTEM_WEIGHT; } /** * Help description of the module * @return */ @Override public String getDescription() { return EmbeddedLinuxJVMBundle.getString("pi.project.description"); } /** * Setup module with PI4J * * @param module * @throws ConfigurationException */ @SneakyThrows(IOException.class) @Override protected void setupModule(Module module) throws ConfigurationException { super.setupModule(module); if(!noLibrariesNeeded) { final String libPath = module.getProject().getBasePath() + File.separator + "lib"; VfsUtil.createDirectories(libPath); File outputFiles = new File(libPath); FileUtilities.unzip(getClass().getResourceAsStream("/pi4j.zip"), outputFiles.getAbsolutePath()); jarsToAdd = outputFiles.listFiles(); } } /** * Project Type * @return */ @Override protected ProjectType getProjectType() { return PI_PROJECT_TYPE; } private void addJarFiles(Module module) { if (jarsToAdd == null) { return; } for (final File fileEntry : jarsToAdd) { if (!fileEntry.isDirectory() && Files.getFileExtension(fileEntry.getName()).contains("jar")) { PsiTestUtil.addLibrary(module, fileEntry.getName(), fileEntry.getParentFile().getPath(), fileEntry.getName()); } } } /** * Adds a custom wizard GUI * @param context * @param parentDisposable * @return */ @Nullable @Override public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) { EmbeddedJavaModuleStep step = new EmbeddedJavaModuleStep(this); Disposer.register(parentDisposable, step); return step; } /** * Not Needed * @param list */ @Override public void setSourcePaths(List<Pair<String, String>> list) { } /** * Not Needed * @param pair */ @Override public void addSourcePath(Pair<String, String> pair) { } /** * gets file marker file name * @return */ public String getMainClassTemplateName() { return "rpimain.ftl"; } }