View Javadoc

1   /*
2    * Copyright 2001-2005 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
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  package net.sf.nxqd;
17  
18  import java.util.logging.Level;
19  import java.util.logging.Logger;
20  import java.util.ArrayList;
21  import java.util.Map;
22  import java.util.List;
23  import java.util.Timer;
24  
25  import org.w3c.dom.Document;
26  
27  import net.sf.nxqd.common.NxqdUtils;
28  import net.sf.nxqd.soap.AxisConnector;
29  import net.sf.nxqd.event.NxqdEvent;
30  import net.sf.nxqd.event.NxqdContainerEvent;
31  import net.sf.nxqd.event.NxqdManagerEvent;
32  import net.sf.nxqd.event.NxqdEventListener;
33  import net.sf.nxqd.event.NxqdManagerEventListener;
34  import net.sf.nxqd.event.NxqdContainerEventListener;
35  
36  import javax.xml.namespace.QName;
37  import org.apache.axis.Constants;
38  
39  /**
40   * The class <code>NxqdManager</code> is the main class for
41   * communicating with the Nxqd Apache module.
42   *
43   * @author <a href="mailto:webhiker@sourceforge.net">webhiker</a>
44   * @version 1.0
45   */
46  public class NxqdManager {
47  
48      /**
49       * The variable <code>logger</code> is used for logging events.
50       *
51       */
52      private static Logger logger = Logger.getLogger(NxqdManager.class.getName());
53  
54      /**
55       * The constant <code>NXQD_PORT</code> specifies the default port
56       * in case it is not specified in the URI.
57       */
58      public  static final String NXQD_PORT = "8080";
59  
60      /**
61       * The variable <code>connected</code> indicates whether or not this
62       * client is connected.
63       *
64       */
65      private boolean connected;
66  
67      /**
68       * The <code>host</code> to connect to.
69       *
70       */
71      private String hostName;
72  
73      private String hostPort;
74  
75      private AxisConnector axisConnector;
76  
77      /**
78       * Creates a new <code>NxqdManager</code> instance which will connect
79       * to the specified host on the default port.
80       *
81       * @param host a <code>String</code> value indicating the hostname of the
82       * machine running the Nxqd server.
83       */
84      public NxqdManager(final String host) {
85          this(host, NXQD_PORT);
86      }
87  
88      /**
89       * The a new <code>NxqdManager</code> constructor creates a new instance
90       * of this driver.
91       *
92       * @param host a <code>String</code> value indicating the hostname of the
93       * machine running the Nxqd server.
94       * @param port an <code>int</code> value specifying the port of the
95       * Nxqd server.
96       */
97      public NxqdManager(final String host, final String port) {
98          this.hostName = host;
99          this.hostPort = port;
100 	containerListeners = new ArrayList();
101 	managerListeners = new ArrayList();
102 	axisConnector = new AxisConnector(hostName, hostPort);
103     }
104 
105     /**
106      * The <code>getHostName</code> method returns the host name
107      * of the machine running the Nxqd server.
108      *
109      * @return a <code>String</code> value
110      */
111     public final String getHostName() {
112 	return hostName;
113     }
114 
115     /**
116      * The <code>getHostPort</code> method returns the host port
117      * of the remote Nxqd server.
118      *
119      * @return an <code>String</code> value
120      */
121     public final String getHostPort() {
122 	return hostPort;
123     }
124 
125     public void connect() throws NxqdException {
126 	if (axisConnector.isConnected()) {
127 	    throw new NxqdException("Already connected");
128 	}
129 	else {
130 	    axisConnector.connect();
131 	}
132     }
133 
134     public void disconnect() throws NxqdException {
135 	if (!axisConnector.isConnected()) {
136 	    throw new NxqdException("Not connected");
137 	}
138 	else {
139 	    if (pollTimer!=null) {
140 		pollTimer.cancel();
141 	    }
142 	    axisConnector.disconnect();
143 	}
144     }
145 
146     public boolean isConnected() {
147 	return axisConnector.isConnected();
148     }
149 
150     /**
151      * The <code>getSessionId</code> method returns the session id which
152      * identifies the client for this session.
153      *
154      * @return a <code>String</code> value
155      */
156     public String getSessionId() {
157 	return axisConnector.getSessionId();
158     }
159 
160     /**
161      * The <code>createContainer</code> method creates
162      * the specified container A NxqdException is thrown if
163      * the container already exists.
164      *
165      * @param containerName a <code>String</code> value
166      * @return a <code>NxqdContainer</code> value
167      * @exception NxqdException if an error occurs
168      */
169     public NxqdContainer createContainer(String containerName) throws NxqdException {
170 	logger.fine("Creating container "+containerName);
171 
172 	Boolean returnValue = (Boolean)axisConnector.invoke("create-container",
173 							    Constants.XSD_BOOLEAN,
174 							    new String[]{"container"},
175 							    new Object[]{containerName});
176 	// expect a "true" result, else something went wrong
177 	if (!returnValue.booleanValue()) {
178 	    throw new NxqdException("Server response indicated an error creating the container ("+containerName+")");
179 	} else {
180 	    logger.fine("Container was created ("+containerName+")");
181 	    return new NxqdContainer(this, containerName);
182 	}
183     }
184 
185     /**
186      * The <code>renameContainer</code> method creates
187      * the specified container A NxqdException is thrown if
188      * the container already exists.
189      *
190      * @param oldName a <code>String</code> indicating the container you want to rename
191      * @param newName a <code>String</code> indicating the new name for the container
192      * @exception NxqdException if an error occurs
193      */
194     public void renameContainer(final String oldName,
195 				final String newName) throws NxqdException {
196 	logger.fine("Renaming container "+oldName+" to "+newName);
197 
198 	Boolean returnValue = (Boolean)axisConnector.invoke("rename-container",
199 							    Constants.XSD_BOOLEAN,
200 							    new String[]{"old-container",
201 									 "new-container"},
202 							    new Object[]{oldName,
203 									 newName});
204 	// expect a "true" result, else something went wrong
205 	if (!returnValue.booleanValue()) {
206 	    throw new NxqdException("Server response indicated an error renaming the container ("+oldName+")");
207 	} else {
208 	    logger.fine("Container was renamed ("+newName+")");
209 	}
210     }
211 
212     /**
213      * The <code>deleteContainer</code> method deletes the
214      * specifed container. A NxqdException is thrown if
215      * the container does not exist.
216      *
217      * @param containerName a <code>String</code> value
218      * @exception NxqdException if an error occurs
219      */
220     public void deleteContainer(String containerName) throws NxqdException {
221 	Boolean returnValue = (Boolean)axisConnector.invoke("delete-container",
222 							    Constants.XSD_BOOLEAN,
223 							    new String[]{"container"},
224 							    new Object[]{containerName});
225 	// expect a "true" result, else something went wrong
226 	if (!returnValue.booleanValue()) {
227 	    throw new NxqdException("Server response indicated an error deleting the container ("+containerName+")");
228 	}
229 	logger.fine("Container was deleted ("+containerName+")");
230     }
231 
232     /**
233      * The <code>deleteContainer</code> method deletes the
234      * specifed container. A NxqdException is thrown if
235      * the container does not exist.
236      *
237      * @param container a <code>NxqdContainer</code> value
238      * @exception NxqdException if an error occurs
239      */
240     public void deleteContainer(NxqdContainer container) throws NxqdException {
241 	Boolean returnValue = (Boolean)axisConnector.invoke("delete-container",
242 							    Constants.XSD_BOOLEAN,
243 							    new String[]{"container"},
244 							    new Object[]{container.getName()});
245 	// expect a "true" result, else something went wrong
246 	if (!returnValue.booleanValue()) {
247 	    throw new NxqdException("Server response indicated an error deleting the container ("+container.getName()+")");
248 	}
249 	logger.fine("Container was deleted ("+container.getName()+")");
250     }
251 
252     /**
253      * The <code>getContainer</code> method returns a handle
254      * to the specified container. A NxqdException is thrown if
255      * the container does not exist.
256      *
257      * @param containerName a <code>String</code> value
258      * @return a <code>NxqdContainer</code> value
259      * @exception NxqdException if an error occurs
260      */
261     public NxqdContainer getContainer(String containerName) throws NxqdException {
262 	if (containerExists(containerName)) {
263 	    return new NxqdContainer(this, containerName);
264 	}
265 	else {
266 	    throw new NxqdException("The container does not exist ("+containerName+")");
267 	}
268     }
269 
270     /**
271      * The <code>containerExists</code> method checks if
272      * the specified container exists. It will return
273      * true if the container exists, false otherwise.
274      * A NxqdException is thrown if other errors occur.
275      *
276      * @param containerName a <code>String</code> value
277      * @return a <code>boolean</code> value
278      * @exception NxqdException if an error occurs
279      */
280     public boolean containerExists(String containerName) throws NxqdException {
281 	if (containerName.indexOf('/')>=0) {
282 	    throw new NxqdException("very naughty character");
283 	}
284 	Boolean result = (Boolean)axisConnector.invoke("container-exists",
285 						       Constants.XSD_BOOLEAN,
286 						       new String[]{"container"},
287 						       new Object[]{containerName});
288 	return result.booleanValue();
289     }
290 
291     /**
292      * The <code>listContainers</code> method returns a List containing
293      * the container names managed by the server. This list may
294      * be empty, but it will never be null.
295      *
296      * @return a <code>List</code> value
297      * @exception NxqdException if an error occurs
298      */
299     public List listContainers() throws NxqdException {
300 	Object result = axisConnector.invoke("get-container-list",
301 					     new Object[0]);
302 	if (result == null) {
303 	    return new ArrayList();
304 	}
305 	else {
306 	    // for some reason, if only one item is found
307 	    // it s returned as a String
308 	    if (result instanceof String) {
309 		List resultList = new ArrayList();
310 		resultList.add(result.toString());
311 		return resultList;
312 	    }
313 	    else {
314 		return (List)result;
315 	    }
316 	}
317     }
318 
319     /**
320      * The <code>query</code> method executes the specified queryExpression
321      * on this database. No preprocessing of the query is performed.
322      *
323      * @param queryExpression a <code>String</code> value
324      * @return a <code>List</code> value which will contain XML fragments
325      * as <code>String</code> objects.
326      * @exception NxqdException if an error occurs
327      */
328     public List query(final String queryExpression) throws NxqdException {
329 	return query(queryExpression, null);
330     }
331 
332 
333     /**
334      * The <code>query</code> method executes the specified queryExpression
335      * on this database. No preprocessing of the query is performed.
336      *
337      * @param queryExpression a <code>String</code> value
338      * @param nameSpaces a <code>Map</code> value
339      * @return a <code>List</code> value which will contain XML fragments
340      * as <code>String</code> objects.
341      * @exception NxqdException if an error occurs
342      */
343     public List query(final String queryExpression,
344 		      final Map nameSpaces) throws NxqdException {
345 	
346 	Object result = axisConnector.invoke("query",
347 					     Constants.XSD_STRING,
348 					     new String[]{"query",
349 							  "namespacePrefix",
350 							  "namespaceURI"},
351 					     new Object[]{queryExpression,
352 							  NxqdUtils.getKeysAsList(nameSpaces),
353 							  NxqdUtils.getValuesAsList(nameSpaces)});
354 	return NxqdUtils.gsoapResultObjectToList(result);
355     }
356 
357     /**
358      * The <code>lazyQuery</code> method executes the specified queryExpression
359      * on this database. No preprocessing of the query is performed. This querying
360      * is different from query in the way that no result is returned. Results can be
361      * retrieved by calling <code>getResults</code>
362      *
363      * @param queryExpression a <code>String</code> value
364      * @param nameSpaces a <code>Map</code> value
365      * @param sessionID  a <code>String</code> value representing the client's session; retrieved using <code>getSessionId()</code>
366      * @return a <code>int</code> value which will retrieve the query id if the query was successful 
367      * The query id retrieved has to be submitted to <code>get_results</code> to get the results associated with
368      * the lazy query. If query is unsuccessful, return 0.
369      * @exception NxqdException if an error occurs
370      * @author Manish Rai Jain
371      */
372     public int lazyQuery(final String queryExpression,
373 		      final Map nameSpaces,
374 		      final String sessionID) throws NxqdException {
375 	
376 	Integer result =  (Integer)axisConnector.invoke("lazyquery",
377 						       Constants.XSD_INT,
378 						       new String[]{"query",
379 								    "namespacePrefix",
380 								    "namespaceURI",
381 								    "ssid"},
382 						       new QName[]{Constants.XSD_STRING,
383 								   Constants.XSD_ANY,
384 								   Constants.XSD_ANY,
385 								   Constants.XSD_STRING},
386 						       new Object[]{queryExpression,
387 								    NxqdUtils.getKeysAsList(nameSpaces),
388 								    NxqdUtils.getValuesAsList(nameSpaces),
389 								    sessionID});
390 	return result.intValue();
391 
392     }
393     
394     /**
395      * The <code>getResults method will retrieve the results after a
396      * <code>lazyQuery</code> has been executed. 
397      * 
398      * @param numResults a <code>int</code> value to specify how many results to retrieve
399      * @param sessionID a <code>String</code> value to specify which client's session
400      * @param queryID a <code>int</code> value retrieved from <code>lazyQuery</code>
401      * @author Manish Rai Jain
402      */
403     public List getResults(final int numResults, final String sessionID, final int queryID)
404     	throws NxqdException {
405     	Integer num = new Integer(numResults);
406 	Integer qID = new Integer(queryID);
407     	Object result = axisConnector.invoke("get-results",
408 					     Constants.XSD_STRING,
409 					     new String[]{"numresult",
410 							  "ssid",
411 							  "queryid"},
412 					     new QName[]{Constants.XSD_INT,
413 							 Constants.XSD_STRING,
414 							 Constants.XSD_INT},
415 					     new Object[]{num,
416 							  sessionID,
417 							  qID});
418     	return NxqdUtils.gsoapResultObjectToList(result);
419     }
420     
421     /**
422      * The <code>createModify</code> method will create an 
423      * <code>XmlModify</code> object.
424      *
425      * @return a <code>NxqdModify</code> value
426      * @exception NxqdException if an error occurs
427      */
428     public NxqdModify createModify() throws NxqdException {
429 	throw new NxqdException("createModify() is not yet supported");
430     }
431 
432     /**
433      * Describe <code>prepare</code> method here.
434      *
435      * @param query a <code>String</code> The XQuery query string to compile.
436      * @return a <code>NxqdQueryExpression</code> value
437      * @exception NxqdException if an error occurs
438      */
439     public NxqdQueryExpression prepare(String query) throws NxqdException {
440 	throw new NxqdException("prepare(String query) is not yet supported");
441     }
442 
443     /**
444      * The <code>putDocument</code> method adds the specified document to the
445      * container using the specified documentId. An exception is thrown if
446      * the specified documentId already exists.
447      *
448      * @param containerId a <code>String</code> value
449      * @param documentId a <code>String</code> value
450      * @param documentStr a <code>String</code> value
451      * @exception NxqdException if an error occurs
452      */
453     protected void putDocument(final String containerId,
454 			       final String documentId, 
455 			       final String documentStr) throws NxqdException {
456 	Object ret = axisConnector.invoke("put-document",
457 					  Constants.XSD_BOOLEAN,
458 					  new String[]{"container",
459 						       "name",
460 						       "doc"},
461 					  new Object[]{containerId,
462 						       documentId,
463 						       documentStr});
464 	if (!((Boolean)ret).booleanValue()) {
465 	    throw new NxqdException("Error occured while adding the document");
466 	}
467     }
468     
469     /**
470      * The <code>getDocument</code> method retrievs the specified document from the
471      * container using the specified documentId. An exception is thrown if
472      * the specified documentId does not exist.
473      *
474      * @param containerId a <code>String</code> value
475      * @param documentId a <code>String</code> value
476      * @return a <code>String</code> value
477      * @exception NxqdException if an error occurs
478      */
479     protected String getDocument(final String containerId,
480 				 final String documentId) throws NxqdException {
481 	return (String)axisConnector.invoke("get-document",
482 					    Constants.XSD_STRING,
483 					    new String[]{"container",
484 							 "name"},
485 					    new Object[]{containerId,
486 							 documentId});
487     }
488     
489     /**
490      * The <code>deleteDocument</code> method deletes the specified document from the
491      * container using the specified documentId. An exception is thrown if
492      * an error occurred while deleting the document.
493      *
494      * @param containerId a <code>String</code> value
495      * @param documentId a <code>String</code> value
496      * @exception NxqdException if an error occurs
497      */
498     protected void deleteDocument(final String containerId,
499 				  final String documentId) throws NxqdException {
500 	if (!((Boolean)axisConnector.invoke("delete-document",
501 					    Constants.XSD_BOOLEAN,
502 					    new String[]{"container",
503 							 "name"},
504 					    new Object[]{containerId,
505 							 documentId})).booleanValue()) {
506 	    throw new NxqdException("Error deleting document");
507 	}
508     }
509 
510     /**
511      * The <code>documentExists</code> method checks if
512      * the specified document exists. It will return
513      * true if the document exists, false otherwise.
514      * A NxqdException is thrown if other errors occur.
515      *
516      * @param containerId a <code>String</code> value
517      * @param documentId a <code>String</code> value
518      * @return a <code>boolean</code> value
519      * @exception NxqdException if an error occurs
520      */
521     protected boolean documentExists(final String containerId,
522 				     final String documentId) throws NxqdException {
523 	Object result = axisConnector.invoke("document-exists",
524 					     Constants.XSD_BOOLEAN,
525 					     new String[]{"container",
526 							  "name"},
527 					     new Object[]{containerId,
528 							  documentId});
529 	return ((Boolean)result).booleanValue();
530     }
531 
532     /**
533      * The <code>listDocuments</code> method returns a List containing
534      * the document id's managed by the server. This list may
535      * be empty, but it will never be null, and contains <code>String</code>
536      * values.
537      *
538      * @return a <code>List</code> value
539      * @exception NxqdException if an error occurs
540      */
541     protected List listDocuments(final String containerId) throws NxqdException {
542 	Object result = axisConnector.invoke("get-document-list",
543 					     Constants.XSD_STRING,
544 					     new String[]{"container"},
545 					     new Object[]{containerId});
546 	return NxqdUtils.gsoapResultObjectToList(result);
547     }
548 
549     /**
550      * Returns the number of XML Documents in this container.
551      *
552      * @return an <code>long</code> value
553      * @exception XmlException if an error occurs
554      */
555     protected long getNumDocuments(final String containerId) throws NxqdException {
556 	return ((java.math.BigInteger)axisConnector.invoke("get-document-count",
557 							   Constants.XSD_INTEGER,
558 							   new String[]{"container"},
559 							   new Object[]{containerId})).longValue();
560     }
561 
562     ///////////////////////////////////////////////////////////////////////////////////////
563 
564     /**
565        /**
566        * The <code>putBlob</code> method adds the specified blob to the
567        * container using the specified blobId. An exception is thrown if
568        * the specified blobId already exists.
569        *
570        *
571        * @param containerId a <code>String</code> value
572        * @param blobId a <code>String</code> value
573        * @param blob a <code>byte[]</code> value
574        * @exception NxqdException if an error occurs
575        */
576 	protected void putBlob(final String containerId,
577 			       final String blobId, 
578 			       final byte[] blob) throws NxqdException {
579 	    Object ret = axisConnector.invoke("put-blob",
580 					      Constants.XSD_BOOLEAN,
581 					      new String[]{"container",
582 							   "name",
583 							   "doc"},
584 					      new Object[]{containerId,
585 							   blobId,
586 							   blob});
587 	    if (!((Boolean)ret).booleanValue()) {
588 		throw new NxqdException("Error occured while adding the blob");
589 	    }
590 	}
591     
592     /**
593      * The <code>getBlob</code> method retrieves the specified blob from the
594      * container using the specified blobId. An exception is thrown if
595      * the specified blobId does not exist.
596      *
597      * @param containerId a <code>String</code> value
598      * @param blobId a <code>String</code> value
599      * @return a <code>String</code> value
600      * @exception NxqdException if an error occurs
601      */
602     protected byte[] getBlob(final String containerId,
603 			     final String blobId) throws NxqdException {
604 	return (byte[])axisConnector.invoke("get-blob",
605 					    Constants.XSD_BYTE,
606 					    new String[]{"container",
607 							 "name"},
608 					    new Object[]{containerId,
609 							 blobId});
610     }
611     
612     /**
613      * The <code>deleteBlob</code> method deletes the specified blob from this
614      * container using the specified blobId. An exception is thrown if
615      * an error occurred while deleting the document.
616      *
617      * @param containerId a <code>String</code> value
618      * @param blobId a <code>String</code> value
619      * @exception NxqdException if an error occurs
620      */
621     protected void deleteBlob(final String containerId,
622 			      final String blobId) throws NxqdException {
623 	if (!((Boolean)axisConnector.invoke("delete-blob",
624 					    Constants.XSD_BOOLEAN,
625 					    new String[]{"container",
626 							 "name"},
627 					    new Object[]{containerId,
628 							 blobId})).booleanValue()) {
629 	    throw new NxqdException("Error deleting blob");
630 	}
631     }
632 
633     /**
634      * The <code>documentExists</code> method checks if
635      * the specified blob exists. It will return
636      * true if the blob exists, false otherwise.
637      * A NxqdException is thrown if other errors occur.
638      *
639      * @param containerId a <code>String</code> value
640      * @param blobId a <code>String</code> value
641      * @return a <code>boolean</code> value
642      * @exception NxqdException if an error occurs
643      */
644     protected boolean blobExists(final String containerId,
645 				 final String blobId) throws NxqdException {
646 	Object result = axisConnector.invoke("blob-exists",
647 					     Constants.XSD_BOOLEAN,
648 					     new String[]{"container",
649 							  "name"},
650 					     new Object[]{containerId,
651 							  blobId});
652 	return ((Boolean)result).booleanValue();
653     }
654 
655     /**
656      * The <code>listBlobs</code> method returns a List containing
657      * the blob id's managed by the server. This list may
658      * be empty, but it will never be null, and contains <code>String</code>
659      * values.
660      *
661      * @return a <code>List</code> value
662      * @exception NxqdException if an error occurs
663      */
664     protected List listBlobs(final String containerId) throws NxqdException {
665 	Object result = axisConnector.invoke("get-blob-list",
666 					     Constants.XSD_STRING,
667 					     new String[]{"container"},
668 					     new Object[]{containerId});
669 	return NxqdUtils.gsoapResultObjectToList(result);
670     }
671 
672     /**
673      * Returns the number of blobs in the specified container.
674      *
675      * @return an <code>long</code> value
676      * @exception XmlException if an error occurs
677      */
678     protected long getNumBlobs(final String containerId) throws NxqdException {
679 	return ((java.math.BigInteger)axisConnector.invoke("get-blob-count",
680 							   Constants.XSD_INTEGER,
681 							   new String[]{"container"},
682 							   new Object[]{containerId})).longValue();
683     }
684 
685     // -------- The event handling methods ----------
686     private List containerListeners, managerListeners;
687     private long managerPollDelay     = 5000;
688     private long containerPollDelay   = 5000;
689     private Timer pollTimer;
690 
691     public void addNxqdContainerEventListener(NxqdContainerEventListener cl) {
692 	synchronized (containerListeners) {
693 	    containerListeners.add(cl);
694 	    reschedulePollTimers();
695 	}
696     }
697 
698     public void removeNxqdContainerEventListener(NxqdContainerEventListener cl) {
699 	synchronized (containerListeners) {
700 	    containerListeners.remove(cl);
701 	    reschedulePollTimers();
702 	}
703     }
704 
705     /**
706      * The <code>setContainerEventPeriod</code> method sets the polling period for retrieving the 
707      * container event queue from the server.
708      *
709      * @param ms an <code>long</code> value represeting the pollingperiod in milliseconds.
710      * Defaults to 5000.
711      */
712     public void setContainerEventPeriod(long ms) {
713 	containerPollDelay = ms;
714     }
715 
716     public void addNxqdManagerEventListener(NxqdManagerEventListener ml) {
717 	synchronized (managerListeners) {
718 	    managerListeners.add(ml);
719 	    reschedulePollTimers();
720 	}
721     }
722 
723     public void removeNxqdManagerEventListener(NxqdManagerEventListener ml) {
724 	synchronized (managerListeners) {
725 	    managerListeners.remove(ml);
726 	    reschedulePollTimers();
727 	}
728     }
729 
730     /**
731      * The <code>setManagerEventPeriod</code> method sets the polling period for retrieving the 
732      * manager event queue from the server.
733      *
734      * @param ms an <code>long</code> value represeting the pollingperiod in milliseconds.
735      * Defaults to 5000.
736      */
737     public void setManagerEventPeriod(long ms) {
738 	managerPollDelay = ms;
739     }
740 
741     private void reschedulePollTimers() {
742 	if (pollTimer!=null) {
743 	    pollTimer.cancel();
744 	}
745 	pollTimer = new Timer();
746 	if (managerListeners.size()>0) {
747 	    pollTimer.schedule(new ManagerEventTask(),   managerPollDelay, managerPollDelay);
748 	}
749 	if (containerListeners.size()>0) {
750 	    pollTimer.schedule(new ContainerEventTask(), containerPollDelay, containerPollDelay);
751 	}
752     }
753 
754     private void pullGenericEvents(final String methodName,
755 				   final NxqdEvent event, 
756 				   final long pollDelay,
757 				   List listeners) throws NxqdException {
758 
759 	// get the notifs from the server
760 	Object result = axisConnector.invoke(methodName,
761 					     new String[]{"ssid",
762 							  "period"},
763 					     new Object[]{getSessionId(),
764 							  new Long(pollDelay)});
765 	List notifications = NxqdUtils.gsoapResultObjectToList(result);
766 
767 	synchronized (listeners) {
768 	    NxqdEventListener ml;
769 	    NxqdEvent ne = null;
770 	    for (int i = 0; i < notifications.size(); i++) {
771 		try {
772 		    ne = (NxqdEvent)event.getClass().newInstance();
773 		}
774 		catch (Throwable t) {
775 		}
776 		ne.setDetail(notifications.get(i).toString());
777 
778 		for (int j = 0; j < listeners.size(); j++) {
779 		    ml = (NxqdEventListener)listeners.get(j);
780 		    ml.handleEvent(ne);
781 		    switch (ne.getType()) {
782 		    case NxqdManagerEvent.CONTAINER_CREATED :
783 			((NxqdManagerEventListener)ml).handleContainerCreated(ne.getName());
784 			break;
785 		    case NxqdManagerEvent.CONTAINER_DELETED :
786 			((NxqdManagerEventListener)ml).handleContainerDeleted(ne.getName());
787 			break;
788 		    case NxqdManagerEvent.CONTAINER_RENAMED :
789 			((NxqdManagerEventListener)ml).handleContainerRenamed(ne.getName(), ne.getSource());
790 			break;
791 		    case NxqdContainerEvent.RESOURCE_CREATED :
792 			((NxqdContainerEventListener)ml).handleResourceCreated(ne.getSource(), ne.getName());
793 			break;
794 		    case NxqdContainerEvent.RESOURCE_DELETED :
795 			((NxqdContainerEventListener)ml).handleResourceDeleted(ne.getSource(), ne.getName());
796 			break;
797 		    case NxqdContainerEvent.RESOURCE_UPDATED :
798 			((NxqdContainerEventListener)ml).handleResourceUpdated(ne.getSource(), ne.getName());
799 			break;
800 		    }
801 		}
802 	    }
803 	}
804     }
805 
806     private void pullManagerEvents() throws NxqdException {
807 	pullGenericEvents("get-manager-events",
808 			  new NxqdManagerEvent(),
809 			  managerPollDelay,
810 			  managerListeners);
811     }
812     
813     private void pullContainerEvents() throws NxqdException {
814 	pullGenericEvents("get-container-events",
815 			  new NxqdContainerEvent(),
816 			  containerPollDelay,
817 			  containerListeners);
818     }
819 
820     class ManagerEventTask extends java.util.TimerTask {
821 
822 	public ManagerEventTask() {
823 	}
824 
825 	public void run() {
826 	    try {
827 		pullManagerEvents();
828 	    }
829 	    catch (Throwable t) {
830 		t.printStackTrace();
831 	    }
832 	}
833     }
834 
835     class ContainerEventTask extends java.util.TimerTask {
836 
837 	public ContainerEventTask() {
838 	}
839 
840 	public void run() {
841 	    try {
842 		pullContainerEvents();
843 	    }
844 	    catch (NxqdException ne) {
845 		ne.printStackTrace();
846 	    }
847 	}
848     }
849 
850 }