View Javadoc

1   package org.opensync.engine.server;
2   
3   import java.io.*;
4   import java.util.*;
5   import org.xml.sax.*;
6   import javax.xml.parsers.*;
7   import javax.mail.MessagingException;
8   
9   import org.springframework.context.*;
10  import org.springframework.context.support.ClassPathXmlApplicationContext;
11  
12  import org.apache.log4j.BasicConfigurator;
13  import org.opensync.tools.*;
14  
15  import org.opensync.engine.admin.gui.AppFrm;
16  import org.opensync.engine.util.I18n;
17  import org.opensync.engine.server.config.ConfigDoc;
18  import org.opensync.engine.server.TaskListener;
19  
20  import org.opensync.xmldb.DatabaseManager;
21  import org.xmldb.api.base.XMLDBException;
22  
23  /***
24   * This class represents the OpenSync application
25   */
26  
27  public class OpenSync implements TaskListener {
28  
29    private static class MonitorInputStreamThread extends Thread {
30  
31          private Reader reader;
32          private Writer writer;
33  
34          public MonitorInputStreamThread(InputStream in) {
35  
36              reader = new InputStreamReader(new BufferedInputStream(in));
37              writer = new OutputStreamWriter(System.out);
38              setDaemon(true);
39          }
40  
41          public void run() {
42  
43              try {
44                  int c;
45                  while ((c = reader.read()) != -1) {
46  
47                      writer.write(c);
48                      writer.flush();
49                  }
50              }
51              catch (IOException ioe) {
52                  ioe.printStackTrace(System.out);
53              }
54              System.out.println("MonitorInputStreamThread exiting...");
55          }
56      }
57  
58  
59    class Flag {
60      boolean flag;
61    }
62  
63    /***
64     * The instance of the OpenSync server
65     *
66     */
67    static protected OpenSync instance;
68  
69    /***
70     * The internal XML database server for
71     * incremental synchronizations
72     */
73    static protected DatabaseManager dbMgr;
74  
75    /***
76     * The config document
77     *
78     */
79    protected ConfigDoc configDoc;
80    /***
81     * The log
82     *
83     */
84    protected Log log;
85    
86    /***
87     * The task scheduler
88     *
89     */
90    protected TasksScheduler tasksScheduler;
91    /***
92     * The frame of the application
93     *
94     */
95    protected AppFrm appFrame;
96    /***
97     * The pool manager
98     *
99     */
100   protected PoolManager poolManager;
101   /***
102    * The home directory of the OpenSync application
103    *
104    */
105   protected String home = null;
106   protected Locale locale = null;
107 
108   protected boolean incrementalMode = false;
109 
110   /***
111    * The command arguments
112    *
113    *
114    */
115   static protected String[] args;
116 
117   /***
118    * The properties of the application
119    *
120    */
121   protected OpenSyncProps properties = new OpenSyncProps();
122 
123   /***
124    * exitOnFinish if true, the application will exit when Agendas are done.
125    * Must be used with a schedule negative time like <schedule daysOfWeek="2" time="-1:01"  />
126    * A negative time tell the scheduler to start immediatly the Agenda with that schedule.
127    */
128   static private boolean exitOnFinish = false;
129 
130   /***
131    * Create the OpenSync object
132    *
133    */
134   public OpenSync() {
135   }
136   /***
137    * Get the instance of the OpenSync object (singleton)
138    *
139    */
140   static public OpenSync getInstance(){
141     if(instance == null){
142       setInstance();
143     }
144     return instance;
145   }
146   /***
147    * Set the instance of the OpenSync object (singleton)
148    *
149    */
150   static protected synchronized void setInstance(){
151     if(instance == null){
152     	ApplicationContext context = new ClassPathXmlApplicationContext("/etc/applicationContext.xml");
153         //instance = new OpenSync();
154     	instance = (OpenSync)context.getBean("openSync");
155     }
156   }
157   /***
158    * Start the OpenSync server
159    *
160    * @exception OpenSyncException
161    * @exception IOException
162    * @exception SAXException
163    * @exception DocumentException
164    * @exception ParserConfigurationException
165    */
166   synchronized protected void start()
167   throws ParserConfigurationException,IOException,OpenSyncException,SAXException {
168 
169     log.setLevel(properties.getLogLevel());
170     poolManager = PoolManager.getInstance();
171     if(!loadState()){
172       configDoc = new ConfigDoc();
173       // Check if the config file is a valid XML file
174       configDoc.checkXML();
175       configDoc.init();
176       // Check if the sources are available (access to database is possible).
177       configDoc.checkSourcesAvailability();
178       tasksScheduler = new TasksScheduler(properties.getSchedulerHttpPort());
179       tasksScheduler.schedule(configDoc.getAgendas(),false);
180     }
181     else{
182       //tasksScheduler.schedule(configDoc.getAgendas(),true);
183       tasksScheduler.schedule(configDoc.getAgendas(),false);
184     }
185     if(appFrame != null){
186       appFrame.getAppPnl().process(configDoc);
187       appFrame.getAppPnl().getLogIfrm().getLogTextPnl().setRollWindow(
188         properties.getGuiLogRollWindow()
189       );
190     }
191     init();
192     tasksScheduler.start();
193   }
194 
195   //TaskListern implements
196   /***
197    * Implements the TaskListenr interface
198    *
199    * @param event the task event
200    */
201   public void taskStart(TaskEvent event) {
202   }
203   /***
204    * Implements the TaskListenr interface
205    *
206    * @param event the task event
207    */
208   synchronized public void taskFail(TaskEvent event){
209 
210     OpenSync openSync = OpenSync.getInstance();
211 
212     event.getTask().setFinish(true);
213     event.getTask().setStatus("failure");
214     try {
215       if (this.getIncrementalMode())
216 	dbMgr.closeDatabase();
217     }
218     catch (XMLDBException xmldbex) {
219       if(openSync != null){
220       	openSync.getLog().error(Log.ROOT,xmldbex.getMessage());
221       }
222     }
223     catch (ClassNotFoundException cnfex) {
224       if(openSync != null){
225       	openSync.getLog().error(Log.ROOT,cnfex.getMessage());
226       }
227     }
228     catch (IllegalAccessException iaex) {
229       if(openSync != null){
230       	openSync.getLog().error(Log.ROOT,iaex.getMessage());
231       }
232     }
233     catch (InstantiationException iex) {
234       if(openSync != null){
235       	openSync.getLog().error(Log.ROOT,iex.getMessage());
236       }
237     }
238     try {
239       notification();
240     }
241     catch (MessagingException mex) {
242       if(openSync != null){
243       	openSync.getLog().error(Log.ROOT,mex.getMessage());
244       }
245     }
246     catch (IOException ioe) {
247       if(openSync != null){
248       	openSync.getLog().error(Log.ROOT,ioe.getMessage());
249       }
250     }
251     catch (SAXException saxex) {
252       if(openSync != null){
253       	openSync.getLog().error(Log.ROOT,saxex.getMessage());
254       }
255     }
256     catch (ParserConfigurationException pcex) {
257       if(openSync != null){
258       	openSync.getLog().error(Log.ROOT,pcex.getMessage());
259       }
260     }
261 
262   }
263   /***
264    * Implements the TaskListenr interface
265    *
266    * @param event the task event
267    */
268   synchronized public void taskStop(TaskEvent event) {
269 
270     OpenSync openSync = OpenSync.getInstance();
271 
272     event.getTask().setFinish(true);
273     event.getTask().setStatus("success");
274     try {
275       notification();
276     }
277     catch (MessagingException mex) {
278       if(openSync != null){
279       	openSync.getLog().error(Log.ROOT,mex.getMessage());
280       }
281     }
282     catch (IOException ioe) {
283       if(openSync != null){
284       	openSync.getLog().error(Log.ROOT,ioe.getMessage());
285       }
286     }
287     catch (SAXException saxex) {
288       if(openSync != null){
289       	openSync.getLog().error(Log.ROOT,saxex.getMessage());
290       }
291     }
292     catch (ParserConfigurationException pcex) {
293       if(openSync != null){
294       	openSync.getLog().error(Log.ROOT,pcex.getMessage());
295       }
296     }
297   }
298 
299   synchronized private String tasksFinish(Collection tasks, Flag notify, String taskLevelMessage) {
300     Iterator tasksIter = tasks.iterator();
301     notify.flag = true;
302     while(tasksIter.hasNext()) {
303       Task task = (Task)tasksIter.next();
304       if (task.getSubTasks().size()>0) {
305         taskLevelMessage = tasksFinish(task.getSubTasks(), notify, taskLevelMessage);
306         notify.flag = notify.flag && task.getFinish();
307       } else {
308         notify.flag = notify.flag && task.getFinish();
309       }
310       if (task.getFinish()) {
311         String taskMessage = "The task "+ task.getName() + " finished with "+ task.getStatus() + ".\r\n";
312         taskLevelMessage += taskMessage;
313       }
314     }
315     return taskLevelMessage;
316   }
317 
318   synchronized private String tasksFail(Collection tasks, Flag notify, String taskLevelMessageFail) {
319     Iterator tasksIter = tasks.iterator();
320     notify.flag = true;
321     while(tasksIter.hasNext()) {
322       Task task = (Task)tasksIter.next();
323       if (task.getSubTasks().size()>0) {
324         taskLevelMessageFail = tasksFail(task.getSubTasks(), notify, taskLevelMessageFail);
325         notify.flag = notify.flag || ( task.getFinish() && task.getStatus().equals("failure"));
326       } else {
327         notify.flag = notify.flag && ( task.getFinish() && task.getStatus().equals("failure"));
328       }
329       if (task.getFinish()) {
330         String taskMessage = "The task "+ task.getName() + " finished with "+ task.getStatus() + ".\r\n";
331         if (task.getStatus().equals("failure")) taskLevelMessageFail += taskMessage;
332       }
333     }
334     return taskLevelMessageFail;
335   }
336 
337   synchronized protected void notification() throws SAXException, ParserConfigurationException, MessagingException, IOException {
338 
339       boolean notifyAll = true;
340 
341       Enumeration elems = configDoc.getAgendas().elements();
342 
343       while(elems.hasMoreElements()){
344 
345         String taskLevelMessage = "";
346         String taskLevelMessageFail = "";
347 
348         Agenda agenda = (Agenda)elems.nextElement();
349 
350         Iterator tasks = agenda.getTasks().iterator();
351 
352         Flag notify = new Flag();
353         notify.flag = true;
354 
355         taskLevelMessage = tasksFinish(agenda.getTasks(), notify, taskLevelMessage);
356         if (Utils.debug) System.out.println("notify after tasksFinish: "+notify.flag);
357 	OpenSync.getInstance().getLog().debug(Log.ROOT,"notify after tasksFinish: "+notify.flag);
358         notifyAll = notifyAll && notify.flag;
359 
360         taskLevelMessageFail = tasksFail(agenda.getTasks(), notify, taskLevelMessageFail);
361         if (Utils.debug) System.out.println("notify after tasksFail: "+notify.flag);
362 	OpenSync.getInstance().getLog().debug(Log.ROOT, "notify after tasksFail: "+notify.flag);
363         notifyAll = notifyAll || notify.flag;
364 
365         if (Utils.debug) System.out.println("notifyAll: "+notifyAll);
366 	OpenSync.getInstance().getLog().debug(Log.ROOT, "notifyAll: "+notifyAll);
367 
368         if (notifyAll && !agenda.getFinish()) {
369           agenda.setFinish(true);
370           Notification notification = agenda.getNotification();
371           if (notification != null) {
372             JMail jmail = notification.initMessage();
373             notification.setSubject(jmail, notification.getSubject(jmail)+" The agenda "+agenda.getName()+ " finished.");
374 
375             if (notification.getLevel().equals("normal")) {
376               notification.setBodyText(jmail, taskLevelMessage);
377             }
378             if (notification.getLevel().equals("verbose")) {
379               notification.setBodyText(jmail, taskLevelMessage);
380               notification.setBodyAttachement(jmail, home+"/log/sophsync.log");
381             }
382             if (notification.getLevel().equals("debug")) {
383               if (taskLevelMessageFail.trim().equals("")) {
384                 notification.setBodyText(jmail, "No tasks finished with failure.");
385               } else {
386                 notification.setBodyText(jmail, taskLevelMessageFail);
387               }
388               notification.setBodyAttachement(jmail, home+"/log/sophsync.log");
389             }
390             try {
391             	notification.sendMessage(jmail);
392 	    } catch(MessagingException me) {
393 	      throw me;
394 	    } catch (IOException ioe) {
395 	      throw ioe;
396 	    }
397           }
398         }
399 
400 	if (agenda.getFinish() && exitOnFinish) {
401 	  tasksScheduler.setExitApp(true);
402 	  System.out.println("OpenSync finished");
403 	  System.exit(0);
404 	}
405 
406       }
407     }
408   /***
409    * Initialize the OpenSync application
410    *
411    */
412   protected void init(){
413     Enumeration elems = configDoc.getAgendas().elements();
414     while(elems.hasMoreElements()){
415       Agenda agenda = (Agenda)elems.nextElement();
416       agenda.setFinish(false);
417       Iterator tasks = agenda.getTasks().iterator();
418       while(tasks.hasNext()){
419         Task task = (Task)tasks.next();
420         init(task);
421       }
422     }
423   }
424   /***
425    * Register the log object to all tasks
426    *
427    * @param task
428    */
429   protected void init(Task task){
430     task.addTaskListener(this);
431     task.addTaskListener(log);
432     task.setFinish(false);
433     Iterator iterator = task.getSubTasks().iterator();
434     while(iterator.hasNext()){
435       Task subTask = (Task)iterator.next();
436       init(subTask);
437     }
438   }
439   /***
440    * Get of the absolute path of a directory (OpenSync_HOME + directory)
441    *
442    * @param directory the directory
443    * @param check check if it exists
444    * @exception FileNotFoundException
445    */
446   public String getDirectoryPath(String directory,boolean check)throws FileNotFoundException{
447     String path = home + System.getProperty("file.separator") + directory;
448     if(check){
449       File file = new File(path);
450       if(!(file.exists() &&  file.isDirectory())){
451         throw new FileNotFoundException(
452           I18n.getInstance().format("error.directory.not-found",new Object[]{path})
453         );
454       }
455     }
456     return path;
457   }
458   /***
459    * Get of the absolute path of a file (OpenSync_HOME + file)
460    *
461    * @param fileName the file name
462    * @param check check if it exists
463    * @exception FileNotFoundException
464    */
465   public String getFilePath(String fileName,boolean check)throws FileNotFoundException{
466     String fileSeparator = System.getProperty("file.separator");
467 
468     String path;
469     if ( (fileName.indexOf(fileSeparator) > 1) || (fileName.indexOf(fileSeparator) == -1) ) path = home + fileSeparator + fileName;
470     else path = home + fileName;
471     if(check){
472       File file = new File(path);
473       if(!(file.exists() &&  file.isFile())){
474         throw new FileNotFoundException(
475           I18n.getInstance().format("error.file.not-found",new Object[]{path})
476         );
477       }
478     }
479     return path;
480   }
481   /***
482    * Get the properties of the application
483    *
484    */
485   public OpenSyncProps getProperties(){
486     return properties;
487   }
488   /***
489    * Get the pool manager
490    *
491    */
492   public PoolManager getPoolManager(){
493     return poolManager;
494   }
495   /***
496    * Get the log
497    *
498    */
499   public Log getLog(){
500     return log;
501   }
502   /***
503    * Get the config document
504    *
505    */
506   public ConfigDoc getConfigDoc(){
507     return configDoc;
508   }
509 
510   /***
511    * Get the incremental mode
512    * @boolean
513    */
514    public boolean getIncrementalMode() {
515      return this.incrementalMode;
516    }
517 
518   /***
519    * Get the application Frame
520    *
521    */
522   public AppFrm getAppFrame(){
523     return appFrame;
524   }
525   /***
526    * Set the application Frame
527    *
528    * @param appFrame the frame a the application
529    */
530   public void setAppFrame(AppFrm appFrame){
531     this.appFrame = appFrame;
532   }
533   /***
534    * Restart the server
535    *
536    */
537   public static void restart() {
538     if(instance.appFrame != null){
539       instance.appFrame.setVisible(false);
540       instance.appFrame = null;
541     }
542     instance.configDoc = null;
543     instance.log = null;
544     instance.tasksScheduler = null;
545     instance.poolManager = null;
546     instance.home = null;
547     instance = null;
548     OpenSync.main(OpenSync.args);
549   }
550 
551   public void loadProperties() throws OpenSyncException, IOException, FileNotFoundException {
552 
553     //this.home = System.getProperty("OpenSync.home");
554     //String fileSeparator = System.getProperty("file.separator");
555     //String path = getFilePath("etc"+fileSeparator+"OpenSync.properties",true);
556     //properties.loadProperties(path);
557 
558     // Set the incremantal mode for synchronizations
559     this.incrementalMode = properties.getIncrementalMode();
560 
561     // Set the XSLT processor and the XML parser from the OpenSyncProperties
562     System.setProperty("javax.xml.transform.TransformerFactory", properties.getXsltProcessorProp());
563     System.setProperty("javax.xml.parsers.SAXParserFactory", properties.getXmlParserProp());
564   }
565 
566   public static void startXMLDatabase() {
567 
568     //
569     // First try to launch the internal native XML database*
570     //
571     if(System.getProperty("xindice.home") == null){
572       System.err.println("No xindice.home property set");
573       usage();
574       System.exit(1);
575     }
576 
577     Process p = null;
578     // Try to stop the XML server (just in case)
579     try {
580       String commandStop = System.getProperty("xindice.home")+
581 			   System.getProperty("file.separator")+
582 			   "bin"+System.getProperty("file.separator")+
583 			   "xindiceadmin shutdown -c /db ";
584       p = OpenSync.executeCmd(commandStop);
585       } catch (IOException ioex) {}
586 
587       try {
588 
589 	p.waitFor();
590 
591 	/* Handle exceptions for waitFor() */
592 
593       } catch (InterruptedException intexc) {
594 
595 	System.out.println("Database already stopped, exit code: " + intexc.getMessage());
596       }
597       System.out.println("Database stopped with exit code:"+ p.exitValue());
598 
599       // Start the XML server before launching OpenSync
600       String commandStart;
601       // Detect the OS to launch the right script
602       String nameOS = System.getProperty("os.name" );
603       if (nameOS.toUpperCase().indexOf("WINDOWS") > -1) {
604 	// Windows script launched
605 	commandStart = System.getProperty("xindice.home")+
606 		System.getProperty("file.separator")+
607 		"startup";
608       } else {
609 	// Unix script launched
610 	commandStart = System.getProperty("xindice.home")+
611 		System.getProperty("file.separator")+
612 		"start";
613       }
614       try {
615 	executeCmd(commandStart);
616       }
617       catch (IOException ioex) {}
618 
619       OpenSync openSync = OpenSync.getInstance();
620 
621       // Test if the XML server is running
622       // Try to create a test collection
623       dbMgr = null;
624       boolean launched = false;
625       while (!launched) {
626 	try {
627 	  dbMgr = new DatabaseManager();
628 	  org.xmldb.api.base.Collection col_test = dbMgr.createCollection("test_col");
629 	  dbMgr.removeCollection("test_col");
630 	  launched = true;
631 	} catch (Exception ex) {
632 	      launched = false;
633 	} finally {
634 	  try {
635 	    dbMgr.closeDatabase();
636 	  }
637 	   catch (XMLDBException xmldbex) {
638 	     if(openSync != null){
639 	     	openSync.getLog().error(Log.ROOT,xmldbex.getMessage());
640 	     }
641 	   }
642 	   catch (ClassNotFoundException cnfex) {
643 	     if(openSync != null){
644 	     	openSync.getLog().error(Log.ROOT,cnfex.getMessage());
645 	     }
646 	   }
647 	   catch (IllegalAccessException iaex) {
648 	     if(openSync != null){
649 	     	openSync.getLog().error(Log.ROOT,iaex.getMessage());
650 	     }
651 	   }
652 	   catch (InstantiationException iex) {
653 	     if(openSync != null){
654 	     	openSync.getLog().error(Log.ROOT,iex.getMessage());
655 	     }
656 	   }
657 	}
658       }
659   }
660 
661   /***
662    * The main of the OpenSync application
663    *
664    * @param args the arguments
665    */
666   public static void main(String[] args) {
667 
668     /* Now, properties set with the OpenSync.properties file :
669     // Properties settings to use Saxon 7.1 as XSL processor, and Xerces-J-2.0.2 as XML parser.
670     System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
671     //System.setProperty("javax.xml.transform.TransformerFactory", "com.icl.saxon.TransformerFactoryImpl");
672     //System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "net.sf.saxon.om.DocumentBuilderFactoryImpl");
673     //System.setProperty("javax.xml.parsers.SAXParserFactory", "net.sf.saxon.aelfred.SAXParserFactoryImpl");
674     System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
675 
676     // Piccolo : high performance XML parser
677     // By default: non validating parser, but able to create validating parser with Xerces for instance.
678     //System.setProperty("javax.xml.parsers.SAXParserFactory", "com.bluecast.xml.JAXPSAXParserFactory");
679     //System.setProperty("com.bluecast.xml.ValidatingSAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
680     //System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
681     */
682 
683   	BasicConfigurator.configure();
684     
685   	OpenSync.args = args;
686     OpenSync openSync = OpenSync.getInstance();
687 
688     try {
689 
690 	      /* Load the properties from the %OpenSync_HOME%\etc\OpenSync.properties file
691 	      Content may look like:
692 	      #in Ko
693 	      gui.log.roll-window=24
694 	      #level ERROR INFO DETAILS
695 	      log.level=INFO
696 	      gui.task.close-when-finish=true
697 	      scheduler.http-port=80
698 	      # true or false
699 	      synchronizer.incremental=true
700 	      */
701     	openSync.loadProperties();
702 
703       if (openSync.getIncrementalMode()) startXMLDatabase();
704 
705       if(!(args.length == 1 && args[0].equalsIgnoreCase("-nogui"))){
706         AppFrm frame = new AppFrm(openSync);
707         frame.show();
708         Thread.sleep(1000);
709       }
710       if(openSync.getHome() == null){
711         System.err.println("No OpenSync.home property set");
712         usage();
713         System.exit(1);
714       }
715 
716       if(openSync.getLocale() == null){
717         System.err.println("No language and country property set");
718         usage();
719         System.exit(1);
720       }
721 
722       String tmp;
723       tmp = System.getProperty("onFinish");
724       exitOnFinish = (tmp != null && tmp.equalsIgnoreCase("exit"));
725 
726       I18n i18n = I18n.getInstance();
727       try {
728       	i18n.setLocale(openSync.getLocale());
729       } catch (java.util.MissingResourceException mre) {
730 	System.out.println(mre.getMessage());
731 	usage();
732 	System.exit(1);
733       }
734       System.out.println(i18n.get("gui.product") + " " + i18n.get("gui.version"));
735       System.out.println(i18n.get("gui.copyright"));
736       System.out.println(i18n.get("gui.comments"));
737       openSync.start();
738     }
739     catch(OpenSyncException e) {
740       e.printStackTrace();
741       if(openSync != null){
742       	openSync.getLog().error(Log.ROOT,e.getMessage());
743       }
744     }
745     catch(SAXException e) {
746       e.printStackTrace();
747       Exception ex = e.getException();
748       if(ex instanceof OpenSyncException){
749       	openSync.getLog().error(Log.ROOT,ex.getMessage());
750       }
751       else{
752         if(OpenSync.getInstance() != null){
753         	openSync.getLog().fatal(Log.ROOT,Log.formatStackTrace(e));
754         }
755       }
756     }
757     catch(Exception e) {
758       if(OpenSync.getInstance() != null){
759       	openSync.getLog().fatal(Log.ROOT,e);
760       }
761       e.printStackTrace();
762     }
763   }
764 
765   static public Process executeCmd(String command) throws IOException {
766 
767     String nameOS = System.getProperty("os.name" );
768 
769     String[] cmd = new String[3];
770 
771     boolean os_found = false;
772 
773     // Test the os.name (cf. http://www.vamphq.com/os.html)
774     if( nameOS.equals( "Windows NT" ) || nameOS.equals("Windows 2000") )
775     {
776       cmd[0]="cmd.exe";
777       cmd[1]="/C";
778       cmd[2]=command;
779       os_found = true;
780     }
781     else if ( nameOS.equals( "Windows 95" ) || nameOS.equals("Windows 98") )
782     {
783       cmd[0]="command.com";
784       cmd[1]="/C";
785       cmd[2]=command;
786       os_found = true;
787     }
788     else if ( nameOS.toUpperCase().equals("LINUX") ||
789               nameOS.toUpperCase().equals("SUNOS") ||
790               nameOS.toUpperCase().equals("SOLARIS") ||
791 	      nameOS.toUpperCase().equals("FREEBSD") ||
792 	      nameOS.toUpperCase().equals("AIX") ||
793 	      nameOS.toUpperCase().equals("IRIX") ||
794 	      nameOS.toUpperCase().equals("HP-UX")
795 	      )
796     {
797       // Support of several Unix
798       cmd[0]="/bin/sh";
799       cmd[1]="-c";
800       cmd[2]=command;
801       os_found = true;
802     } else {
803       // Just launch the command
804       os_found = false;
805     }
806 
807     String s = null;
808     if (Utils.debug) System.out.println("OS name: "+nameOS);
809 
810     Process p;
811     if (os_found) {
812       if (Utils.debug) System.out.println("\ncommand launched: "+cmd[0]+" "+cmd[1]+" "+cmd[2]);
813       p = Runtime.getRuntime().exec(cmd, null);
814     } else {
815       if (Utils.debug) System.out.println("\ncommand launched: "+command);
816       p = Runtime.getRuntime().exec(command, null);
817     }
818     if (Utils.debug) {
819       // Start threads to suck the bytes out of the stderr
820       // and stdout. If you don't do this, Windows will hang.
821 
822       InputStream processOut = p.getInputStream();
823       InputStream processErr = p.getErrorStream();
824 
825       Thread thread = new MonitorInputStreamThread(processOut);
826       thread.start();
827 
828       thread = new MonitorInputStreamThread(processErr);
829       thread.start();
830     }
831 
832     return p;
833 
834   }
835   /***
836    * Print the usage of the command line
837    *
838    */
839   static public void usage(){
840     System.out.println("usage of OpenSync");
841     System.out.println("\t-Dincremental=\"yes\" or \"no\" to set the synchronization incremental mode");
842     System.out.println("\t-DOpenSync.home=OpenSync_HOME to set the OpenSync home directory");
843     System.out.println("\t-DOpenSync.config=OpenSync_CONFIG to set the OpenSync configuration file");
844     System.out.println("\t-DOpenSync.configfolder=OpenSync_CONFIGFOLDER to set the OpenSync configuration file");
845     System.out.println("\t-Dlanguage_country=\"en_US\" to set the language and country of OpenSync (here: english & USA)");
846     System.out.println("\tAvailable languages and countries are: \"en_US\" (english USA), \"fr_FR\" (french FRance)");
847     System.out.println("\t-nogui for no GUI");
848   }
849   /***
850    * Save the state of the server
851    *
852    */
853   synchronized public void saveState(){}
854 
855   synchronized public void saveStateNotWorkingUnderAix(){
856     FileOutputStream fos = null;
857     ObjectOutputStream oos = null;
858     try {
859       File file = new File(getFilePath("etc/sophsync.dat",false));
860       fos = new FileOutputStream(file);
861       oos = new ObjectOutputStream(fos);
862       oos.writeObject(configDoc);
863       oos.writeObject(tasksScheduler);
864     }
865     catch(IOException e){
866       log.fatal(Log.ROOT,e);
867     }
868     finally {
869       try {
870         if(oos != null){
871           oos.close();
872         }
873         if(fos != null){
874           fos.close();
875         }
876       }
877       catch (Exception ex) {
878         log.fatal(Log.ROOT,ex);
879       }
880     }
881   }
882   /***
883    * Load the state of the server
884    *
885    * @exception IOException
886    */
887   public boolean loadState()throws SAXException, ParserConfigurationException, IOException, OpenSyncException {
888     //if(true)return false;
889     String path = null;
890     try {
891       //path = getFilePath("etc/config.xml",true);
892       path = getFilePath(ConfigDoc.getConfigFileName(),true);
893     }
894     catch (FileNotFoundException ex) {
895       log.debug(Log.ROOT,"error.config.file-not-found",null);
896       return false;
897     }
898     long lastModified = new File(path).lastModified();
899     ConfigDoc configDoc_check = new ConfigDoc();
900     // Check if the config file is a valid XML file
901     configDoc_check.checkXML();
902     configDoc_check.readFile();
903     lastModified = configDoc_check.checkLastModified(lastModified);
904 
905     try {
906       String fileSeparator = System.getProperty("file.separator");
907       path = getFilePath("etc"+fileSeparator+"sophsync.dat",true);
908     }
909     catch (FileNotFoundException ex) {
910       log.debug(Log.ROOT,"backup-file.not-found",null);
911       return false;
912     }
913 
914     log.debug(Log.ROOT,"backup-file.found",null);
915     FileInputStream fis = null;
916     ObjectInputStream ois = null;
917     try {
918       fis = new FileInputStream(path);
919       ois = new ObjectInputStream(fis);
920       configDoc = (ConfigDoc)ois.readObject();
921       if(lastModified > configDoc.getLastModified()){
922         log.debug(Log.ROOT,"config-file.modified",null);
923 	configDoc.setLastModified(lastModified);
924         return false;
925       }
926       tasksScheduler = (TasksScheduler)ois.readObject();
927       return true;
928     }
929     catch(Exception e){
930       log.warn(Log.ROOT,"backup-file.bad-version",null);
931       log.warn(Log.ROOT,e.getMessage());
932       // Don't print the stack trace (for end user only)
933       //e.printStackTrace();
934       return false;
935     }
936     finally {
937       try {
938         if(ois != null){
939           ois.close();
940         }
941         if(fis != null){
942           fis.close();
943         }
944       }
945       catch (Exception ex) {
946         log.fatal(Log.ROOT,ex);
947 	// Don't print the stack trace (for end user only)
948 	//e.printStackTrace();
949       }
950     }
951   }
952 /***
953  * @param properties The properties to set.
954  */
955 public void setProperties(OpenSyncProps properties) {
956 	this.properties = properties;
957 }
958 /***
959  * @return Returns the home.
960  */
961 public String getHome() {
962 	return home;
963 }
964 /***
965  * @param home The home to set.
966  */
967 public void setHome(String home) {
968 	this.home = home;
969 }
970 /***
971  * @return Returns the locale.
972  */
973 public Locale getLocale() {
974 	return locale;
975 }
976 /***
977  * @param locale The locale to set.
978  */
979 public void setLocale(Locale locale) {
980 	this.locale = locale;
981 }
982   public void setLog(Log log) {
983     this.log = log;
984   }
985 }