/* JFox, the OpenSource J2EE Application Server
 *
 * Copyright (C) 2002 huihoo.com
 * Distributable under GNU LGPL license
 * See the GNU Lesser General Public License for more details.
 */

package org.jfox.jdbc.xa;

import java.util.Properties;
import javax.sql.XADataSource;

/**
 * 根据提供的 url 取得相应的 XADataSource 实例,并设置好 url
 *
 * 现在支持 Oracle DB2 SQLServer MySQL
 *
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public abstract class XADataSourceFactory {

  public abstract XADataSource newXADataSource(String url) throws Exception;

  public void setUrl(XADataSource xads,String url) throws Exception {
    xads.getClass().getMethod("setURL",new Class[]{String.class})
            .invoke(xads,new Object[]{url});
  }

  protected static URLProperties parseSqlURL(String url){
    // url example: jdbc:microsoft:sqlserver://localhost:1433;user=x;password=y;databaseName=db;
    int biasIndex = url.indexOf("://");
    int semicolonIndex = url.indexOf(";");

    String serverNameAndPortNumber = url.substring(biasIndex+3,semicolonIndex);
    String urlProperties = url.substring(semicolonIndex+1);

    URLProperties urlProp = new URLProperties();
    parseSqlServerNameAndPort(serverNameAndPortNumber,urlProp);
    parseSqlProperties(urlProperties,urlProp);
    return urlProp;
  }

  protected static void parseSqlProperties(String urlProperties, URLProperties urlProp) {
    int pre_semicolonIndex = -1;
    int post_semicolonIndex = pre_semicolonIndex;
    while((post_semicolonIndex = urlProperties.indexOf(";",pre_semicolonIndex+1)) > 0){
      String kv = urlProperties.substring(pre_semicolonIndex+1,post_semicolonIndex);
      int equalsIndex = kv.indexOf("=");
      if(equalsIndex > 0){
        urlProp.setProperty(kv.substring(0,equalsIndex).trim(),kv.substring(equalsIndex+1).trim());
      }
      pre_semicolonIndex = post_semicolonIndex;
    }
    if(pre_semicolonIndex + 1 != urlProperties.length()) {
      String kv = urlProperties.substring(pre_semicolonIndex + 1);
      int equalsIndex = kv.indexOf("=");
      if(equalsIndex > 0){
        urlProp.setProperty(kv.substring(0,equalsIndex).trim(),kv.substring(equalsIndex+1).trim());
      }
    }
  }

  protected static void parseSqlServerNameAndPort(String serverNameAndPortNumber, URLProperties urlProp) {
    int colonIndex = serverNameAndPortNumber.indexOf(":");
    if(colonIndex > 0){
      urlProp.setProperty("serverName", serverNameAndPortNumber.substring(0,colonIndex));
      urlProp.setProperty("portNumber", serverNameAndPortNumber.substring(colonIndex+1));
    }
    else {
      urlProp.setProperty("serverName", serverNameAndPortNumber);
    }
  }

  static protected class URLProperties {
    private Properties prop = new Properties();
     public String getProperty(String key) {
      return prop.getProperty(key.toUpperCase());
    }

    public synchronized Object setProperty(String key, String value) {
      Object old = prop.getProperty(key.toUpperCase());
      prop.setProperty(key.toUpperCase(),value);
      return old;
    }

    public synchronized boolean containsKey(Object key) {
      return prop.containsKey(((String)key).toUpperCase());
    }
  }


}