estava vendo o funcionamento do AMFPHP, onde verifiquei que o mapeamento das classes são flexíveis, onde posso ter múltiplas classes mapeadas, enquanto no granite, eu tinha que mapear apenas uma única classe de cada vez... mas segundo a sugestão repassada, tem como deixar o Granite funcionando de forma similar ao AMFPHP, que em tese é mais fácil de reutilizar o mapeamento...
a dica está nesse [link flex-brasil]
onde é sugerido a alteração da classe: org.granite.messaging.service.SimpleServiceFactory.java
para que o Granite possa ser utilizado de forma flexível:
classe original:
package org.granite.messaging.service;
import flex.messaging.messages.RemotingMessage;
import org.granite.config.flex.Destination;
import org.granite.context.GraniteContext;
import java.util.Collections;
import java.util.Map;
/**
* @author Franck WOLFF
*/
public class SimpleServiceFactory extends ServiceFactory {
@Override
public ServiceInvoker<?> getServiceInstance(RemotingMessage request) throws ServiceException {
String messageType = request.getClass().getName();
String destinationId = request.getDestination();
GraniteContext context = GraniteContext.getCurrentInstance();
Destination destination = context.getServicesConfig().findDestinationById(messageType, destinationId);
if (destination == null)
throw new ServiceException("No matching destination: " + destinationId);
String scope = (String)destination.getProperties().get("scope");
Map<String, Object> cache = null;
if (scope == null || "request".equals(scope))
cache = context.getRequestMap();
else if ("session".equals(scope))
cache = context.getSessionMap();
else if ("application".equals(scope))
cache = Collections.synchronizedMap(context.getApplicationMap());
else
throw new ServiceException("Illegal scope in destination: " + destination);
String key = SimpleServiceInvoker.class.getName() + '.' + destination.getId();
SimpleServiceInvoker service = (SimpleServiceInvoker)cache.get(key);
if (service == null) {
service = new SimpleServiceInvoker(destination, this);
cache.put(key, service);
}
return service;
}
}
classe alterada:
package org.granite.messaging.service;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.granite.config.flex.Destination;
import org.granite.context.GraniteContext;
import flex.messaging.messages.RemotingMessage;
/**
* @author Franck WOLFF
* @author Erko Bridee de Almeida Cabrera
*
* Alterações da classe para possibilitar um mapeamento
* flexivel para qualquer classe do projeto
*
* * dica do link:
* http://br.groups.yahoo.com/group/flex-brasil/message/7933
* - Graniteds com unico mapeamento de Classe
*
*/
public class SimpleServiceFactory extends ServiceFactory {
@Override
public ServiceInvoker<?> getServiceInstance(RemotingMessage request) throws ServiceException {
String messageType = request.getClass().getName();
String destinationId = request.getDestination();
GraniteContext context = GraniteContext.getCurrentInstance();
Destination destination = context.getServicesConfig().findDestinationById(messageType, destinationId);
if (destination == null)
throw new ServiceException("No matching destination: " + destinationId);
String scope = (String)destination.getProperties().get("scope");
Map<String, Object> cache = null;
if (scope == null || "request".equals(scope))
cache = context.getRequestMap();
else if ("session".equals(scope))
cache = context.getSessionMap();
else if ("application".equals(scope))
cache = Collections.synchronizedMap(context.getApplicationMap());
else
throw new ServiceException("Illegal scope in destination: " + destination);
/*************/
Destination d = destination;
if( destination.getProperties().get("source").equals("*") ){
Map<String, Object> propertiesMap = new HashMap<String, Object>();
propertiesMap.put("source", request.getSource());
d = new Destination(destination.getId(),
destination.getChannelRefs
(), propertiesMap, destination.getRoles());
}
/**************/
/* String key = SimpleServiceInvoker.class.getName() + '.' + destination.getId();
SimpleServiceInvoker service = (SimpleServiceInvoker)cache.get(key);
if (service == null) {
service = new SimpleServiceInvoker(destination, this);
cache.put(key, service);
} ALTERADO */
String key = SimpleServiceInvoker.class.getName() + '.' +
d.getProperties().get("source"); //<--Muda Aqui
SimpleServiceInvoker service = (SimpleServiceInvoker)cache.get(key);
if( service == null ) {
service = new SimpleServiceInvoker( d, this ); //<--Muda Aqui
cache.put(key, service);
}
return service;
}
}
com isto no projeto do código fonte do GraniteDS, basta usar o build.xml para regerar o .jar do Granite e utilizar este novo jar gerado...
com isto no exemplo do Granite-Pojo, o services-config.xml fica de outra forma:
<services>
<service
id="granite-service"
class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="pojo">
<channels>
<channel ref="my-graniteamf"/>
</channels>
<properties>
<scope>session</scope>
<source>*</source>
</properties>
</destination>
</service>
</services>
e no código mxml, no mx:RemoteObject, você deverá indicar o atributo source, como mostrado abaixo:
<mx:RemoteObject
id="srv"
showBusyCursor="true"
destination="pojo"
source="test.pojo.PojoService"/>
feito isto, com um único mapeamento, você poderá acessar n-classes do seu projeto...
melhor, o que achou?