![]()  | 
CS 635: Advanced Object-Oriented Design & Programming | 
|---|
| References | slide # 1 | 
| Motivating Adapter | slide # 2 | 
| Adapter | slide # 7 | 
| ...Consequences | slide # 11 | 
| ...Adapter Verses State | slide # 15 | 
CGI Environment Variables at:
http://hoohoo.ncsa.uiuc.edu/cgi/env.html
Servlets have greater functionality and are faster, but require special Web servers or servers with special extensions
To help write Java CGI programs there is class sdsu.net.CGI
Adapters would be useful in moving code between servers to avoid having to rewrite the code
There are various issues in writing such adapters
One issue is access to the CGI environment variables
There are about 20 common CGI environment variables
In servlets one has a HttpRequest class that has a getX() method for each CGI environment variable
sdsu.net.CGI class returns a hash table with one entry per CGI environment variable
Do we have to rewrite all the CGI programs?
We have code that uses a class with get( "X" ) method
We can write a wrapper around HttpRequest to make it act
like a hash table 
sdsu.net.CGI cgiGateWay = sdsu.net.CGI.getInstance();
Hashtable cgiVariables =
     cgiGateWay.getCGIEnvironmentVariables();
To avoid more CGI details the complete code is not shown
class HTTPAdapter extends HttpRequest
     {
     Hashtable CGIvariables;
     
     public HTTPAdapter( Hashtable CGIEnvironment )
          {
          CGIvariables = CGIEnvironment;
          }
     
     public String getAuthType()
          {
          return (String) CGIvariables.get( "AUTH_TYPE" );
          }
          
     public String getRemoteUser()
          {
          return (String) CGIvariables.get( "REMOTE_USER" );
          }
          
          etc. 
     }
Class Adapter Example
class OldSquarePeg {
     public:
          void squarePegOperation()
               { do something }
}
class RoundPeg {
     public:
          void virtual roundPegOperation = 0;
}
class PegAdapter: private OldSquarePeg, 
                    public RoundPeg  {
     public:
          void virtual roundPegOperation()  {
               add some corners;
               squarePegOperation();
          }
}
     
void clientMethod() {
     RoundPeg* aPeg = new PegAdapter();
     aPeg->roundPegOperation();
}
class OldSquarePeg     {
     public:
          void squarePegOperation() { do something }
     }
class RoundPeg     {
     public:
          void virtual roundPegOperation = 0;
     }
class PegAdapter:  public RoundPeg     {
     private:
          OldSquarePeg* square;
          
     public:
          PegAdapter()  { square = new OldSquarePeg; }
               
          void virtual roundPegOperation()     {
               add some corners;
               square->squarePegOperation();
               }
     }
The Adapter may just map one operation to another
class PegAdapter:  public RoundPeg     {
     private:
          OldSquarePeg* square;
          
     public:
          PegAdapter()     { square = new OldSquarePeg;}
               
          void roundPegOperation()     {
               square->squarePegOperation();
          }
}
This class would be given a list of keys to getX methods and an Adaptee object
HttpRequest CGIEnvironment = getHttpRequest();
PluggableHashAdapter sample = 
     new PluggableHashAdapter( CGIEnvironment );
sample.adapt( "AUTH_TYPE" , getAuthType );
sample.adapt( "REMOTE_USER" , getRemoteUser );
etc.
sample.get( "REMOTE_USER" );
Pluggable Adapters are common in Smalltalk, were it is
easier to map strings to method calls
class OldSquarePeg {
     public:
          void virtual squarePegOperation() { blah }
}
class RoundPeg {
     public:
          void virtual roundPegOperation() { blah }
}
class PegAdapter: public OldSquarePeg, RoundPeg {
     public:
          void virtual roundPegOperation() {
               add some corners;
               squarePegOperation();
          }
          void virtual squarePegOperation() {
               add some corners;
               roundPegOperation();
          }
}