Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 49c61517bd1fbf3bd8549fae12512503992cb061 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
                                                                                
                                                        



                                                                                




                                                                                
                                        
                                                       
                                                             
                                                             
                                                                            
                                                                
                                                                                      
                                                                             

                                                               

                                             
                                                    
                                                     
                                                    



                                
                                       
                                                       
 
                                                 

                                                              

                                                                                      
 

                                                                                          
 
                                                      
                                                              
 



                                                                         
                                                                 
 
                                                          
                                            



                                          
                                                                                                    
 
                                                                                                 
 
                                                                                                                                  
 
 
                                            
 
                                                                                                                 
                        
                                                                 

                                                                                 
                                                                             
                                                                        
                                                             





                                                                                             
         
 
 
                                                              
 
                                 
                                                           
         
 

                                                                
                                                          

         

                                                                
                                                          
         
 
 
                                                                 
 

                                                                   
         
 




                                                              
         
 
 
                                                                 
 


                                                                 
         
 

                                                                 

         
                                         
                                                                                              
         
 
                                            
                                                                  
         
 



                                                                                                
                                            
                                                                                                 
         
 







                                                                                             




                                                                               
                                     
                                                                                                    







                                                                                                
         
 
                                         
                                                                                         

         

                                                                   
         
 

                                                                                                                    
         
 



                                                                                                                 


                                                                     
         
 

                                         
         
 


                                                                                  
         
 

                                            
         
 







                                                                              
         
 


                                                                    

         

                                                                           
         
 





                                                                       

         










































                                                                                            

         


                                                 




                                                  


                                                                                                 



                                                                                       
                                                    
                                        
                                    


                                              
                                                                                                                                      








                                                                                                
                                                                                                                                                   
         
 






                                                                                       
         
 
           























                                                                                                                  
           

                                                                                                            

         
           
                                                                                             
                                                                                 
                         
           
                                                      
                                                                                  
                                                                    
         
 

                                                            
         
 

                                                                

         

                                                              

         

                                                                  

         

                                                            

         

                                                              

         

                                                                      

         

                                                                                               

         



                                                                  
 



                                          
                                                                          





                                                        

                                                                                                                          
           
                                                                                    
                                                                                                                                       





                                                                         
                                                        


                                                                            
                                                           

                 
                                          
                                                           


                                           
                                                             

                 


                                                                                  
                                               
                                                        
                                                                                 
                                                     

                                                                                              


                         





                                                                      
                                                          
                                                     

                                                                                              



                                                              
                                                     

                                                                                              
                                                     





                                                              
                                                     

                                                                                              


                         
                                               
                                                        
                                             
                                                                         
                                                     

                                                                                              
                         






                                                                                         


                                                                       
                 
                

                                                               


                                                                
                 
 
                                               
                                                                


                                                                   



                                                               


                                                                   




                                                         
                                                             

                                                                                               


                         
                                                                

                                                                                                   


                         
                                                             

                                                                                                 


                         
                                                                   

                                                                                                     


                         
                                                          

                                                                                               


                         
                                                             

                                                                                                 


                         
                                                                         

                                                                                                         


                         
         
 


                                                       





                                                                                                     
                                                           
                                                                                               


                 
 
/*******************************************************************************
 * Copyright (c) 2006, 2009 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.db.internal;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.datatools.connectivity.ConnectEvent;
import org.eclipse.datatools.connectivity.IConnectionProfile;
import org.eclipse.datatools.connectivity.IManagedConnection;
import org.eclipse.datatools.connectivity.IManagedConnectionOfflineListener;
import org.eclipse.datatools.connectivity.drivers.DriverManager;
import org.eclipse.datatools.connectivity.drivers.jdbc.IJDBCDriverDefinitionConstants;
import org.eclipse.datatools.connectivity.sqm.core.connection.ConnectionInfo;
import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
import org.eclipse.datatools.sqltools.core.profile.ProfileUtil;
import org.eclipse.jpt.db.ConnectionListener;
import org.eclipse.jpt.db.ConnectionProfile;
import org.eclipse.jpt.db.DatabaseIdentifierAdapter;
import org.eclipse.jpt.utility.internal.ListenerList;
import org.eclipse.jpt.utility.internal.StringTools;

/**
 *  Wrap a DTP ConnectionProfile
 */
final class DTPConnectionProfileWrapper
	implements DTPDatabaseObject, ConnectionProfile
{
	/** the wrapped DTP connection profile */
	private final IConnectionProfile dtpConnectionProfile;

	/** adapter supplied by the client (determines identifier delimiters, etc.) */
	private final DatabaseIdentifierAdapter identifierAdapter;

	/** callback passed to the identifier adapter */
	private final DatabaseIdentifierAdapter.DefaultCallback identifierAdapterCallback;

	/** the DTP managed connection we listen to */
	private final IManagedConnection dtpManagedConnection;

	/**
	 * forward events from the DTP managed connection above;
	 * we listen and propagate events iff we have listeners ourselves
	 */
	private final LocalConnectionListener connectionListener;

	/** lazy-initialized, and deleted at disconnect */
	private DTPDatabaseWrapper database;


	// ********** constants **********

	private static final String LIVE_DTP_CONNECTION_TYPE = "java.sql.Connection";  //$NON-NLS-1$

	private static final String OFFLINE_DTP_CONNECTION_TYPE = ConnectionInfo.class.getName();

	private static final String DATABASE_PRODUCT_PROP_ID = "org.eclipse.datatools.connectivity.server.version";  //$NON-NLS-1$


	// ********** constructor **********

	DTPConnectionProfileWrapper(IConnectionProfile dtpConnectionProfile, DatabaseIdentifierAdapter adapter) {
		super();
		this.dtpConnectionProfile = dtpConnectionProfile;
		this.identifierAdapter = adapter;
		this.identifierAdapterCallback = new IdentifierAdapterCallback();
		this.dtpManagedConnection = this.buildDTPManagedConnection();
		this.connectionListener = new LocalConnectionListener();
		// don't listen to the managed connection yet
	}

	private IManagedConnection buildDTPManagedConnection() {
		String connectionType = this.dtpConnectionProfile.supportsWorkOfflineMode() ?
				OFFLINE_DTP_CONNECTION_TYPE : LIVE_DTP_CONNECTION_TYPE;
		return this.dtpConnectionProfile.getManagedConnection(connectionType);
	}


	// ********** DatabaseObject implementation **********

	public String getName() {
		return this.dtpConnectionProfile.getName();
	}

	public String getIdentifier(String javaIdentifier) {
		// connection profiles do not have "identifiers"
		throw new UnsupportedOperationException();
	}

	public String getIdentifier() {
		// connection profiles do not have "identifiers"
		throw new UnsupportedOperationException();
	}


	// ********** DTPDatabaseObject implementation **********

	public DTPConnectionProfileWrapper getConnectionProfile() {
		return this;
	}

	public synchronized DTPDatabaseWrapper getDatabase() {
		if (this.database == null) {
			this.database = this.buildDatabase();
		}
		return this.database;
	}


	// ********** ConnectionProfile implementation **********

	// ***** properties
	public String getProviderID() {
		return this.dtpConnectionProfile.getProviderId();
	}

	public String getInstanceID() {
		return this.dtpConnectionProfile.getInstanceID();
	}

	public String getDatabaseName() {
		return this.getProperty(IJDBCDriverDefinitionConstants.DATABASE_NAME_PROP_ID);
	}

	public String getDatabaseProduct() {
		return this.getProperty(DATABASE_PRODUCT_PROP_ID);
	}

	public String getDatabaseVendor() {
		return this.getProperty(IJDBCDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID);
	}

	public String getDatabaseVersion() {
		return this.getProperty(IJDBCDriverDefinitionConstants.DATABASE_VERSION_PROP_ID);
	}

	public String getDriverClassName() {
		return this.getProperty(IJDBCDriverDefinitionConstants.DRIVER_CLASS_PROP_ID);
	}

	public String getURL() {
		return this.getProperty(IJDBCDriverDefinitionConstants.URL_PROP_ID);
	}

	/**
	 * Returns the user name.
	 * Allows user name composed by more than one word.
	 * If the user name contains a keyword, it returns the first word only.
	 */
	public String getUserName() {
		String userName = this.getProperty(IJDBCDriverDefinitionConstants.USERNAME_PROP_ID);
		userName = userName.trim(); 
		String[] names =  userName.split("\\s+");	//$NON-NLS-1$
		if(names.length == 3) { // 208946 handle username like "sys as sysdba" on Oracle
		    if(this.nameIsKeyword(names[1])) {
		    	return names[0];
		    }
		}
		return userName;
	}

	public String getUserPassword() {
		return this.getProperty(IJDBCDriverDefinitionConstants.PASSWORD_PROP_ID);
	}

	public String getDriverDefinitionID() {
		return this.getProperty(DRIVER_DEFINITION_PROP_ID);
	}

	public String getDriverJarList() {
		return DriverManager.getInstance().getDriverInstanceByID(this.getDriverDefinitionID()).getJarList();
	}

	public String getDriverName() {
		return DriverManager.getInstance().getDriverInstanceByID(this.getDriverDefinitionID()).getName();
	}

	// ***** connection
	public boolean isActive() {
		return this.isConnected() || this.isWorkingOffline();
	}

	public boolean isInactive() {
		return ! this.isActive();
	}

	public boolean isConnected() {
		return this.dtpManagedConnection.isConnected()
				&& ! this.dtpManagedConnection.isWorkingOffline();
	}

	public boolean isDisconnected() {
		return ! this.isConnected();
	}

	public void connect() {
		if (this.isDisconnected()) {
			this.checkStatus(this.dtpConnectionProfile.connect());
		}
	}
	
	public void disconnect() {
		this.checkStatus(this.dtpConnectionProfile.disconnect());
	}

	// ***** off-line support
	public boolean isWorkingOffline() {
		return this.dtpManagedConnection.isWorkingOffline();
	}

	public boolean supportsWorkOfflineMode() {
		return this.dtpConnectionProfile.supportsWorkOfflineMode();
	}

	public IStatus saveWorkOfflineData() {
		return this.dtpConnectionProfile.saveWorkOfflineData();
	}
	
	public boolean canWorkOffline() {
		return this.dtpConnectionProfile.canWorkOffline();
	}

	public IStatus workOffline() {
		return this.dtpConnectionProfile.workOffline();
	}
	
	// ***** listeners
	public synchronized void addConnectionListener(ConnectionListener listener) {
		if (this.hasNoListeners()) {  // first listener added
			this.startListening();
		}
		this.connectionListener.addConnectionListener(listener);
	}

	private void startListening() {
		this.dtpManagedConnection.addConnectionListener(this.connectionListener);
		if (this.database != null) {  // don't trigger database creation
			if (this.isConnected()) {  // DTP does not change when off-line
				this.database.startListening();
			}
		}
	}

	public synchronized void removeConnectionListener(ConnectionListener listener) {
		this.connectionListener.removeConnectionListener(listener);
		if (this.hasNoListeners()) {  // last listener removed
			this.stopListening();
		}
	}

	private void stopListening() {
		if (this.database != null) {  // don't trigger database creation
			if (this.isConnected()) {  // DTP does not change when off-line
				this.database.stopListening();
			}
		}
		this.dtpManagedConnection.removeConnectionListener(this.connectionListener);
	}

	boolean hasNoListeners() {
		return this.connectionListener.hasNoListeners();
	}

	boolean hasAnyListeners() {
		return this.connectionListener.hasAnyListeners();
	}


	// ********** internal methods **********

	private void checkStatus(IStatus status) {
		if (status.isOK()) {
			return;
		}
		if (status.isMultiStatus()) {
			for (IStatus child : status.getChildren()) {
				this.checkStatus(child);  // recurse, looking for the first error
			}
		}
		throw new RuntimeException(status.getMessage(), status.getException());
	}

	private DTPDatabaseWrapper buildDatabase() {
		if (this.isInactive()) {
			return null;
		}

		if (this.isWorkingOffline()) {
			ConnectionInfo connectionInfo = (ConnectionInfo) this.dtpManagedConnection.getConnection().getRawConnection();
			return new DTPDatabaseWrapper(this, connectionInfo.getSharedDatabase());
		}

		// TODO see DTP bug 202306
		// pass connect=true in to ProfileUtil.getDatabase()
		// there is a bug mentioned in a comment: 
		//     "during the profile connected event notification, 
		//     IManagedConnection is connected while IConnectionProfile is not"
		// so, some hackery here to handle hackery there
		return new DTPDatabaseWrapper(this, ProfileUtil.getDatabase(new DatabaseIdentifier(this.getName(), this.getDatabaseName()), true));
	}

	synchronized void clearDatabase() {
		if (this.database != null) {
			if (this.isConnected()) {  // DTP does not change when off-line
				this.database.stopListening();
			}
			this.database = null;
		}
	}

	/**
	 * This is called whenever we need to convert an identifier to a name
	 * (e.g. {@link org.eclipse.jpt.db.Table#getColumnForIdentifier(String)}).
	 * We channel all the calls to here and then we delegate to the
	 * client-supplied "database identifier adapter".
	 */
	String convertIdentifierToName(String identifier) {
		return this.identifierAdapter.convertIdentifierToName(identifier, this.identifierAdapterCallback);
	}

	/**
	 * The default "database identifier adapter" calls back to here so we can delegate to
	 * the database, which contains all the information necessary to properly
	 * convert identifiers.
	 */
	String convertIdentifierToName_(String identifier) {
		// the database should not be null here - call its internal method
		return this.database.convertIdentifierToName_(identifier);
	}

	/**
	 * This is called whenever we need to convert a name to an identifier
	 * (e.g. {@link org.eclipse.jpt.db.Table#getColumnForIdentifier(String)}).
	 * We channel all the calls to here and then we delegate to the
	 * client-supplied "database identifier adapter".
	 */
	String convertNameToIdentifier(String name) {
		return this.identifierAdapter.convertNameToIdentifier(name, this.identifierAdapterCallback);
	}

	/**
	 * The default "database identifier adapter" calls back to here so we can delegate to
	 * the database, which contains all the information necessary to properly
	 * convert names.
	 */
	String convertNameToIdentifier_(String name) {
		// the database should not be null here - call its internal method
		return this.database.convertNameToIdentifier_(name);
	}

	void databaseChanged(DTPDatabaseWrapper db) {
		this.connectionListener.databaseChanged(db);
	}

	void catalogChanged(DTPCatalogWrapper catalog) {
		this.connectionListener.catalogChanged(catalog);
	}

	void schemaChanged(DTPSchemaWrapper schema) {
		this.connectionListener.schemaChanged(schema);
	}

	void sequenceChanged(DTPSequenceWrapper sequence) {
		this.connectionListener.sequenceChanged(sequence);
	}

	void tableChanged(DTPTableWrapper table) {
		this.connectionListener.tableChanged(table);
	}

	void columnChanged(DTPColumnWrapper column) {
		this.connectionListener.columnChanged(column);
	}

	void foreignKeyChanged(DTPForeignKeyWrapper foreignKey) {
		this.connectionListener.foreignKeyChanged(foreignKey);
	}

	private String getProperty(String propertyName) {
		return this.dtpConnectionProfile.getBaseProperties().getProperty(propertyName);
	}

	private boolean nameIsKeyword(String name) {
		return name.equalsIgnoreCase("as");  //$NON-NLS-1$
	}


	// ********** overrides **********

	@Override
	public String toString() {
		return StringTools.buildToStringFor(this, this.getName());
	}


	// ********** DTP connection listener **********

	/**
	 * This listener translates and forwards {@link org.eclipse.datatools.connectivity.IManagedConnectionListener} and
	 * {@link IManagedConnectionOfflineListener} events to {@link ConnectionListener}s.
	 */
	class LocalConnectionListener implements IManagedConnectionOfflineListener {
		private ListenerList<ConnectionListener> listenerList = new ListenerList<ConnectionListener>(ConnectionListener.class);

		LocalConnectionListener() {
			super();
		}

		void addConnectionListener(ConnectionListener listener) {
			this.listenerList.add(listener);
		}

		void removeConnectionListener(ConnectionListener listener) {
			this.listenerList.remove(listener);
		}

		boolean hasNoListeners() {
			return this.listenerList.isEmpty();
		}

		boolean hasAnyListeners() {
			return ! this.listenerList.isEmpty();
		}


		// ********** IManagedConnectionListener implementation **********

		// off-line or inactive => live
		public void opened(ConnectEvent event) {
			// do not build the database here - it is built on-demand
			// forward event to listeners
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.opened(DTPConnectionProfileWrapper.this);
			}
		}

		/**
		 * This method is never called from the base DTP code.
		 * Perhaps DTP extenders call it....
		 * @see ManagedConnection#fireModifiedEvent(Object)
		 *     which is never called...
		 */
		public void modified(ConnectEvent event) {
			// forward event to listeners
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.modified(DTPConnectionProfileWrapper.this);
			}
		}

		public boolean okToClose(ConnectEvent event) {
			// forward event to listeners
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				if ( ! listener.okToClose(DTPConnectionProfileWrapper.this)) {
					return false;
				}
			}
			return true;
		}

		public void aboutToClose(ConnectEvent event) {
			// forward event to listeners
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.aboutToClose(DTPConnectionProfileWrapper.this);
			}
		}

		// live or off-line => inactive
		public void closed(ConnectEvent event) {
			// clear the database
			DTPConnectionProfileWrapper.this.clearDatabase();
			// forward event to listeners
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.closed(DTPConnectionProfileWrapper.this);
			}
		}


		// ********** IManagedConnectionOfflineListener implementation **********

		// live => off-line
		public boolean okToDetach(ConnectEvent event) {
			// convert the event to an "ok to close" event;
			// we are "closing" the live connection
			return this.okToClose(event);
		}
		
		// live => off-line
		public void aboutToDetach(ConnectEvent event) {
			// convert the event to a "close" event;
			// we are "closing" the live connection
			this.closed(event);
		}

		// inactive or live => off-line
		public void workingOffline(ConnectEvent event) {
			// convert the event to an "open" event;
			// we are "opening" the off-line connection
			this.opened(event);
		}

		// off-line => live
		public void aboutToAttach(ConnectEvent event) {
			// convert the event to an "close" event;
			// we are "closing" the off-line connection
			this.closed(event);
		}


		// ********** internal methods **********

		void databaseChanged(DTPDatabaseWrapper db) {
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.databaseChanged(DTPConnectionProfileWrapper.this, db);
			}
		}

		void catalogChanged(DTPCatalogWrapper catalog) {
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.catalogChanged(DTPConnectionProfileWrapper.this, catalog);
			}
		}

		void schemaChanged(DTPSchemaWrapper schema) {
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.schemaChanged(DTPConnectionProfileWrapper.this, schema);
			}
		}

		void sequenceChanged(DTPSequenceWrapper sequence) {
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.sequenceChanged(DTPConnectionProfileWrapper.this, sequence);
			}
		}

		void tableChanged(DTPTableWrapper table) {
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.tableChanged(DTPConnectionProfileWrapper.this, table);
			}
		}

		void columnChanged(DTPColumnWrapper column) {
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.columnChanged(DTPConnectionProfileWrapper.this, column);
			}
		}

		void foreignKeyChanged(DTPForeignKeyWrapper foreignKey) {
			for (ConnectionListener listener : this.listenerList.getListeners()) {
				listener.foreignKeyChanged(DTPConnectionProfileWrapper.this, foreignKey);
			}
		}

	}


	// ********** default DatabaseFinder **********

	class IdentifierAdapterCallback implements DatabaseIdentifierAdapter.DefaultCallback {
		public String convertIdentifierToName(String identifier) {
			// call back to the internal method
			return DTPConnectionProfileWrapper.this.convertIdentifierToName_(identifier);
		}
		public String convertNameToIdentifier(String name) {
			// call back to the internal method
			return DTPConnectionProfileWrapper.this.convertNameToIdentifier_(name);
		}
	}

}

Back to the top