1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  package org.fosstrak.llrp.adaptor;
23  
24  import java.rmi.AlreadyBoundException;
25  import java.rmi.NotBoundException;
26  import java.rmi.RemoteException;
27  import java.rmi.registry.LocateRegistry;
28  import java.rmi.registry.Registry;
29  import java.util.ArrayList;
30  import java.util.HashMap;
31  import java.util.LinkedList;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.concurrent.ConcurrentHashMap;
35  
36  import org.apache.log4j.Logger;
37  import org.fosstrak.llrp.adaptor.config.AdaptorConfiguration;
38  import org.fosstrak.llrp.adaptor.config.ConfigurationLoader;
39  import org.fosstrak.llrp.adaptor.config.ReaderConfiguration;
40  import org.fosstrak.llrp.adaptor.exception.LLRPDuplicateNameException;
41  import org.fosstrak.llrp.adaptor.exception.LLRPRuntimeException;
42  import org.fosstrak.llrp.adaptor.queue.QueueEntry;
43  import org.fosstrak.llrp.client.LLRPExceptionHandler;
44  import org.fosstrak.llrp.client.LLRPExceptionHandlerTypeMap;
45  import org.fosstrak.llrp.client.MessageHandler;
46  import org.llrp.ltk.types.LLRPMessage;
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  public class AdaptorManagement {
96  	
97  	
98  	public static final String DEFAULT_ADAPTOR_NAME = "DEFAULT";
99  	
100 	
101 	
102 	
103 	private static Logger log = Logger.getLogger(AdaptorManagement.class);
104 
105 	
106 	private LLRPExceptionHandler exceptionHandler = null;
107 	
108 	
109 
110 
111 
112 	private boolean commitChanges = true;
113 	
114 	
115 	private String readConfig = null;
116 	
117 	
118 	private String storeConfig = null;
119 	
120 	
121 
122 
123 
124 	private boolean initialized = false;
125 	
126 	
127 	
128 	private boolean export = false;
129 	
130 	
131 	private static boolean error = false;
132 	
133 	
134 	private static LLRPRuntimeException errorException = null;
135 	
136 	
137 	private static LLRPExceptionHandlerTypeMap errorType = null;
138 	
139 	
140 	
141 	
142 	private ConfigurationLoader configLoader = new ConfigurationLoader();
143 
144 	
145 	
146 	
147 	
148 	
149 	
150 	private Map<String, AdaptorWorker> workers = new ConcurrentHashMap<String, AdaptorWorker> ();
151 	
152 	
153 	private Map<String, AdaptorWorker> localWorkers = new ConcurrentHashMap<String, AdaptorWorker> ();
154 	
155 	
156 	private Map<String, AdaptorWorker> remoteWorkers = new ConcurrentHashMap<String, AdaptorWorker> ();
157 	
158 	
159 	private LinkedList<MessageHandler> fullHandlers = new LinkedList<MessageHandler> ();
160 	
161 	
162 	private Map<Class, LinkedList<MessageHandler> > partialHandlers = new HashMap<Class, LinkedList<MessageHandler> > ();
163 	
164 	
165 	
166 	
167 	
168 	
169 
170 
171 
172 
173 
174 
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 	public boolean initialize(
185 			String readConfig, 
186 			String storeConfig,
187 			boolean commitChanges,
188 			LLRPExceptionHandler exceptionHandler,
189 			MessageHandler handler) 
190 		throws LLRPRuntimeException {
191 		
192 		return initialize(readConfig, 
193 				storeConfig, 
194 				commitChanges, exceptionHandler, handler, false);
195 	}
196 	
197 	
198 
199 
200 
201 
202 
203 
204 
205 
206 
207 
208 
209 
210 
211 
212 
213 
214 
215 
216 	public boolean initialize(
217 			String readConfig, 
218 			String storeConfig,
219 			boolean commitChanges,
220 			LLRPExceptionHandler exceptionHandler,
221 			MessageHandler handler,
222 			boolean export) 
223 		throws LLRPRuntimeException {
224 		if (initialized) {
225 			log.error("You cannot initialize the AdaptorManagement twice!\n" +
226 					"use the getters/setters to perform the requested changes!\n" +
227 					"we will abort now!!!");
228 			return false;
229 		}
230 		
231 		this.export = export;
232 		
233 		this.readConfig = readConfig;
234 		this.storeConfig = storeConfig;
235 		this.commitChanges = commitChanges;
236 		this.exceptionHandler = exceptionHandler;
237 		
238 		if (null != handler) {
239 			registerFullHandler(handler);
240 		}
241 		
242 		load();
243 		initialized = true;
244 		return true;
245 	}
246 	
247 	
248 
249 
250 
251 	public boolean isInitialized() {
252 		return initialized;
253 	}
254 	
255 	
256 
257 
258 
259 	public synchronized void reset() throws LLRPRuntimeException {
260 		if (!initialized) {
261 			throw new LLRPRuntimeException("AdaptorManagement is not initialized");
262 		}
263 		clearWorkers();
264 		
265 		
266 		synchronized (fullHandlers) {
267 			fullHandlers.clear();
268 		}
269 		
270 		synchronized (partialHandlers) {
271 			partialHandlers.clear();
272 		}
273 		
274 		
275 		load();
276 		log.debug("finished reset");
277 	}
278 	
279 	
280 
281 
282 
283 	private void load() throws LLRPRuntimeException {
284 		try {
285 			loadFromFile();
286 		} catch (LLRPRuntimeException e) {
287 			setStatus(true, 
288 					e,
289 					LLRPExceptionHandlerTypeMap.EXCEPTION_ADAPTOR_MANAGEMENT_NOT_INITIALIZED);
290 			throw e;
291 		}
292 	}
293 	
294 	
295 
296 
297 	public void commit() {
298 		if (isCommitChanges()) {
299 			try {
300 				storeToFile();
301 			} catch (LLRPRuntimeException e) {
302 				log.debug("could not commit the changes to the configuration file");
303 				setStatus(true, 
304 						e,
305 						LLRPExceptionHandlerTypeMap.EXCEPTION_ADAPTOR_MANAGEMENT_NOT_INITIALIZED);
306 			}
307 		}
308 	}
309 	
310 	
311 
312 
313 
314 	public void checkStatus() throws LLRPRuntimeException {
315 		if (error) {
316 			postException(errorException, errorType, "", "");
317 			throw errorException;
318 		}
319 	}
320 	
321 	
322 
323 
324 	private void setStatus(
325 			boolean error,
326 			LLRPRuntimeException errorException, 
327 			LLRPExceptionHandlerTypeMap errorType) 
328 	{
329 		this.error = error;
330 		this.errorException = errorException;
331 		this.errorType = errorType;
332 	}
333 	
334 	
335 
336 
337 
338 	public synchronized void shutdown() {
339 		log.debug("shutting AdaptorManagement down.");
340 		
341 		
342 		disconnectReaders();
343 		
344 		
345 		synchronized (AdaptorManagement.class) {
346 			synchronized (workers) {
347 				synchronized (localWorkers) {
348 					synchronized (remoteWorkers) {
349 						for (AdaptorWorker worker : workers.values()) {
350 							
351 							worker.tearDown();
352 						}
353 						
354 						for (AdaptorWorker worker : remoteWorkers.values()) {
355 							
356 							try {
357 								worker.getAdaptor().deregisterFromAsynchronous(worker.getCallback());
358 							} catch (RemoteException e) {
359 								log.error("an error occured when deregistering from remote adaptor: " 
360 										+ e.getMessage());
361 							}
362 						}
363 					} 
364 				} 
365 			} 
366 		} 
367 	}
368 	
369 	
370 		
371 	
372 
373 
374 
375 	private synchronized void clearWorkers() throws LLRPRuntimeException {
376 		synchronized (workers) {
377 			synchronized (localWorkers) {
378 				synchronized (remoteWorkers) {
379 					
380 					for (AdaptorWorker worker : workers.values()) {
381 						try {
382 							if (worker.getAdaptorIpAddress() == null) {
383 								
384 								worker.getAdaptor().undefineAll();
385 							}
386 							undefine(worker.getAdaptor().getAdaptorName());
387 						} catch (RemoteException e) {
388 							e.printStackTrace();
389 						}
390 					}		
391 					
392 					
393 					remoteWorkers.clear();
394 					localWorkers.clear();
395 					workers.clear();
396 				}
397 			}
398 		}
399 	}
400 	
401 	
402 
403 
404 	public void disconnectReaders() {
405 		synchronized (workers) {
406 			synchronized (localWorkers) {
407 				for (AdaptorWorker worker : localWorkers.values()) {
408 					try {
409 						worker.getAdaptor().disconnectAll();
410 					} catch (RemoteException e) {
411 						e.printStackTrace();
412 					} catch (LLRPRuntimeException e) {
413 						e.printStackTrace();
414 					}
415 				}
416 			}
417 		}
418 	}
419 	
420 	
421 
422 
423 
424 
425 
426 	public boolean containsAdaptor(String adaptorName) throws LLRPRuntimeException {
427 		checkStatus();
428 	
429 		return workers.containsKey(adaptorName);
430 	}
431 	
432 	
433 
434 
435 
436 
437 
438 	public boolean isLocalAdapter(String adapterName) throws LLRPRuntimeException {
439 		checkStatus();
440 		
441 		return localWorkers.containsKey(adapterName);
442 	}
443 	
444 	
445 
446 
447 
448 
449 
450 
451 
452 	public synchronized String define(String adaptorName, String address) 
453 		throws LLRPRuntimeException, RemoteException, NotBoundException {
454 		checkStatus();
455 		
456 		synchronized (workers) {
457 			synchronized (localWorkers) {
458 				synchronized (remoteWorkers) {
459 					
460 					Adaptor adaptor = null;
461 					if (address != null) {
462 						
463 						
464 						Registry registry = LocateRegistry.getRegistry(address, Constants.registryPort);
465 						adaptor = (Adaptor) registry.lookup(Constants.adaptorNameInRegistry);
466 						
467 						
468 						
469 						log.debug(String.format("adaptor is remote. therefore renaming %s to %s.",
470 								adaptorName, adaptor.getAdaptorName()));
471 						
472 						adaptorName = adaptor.getAdaptorName();
473 					}
474 					
475 					
476 					if (containsAdaptor(adaptorName)) {
477 						log.error("Adaptor '" + adaptorName + "' already exists!");
478 						LLRPDuplicateNameException e = new LLRPDuplicateNameException(adaptorName, 
479 								"Adaptor '" + adaptorName + "' already exists!");
480 						
481 						postException(
482 								e, LLRPExceptionHandlerTypeMap.EXCEPTION_ADAPTOR_ALREADY_EXISTS,
483 								adaptorName, "");
484 						throw e;
485 					}
486 					
487 					AdaptorCallback cb = null;
488 					AdaptorWorker worker = null;
489 					if (address == null) {
490 						
491 						if (export) {
492 							
493 							String HOST_NAME_PREFIX = "server adaptor - ";
494 							String HOST_ADDRESS = String.format("unknown ip %d", System.currentTimeMillis());
495 							try {
496 								java.net.InetAddress localMachine = java.net.InetAddress.getLocalHost();
497 								HOST_ADDRESS = localMachine.getHostAddress();
498 							}
499 							catch (java.net.UnknownHostException uhe) {
500 								log.debug("hmmm, what happened? " +
501 										"This should not occur here :-).");
502 							}
503 							adaptorName = HOST_NAME_PREFIX + HOST_ADDRESS;
504 						}
505 						
506 						
507 						adaptor = new AdaptorImpl(adaptorName);
508 						((AdaptorImpl)adaptor).setAdaptorManagement(this);
509 						cb = new AdaptorCallback(false);
510 						worker = new AdaptorWorker(cb, adaptor);
511 						worker.setAdaptorIpAddress(null);
512 						localWorkers.put(adaptorName, worker);
513 						
514 						log.debug("created a new local adaptor '" + 
515 								adaptorName + "'.");
516 					} else {
517 						
518 						cb = new AdaptorCallback(true);
519 						worker = new AdaptorWorker(cb, adaptor);
520 						
521 						worker.setAdaptorIpAddress(address);
522 						remoteWorkers.put(adaptorName, worker);
523 						
524 						log.debug("created a new client adaptor '" + 
525 								adaptorName + "' with url '" + address + "'.");
526 					}
527 					
528 					
529 					try {
530 						adaptor.registerForAsynchronous(cb);
531 					} catch (RemoteException e) {
532 						e.printStackTrace();
533 					}
534 					
535 					
536 					workers.put(adaptorName, worker);
537 					
538 					
539 					new Thread(worker).start();
540 					
541 					
542 					
543 					if ((export) && (address == null)) {
544 						
545 					
546 						
547 						log.debug("create a registry for the export of the local adaptor.");
548 						LocateRegistry.createRegistry(Constants.registryPort);
549 						Registry registry = LocateRegistry.getRegistry(Constants.registryPort);
550 						
551 						log.debug("bind the adaptor to the registry");
552 						try {
553 							registry.bind(Constants.adaptorNameInRegistry, adaptor);
554 						} catch (AlreadyBoundException e) {
555 
556 							
557 							
558 							log.error("THERE WAS A SEVERE ERROR THAT SHOULD NEVER OCCUR!!!");
559 							e.printStackTrace();
560 						}
561 					}
562 				}
563 			}
564 			
565 			commit();
566 		}
567 		
568 		return adaptorName;
569 	}
570 	
571 	
572 
573 
574 
575 
576 	public synchronized void undefine(String adaptorName) throws LLRPRuntimeException {
577 		checkStatus();
578 		
579 		synchronized (workers) {
580 			synchronized (localWorkers) {
581 				synchronized (remoteWorkers) {
582 					if (!containsAdaptor(adaptorName)) {
583 						log.error("Adaptor '" + adaptorName + "' does not exist!");
584 						LLRPRuntimeException e = new LLRPRuntimeException("Adaptor '" + adaptorName + "' does not exist!");
585 						
586 						postException(
587 								e, LLRPExceptionHandlerTypeMap.EXCEPTION_ADAPTER_NOT_EXIST,
588 								adaptorName, "");
589 						throw e;
590 					}
591 					
592 					localWorkers.remove(adaptorName);
593 					remoteWorkers.remove(adaptorName);
594 					
595 					
596 					AdaptorWorker worker = workers.remove(adaptorName);
597 					try {
598 						worker.getAdaptor().deregisterFromAsynchronous(worker.getCallback());
599 						
600 						worker.tearDown();
601 						
602 					} catch (RemoteException e) {
603 						e.printStackTrace();
604 					}
605 				}
606 			}
607 		}
608 		commit();
609 	}
610 	
611 	
612 
613 
614 
615 	public List<String> getAdaptorNames() throws LLRPRuntimeException {
616 		checkStatus();
617 		
618 		ArrayList<String> adaptorNames = new ArrayList<String> ();
619 		
620 		
621 		for (AdaptorWorker worker : workers.values()) {
622 			try {
623 				adaptorNames.add(worker.getAdaptor().getAdaptorName());
624 				worker.cleanConnFailure();
625 			} catch (RemoteException e) {
626 				worker.reportConnFailure();
627 				log.error("could not connect to remote adaptor: " + e.getMessage());
628 			}
629 			
630 		}
631 		checkWorkers();
632 
633 		return adaptorNames;
634 	}
635 	
636 	
637 
638 
639 
640 
641 
642 	public Adaptor getAdaptor(String adaptorName) throws LLRPRuntimeException {
643 		checkStatus();
644 		
645 		if (!containsAdaptor(adaptorName)) {			
646 			log.error("Adaptor '" + adaptorName + "' does not exist!");
647 			LLRPRuntimeException e = new LLRPRuntimeException("Adaptor '" + adaptorName + "' does not exist!");
648 			
649 			postException(
650 					e, LLRPExceptionHandlerTypeMap.EXCEPTION_ADAPTER_NOT_EXIST,
651 					adaptorName, "");
652 			throw e;
653 		}
654 		
655 		return workers.get(adaptorName).getAdaptor();
656 	}
657 	
658 	
659 
660 
661 
662 
663 	public AdaptorImpl getDefaultAdaptor() throws LLRPRuntimeException {
664 		checkStatus();
665 						
666 		if (!workers.containsKey(DEFAULT_ADAPTOR_NAME)) {
667 			
668 			try {
669 				define(DEFAULT_ADAPTOR_NAME, null);
670 			} catch (Exception e) {
671 				
672 				
673 				log.debug("hmmm, what happened? This should not occur here :-).");
674 			}
675 		}
676 		return (AdaptorImpl)getAdaptor(DEFAULT_ADAPTOR_NAME);
677 	}
678 	
679 	
680 
681 
682 
683 
684 	public boolean isReady(String adaptorName) throws LLRPRuntimeException {
685 		checkStatus();
686 		
687 		if (!containsAdaptor(adaptorName)) {			
688 			log.error("Adaptor '" + adaptorName + "' does not exist!");
689 			LLRPRuntimeException e = new LLRPRuntimeException("Adaptor '" + adaptorName + "' does not exist!");
690 			
691 			postException(
692 					e, LLRPExceptionHandlerTypeMap.EXCEPTION_ADAPTER_NOT_EXIST,
693 					adaptorName, "");
694 			throw e;
695 		}
696 		
697 		return workers.get(adaptorName).isReady();
698 	}
699 	
700 	
701 	
702 
703 
704 
705 
706 
707 
708 
709 	public void enqueueLLRPMessage(String adaptorName, String readerName, LLRPMessage message) throws LLRPRuntimeException {
710 		checkStatus();
711 		
712 		synchronized (workers) {
713 			AdaptorWorker theWorker = null;
714 			if (!workers.containsKey(adaptorName)) {
715 				postException(new LLRPRuntimeException("Adaptor does not exist"), 
716 						LLRPExceptionHandlerTypeMap.EXCEPTION_ADAPTER_NOT_EXIST, adaptorName, readerName);
717 				
718 			} else {
719 				theWorker = workers.get(adaptorName);
720 			}
721 			
722 			if (!theWorker.isReady()) {
723 				LLRPRuntimeException e = new LLRPRuntimeException("Queue is full");
724 				postException(e, LLRPExceptionHandlerTypeMap.EXCEPTION_READER_LOST, "AdaptorManagement", readerName);
725 				throw e;
726 			}
727 			log.debug("enqueueLLRPMessage(" + adaptorName + ", " + readerName + ")");
728 			theWorker.enqueue(new QueueEntry(message, readerName, adaptorName));
729 		}
730 	}
731 	
732 	
733 
734 
735 
736 	public void registerFullHandler(MessageHandler handler) {
737 		synchronized (fullHandlers) {
738 			fullHandlers.add(handler);
739 		}
740 	}
741 	
742 	
743 
744 
745 
746 	public void deregisterFullHandler(MessageHandler handler) {
747 		synchronized (fullHandlers) {
748 			fullHandlers.remove(handler);
749 		}
750 	}
751 	
752 	
753 
754 
755 
756 
757 	public boolean hasFullHandler(MessageHandler handler) {
758 		synchronized (fullHandlers) {
759 			return fullHandlers.contains(handler);
760 		}
761 	}
762 	
763 	
764 
765 
766 
767 
768 	public void registerPartialHandler(MessageHandler handler, Class clzz) {
769 		synchronized (partialHandlers) {
770 			LinkedList<MessageHandler> handlers = partialHandlers.get(clzz);
771 			if (null == handlers) {
772 				handlers = new LinkedList<MessageHandler> ();
773 				partialHandlers.put(clzz, handlers);
774 			}
775 			handlers.add(handler);
776 		}
777 	}
778 	
779 	
780 
781 
782 
783 
784 	public void deregisterPartialHandler(MessageHandler handler, Class clzz) {
785 		synchronized (partialHandlers) {
786 			LinkedList<MessageHandler> handlers = partialHandlers.get(clzz);
787 			if (null != handlers) {
788 				synchronized (handlers) {					
789 					handlers.remove(handler);
790 				}
791 			}
792 		}
793 	}
794 	
795 	
796 
797 
798 
799 
800 
801 	public boolean hasPartialHandler(MessageHandler handler, Class clzz) {
802 		synchronized (partialHandlers) {
803 			LinkedList<MessageHandler> handlers = partialHandlers.get(clzz);
804 			if (null != handlers) {
805 				synchronized (handlers) {
806 					return handlers.contains(handler);
807 				}
808 			}
809 		}
810 		return false;
811 	}
812 	
813 	
814 
815 
816 
817 
818 
819 
820 
821 	public void dispatchHandlers(String adaptorName, String readerName, 
822 			LLRPMessage message) {
823 		
824 		
825 		synchronized (fullHandlers) {
826 			for (MessageHandler handler : fullHandlers) {
827 				handler.handle(adaptorName, readerName, message);
828 			}
829 		}
830 		
831 		
832 		synchronized (partialHandlers) {
833 			LinkedList<MessageHandler> handlers = partialHandlers.get(message.getClass());
834 			if (null != handlers) {
835 				synchronized (handlers) {
836 					for (MessageHandler handler : handlers) {
837 						handler.handle(adaptorName, readerName, message);
838 					}
839 				}
840 			}
841 		}
842 		
843 	}
844 	
845 	
846 
847 
848 
849 
850 
851 
852 	public void postException(
853 			LLRPRuntimeException e, 
854 			LLRPExceptionHandlerTypeMap 
855 			exceptionType, 
856 			String adapterName, 
857 			String readerName) 
858 	{
859 		
860 		if (exceptionHandler == null) {
861 			log.error("ExceptionHandler not set!!!");
862 			e.printStackTrace();
863 			return;
864 		}
865 
866 		log.debug(String.format("Received error call on callback from '%s'.\nException:\n%s", readerName, e.getMessage()));
867 		
868 		exceptionHandler.postExceptionToGUI(exceptionType, e, adapterName, readerName);
869 	}
870 	
871 	
872 	
873 	
874 	
875 	private AdaptorManagement() {}
876 	
877 	
878 	private static AdaptorManagement instance = new AdaptorManagement();
879 	
880 	
881 
882 
883 
884 	public static AdaptorManagement getInstance() {
885 		return instance;
886 	}
887 
888 	
889 	
890 	
891 	private synchronized void createDefaultConfiguration() throws LLRPRuntimeException {
892 			
893 		
894 		storeConfig = null;
895 		
896 		
897 		setCommitChanges(false);
898 		
899 		
900 		clearWorkers();
901 		
902 		
903 		try {
904 			define(DEFAULT_ADAPTOR_NAME, null);
905 		} catch (RemoteException e) {
906 			e.printStackTrace();
907 		} catch (NotBoundException e) {
908 			e.printStackTrace();
909 		}
910 	}
911 	
912 	
913 	
914 
915 
916 
917 
918 
919 	public synchronized void loadFromFile() throws LLRPRuntimeException {
920 	
921 		if (readConfig == null) {
922 
923 			
924 			
925 			
926 			log.info("config not specified -> create a default configuration");	
927 			createDefaultConfiguration();
928 			return;
929 		}
930 		
931 		
932 		boolean commitMode = isCommitChanges();
933 		setCommitChanges(false);
934 		
935 		boolean isExported = false;
936 		synchronized (AdaptorManagement.class) {
937 			synchronized (workers) {
938 				synchronized (localWorkers) {
939 					synchronized (remoteWorkers) {
940 						
941 						
942 						clearWorkers();
943 						
944 						List<AdaptorConfiguration> configurations = null;
945 						try {
946 							configurations = configLoader.getConfiguration(readConfig);
947 						} catch (LLRPRuntimeException e) {
948 							log.info("could not read the config -> create a default configuration");
949 							
950 							createDefaultConfiguration();
951 							return;
952 						}
953 						
954 						for (AdaptorConfiguration adaptorConfiguration : configurations) {
955 							
956 							String adaptorName = adaptorConfiguration.getAdaptorName();
957 							String adaptorIP = adaptorConfiguration.getIp();
958 											
959 							if (adaptorConfiguration.isLocal()) {
960 								log.debug("Load local Adaptor");
961 								adaptorIP = null;
962 							} else {
963 								log.debug(String.format("Load Remote Adaptor: '%s' on '%s'",
964 										adaptorName, 
965 										adaptorConfiguration.getIp()));
966 							}
967 							
968 							boolean adaptorCreated = false;
969 							try {
970 								if ((export) && (isExported)) {
971 									
972 									isExported = true;
973 									define(adaptorName, adaptorIP);
974 								}
975 								adaptorName = define(adaptorName, adaptorIP);
976 	
977 								adaptorCreated = true;
978 								log.debug(String.format("adaptor '%s' successfully created", adaptorName));
979 							} catch (Exception e) {
980 								log.error(String.format("could not create adaptor '%s': %s", adaptorName,
981 										e.getMessage()));
982 							}
983 							
984 							
985 							
986 							if ((adaptorCreated) && (adaptorConfiguration.isLocal())) {
987 								
988 								Adaptor adaptor = getAdaptor(adaptorName);
989 								
990 								if (adaptorConfiguration.getReaderPrototypes() != null) {
991 									for (ReaderConfiguration readerConfiguration : adaptorConfiguration.getReaderPrototypes()) {
992 										
993 										String readerName = readerConfiguration.getReaderName();
994 										String readerIp = readerConfiguration.getReaderIp();
995 										int readerPort = readerConfiguration.getReaderPort();
996 										boolean readerClientInitiated = readerConfiguration.isReaderClientInitiated();
997 										boolean connectImmediately = readerConfiguration.isConnectImmediately();
998 										
999 										log.debug(String.format("Load llrp reader: '%s' on '%s:%d', clientInitiatedConnection: %b, connectImmediately: %b", 
1000 												readerName, readerIp, readerPort, readerClientInitiated, connectImmediately));
1001 										
1002 										
1003 										try {
1004 											
1005 											adaptor.define(readerName, readerIp, readerPort, readerClientInitiated, connectImmediately);
1006 											log.debug(String.format("reader '%s' successfully created", readerName));
1007 										} catch (RemoteException e) {
1008 											log.error(String.format("could not create reader '%s'", readerName));
1009 											e.printStackTrace();
1010 										}
1011 									}
1012 								}
1013 							}
1014 						}
1015 						
1016 					} 
1017 				} 
1018 			} 
1019 		} 
1020 		
1021 		
1022 		setCommitChanges(commitMode);
1023 	}
1024 	
1025 	
1026 
1027 
1028 
1029 
1030 	public synchronized void storeToFile() throws LLRPRuntimeException {
1031 		if (storeConfig == null) {
1032 			log.info("Store config not specified, not storing the configuration.");
1033 			return;
1034 		}
1035 		
1036 		synchronized (AdaptorManagement.class) {
1037 			synchronized (workers) {
1038 				synchronized (localWorkers) {
1039 					synchronized (remoteWorkers) {
1040 						
1041 						List<AdaptorConfiguration> configurations = new LinkedList<AdaptorConfiguration>();
1042 						
1043 		 				for (String adaptorName : workers.keySet()) {
1044 		 					String ip = workers.get(adaptorName).getAdaptorIpAddress();
1045 		 					boolean isLocal = false;
1046 		 					if (ip == null) {
1047 		 						isLocal = true;
1048 		 					}
1049 							configurations.add(
1050 									new AdaptorConfiguration(
1051 											adaptorName, 
1052 											ip,
1053 											isLocal,
1054 											null));
1055 						}
1056 						
1057 		 				for (AdaptorConfiguration configuration : configurations) {
1058 		 					if (configuration.isLocal()) {
1059 			 					List<ReaderConfiguration> readerConfigurations = new LinkedList<ReaderConfiguration> ();
1060 			 					configuration.setReaderConfigurations(readerConfigurations);
1061 			 					
1062 			 					Adaptor adaptor = getAdaptor(configuration.getAdaptorName());
1063 			 					try {
1064 									for (String readerName : adaptor.getReaderNames()) {
1065 										Reader reader = adaptor.getReader(readerName);
1066 										boolean connectImmed = false;	
1067 										boolean clientInit = reader.isClientInitiated();
1068 										String ip = reader.getReaderAddress();
1069 										int port = reader.getPort();
1070 										
1071 										readerConfigurations.add(new ReaderConfiguration(
1072 													readerName,
1073 													ip,
1074 													port,
1075 													clientInit,
1076 													connectImmed
1077 												)
1078 										);
1079 									}
1080 								} catch (RemoteException e) {
1081 									
1082 									e.printStackTrace();
1083 								}
1084 		 					}
1085 		 				}
1086 		 				
1087 		 				try {
1088 		 					configLoader.writeConfiguration(configurations, storeConfig);
1089 		 				} catch (LLRPRuntimeException e) {
1090 		 					postException(e, 
1091 		 							LLRPExceptionHandlerTypeMap.EXCEPTION_ADAPTOR_MANAGEMENT_CONFIG_NOT_STORABLE, 
1092 		 							"", "");
1093 		 				}
1094 		 				
1095 					} 
1096 				} 
1097 			} 
1098 		} 
1099 	}
1100 	
1101 	
1102 	
1103 
1104 
1105 
1106 	public LLRPExceptionHandler getExceptionHandler() {
1107 		return exceptionHandler;
1108 	}
1109 
1110 	
1111 
1112 
1113 
1114 	public void setExceptionHandler(LLRPExceptionHandler exceptionHandler) {
1115 		this.exceptionHandler = exceptionHandler;
1116 	}
1117 
1118 	
1119 
1120 
1121 
1122 
1123 	public boolean isCommitChanges() {
1124 		return commitChanges;
1125 	}
1126 
1127 	
1128 
1129 
1130 
1131 
1132 
1133 
1134 
1135 
1136 	public void setCommitChanges(boolean commitChanges) {
1137 		this.commitChanges = commitChanges;
1138 	}
1139 
1140 	
1141 
1142 
1143 
1144 	public String getReadConfig() {
1145 		return readConfig;
1146 	}
1147 
1148 	
1149 
1150 
1151 
1152 	public void setReadConfig(String readConfig) {
1153 		this.readConfig = readConfig;
1154 	}
1155 
1156 	
1157 
1158 
1159 
1160 	public String getStoreConfig() {
1161 		return storeConfig;
1162 	}
1163 
1164 	
1165 
1166 
1167 
1168 	public void setStoreConfig(String storeConfig) {
1169 		this.storeConfig = storeConfig;
1170 	}
1171 	
1172 	private synchronized void checkWorkers() {
1173 		LinkedList<AdaptorWorker> error = new LinkedList<AdaptorWorker> ();
1174 		synchronized (workers) {
1175 			synchronized (localWorkers) {
1176 				synchronized (remoteWorkers) {
1177 					for (AdaptorWorker worker : workers.values()) {
1178 						if (!worker.ok()) {
1179 							error.add(worker);
1180 						}
1181 					}
1182 					
1183 					
1184 					for (AdaptorWorker worker : error) {
1185 						
1186 						workers.remove(worker);
1187 						remoteWorkers.remove(worker);
1188 						localWorkers.remove(worker);
1189 					}
1190 				}
1191 			}
1192 		}
1193 		commit();
1194 	}
1195 }