KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > whack > ExternalComponentManager


1 /**
2  * $RCSfile: ExternalComponentManager.java,v $
3  * $Revision: 1.11 $
4  * $Date: 2005/05/28 04:54:35 $
5  *
6  * Copyright 2005 Jive Software.
7  *
8  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */

20
21 package org.jivesoftware.whack;
22
23 import org.xmpp.component.*;
24 import org.xmpp.packet.JID;
25 import org.xmpp.packet.Packet;
26 import org.jivesoftware.whack.container.ServerContainer;
27
28 import javax.net.SocketFactory;
29 import java.util.Hashtable JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.prefs.Preferences JavaDoc;
32
33 /**
34  * Implementation of the ComponentManager interface for external components.
35  * This implementation follows JEP-0014.
36  *
37  * @author Matt Tucker
38  */

39 public class ExternalComponentManager implements ComponentManager {
40
41     /**
42      * Keeps the IP address or hostname of the server. This value will be used only for creating
43      * connections.
44      */

45     private String JavaDoc host;
46     /**
47      * Port of the server used for establishing new connections.
48      */

49     private int port;
50     /**
51      * Keeps the domain of the XMPP server. The domain may or may not match the host. The domain
52      * will be used mainly for the XMPP packets while the host is used mainly for creating
53      * connections to the server.
54      */

55     private String JavaDoc domain;
56     /**
57      * This is a global secret key that will be used during the handshake with the server. If a
58      * secret key was not defined for the specific component then the global secret key will be
59      * used.
60      */

61     private String JavaDoc defaultSecretKey;
62     /**
63      * Keeps the secret keys to use for each subdomain. If a key was not found for a specific
64      * subdomain then the global secret key will used for the handshake with the server.
65      */

66     private Map JavaDoc<String JavaDoc, String JavaDoc> secretKeys = new Hashtable JavaDoc<String JavaDoc,String JavaDoc>();
67
68     Preferences JavaDoc preferences = Preferences.userRoot();
69     private String JavaDoc preferencesPrefix;
70
71     /**
72      * Keeps a map that associates a domain with the external component thas is handling the domain.
73      */

74     private Map JavaDoc<String JavaDoc, ExternalComponent> componentsByDomain = new Hashtable JavaDoc<String JavaDoc,ExternalComponent>();
75     /**
76      * Keeps a map that associates a component with the wrapping ExternalComponent.
77      */

78     private Map JavaDoc<Component, ExternalComponent> components = new Hashtable JavaDoc<Component,ExternalComponent>();
79
80     private Log logger;
81
82     /**
83      * Constructs a new ExternalComponentManager that will make connections
84      * to the specified XMPP server on the default port (5222).
85      *
86      * @param host the IP address or name of the XMPP server to connect to (e.g. "example.com").
87      */

88     public ExternalComponentManager(String JavaDoc host) {
89         this(host, 5222);
90     }
91
92     /**
93      * Constructs a new ExternalComponentManager that will make connections to
94      * the specified XMPP server on the given port.
95      *
96      * @param host the IP address or name of the XMPP server to connect to (e.g. "example.com").
97      * @param port the port to connect on.
98      */

99     public ExternalComponentManager(String JavaDoc host, int port) {
100         this.host = host;
101         this.port = port;
102         this.domain = host;
103
104         createDummyLogger();
105
106         // Set this ComponentManager as the current component manager
107
ComponentManagerFactory.setComponentManager(this);
108     }
109
110     /**
111      * Sets a secret key for a sub-domain, for future use by a component
112      * connecting to the server. Keys are used as an authentication mechanism
113      * when connecting to the server. Some servers may require a different
114      * key for each component, while others may use a global secret key.
115      *
116      * @param subdomain the sub-domain.
117      * @param secretKey the secret key
118      */

119     public void setSecretKey(String JavaDoc subdomain, String JavaDoc secretKey) {
120         secretKeys.put(subdomain, secretKey);
121     }
122
123     /**
124      * Returns the secret key for a sub-domain. If no key was found then the default secret key
125      * will be returned.
126      *
127      * @param subdomain the subdomain to return its secret key.
128      * @return the secret key for a sub-domain.
129      */

130     public String JavaDoc getSecretKey(String JavaDoc subdomain) {
131         // Find the proper secret key to connect as the subdomain.
132
String JavaDoc secretKey = secretKeys.get(subdomain);
133         if (secretKey == null) {
134             secretKey = defaultSecretKey;
135         }
136         return secretKey;
137     }
138
139     /**
140      * Sets the default secret key, which will be used when connecting if a
141      * specific secret key for the component hasn't been sent. Keys are used
142      * as an authentication mechanism when connecting to the server. Some servers
143      * may require a different key for each component, while others may use
144      * a global secret key.
145      *
146      * @param secretKey the default secret key.
147      */

148     public void setDefaultSecretKey(String JavaDoc secretKey) {
149         this.defaultSecretKey = secretKey;
150     }
151
152     public void addComponent(String JavaDoc subdomain, Component component) throws ComponentException {
153         if (componentsByDomain.containsKey(subdomain)) {
154             if (componentsByDomain.get(subdomain).getComponent() == component) {
155                 // Do nothing since the component has already been registered
156
return;
157             }
158             else {
159                 throw new IllegalArgumentException JavaDoc("Subdomain already in use by another component");
160             }
161         }
162         // Find the proper secret key to connect as the subdomain.
163
String JavaDoc secretKey = secretKeys.get(subdomain);
164         if (secretKey == null) {
165             secretKey = defaultSecretKey;
166         }
167         // Create a wrapping ExternalComponent on the component
168
ExternalComponent externalComponent = new ExternalComponent(component, this);
169         try {
170             // Register the new component
171
componentsByDomain.put(subdomain, externalComponent);
172             components.put(component, externalComponent);
173             // Ask the ExternalComponent to connect with the remote server
174
externalComponent.connect(host, port, SocketFactory.getDefault(), subdomain);
175             // Initialize the component
176
JID componentJID = new JID(null, externalComponent.getDomain(), null);
177             externalComponent.initialize(componentJID, this);
178         } catch (ComponentException e) {
179             // Unregister the new component
180
componentsByDomain.remove(subdomain);
181             components.remove(component);
182             // Re-throw the exception
183
throw e;
184         }
185         // Ask the external component to start processing incoming packets
186
externalComponent.start();
187     }
188
189     public void removeComponent(String JavaDoc subdomain) throws ComponentException {
190         ExternalComponent externalComponent = componentsByDomain.remove(subdomain);
191         components.remove(externalComponent.getComponent());
192         if (externalComponent != null) {
193             externalComponent.shutdown();
194         }
195     }
196
197     public void sendPacket(Component component, Packet packet) {
198         // Get the ExternalComponent that is wrapping the specified component and ask it to
199
// send the packet
200
components.get(component).send(packet);
201     }
202
203     public String JavaDoc getProperty(String JavaDoc name) {
204         return preferences.get(getPreferencesPrefix() + name, null);
205     }
206
207     public void setProperty(String JavaDoc name, String JavaDoc value) {
208         preferences.put(getPreferencesPrefix() + name, value);
209     }
210
211     private String JavaDoc getPreferencesPrefix() {
212         if (preferencesPrefix == null) {
213             preferencesPrefix = "whack." + domain + ".";
214         }
215         return preferencesPrefix;
216     }
217
218     /**
219      * Sets the domain of the XMPP server. The domain may or may not match the host. The domain
220      * will be used mainly for the XMPP packets while the host is used mainly for creating
221      * connections to the server.
222      *
223      * @param domain the domain of the XMPP server.
224      */

225     public void setServerName(String JavaDoc domain) {
226         this.domain = domain;
227     }
228
229     public String JavaDoc getServerName() {
230         return domain;
231     }
232
233     public boolean isExternalMode() {
234         return true;
235     }
236
237     /**
238      * Returns the location of the <code>home</code> directory.
239      *
240      * @return the location of the home directory.
241      */

242     public String JavaDoc getHomeDirectory() {
243         return ServerContainer.getInstance().getHomeDirectory();
244     }
245
246     public Log getLog() {
247         return logger;
248     }
249
250     private void createDummyLogger() {
251         this.logger = new Log() {
252             public void error(String JavaDoc message) {
253                 System.out.println(message);
254             }
255
256             public void error(String JavaDoc message, Throwable JavaDoc throwable) {
257                 System.err.println(message);
258                 throwable.printStackTrace();
259             }
260
261             public void error(Throwable JavaDoc throwable) {
262                 throwable.printStackTrace();
263             }
264
265             public void warn(String JavaDoc message) {
266                 System.out.println(message);
267             }
268
269             public void warn(String JavaDoc message, Throwable JavaDoc throwable) {
270                 System.out.println(message);
271                 throwable.printStackTrace();
272             }
273
274             public void warn(Throwable JavaDoc throwable) {
275                 throwable.printStackTrace();
276             }
277
278             public void info(String JavaDoc message) {
279                 System.out.println(message);
280             }
281
282             public void info(String JavaDoc message, Throwable JavaDoc throwable) {
283                 System.out.println(message);
284                 throwable.printStackTrace();
285             }
286
287             public void info(Throwable JavaDoc throwable) {
288                 throwable.printStackTrace();
289             }
290
291             public void debug(String JavaDoc message) {
292                 System.out.println(message);
293             }
294
295             public void debug(String JavaDoc message, Throwable JavaDoc throwable) {
296                 System.out.println(message);
297                 throwable.printStackTrace();
298             }
299
300             public void debug(Throwable JavaDoc throwable) {
301                 throwable.printStackTrace();
302             }
303         };
304     }
305 }
Popular Tags