| /******************************************************************************* |
| * Copyright (c) 2011, 2015 EclipseSource and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * EclipseSource - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.rap.rwt.internal; |
| |
| import java.util.concurrent.atomic.AtomicReference; |
| |
| import org.eclipse.rap.rwt.internal.util.ClassUtil; |
| import org.eclipse.rap.rwt.internal.util.SharedInstanceBuffer; |
| import org.eclipse.rap.rwt.internal.util.SharedInstanceBuffer.InstanceCreator; |
| import org.eclipse.rap.rwt.service.ApplicationContext; |
| import org.eclipse.rap.rwt.service.UISession; |
| import org.eclipse.swt.internal.SerializableCompatibility; |
| |
| |
| public class SingletonManager implements SerializableCompatibility { |
| |
| private static final String ATTR_SINGLETON_MANAGER |
| = SingletonManager.class.getName() + "#instance"; |
| |
| private final SharedInstanceBuffer<Class<?>, AtomicReference<Object>> singletonHolders; |
| private InstanceCreator<Class<?>, AtomicReference<Object>> instanceCreator; |
| |
| SingletonManager() { |
| singletonHolders = new SharedInstanceBuffer<>(); |
| instanceCreator = new InstanceCreator<Class<?>, AtomicReference<Object>>() { |
| @Override |
| public AtomicReference<Object> createInstance( Class<?> key ) { |
| return new AtomicReference<>(); |
| } |
| }; |
| } |
| |
| public <T> T getSingleton( Class<T> type ) { |
| AtomicReference<T> singletonHolder = getSingletonHolder( type ); |
| synchronized( singletonHolder ) { |
| T singleton = singletonHolder.get(); |
| if( singleton == null ) { |
| singleton = ClassUtil.newInstance( type ); |
| singletonHolder.set( singleton ); |
| } |
| return singleton; |
| } |
| } |
| |
| @SuppressWarnings( "unchecked" ) |
| private <T> AtomicReference<T> getSingletonHolder( Class<T> type ) { |
| Object result = singletonHolders.get( type, instanceCreator ); |
| return ( AtomicReference<T> )result; |
| } |
| |
| public static void install( UISession uiSession ) { |
| checkNotInstalled( uiSession ); |
| uiSession.setAttribute( ATTR_SINGLETON_MANAGER, new SingletonManager() ); |
| } |
| |
| public static void install( ApplicationContext applicationContext ) { |
| checkNotInstalled( applicationContext ); |
| applicationContext.setAttribute( ATTR_SINGLETON_MANAGER, new SingletonManager() ); |
| } |
| |
| public static SingletonManager getInstance( UISession uiSession ) { |
| return ( SingletonManager )uiSession.getAttribute( ATTR_SINGLETON_MANAGER ); |
| } |
| |
| public static SingletonManager getInstance( ApplicationContext applicationContext ) { |
| return ( SingletonManager )applicationContext.getAttribute( ATTR_SINGLETON_MANAGER ); |
| } |
| |
| private static void checkNotInstalled( UISession uiSession ) { |
| if( getInstance( uiSession ) != null ) { |
| String msg = "SingletonManager already installed for UI session: " + uiSession.getId(); |
| throw new IllegalStateException( msg ); |
| } |
| } |
| |
| private static void checkNotInstalled( ApplicationContext applicationContext ) { |
| if( getInstance( applicationContext ) != null ) { |
| String msg = "SingletonManager already installed for application context"; |
| throw new IllegalStateException( msg ); |
| } |
| } |
| |
| } |