Created
October 27, 2014 07:28
-
-
Save kthoms/ef75065631786908e022 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.rhenus.fl.frame.server.services; | |
import org.eclipse.core.runtime.IProgressMonitor; | |
import org.eclipse.core.runtime.IStatus; | |
import org.eclipse.core.runtime.Status; | |
import org.eclipse.core.runtime.jobs.Job; | |
import org.eclipse.scout.commons.logger.IScoutLogger; | |
import org.eclipse.scout.commons.logger.ScoutLogManager; | |
import org.eclipse.scout.rt.server.IServerSession; | |
import org.eclipse.scout.rt.server.IServerSessionProvider; | |
import org.eclipse.scout.rt.server.ServerJob; | |
import org.eclipse.scout.rt.server.ThreadContext; | |
import org.eclipse.scout.rt.server.services.ServerServiceFactory; | |
import org.eclipse.scout.rt.shared.OfflineState; | |
import org.eclipse.scout.rt.shared.TierState; | |
import org.eclipse.scout.rt.shared.TierState.Tier; | |
import org.eclipse.scout.service.CreateServiceImmediatelySchedulingRule; | |
import org.eclipse.scout.service.IService; | |
import org.eclipse.scout.service.IService2; | |
import org.eclipse.scout.service.IServiceFactory; | |
import org.eclipse.scout.service.ServiceConstants; | |
import org.eclipse.scout.service.ServiceUtility; | |
import org.osgi.framework.Bundle; | |
import org.osgi.framework.ServiceRegistration; | |
import org.springframework.context.ApplicationContext; | |
/** | |
* Copied from org.eclipse.scout.rt.server.services.ServerServiceFactory. Extends the class | |
* by the capability to instantiate services through spring. | |
* <p> | |
* | |
* Service factory handling server services based on a {@link IServerSession}. | |
* The service exists once per osgi environment and is cached persistent. The | |
* service is only available within a {@link Job} that implements | |
* {@link IServerSessionProvider} with a compatible {@link IServerSession} type | |
* or within a thread with {@link ThreadContext#getServerSession()}!=null see | |
* {@link ServerJob} | |
* <p> | |
* The factory supports {@link ServiceConstants#SERVICE_SCOPE} with an | |
* {@link IServerSession} class.<br> | |
* The factory supports {@link ServiceConstants#SERVICE_CREATE_IMMEDIATELY} | |
* <p> | |
* Visiblity: ServerJob.getCurrentSession()!=null && (BE || OFF), see also | |
* {@link IService} for details | |
*/ | |
@SuppressWarnings("rawtypes") | |
public abstract class AbstractSpringAwareServerServiceFactory implements IServiceFactory { | |
private static final IScoutLogger LOG = ScoutLogManager | |
.getLogger(ServerServiceFactory.class); | |
private Bundle m_bundle; | |
private Class<?> m_serviceClass; | |
private String m_sessionType; | |
private Class<? extends IServerSession> m_sessionClass; | |
// lazy creation | |
private Object m_service; | |
private Object m_serviceLock = new Object(); | |
public AbstractSpringAwareServerServiceFactory(Class<?> serviceClass) { | |
if (serviceClass == null) { | |
throw new IllegalArgumentException("service type must not be null"); | |
} | |
if (serviceClass.isInterface()) { | |
throw new IllegalArgumentException( | |
"service type must not be an interface: " + serviceClass); | |
} | |
m_serviceClass = serviceClass; | |
} | |
@Override | |
public void serviceRegistered(final ServiceRegistration registration) | |
throws Throwable { | |
Boolean createImmediately = (Boolean) registration.getReference() | |
.getProperty(ServiceConstants.SERVICE_CREATE_IMMEDIATELY); | |
if (createImmediately != null && createImmediately) { | |
Job job = new Job("create service " | |
+ m_serviceClass.getSimpleName()) { | |
@Override | |
protected IStatus run(IProgressMonitor monitor) { | |
updateClassCache(registration); | |
updateInstanceCache(registration); | |
return Status.OK_STATUS; | |
} | |
}; | |
job.setRule(new CreateServiceImmediatelySchedulingRule()); | |
job.schedule(); | |
} | |
} | |
@Override | |
public Object getService(Bundle bundle, ServiceRegistration registration) { | |
updateClassCache(registration); | |
IServerSession session = ServerJob.getCurrentSession(m_sessionClass); | |
if (session != null) { | |
if (TierState.get() == Tier.BackEnd | |
|| TierState.get() == Tier.Undefined | |
|| OfflineState.isOfflineInCurrentThread()) { | |
updateInstanceCache(registration); | |
return m_service; | |
} | |
} | |
return ServiceUtility.NULL_SERVICE; | |
} | |
@Override | |
public void ungetService(Bundle bundle, ServiceRegistration registration, | |
Object service) { | |
} | |
@SuppressWarnings("unchecked") | |
private void updateClassCache(ServiceRegistration registration) { | |
synchronized (m_serviceLock) { | |
if (m_bundle == null) { | |
m_bundle = registration.getReference().getBundle(); | |
} | |
if (m_sessionType == null) { | |
m_sessionType = (String) registration.getReference() | |
.getProperty(ServiceConstants.SERVICE_SCOPE); | |
} | |
try { | |
if (m_sessionClass == null) { | |
if (m_sessionType == null) { | |
m_sessionClass = IServerSession.class; | |
} else { | |
m_sessionClass = (Class<? extends IServerSession>) m_bundle | |
.loadClass(m_sessionType); | |
if (!IServerSession.class | |
.isAssignableFrom(m_sessionClass)) { | |
throw new IllegalArgumentException( | |
"session type must be a subtype of " | |
+ IServerSession.class + ": " | |
+ m_sessionType); | |
} | |
} | |
} | |
} catch (Throwable t) { | |
LOG.error("Failed creating class of " + m_serviceClass, t); | |
} | |
} | |
} | |
private void updateInstanceCache(ServiceRegistration registration) { | |
synchronized (m_serviceLock) { | |
if (m_service == null) { | |
try { | |
// CUSTOMIZING BEGIN | |
// m_service = m_serviceClass.newInstance(); | |
m_service = getContext().getBean(m_serviceClass); | |
// CUSTOMIZING END | |
if (m_service instanceof IService2) { | |
((IService2) m_service).initializeService(registration); | |
} else if (m_service instanceof IService) { | |
((IService) m_service).initializeService(registration); | |
} | |
} catch (Throwable t) { | |
LOG.error("Failed creating instance of " + m_serviceClass, | |
t); | |
} | |
} | |
} | |
} | |
// CUSTOMIZING BEGIN | |
protected abstract ApplicationContext getContext(); | |
// CUSTOMIZING END | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment