internal static bool addHost(HostUrl hostUrl)     //call locally
 {
     //called by HpnXmlRpcClient.sendJoinRequest()
     //this function will call by current client (locally)
     //when the client receive the hostList it must add each host on this machine of course after register itself on that host by calling addMe function throw XML-RPC
     //and then this function will return 'true' if the addition was successful or 'false' if the addition was failed
     try{
         //check for iterated(repited) host
         String hurl = hostUrl.getHostUrl();
         int    port = hostUrl.getPort();
         for (int index = 0; index < hostsAddresses.Count; index++)
         {
             if (hostsAddresses[index].getHostUrl().Equals(hurl) && hostsAddresses[index].getPort() == port)
             {
                 return(true); //it is already exist does not need to add to hostsAddresses
             }
         }
         hostsAddresses.Add(hostUrl);
         return(true);
         //note: if the add procedure be successful, then a true value will be send
     }catch (System.Exception e) {
         Console.WriteLine("Adding a new host has crached, maybe entered URL or port has a problem.");
         Console.WriteLine(e.Message);
     }
     return(false);       //if the adding process fail in any cases, this false value will show this failure
 }
Exemplo n.º 2
0
        //@Override
        public bool removeMe(String oldHostUrl, int port)                          //Remove a signOff host
        {
            //this function must not be static because it is needed to call by XML-RPC
            //this function will call by a client on another host
            //the client will send its own URL and port to unregister as a signed on host and goes to sign off
            //and then the client will receive 'true' if the elimination was successful or 'false' if the elimination was failed

            //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server
            //is not in its online mode.
            if (!ServerStatus.getServerStatus())
            {
                return(false);
            }

            try{
                //check to find the host in the list
                for (int index = 0; index < hostsAddresses.Count; index++)
                {
                    if (hostsAddresses[index].getHostUrl().Equals(oldHostUrl) && hostsAddresses[index].getPort() == port)
                    {
                        HostUrl hostUrl = hostsAddresses[index];
                        hostsAddresses.RemoveRange(index, 1);
                        tokenRingQueue.remove(hostUrl);
                        break;
                    }
                }
                return(true);
            }
            catch (System.Exception)
            {
            }
            return(false);//if the removing process fail in any cases, this false value will show this failure
        }
        //@Override
        public bool addMe(String newHostUrl, int port)                             //add a signOn host
        {
            //this function must not be static because it is needed to call by XML-RPC

            //this function will call by a client on another host
            //the client will send its own URL and port to register as a new host on this machine
            //and then the client will receive 'true' if the addition was successful or 'false' if the addition was failed

            //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server
            //is not in its online mode.
            if (!ServerStatus.getServerStatus())
            {
                return(false);
            }

            try{
                //check for iterated(repited) host
                for (int index = 0; index < hostsAddresses.Count; index++)
                {
                    if (hostsAddresses[index].getHostUrl().Equals(newHostUrl) && hostsAddresses[index].getPort() == port)
                    {
                        return(true);                    //it means at the previous signoff the address of this host has not removed successfully
                    }
                }
                HostUrl hostUrl = new HostUrl(newHostUrl, port);
                hostsAddresses.Add(hostUrl);
                return(true);
                //note: if the add procedure be successful, then the a true value will be send
            }catch (System.Exception) {
                //Console.WriteLine("Joining a new host has crached, maybe entered URL or port has a problem.");
                //Console.WriteLine(e.Message);
                return(false);//if the adding process fail in any cases, this false value will show this failure
            }
        }
 internal static void removeAllHosts()
 {
     while (hostsAddresses.Count > 2)
     {
         HostUrl hostUrl = hostsAddresses[1];
         hostsAddresses.Remove(hostUrl);
     }
 }
Exemplo n.º 5
0
 internal static void initHostList(int port, String ipv4) //it must call locally in the package by hpn.apache.xml.client.HpnXmlRpcClient Contractor function to register local host and initiate the list
 {                                                        //its modifier must be protected to prevent RPC calls
     if (hostsAddresses.Count <= 0)
     {
         localHostUrl = new HostUrl(port, ipv4);
         hostsAddresses.Add(localHostUrl);  //Set the first server to the local server for internal requests
         tokenRingQueue.add(localHostUrl, false);
     }
 }
 public int compare(HostUrl o2)
 {
     if (this.getHostId() < o2.getHostId())
     {
         return(-1);
     }
     else if (this.getHostId() > o2.getHostId())
     {
         return(1);
     }
     else
     {
         return(0);
     }
 }
        //@Override
        public String joinRequest(String newHostUrl, int port)
        {
            //Console.WriteLine("\nNew joining request from : "+newHostUrl+" port: "+port + " has been received.");
            //this function must not be static because it is needed to call by XML-RPC

            //this function will call by a client on another host
            //the client will send its own URL and port
            //and then the client will receive a list of all hosts

            //because in C# XmlRpcServer Library stoping the servicing has an error we refuse the incoming requests if the server
            //is not in its online mode.
            if (!ServerStatus.getServerStatus())
            {
                return(null);
            }

            try
            {
                bool    flag    = true;
                HostUrl hostUrl = new HostUrl(newHostUrl, port);
                //check for iterated(repited) host
                for (int index = 0; index < hostsAddresses.Count && flag; index++)
                {
                    if (hostsAddresses[index].getHostUrl().Equals(newHostUrl) && hostsAddresses[index].getPort() == port)
                    {
                        flag = false;
                    }
                }
                if (flag)
                {
                    hostsAddresses.Add(hostUrl); //Add the new host that request for joining to the host list of this machine
                }
                //Console.WriteLine("\nNew host has been added : " + hostUrl.getFullUrl());
                return(listAllHostsExcept(hostUrl));
                //note: if the add procedure be successful, then the list of all hosts except local host will be send,
                //if there were no host more than local host it will return an empty String same as "" but not null
            }
            catch (System.Exception)
            { //because of setUrlHost & set port
                //Console.WriteLine("Joining a new host has crached, maybe entered URL or port has a problem.");
                //Console.WriteLine(e.Message);
                return(null);//if the joining process fail in any cases, this null value will show this failure
            }
        }
        internal static String listAllHostsExcept(HostUrl hostUrl)
        {
            //note: if the add procedure be successful, then the list of all hosts except local host and the host that has been added recently will be send,
            //the host that has been added recently must be sent with hostUrl parameter
            //if there were no host more than local host it will return an empty String same as "" but not null
            //if just there is local host it will return null
            String hostsList = "";

            for (int index = 1; index < hostsAddresses.Count; index++)
            {
                if (!(hostsAddresses[index].getHostUrl() == hostUrl.getHostUrl() && hostsAddresses[index].getPort() == hostUrl.getPort()))
                {
                    hostsList += hostsAddresses[index].toString();
                }
                else
                {
                    hostsList = ("true\n" + hostsList);
                }
            }
            return(hostsList);
        }
 internal static bool removeHost(HostUrl hostUrl)
 {
     //this function will call by current client (locally)
     try{
         //check for iterated(repited) host
         String hurl = hostUrl.getHostUrl();
         int    port = hostUrl.getPort();
         for (int index = 0; index < hostsAddresses.Count; index++)
         {
             if (hostsAddresses[index].getHostUrl().Equals(hurl) && hostsAddresses[index].getPort() == port)
             {
                 hostsAddresses.RemoveRange(index, 1);
                 return(true);
             }
         }
     }
     catch (System.Exception e)
     {
         Console.WriteLine("Rupturing an old host has crached, maybe entered URL or port has a problem.");
         Console.WriteLine(e.Message);
     }
     return(false);                       //if the adding process fail in any cases, this false value will show this failure
 }
Exemplo n.º 10
0
 protected abstract bool synchronizeDataBase(HostUrl hostUrl);
        protected override bool synchronizeDataBase(HostUrl hostUrl)
        {
            //called in sendJoinRequest() to get the latest appointments from the known host
            if (this.setDestinationHost(hostUrl))
            {
                Date lmDate = new Date();
                lmDate.resetTime();
                if (calendar.getLastModified() != null)
                {
                    lmDate = calendar.getLastModified();
                }

                //Object[] params = new Object[]{dates};
                host.MethodName = "Calendar.syncRequest";
                host.Params.Clear();
                host.Params.Add(lmDate.ToString());
                try
                {
                    Console.WriteLine("Appointments Syncronization has started ....");
                    response = host.Send(hostUrlAddress);

                    String appointmentLists = (String)response.Value;

                    if (appointmentLists == null)
                    {
                        Console.WriteLine("There is no appointment for synchronization.");
                    }
                    else
                    {
                        String[] lines   = appointmentLists.Split("\n".ToCharArray());
                        Regex    regex   = null;
                        Match    matcher = null;
                        //Set the main seqnum at the current machine!
                        if (lines.Length > 0)
                        {
                            try
                            {
                                regex   = new Regex("SequentialNum:&@\\[(.*?)\\]#!");
                                matcher = regex.Match(lines[0]);
                                if (matcher.Success)
                                {
                                    String mainSeqNumString = matcher.Groups[1].Value;
                                    SequentialNumber.setNextSequentialNumber(Integer.parseInt(mainSeqNumString));
                                    Console.WriteLine("The sequential number has been synchronized successfully.");
                                }
                                else
                                {
                                    Console.WriteLine("Couldn't synchronize the sequential number.");
                                }
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("Couldn't synchronize the sequential number.");
                                Console.WriteLine(e.Message);
                            }
                        }
                        calendar.clearAllAppointments();
                        String seqNum, header, date, time, duration, comment;
                        int    counter       = 0;
                        int    counterFailed = 0;

                        for (int index = 1; index < lines.Length; index++)
                        {
                            try
                            {
                                seqNum   = null;
                                header   = null;
                                date     = null;
                                time     = null;
                                duration = null;
                                comment  = null;
                                //
                                regex   = new Regex("SeqNum:&@\\[(.*?)\\]#!");
                                matcher = regex.Match(lines[index]);
                                if (matcher.Success)
                                {
                                    seqNum = matcher.Groups[1].Value;
                                }
                                //
                                regex   = new Regex("Header:&@\\[(.*?)\\]#!");
                                matcher = regex.Match(lines[index]);
                                if (matcher.Success)
                                {
                                    header = matcher.Groups[1].Value;
                                }
                                //
                                regex   = new Regex("Date:&@\\[(.*?)\\]#!");
                                matcher = regex.Match(lines[index]);
                                if (matcher.Success)
                                {
                                    date = matcher.Groups[1].Value;
                                }
                                //
                                regex   = new Regex("Time:&@\\[(.*?)\\]#!");
                                matcher = regex.Match(lines[index]);
                                if (matcher.Success)
                                {
                                    time = matcher.Groups[1].Value;
                                }
                                //
                                regex   = new Regex("Duration:&@\\[(.*?)\\]#!");
                                matcher = regex.Match(lines[index]);
                                if (matcher.Success)
                                {
                                    duration = matcher.Groups[1].Value;
                                }
                                //
                                regex   = new Regex("Comment:&@\\[(.*?)\\]#!");
                                matcher = regex.Match(lines[index]);
                                if (matcher.Success)
                                {
                                    comment = matcher.Groups[1].Value;
                                }
                                if (seqNum != null && header != null && date != null && time != null && duration != null && comment != null)
                                {
                                    Integer          seqNumber   = new Integer(seqNum);
                                    Integer          secDuration = new Integer(duration);
                                    Date             dateTime    = new Date(date + " " + time, DateString.Format);
                                    SequentialNumber sqn         = new SequentialNumber(seqNumber.intValue());
                                    Appointment      appointment = new Appointment(sqn, dateTime, secDuration.intValue(), header, comment);
                                    calendar.addAppointment(appointment);
                                    counter++;
                                }
                            }
                            catch (Exception)
                            {
                                counterFailed++;
                            }
                        }//end for
                        if (counterFailed > 0)
                        {
                            Console.WriteLine(counterFailed + " numbers of the received appointment in synchronization has failed to add.");
                        }
                        if (counter == 1)
                        {
                            Console.WriteLine("The appointment list has been updated.\n" + counter + " appointment has been added or updated.");
                        }
                        else if (counter > 1)
                        {
                            Console.WriteLine("The appointment list has been updated.\n" + counter + " appointments have been added or updated.");
                        }
                    }//end if
                } catch (Exception e) {
                    Console.WriteLine(e.Message);
                }
            }
            return(false);
        }
 private bool setDestinationHost(HostUrl hostUrl)
 {
     hostUrlAddress = hostUrl.getFullUrl();
     return(true);                //it comes from java implementation
 }
        protected override void sendRuptureRequest()
        {
            // sendRuptureRequest : this function must be call locally when the terminal want to SignOff, and then must clean all hosts from the system except local host because in the next time the host list must be empty
            // this function must be call locally when the terminal want to SignOff, and then must clean all hosts from the system except local host because in the next time the host list must be empty

            Console.WriteLine("");
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("|      <<< Signing Off This Host >>>      |");
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("Please wait to unjoin from all hosts on calendar network!");
            String thisHostIPv4;
            String thisHostUrl;
            int    thisHostPort;

            try
            {
                //Generate the ipv4 address of this machine
                thisHostIPv4 = LocalNet.IpAddress;
                thisHostUrl  = "http://" + thisHostIPv4 + "/";        //Generate the Url of this machine based on its Ip
                thisHostPort = HostsList.getFirstHostUrl().getPort(); //find out the current machine port
                bool result = false;
                //Object[] params = new Object[]{thisHostUrl,thisHostPort};
                host.MethodName = "CalendarNetwork.removeMe";
                host.Params.Clear();
                host.Params.Add(thisHostUrl);
                host.Params.Add(thisHostPort);
                HostsList iterator = new HostsList();
                HostUrl   hostUrl  = iterator.nextHostUrl();
                while (hostUrl != null)
                {
                    if (setDestinationHost(hostUrl))
                    {
                        try
                        {
                            HostsList.removeHost(hostUrl);//Add next host of the list to the hostList of this machine
                            response = host.Send(hostUrlAddress);
                            result   = (bool)response.Value;
                            if (result)
                            {
                                Console.WriteLine("The address of current machine has eliminated on the host : [" + hostUrl.getFullUrl() + "].");
                            }
                            else
                            {
                                Console.WriteLine("Rupturation of the current machine has failed on the host : [" + hostUrl.getFullUrl() + "]");
                            }
                        }
                        catch (System.Exception e)
                        {
                            Console.WriteLine("Rupturation of the current machine has failed on the host : [" + hostUrl.getFullUrl() + "]");
                            Console.WriteLine(e.Message);
                        }
                    }
                    hostUrl = iterator.nextHostUrl();
                }
                Console.WriteLine("All the host was removed successfully!");
                ServerStatus.signOffServer();
                Console.WriteLine("Now this machine will work on offline mode!");
            } catch (Exception e) {
                Console.WriteLine(e.Message);
            }
        }
        protected override void addAppointment()
        {
            Console.WriteLine("");
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("|  <<< Add new appointment procedure >>>  |");
            Console.WriteLine("-------------------------------------------");
            Date date = Reader.nextDateTime();

            Console.Write("Please enter the header/subject of the appointment : ");
            String header = Reader.nextLine();

            Console.Write("Please enter the comment/body of the appointment : ");
            String comment  = Reader.nextLine();
            int    duration = Reader.nextDuration();

            //Object[] params = new Object[]{date, duration, header, comment};
            host.MethodName = "Calendar.createNewAppointment";
            host.Params.Clear();
            host.Params.Add(date.ToString());
            host.Params.Add(duration);
            host.Params.Add(header);
            host.Params.Add(comment);
            try
            {           //it acts on all servers, an iterator on HostList will give the next host
                this.setLocalHost();
                //int sequenceNumber = ((Integer)  host.execute("Calendar.addAppointment", params)).intValue(); //make new appointment on local machine
                response = host.Send(hostUrlAddress);

                int sequenceNumber = (int)response.Value;
                //
                if (sequenceNumber == -1)
                {
                    Console.WriteLine("Adding the new appointment has failed on the local host.");
                }
                else
                {
                    Console.WriteLine("The addition was done successfully on the local host.");
                    //propagate new appointment on all servers, if the addition on local machine was successful!
                    //params = new Object[]{new Integer(sequenceNumber), date, duration, header, comment};
                    host.MethodName = "Calendar.addNewAppointment";
                    host.Params.Clear();
                    host.Params.Add(sequenceNumber);
                    host.Params.Add(date.ToString());
                    host.Params.Add(duration);
                    host.Params.Add(header);
                    host.Params.Add(comment);
                    //
                    HostsList iterator = new HostsList();
                    HostUrl   hostUrl  = iterator.nextHostUrl();
                    if (hostUrl != null)
                    {
                        Console.WriteLine("Now we will try propagating. Please be patient...");
                    }
                    else
                    {
                        Console.WriteLine("There is no other host in the network to propagate this new appointment.");
                    }
                    int counter = 0;
                    while (hostUrl != null)
                    {
                        if (this.setDestinationHost(hostUrl))
                        {
                            try
                            {
                                response = host.Send(hostUrlAddress);
                                bool result = (bool)response.Value;
                                if (!result)
                                {
                                    Console.WriteLine("Adding the new appointment on host [" + hostUrl.getFullUrl() + "] has failed.");
                                }
                                else
                                {
                                    counter++;
                                }
                            }
                            catch (System.Exception e)
                            {
                                Console.WriteLine("Adding the new appointment on host [" + hostUrl.getFullUrl() + "] has failed.");
                                Console.WriteLine(e.Message);
                            }
                        }
                        hostUrl = iterator.nextHostUrl();
                    }
                    if (counter > 0)
                    {
                        Console.WriteLine("This appointment has been sent to " + counter + " host(s).");
                    }
                }
            }
            catch (Exception e) {
                Console.WriteLine(e.Message);
            }
        }
        protected override void sendJoinRequest()
        {
            Console.WriteLine("");
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("| <<< Join Calendar Network procedure >>> |");
            Console.WriteLine("-------------------------------------------");
            Console.Write("Please enter the IPv4 address of a know host that is a member of the calendar network currently : ");
            String ipAddress = Reader.nextIPv4();

            Console.Write("Please enter the port number of the host that you have entered its IP address [" + ipAddress + "]  : ");
            int port = Reader.nextInt(1025, 65535);

            try{
                HostUrl hostUrl = new HostUrl(port, ipAddress);             //Set the destination host based on what the user entered
                if (setDestinationHost(hostUrl))
                {
                    String thisHostIPv4;
                    String thisHostUrl;
                    int    thisHostPort;
                    try
                    {
                        thisHostIPv4 = LocalNet.IpAddress;                     //Generate the ipv4 address of this machine
                        thisHostUrl  = "http://" + thisHostIPv4 + "/";         //Generate the Url of this machine based on its Ip
                        thisHostPort = HostsList.getFirstHostUrl().getPort();  //find out the current machine port

                        if (thisHostIPv4.Equals(ipAddress) && thisHostPort == port)
                        {
                            Console.WriteLine("You can not connect to yourself.\nThe IP address and the port number that you have entered is blonged to this machine.");
                            return;
                        }


                        host.MethodName = "CalendarNetwork.joinRequest";
                        host.Params.Clear();
                        host.Params.Add(thisHostUrl);
                        host.Params.Add(thisHostPort);

                        ServerStatus.signOnServer();                     //if the joining fail it must change to signoff again
                        //String hostsListString = (String) host.execute("CalendarNetwork.joinRequest", params); //joinRequest function is placed in HostList.java file
                        response = host.Send(hostUrlAddress);
                        String hostsListString = (String)response.Value;

                        //
                        if (hostsListString == null)
                        {
                            Console.WriteLine("The joining process was failed on the known host that you have introduced.");
                            ServerStatus.signOffServer();                         //because the joining fail it must change to signoff again
                            return;
                        }
                        else
                        {
                            String[] lines = hostsListString.Split("\n".ToCharArray());
                            if (lines[0].Equals("true"))
                            {
                                HostsList.addHost(hostUrl);//At first Add the known host to the hostList of this machine after a successful connection
                            }
                            else
                            {
                                Console.WriteLine("The joining process was failed on the known host that you have introduced.");
                                ServerStatus.signOffServer(); //because the joining fail it must change to signoff again
                                return;
                            }
                            //sending new request to synchronize the appointments' list
                            this.synchronizeDataBase(hostUrl);
                            Console.WriteLine("The synchronizing stage has finished.\nNow we register this host on other hosts!");
                            String nextHostUrl, nextHostPort;
                            bool   result = false;
                            //host.MethodName = "CalendarNetwork.addMe"; //Added in C#
                            for (int index = 1; index < lines.Length; index++)
                            {
                                nextHostUrl  = null;
                                nextHostPort = null;
                                //The response must be parse and other hosts come out from the String and propagate the current machine on all of them
                                //Must parse each address and send requests separately

                                //At first find the url of the next host
                                Regex regex   = null;
                                Match matcher = null;
                                regex   = new Regex("URL:\\[(.*?)\\]");
                                matcher = regex.Match(lines[index]);
                                if (matcher.Success)
                                {
                                    nextHostUrl = matcher.Groups[1].Value;
                                }
                                //Then find the port number string
                                regex   = new Regex("Port:\\[(.*?)\\]");
                                matcher = regex.Match(lines[index]);
                                if (matcher.Success)
                                {
                                    nextHostPort = matcher.Groups[1].Value;
                                }
                                //Now connect to the next host and register
                                if (nextHostUrl != null && nextHostPort != null)
                                {
                                    hostUrl = new HostUrl(nextHostUrl, Integer.parseInt(nextHostPort));                                 //Set the destination host based on what the user entered
                                    if (setDestinationHost(hostUrl))
                                    {
                                        host.MethodName = "CalendarNetwork.addMe";
                                        host.Params.Clear();
                                        host.Params.Add(thisHostUrl);
                                        host.Params.Add(thisHostPort);
                                        try
                                        {
                                            response = host.Send(hostUrlAddress);
                                            result   = (bool)response.Value;
                                            if (result)
                                            {
                                                HostsList.addHost(hostUrl);//Add next host of the list to the hostList of this machine
                                            }
                                            else
                                            {
                                                Console.WriteLine("Registeration of the current machine has failed on the host : [" + hostUrl.getFullUrl() + "]");
                                            }
                                        }
                                        catch (System.Exception e)
                                        {
                                            Console.WriteLine("Registeration of the current machine has failed on the host : [" + hostUrl.getFullUrl() + "]");
                                            Console.WriteLine(e.Message);
                                        }
                                    }
                                }
                            }                //End of for
                        }                    //End of else
                    } catch (Exception e) {
                        Console.WriteLine(e.Message);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        protected override void modifyAppointment()
        {
            // modifyAppointment : it will call locally to change an appointment and then propagate modifications
            Console.WriteLine("");
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("| <<< Modify an appointment procedure >>> |");
            Console.WriteLine("-------------------------------------------");

            Console.Write("Please enter the sequential number of the appointment : ");
            int         seqNum            = Reader.nextInt();
            Appointment appointmentCopy   = calendar.getAppointmentCopy(seqNum);
            String      appointmentString = calendar.getAppointmentString(seqNum);

            while (appointmentString == null)
            {
                Console.WriteLine("The sequential number that you have entered is not belonged to any appointment.");
                Console.WriteLine("Please try again. Or enter 0 to return the main menu.");
                Console.Write("Please enter the sequential number of the appointment : ");
                seqNum = Reader.nextInt();
                if (seqNum < 1)
                {
                    return;
                }
                appointmentString = calendar.getAppointmentString(seqNum);
            }
            appointmentCopy = calendar.getAppointmentCopy(seqNum);
            Console.WriteLine("The sequential number that you have entered is belonged to the following appointment : ");
            Console.WriteLine(appointmentString);
            while (true)
            {
                Console.Write("\nAre you sure you want to modify this appointment ? [Y/N] : ");
                char response = Reader.nextChar();
                if (response == 'n' || response == 'N')
                {
                    return;
                }
                else if (response == 'y' || response == 'Y')
                {
                    break;
                }
                else
                {
                    Console.Write("The character that you have entered ['" + response + "'] is not correct. You can just enter a character from the set {'n','N','y','Y'}.");
                }
            }

            bool hasChangedFlag = false;
            Date date;

            while (true)
            {
                Console.WriteLine("The date and the time of this appointment is : " + appointmentCopy.getDateTimeString());
                Console.Write("\nDo you want to modify the date & time of this appointment ? [Y/N] : ");
                char response = Reader.nextChar();
                if (response == 'n' || response == 'N')
                {
                    date = appointmentCopy.getDateTime();
                    Console.WriteLine("The date and the time of the appointment has set to its previous value.");
                    break;
                }
                else if (response == 'y' || response == 'Y')
                {
                    Console.WriteLine("So please enter new date and time parameters for this appointment.");
                    date           = Reader.nextDateTime();
                    hasChangedFlag = true;
                    break;
                }
                else
                {
                    Console.Write("The character that you have entered ['" + response + "'] is not correct. You can just enter a character from the set {'n','N','y','Y'}.");
                }
            }


            String header;

            while (true)
            {
                Console.WriteLine("The header of this appointment is : " + appointmentCopy.getHeader());
                Console.Write("\nDo you want to modify the header of this appointment ? [Y/N] : ");
                char response = Reader.nextChar();
                if (response == 'n' || response == 'N')
                {
                    header = appointmentCopy.getHeader();
                    Console.WriteLine("The header of the appointment has set to its previous value.");
                    break;
                }
                else if (response == 'y' || response == 'Y')
                {
                    Console.WriteLine("So please enter a new header for this appointment.");
                    header         = Reader.nextLine();
                    hasChangedFlag = true;
                    break;
                }
                else
                {
                    Console.Write("The character that you have entered ['" + response + "'] is not correct. You can just enter a character from the set {'n','N','y','Y'}.");
                }
            }

            String comment;

            while (true)
            {
                Console.WriteLine("The comment of this appointment is : " + appointmentCopy.getComment());
                Console.Write("\nDo you want to modify the comment of this appointment ? [Y/N] : ");
                char response = Reader.nextChar();
                if (response == 'n' || response == 'N')
                {
                    comment = appointmentCopy.getComment();
                    Console.WriteLine("The comment of the appointment has set to its previous value.");
                    break;
                }
                else if (response == 'y' || response == 'Y')
                {
                    Console.WriteLine("So please enter a new comment for this appointment.");
                    comment        = Reader.nextLine();
                    hasChangedFlag = true;
                    break;
                }
                else
                {
                    Console.Write("The character that you have entered ['" + response + "'] is not correct. You can just enter a character from the set {'n','N','y','Y'}.");
                }
            }

            int duration;

            while (true)
            {
                Console.WriteLine("The duration of this appointment is : " + appointmentCopy.getSecDurationString());
                Console.Write("\nDo you want to modify the duration of this appointment ? [Y/N] : ");
                char response = Reader.nextChar();
                if (response == 'n' || response == 'N')
                {
                    duration = appointmentCopy.getSecDuration();
                    Console.WriteLine("The duration of the appointment has set to its previous value.");
                    break;
                }
                else if (response == 'y' || response == 'Y')
                {
                    Console.WriteLine("So please enter a new duration time for this appointment.");
                    duration       = Reader.nextDuration();
                    hasChangedFlag = true;
                    break;
                }
                else
                {
                    Console.Write("The character that you have entered ['" + response + "'] is not correct. You can just enter a character from the set {'n','N','y','Y'}.");
                }
            }

            while (hasChangedFlag)
            {
                Console.Write("\nAre you sure you want to save the changes for this appointment ? [Y/N] : ");
                char response = Reader.nextChar();
                if (response == 'n' || response == 'N')
                {
                    return;
                }
                else if (response == 'y' || response == 'Y')
                {
                    break;
                }
                else
                {
                    Console.Write("The character that you have entered ['" + response + "'] is not correct. You can just enter a character from the set {'n','N','y','Y'}.");
                }
            }

            //Object[] params = new Object[]{seqNum, date, duration, header, comment};
            host.MethodName = "Calendar.modifyAppointment";
            host.Params.Clear();
            host.Params.Add(seqNum);
            host.Params.Add(date.ToString());
            host.Params.Add(duration);
            host.Params.Add(header);
            host.Params.Add(comment);
            try
            {           //it acts on all servers, an iterator on HostList will give the next host
                if (this.setLocalHost())
                {
                    //bool result = (bool)  host.execute("Calendar.modifyAppointment", params); //make new appointment on local machine
                    response = host.Send(hostUrlAddress);
                    bool result = (bool)response.Value;
                    if (!result)
                    {
                        Console.WriteLine("Modifying the appointment has failed on the local host.");
                    }
                    else
                    {
                        Console.WriteLine("The modification was done successfully on the local host.\nNow we will try propagating. Please be patient...");
                        //propagate new appointment on all servers, if the addition on local machine was successful!
                        HostsList iterator = new HostsList();
                        HostUrl   hostUrl  = iterator.nextHostUrl();
                        int       counter  = 0;
                        while (hostUrl != null)
                        {
                            if (this.setDestinationHost(hostUrl))
                            {
                                try
                                {
                                    response = host.Send(hostUrlAddress);
                                    result   = (bool)response.Value;
                                    if (!result)
                                    {
                                        Console.WriteLine("Modifying of the appointment on host [" + hostUrl.getFullUrl() + "] has failed.");
                                    }
                                    else
                                    {
                                        counter++;
                                    }
                                }
                                catch (System.Exception e)
                                {
                                    Console.WriteLine("Modifying of the appointment on host [" + hostUrl.getFullUrl() + "] has failed.");
                                    Console.WriteLine(e.Message);
                                }
                            }
                            hostUrl = iterator.nextHostUrl();
                        }
                        if (counter > 0)
                        {
                            Console.WriteLine("Modifying was done on " + counter + " hosts.");
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Due to not resolving localhost server, the execution was droped.");
                }
            } catch (Exception e) {
                Console.WriteLine(e.Message);
            }
        }
        protected override void removeAppointment()
        {
            // removeAppointment : it must call locally to remove an appointment and then call XML-RPC to execute on all other machines
            Console.WriteLine("");
            Console.WriteLine("-------------------------------------------");
            Console.WriteLine("|   <<< Remove appointment procedure >>>  |");
            Console.WriteLine("-------------------------------------------");
            Console.Write("Please enter the sequential number of the appointment : ");
            int    seqNum            = Reader.nextInt();
            String appointmentString = calendar.getAppointmentString(seqNum);

            while (appointmentString == null)
            {
                Console.WriteLine("The sequential number that you have entered is not belonged to any appointment.");
                Console.WriteLine("Please try again. Or enter 0 to return the main menu.");
                Console.Write("Please enter the sequential number of the appointment : ");
                seqNum = Reader.nextInt();
                if (seqNum < 1)
                {
                    return;
                }
                appointmentString = calendar.getAppointmentString(seqNum);
            }

            Console.WriteLine("The sequential number that you have entered is belonged to the following appointment : ");
            Console.WriteLine(appointmentString);
            while (true)
            {
                Console.Write("\nAre you sure you want to delete this appointment ? [Y/N] : ");
                char response = Reader.nextChar();
                if (response == 'n' || response == 'N')
                {
                    return;
                }
                else if (response == 'y' || response == 'Y')
                {
                    break;
                }
                else
                {
                    Console.Write("The character that you have entered ['" + response + "'] is not correct. You can just enter a character from the set {'n','N','y','Y'}.");
                }
            }


            //Object[] params = new Object[]{seqNum};
            host.MethodName = "Calendar.removeAppointment";
            host.Params.Clear();
            host.Params.Add(seqNum);

            try
            {
                if (this.setLocalHost())
                {
                    response = host.Send(hostUrlAddress);

                    bool result = (bool)response.Value;

                    if (!result)
                    {
                        Console.WriteLine("Removing this appointment has failed on the local host. Maybe you entered a wrong sequence number.");
                    }
                    else
                    {
                        Console.WriteLine("The deletation was done successfully on the local host.\nNow we will try propagating. Please be patient...");
                        //propagate remove action on all servers, if the remove action on local machine was successful!
                        HostsList iterator = new HostsList();
                        HostUrl   hostUrl  = iterator.nextHostUrl();
                        int       counter  = 0;
                        while (hostUrl != null)
                        {
                            if (this.setDestinationHost(hostUrl))
                            {
                                try
                                {
                                    response = host.Send(hostUrlAddress);

                                    result = (bool)response.Value;

                                    if (!result)
                                    {
                                        Console.WriteLine("Removing the entered appointment [SeqNum : " + seqNum + "] on host [" + hostUrl.getFullUrl() + "] has failed.");
                                    }
                                    else
                                    {
                                        counter++;
                                    }
                                }
                                catch (System.Exception e)
                                {
                                    Console.WriteLine("Removing the entered appointment [SeqNum : " + seqNum + "] on host [" + hostUrl.getFullUrl() + "] has failed.");
                                    Console.WriteLine(e.Message);
                                }
                            }
                            hostUrl = iterator.nextHostUrl();
                        }
                        if (counter > 0)
                        {
                            Console.WriteLine("This appointment has removed from " + counter + " host(s).");
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Due to not resolving localhost server, the execution was droped.");
                }
            } catch (Exception e) {
                Console.WriteLine(e.Message);
            }
        }