File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Starting OCMJD Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Starting OCMJD" Watch "Starting OCMJD" New topic
Author

Starting OCMJD

pedro povoa
Greenhorn

Joined: Jun 17, 2008
Posts: 8
Hello,

Like many people, i just bought my OCMJD voucher... trying to accomplish it before august 1st.
So yesterday i downloaded my essay and many questions are in my head... My project is the URLyBird, with "public long lock(int recNo) throws RecordNotFoundException;" interface.
After reading SCJD FAQ, related topics and ocmjd-paper-roberto-perillo.pdf (awesome by the way), i decided to start from DB interface and db-1x1.db file provided by Oracle.

Conclusions and doubts:
I used DBFileReader.java class by Roberto Perillo as kick off and see whats inside my .db file to design my VO(Room.java in my case) class;
Reading the instructions and studying the .db, i realized that there is no "record number" and no "primary key". But there is no record where Name and Location combination equals true, and since no insertion of data is expected i made both my "primary key". To do so, i @override equals method on my VO class to make sure of that(name.equals(this.name) == true && location.equals(this.location) == true), ignoring the other atributes;
I didn't see the need on @override the hashCode method here, since ill CACHE STORE the records on a List and my LOCK CONTROL will be Map<Thread.ID,Room>, so i didn't;
MagicCookie and the long longCookie attributes are not the same thing. MagicCookie will be used only to compare to a static final variable on my Data class to make sure the .db file is valid;

DB Interface:
I will use RandomAccessFile to seek and read/update records. Thats the only way the argument "int recNo" of DB interface make sense to me;
I concluded the arguments "int recNo" is the position of the record on my List object, and when i need to update the .db file i seek to headerBytes+recNo*bytesRecordLength then write;
I also concluded the "long lockCookie" argument is the Thread.ID from my Map<Thread.ID,Room> to identify the thread holding the lock of that Room object;
I need a utilitary class to transform String[] records to VO and vice-versa;

Now some comments about instructions:
"Data section. 
Repeat to end of file: 
1 byte "deleted" flag. 0 implies valid record, 1 implies deleted record 
"

// Deletes a record, making the record number and associated disk
// storage available for reuse.
// Throws SecurityException if the record is locked with a cookie
// other than lockCookie.
public void delete(int recNo, long lockCookie)

I didn't understand this part, what delete means here? Because all records have this field empty on db-1x1.db(so, all records are valid).
And again, is my conclusions about recNo and lockCookie right?
Do i have to implement this method? Instructions only ask for search and update.

User Interface
• It must allow the user to book a selected record, updating the database file accordingly.
• It must allow the user to search the data for all records, or for records where the name and/or location fields exactly match values specified by the user.
A null value in criteria[n] matches any field value. A non-null value in criteria[n] matches any field value that begins with criteria[n]. (For example, "Fred" matches "Fred" or "Freddy".)

public void update(int recNo, String[] data, long lockCookie)

Here i assume that i must provide a checkbox to allow And/or searchs and filter using .startsWith(String);
Do i have to update the .db file everytime i execute the update() method?
The search of data can be done only on the List i loaded at startup or i must re-read file and re-load List before?


-------------------
About architecture:

Im thinking about making my Data class a SINGLETON with static List for records and static Map<Thread.ID,Room> for locks, to make sure the same object is shared among all clients;
A VO named Room to map records entrys and transit between layers;
Make a Service interface that will be implemented by StandAloneServiceImpl, RemoteServiceImpl and ClientServiceImpl, and make it the only access point the Data.class;
Read .db file to load List at startup without locking and only if my static list is null;
Use Lock only on the record i want to update or delete, leaving .db file available to other threads;
I don't need to control concurrent access to .db file;
I don't need to synchronize methods because of the lock()/unlock() mechanism on Room object;
The Room.java VO implements serializable;


Problems to solve:
How to use and set the startup parameters(server or standalone or client) to instantiate classes;
How to share the Service interface with all running modes, because of different parameters(.bd location, hostname, port);
If is it viable to use the same classes from Service interface to Data.class to db-1x1.db file, since Data class is singleton;
Do i really need to implement serializable on my VO class? Since i write String[] object to the file;

-----------------------


Well, thats what i get so far...
I have to study about the RMI implementation.
Im having trouble to figure out the middle of my application, where i have to combine the 3 different interface implementations(standalone, client and server).

Please tell me if i'm asking/saying anything that is inapropriate, so i can remove it.
Thank you!

Pedro.


SCJA - OCPJP 6.0
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5596
    
  15

Hi Pedro,

Your initial thoughts raise a whole lot of questions, even too much to answer because answering one question might raise 2-3 other questions and makes other questions you asked redundant. So I would advice to start with the main part of the assignment, the Data class implementing the given interface. And when that's finished, you can proceed with the next step.

These are all my remarks concerning your thoughts/questions:
  • if you make your Data class a singleton, why would you make your list and map static?
  • I would not use a VO in my Data class, but just keep the String[], because of a bunch of reasons: Data class will not be reusable at all, all method signatures have String[],...
  • when a record is deleted, you just need to set the deleted flag to true; at the beginning all records no flags are set, so all records are valid
  • you have to implement the given interface which contains methods which are not required actions in the gui (create, delete), so you could decide not to implement these and throw an UnsupportedOperationException and document this decision in your choices.txt, but it's risky and you might risk a failure (you can implement these methods and use some test cases to test the implementation)
  • using a primary key containing name and location is completely wrong and I even think your database file is violating this constraint (and with a bit of thought you'll find the reason why this makes no sense at all) (and by the way if you override equals, you should also override hashCode, because they have kind of a contract with each other)
  • you are not required to update the db-file with each call to update, just update your record cache (but don't forget to store all changes when the server or standalone application are closed)
  • you have to make your Data class thread-safe (so you have to deal with some synchronization), even with the lock/unlock methods (because that won't make your Data class capable of handling concurrent requests of different clients/threads)
  • your lock method will need to generate a lockCookie which is stored in your map with locked records and can be used to update/delete and unlock this record. So you can not store the thread id because RMI does not give any guarantee that calls from the same client are handled by the same thread


  • That's it!
    Best of luck!
    Kind regards,
    Roel


    SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
    http://www.javaroe.be/
    pedro povoa
    Greenhorn

    Joined: Jun 17, 2008
    Posts: 8
    Thank you Roel,

    My initial thoughts are confusing and might be redundant because there's alot of things i only know in theory, so i ended up mixing some concepts.
    Plus, javaSE implementation is a whole new world for me.
    ill study more about the implementation of Data and worry about the other things i mentioned when i get it done.


    Pedro.
    pedro povoa
    Greenhorn

    Joined: Jun 17, 2008
    Posts: 8
    I decided to make what you said, im only using String[] in my Data class. But i added 2 extra fields to it, so it has this format: String[] a = {recNo,...,flagDeleted};
    Where recNo is the order from .db file.
    This way i can store all my records in a List and use the map<Integer, Long> to track locked records.
    ----
    Ill make a question that maybe will make me look stupid, but... oh well... again, almost everything i have to use is new for me.
    My Data class is a singleton, accessed only by "StandAlone" and "Client" implementation of my Service interface.
    If i load my List of records at startup, i have to call "loadData();" at Data constructor. But, to loadData and writeData back to the .db file, i need to know the String dbPath!
    When and how should i load dbPath(coming from view or suncertify.properties)?
    And if i get it right, StandAlone and Client will share the same Data object but they need to specify distinct dbPath. Is that possible?
    I'm having trouble figuring it out... Maybe i shouldn't make it singleton and read .db file every request from view...

    Thank you,
    And Sorry for dumb questions
    Roel De Nijs
    Bartender

    Joined: Jul 19, 2004
    Posts: 5596
        
      15

    pedro povoa wrote:But i added 2 extra fields to it, so it has this format: String[] a = {recNo,...,flagDeleted};

    I would suggest not using this approach. The String[] should just contain the record fields and that's it. You could argue about recNo, but in my opinion it should not be in the String[]. The deleted flag is certainly not a part of the String[], because when the deletedFlag is set to true, the record is deleted and so there will be no String[] because there is no record...
    Some other thoughts:
  • when I use the create-method, do I need to add the recNo to the String[] or does the create-method expects a String[] without recNo-field?
  • same question for update method + what will you do if the recNo-parameter and the recNo in the String[] are different?


  • So you are looking for a way to pass the dbPath to your Data class to be able to initialize the record cache. Have you tried the search engine of this forum, because all questions you have are almost certainly already asked (even more than once). I could find this thread and this one, both having an alternative to solve your problem.

    Good luck!
    pedro povoa
    Greenhorn

    Joined: Jun 17, 2008
    Posts: 8
    Hello guys,

    i had a minor cirurgy last week... so i had to take a break from certification.
    But meanwhile, i followed Roel's advice and started to read "SCJD Exam with J2SE 5, Second Edition. By Andrew Monkhouse and Terry Camerlengo" and i must say:
    If you are , this book will clarify your mind and you will for sure get a better idea of what you have to do. And you get working samples!

    Kind regards,
    Pedro.


    Jonathan Russell
    Greenhorn

    Joined: Apr 21, 2011
    Posts: 7

    pedro povoa wrote:Hello guys,

    i had a minor cirurgy last week... so i had to take a break from certification.
    But meanwhile, i followed Roel's advice and started to read "SCJD Exam with J2SE 5, Second Edition. By Andrew Monkhouse and Terry Camerlengo" and i must say:
    If you are , this book will clarify your mind and you will for sure get a better idea of what you have to do. And you get working samples!

    Kind regards,
    Pedro.



    That's great to hear pedro, as I am working my way through that book just now before starting on my URLyBird assignment.

    I'm thinking once I've completed the assignment in the book it I will be able to modify it in eight weeks or so so it does all the functionality required by URLyBird. Does this seem like a good idea?
    pedro povoa
    Greenhorn

    Joined: Jun 17, 2008
    Posts: 8
    Jonathan Russell wrote:That's great to hear pedro, as I am working my way through that book just now before starting on my URLyBird assignment.

    I'm thinking once I've completed the assignment in the book it I will be able to modify it in eight weeks or so so it does all the functionality required by URLyBird. Does this seem like a good idea?


    If you just adapt your project to URLyBird, it will take alot of work indeed and might work just fine(start changing the DB interface and .db file, off course). It would be against the rules if they did a equals project even with different subject.
    But you risk to make a poor "choices.txt" file and leave some trash in your code if you do.

    The intention of this cert is that you code it all by yourself, but you can use the books project for consulting. Why not.

    Regards,
    Pedro.

    Roel De Nijs
    Bartender

    Joined: Jul 19, 2004
    Posts: 5596
        
      15

    Jonathan Russell wrote:Does this seem like a good idea?

    That could result in automatic failure when you don't adjust the code appropriately. More info can be found in this thread.
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Starting OCMJD