/**
       Read a simple XML file to find the locations of the domains for
       this WebLogic 11g R1 installation.
       
       Example:
       <?xml version="1.0" encoding="UTF-8"?>
       <domain-registry xmlns="http://xmlns.oracle.com/weblogic/domain-registry">
         <domain location="/opt/Oracle/Middleware/user_projects/domains/base_domain"/>
       </domain-registry> 
       
              \param[in]  domainRegistryXml File object of the XML file
                                            to open.
                                            
              \param[out] domains           vector that will contain the
                                            list of discovered domains.
     */
    void WebLogicFileReader::ReadDomainRegistryXml(
            const SCXFilePath& domainRegistryXml,
            vector<SCXFilePath>& domains)
    {
        string xml;

        try {
            SCXHandle<istream> reader = 
                    OpenDomainRegistryXml(domainRegistryXml.Get());
            GetStringFromStream(reader, xml);

            XElementPtr domainRegistryNode;
            XElement::Load(xml, domainRegistryNode);
            if (domainRegistryNode->GetName() == WEBLOGIC_DOMAIN_REGISTRY_XML_NODE)
            {
                XElementList domainNodes;
                domainRegistryNode->GetChildren(domainNodes);
                for (size_t index = 0; index < domainNodes.size(); ++index)
                {
                    string location;
                    if (domainNodes[index]->GetName() == WEBLOGIC_DOMAIN_XML_NODE && 
                        domainNodes[index]->GetAttributeValue(WEBLOGIC_LOCATION_XML_ATTRIBUTE, location))
                    {
                        wstring wideLocation = StrFromUTF8(location);
                        SCXFilePath domainPath;
                        domainPath.SetDirectory(wideLocation);                                
                        domains.push_back(domainPath);
                    }
                }
            }
        }
        catch (SCXFilePathNotFoundException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadDomainRegistryXml() - ").
                    append(m_installationPath).append(L" - Could not find file: ").
                    append(domainRegistryXml.Get()));
        }
        catch (SCXUnauthorizedFileSystemAccessException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadDomainRegistryXml() - ").
                    append(m_installationPath).append(L" - not authorized to open file: ").
                    append(domainRegistryXml.Get()));
        }
        catch (XmlException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadDomainRegistryXml() - ").
                    append(m_installationPath).append(L" - Could not load XML from file: ").
                    append(domainRegistryXml.Get()));
        }
    }
    /**
        Update version
        
        Load XML file <disk path>\properties\version\profile.version

        <?xml version="1.0" encoding="UTF-8"?>
        <profile>
          <id>default</id>
          <version>7.0.0.0</version>
          <build-info date="8/31/08" level="r0835.03"/>
        </profile>
              
    */
    void WebSphereAppServerInstance::UpdateVersion()
    {
        const string cProfileNodeName("profile");
        const string cVersionNodeName("version");
        
        string xmlcontent;
        SCXFilePath filename(GetProfileVersionXml());

        try {
            SCXHandle<istream> mystream = m_deps->OpenXmlVersionFile(filename.Get());
            GetStringFromStream(mystream, xmlcontent);

            XElementPtr profileNode;
            XElement::Load(xmlcontent, profileNode);

            if (profileNode->GetName() == cProfileNodeName)
            {
                XElementPtr versionNode;
                if (profileNode->GetChild(cVersionNodeName, versionNode))
                {
                    wstring version;
                    versionNode->GetContent(version);
                    SetVersion(version);
                }
            }
        }
        catch (SCXFilePathNotFoundException&)
        {
            SCX_LOGERROR(m_log, wstring(L"WebSphereAppServerInstance::UpdateVersion() - ").append(GetId()).append(L" - Could not find file: ").append(filename));
        }
        catch (SCXUnauthorizedFileSystemAccessException&)
        {
            SCX_LOGERROR(m_log, wstring(L"WebSphereAppServerInstance::UpdateVersion() - ").append(GetId()).append(L" - not authorized to open file: ").append(filename));
        }
        catch (XmlException&)
        {
            SCX_LOGERROR(m_log, wstring(L"WebSphereAppServerInstance::UpdateVersion() - ").append(GetId()).append(L" - Could not load XML from file: ").append(filename));
        }
    }
    /**
       Read a simple XML file to find the locations of the both 
       the Admin and Managed servers for a WebLogic 11g R1 installation.
       
       Example:
       <?xml version="1.0" encoding="UTF-8"?>
       <domain ...>
         <name>base_domain</name>
         <domain-version>10.3.2.0</domain-version>
         <security-configuration ...>
            ...
         </security-configuration>
         <server>
           <name>AdminServer</name>
           <ssl>
             <name>AdminServer</name>
             <enabled>true</enabled>
             <listen-port>7012</listen-port>
           </ssl>
           <machine>new_UnixMachine_1</machine>
           <listen-port>7011</listen-port>
           <listen-address/>
         </server>
         <server>
           <name>new_ManagedServer_1</name>
           <ssl>
             <name>new_ManagedServer_1</name>
             <enabled>true</enabled>
             <listen-port>7513</listen-port>
           </ssl>
           <machine>new_UnixMachine_1</machine>
           <listen-port>7013</listen-port>
           <listen-address/>
         </server>
         <embedded-ldap>
           <name>base_domain</name>
           <credential-encrypted>{AES}RVX+Cadq8XJ5EvV7/1Ta2qGZrJlxve6t5CEa2A9euGUkYOMDTAwAqytymqDBS00Q</credential-encrypted>
         </embedded-ldap>
         <configuration-version>10.3.2.0</configuration-version>
         <machine xsi:type="unix-machineType">
           <name>new_UnixMachine_1</name>
           <node-manager>
             <name>new_UnixMachine_1</name>
             <listen-address>localhost</listen-address>
             <listen-port>5566</listen-port>
           </node-manager>
         </machine>
         <admin-server-name>AdminServer</admin-server-name>
       </domain>

              \param[in]  domainDir         Directory of the domain (needed
                                            for build the path to the server
       
              \param[in]  configXml         File object of the XML file
                                            to open.
                                            
              \param[out] instances         vector that will contain the
                                            list of server instances for the
                                            given domain.
       
     */
    void WebLogicFileReader::ReadConfigXml(
            const SCXFilePath& domainDir,
            const SCXFilePath& configXml,
            vector<SCXHandle<AppServerInstance> >& instances)
    {
        SCX_LOGTRACE(m_log, L"WebLogicFileReader::ReadConfigXml");
        SCX_LOGTRACE(m_log, 
                wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                append(L"Reading the file: ").append(configXml.Get()));
        string xml;

        try {
            SCXHandle<istream> reader = 
                    OpenConfigXml(configXml.Get());
            GetStringFromStream(reader, xml);

            XElementPtr domainNode;
            XElement::Load(xml, domainNode);
            
            if (domainNode->GetName() == WEBLOGIC_DOMAIN_XML_NODE)
            {
                string version;
                ReadConfigXmlForVersion(domainNode, version);
                
                string adminServerName;
                ReadConfigXmlForAdminServerName(domainNode, adminServerName);
                
                XElementList serverNodes;
                domainNode->GetChildren(serverNodes);
                for (size_t index = 0; index < serverNodes.size(); ++index)
                {
                    if (serverNodes[index]->GetName() == WEBLOGIC_SERVER_XML_NODE)
                    {
                        bool isAdminServer = false;
                        bool isSslEnabled = false;
                        string name = "";
                        string httpPort = "";
                        string httpsPort = "";

                        XElementList childNodes;
                        serverNodes[index]->GetChildren(childNodes);
                        for (size_t j = 0; j < childNodes.size(); ++j)
                        {
                            /*
                             *   <server>
                             *     <name>new_ManagedServer_1</name>
                             *     <ssl>
                             *       <name>new_ManagedServer_1</name>
                             *       <enabled>true</enabled>
                             *       <listen-port>7513</listen-port>
                             *     </ssl>
                             *     <machine>new_UnixMachine_1</machine>
                             *     <listen-port>7013</listen-port>
                             *     <listen-address/>
                             *   </server>
                             * 
                             */
                            if (childNodes[j]->GetName() == WEBLOGIC_NAME_XML_NODE)
                            {
                                name = childNodes[j]->GetContent();
                                isAdminServer = adminServerName == name;                                       
                            } 
                            else if (childNodes[j]->GetName() == WEBLOGIC_SSL_XML_NODE)
                            {
                                ReadConfigXmlForSslInformation(
                                        childNodes[j],
                                        isSslEnabled,
                                        httpsPort);                            } 
                            else if (childNodes[j]->GetName() == WEBLOGIC_LISTEN_PORT_XML_NODE)
                            {
                                httpPort = childNodes[j]->GetContent();
                            }                            
                        }
                        /*
                         * Having found the server node, 
                         * read the children
                         */
                        wstring wideName = StrFromUTF8(name);
                        SCXFilePath pathOnDisk;
                        pathOnDisk.SetDirectory(domainDir.Get());
                        pathOnDisk.AppendDirectory(WEBLOGIC_SERVERS_DIRECTORY);
                        pathOnDisk.AppendDirectory(wideName);

                        if (DoesServerDirectoryExist(pathOnDisk))
                        {
                            SCX_LOGTRACE(m_log, 
                                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                                    append(L"Adding instance for ID='").append(pathOnDisk.Get()).
                                    append(L"'"));
                            // when the HTTP port is not set for the AdminServer,
                            // default to the default weblogic HTTP port (i.e. 7001)
                            wstring wideHttpPort = StrFromUTF8(httpPort);
                            if(isAdminServer && L"" == wideHttpPort)
                            {
                                wideHttpPort = DEFAULT_WEBLOGIC_HTTP_PORT;
                            }

                            // when the HTTPS port is not set, default to
                            // the default HTTPS port (i.e. 7002)
                            wstring wideHttpsPort = StrFromUTF8(httpsPort);
                            if(L"" == wideHttpsPort)
                            {
                                wideHttpsPort = DEFAULT_WEBLOGIC_HTTPS_PORT;
                            }
                        
                            wstring wideVersion = StrFromUTF8(version);
                        
                            SCXHandle<AppServerInstance> instance(
                                 new WebLogicAppServerInstance (
                                        pathOnDisk.GetDirectory()));
                        
                            instance->SetHttpPort(wideHttpPort);
                            instance->SetHttpsPort(wideHttpsPort);
                            instance->SetIsDeepMonitored(false, PROTOCOL_HTTPS);
                            instance->SetIsRunning(false);
                            instance->SetVersion(wideVersion);
                        
                            instance->SetServer(
                                    isAdminServer ?
                                            WEBLOGIC_SERVER_TYPE_ADMIN :
                                            WEBLOGIC_SERVER_TYPE_MANAGED);
                           
                            instances.push_back(instance);
                        }
                        else
                        {
                            SCX_LOGTRACE(m_log, 
                                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                                    append(L"The directory (").append(pathOnDisk.Get()).
                                    append(L") does not exist on disk, ignoring this instance"));
                        }
                    }
                }
            }
        }
        catch (SCXFilePathNotFoundException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                    append(m_installationPath).append(L" - Could not find file: ").
                    append(configXml.Get()));
        }
        catch (SCXUnauthorizedFileSystemAccessException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                    append(m_installationPath).append(L" - not authorized to open file: ").
                    append(configXml.Get()));
        }
        catch (XmlException& x)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                    append(m_installationPath).append(L" - Could not load XML from file: ").
                    append(configXml.Get()));
        }
    }
    /**
        Update ports for Tomcat

        Load XML file <ConfigPath>/conf/server.xml

        Get node /Server/Service/Connector where attribute protocol is HTTP/1.1 and secure is true
        Get attribute named port for HTTPS Port
        Get node /Server/Service/Connector where attribute protocol is HTTP/1.1 and no attribute named secure exist
        Get attribute named port for HTTP Port
    */
    void TomcatAppServerInstance::UpdatePorts()
    {
        const string cDeploymentNodeName("deployment");
        const string cServerNodeName("Server");
        const string cServiceNodeName("Service");
        const string cConnectorNodeName("Connector");
        const string cProtocolAttributeName("protocol");
        const string cSecureAttributeName("secure");
        const string cPortAttributeName("port");
        const string cHTTP11Name("HTTP/1.1");
        const string cTrueName("true");

        SCXFilePath filename(m_diskPath);

        string xmlcontent;
        filename.Append(L"/conf/server.xml");

        try {
            SCXHandle<istream> mystream = m_deps->OpenXmlServerFile(filename.Get());
            GetStringFromStream(mystream, xmlcontent);

            XElementPtr serverNode;
            XElement::Load(xmlcontent, serverNode);
            if (serverNode->GetName() == cServerNodeName)
            {
                XElementPtr serviceNode;

                if (serverNode->GetChild(cServiceNodeName, serviceNode))
                {
                    XElementList connectorNodes;
                    bool foundHTTPnode = false;
                    bool foundHTTPSnode = false;

                    serviceNode->GetChildren(connectorNodes);
                    for (size_t idx = 0; !(foundHTTPnode && foundHTTPSnode) && idx < connectorNodes.size(); ++idx)
                    {
                        string protocolprop;
                        if (connectorNodes[idx]->GetName() == cConnectorNodeName)
                        {
                            // For Tomcat 5 there is no 'Protocol' specified for the HTTP Connector
                            // we will use the Connectors as they appear in the file.
                            bool hasAttribute = connectorNodes[idx]->GetAttributeValue(cProtocolAttributeName, protocolprop);
                            if( ( hasAttribute && (cHTTP11Name == protocolprop) ) ||
                                !hasAttribute )
                            {
                                string secureprop;
                                string portprop;

                                if (connectorNodes[idx]->GetAttributeValue(cPortAttributeName, portprop))
                                {
                                    if (connectorNodes[idx]->GetAttributeValue(cSecureAttributeName, secureprop) && 
                                        cTrueName == secureprop)
                                    {
                                        m_httpsPort = StrFromUTF8(portprop);
                                        foundHTTPSnode = true;
                                    }
                                    else
                                    {
                                        m_httpPort = StrFromUTF8(portprop);
                                        foundHTTPnode = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (SCXFilePathNotFoundException&)
        {
            SCX_LOGERROR(m_log, wstring(L"TomcatAppServerInstance::UpdateTomcatPorts() - ").append(GetId()).append(L" - Could not find file: ").append(filename));
        }
        catch (SCXUnauthorizedFileSystemAccessException&)
        {
            SCX_LOGERROR(m_log, wstring(L"TomcatAppServerInstance::UpdateTomcatPorts() - ").append(GetId()).append(L" - not authorized to open file: ").append(filename));
        }
        catch (XmlException&)
        {
            SCX_LOGERROR(m_log, wstring(L"TomcatAppServerInstance::UpdateTomcatPorts() - ").append(GetId()).append(L" - Could not load XML from file: ").append(filename));
        }
    }
    /**
        Update ports for WebSphere

        Load XML file <disk path>/config/cells/<Cell Name>/nodes/<Node Name>/serverindex.xml
        
        Ger serverIndex/serverEntries node where serverName attribute is the name of the server
        For HTTP port get specialEndpoints node where endPointName is WC_defaulthost and 
          get port attribute from endPoint node
        For HTTPS port get specialEndpoints node where endPointName is WC_defaulthost_secure and 
          get port attribute from endPoint node
    */
    void WebSphereAppServerInstance::UpdatePorts()
    {
        const string cServerIndexNodeName("serverindex:ServerIndex");
        const string cServerEntriesNodeName("serverEntries");
        const string cServerNameAttributeName("serverName");
        const string cSpecialEndpointsNodeName("specialEndpoints");
        const string cEndPointNameAttributeName("endPointName");
        const string cWCdefaultHostName("WC_defaulthost");
        const string cWCdefaultHostSecureName("WC_defaulthost_secure");
        const string cEndPointNodeName("endPoint");
        const string cPortAttributeName("port");
        
        string xmlcontent;
        SCXFilePath filename(returnProfileDiskPath(m_diskPath));        

        filename.AppendDirectory(L"config");
        filename.AppendDirectory(L"cells");
        filename.AppendDirectory(m_cell);
        filename.AppendDirectory(L"nodes");
        filename.AppendDirectory(m_node);
        filename.SetFilename(L"serverindex.xml");

        try {
            SCXHandle<istream> mystream = m_deps->OpenXmlServerFile(filename.Get());
            GetStringFromStream(mystream, xmlcontent);

            // Load the XML, but don't honor namespaces
            XElementPtr serverIndexNode;
            XElement::Load(xmlcontent, serverIndexNode, false);

            if (serverIndexNode->GetName() == cServerIndexNodeName)
            {
                XElementList serverEntriesNodes;
                bool foundServer = false;

                serverIndexNode->GetChildren(serverEntriesNodes);

                for (size_t idx = 0; !foundServer && idx < serverEntriesNodes.size(); ++idx)
                {
                    string name;
                    if (serverEntriesNodes[idx]->GetName() == cServerEntriesNodeName && 
                        serverEntriesNodes[idx]->GetAttributeValue(cServerNameAttributeName, name) && 
                        m_server == StrFromUTF8(name))
                    {
                        XElementList childNodes;
                        bool foundHTTPnode = false;
                        bool foundHTTPSnode = false;
                        foundServer = true;

                        serverEntriesNodes[idx]->GetChildren(childNodes);

                        for (size_t idx2 = 0; !(foundHTTPnode && foundHTTPSnode) && idx2 < childNodes.size(); ++idx2)
                        {
                            if (childNodes[idx2]->GetName() == cSpecialEndpointsNodeName && 
                                childNodes[idx2]->GetAttributeValue(cEndPointNameAttributeName, name))
                            { 
                                if (cWCdefaultHostName == name)
                                {
                                    GetPortFromXml(childNodes[idx2], foundHTTPnode, m_httpPort);
                                }
                                else if (cWCdefaultHostSecureName == name)
                                {
                                    GetPortFromXml(childNodes[idx2], foundHTTPSnode, m_httpsPort);
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (SCXFilePathNotFoundException&)
        {
            SCX_LOGERROR(m_log, wstring(L"WebSphereAppServerInstance::UpdatePorts() - ").append(GetId()).append(L" - Could not find file: ").append(filename));
        }
        catch (SCXUnauthorizedFileSystemAccessException&)
        {
            SCX_LOGERROR(m_log, wstring(L"WebSphereAppServerInstance::UpdatePorts() - ").append(GetId()).append(L" - not authorized to open file: ").append(filename));
        }
        catch (XmlException&)
        {
            SCX_LOGERROR(m_log, wstring(L"WebSphereAppServerInstance::UpdatePorts() - ").append(GetId()).append(L" - Could not load XML from file: ").append(filename));
        }
    }