November 23, 2014
Hot Topics:

Consolidating Email using Java, Part 2

  • November 15, 2005
  • By Richard G. Baldwin
  • Send Email »
  • More Articles »

Complete Program Listings

Complete listings of the classes discussed in this lesson are shown in Listings 9 and 10 below.
 
/*File BigDog06fetch.java 
Copyright 2005, R.G.Baldwin
Rev 08/17/05
This is a modification of the program named
BigDog04g to fully automate the process.
DISCLAIMER:  THIS PROGRAM IS PROVIDED TO YOU AT 
NO COST.  BY USING THIS PROGRAM TO PROCESS YOUR 
EMAIL, YOU AGREE THAT YOU ARE USING IT AT YOUR 
OWN RISK.  THE AUTHOR OF THE PROGRAM, RICHARD G. 
BALDWIN, ACCEPTS NO LIABILITY FOR ANY LOSS THAT 
YOU MAY INCUR THROUGH THE USE OF THIS PROGRAM.
This program downloads all messages from a
pop3Server and writes them as individual files in
a local working directory.  Then it instantiates 
an object of the class BigDog06forward, which 
forwards the messages to a specified email 
address using a specified SMTP server.
Messages are not deleted from the pop3Server 
until they have been forwarded to the specified 
email address. When the messages are deleted from
the pop3Server, the message files are also 
removed from the working directory.
By enabling and disabling blocks of code prior to
compilation, you can customize the program to 
cause the  message files to be moved from the
working directory into an archive directory or 
simply deleted from the working directory without
saving them in an archive directory.
The following information is provided as 
command-line parameters:
pop3Server: server from which the messages will 
  be downloaded
userName: on pop3Server
password: on pop3Server
destinationAddress: email address to which the 
  messages are to be forwarded
smtpServer: an available SMTP server that can be 
  used to forward the messages
workingDir: messages are temporarily stored here
archiveDir: messages are moved to here from the 
  workingDir for long-term storage if desired
fwdTag: String prepended to the subject when the 
  message is forwarded.
Note that both of the directories listed above 
must already exist when the program is run for 
the first time.
If message files are not being saved in an 
archive directory, the seventh parameter is a 
dummy parameter, which is essentially ignored by 
the program, but it must be provided.
If you don't want to tag the subject of the 
forwarded msg, just enter "" as the eighth 
command-line parameter.
For technical information on POP3, see RFC 1725
at
http://www.cse.ohio-state.edu/cgi-bin/rfc/
rfc1725.html
A POP3 Command Summary follows based on the
information at that web site.
Minimal POP3 Commands:
USER name
PASS string
QUIT
STAT
LIST [msg]
RETR msg
DELE msg
NOOP
RSET
QUIT
Optional POP3 Commands:
APOP name digest
TOP msg n
UIDL [msg]
POP3 Replies:
+OK
-ERR
Tested using JDK 1.5.0_01 under WinXP
************************************************/
import java.net.*;
import java.io.*;
import java.awt.*;
class BigDog06fetch{
  static String workingDir;
  int numberMsgs = 0;
  int msgNumber;
  String uidl = "";//unique msg ID
  BufferedReader inputStream;
  PrintWriter outputStream;
  Socket socket;
  String pathFileName;
  static String[] params;
  public static void main(String[] args){
    if(args.length != 8){
      System.out.println(
                   "Wrong number of parameters");
      System.out.println(
         "Usage: java BigDog06fetch "
         + "npop3Server nuserName npassword "
         + "ndestinationAddress nsmtpServer"
         + "nworkingDir narchiveDir nfwdTag");
      System.out.println("If not saving msg "
        + "files in archive, seventh parameter "
        + "is a dummy parameter.");
      System.out.println("Terminating program.");
      System.exit(0);
    }//end if
    
    //Save the command-line parameters for later 
    //use by the object of the class
    // BigDog06forward
    params = args;
    //Establish the name of the working
    // directory.  Note that this directory must
    // already exist.
    workingDir = args[5];
    
    System.out.println(
                     "pop3Server: " + params[0]);
    System.out.println("userName: " + params[1]);
    System.out.println("password: .........."); 
    System.out.println(
             "destinationAddress: " + params[3]);
    System.out.println(
                     "smtpServer: " + params[4]);
    System.out.println(
                    "workingDir: " +  params[5]);
    System.out.println(
                     "archiveDir: " + params[6]);
    System.out.println("fwdTag: " + params[7]);
    
    //Instantiate an object that will download
    // and save the messages as individual files.
    // This object will in turn instantiate an
    // object of the class BigDog06forward, which
    // will forward the messages to the
    // destination email address.    
    new BigDog06fetch(args[0],args[1],args[2]);
  }//end main
  //===========================================//
  //Constructor
  BigDog06fetch(String pop3Server,
                String userName,
                String password){
    int port = 110; //pop3 mail port
    try{
      //Get a socket, connected to the specified
      // pop3Server on the specified port.
      socket = new Socket(pop3Server,port);
      //Get an input stream from the socket
      inputStream = new BufferedReader(
                     new InputStreamReader(
                       socket.getInputStream()));
      //Get  an output stream to the socket.
      // Note that this stream will autoflush.
      outputStream = new PrintWriter(
               new OutputStreamWriter(
                 socket.getOutputStream()),true);
      //Display the msg received from the
      // pop3Server on the command-line screen
      // immediately following connection.
      String connectMsg = validateOneLine();
      System.out.println(
        "Connected to pop3Server " + connectMsg);
      //The communication process is now in the
      // AUTHORIZATION state.  Send the user
      // name and password to the pop3Server.
      //Commands are sent in plain text, upper
      // case to the pop3Server.  Some commands
      // require an argument following the
      // command, as is the case with USER.
      //Send the command.
      outputStream.println("USER " + userName);
      //Get response and confirm that the
      // response was +OK and was not -ERR.
      String userResponse = validateOneLine();
      //Display the response on the command-
      // line screen.
      System.out.println("USER " + userResponse);
      //Send the password to the pop3Server
      outputStream.println("PASS " + password);
      //Validate the pop3Server's response as +OK
      // Display the response in the process.
      System.out.println(
                    "PASS " + validateOneLine());
      System.out.println("Downloading Messages");
    }catch(Exception e){
      e.printStackTrace();
      System.exit(0);
    }//end catch
    
    fetchMsgs();
  }//end constructor
  //===========================================//
  //Validate a one-line response.
  //The purpose of this method is to confirm that
  // the pop3Server returned +OK and not -ERR to
  // the previous command.
  //If +OK, the method returns the string
  // returned by the pop3Server.
  //If -ERR, the method displays the string
  // returned by the pop3Server and terminates
  // the session.
  private String validateOneLine(){
    try{
      String response = inputStream.readLine();
      if(response.startsWith("+OK")){
        return response;
      }else{
        System.out.println(response);
        //Terminate the session.
        outputStream.println("QUIT");
        socket.close();
        System.out.println(
                       "Premature QUIT on -ERR");
        System.exit(0);
      }//end else
    }catch(IOException ex){
      ex.printStackTrace();
      System.exit(0);
    }//end catch
    //The following return statement is required
    // to satisfy the compiler, but it can never
    // be reached.
    return "Make compiler happy";
  }//end validateOneLine()
  //===========================================//
  
  void fetchMsgs(){
    //Download all messages on the pop3Server.
    try{
      //The communication process is now in the
      // TRANSACTION state.
      //Retrive and save messages
      outputStream.println("STAT");
      String stat = validateOneLine();
      //Get the number of messages as a String.
      String numberMsgsStr = stat.substring(
                          4,stat.indexOf(" ",5));
      //Convert the String to an int.
      numberMsgs = Integer.parseInt(
                                  numberMsgsStr);
                            
      if(numberMsgs == 0){
        System.out.println(
                          "No msg to download.");
        System.out.println(
                         "Terminating program.");
        System.exit(0);
      }//end if
      //NOTE: Msg numbers begin with 1, not 0.
      //Retrieve and save each message.  Each msg
      // ends with a period on a new line.
      msgNumber = 1;
      while(msgNumber <= numberMsgs){
        //Process the next message.
        //Get and save a unique identifier for
        // the message from the pop3Server and
        // validate the response.
        outputStream.println(
                            "UIDL " + msgNumber);
        uidl = validateOneLine();
        //Open an output file to save the
        // message.  Use the UIDL as the file
        // name.
        pathFileName = workingDir + uidl;
        DataOutputStream dataOut =
                          new DataOutputStream(
                            new FileOutputStream(
                                  pathFileName));
        //Send a RETR command to begin the
        // message retrieval process
        outputStream.println(
                            "RETR " + msgNumber);
        //Validate the response.
        String retrResponse =
                               validateOneLine();
        //Read the first line in the message from
        // the pop3Server.
        String msgLine = inputStream.readLine();
        //Continue reading lines until a "." is
        // encountered as the first char in a
        // line.  That signals the end of the
        // msg.
        while(!(msgLine.equals("."))){
          //Write the line to the output file and
          // read the next line.  Insert newline
          // characters when writing the output
          // to the file.
          dataOut.writeBytes(msgLine + "n");
          msgLine = inputStream.readLine();
        }//end while(!(msgLine.equals(".")
        
        //Close the output file.  The message is
        // now stored in a local file with a file
        // name based on the unique ID provided
        // by the pop3Server.
        dataOut.close();
        //Show progress on the command-line
        // screen
        System.out.print(msgNumber + " ");
        //Increment the message number in
        // preparation for processing the next
        // message.
        msgNumber++;
      }//end while(msgNumber <= numberMsgs)
      System.out.println(
                        "nMessages downloaded");
                 
      //Terminate the session with the
      // pop3Server.
      System.out.println(
                "nDisconnect from pop3Server.");
      outputStream.println("QUIT"); 
      String quitResponse = validateOneLine();
      //Display the response on the
      // command-line screen.
      System.out.println("QUIT " + quitResponse);
      System.out.println();//blank line
      
      socket.close();
      
      //Sound an alarm.
      try{
        Thread.currentThread().sleep(500);
        Toolkit.getDefaultToolkit().beep();
        Thread.currentThread().sleep(500);
        Toolkit.getDefaultToolkit().beep();
        Thread.currentThread().sleep(500);
      }catch(Exception ex){
        ex.printStackTrace();
        System.exit(0);
      }//end catch
                   
      //All messages have been downloaded and
      // saved as local files.  Instantiate an
      // object that will forward each of the
      // messages to the specified email
      // address.
      new BigDog06forward(
          params[0],//pop3Server
          params[1],//userName
          params[2],//password
          params[3],//destinationAddress
          params[4],//smtpServer
          params[5],//workingDir
          params[6],//archiveDir
          params[7]);//fwdTag
    }//end try
    catch(Exception ex){
      ex.printStackTrace();
      System.exit(0);
    }//end catch
  }//end fetchMsgs
  //===========================================//
}//end class BigDog06fetch
//=============================================//

Listing 9

 

/*File BigDog06forward.java
Copyright 2005, R.G.Baldwin
Rev 08/17/05
DISCLAIMER:  THIS PROGRAM IS PROVIDED TO YOU AT 
NO COST.  BY USING THIS PROGRAM TO PROCESS YOUR 
EMAIL, YOU AGREE THAT YOU ARE USING IT AT YOUR 
OWN RISK.  THE AUTHOR OF THE PROGRAM, RICHARD G.
BALDWIN, ACCEPTS NO LIABILITY FOR ANY LOSS THAT 
YOU MAY INCUR THROUGH THE USE OF THIS PROGRAM.
An object of this class is instantiated by an
object of the class named BigDog06fetch to 
process a set of message files written by the
BigDog06fetch object.
This object tags messages with a tag defined by 
the user as a command-line parameter to the 
main method for the class named BigDog06fetch.  
Then the object forwards the messages to a 
destination email account that is specified as a 
command-line parameter using an SMTP server that 
is specified as a command-line parameter.
See additional comments at the beginning of 
BigDog06fetch.java.
This program uses the DELE command to delete
messages from the POP3 server from which the 
messages were originally downloaded.  Deletion of
the messages from the server can be disabled for 
test purposes by disabling a block of code before
compiling the program.
Certain portions of this program may have been
disabled for test purposes.  Search for the word
disable to identify those portions.
Tested using JDK 1.5.0_01 under WinXP
************************************************/
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
//import java.awt.event.*;
import sun.net.smtp.SmtpClient;
class BigDog06forward{
  //User-specific information is stored here.
  // This information is provided in the form of
  // constructor parameters.
  //ID of the destination email account.
  final String destinationAddress;
  //An smtp server through which the user is
  // authorized to send email messages.
  final String smtpServer;
  //Local folder where message files are stored
  // awaiting processing.
  final String workingDir;
  //Local folder for archiving message files.
  final String archiveDir;
  //Tag that is prepended to the Subject line of
  // the message before forwarding.
  String fwdTag;
  //Following are working variables used by the
  // program for various purposes.
  BufferedReader inputStream;
  PrintWriter outputStream;
  Socket socket;
  String pathFileName;
  Vector <String> msgToDelete = 
                            new Vector<String>();
  String uidl;
  boolean okToDelete = false;
  int msgNumber = 0;
  String pop3Server;
  String userName;
  String password;
  //===========================================//
  //Constructor
  BigDog06forward(final String pop3Server,
            final String userName,
            final String password,
            final String destinationAddress,
            final String smtpServer,
            final String workingDir,
            final String archiveDir,
            final String fwdTag){
    this.pop3Server = pop3Server;
    this.userName = userName;
    this.password = password;
    this.destinationAddress = destinationAddress;
    this.smtpServer = smtpServer;
    this.workingDir = workingDir;
    this.archiveDir = archiveDir;
    this.fwdTag = fwdTag;
    
    System.out.println("Forwarding messages:");
    
    forwardMsgs();
    deleteMsgs();
  }//end constructor
  //===========================================//
  //Validate a one-line response.
  //The purpose of this method is to confirm that
  // the pop3Server returned +OK and not -ERR to
  // the previous command.
  //If +OK, the method returns the string
  // returned by the pop3Server.
  //If -ERR, the method displays the string
  // returned by the pop3Server and terminates
  // the session.
  private String validateOneLine(){
    try{
      String response = inputStream.readLine();
      if(response.startsWith("+OK")){
        return response;
      }else{
        System.out.println(response);
        //Terminate the session.
        outputStream.println("QUIT");
        socket.close();
        System.out.println(
                       "Premature QUIT on -ERR");
        System.exit(0);
      }//end else
    }catch(IOException e){
      e.printStackTrace();
      System.exit(0);
    }//end catch
                
    //The following return statement is requied
    // to satisfy the compiler, but it can never
    // be reached..
    return "Make compiler happy";
  }//end validateOneLine()
  //===========================================//
  
  //Method to move a file from its current
  // location specified by pathFileName to a new
  // location specified by archiveDir.
  public void moveFile(String pathFileName,
                       String archiveDir){
    String fileName = pathFileName.substring(
              pathFileName.lastIndexOf('/') + 1);
    String archiveDirFileName =
                           archiveDir + fileName;
    boolean moved =
                 new File(pathFileName).renameTo(
                   new File(archiveDirFileName));
    if(!moved)System.out.println(
      "Unable to move " + new File(pathFileName)
      + "nto " + new File(archiveDirFileName));
  }//end moveFile method
  //===========================================//
  
  //This method reads and saves lines of data
  // from a file starting with the line that
  // startsWith firstLine and ending with the
  // line that startsWith lastLine.
  //If firstLine is null, data is saved beginning
  // with the first line in the file.
  //If lastLine is null, data is saved to the end
  // of the file.
  //The lines of data from the file are saved by
  // concatenating them into a single string with
  // a newline inserted into the string at the
  // end of each line.
  //The name and path to the file is given by
  // pathFileName.
  public String readLines(String pathFileName,
                          String firstLine,
                          String lastLine){
    StringBuffer strBuf = new StringBuffer();
    try{
      BufferedReader inDataMsg
        = new BufferedReader(new FileReader(
                                  pathFileName));
      String data;
      boolean isSave = false;
      while((data = inDataMsg.readLine())
                                        != null){
        if( ((firstLine == null) ||
             (data.startsWith(firstLine))) &&
             (isSave == false)){
          isSave = true;
        }//end if
        if(isSave){
          strBuf.append(data + "n");
        }//end if
        if((lastLine != null) &&
           (data.startsWith(lastLine))){
          break;//no need to read any more
        }//end if
      }//end while loop
      inDataMsg.close();//Close file
    }catch(Exception e){
      e.printStackTrace();
      System.exit(0);
    }//end catch
    return new String(strBuf);
  }//end readLines
  //===========================================//
  
  //This method is used to construct an email
  // message and send it to the 
  // destinationAddress.
  public boolean forwardEmailMsg(
                       String destinationAddress,
                       String smtpServer,
                       String fwdTag,
                       String pathFileName){
      StringBuffer message = new StringBuffer(
                             "No message found");
      try{
        //Pass a string containing the name of
        // the smtp server as a parameter to the
        // following constructor.
        SmtpClient smtp =
                      new SmtpClient(smtpServer);
        //Pass any valid email address to the
        // from() method.
        smtp.from(destinationAddress);
        //Pass the email address of the
        // destinationAddress to the to() method.
        smtp.to(destinationAddress);
        //Construct the message as a single
        // StringBuffer object by concatenating
        // all of the lines in the message file.
        message = new StringBuffer(readLines(
                        pathFileName,null,null));
        //Insert fwdTag in subject
        message = message.insert(message.indexOf(
                          "Subject: ")+9,fwdTag);
        //Get an output stream for the message
        PrintStream msg = smtp.startMessage();
        //Write the message into the output
        // stream.
        msg.println(new String(message));
        //Close the stream and send the message
        smtp.closeServer();
        return true;
      }catch( Exception e ){
        e.printStackTrace();
        System.out.println(
                       "while forwarding email");
        //Sound an alarm.
        try{
          Thread.currentThread().sleep(500);
          Toolkit.getDefaultToolkit().beep();
          Thread.currentThread().sleep(500);
          Toolkit.getDefaultToolkit().beep();
          Thread.currentThread().sleep(500);
        }catch(Exception ex){
          System.out.println(ex);
        }//end catch
        
        //Return false to indicate that the msg
        // was not successfully forwarded.
        return false;
      }//end catch
  }//end forwardEmailMsg
  //===========================================//
  
  void forwardMsgs(){
    //Get a directory listing
    //The following code creates a directory
    // listing containing only those files that
    // begin with +OK.
    //This is an anonymous implementation of a
    // class that implements FilenameFilter.
    String[] dirList = 
                       new File(workingDir).list(
      new FilenameFilter(){public boolean accept(
                           File dir,String name){
          if(!(new File(dir,name).
            isFile())) return false;
          return name.startsWith("+OK");
        }//end accept
      }//end FilenameFilter
    );//end list
    //Now process the files in the directory
    for(int msgCounter = 0;
                     msgCounter < dirList.length;
                                   msgCounter++){
      String fileName = dirList[msgCounter];
      pathFileName = workingDir + fileName;
      //Get the original message number used by
      // the pop3Server to ID the msg.
      String strMsgNumber =
           fileName.substring(
             fileName.indexOf(" "),
               fileName.lastIndexOf(" ")).trim();
      msgNumber = Integer.parseInt(strMsgNumber);
      System.out.print("" + msgNumber + " ");
      //This code forwards the message to the
      // destination email account and adds the
      // identification of the message to the
      // list of messages scheduled for deletion
      // from the pop3Server later.  The third
      // parameter can be used to tag the message
      // to show that it was forwarded.  This
      // parameter is provided as a command-line
      // parameter to the BigDog06fetch program.
      //  Just pass an empty string, "", if you
      // don't want to tag it.
      //Don't add the message to the deletion
      // list if forwarding failed.
      okToDelete = forwardEmailMsg(
                              destinationAddress,
                              smtpServer,
                              fwdTag,
                              pathFileName);
      if(okToDelete){
        msgToDelete.add(pathFileName);
      }//end if
    }//end for loop on directory length
    //Sound an audio alert
    try{
      Thread.currentThread().sleep(500);
      Toolkit.getDefaultToolkit().beep();
      Thread.currentThread().sleep(500);
      Toolkit.getDefaultToolkit().beep();
      Thread.currentThread().sleep(500);
      Toolkit.getDefaultToolkit().beep();
       Thread.currentThread().sleep(500);
    }catch(Exception ex){
      ex.printStackTrace();
      System.exit(0);
    }//end catch
  }//end forwardMsgs
  //===========================================//
  
  void deleteMsgs(){
    System.out.println(
        "nDelete Msgs from POP3 server.");
    //Get connected to the email pop3Server
    int port = 110; //pop3 mail port
    try{
      //Get a socket, connected to the specified
      // pop3Server on the specified port.
      socket = new Socket(pop3Server,port);
      //Get an input stream from the socket
      inputStream = new BufferedReader(
                     new InputStreamReader(
                       socket.getInputStream()));
      //Get  an output stream to the socket
      outputStream = new PrintWriter(
               new OutputStreamWriter(
                 socket.getOutputStream()),true);
      //Display the msg received from the
      // pop3Server on the command-line screen
      // immediately following connection.
      String connectMsg = validateOneLine();
      System.out.println(
                     "nConnected to pop3Server "
                                   + connectMsg);
      //The communication process is now in the
      // AUTHORIZATION state.  Send the user name
      // and password to the pop3Server.
      outputStream.println("USER " + userName);
      //Get response and confirm that the
      // response was +OK and was not -ERR.
      String userResponse = validateOneLine();
      //Display the response on the command-line
      // screen.
      System.out.println("USER " + userResponse);
      //Send the password to the pop3Server
      outputStream.println("PASS " + password);
      //Validate the pop3Server's response as
      // +OK. Display the response in the
      // process.
      System.out.println("PASS "
                            + validateOneLine());
    }catch(Exception ex){
      ex.printStackTrace();
      System.exit(0);
    }//end catch
    //Process the files in the msgToDelete
    // collection and delete those messages from
    // the email pop3Server.
    System.out.println(
            "nDeleting Msgs from POP3 server.");
    for(int cnt = 0;
                 cnt < msgToDelete.size();cnt++){
      pathFileName = msgToDelete.
                                  elementAt(cnt);
      String strMsgNumber = pathFileName.
         substring(pathFileName.indexOf(" "),
           pathFileName.lastIndexOf(" ")).trim();
      int msgNumber = Integer.parseInt(
                                   strMsgNumber);
      //Deletion of a message from the pop3Server
      // is accomplished by marking the message
      // for deletion while in the TRANSACTION
      // state.  The message is actually deleted
      // when the client sends a QUIT command to
      // the pop3Server causing the pop3Server to
      // enter the UPDATE state.  If the program
      // aborts prematurely before sending a QUIT
      // command, marked messages are not deleted
      // from the pop3Server.
      //Mark the message for deletion.
/*
      //Disable the following statement if you
      // enable message deletion.
      System.out.println(
                    "Message deletion disabled");
*/
      //Disable this code to disable deletion of
      // messages from the pop3Server
      outputStream.println("DELE " + msgNumber);
      //Validate the response and display
      // progress.  Will terminate on DELE ERR.
      validateOneLine();
      System.out.print(msgNumber + " ");
      //Disable to here to disable deletion of
      // messages from the pop3Server
      //You can customize the program to either
      // move the message files from the working
      // directory into an archive directory, or
      // to simply delete the message files from
      // the working directory without saving
      // them in an archive directory.
      
      //To move message files to the archive
      // directory, enable this block of code and
      // disable the next block of code.
      {//Start move block
        moveFile(pathFileName,archiveDir);
      }//End move block
/*
      //To delete message files without saving
      // them in an archive directory, enable
      // this block of code and disable the
      // previous block of code.
      {//Start delete block
        File file = new File(pathFileName);
        boolean isDeleted = file.delete();
        if(!isDeleted)System.out.println(
                     "Unable to delete " + file);
      }//End delete block
*/
    }//end for loop on msgToDelete.size()
    
    System.out.println();//blank line
    //Terminate the session with the pop3Server
    // causing the marked messages to actually be
    // deleted from the pop3Server.
    System.out.println(
                  "Disconnect from POP3 server");
    outputStream.println("QUIT");
    String quitResponse = validateOneLine();
    //Display the response on the command-line
    // screen.
    System.out.println("QUIT " + quitResponse);
    //Server is now in the UPDATE mode. It will
    // delete all files marked with the DELE
    // command earlier in the execution of the
    // program.
    //Close the socket
    try{
      socket.close();
    }catch(Exception ex){
      ex.printStackTrace();
      System.exit(0);
    }//end catch
    System.out.println("Messages deleted "
         + "from pop3Server.");
  }//end deleteMsgs
  //===========================================//
}//end class BigDog06forward
//=============================================//


Listing 10

 


Copyright 2005, Richard G. Baldwin.  Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is a combination of Java, C#, and XML. In addition to the many platform and/or language independent benefits of Java and C# applications, he believes that a combination of Java, C#, and XML will become the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin's Programming Tutorials, which have gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.

In addition to his programming expertise, Richard has many years of practical experience in Digital Signal Processing (DSP).  His first job after he earned his Bachelor's degree was doing DSP in the Seismic Research Department of Texas Instruments.  (TI is still a world leader in DSP.)  In the following years, he applied his programming and DSP expertise to other interesting areas including sonar and underwater acoustics.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

Baldwin@DickBaldwin.com





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel