001    package com.sptci.rwt.webui;
002    
003    import java.security.Principal;
004    import java.util.ArrayList;
005    import java.util.Collection;
006    import java.util.Map;
007    import java.util.TreeMap;
008    
009    import javax.naming.Binding;
010    import javax.naming.Context;
011    import javax.naming.InitialContext;
012    import javax.naming.NamingEnumeration;
013    
014    import nextapp.echo2.app.Component;
015    import nextapp.echo2.app.FloatingPane;
016    
017    import com.sptci.echo2.Application;
018    import com.sptci.echo2.Configuration;
019    import com.sptci.echo2.Controller;
020    import com.sptci.echo2.View;
021    
022    import com.sptci.rwt.Category;
023    import com.sptci.rwt.ConnectionManager;
024    import com.sptci.rwt.ConnectionParameters;
025    import com.sptci.rwt.Connections;
026    import com.sptci.rwt.DBMSAnalyser;
027    import com.sptci.rwt.DBMSMetaData;
028    import com.sptci.rwt.DatabaseType;
029    import com.sptci.rwt.Queries;
030    import com.sptci.rwt.Query;
031    
032    /**
033     * The primary <code>ContentPane</code> for the application.
034     *
035     * <p>&copy; Copyright 2007 <a href='http://sptci.com/' target='_new'>Sans Pareil Technologies, Inc.</a></p>
036     * @author Rakesh Vidyadharan 2007-09-29
037     * @version $Id: MainController.java 4123 2008-05-25 21:49:01Z rakesh $
038     */
039    public class MainController extends Controller<MainView>
040    {
041      /**
042       * The property name used to identify the connection manager for the
043       * session.
044       *
045       * {@value}
046       */
047      public static final String CONNECTION_MANAGER = "connectionManager";
048    
049      /**
050       * The property name used to identify the instance of this class stored
051       * for the session.
052       *
053       * {@value}
054       */
055      public static final String CONTROLLER = "controller";
056    
057      /** The object that represents saved connections. */
058      private Connections connections;
059    
060      /** The object that represents saved queries. */
061      private Queries queries;
062    
063      /**
064       * Create a new instance of the controller for the specified view.
065       *
066       * @param view The view this controller controls.
067       */
068      public MainController( final MainView view )
069      {
070        super( view );
071        Application.getApplication().setProperty( CONTROLLER, this );
072    
073        Principal principal = Application.getApplication().getPrincipal();
074        String user = ( (principal == null ) ? "default" : principal.getName() );
075        connections = Connections.getInstance( user );
076        queries = Queries.getInstance( user );
077      }
078    
079      /**
080       * Return the instance stored for the session.
081       *
082       * <p><b>Note:</b> This method should be invoked only after being
083       * instantiated.</p>
084       *
085       * @return The controller for the session.
086       */
087      public static MainController getController()
088      {
089        return (MainController)
090          Application.getApplication().getProperty( CONTROLLER );
091      }
092    
093      /**
094       * Get the connection manager in use by the session.
095       *
096       * @return The manager in use.
097       */
098      public ConnectionManager getConnectionManager()
099      {
100        return (ConnectionManager) application.getProperty( CONNECTION_MANAGER );
101      }
102    
103      /**
104       * Set the connection manager to use for the session.
105       *
106       * @param manager The manager to use.
107       */
108      public void setConnectionManager( final ConnectionManager manager )
109      {
110        application.setProperty( CONNECTION_MANAGER, manager );
111        getView().refresh();
112      }
113    
114      /**
115       * Retrieve all the available datasources configured under the
116       * <code>java:/comp/env</code> context.
117       *
118       * @return The collection of configured datasource names.
119       */
120      public Collection<String> getDataSources()
121      {
122        Collection<String> collection = new ArrayList<String>();
123    
124        try
125        {
126          Context context = new InitialContext();
127          addBinding( "java:/comp/env", context, collection );
128        }
129        catch ( Throwable t )
130        {
131          processFatalException( Configuration.getString(
132                this, "dataSourceError" ), t );
133        }
134    
135        return collection;
136      }
137    
138      private void addBinding( final String name, final Context environment,
139          final Collection<String> collection ) throws javax.naming.NamingException
140      {
141        for ( NamingEnumeration<Binding> enumeration =
142            environment.listBindings( name ); enumeration.hasMore(); )
143        {
144          Binding binding = enumeration.nextElement();
145          final String resource = name + "/" + binding.getName();
146    
147          if ( environment.lookup( resource ) instanceof javax.sql.DataSource )
148          {
149            collection.add( resource );
150          }
151          else addBinding( resource, environment, collection );
152        }
153      }
154    
155      /**
156       * Retrieve all the saved database connections configured by the user.
157       *
158       * @return A {@link java.util.Map} containing the database name as the
159       *   <code>key</code> and a {@link java.util.Collection} of saved
160       *   connection names as the <code>value</code>.
161       */
162      public Map<String,Collection<String>> getSavedConnections()
163      {
164        Map<String,Collection<String>> map = new TreeMap<String,Collection<String>>();
165        
166        for ( DatabaseType dt : connections.getDatabaseTypes() )
167        {
168          ArrayList<String> list = new ArrayList<String>();
169          list.addAll( dt.getNames() );
170          map.put( dt.getName(), list );
171        }
172    
173        return map;
174      }
175    
176      /**
177       * Create a connection parameters bean using the values in the {@link
178       * ConnectionDialogue}.
179       *
180       * @return The new connection parameters bean.
181       */
182      public ConnectionParameters getParameters(
183          final ConnectionDialogue dialogue )
184      {
185        final String userName = dialogue.getUserName();
186        final String password = dialogue.getPassword();
187        final String host = dialogue.getHost();
188        final int port = dialogue.getPort();
189        final String database = dialogue.getDatabase();
190        final String databaseType = dialogue.getDatabaseType();
191        final String urlPattern = Configuration.getString(
192            dialogue, databaseType + ".urlPattern" );
193        final String driver = Configuration.getString(
194            dialogue, databaseType + ".driver" );
195    
196        return new ConnectionParameters( userName, password, host, port,
197            database, databaseType, urlPattern, driver );
198      }
199    
200      /**
201       * Retrieve the metadata about the database pointed to by the current
202       * active {@link com.sptci.rwt.ConnectionManager}.
203       *
204       * @return The meta data value object for the database.  Returns
205       *   <code>null</code> if no active connection manager exists for the
206       *   application.
207       */
208      public DBMSMetaData getDBMSMetaData()
209      {
210        DBMSMetaData metadata = null;
211        ConnectionManager manager = getConnectionManager();
212        if ( manager == null )
213        {
214          return null;
215        }
216    
217        try
218        {
219          DBMSAnalyser analyser = new DBMSAnalyser( manager );
220          metadata = analyser.analyse();
221        }
222        catch ( Throwable t )
223        {
224          processFatalException(
225              Configuration.getString( this, "dbmsMetaData" ), t );
226        }
227    
228        return metadata;
229      }
230    
231      /**
232       * Method used to update the content of {@link MainView#right} content
233       * area.
234       *
235       * @param component The component that is to be displayed.
236       */
237      public void setContent( final Component component )
238      {
239        getView().setContent( component );
240      }
241    
242      /**
243       * Convenient method for {@link com.sptci.echo2.Application#addPane}.
244       */
245      public void addPane( final FloatingPane pane )
246      {
247        application.addPane( pane );
248      }
249      
250      /**
251       * Returns {@link #connections}.
252       *
253       * @return The value/reference of/to connections.
254       */
255      public Connections getConnections()
256      {
257        return connections;
258      }
259      
260      /**
261       * Returns {@link #queries}.
262       *
263       * @return The value/reference of/to queries.
264       */
265      public Queries getQueries()
266      {
267        return queries;
268      }
269      
270      /**
271       * Returns {@link com.sptci.rwt.Queries#getCategories}.
272       *
273       * @return The value/reference of/to queries.
274       */
275      public Collection<Category> getCategories()
276      {
277        return queries.getCategories();
278      }
279    
280      /**
281       * Rebuild the {@link MainView#menuComponent} to reflect modifications
282       * made to the application persistent state.  Persistent state is
283       * modified when new connections/queries are added to the persistent
284       * state.
285       */
286      public void resetMenu()
287      {
288        view.rebuildMenu();
289      }
290    
291      /**
292       * Convenience method that invokes {@link
293       * com.sptci.echo2.Application#getParentView}
294       *
295       * @return The parent view of the specified component.
296       */
297      public View getParentView( Component component )
298      {
299        return application.getParentView( component );
300      }
301    
302      /**
303       * Sets the focussed component for the application.
304       *
305       * @see nextapp.echo2.app.ApplicationInstance#setFocusedComponent
306       * @param component The component that is to gain the focus.
307       */
308      public void setFocused( Component component )
309      {
310        application.setFocusedComponent( component );
311      }
312    }