1 /* 2 * Copyright the original author or authors. 3 * 4 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.mozilla.org/MPL/MPL-1.1.html 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import org.as2lib.core.BasicClass; 18 import org.as2lib.env.except.IllegalArgumentException; 19 import org.as2lib.data.holder.Map; 20 import org.as2lib.data.holder.map.PrimitiveTypeMap; 21 import org.as2lib.io.conn.core.server.Server; 22 import org.as2lib.io.conn.core.server.ServerServiceProxy; 23 import org.as2lib.io.conn.core.server.ServerRegistry; 24 import org.as2lib.io.conn.local.server.LocalServerServiceProxy; 25 import org.as2lib.io.conn.local.LocalConfig; 26 27 /** 28 * {@code LocalServer} acts as a composite for many services that are all combined 29 * in one domain. 30 * 31 * <p>Example: 32 * <code> 33 * var server:LocalServer = new LocalServer("local.as2lib.org"); 34 * server.putService("myServiceOne", new MyServiceOne()); 35 * server.putService("myServiceTwo", new MyServiceTwo()); 36 * server.run(); 37 * </code> 38 * 39 * @author Simon Wacker 40 * @author Christoph Atteneder 41 */ 42 class org.as2lib.io.conn.local.server.LocalServer extends BasicClass implements Server { 43 44 /** Name of this server. */ 45 private var host:String; 46 47 /** All services. */ 48 private var services:Map; 49 50 /** Server status. */ 51 private var running:Boolean; 52 53 /** Stores the server registry. */ 54 private var serverRegistry:ServerRegistry; 55 56 /** 57 * Constructs a new {@code LocalServer} instance. 58 * 59 * @param host the name of this server 60 * @throws IllegalArgumentException if the passed-in {@code host} is {@code null}, 61 * {@code undefined} or an empty string 62 */ 63 public function LocalServer(host:String) { 64 if (!host) throw new IllegalArgumentException("Argument 'host' must not be null, undefined or a blank string.", this, arguments); 65 this.host = host; 66 services = new PrimitiveTypeMap(); 67 running = false; 68 } 69 70 /** 71 * Returns the currently used server registry. 72 * 73 * <p>This is either the server registry set via {@link #setServerRegistry} or the 74 * default registry returned by the {@link LocalConfig#getServerRegistry} method. 75 * 76 * @return the currently used server registry 77 */ 78 public function getServerRegistry(Void):ServerRegistry { 79 if (!serverRegistry) serverRegistry = LocalConfig.getServerRegistry(); 80 return serverRegistry; 81 } 82 83 /** 84 * Sets a new server registry. 85 * 86 * <p>If {@code serverRegistry} is {@code null} or {@code undefined} the 87 * {@link #getServerRegistry} method will return the default server registry. 88 * 89 * @param serverRegistry the new server registry 90 */ 91 public function setServerRegistry(serverRegistry:ServerRegistry):Void { 92 this.serverRegistry = serverRegistry; 93 } 94 95 /** 96 * Runs this server. 97 * 98 * <p>This involves registering itself at the server registry and running all added 99 * services with this host. 100 * 101 * <p>If this server is already running a restart will be made. This means it will 102 * be stopped and run again. 103 */ 104 public function run(Void):Void { 105 if (isRunning()) this.stop(); 106 getServerRegistry().registerServer(getHost()); 107 if (services.size() > 0) { 108 var serviceArray:Array = services.getValues(); 109 for (var i:Number = 0; i < serviceArray.length; i++) { 110 ServerServiceProxy(serviceArray[i]).run(host); 111 } 112 } 113 running = true; 114 } 115 116 /** 117 * Stops this server. 118 * 119 * <p>This involves stopping all services and removing itself from the server registry. 120 */ 121 public function stop(Void):Void { 122 if (services.size() > 0) { 123 var serviceArray:Array = services.getValues(); 124 for (var i:Number = 0; i < serviceArray.length; i++) { 125 ServerServiceProxy(serviceArray[i]).stop(); 126 } 127 } 128 if (getServerRegistry().containsServer(getHost())) { 129 getServerRegistry().removeServer(getHost()); 130 } 131 running = false; 132 } 133 134 /** 135 * Puts the passed-in {@code service} to the passed-in {@code path} on this server. 136 * 137 * <p>{@code service} and {@code path} are wrapped in a {@link ServerServiceProxy} 138 * instance. 139 * 140 * @param path that path to the service on the host 141 * @param service the service to make locally available 142 * @return the newly created server service proxy that wraps {@code service} and 143 * {@code path} 144 * @throws IllegalArgumentException if the passed-in {@code path} is {@code null}, 145 * {@code undefined} or an empty string or if the passed-in {@code service} is 146 * {@code null} or {@code undefined} 147 * @see #addService 148 */ 149 public function putService(path:String, service):ServerServiceProxy { 150 // source out instantiation 151 var proxy:ServerServiceProxy = new LocalServerServiceProxy(path, service); 152 addService(proxy); 153 return proxy; 154 } 155 156 /** 157 * Adds the passed-in {@code serviceProxy} to this service. 158 * 159 * <p>If this server is running, the {@code serviceProxy} will be run immediately 160 * too. 161 * 162 * @param serviceProxy the proxy that wraps the actual service 163 * @throws IllegalArgumentException if the passed-in {@code serviceProxy} is 164 * {@code null} or {@code undefined} or if the path of the passed-in {@code serviceProxy} 165 * is {@code null}, {@code undefined} or an empty string or if the path of the passed-in 166 * {@code serviceProxy} is already in use 167 * @see #putService 168 */ 169 public function addService(serviceProxy:ServerServiceProxy):Void { 170 if (!serviceProxy) throw new IllegalArgumentException("Service proxy must not be null or undefined.", this, arguments); 171 var path:String = serviceProxy.getPath(); 172 if (!path) throw new IllegalArgumentException("Service proxy's path must not be null, undefined or a blank string.", this, arguments); 173 if (services.containsKey(path)) throw new IllegalArgumentException("Service proxy with proxy path [" + path + "] is already in use.", this, arguments); 174 services.put(path, serviceProxy); 175 if (isRunning()) { 176 serviceProxy.run(host); 177 } 178 } 179 180 /** 181 * Removes the service registered wiht the passed-in {@code path}. 182 * 183 * <p>If the service is running it will be stopped. 184 * 185 * <p>{@code null} will be returned if: 186 * <ul> 187 * <li>The passed-in {@code path} is {@code null} or an empty string.</li> 188 * <li>There is no registered service with the passed-in {@code path}.</li> 189 * </ul> 190 * 191 * @param path the path of the service to remove 192 * @return the removed server service proxy wrapping the actual service 193 */ 194 public function removeService(path:String):ServerServiceProxy { 195 if (!path) return null; 196 var service:ServerServiceProxy = services.remove(path); 197 if (service.isRunning()) service.stop(); 198 return service; 199 } 200 201 /** 202 * Returns the service registered with the passed-in {@code path}. 203 * 204 * <p>{@code null} will be returned if: 205 * <ul> 206 * <li>The passed-in {@code path} is {@code null} or an empty string.</li> 207 * <li>There is no service registered with the passed-in {@code path}.</li> 208 * </ul> 209 * 210 * @param path the path of the service to return 211 * @return the server service proxy wrapping the actual service 212 */ 213 public function getService(path:String):ServerServiceProxy { 214 if (!path) return null; 215 return services.get(path); 216 } 217 218 /** 219 * Returns whether this server is running. 220 * 221 * <p>This server is by default not running. It runs as soon as you call the 222 * {@link #run} method. And stops when you call the {@ink #stop} method. 223 * 224 * @return {@code true} if this server is running else {@code false} 225 */ 226 public function isRunning(Void):Boolean { 227 return running; 228 } 229 230 /** 231 * Returns the host of this server. 232 * 233 * @return this host of this server 234 */ 235 public function getHost(Void):String { 236 return host; 237 } 238 239 }