001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.messaging.service;
022    
023    import java.util.HashMap;
024    import java.util.Map;
025    
026    import org.granite.config.flex.Destination;
027    import org.granite.logging.Logger;
028    import org.granite.util.ClassUtil;
029    
030    import flex.messaging.messages.RemotingMessage;
031    
032    /**
033     * @author Franck WOLFF
034     */
035    public class SimpleServiceInvoker extends ServiceInvoker<SimpleServiceFactory> {
036    
037        private static final Logger log = Logger.getLogger(SimpleServiceInvoker.class);
038    
039        private final Map<String, Object> sources;
040    
041        protected SimpleServiceInvoker(Destination destination, SimpleServiceFactory factory) throws ServiceException {
042            super(destination, factory);
043    
044            String className = destination.getProperties().get("source");
045            if (className == null)
046                throw new ServiceException("No source property for destination: " + destination);
047            className = className.trim();
048    
049            log.debug(">> New SimpleServiceInvoker constructing new: %s", className);
050    
051            // Invokee class set at runtime (RemoteObject.source).
052            if ("*".equals(className))
053                sources = new HashMap<String, Object>();
054            else {
055                try {
056                    if (destination.getScannedClass() != null)
057                            this.invokee = destination.getScannedClass().newInstance();
058                    else
059                            this.invokee = ClassUtil.newInstance(className);
060                } catch (Exception e) {
061                    throw new ServiceException("Invalid source property for destination: " + destination, e);
062                }
063                sources = null;
064            }
065        }
066    
067        @Override
068        protected Object adjustInvokee(RemotingMessage request, String methodName, Object[] args) throws ServiceException {
069    
070            if (sources == null)
071                return super.adjustInvokee(request, methodName, args);
072    
073            String className = request.getSource();
074            if (className == null)
075                throw new ServiceException("No source property in request for '*' destination: " + destination);
076            className = className.trim();
077    
078            Object invokee = null;
079    
080            synchronized (sources) {
081                invokee = sources.get(className);
082                if (invokee == null) {
083                    try {
084                        invokee = ClassUtil.newInstance(className);
085                    } catch (Exception e) {
086                        throw new ServiceException("Invalid source property in request for '*' destination: " + destination, e);
087                    }
088                    sources.put(className, invokee);
089                }
090            }
091    
092            return invokee;
093        }
094    }