Revision 10401 branches/v10/libraries/libFMap/src/com/iver/cit/gvsig/fmap/drivers/DefaultDBDriver.java

View differences:

DefaultDBDriver.java
51 51
import java.sql.SQLException;
52 52
import java.sql.Statement;
53 53
import java.sql.Types;
54
import java.util.ArrayList;
54 55
import java.util.Hashtable;
56
import java.util.TreeMap;
55 57

  
56 58
import org.apache.log4j.Logger;
57 59

  
60
import com.hardcode.driverManager.DriverEvent;
61
import com.hardcode.driverManager.DriverEventListener;
62
import com.hardcode.driverManager.IDelayedDriver;
58 63
import com.hardcode.gdbms.engine.data.DataSourceFactory;
59 64
import com.hardcode.gdbms.engine.data.driver.ObjectDriver;
60 65
import com.hardcode.gdbms.engine.values.Value;
61 66
import com.hardcode.gdbms.engine.values.ValueFactory;
62 67
import com.iver.cit.gvsig.fmap.DriverException;
63 68
import com.iver.cit.gvsig.fmap.DriverJdbcNotFoundExceptionType;
69
import com.iver.cit.gvsig.fmap.MapContext;
64 70
import com.iver.cit.gvsig.fmap.Messages;
65 71
import com.iver.cit.gvsig.fmap.SqlDriveExceptionType;
66 72
import com.iver.cit.gvsig.fmap.core.IFeature;
67 73
import com.iver.cit.gvsig.fmap.core.IGeometry;
74
import com.iver.cit.gvsig.fmap.drivers.jdbc.utils.ConnectionWithParams;
75
import com.iver.cit.gvsig.fmap.drivers.jdbc.utils.SingleJDBCConnectionManager;
68 76
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
69 77
import com.iver.cit.gvsig.fmap.layers.XMLException;
70 78
import com.iver.utiles.XMLEntity;
......
77 85
 */
78 86
public abstract class DefaultDBDriver implements VectorialJDBCDriver, ObjectDriver {
79 87
    private static Logger logger = Logger.getLogger(SelectableDataSource.class.getName());
80
    private static Hashtable poolPassw = new Hashtable();
88
    protected static Hashtable poolPassw = new Hashtable();
81 89

  
82 90
    protected Connection conn;
83 91
    // protected String tableName;
84 92
    // protected String whereClause;
85 93
    // protected String fields;
86 94
    // protected String sqlOrig;
87
    private DBLayerDefinition lyrDef = null;
95
    protected DBLayerDefinition lyrDef = null;
88 96
    protected ResultSet rs;
89 97
    protected boolean bCursorActivo = false;
90 98
    protected Statement st;
91 99
    protected int numReg=-1;
92 100

  
93
    private Rectangle2D fullExtent = null;
101
    protected Rectangle2D fullExtent = null;
94 102

  
95 103
    // protected String strFID_FieldName;
96 104
    // protected String idFID_FieldName;
......
100 108

  
101 109
    protected ResultSetMetaData metaData = null;
102 110
    protected Rectangle2D workingArea;
103
	private String driverClass;
104
	private String userName;
105
	private String dbUrl;
106
	private String className;
107
	private String catalogName;
108
	private String tableName;
109
	private String[] fields;
110
	private String FIDfield;
111
	private String geometryField;
112
	private String whereClause;
113
	private String strSRID;
111
    protected String driverClass;
112
    protected String userName;
113
    protected String dbUrl;
114
    protected String className;
115
    protected String catalogName;
116
    protected String tableName;
117
    protected String[] fields;
118
    protected String FIDfield;
119
    protected String geometryField;
120
    protected String whereClause;
121
    protected String strSRID;
114 122
	//private double flatness;
123
	
124
    protected String host, port, dbName, connName;
125
    
126
    protected ArrayList driverEventListeners = new ArrayList();
127
    
115 128

  
116 129
    abstract public void setData(Connection conn, DBLayerDefinition lyrDef);
117 130

  
......
289 302
	    } catch (SQLException e) {
290 303
	    	throw new com.hardcode.gdbms.engine.data.driver.DriverException(e);
291 304
    	}
292
        throw new com.hardcode.gdbms.engine.data.driver.DriverException("Tipo no soportado: " + str);
305
	    return Types.OTHER;
306
        // throw new com.hardcode.gdbms.engine.data.driver.DriverException("Tipo no soportado: " + str);
293 307
	}
294 308
    /**
295 309
     * Obtiene el valor que se encuentra en la fila y columna indicada
......
396 410
        return -1;
397 411
    }
398 412

  
399
    public void close()
400
    {
413
    public void close() {
401 414
    }
402 415

  
403 416
    /**
......
461 474
    {
462 475

  
463 476
        className = xml.getStringProperty("className");
464
        dbUrl = xml.getStringProperty("dbURL");
477
        
465 478
        catalogName = xml.getStringProperty("catalog");
466 479
        userName =xml.getStringProperty("username");
467 480
        driverClass =xml.getStringProperty("driverclass");
......
471 484
        geometryField = xml.getStringProperty("THE_GEOM");
472 485
        whereClause = xml.getStringProperty("whereclause");
473 486
        strSRID = xml.getStringProperty("SRID");
487

  
488
        if (xml.contains("host"))
489
        {
490
	        host = xml.getStringProperty("host");
491
	        port = xml.getStringProperty("port");
492
	        dbName = xml.getStringProperty("dbName");
493
	        connName = xml.getStringProperty("connName");
494
        }
495
        else
496
        {
497
        	// Por compatibilidad con versiones anteriores
498
        	dbUrl = xml.getStringProperty("dbURL");
499
        	extractParamsFromDbUrl(dbUrl);
500
        	
501
        }
474 502
        if (xml.contains("minXworkArea"))
475 503
        {
476 504
            double x = xml.getDoubleProperty("minXworkArea");
......
497 525

  
498 526
    }
499 527

  
500
    public void load() throws DriverException{
528
    private void extractParamsFromDbUrl(String dbUrl2) {
529
    	//jdbc:postgres://localhost:5431/latin1
530
    	int iDbName = dbUrl2.lastIndexOf('/');
531
		dbName = dbUrl2.substring(iDbName+1);
532
		int iLast2points = dbUrl2.lastIndexOf(':');
533
		port = dbUrl2.substring(iLast2points+1, iDbName);
534
		int iHost = dbUrl2.indexOf("//");
535
		host = dbUrl2.substring(iHost + 2, iLast2points);
536
		connName = dbUrl2;
537
	}
538

  
539
	public void load() throws DriverException {
501 540
    	try {
502 541
            Class.forName(driverClass);
542
            
543
            String _drvName = getName();
503 544

  
504
            String keyPool = dbUrl + "_" + userName;
545
            String keyPool = _drvName.toLowerCase() + "_" + host.toLowerCase()
546
            + "_" + port + "_" + dbName.toLowerCase()
547
            + "_" + userName.toLowerCase();
548
            
505 549
            Connection newConn = null;
506 550
            String clave = null;
507
            if (!poolPassw.containsKey(keyPool))
508
            {
509
                JPasswordDlg dlg = new JPasswordDlg();
510
                String strMessage = Messages.getString("conectar_jdbc");
511
                String strPassword = Messages.getString("password");
512
                dlg.setMessage(strMessage + " " + dbUrl + ". " + strPassword + "?");
513
                dlg.show();
514
                clave = dlg.getPassword();
515
                if (clave == null)
516
                    return;
517
                poolPassw.put(keyPool, clave);
518
            }
519
            else
520
            {
551
            ConnectionWithParams cwp = null;
552
            
553
            if (poolPassw.containsKey(keyPool)) {
554
            	
521 555
                clave = (String) poolPassw.get(keyPool);
556
                cwp = SingleJDBCConnectionManager.instance().getConnection(
557
 					_drvName, userName, clave, connName,
558
 					host, port, dbName, true);
559

  
560
            } else {
561
            	
562
                cwp = SingleJDBCConnectionManager.instance().getConnection(
563
     					_drvName, userName, null, connName,
564
     					host, port, dbName, false);
565
                
566
                if (cwp.isConnected()) {
567
                	
568
                	poolPassw.put(keyPool, cwp.getPw());
569
                	
570
                } else {
571
                	
572
                    JPasswordDlg dlg = new JPasswordDlg();
573
                    String strMessage = Messages.getString("conectar_jdbc");
574
                    String strPassword = Messages.getString("password");
575
                    dlg.setMessage(strMessage
576
                    		+ " ["
577
                    		+ _drvName + ", "
578
                    		+ host + ", "
579
                    		+ port + ", "
580
                    		+ dbName + ", "
581
                    		+ userName + "]. "
582
                    		+ strPassword
583
                    		+ "?");
584
                    dlg.show();
585
                    clave = dlg.getPassword();
586
                    if (clave == null)
587
                        return;
588
                    poolPassw.put(keyPool, clave);
589
                    
590
                    cwp.connect(clave);
591
                }
522 592
            }
523
            newConn = DriverManager.getConnection(dbUrl, userName, clave);
593

  
594
            newConn = cwp.getConnection();
524 595
            newConn.setAutoCommit(false);
525 596

  
526 597
            DBLayerDefinition lyrDef = new DBLayerDefinition();
......
540 611
            	lyrDef = getLyrDef();
541 612
            }
542 613

  
543

  
544

  
545 614
            setData(newConn, lyrDef);
546 615
        } catch (ClassNotFoundException e) {
547 616
            logger.debug(e);
......
551 620
            type.setLayerName(this.getTableName());
552 621
            throw new DriverException("Driver JDBC no encontrado", e,  type);
553 622
        } catch (SQLException e) {
554
            logger.debug(e);
555
            SqlDriveExceptionType type =
556
            	new SqlDriveExceptionType();
557
            type.setSql("No disponible");
558
            throw new DriverException(e, type);
559
        }
623
        	
624
        	throw new DriverException(e.getMessage());
625
        	
626
		}
560 627
    }
561 628
    /* (non-Javadoc)
562 629
     * @see com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver#getXMLEntity()
......
567 634
        xml.putProperty("className",this.getClass().getName());
568 635
        try {
569 636
            DatabaseMetaData metadata = getConnection().getMetaData();
570
            xml.putProperty("dbURL", metadata.getURL());
571 637
            xml.putProperty("catalog", getLyrDef().getCatalogName());
638
            
572 639
            // TODO: NO DEBEMOS GUARDAR EL NOMBRE DE USUARIO Y CONTRASE?A
573 640
            // AQUI. Hay que utilizar un pool de conexiones
574 641
            // y pedir al usuario que conecte a la base de datos
......
590 657
            xml.putProperty("THE_GEOM", lyrDef.getFieldGeometry());
591 658
            xml.putProperty("whereclause", getWhereClause());
592 659
            xml.putProperty("SRID", lyrDef.getSRID_EPSG());
660

  
661
            ConnectionWithParams cwp =
662
            	SingleJDBCConnectionManager.instance().findConnection(getConnection());
663

  
664
            xml.putProperty("host", cwp.getHost());
665
            xml.putProperty("port", cwp.getPort());
666
            xml.putProperty("dbName", cwp.getDb());
667
            xml.putProperty("connName", cwp.getName());
668

  
593 669
            if (getWorkingArea() != null)
594 670
            {
595 671
                xml.putProperty("minXworkArea", getWorkingArea().getMinX());
......
718 794
    }
719 795
    
720 796
    /**
797
     * Gets available table names. Should be overwritten by subclasses if its
798
     * not compatible or if it can be refined
799
     * 
800
     * @param conn connection object
801
     * @param catalog catalog name
802
     * @return array of strings with available table names
803
     * @throws SQLException
804
     */
805
    public String[] getTableNames(Connection conn, String catalog) throws SQLException {
806
    	
807
    	DatabaseMetaData dbmd = conn.getMetaData();
808
        String[] types = {"TABLE", "VIEW"};
809
		ResultSet rs = dbmd.getTables(catalog, null, null, types);
810
		TreeMap ret = new TreeMap();
811
		while (rs.next()){
812
			ret.put(rs.getString("TABLE_NAME"), rs.getString("TABLE_NAME"));
813
		}
814
		rs.close();
815
		return (String[]) ret.keySet().toArray(new String[0]);
816
    }
817
    
818

  
819
    /**
820
     *       Gets all field names of a given table
821
     * @param conn connection object
822
     * @param table_name table name
823
     * @return all field names of the given table
824
     * @throws SQLException
825
     */
826
    public String[] getAllFields(Connection conn, String table_name) throws SQLException {
827
    	
828
		Statement st = conn.createStatement();
829
		ResultSet rs = st.executeQuery("select * from " + table_name + " LIMIT 1");
830
		ResultSetMetaData rsmd = rs.getMetaData();
831
		String[] ret = new String[rsmd.getColumnCount()];
832

  
833
		for (int i = 0; i < ret.length; i++) {
834
			ret[i] = rsmd.getColumnName(i+1);
835
		}
836
		rs.close(); st.close();
837
		return ret;
838
    }
839

  
840
    /**
841
     *       Gets all field type names of a given table
842
     * @param conn connection object
843
     * @param table_name table name
844
     * @return all field type names of the given table
845
     * @throws SQLException
846
     */
847
    public String[] getAllFieldTypeNames(Connection conn, String table_name) throws SQLException {
848
    	
849
		Statement st = conn.createStatement();
850
		ResultSet rs = st.executeQuery("select * from " + table_name + " LIMIT 1");
851
		ResultSetMetaData rsmd = rs.getMetaData();
852
		String[] ret = new String[rsmd.getColumnCount()];
853

  
854
		for (int i = 0; i < ret.length; i++) {
855
			ret[i] = rsmd.getColumnTypeName(i+1);
856
		}
857
		rs.close(); st.close();
858
		return ret;
859
    }
860

  
861
    /**
862
     * Gets the table's possible id fields. By default, all fields can be id. 
863
     * It should be overwritten by subclasses.
864
     * 
865
     * @param conn conenction object
866
     * @param table_name table name
867
     * @return the table's possible id fields
868
     * @throws SQLException
869
     */
870
    public String[] getIdFieldsCandidates(Connection conn, String table_name) throws SQLException {
871
    	return getAllFields(conn, table_name);
872
    }
873
    
874
    /**
875
     * Gets the table's possible geometry fields. By default, all fields can be geometry
876
     * fields. It should be overwritten by subclasses.
877
     * 
878
     * @param conn conenction object
879
     * @param table_name table name
880
     * @return the table's possible geometry fields
881
     * @throws SQLException
882
     */
883
    public String[] getGeometryFieldsCandidates(Connection conn, String table_name) throws SQLException {
884
    	return getAllFields(conn, table_name);
885
    }
886
    
887
    /**
888
     * Tells if it's an empty table (with no records)
889
     * @param conn conenction object
890
     * @param tableName rtable name
891
     * @return whether it's an empty table (with no records) or not
892
     */
893
	public boolean isEmptyTable(Connection conn, String tableName) {
894
		
895
		boolean res = true;
896

  
897
		try {
898
			Statement st = conn.createStatement();
899
			ResultSet rs = null;
900
			rs = st.executeQuery("select * from " + tableName + " LIMIT 1");
901
			res = !rs.next();
902
			rs.close(); st.close();
903
		} catch (Exception ex) {
904
			res = true;
905
		}
906
		return res;
907
	}
908

  
909

  
910

  
911
	/**
912
	 * Utility method to allow the driver to do something with the geometry field.
913
	 * By default does nothing.
914
	 * 
915
	 * @param flds user-selected fields
916
	 * @param geomField geometry field
917
	 * @return new user-selected fields
918
	 */
919
	public String[] manageGeometryField(String[] flds, String geomField) {
920
		return flds;
921
	}
922
	
923
	/**
721 924
	 * Empty method called when the layer is going to be removed from the view.
722 925
	 * Subclasses can overwrite it if needed.
723 926
	 *
......
725 928
	public void remove() {
726 929
		
727 930
	}
931

  
932
	public void addDriverEventListener(DriverEventListener listener) {
933
		if (!driverEventListeners.contains(listener))
934
			driverEventListeners.add(listener);
935
		
936
	}
937

  
938
	public void removeDriverEventListener(DriverEventListener listener) {
939
		driverEventListeners.remove(listener);
940
		
941
	}
942
	
943
	public void notifyDriverEndLoaded() {
944
		DriverEvent event = new DriverEvent(DriverEvent.DRIVER_EVENT_LOADING_END);
945
		for (int i=0; i < driverEventListeners.size(); i++)
946
		{
947
			DriverEventListener aux = (DriverEventListener) driverEventListeners.get(i);
948
			aux.driverNotification(event);
949
		}
950
	}
728 951
    
729

  
730 952
}

Also available in: Unified diff