/* Copyright (C) 2001, 2006 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. */ package gov.nasa.worldwind; import gov.nasa.worldwind.avlist.*; import gov.nasa.worldwind.cache.*; import gov.nasa.worldwind.exception.WWRuntimeException; import gov.nasa.worldwind.retrieve.RetrievalService; import gov.nasa.worldwind.util.*; import java.util.logging.Level; import java.beans.PropertyChangeListener; /** * @author Tom Gaskins * @version $Id: WorldWind.java 5113 2008-04-21 23:46:50Z tgaskins $ */ public final class WorldWind { public static final String SHUTDOWN_EVENT = "gov.nasa.worldwind.ShutDown"; private static WorldWind instance = new WorldWind(); private WWObjectImpl wwo; private MemoryCacheSet memoryCacheSet; private FileCache dataFileCache; private RetrievalService retrievalService; private TaskService taskService; private NetworkStatus networkStatus; private WorldWind() // Singleton, prevent public instantiation. { this.initialize(); } private void initialize() { this.wwo = new WWObjectImpl(); this.retrievalService = (RetrievalService) createConfigurationComponent(AVKey.RETRIEVAL_SERVICE_CLASS_NAME); this.taskService = (TaskService) createConfigurationComponent(AVKey.TASK_SERVICE_CLASS_NAME); this.dataFileCache = (FileCache) createConfigurationComponent(AVKey.DATA_FILE_CACHE_CLASS_NAME); this.memoryCacheSet = (MemoryCacheSet) createConfigurationComponent(AVKey.MEMORY_CACHE_SET_CLASS_NAME); this.networkStatus = (NetworkStatus) createConfigurationComponent(AVKey.NETWORK_STATUS_CLASS_NAME); } private void dispose() { if (this.taskService != null) this.taskService.shutdown(true); if (this.retrievalService != null) this.retrievalService.shutdown(true); if (this.memoryCacheSet != null) this.memoryCacheSet.clear(); } /** * Reinitialize World Wind to its initial ready state. Shut down and restart all World Wind services and clear all * World Wind memory caches. Cache memory will be released at the next JVM garbage collection. * <p/> * Call this method to reduce World Wind's current resource usage to its initial, empty state. This is typically * required by applets when the user leaves the applet page. * <p/> * World Wind can continue to be used after calling this method. The state of any existing World Wind drawables is * subsequently indeterminate and they should be disposed. */ public static synchronized void shutDown() { instance.wwo.firePropertyChange(SHUTDOWN_EVENT, null, -1); instance.dispose(); instance = new WorldWind(); instance.initialize(); } public static MemoryCacheSet getMemoryCacheSet() { return instance.memoryCacheSet; } public static synchronized MemoryCache getMemoryCache(String key) { return instance.memoryCacheSet.getCache(key); } public static FileCache getDataFileCache() { return instance.dataFileCache; } public static RetrievalService getRetrievalService() { return instance.retrievalService; } public static TaskService getTaskService() { return instance.taskService; } public static NetworkStatus getNetworkStatus() { return instance.networkStatus; } /** * Indicates whether World Wind will attempt to connect to the network to retrieve data or for other reasons. * * @return <code>true</code> if World Wind is in off-line mode, <code>false</code> if not. * @see NetworkStatus */ public static boolean isOfflineMode() { return getNetworkStatus().isOfflineMode(); } /** * Indicate whether World Wind should attempt to connect to the network to retrieve data or for other reasons. The * default value for this attribute is <code>false</code>, indicating that the network should be used. * * @param offlineMode <code>true</code> if World Wind should use the network, <code>false</code> otherwise * @see NetworkStatus */ public static void setOfflineMode(boolean offlineMode) { getNetworkStatus().setOfflineMode(offlineMode); } /** * @param className the full name, including package names, of the component to create * @return the new component * @throws WWRuntimeException if the <code>Object</code> could not be created * @throws IllegalArgumentException if <code>className</code> is null or zero length */ public static Object createComponent(String className) throws WWRuntimeException { if (className == null || className.length() == 0) { Logging.logger().severe("WorldWind.ClassNameKeyNulZero"); throw new IllegalArgumentException(Logging.getMessage("WorldWind.ClassNameKeyNulZero")); } try { Class c = Class.forName(className.trim()); return c.newInstance(); } catch (Exception e) { Logging.logger().log(Level.SEVERE, "WorldWind.ExceptionCreatingComponent", className); throw new WWRuntimeException(Logging.getMessage("WorldWind.ExceptionCreatingComponent", className), e); } catch (Throwable t) { Logging.logger().log(Level.SEVERE, "WorldWind.ErrorCreatingComponent", className); throw new WWRuntimeException(Logging.getMessage("WorldWind.ErrorCreatingComponent", className), t); } } /** * @param classNameKey the key identifying the component * @return the new component * @throws IllegalStateException if no name could be found which corresponds to <code>classNameKey</code> * @throws IllegalArgumentException if <code>classNameKey<code> is null * @throws WWRuntimeException if the component could not be created */ public static Object createConfigurationComponent(String classNameKey) throws IllegalStateException, IllegalArgumentException { if (classNameKey == null) { Logging.logger().severe("WorldWind.ClassNameKeyNulZero"); throw new IllegalArgumentException(Logging.getMessage("WorldWind.ClassNameKeyNulZero")); } String name = Configuration.getStringValue(classNameKey); if (name == null) { Logging.logger().log(Level.SEVERE, "WorldWind.NoClassNameInConfigurationForKey", classNameKey); throw new WWRuntimeException( Logging.getMessage("WorldWind.NoClassNameInConfigurationForKey", classNameKey)); } try { return WorldWind.createComponent(name.trim()); } catch (Throwable e) { Logging.logger().log(Level.SEVERE, "WorldWind.UnableToCreateClassForConfigurationKey", name); throw new IllegalStateException( Logging.getMessage("WorldWind.UnableToCreateClassForConfigurationKey", name), e); } } public static void setValue(String key, String value) { instance.wwo.setValue(key, value); } public static Object getValue(String key) { return instance.wwo.getValue(key); } public static String getStringValue(String key) { return instance.wwo.getStringValue(key); } public static boolean hasKey(String key) { return instance.wwo.hasKey(key); } public static void removeKey(String key) { instance.wwo.removeKey(key); } public static void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { instance.wwo.addPropertyChangeListener(propertyName, listener); } public static void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { instance.wwo.removePropertyChangeListener(propertyName, listener); } public static void addPropertyChangeListener(PropertyChangeListener listener) { instance.wwo.addPropertyChangeListener(listener); } public static void removePropertyChangeListener(PropertyChangeListener listener) { instance.wwo.removePropertyChangeListener(listener); } }