//$Id
//
package com.util;

//java imports
import java.util.Properties;
import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
import java.io.StringReader;
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.*; 
import java.io.*;
import javax.xml.transform.stream.*;
import java.util.Vector;
import java.util.List;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
import java.util.Timer;
import java.net.URI;

/**
 * Acts as an utility class for documents management.
 * This class forms the request for zoho services, excutes them and handles the response.
 *
 * @version 1.0
 */
public class ZohoUtil
{

    /**
     * Zoho API key. 
     */
    public static String API_KEY = URLDataHandler.getUserSettings().getProperty("apiKey");
  //      "394117ed10cb8020fc89e9cf05271724"; // APIKEY needs to be changed
    
    /**
     * Used in forming the URL for fetching the Zoho Writer private documents.
     */
    public static String writerGetDocsURL = "http://export.writer.zoho.com/api/private"+
                          "/xml/documents1?apikey="+API_KEY+"&ticket=";

    /**
     * Used in forming the URL for fetching the Zoho Sheet private documents(workbooks).
     */
    public static String sheetGetDocsURL = "http://sheet.zoho.com/api/private/"+
                          "xml/books1?apikey="+API_KEY+"&ticket=";

    /**
     * Used in forming the URL for fetching the Zoho Show private documents(presentations). 
     */
    public static String showGetDocsURL = "http://show.zoho.com/api/private/"+
                          "xml/presentations1?apikey="+API_KEY+"&ticket=";

    /**
     * Writer editor URL - for editing the existing document 
     */
    public static String writerEditorURL = "http://writer.zoho.com/home.do?" ;
    
    /**
     * Sheet editor URL - for editing the existing document
     */
    public static String sheetEditorURL = 
        "http://sheet.zoho.com/open.do?sidebar=hidden&top=entrepreneur" ;

    /**
     * Show editor URL - for editing the existing document
     */
    public static String showEditorURL = "http://show.zoho.com/Edit.do?" ;

    /**
     * Used in forming the URL for fetching the content of a document in Writer. 
     */
    public static String writerDocContentURL = 
        "http://export.writer.zoho.com/api/private/xml/content/";


    /**
     * Used in forming the URL for Zoho Sheet preview
     */
    public static String sheetPreviewURL = 
        "http://sheet.zoho.com/open.do?export=html&prt=preview&docid=";

    /**
     * Writer editor URL - for new document
     */
    public static String newWriterURL = "http://writer.zoho.com/home.do" ;

    /**
     * Sheet editor URL - for new document
     */
    public static String newSheetURL = 
        "http://sheet.zoho.com/home.do?sidebar=hidden&top=entrepreneur" ;

    /**
     * Show editor URL - for new document
     */
    public static String newShowURL = 
        "http://show.zoho.com/New.do?NEW_DOC=true&TP=true";

    /**
     * Used in forming the URL for deleting Writer document.
     */
    public static String deleteWriterDocUrl = 
        "http://export.writer.zoho.com/api/private/xml/deleteDocument/" ;

    /**
     * Used in forming the URL for deleting Sheet document.
     */
    public static String deleteSheetDocUrl = 
        "http://sheet.zoho.com/api/private/xml/deletebook/" ;

    /**
     * Used in forming the URL for deleting Show document.
     */
    public static String deleteShowDocUrl = 
        "http://show.zoho.com/api/private/xml/deletepresentation/" ;

    /**
     * Used in forming the URL for thrashing Writer document.
     */
    public static String thrashWriterDocUrl = 
        "http://export.writer.zoho.com/api/private/xml/trashDocument/";

    /**
     * Used in forming the URL for thrashing Sheet document.
     */
    public static String thrashSheetDocUrl = 
        "http://sheet.zoho.com/api/private/xml/trashbook/";

    /**
     * Used in forming the URL for thrashing Show document.
     */
    public static String thrashShowDocUrl = 
        "http://show.zoho.com/api/private/xml/trashpresentation/";

    /**
     * Used in forming the URL for getting the private documents count in Writer.
     */
    public static String writerDocsCountURL = 
        "http://export.writer.zoho.com/api/private/xml/documents/count?";

    /**
     * Used in forming the URL for getting the private documents count in Sheet.
     */
    public static String sheetDocsCountURL = 
        "http://sheet.zoho.com/api/private/xml/books/count?";

    /**
     * Used in forming the URL for getting the private documents count in Show.
     */
    public static String showDocsCountURL = 
        "http://show.zoho.com/api/private/xml/presentations/count?";

    /**
     * Used in forming the URL for fetching the shared documents in Writer.
     */
    public static String getSharedWriterDocsURL = 
        "http://export.writer.zoho.com/api/private/xml/incomingdocuments?apikey="
        +API_KEY+"&ticket=";

    /**
     * Used in forming the URL for fetching the shared documents in Sheet.
     */
    public static String getSharedSheetDocsURL = 
        "http://sheet.zoho.com/api/private/xml/incomingbooks?apikey="
        +API_KEY+"&ticket=";

    /**
     * Used in forming the URL for fetching the shared documents in Show.
     */
    public static String getSharedShowDocsURL = 
        "http://show.zoho.com/api/private/xml/incomingpresentations?apikey="
        +API_KEY+"&ticket=";

    /**
     * Used in forming the URL for sharing a document in Writer.
     */
    public static String shareWriterDocURL = 
        "http://export.writer.zoho.com/api/private/json/shareDocument/";

    /**
     * Used in forming the URL for sharing a document in Sheet.
     */
    public static String shareSheetDocURL = 
        "http://sheet.zoho.com/api/private/json/shareBook/";

    /**
     * Used in forming the URL for sharing a document in Show.
     */
    public static String shareShowDocURL = 
        "http://show.zoho.com/api/private/json/sharepresentation/"; 

    /**
     * Used in forming the URL for cancel-sharing of a document in Sheet.
     */
    public static String cancelSheetShareURL = 
        "http://sheet.zoho.com/api/private/xml/cancelSharing/";

    /**
     * Used in forming the URL for cancel-sharing of a document in Show.
     */
    public static String cancelShowShareURL = 
        "http://show.zoho.com/api/private/xml/cancelsharing/";

    /**
     * Used in forming the URL for cancel-sharing of a document in Writer.
     */
    public static String cancelWriterShareURL = 
        "http://export.writer.zoho.com/api/private/xml/cancelsharing/";


    /**
     * Cancels the sharing of a document for the given list of emailIds.
     * If cancelling process is failed for few emailIds, those emailIds will be returned with comma separation.
     *
     * @param docId - Document Id
     * @param docType - Document type
     * @param apiTicket - User ticket associated with zoho service
     * @param usersId - list of emailIds(with comma separated).
     * @return String - list of emailIds(with comma separated) for which the cancelling process is failed.
     */
    public static String cancelShare(String docId , String docType , 
                 String apiTicket,String usersId)
    {
        System.out.println("ZohoUtil:cancelShare::docId:"+
            docId+"******* docType:"+docType+"****** apiTicket:"+
            apiTicket+"********* usersId:"+usersId+"***");
        String response = "";
        try
        {
            String prefixURL = docId+"?apikey="+API_KEY+"&ticket="+apiTicket;
            String urll = "";
            if(docType.equals("document") || docType.equals("workbook")
                  || docType.equals("presentation"))
            {
                if(docType.equals("document"))
                {
                    urll = cancelWriterShareURL+prefixURL+"&emailid=";
                }
                else if(docType.equals("workbook"))
                {
                    urll = cancelSheetShareURL+prefixURL+"&userId=";
                }
                else if(docType.equals("presentation"))
                {
                    urll = cancelShowShareURL+prefixURL+"&emailid=";
                }
                if(usersId != null && !usersId.trim().equals(""))
                {
                    StringTokenizer st = new StringTokenizer(usersId , ",");
                    while(st.hasMoreTokens())
                    {
                        String id = st.nextToken().toString();
                        if(!id.trim().equals(""))
                        {
                            String completeUrll = urll+id;
                            String rrsp = getURLResponse(completeUrll,"POST","");
                            //System.out.println("ZohoUtil:"+
                            //   "cancelSharing:url::"+completeUrll+"****"
                            //   +"response::"+rrsp);    
                            if(checkErrorInResponse(rrsp))
                            {
                                if(!response.trim().equals(""))
                                {
                                    response = response + ",";
                                }
                                response = response + id;
                            }
                        }
                    }
                }
                
            }
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil:cancelShare::docId:"+
                    docId+"******* docType:"+docType+"****** apiTicket:"+
                    apiTicket+"********* usersId:"+usersId+"***");
            e.printStackTrace();    
        }
        return response;
    }



    /**
     * Shares a Sheet document to the given emailIds based on their access permission.
     * Checks the emailIds of readOnlyUsers and editUsers. Filters out the emailIds not registered in the zohoconnect assist database.And shares the document only for the emailIds of the registered zohoconnect users. Returns the response of the sharing and the list of emailIds of the non-zohoconnect users in JSON format.
     * And also sends email to the shared emailIds using {@link com.ea.zoho.server.util.ShareMailThread}.
     *
     * @param ticket - User ticket associated with zoho service
     * @param readOnlyUsers - list of emailIds with read only permission
     * @param editUsers - list of emailIds with read and write permissions
     * @param docId - Document Id
     * @param userName - Name of the user who shares
     * @return String - Response of the sharing and the list of emailIds of the non-zohoconnect users in JSON format.
     */
    public static String shareSheetDoc(String ticket, String readOnlyUsers,
                      String editUsers,String docId,String userName)
    {
        System.out.println("ZohoUtil:shareSheetDoc:ticket:"+ticket
           +"****readOnlyUsers:"+readOnlyUsers+"*****editUsers:"+
           editUsers+"****docId:"+docId+"********userName:"+userName);    
        String urll = shareSheetDocURL+docId+"?apikey="+API_KEY
                      +"&ticket="+ticket;
        String notAvailableUsers = "";
        if(readOnlyUsers != null && !readOnlyUsers.trim().equals(""))
        {
           /* String[] usersInEnt = filterEntrepreneurUser(readOnlyUsers);
            readOnlyUsers = usersInEnt[0];
            notAvailableUsers = usersInEnt[1];
            System.out.println("ZohoUtil:shareSheetDoc:readonlyusers:"+readOnlyUsers+
                  "**notAvailableUsers::"+notAvailableUsers+"**"); */
            urll = urll+"&readOnlyUsers="+readOnlyUsers;
        }
        if(editUsers != null && !editUsers.trim().equals(""))
        {
           /* String[] usersInEnt = filterEntrepreneurUser(editUsers);
            editUsers = usersInEnt[0];
            if(!notAvailableUsers.equals(""))
            {
                notAvailableUsers = notAvailableUsers + ",";
            }
            notAvailableUsers = notAvailableUsers+usersInEnt[1];
            System.out.println("ZohoUtil:shareSheetDoc:editusers:"+editUsers+
                    "**total notAvailableUsers::"+notAvailableUsers+"**"); */
            urll = urll+"&readWriteUsers="+editUsers;
            System.out.println("ZohoUtil:shareSheetDoc:URL::"+urll);    
        }
        String urlResp = "";
        String resp = "[{\"type\":\"sheet\"},";
        if((readOnlyUsers != null && !readOnlyUsers.trim().equals("")) ||
             (editUsers != null && !editUsers.trim().equals("")))
        {
            urlResp = getURLResponse(urll,"POST","");
            resp = resp+urlResp
                +",{\"nonRegisteredUsers\":\""+notAvailableUsers+"\"}]";
            
               //mail will be sent from zoho-end rajarajan
           // ShareMailThread sh = new ShareMailThread("workbook",urlResp,userName,"");
        }
        else
        {
            resp = resp+"{\"nonRegisteredUsers\":\""+notAvailableUsers+"\"}]";
        }
        
        System.out.println("ZohoUtil:shareSheetDoc:"+resp);    
        return resp;
    }


    /**
     * Shares a Writer/Show document to the given emailIds based on their access permission.
     * Checks the emailIds of readOnlyUsers and editUsers. Filters out the emailIds not registered in the zohoconnect assist database.And shares the document only for the emailIds of the registered zohoconnect users. Returns the response of the sharing and the list of emailIds of the non-zohoconnect users in JSON format.
     * And also sends email to the shared emailIds using {@link com.ea.zoho.server.util.ShareMailThread}.
     *
     * @param ticket - User ticket associated with zoho service
     * @param readOnlyUsers - list of emailIds with read only permission
     * @param editUsers - list of emailIds with read and write permissions
     * @param docId - Document Id
     * @param userName - Name of the user who shares
     * @param docType - decides the type of document(writer/show)
     * @return String - Response of the sharing and the list of emailIds of the non-zohoconnect users in JSON format.
     */
    public static String shareWriterShowDoc(String ticket, String readOnlyUsers,
             String editUsers,String docId,String userName,String docType)
    {
        System.out.println("ZohoUtil:shareWriterShowDoc:ticket:"+
           ticket+"**readOnlyUsers:"+readOnlyUsers+"**editUsers:"+editUsers+
           "*****docId:::::"+docId+"****userName:"+userName
           +"***docType:"+docType+"*");
        String response = "";
        String urll = "";
        if(docType.equals("document"))
        {
            //orig rajarajan
           // urll = shareWriterDocURL+docId+"?apikey="+API_KEY
                   //     +"&ticket="+ticket+"&sendemail=false";
            //mail will be sent from zoho-end
            urll = shareWriterDocURL+docId+"?apikey="+API_KEY
                        +"&ticket="+ticket+"&sendemail=true";
            response = "[{\"type\":\"writer\"},";
        }
        else if(docType.equals("presentation"))
        {
            urll = shareShowDocURL+docId+"?apikey="+API_KEY
                        +"&ticket="+ticket;
            response = "[{\"type\":\"show\"},";
        }
        String notAvailableUsers = "";
        if(readOnlyUsers != null && !readOnlyUsers.trim().equals(""))
        {
           // String[] usersInEnt = filterEntrepreneurUser(readOnlyUsers);
           // readOnlyUsers = usersInEnt[0];
           // notAvailableUsers = usersInEnt[1];
            System.out.println("ZohoUtil:shareWriterShowDoc:readonlyusers:"+readOnlyUsers+
                  "**notAvailableUsers::"+notAvailableUsers+"**");
            if(readOnlyUsers != null && !readOnlyUsers.trim().equals(""))
            {
                String readUrl = urll+"&shareto="+readOnlyUsers+"&allowtowrite=false";
                String readResp = getURLResponse(readUrl,"POST","");
                response = response + "{\"readonly\":"+readResp+"},";
               //mail will be sent from zoho-end rajarajan
               //ShareMailThread sh = new ShareMailThread(docType,readResp,userName,readOnlyUsers);
            }
        }
        if(editUsers != null && !editUsers.trim().equals(""))
        {
           /*String[] usersInEnt = filterEntrepreneurUser(editUsers);
            editUsers = usersInEnt[0];
            if(!notAvailableUsers.equals(""))
            {
                notAvailableUsers = notAvailableUsers + ",";
            }
            notAvailableUsers = notAvailableUsers+usersInEnt[1];
            System.out.println("ZohoUtil:shareWriterShowDoc:editusers:"+editUsers+
                    "**total notAvailableUsers::"+notAvailableUsers+"**"); */
            if(editUsers != null && !editUsers.trim().equals(""))
            {
                String editUrl = urll+"&shareto="+editUsers+"&allowtowrite=true";
                String editResp =  getURLResponse(editUrl,"POST","");
                response = response + "{\"edit\":"+editResp+"},";
               //mail will be sent from zoho-end rajarajan
               // ShareMailThread sh = new ShareMailThread(docType,editResp,userName,editUsers);
            }
        }
        response = response + "{\"nonRegisteredUsers\":\""+notAvailableUsers+"\"}]";
        System.out.println("ZohoUtil:shareWriterShowDoc:"+response);    
        return response;
    }


    /**
     * Fetches the complete shared documents for an user from the zoho services.
     * Fetches the shared documents from Writer,Sheet and Show separately. Merges these shared documents using {@link #mergeAllResponsesInXMLForm} and returns the same.
     *
     * @param ticketId - User ticket associated with zoho services
     * @return String - list of shared documents in XML format.
     */
    public static String getSharedDoc(String ticketId)
    {
        String writerShrdDoc = getSharedDocsList(ticketId,getSharedWriterDocsURL);
        String sheetShrdDoc = getSharedDocsList(ticketId,getSharedSheetDocsURL);
        String showShrdDoc = getSharedDocsList(ticketId,getSharedShowDocsURL);
        String mergedResp = mergeAllResponsesInXMLForm(writerShrdDoc,sheetShrdDoc,showShrdDoc);
        //System.out.println("ZohoUtil:getSharedDoc:"+mergedResp);    
        return mergedResp;
    }

    /**
     * Executes the given shared documents url for the given ticketId and returns the response.
     * 
     * @param ticketId - User ticket associated with zoho services.
     * @param urll - URL to fetch shared documents
     * @return String - shared documents response in XML format
     */
    public static String getSharedDocsList(String ticketId,String urll)
    {
        String response = "";
        String compURL = getCompleteURL(urll,ticketId,null,null);
        response = getURLResponse(compURL, "GET",null);
        //System.out.println("ZohoUtil:getSharedDocsList::"+
        //          compURL+"***************"+response);    
        return response;
    }

    /**
     * Fetches the private documents of an user from the zoho services(Writer,Sheet and Show).
     * Merges the Writer,Sheet and Show response using {@link #mergeAllResponsesInXMLForm}.
     *
     * @param ticketId - User ticket associated with zoho service
     * @param startFrom - starting document number. 
     * @param limit - limit of documents to be fetched.
     * @return String - private documents in XML format.
     */
    public static String getCompleteDocs(String ticketId,
            String startFrom,String limit)
    {
        String writerResponse = getWriterDocsList(ticketId,startFrom,limit);
        String sheetsResponse = getSheetsDocsList(ticketId,startFrom,limit);
        String showResponse = getShowsDocsList(ticketId,startFrom,limit);
        String mergedResp = mergeAllResponsesInXMLForm(writerResponse,
                            sheetsResponse,showResponse);
        //System.out.println("ZohoUtil:: getCompleteDocs:: ticketId::"
        //        +ticketId+"  RESPONSE PROPS:::"+mergedResp);    
        return mergedResp;
    }

    /**
     * Fetches the private documents from Zoho Writer.
     *
     * @param ticketId - User ticket associated with zoho service
     * @param startFrom - starting document number. 
     * @param limit - limit of documents to be fetched.
     * @return String - private documents in XML format.
     */
    public static String getWriterDocsList(String ticketId,
            String startFrom ,String limit)
    {
        String response = "";
        String writerURL = getCompleteURL(writerGetDocsURL,ticketId,
                               startFrom,limit);
        response = getURLResponse(writerURL, "GET",null);
        return response;
    }

    /**
     * Fetches the private documetns from Zoho Sheet.
     *
     * @param ticketId - User ticket associated with zoho service
     * @param startFrom - starting document number 
     * @param limit - limit of documents to be fetched.
     * @return String - private documents in XML format.
     */
    public static String getSheetsDocsList(String ticketId,
              String startFrom, String limit)
    {
        String response = "";
        String sheetsURL = getCompleteURL(sheetGetDocsURL,ticketId,
                                 startFrom,limit);
        response = getURLResponse(sheetsURL, "GET",null);
        return response;
    }

    /**
     * Fetches the private documetns from Zoho Show.
     *
     * @param ticketId - User ticket associated with zoho service
     * @param startFrom - starting document number 
     * @param limit - limit of documents to be fetched.
     * @return String - private documents in XML format.
     */
    public static String getShowsDocsList(String ticketId,
              String startFrom , String limit )
    {
        
        String response = "";
        String showsURL = getCompleteURL(showGetDocsURL,ticketId,
                                startFrom,limit);
        response = getURLResponse(showsURL , "GET",null);
        return response;
    }

    /**
     * Appends the given ticketId,startFrom and limit with the given urll.
     * startFrom and limit values are not appended with the urll if their values are null and empty.
     *
     * @param urll - URL to which the values need to be appended
     * @param ticketId - User ticket associated with zoho service
     * @param startFrom - starting document number 
     * @param limit - limit of documents to be fetched.
     * @return String - URL with the appended values.
     */
    private static String getCompleteURL(String urll, String ticketId,
                 String startFrom , String limit)
    {
        String completeURL = urll+ticketId;
        if( startFrom != null && !startFrom.trim().equals("") )
        {
            completeURL = completeURL + "&start-from=" + startFrom;
        }
        if( limit != null && !limit.trim().equals(""))
        {
            completeURL = completeURL + "&limit=" + limit;
        }
        return completeURL;
    }

    /**
     * Executes the given URL on zoho service and returns the response.
     * Executes the URL using {@link com.ea.zoho.server.util.URLDataHandler#getDataFromURL}.
     * 
     * @param urll - URL to be executed on zoho service.
     * @param type - method type(GET/POST)
     * @param xmlString 
     * @return String - returns the response.
     * @see com.ea.zoho.server.util.URLDataHandler
     */
    public static String getURLResponse(String urll,String type,
                          String xmlString)
    {
        String response = "";
        try
        {
            response = URLDataHandler.getDataFromURL("","","",
                    xmlString,urll,type);
        }
        catch(Exception ex)
        {
            ex.printStackTrace();    
        }
        //System.out.println("ZohoUtil::: getURLResponse::"+
        //        "URL::::"+urll+ "          RESPONSE:::"+response);    
        return response;
    }

    /**
     * Used in appending the XML responses of Writer,Sheet and Show.
     * Appends all the separate XML responses as single XML( with result tag as main element). If an error occurs in any of the responses, corresponse resposne(s) is not merged with the resultant response. Separate element for Error responses is added with ErrorResponseFor tag and the error services names(Documents/Workbooks/Presentations) with comma separation are set as values.
     * 
     * @param writerResponse - writer response in xml format
     * @param sheetsResponse - sheet response in xml format
     * @param showResponse - show response in xml format
     * @return String - result in XML format.
     */
    public static String mergeAllResponsesInXMLForm(String writerResponse,
            String sheetsResponse, String showResponse)
    {
        String docString = "";
        try
        {
            Document doc = null;
            String errorResponse = "";
            Element writerRootEle = null;
            if(API_KEY==null || API_KEY.trim().length()<0)
            {
                errorResponse="Invalid API Key configured.Congigure a valid API key in userSettings.conf and try"; 
            }else
            {    
            if(writerResponse != null && !checkErrorInResponse(writerResponse))
            {
                doc = getBaseDocument(writerResponse);
                writerRootEle = doc.getDocumentElement();
            }
            else
            {
                errorResponse = "Documents";
            }
            if(sheetsResponse != null && !checkErrorInResponse(sheetsResponse))
            {
                //Writer has proper response
                if(doc != null)
                {
                    //Returns <workbooks> node content -> from response xmlstring
                    Element sheetTagElement = getFirstChildNode(sheetsResponse);
                    Node sheetTagEleImported = doc.importNode(sheetTagElement,true);
                    writerRootEle.getFirstChild().appendChild(sheetTagEleImported);
                }
                else
                {
                    doc = getBaseDocument(sheetsResponse);
                    writerRootEle = doc.getDocumentElement();
                }
            }
            else
            {
                errorResponse = ((errorResponse.equals("")?
                            "Workbooks":(errorResponse+",Workbooks")));
            }
            if( showResponse != null && !checkErrorInResponse(showResponse))
            {
                //Doc has been set previously from Writer&(/)Sheet response
                if(doc != null)
                {
                    //Returns <presentations> node content ->  from response xmlstring
                    Element showTagElement = getFirstChildNode(showResponse);
                    Node showTagEleImported = doc.importNode(showTagElement,true);
                    writerRootEle.getFirstChild().appendChild(showTagEleImported);
                }
                else
                {
                    doc = getBaseDocument(showResponse);
                    writerRootEle = doc.getDocumentElement();
                }
            }
            else
            {
                errorResponse = ((errorResponse.equals("")?
                      "Presentations":(errorResponse+",Presentations")));
            }
            }
            if(!errorResponse.equals(""))
            {
                //If error response received for all the services.
                if(doc == null)
                {
                    doc = createDocumentForErrorResp();
                    writerRootEle = doc.getDocumentElement();
                }
                Element errorResponseEle = getErrorResponseElement(errorResponse,doc);
                Node errorNode = doc.importNode(errorResponseEle,true);
                writerRootEle.appendChild(errorNode);
            }
            docString = getEquivalentStringForXMLNode(writerRootEle);
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil::: mergeAllResponsesInXMLForm::"
                +docString+"*****writer*"+writerResponse+"***sheet**"+
                sheetsResponse+"****show*"+showResponse);    
            e.printStackTrace();    
        }
        return docString;
    }

    /**
     * Creates a document for error response.
     * Used to handle the error scenario - while all the zoho services response has error message on fetching documents. Creates a document with response tag to indicate the error scenario in XML format.
     *
     * @return Document
     * @see #mergeAllResponsesInXMLForm
     */
    private static Document createDocumentForErrorResp()
    {
        //System.out.println("ZohoUtil:createDocumentForErrorResp:");
        Document doc = null;
        try
        {
            DocumentBuilderFactory docBuilderFactory = 
                     DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder=docBuilderFactory.newDocumentBuilder();
            doc = docBuilder.newDocument();
            Element responseEle = doc.createElement("response");
            doc.appendChild(responseEle);
            //System.out.println("createDocumentForErrorResp:::Doc::"+doc);    
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil:createDocumentForErrorResp:"+
                "Exception while creating new document for error response");    
            e.printStackTrace();    
        }
        return doc;
    }

    /**
     * Creates an element with respect to the given document and with the given errorResp message.
     * Creates an element with ErrorResponseFor as name and services as attribute with the given errorResp as value. This method is used while error occured in any of the zoho services response on fetching documents.
     *
     * @param errorResp - message to be set as value
     * @param doc - base document
     * @see #mergeAllResponsesInXMLForm
     */
    private static Element getErrorResponseElement(
            String errorResp,Document doc) throws Exception
    {
        Element ele = null;
        try
        {
            ele = doc.createElement("ErrorResponseFor");
            ele.setAttribute("services",errorResp);
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil:getErrorResponseElement:"+
                "Excepion while forming error response element");    
            System.out.println("ZohoUtil:getErrorResponseElement::"+
                "errorString:"+errorResp+"** Element:"+ele);    
            throw e;
        }
        return ele;
    }

    /**
     * Returns equivalent String object for an Element object.
     *
     * @param ele - Element object to be converted to an equivalent String object
     * @return String - equivalent String object for the given Element object
     */
    private static String getEquivalentStringForXMLNode(Element ele)
    {
        String equivalentString = "";
        try
        {
            DOMSource dm = new DOMSource(ele);
            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer = tf.newTransformer();
            transformer.transform(dm, result);
            equivalentString = writer.toString();
        }
        catch(Exception e)
        {
            e.printStackTrace();    
        }
        return equivalentString;
    }

    /**
     * Returns the base document from the given string object which is in XML format.
     *
     * @param xmlString - XML in string form
     * @return Document - base document
     */
    public static Document getBaseDocument(String xmlString)
    {
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document baseDoc = builder.parse(new InputSource(new StringReader(xmlString)));
            return baseDoc;
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil:: getDocumentElement::"+xmlString);    
            e.printStackTrace();    
        }
        return null;
    }

    /**
     * Returns the first child element present under <result> node from the given String object which is in XML format.
     *
     * @param xmlString - xml in string form
     * @return Element - first child element present under <result> node.
     */
    private static Element getFirstChildNode(String xmlString)
    {
        Element tagEle = null;
        try
        {
            Document baseDoc = getBaseDocument(xmlString);
            Element rootEle = baseDoc.getDocumentElement();
            Node resultEle = ((rootEle.getElementsByTagName("result")).item(0)).cloneNode(true);
            tagEle = (Element)resultEle.getFirstChild();
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil:: getFirstChildNode::"+
                "XMLSTRING::"+xmlString+"     "+
                " Resultant Element::::::"+tagEle);    
            e.printStackTrace();    
        }
        return tagEle;
    }

    /**
     * Returns the editor url for the existing document based on the given docType.
     * 
     * @param docType - type of document(document/workbook/presentation).
     * @param docId - Document Id of the document to be opened
     * @param docName - Document name
     * @param enableDisplayAll - boolean value.Can be ignored.
     * @param apiTicket - User ticket associated with zoho service
     * @return String - editor URL
     */
    public static String getEditorURL(String docType, String docId , 
                  String docName,boolean enableDisplayAll,String apiTicket)
    {
        //System.out.println("ZohoUtil:: getEditorURL:: DocType:"
        //   +docType+"** DocId:"+docId+"* enableDisplayAll:"+enableDisplayAll);    
        String editorURL = "";
        if(docType.equals("document"))
        {
            editorURL = writerEditorURL+"docId="+docId;
        }
        else if(docType.equals("workbook"))
        {
            editorURL = sheetEditorURL+"&docid="+docId+"&ticket="+apiTicket;
        }
        else if(docType.equals("presentation"))
        {
            editorURL = showEditorURL+"P_ID="+docId+"&TP=true&ticket="+apiTicket;
        }
        /*
        if(editorURL != null && !editorURL.trim().equals(""))       
        {
            editorURL = editorURL+"&ticket="+apiTicket; 
        }
        */
        //System.out.println("ZohoUtil:getEditorURL:URL:"+editorURL);    
        return editorURL;
    }

    /**
     * Gets the document content for a Writer document.
     *
     * @param docType - should be "document"
     * @param docId - Document Id of the document whose content needs to be fetched
     * @param docName - Document name
     * @param apiTicket - User ticket associated with the zoho service
     * @return String - document content in XML format.
     */
    public static String getDocumentContent(String docType,String docId,
            String docName,String apiTicket)
    {
        String xmlString = "";
        //System.out.println("ZohoUtil:: getDocumentContent::"+" DocType:"
        //    +docType+"* DocName:"+docName+"* "+"DocID:"+docId+"*");
        if(docType.equals("document"))
        {
            String completeURL = writerDocContentURL+docId+"?apikey="+
                                 API_KEY+"&ticket="+apiTicket;
            xmlString = getURLResponse(completeURL,"GET",null);
        }
        //System.out.println("ZohoUtil: getDocumentContent:: RESPONSE::"
        //        + xmlString);
        return xmlString;
    }

    /**
     * Returns the preview URL for a Sheet document.
     * 
     * @param docType - document type - can be ignored.
     * @param docId - Document Id 
     * @param docName - Document name
     * @param apiTicket - User ticket associated with zoho service
     * @return String - Sheet Preview URL
     */
    public static String getSheetPreviewURL(String docType,String docId,
            String docName,String apiTicket)
    {
        //System.out.println("ZohoUtil:: getSheetPreviewURL: docType:"+
        //    docType+"** docId:"+docId+"* DocName:"+docName+"* ticket:"+apiTicket);
        String compPreviewURL = sheetPreviewURL+docId+"&ticket="+apiTicket;
        //System.out.println("ZohoUtil: getSheetPreviewURL::"
        //        +compPreviewURL);    
        return compPreviewURL;
    }

    /**
     * 
     */
    private static List parseSheetsName(String xmlString)
    {
        List sheetNames = new ArrayList();
        try
        {
            Element sheetsElement = getFirstChildNode(xmlString);
            NodeList nl = sheetsElement.getElementsByTagName("sheet");
            int nlCount = nl.getLength();
            for(int count = 0 ; count < nlCount ; count++ )
            {
                Element sheetEle = (Element)nl.item(count);
                String name = sheetEle.getAttribute("name"); 
                sheetNames.add(name);
            }
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil: parseSheetsName:: SheetNames::"+
                sheetNames);    
            e.printStackTrace();    
        }
        return sheetNames;
    }

    /**
     * Returns the editor URL for new document based on the given docType.
     *
     * @param docType - type of document(document/workbook/presenation)
     * @param apiTicket - User ticket associated with the zoho service
     * @return String - new document editor URL
     */
    public static String getNewDocURL(String docType , String apiTicket)
    {
        String newDocUrl = "";
        try
        {
            if(docType.equals("document"))
            {
                newDocUrl = newWriterURL;//+"?ticket="+apiTicket;
            }
            else if(docType.equals("workbook"))
            {
                newDocUrl = newSheetURL+"&ticket="+apiTicket;
            }
            else if(docType.equals("presentation"))
            {
                newDocUrl = newShowURL+"&ticket="+apiTicket;
            }
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil:getNewDocURL:URL:"+newDocUrl);    
            e.printStackTrace();    
        }
        return newDocUrl;
    }

    /**
     * Deletes a document from zoho service.
     * Moves the existing document to trash and then deletes the document.If the document is unable to move to thrash, returns false without processing further i.e. deletion process will not happen.
     * 
     * @param docId - Document Id of the document to be deleted
     * @param docType - type of the document(document/workbook/presentation)
     * @param apiTicket - User ticket associated with zoho service
     * @return boolean - Return true if the document is moved to trash. Else false.
     */
    public static boolean deleteDoc(String docId,String docType,
                     String apiTicket)
    {
        boolean isDeleted = false;
        if(!thrashDocument(docId,docType,apiTicket))
        {
            System.out.println("ZohoUtil:thrashDocument::"+
                    "Unable to thrash the document with ID:"+docId+
                    ".So not processing further to delete the Document");    
            return isDeleted;
        }
        String prefixURL = docId+"?apikey="+API_KEY+"&ticket="+apiTicket;
        String completeURL = "";
        if(docType.equals("document"))
        {
            completeURL = deleteWriterDocUrl;
        }
        else if(docType.equals("workbook"))
        {
            completeURL = deleteSheetDocUrl;
        }
        else if(docType.equals("presentation"))
        {
            completeURL = deleteShowDocUrl;
        }
        completeURL = completeURL + prefixURL;
        String xmlResponse = "";
        try
        {
            xmlResponse = getURLResponse(completeURL,"POST","");
            //Once the doc is trashed, its details cannot be given
            //in the restAPI used for getting the docs list.So 
            //there is no point in relying on this delete response if the
            //trashing was successfull.So returning always true, once the
            //thrashing was successfull.
            isDeleted = true;
            /*
            if(xmlResponse != null && !checkErrorInResponse(xmlResponse))
            {
                isDeleted = true;
            }
            */
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil:: deleteDoc::DocId:"+docId+
                 "***DocType:"+docType+"*****apiTicket::"+apiTicket);    
            System.out.println("ZohoUtil::deleteDoc::URL:"+completeURL+
                "*****     RESPONSE::"+xmlResponse+"******** ReturnValue:"+
                isDeleted);    
            e.printStackTrace();    
        }
        return isDeleted;
    }

    /**
     * Moves an existing document to trash.
     * 
     * @param docId - Document Id of the document to be trashed
     * @param docType - type of document(document/workbook/presentation).
     * @param apiTicket - User ticket associated with zoho service
     * @return boolean - Returns true, if the trashing response from zoho service has no error.Else false.
     */
    public static boolean thrashDocument(String docId,String docType,
                  String apiTicket)
    {
        boolean isThrashed = false;
        String prefixURL = docId+"?apikey="+API_KEY+"&ticket="+apiTicket;
        String completeURL = "";
        if(docType.equals("document"))
        {
            completeURL = thrashWriterDocUrl;
        }
        else if(docType.equals("workbook"))
        {
            completeURL = thrashSheetDocUrl;
        }
        else if(docType.equals("presentation"))
        {
            completeURL = thrashShowDocUrl;
        }
        completeURL = completeURL + prefixURL;
        String xmlResponse = "";
        try
        {
            xmlResponse = getURLResponse(completeURL,"POST","");
            if(xmlResponse != null && !checkErrorInResponse(xmlResponse))
            {
                isThrashed = true;
            }
            //Some times trashing request get timed out,but doc is trashed at
            //the Zoho services end.
            //So on the assumptions:: if the response is null, the request was 
            //timed out.And the doc was trashed at the services end.So returning
            //true at this scenarios.To avoid (misleading)error messages at
            //client end.
            else if(xmlResponse == null)
            {
                isThrashed = true;
            }
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil: thrashDocument:DocID:"
                +docId+"** DocType:"+docType+"** apiTicket:"+apiTicket);
            System.out.println("ZohoUtil: thrashDocument:CompleteURL:"+
                completeURL+"*** RESPONSE::"+xmlResponse+"** IsThrashed:"+
                isThrashed);
            e.printStackTrace();    
        }
        return isThrashed;
    }
    
    /**
     * Checks the XML response.
     * If the response contains <result> as its first node, returns true to indicate the response is success.Else returns false.
     * 
     * @param xmlString - xml response from zoho service
     * @return boolean - Returns true if the response is success.Else false.
     */
    public static boolean checkErrorInResponse(String xmlString)
    {
        boolean isResponseFailure = true;
        try
        {
            Document baseDoc =  getBaseDocument(xmlString);
            String baseTag=((Element)(baseDoc.getDocumentElement())
                    .getFirstChild()).getTagName();
            //System.out.println("ZohoUtil::checkErrorInResponse::"+
            //        "Base TagName"+baseTag);    
            if(baseTag.equals("result"))
            {
                isResponseFailure = false;
            }
            else
            {
                System.out.println("ZohoUtil:checkErrorInResponse:"+
                     xmlString);    
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();    
        }
        return isResponseFailure;
    }

    /**
     * Used in getting the count of private documents of an user for the given docType(zoho service).
     *
     * @param docType - type of the document(document/workbook/presentation).
     * @param apiTicket - User ticket associated with the zoho service
     * @param String - returns the xml response of the count query executed on zoho service.
     */
    public static String getDocCountResponse(String docType,String apiTicket)
    {
        String xmlResponse = "";
        try
        {
            String completeURL = "";
            if(docType.equals("document"))
            {
                completeURL = writerDocsCountURL;
            }
            else if(docType.equals("workbook"))
            {
                completeURL = sheetDocsCountURL;
            }
            else if(docType.equals("presentation"))
            {
                completeURL = showDocsCountURL;
            }
            completeURL = completeURL+"apikey="+API_KEY+"&ticket="+apiTicket;
            xmlResponse = getURLResponse(completeURL, "GET",null);
        }
        catch(Exception e)
        {
            System.out.println("ZohoUtil:getDocCountResponse:"+
               "DocType:"+docType+"**** APITICKET:"+apiTicket+"*");
            e.printStackTrace();    
        }
        return xmlResponse;
    }

    /**
     * Used in handling special character.
     */
    public static String handleSpecialChars(String str)
    {
        String temp = str;
        if(str.indexOf("'") != -1)
        {
            temp = str.replaceAll("'","\\\\'");
        }
        //System.out.println("ZohoUtil:handleSpecialChars:"
        //    +"Incoming String:"+str+"** ReplacedString:"+temp+"**");
        return temp;
    }


    /**
     * Rolls back the changes made in the current transaction.
     *
     * @param conn - Connection object
     */
    public static void rollBack(java.sql.Connection conn)
    {
        try
        {
            conn.rollback();
        }
        catch(Exception e)
        {
            System.out.println("Exception while connection rollback  from ZohoUtil.rollBack "+ e.getMessage());
            e.printStackTrace();
        }
    }
    
    /** 
     * Closes the given Connection object.
     * 
     * @param conn - Connection object to be closed.
     */
    public static void close(java.sql.Connection conn)
    {
        try
        {
            //System.out.println(" connection close called >>>>>>>>>>>  "+ conn);
            conn.close();
        }
        catch(Exception e)
        {
            System.out.println("Exception while closing connection from ZohoUtil.close "+ e.getMessage());
            e.printStackTrace();
        }
    }

   public static Properties getProxyDetails()
   {   
     return  URLDataHandler.getUserSettings();
      /* String bname = "userSettings.conf";     // in WEB-INF/classes dir
       Properties proxyProps=new Properties();
       try {
           File cfg = new File(new URI
                   (this.getClass().getClassLoader().getResource(bname).toString()));

           proxyProps.load(new FileInputStream(cfg));
       } catch (Exception e) {
       }
       return proxyProps; */

   }

/**Akiyoshi Matsumoto**/

    public static String getStyleSheet(){
	String stylesheet = URLDataHandler.getUserProperty("stylesheet");
	if(stylesheet != null || stylesheet.trim().length() >0){
		return stylesheet;
	}else{
		return "styles.css";
	}
    }

/**end of Akiyoshi Matsumoto**/


    /**
     * to get the user acoount details props using the given ticketId      * 
     * @param ticketId - User ticket associated with zoho services.
     * @param urll - URL to fetch the account details
     * @return String - shared documents response in XML format
     */
    public static String getUserDetails(String urll)
    {
        String response = "";
        response=getURLResponse(urll,"POST","");
        System.out.println("ZohoUtil:getUserDetails::"+urll+"response:"+response);    
        return response;
    }
    public static String getAPIKey()
    {
      return API_KEY;
    }    

}
