aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes MetaData framework Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "MetaData framework" Watch "MetaData framework" New topic
Author

MetaData framework

Vlad Rabkin
Ranch Hand

Joined: Jul 07, 2003
Posts: 555
Hi,

In order to design flexibable framework to avoid problems on the GUI client in case
database column structure changes I have decided to use RecordModel instead of String[]
representing a record.
We have already discussed this topic with Andrew and separately with Phil.
here is my design. Still, there are some open issues, which are not clear to me.
I don't have any experience in designing such things (I have alway used clear
"java bean like " interface instead of MetaData/ColumnModel/RecordModel).
It is not easy to represent the problem of this topic, but I will do my best...
I would approciate any help!

I use following concept: Names of database column, their display labels
and description (tooltips) are hard coded on the GUI client
(The can be any time move to properties file). Whatever happens on the server:
columns chage their places, new column will be added, columns change their names)
there is only one entry point to be changed on the client: database column names.
It also allows dynamic access to the length of fields to validate requests on client
(e.g. customer id).
I know, I could use index instead, but I decided not to use it, since it is terrible
on the client GUI to understand which column is used (E.g.it is much easer to work with
column "location" than #2.). I know, there some advantages of using indexes, but
I decided to avoid them.

Here are interface defined to represent a Record:


Here is adapter interface (database interface used by GUI client):


Here are some client classes relating to the problem:


There are two samples in RoomTableModel (ClientColumn.getName())
and in ClientWindow(ClientColumn.getLabel(), ClientColumn.getDescription())
showing how I use ClientColumn and RecordModel interface. As you can see I connect
ClientColumn information, responsible for displaying column) and RecordModel(responsible for
database structure). It works Ok now, but I am not sure it is a good design.
Probably it would be better to make ClientColumn extend ColumnModel, but to use it I need
than two new interfaces ClientMetaData and ClientRecordModel...
Could you please tell me if my design is Ok now. If not, what could I do better?
Thanx,
Vlad
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Vlad,
As you asked me to answer to this post, I'll do. I didn't reply because as it seems that we have so different views on this subject, I felt like a bit risky to enter into this discussion. (To be 100% honest, I am also in a hurry now to finish the GUI parts of the assignment).
Whatever happens on the server:
columns chage their places, new column will be added, columns change their names)
there is only one entry point to be changed on the client: database column names.
It also allows dynamic access to the length of fields to validate requests on client

Till there, I agree.
I know, I could use index instead, but I decided not to use it, since it is terrible
on the client GUI to understand which column is used (E.g.it is much easer to work with
column "location" than #2.). I know, there some advantages of using indexes, but
I decided to avoid them.

Still perfect IMO, anyway I do the same as you.
Here are interface defined to represent a Record:

From here, our ways take different directions. You seem to have invested in a different way of abstracting records data, while I kept data representation unchanged (record = array of String field values) and chose to invest a bit more in added meta-data functionalities.
I see the application as a classical three-tier system : database-business-presention.
  • The database tier is defined for us by the provided DBAccess interface which must be implemented in a Data class.
  • The business tier is like a "fa´┐Żade" which implements the application functionalities in a way which hides data access to the client (presentation). In our assignment, its two main methods are book() and search().
  • The presentation tier, which is the client GUI.


  • With your RecordModel / DBAdatapter I feel like you insert a fourth tier between the first (database) and the second (business). Maybe I missed something, but it brings additional complexity without much benefit IMO.
    Just for comparison, I personally regret that you abandoned your idea of concurrent-reads-single-write-locks for simplicity. The job was done, well done, it was just a little more complex than "classical" synch, and added a big plus in terms of performance and global db concurrency (you know that I kept it). If you want to keep things simple, I think you could forget that fourth tier. JMO.
    I hope other people will give you their own opinion on that design.
    Best,
    Phil.
    Andrew Monkhouse
    author and jackaroo
    Marshal Commander

    Joined: Mar 28, 2003
    Posts: 11481
        
      94

    Hi Vlad,
    Why do you have the MetaData as part of your Record?
    There are valid reasons for doing this - but just want to see if you have thought of them or not
    [And now that I've seen Phil's post, I can also add that the answer to my question could also act as an argument against Phil's idea of leaving everything in String[]s ]
    I think your design is OK at the moment, but I will think about it some more.
    Why do you have ClientProps.CUSTOMER and ClientWindow.CUSTOMER_LABEL? Should the constants be in the same class (probably ClientProps)? Or have I misunderstood the use of ClientProps?
    Regards, Andrew
    [ September 19, 2003: Message edited by: Andrew Monkhouse ]

    The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
    Vlad Rabkin
    Ranch Hand

    Joined: Jul 07, 2003
    Posts: 555
    Hi Phil,
    Tx for your response.
    I didn't reply because as it seems that we have so different views on this subject... To be 100% honest, I am also in a hurry now to finish the GUI parts of the assignment

    Phil, I want this discussion to be a bit different from others. It is like I offered my design and want to defend your critic. I personally don't like my design and instead of arguing I am much more intersted that somebody presents other deisgn, which is simpler, but provides the client flexibility". I am ready to wait. I don't want to put in the rush with answer. I would be glad to get your personal ideas how it shoulb be done when you have time.
    You seem to have invested in a different way of abstracting records data, while I kept data representation unchanged (record = array of String field values) and chose to invest a bit more in added meta-data functionalities.

    Let me be honest, I didn't want to do it at all. I wanted to use String[] as it was presented in DB interface by Sun. You are the first who did me in all this nightmare
    With your RecordModel / DBAdatapter I feel like you insert a fourth tier between the first (database) and the second (business). Maybe I missed something, but it brings additional complexity without much benefit IMO.

    You are right, but I don't know how to redesign it.
    The point is I decided not to book/search methods in adapter.
    I am afraid to breach Sun requirements. They say that all database functionality (if not /lock/unlock at least delete/update/read/find/create) must be available over the network. In your design (which I also have at the moment, but will change it) there are only two methods available over network, which is dangerous. I gave up and send request to Sun a month ago whether it is Ok with requirements. I didn't get any answer. So, I don't want to take a challange
    Now the most important question to you:
    I assume you have some kind of following method:
    String[] findByCriteria(...) or Record[] findByCriteria(...) in your Bussines Interface (AdapterInterface, Businees Tier).
    I beleive you have find returning Record[].
    And that is what my problem is to understand:
    How your Record object that your Businees tier passes to client looks like?
    You said you take care of data structure changes in Business Tier, but what does it mean for client. Does the client work than with fixed array of some kind of Objects?
    Just for comparison, I personally regret that you abandoned your idea of concurrent-reads-single-write-locks for simplicity. The job was done, well done, it was just a little more complex than "classical" synch

    Me too..
    Phil, anybody else, I am open to any other ideas. I don't want to re-found America, there probably some good rules to do it, which I don't know.
    Tx,
    Vlad
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Andrew,
    Why do you have the MetaData as part of your Record?
    There are valid reasons for doing this - but just want to see if you have thought of them or not
    [And now that I've seen Phil's post, I can also add that the answer to my question could also act as an argument against Phil's idea of leaving everything in String[]s ]

    I think that if you have a Data.getMetaData() method which returns a MetaData instance able - among other things - to return Field objects queried by name or by index, you don't need an additional layer to abstract record/field access even if keeping unchanged the record format.
    Vlad, I didn't talk about what I like : I like ClientColumn which actually adds functionality / information and should be quite handy.
    Best,
    Phil.
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Vlad,
    Phil, I want this discussion to be a bit different from others. It is like I offered my design and want to defend your critic. I personally don't like my design and instead of arguing I am much more intersted that somebody presents other deisgn, which is simpler, but provides the client flexibility". I am ready to wait. I don't want to put in the rush with answer. I would be glad to get your personal ideas how it shoulb be done when you have time.

    Good idea. I am finishing the server GUI now. Afterwards, I'll have client-GUI design issues to solve myself, and it will easier for me to discuss about them when I'll be busy myself with them.
    The point is I decided not to book/search methods in adapter.
    I am afraid to breach Sun requirements. They say that all database functionality (if not /lock/unlock at least delete/update/read/find/create) must be available over the network. In your design (which I also have at the moment, but will change it) there are only two methods available over network, which is dangerous.

    Which assignment have you ? It's different in URLyBird.
    But if it's the case for you, it's an argument against your additional tier, right ? Because the db interface is fixed in the assignment.
    How your Record object that your Business tier passes to client looks like?

    Actually, no kidding, I don't know yet ! I'll fix the interface between server (business) and client when I'll have the clients constraints in mind (very soon ). But I know that for the other side of the business tier (interface to the database), I won't use anything other than the provided DBAccess interface, a little bit extended in Data as far as findByCriteria is concerned (I added an overloaded method which accepts criteria ranges, because I needed it to support the time range constraint).
    Best,
    Phil.
    Vlad Rabkin
    Ranch Hand

    Joined: Jul 07, 2003
    Posts: 555
    Hi Andrew and Phil,
    I didn't want to make you immediatelly work on this topic, but thanx a lot that you replied so fast.
    Phil;
    you don't need an additional layer to abstract record/field access even if keeping unchanged the record format.

    Could you specifify which interface you by saying "abstract record/field access"`?
    Why do you have ClientProps.CUSTOMER and ClientWindow.CUSTOMER_LABEL? Should the constants be in the same class (probably ClientProps)? Or have I misunderstood the use of ClientProps?

    Good question. That is what I refactored yesterday, but didn't want send changes not to consfuse anyone.
    CUSTOMER - is String constant "customer".
    CUSTOMER_LABEL was the only int constant to find appropriate ClientColumn from ClientColumn[] array, needed for book component to set label and tooltip on "book" button and to know the column in JTable to get customer value to enable/disable book button.
    To avoid having this constant I added yesterday one more class:
    ClientColumnInfo wrapping an array of ClientColumn to be able to get a Client Column not by index, but by name:

    The wrapper will be used:


    Andrew, Phil there is no way I want tp push you with answer. I will be glad to get any feedback any time.
    Tx,
    Vlad
    Vlad Rabkin
    Ranch Hand

    Joined: Jul 07, 2003
    Posts: 555
    Hi Phil,
    Which assignment have you ? It's different in URLyBird.
    But if it's the case for you, it's an argument against your additional tier, right ? Because the db interface is fixed in the assignment.

    I do have URLyBird.
    Yes it is an argument against additional tier.
    But, I beleive that having local/remote adapter with interface RecordModel read(int recNo); is Ok. It provides still all database functionality.
    What can be gangerous is just having in adapter only three methods:
    find
    book (don't forget book is something different from update)
    getMetaData
    There is no way I want you to prevent from doing this, but I personally dediced to go conservative way. So, I have actialy two teir architecture: My DataAdapter just changes signature of original DB Interface methods and add getMetadata and find looks now instead of:
    int[] find(String[] criteria)
    RecordModel[] find(RecordModel criteria)
    Best,
    Vlad
    [ September 19, 2003: Message edited by: Vlad Rabkin ]
    Philippe Maquet
    Bartender

    Joined: Jun 02, 2003
    Posts: 1872
    Hi Vlad,
    If you've got URLyBird, how can you write :
    They say that all database functionality (if not /lock/unlock at least delete/update/read/find/create) must be available over the network. In your design (which I also have at the moment, but will change it) there are only two methods available over network, which is dangerous.
    ?
    Where do they say that in the instructions ?
    Best,
    Phil.
    Vlad Rabkin
    Ranch Hand

    Joined: Jul 07, 2003
    Posts: 555
    Hi Phil,
    I didn't want to scare you it is only my interpretion of Sun:
    The following are the "top level" features that must be implemented:
    A client program with a graphical user interface that connects to the database
    A data access system that provides record locking and a flexible search mechanism
    Network server functionality for the database system

    Interface with book/find/getMetaData is NOT to my opinion :
    Network server functionality for the database system

    Of course there is some space to argue:
    Line 2: data access system ...
    Line 3: ... database system
    There is a difference between "data access system" and "database system".
    Theoretically I could say I could make lock/unlock on server, but I don't see excuse not to provide update/create/delete/read in newtwork mode and that bothers me. Then I asked myself: Do I want to play with Sun? Nope....
    Best,
    Vlad
    [ September 19, 2003: Message edited by: Vlad Rabkin ]
    Vlad Rabkin
    Ranch Hand

    Joined: Jul 07, 2003
    Posts: 555
    Hi Phil,
    This is my mail to Sun sent on 18.08.2003 (I didn't an answer):


    Hello,
    I have decided to apply 3-tier architecture in my assignment (URLyBird 1.1.1).
    I have provided new local and remote interfaces to allow high level access to the database:
    public interface DBServer {
    public void book(RecordModel record)
    throws RecordNotFoundException,
    DBConcurrentModificationException,
    IOException;
    public RecordModel[] find(RecordModel criteria) throws IOException;
    public MetaData getMetaData() throws IOException;
    }
    public interface DBServerRemote extends DBServer, Remote {
    }
    The interface for database access defined by Sun, which will be available only for local use, because it will be used by implementation of DBServer interface, not the client application:
    package suncertify.db;
    public interface DB
    {
    public String[] read(int recNo) throws RecordNotFoundException;
    public void update(int recNo, String[] data, long lockCookie)
    throws RecordNotFoundException, SecurityException;
    public void delete(int recNo, long lockCookie)
    throws RecordNotFoundException, SecurityException;
    public int[] find(String[] criteria);
    public int create(String[] data) throws DuplicateKeyException;
    public long lock(int recNo) throws RecordNotFoundException;
    public void unlock(int recNo, long cookie)
    throws RecordNotFoundException, SecurityException;
    }
    The only access point to work in network mode will be then DBServerRemote interface, which provides only 3 methods required by the my client application.
    There is a following requirement in the assignment:
    The following are the "top level" features that must be implemented:
    A client program with a graphical user interface that connects to the database
    A data access system that provides record locking and a flexible search mechanism
    Network server functionality for the database system
    My question is:
    -if my design satisfies requirement,
    -Do I have to provide additionally a Remote interface, whose methods would have the same signatures and functionality as local DB interface, except throwing RemoteException,
    since I don't understand what interface do you mean by saying "Network server functionality for the database system ".
    Vlad Rabkin
    Ranch Hand

    Joined: Jul 07, 2003
    Posts: 555
    Hi,
    I realized that my design was over complicated. I present here the modified design and ask you review it again and answer my questions.



    1) RecordModel

    public int findColumn(String columnName)

    This method is used to find appropriate column in the record to be used for get/set methods.
    It is in the RecordModel. I could have a class MetaData wrapping ColumnModel[] and move this
    method there. I haven't done it because:

    - I tried to simulate JDBC interface, where findColumn(String name) is in ResultSet, not in ResultSetmetaData.
    - it allows a client to create his ColumnModel[] with a different order column and it would still work.
    - it allows me to not to have additional MetaData class.

    What is better: having int findColumn(String columnName) in RecordModel or in MetaData?

    2) MetaData class

    I don't have now MetaData class for simplicity. I use directly ClientModel[];
    It means that my server has to clone ClientModel[].clone() it getMetaData()
    to avoid protect it from client. Having MetaData as an addiotional class I could provide only
    get methods making the oobject immutable.

    What is better?

    3) Hashtable in find method of DBAdapter contains db field names as keys and values as values
    I could use HashMap instead of Hastable and clone it on the server to protect the object
    if teh client changes it after making request.

    What is better?

    4) Does it all look now more or less Ok?
    Tx a lot,
    Vlad
     
    It is sorta covered in the JavaRanch Style Guide.
     
    subject: MetaData framework