001 /**
002 * Copyright (C) 2012 FuseSource, Inc.
003 * http://fusesource.com
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.fusesource.hawtdispatch.transport;
019
020 import org.fusesource.hawtdispatch.DispatchQueue;
021 import org.fusesource.hawtdispatch.Task;
022 import org.fusesource.hawtdispatch.TaskWrapper;
023
024 import java.util.LinkedList;
025
026 /**
027 * <p>
028 * The BaseService provides helpers for dealing async service state.
029 * </p>
030 *
031 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
032 */
033 public abstract class ServiceBase {
034
035 public static class State {
036 public String toString() {
037 return getClass().getSimpleName();
038 }
039 public boolean isStarted() {
040 return false;
041 }
042 public boolean isStarting() {
043 return false;
044 }
045 }
046
047 static class CallbackSupport extends State {
048 LinkedList<Task> callbacks = new LinkedList<Task>();
049
050 void add(Task r) {
051 if (r != null) {
052 callbacks.add(r);
053 }
054 }
055
056 void done() {
057 for (Task callback : callbacks) {
058 callback.run();
059 }
060 }
061 }
062
063 public static final State CREATED = new State();
064 public static class STARTING extends CallbackSupport {
065 public boolean isStarting() {
066 return true;
067 }
068 }
069 public static final State STARTED = new State() {
070 public boolean isStarted() {
071 return true;
072 }
073 };
074 public static class STOPPING extends CallbackSupport {
075 }
076
077 public static final State STOPPED = new State();
078
079
080 protected State _serviceState = CREATED;
081
082 @Deprecated
083 final public void start(final Runnable onCompleted) {
084 start(new TaskWrapper(onCompleted));
085 }
086
087 final public void start(final Task onCompleted) {
088 getDispatchQueue().execute(new Task() {
089 public void run() {
090 if (_serviceState == CREATED ||
091 _serviceState == STOPPED) {
092 final STARTING state = new STARTING();
093 state.add(onCompleted);
094 _serviceState = state;
095 _start(new Task() {
096 public void run() {
097 _serviceState = STARTED;
098 state.done();
099 }
100 });
101 } else if (_serviceState instanceof STARTING) {
102 ((STARTING) _serviceState).add(onCompleted);
103 } else if (_serviceState == STARTED) {
104 if (onCompleted != null) {
105 onCompleted.run();
106 }
107 } else {
108 if (onCompleted != null) {
109 onCompleted.run();
110 }
111 error("start should not be called from state: " + _serviceState);
112 }
113 }
114 });
115 }
116
117 @Deprecated
118 final public void stop(final Runnable onCompleted) {
119 stop(new TaskWrapper(onCompleted));
120 }
121
122 final public void stop(final Task onCompleted) {
123 getDispatchQueue().execute(new Task() {
124 public void run() {
125 if (_serviceState == STARTED) {
126 final STOPPING state = new STOPPING();
127 state.add(onCompleted);
128 _serviceState = state;
129 _stop(new Task() {
130 public void run() {
131 _serviceState = STOPPED;
132 state.done();
133 }
134 });
135 } else if (_serviceState instanceof STOPPING) {
136 ((STOPPING) _serviceState).add(onCompleted);
137 } else if (_serviceState == STOPPED) {
138 if (onCompleted != null) {
139 onCompleted.run();
140 }
141 } else {
142 if (onCompleted != null) {
143 onCompleted.run();
144 }
145 error("stop should not be called from state: " + _serviceState);
146 }
147 }
148 });
149 }
150
151 private void error(String msg) {
152 try {
153 throw new AssertionError(msg);
154 } catch (Exception e) {
155 e.printStackTrace();
156 }
157 }
158
159 protected State getServiceState() {
160 return _serviceState;
161 }
162
163 abstract protected DispatchQueue getDispatchQueue();
164
165 abstract protected void _start(Task onCompleted);
166
167 abstract protected void _stop(Task onCompleted);
168
169 }