package org.jetbrains.plugins.ruby.motion.bridgesupport; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.reference.SoftReference; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.ruby.motion.symbols.MotionSymbolUtil; import java.io.IOException; import java.util.Set; public class FrameworkInfo { private static final Logger LOG = Logger.getInstance(FrameworkInfo.class); @NotNull private final String myBridgeSupportPath; @NotNull private final String myName; @NotNull private final String myVersion; private final boolean myOSX; private SoftReference<Framework> myFramework = null; private SoftReference<Set<String>> myIdSelectorNames = null; private SoftReference<Set<String>> mySelectorNames = null; public FrameworkInfo(@NotNull String name, @NotNull String version, boolean isOSX, @NotNull String bridgeSupportFilePath) { myBridgeSupportPath = bridgeSupportFilePath; myName = name; myOSX = isOSX; myVersion = version; } @NotNull public String getName() { return myName; } @Nullable public synchronized Framework getFramework() { Framework result = SoftReference.dereference(myFramework); return result != null ? result : reloadFramework().first; } @Nullable public synchronized Set<String> getIdSelectorNames() { Set<String> result = SoftReference.dereference(myIdSelectorNames); return result != null ? result : reloadFramework().second; } @Nullable public synchronized Set<String> getSelectorNames() { Set<String> result = SoftReference.dereference(mySelectorNames); return result != null ? result : reloadFramework().third; } private Trinity<Framework, Set<String>, Set<String>> reloadFramework() { VirtualFile file = LocalFileSystem.getInstance().findFileByPath(myBridgeSupportPath); if (file == null) return Trinity.create(null, null, null); Set<String> idSelectorNames = null; Set<String> selectorNames = null; Framework framework = null; try { framework = BridgeSupportReader.read(myName, myVersion, file.getInputStream(), myOSX); idSelectorNames = ContainerUtil.newHashSet(); selectorNames = ContainerUtil.newHashSet(); for (Class clazz : framework.getClasses()) { for (Function function : clazz.getFunctions()) { if (function.isId()) { idSelectorNames.addAll(MotionSymbolUtil.getSelectorNames(function)); } selectorNames.add(function.getName()); } } } catch (IOException e) { LOG.error("Failed to load bridgesupport file", e); } myFramework = framework != null ? new SoftReference<>(framework) : null; myIdSelectorNames = idSelectorNames != null ? new SoftReference<>(idSelectorNames) : null; mySelectorNames = selectorNames != null ? new SoftReference<>(selectorNames) : null; return Trinity.create(framework, idSelectorNames, selectorNames); } }