001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2012 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.client.messaging;
022    
023    import java.util.ArrayList;
024    import java.util.Arrays;
025    import java.util.List;
026    import java.util.concurrent.TimeUnit;
027    
028    import org.granite.client.messaging.channel.Channel;
029    import org.granite.client.messaging.channel.ResponseMessageFuture;
030    import org.granite.client.messaging.messages.requests.InvocationMessage;
031    
032    /**
033     * @author Franck WOLFF
034     */
035    public class RemoteService {
036    
037            private final Channel channel;
038            private final String id;
039    
040            public RemoteService(Channel channel, String id) {
041                    if (channel == null || id == null)
042                            throw new NullPointerException("channel and id cannot be null");
043                    this.channel = channel;
044                    this.id = id;
045            }
046    
047            public Channel getChannel() {
048                    return channel;
049            }
050    
051            public String getId() {
052                    return id;
053            }
054            
055            public RemoteServiceInvocation newInvocation(String method, Object...parameters) {
056                    return new RemoteServiceInvocation(this, method, parameters);
057            }
058            
059            public static interface RemoteServiceInvocationChain {
060                    
061                    RemoteServiceInvocationChain appendInvocation(String method, Object...parameters);
062                    ResponseMessageFuture invoke();
063            }
064            
065            public static class RemoteServiceInvocation implements RemoteServiceInvocationChain {
066                    
067                    private final RemoteService remoteService;
068                    private final InvocationMessage request;
069                    
070                    private long timeToLive = 0L;
071                    private List<ResponseListener> listeners = new ArrayList<ResponseListener>();
072                    
073                    public RemoteServiceInvocation(RemoteService remoteService, String method, Object...parameters) {
074                            if (remoteService == null)
075                                    throw new NullPointerException("remoteService cannot be null");
076                            this.remoteService = remoteService;
077                            this.request = new InvocationMessage(null, remoteService.id, method, parameters);
078                    }
079                    
080                    public RemoteServiceInvocation addListener(ResponseListener listener) {
081                            if (listener != null)
082                                    this.listeners.add(listener);
083                            return this;
084                    }
085                    
086                    public RemoteServiceInvocation addListeners(ResponseListener...listeners) {
087                            if (listeners != null && listeners.length > 0)
088                                    this.listeners.addAll(Arrays.asList(listeners));
089                            return this;
090                    }
091                    
092                    public RemoteServiceInvocation setTimeToLive(long timeToLiveMillis) {
093                            return setTimeToLive(timeToLiveMillis, TimeUnit.MILLISECONDS);
094                    }
095                    
096                    public RemoteServiceInvocation setTimeToLive(long timeToLive, TimeUnit unit) {
097                            if (timeToLive < 0)
098                                    throw new IllegalArgumentException("timeToLive cannot be negative");
099                            if (unit == null)
100                                    throw new NullPointerException("unit cannot be null");
101                            this.timeToLive = unit.toMillis(timeToLive);
102                            return this;
103                    }
104                    
105                    @Override
106                    public RemoteServiceInvocationChain appendInvocation(String method, Object...parameters) {
107                            InvocationMessage message = request;
108                            while (message.getNext() != null)
109                                    message = message.getNext();
110                            message.setNext(new InvocationMessage(null, remoteService.id, method, parameters));
111                            return this;
112                    }
113                    
114                    @Override
115                    public ResponseMessageFuture invoke() {
116                            request.setTimeToLive(timeToLive);
117                            return remoteService.channel.send(request, listeners.toArray(new ResponseListener[listeners.size()]));
118                    }
119            }
120    }