package org.ripla.rap; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.internal.application.ApplicationContextImpl; import org.eclipse.rap.rwt.internal.theme.Theme; import org.eclipse.rap.rwt.internal.theme.ThemeManager; import org.eclipse.rap.rwt.service.ResourceLoader; @SuppressWarnings("restriction") public class ThemeManagerHelper { private static ThemeManager themeManager; static { replaceStandardResourceLoader(); } public static void adaptApplicationContext(final Object toAdapt) { if (toAdapt instanceof ApplicationContextImpl) { ensureThemeManager(); ((ApplicationContextImpl) toAdapt).setThemeManager(themeManager); } } public static void resetThemeManager() { if (isThemeManagerAvailable()) { doThemeManagerReset(); } } public static void resetThemeManagerIfNeeded() { if (isThemeManagerResetNeeded()) { doThemeManagerReset(); } } public static void replaceStandardResourceLoader() { ThemeManager.STANDARD_RESOURCE_LOADER = new TestResourceLoader(); } private static void ensureThemeManager() { if (themeManager == null) { themeManager = new TestThemeManager(); } } private static void doThemeManagerReset() { ((TestThemeManager) themeManager).resetInstanceInTestCases(); } private static boolean isThemeManagerResetNeeded() { boolean result = isThemeManagerAvailable(); if (result) { final List<String> registeredThemeIds = Arrays.asList(themeManager .getRegisteredThemeIds()); if (registeredThemeIds.size() == 2) { result = !registeredThemeIds .contains(ThemeManager.FALLBACK_THEME_ID) || !registeredThemeIds.contains(RWT.DEFAULT_THEME_ID); } } return result; } private static boolean isThemeManagerAvailable() { return themeManager != null; } public static class TestThemeManager extends ThemeManager { boolean initialized; boolean activated; boolean deactivated; @Override public void initialize() { if (!initialized) { // Register empty default theme. Execute tests against fall-back // theme. final Theme lTheme = new Theme(RWT.DEFAULT_THEME_ID, "RAP Default Theme", null); // addThemeableWidget(Button.class, new TestResourceLoader()); // lTheme.initialize(getThemeableWidget()); registerTheme(lTheme); initialized = true; } } @Override public void activate() { if (!activated) { super.activate(); activated = true; } deactivated = false; } @Override public void deactivate() { // ignore reset for test cases to improve performance deactivated = true; } @Override public String[] getRegisteredThemeIds() { String[] result = new String[0]; if (!deactivated) { result = super.getRegisteredThemeIds(); } return result; } public void resetInstanceInTestCases() { initialized = false; activated = false; super.deactivate(); } } // TODO [ApplicationContext]: Used as performance optimized solution for // tests. At the time being // buffering speeds up RWTAllTestSuite about 10% on my machine. Think about // a less intrusive // solution. private static class TestResourceLoader implements ResourceLoader { private final ClassLoader classLoader = ThemeManager.class .getClassLoader(); private final Map<String, StreamBuffer> resourceStreams = new HashMap<String, StreamBuffer>(); @Override public InputStream getResourceAsStream(final String name) throws IOException { StreamBuffer result = resourceStreams.get(name); if (!hasStreamBuffer(result)) { result = bufferStream(name); } else { result.reset(); } return result; } private StreamBuffer bufferStream(final String name) { StreamBuffer result = null; final InputStream in = classLoader.getResourceAsStream(name); if (in != null) { result = new StreamBuffer(in); result.mark(Integer.MAX_VALUE); resourceStreams.put(name, result); } return result; } private boolean hasStreamBuffer(final StreamBuffer result) { return result != null; } } private static class StreamBuffer extends BufferedInputStream { private StreamBuffer(final InputStream in) { super(in); } @Override public void close() throws IOException { } } }