package cn.org.rapid_framework.flex.messaging.services; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import cn.org.rapid_framework.flex.messaging.annotation.RemotingObject; import flex.messaging.config.ConfigMap; import flex.messaging.services.AbstractBootstrapService; import flex.messaging.services.Service; import flex.messaging.services.ServiceException; /** * This BootstrapService is used to dynamicaly create a Remoting Service along * with its Remoting Destinations without the need for any configuration files. * * @author badqiu */ public class SpringRemotingDestinationBootstrapService extends AbstractBootstrapService { public static final String DEFAULT_INCLUDE_END_WITH_BEANS = "FlexService"; private String destChannel; private String destSecurityConstraint; private String destScope; private String destAdapter; private String destFactory; private String serviceId; private String includeEndsWithBeans; /** * Called by the <code>MessageBroker</code> after all of the server * components are created but right before they are started. This is * usually the place to create dynamic components. * * @param id Id of the <code>AbstractBootstrapService</code>. * @param properties Properties for the <code>AbstractBootstrapService</code>. */ public void initialize(String id, ConfigMap properties) { serviceId = properties.getPropertyAsString("service-id", "remoting-service"); destFactory = properties.getPropertyAsString("dest-factory", "spring"); destAdapter = properties.getProperty("dest-adapter"); destScope = properties.getProperty("dest-scope"); destSecurityConstraint = properties.getProperty("dest-security-constraint"); destChannel = properties.getPropertyAsString("dest-channel","my-amf"); includeEndsWithBeans = properties.getPropertyAsString("includeEndsWithBeans",DEFAULT_INCLUDE_END_WITH_BEANS); Service remotingService = broker.getService(serviceId); if(remotingService == null) { throw createServiceException("not found Service with serviceId:"+serviceId); } createSpringDestinations(remotingService); } private ServiceException createServiceException(String message) { ServiceException ex = new ServiceException(); ex.setMessage(message); return ex; } private void createSpringDestinations(Service remotingService) { WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(broker.getInitServletContext()); List<String> addedBeanNames = new ArrayList(); for(String beanName : wac.getBeanDefinitionNames()) { Class type = wac.getType(beanName); boolean isCreateSpringDestination = type.isAnnotationPresent(RemotingObject.class) || beanName.endsWith(includeEndsWithBeans) || isCreateDestination(beanName,type); if(isCreateSpringDestination) { createSpringDestination(remotingService, beanName); addedBeanNames.add(beanName); } } System.out.println("[Auto Export Spring to BlazeDS RemotingDestination],beanNames="+addedBeanNames); } protected boolean isCreateDestination(String beanName,Class type) { return false; } /* <!-- A verbose example using child tags. --> <destination id="sampleVerbose"> <channels> <channel ref="my-secure-amf" /> </channels> <adapter ref="java-object" /> <security> <security-constraint ref="sample-users" /> </security> <properties> <source>my.company.SampleService</source> <scope>session</scope> <factory>myJavaFactory</factory> </properties> </destination> */ protected void createSpringDestination(Service service, String destinationId) { flex.messaging.services.remoting.RemotingDestination destination = (flex.messaging.services.remoting.RemotingDestination)service.createDestination(destinationId); destination.setSource(destinationId); destination.setFactory(destFactory); if(destAdapter != null) destination.createAdapter(destAdapter); if(destScope != null) destination.setScope(destScope); if(destSecurityConstraint != null) destination.setSecurityConstraint(destSecurityConstraint); if(destChannel != null) destination.addChannel(destChannel); service.addDestination(destination); } /** * Called by the <code>MessageBroker</code> as server starts. Useful for * custom code that needs to run after all the components are initialized * and the server is starting up. */ public void start() { // No-op } /** * Called by the <code>MessageBroker</code> as server stops. Useful for * custom code that needs to run as the server is shutting down. */ public void stop() { // No-op } }