package org.fandev.sdk; import com.intellij.openapi.projectRoots.*; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.diagnostic.Logger; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import org.fandev.lang.fan.FanBundle; import org.fandev.utils.OSUtil; import org.fandev.utils.FanUtil; import org.fandev.icons.Icons; import javax.swing.*; import java.io.File; /** * @author Dror Bereznitsky * @date Jan 18, 2009 4:27:47 PM */ public class FanSdkType extends SdkType implements ApplicationComponent { private static final String FAN_SDK_NAME = "FAN_SDK"; private static final String FAN_SDK_TYPE = "FanSdkType"; public static final String FAN_LAUNCHER_WIN ="fan.exe"; public static final String FAN_LAUNCHER_UNIX = "fan"; public static final String JSTUB_WIN ="jstub.exe"; public static final String JSTUB_UNIX = "fanlaunch"; public static final String FAN_LAUNCHER_DIR = "bin"; public static final String FAN_LIB_DIR = "lib/fan"; public static final String SRC_DIR = "src"; public static final String FAN_SRC_DIR = "fan"; private static final Logger log = Logger.getInstance("org.fandev.sdk.FanSdkType"); public FanSdkType() { super(FAN_SDK_NAME); } public FanSdkType(@NonNls final String name) { super(name); } @Override public Icon getIcon() { return Icons.FAN_16; } @Override public Icon getIconForAddAction() { return getIcon(); } @Override public String getVersionString(@NotNull final String sdkHome) { FanUtil.setFanHome(sdkHome); ClassLoader cl = FanUtil.getSysClassloader(sdkHome); try { final Class podClass = Class.forName("fan.sys.Pod", true, cl); final Class versionClass = Class.forName("fan.sys.Version", true, cl); final Object o = podClass.getDeclaredMethod("find", String.class, boolean.class).invoke(null, "sys", Boolean.TRUE); final Object versionObj = podClass.getDeclaredMethod("version").invoke(o); return (String)versionClass.getDeclaredMethod("toStr").invoke(versionObj); } catch (Exception e) { log.warn("Could not determine Fantom SDK version", e); } finally { cl = null; } return ""; } public String suggestHomePath() { final String path = findFanLauncher(); if (path != null) { return path; } if (SystemInfo.isWindows){ return "C:/dev/fan"; } else if (SystemInfo.isMac){ return "/applications/fan"; } else if (SystemInfo.isUnix || SystemInfo.isLinux) { return "/usr/share/fantom"; } throw new IllegalStateException(FanBundle.message("os.not.supported")); } public boolean isValidSdkHome(final String path) { return (new File(path + File.separator + getFanLauncherPath())).exists(); } public String suggestSdkName(final String currentSdkName, final String sdkHome) { return "Fantom SDK " + getVersionString(sdkHome); } public AdditionalDataConfigurable createAdditionalDataConfigurable(final SdkModel sdkModel, final SdkModificator sdkModificator) { return new FanSdkConfigurable(); } public void saveAdditionalData(final SdkAdditionalData additionalData, final Element additional) { } public String getPresentableName() { return FanBundle.message("fan.sdk.title"); } public static FanSdkType getInstance(){ return ApplicationManager.getApplication().getComponent(FanSdkType.class); } @NotNull public String getComponentName() { return FAN_SDK_TYPE; } public void initComponent() { // init code goes here } public void disposeComponent() { // dispose code goes here } @Override public void setupSdkPaths(final Sdk sdk) { if (sdk == null) { throw new IllegalArgumentException("Sdk should not be null"); } final VirtualFile sysJar = sdk.getHomeDirectory().findFileByRelativePath("lib/java/sys.jar"); if (sysJar != null) { VirtualFile sysSources = sdk.getHomeDirectory().findFileByRelativePath("src/sys/java"); if (sysSources == null) { // For older versions of fan sysSources = sdk.getHomeDirectory().findFileByRelativePath("src/jfan"); } final SdkModificator sdkModificator = sdk.getSdkModificator(); sdkModificator.addRoot( sysJar, OrderRootType.CLASSES); if (sysSources == null) { sdkModificator.addRoot(sysSources, OrderRootType.SOURCES); } final VirtualFile extDir = getExtDir(sdk); // Add all jars in <FAN_HOME>/lib/java/ext/<OS> dir if (extDir.exists()) { for (final VirtualFile lib : extDir.getChildren()) { if ("jar".equals(lib.getExtension())) { sdkModificator.addRoot(lib, OrderRootType.CLASSES); } } } sdkModificator.commitChanges(); } } public static VirtualFile getExtDir(final Sdk sdk) { if (sdk == null) { throw new IllegalArgumentException("Sdk should not be null"); } // This needs more work. E.g., 64-bit linux, win32 versions of swt.jar // But right now these are the packaged directory names in 1.0.51 final String os = SystemInfo.isWindows ? "win32-x86" : SystemInfo.isMac ? "macosx-x86_64" : "linux-x86"; //os += SystemInfo.is32Bit ? "-x86" : "-x86_64"; return sdk.getHomeDirectory().findFileByRelativePath("lib/java/ext/" + os); } public static String getFanLauncher() { if (SystemInfo.isWindows){ return FAN_LAUNCHER_WIN; } else if (SystemInfo.isUnix){ return FAN_LAUNCHER_UNIX; } throw new IllegalStateException(FanBundle.message("os.not.supported")); } public static String getFanLauncherPath() { if (SystemInfo.isWindows){ return FAN_LAUNCHER_DIR + File.separator + FAN_LAUNCHER_WIN; } else if (SystemInfo.isUnix){ return FAN_LAUNCHER_DIR + File.separator + FAN_LAUNCHER_UNIX; } throw new IllegalStateException(FanBundle.message("os.not.supported")); } public static String getJStubPath() { if (SystemInfo.isWindows){ return FAN_LAUNCHER_DIR + File.separator + JSTUB_WIN; } else if (SystemInfo.isUnix){ return FAN_LAUNCHER_DIR + File.separator + JSTUB_UNIX; } throw new IllegalStateException(FanBundle.message("os.not.supported")); } public static String getFanLibDir() { return FAN_LIB_DIR; } public static String getSrcDir() { return SRC_DIR; } public static String getFanSrcDir() { return FAN_SRC_DIR; } @Nullable private static String findFanLauncher() { final String exePath = getFanLauncherPath(); final String interpreterName = getFanLauncher(); final String pathByName = OSUtil.findExecutableByName(interpreterName); if (pathByName == null) { return null; } return pathByName.endsWith(exePath) ? pathByName.substring(0, pathByName.length() - exePath.length()) : null; } }