Lab 2

CPE 437

Due 7/2/09

 

Overview

In this lab you’ll play around with some fundamentals of HTTP, internationalization, Java sockets, annotations, reflection, and JDBC. 

 

1.   Use telnet to do a web hit

The Linux “telnet” utility conducts a simple textual terminal session with a remote machine.  It can be directed, via appropriate commandline arguments, to conduct such a session at any port on the remote machine (check “man”).  Since HTTP is a textual protocol, this means you can “fake” a website into accepting an HTTP request that you hand-type to it, via telnet.  Doing this is a good illustration of the HTTP format, and also can be a useful debugging tool in certain cases. 

 

a. Create, in a separate text file, a properly-formatted HTTP request to do a GET from Google’s home page.  The examples from p. 557 of Murach will be useful.  However, don’t send any cookies, and say you’ll accept only HTML text.

 

b. Set up a telnet session, directed at Google’s webserver, and send your HTTP request.  Revise the request if needed until you get a 200 (non-error) response.  Save the response HTML content in a separate file, named with an html suffix.

 

c. Confirm that you got a valid HTML response by bringing up your saved file in a browser, so you can see the Google home page.  No turnin needed for this one; just be sure you don’t hand in the lab until part c is done.

 

2. Play with language settings at Google.

 

a. Edit your faked-up HTTP request to ask for a response in Spanish.  Confirm that the returned HTML is in Spanish.

 

b. Adjust your *browser* to request Chinese from Google.  Hit Google via the browser (not telnet) and see Google’s home page in Chinese.  Print this as part of your lab handin.

  

3-5. Write a rudimentary ORM

Writing a simple ORM program will give you a better understanding of what Hibernate does, and will give you practice with XML, XSD, reflection, and JDBC.  This is the major part of the lab.  When you’re done, hand in:

 

1.  The source of your program; call it MyORM.java

2.  Your MyORM.xml and MyORM.xsd files

3.  A copy of this lab, with the indicated boxes (honestly) checked, and your signature at the bottom.

 

3. Write XML parsers for the ORM

a. Write code to parse, using DOM, an XML file of the following format, which describes a database connection and a set of annotated classes for which you’ll create corresponding database tables. 

 

<?xml version="1.0" encoding="UTF-8" ?>

 

<simpleORM xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xmlns="http://www.softwareinventions.com/cpe437/Lab2/MyORM"

 xsi:schemaLocation="http://www.softwareinventions.com/cpe437/Lab2/MyORM

 MyORM.xsd">

 

   <database user="cstaley" password="whatever" database="ORMExperiment" port="1000"/>

   <ORMClass>com.softwareinventions.cpe437.Lab2.Sample1 </ORMClass>

   <ORMClass> com.softwareinventions.cpe437.Lab2.Sample2 </ORMClass>

</simpleORM>

 

Note these rules:

 

i. There must be exactly one “database” tag, the first child of the root tag.

ii. All attributes of the database tag are required, except for “port”, which defaults to 3306 if omitted. 

iii. If “port” is supplied, it must fall between 1 and 65535, inclusive.

iii. There may be any number of ORMClass tags after the database tag.

iv. All tags are in a namespace, as shown (you may adjust the namespace URI to customize it if you wish).

v. There is an associated XSD file, MyORM.xsd.

 

Create from the XML file, an object of type ORMCfg, as below.  I made mine a nested class of MyORM.

 

      static private class ORMCfg {

            public String dbName;

            public String user;

            public String password;

            public int port;

            List<Class<Object> > ormCls;

      }

 

Write two methods of MyORM, to do this, with prototypes as shown. 

 

      private static ORMCfg readNoCfgDOMXML(File cfgFile) throws Exception

      private static ORMCfg readCfgDOMXML(File cfgFile) throws Exception

 

The first version does not rely upon the XSD (turn off validation); the second does.  The first version won’t need an xsd file, but you must enforce each of the format rules above by hand.  Obviously, to test the second you’ll also need to create the MyORM.xsd file, expressing in it all the format rules above, but then you can rely on the parser to do all error checking.  Be sure to test each version by providing xml files that break each of the rules above, and that omit the “port” attribute (be sure 3306 gets filled in automatically in the XSD version).

 

To do this, you’ll need to research XML namespaces, and XSD formats.  Readings for both of these have been added to the reading list.  (Of particular value will be the w3schools reference I emailed about earlier today.)

 

Be sure also that you give nice neat error messages out of the XSD-guided parse, not the garbage the DocumentBuilder supplies by default.  Investigate ErrorHandler in order to do this, and make your ErrorHandler an anonymous inner class (to reinforce that concept, which is part of the Java-basics list).  Error messages must be of the form:

 

      Error while parsing file: <config filename> at line <lineno>, col <colno>

 

For the non-XSD parse, you may make up your own error messages so long as they are clear.

 

Check that you get clear error messages, or correct action in the non-XSD parse for:

 

□ a missing database tag

□ a double database tag

□ a missing password attribute

□ a port attribute with value 65536

□ a port attribute with non-integer value

□ a missing port attribute (default of 3306)

 

Check that you get clear error messages, with the specified format in the XSD parse, and relying only on the parser’s error checking, for:

 

□ a missing database tag

□ a double database tag

□ a missing password attribute

□ a port attribute with value 65536

□ a port attribute with non-integer value

□ a missing port attribute (default of 3306)

 

Write here how you ensured that your tags were in a namespace, and the line of your XML file that ensured this:

 

_______________________________________________________________

 

_______________________________________________________________

 

4. Create annotations and do reflection

 

Create annotations called Entity and Field.  Entity has one required property: a tableName.   Field has two optional properties, a columnName and a boolean “nullable”, which default to empty string and false. 

 

Entity may be attached to a class for which you automatically want a database table generated, and Field may be attached to any get method(s) of an Entity-annotated class.   Attaching Entity to a class identifies it as a class that should have a corresponding database table, of the given tableName.  Attaching Field to a get method of an Entity-annotated class identifies the method’s return value as a property that should be stored in the table, under the given column name (which must be the same as the property name if no column name is specified), and with the specified nullability.  So, if some class “Sample” must be stored in the database, you can annotate it as described to indicate how it should be stored.

 

Attaching Field to any method other than a get-method is an error (you must check this in your code – the annotation system only allows you to specify that an annotation must be attached to some method).  A get-method must have no parameters, must have the name getPropertyName (where PropertyName is the name of the property) and must return a value.  For now, accept only int, double, or String values, and create INT, FLOAT, or VARCHAR(256) fields for them, respectively.  Generate suitable error messages for any Field-annotated method or any Entity-annotated class that breaks any of these rules, and ignore the method, using only those that follow the rules.

 

After reading your XML file, examine, via reflection, each of the ORMClass classes it specifies, to make sure that each such class has an Entity annotation, and to find all get-methods in them with Field annotations.   Check that your error handling works correctly for ORMClass entries in the XML file that have:

 

□ a missing Entity annotation

□ a Field annotation with no properties given (defaults apply)

□ a Field annotation on a method that meets “get” rules except it returns void

□ a Field annotation on a method that meets “get” rules except it has a parameter

□ a Field annotation on a method that meets “get” rules except for its name.

□ a Field annotation on a method that meets all “get” rules except it returns a type that is not one of the three allowed.

 

Check also, for ORMClass classes that have correct annotations, that:

 

□ the right field name, data type and nullability appear in the database when the Field annotation has a tableName and nullability specified

□ the right field name, data type and nullability appear in the database when the Field annotation has no tableName and nullability specified

□ the right database table name is created, based on the tableName property of Entity (and not on the name of the ORMClass itself)

□ all three allowed types work properly, producing corresponding columns in the database.

□ your Field and Entity annotations do not appear in the XML file at all, but are attached directly to classes which classes are specified in the XML file

 

 

5. Generate the database

 

Write JDBC to log into the database server, with the port, user name and password given in the XML.  Assume an empty database of the specified name (I don’t believe JDBC permits database creation, just table creation, but if anyone finds otherwise, please let me kmow.).  For this database, generate SQL statements to create a table for each valid Entity-class, with the columns indicated by the valid Field annotations.  Verify that

 

□ your tables were correctly created.

 

Affirm, by your signature below, that you carefully followed through on testing of each of the points checked above. 

 

_____________________________________________________              _______

Name                                                                                                  Date