Click here to Skip to main content
Click here to Skip to main content

DataSet - A Polymorph Collection

By , 20 Mar 2013
 

Introduction 

The DataSet is a simple class that holds items of any type. I initially used it for providing data to the client layer, encapsulating the server side functionality by only exposing data. This then got expanded with the ConfigData, a wrapped DataSet that provides configuration data and enforces reading all the items. 

This article describes the package of classes I use to support the DataSet. On its own, this isn't much, but I realised that a lot of other subjects I wanted to post articles on required this as it is my de-facto structure for throwing data around. 

Background 

It is often the case that a class has no function, just value. Well over time, I grew tired of writing myriad data classes with nothing but accessor methods. So based on a design I had used in various jobs, I went about building my own. 

Base Classes

The structure is simple as can be. A DataSet contains a set of DataItem objects. Each item takes a name/value pair and once created is immutable. As a result of getting stung around trying to use generics, I shifted the design so that the item holds an Object and the class itself ensures safe casting, rather than having to deal with it at a higher level.

In the DataSet, items can be retrieved as an object or the value accessed directly; this saves on a lot of null checks and method chaining.

The 'native' types that can be safely called from the DataSet and DataItem are all listed in enum ValueType. All other types are treated as an Object and the consumer is responsible for managing them safely. 

There are then two wrapper classes. The ConfigData is used for loading configuration from a file for an application and SealedDataSet provides read only access to a DataSet

Transport Layer 

The two major uses I have for the DataSet are communication and persistence. For this I provide two classes that read and write the data. 

DataReader is used to take an inbound String from a BufferedReader and turn it into a DataSet. The reverse is performed by DataWriter,  turning a DataSet into a String and writing it a  BufferedWritter. The format of these strings is nice and simple:

An example of the format, taken from the JavaDoc, is:

# comments can be added at any point and each
# item is written thus:
# name t value
example {
# Boolean -
   isMale ? TRUE
# DataSet -
   subBlock {
      item - simple text.
   } 
# Date -
   dateWriten @ 2013-02-27 12:00:25.3789Z
# Double -
   weight $ 75.3
# Integer -
   age % 42
# String [without reserved characters] -
   name - William Norman-Walker
# String [with reserved chracters] -
   longText \
\# this will all be read as\
it \@ contains all the special chracters \\ escaped\
\{ so the parser can read them \}.\
all for \$15.00 \@ \-50\% discount
} 

It is a bit like a few other formats I know; but that's how it evolved. For simple config files, the type character can be omitted and is treated as a string. The extended format is actually overkill, and simply using a backslash on the line terminator is enough for it to be parsed cleanly. 

Using the code

So how do I use it? The first way is for loading configuration options. I store the config for an app in a data file and then load it in at start up: }/**

 * Standard Entry point.
 * @param args
 */
public static void main (String[] args) {
    DataReader reader = null;
    try {
        reader = new DataReader(new File("demmo.config"));
        ConfigData config = new ConfigData(reader.read());
        App app = new Appendable(config);
        config.close();
    } catch (DataException ex) {
        System.err.print(ex);
    } catch (java.io.IOException ex) {
        System.err.print(ex);
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ex) {
                System.err.print(ex);
            }
        }
    }
} 

I am not a great fan of throwing exceptions, but here I think it does make sense. For consideration would be a constructor for ConfigData that takes a file and deals with all the underlying problems.

Points of Interest

I use these classes in a lot in the stuff I write. The purpose of this article is that I will not have to re-visit this in future. For those interested, the next article should be on an expression evaluator that uses a DataSet to find variable names. 

History 

  • 2013-03 - Initial submission to CodeProject.
  • 2013-03-13 - Updated code, bug fix in toString() of DataItem

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Nagy Vilmos
President Belligerent Bad Tempered Old Fools Club
United Kingdom United Kingdom
Member
Do not tell anyone I am not Hungarian. It's a huge secret.
I have worked across too many platforms over the years - COBOL, Pascal, C, C++, VB3-6, C# and java are some of them - and now I just write pretty front ends for users with less wit than a gumby.
 
If I had a pound for everything I've learned over the years, I'd have £12,879.73
 
Semper ebrius, quantum variat.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionUsage Examples?memberGreg Niswonger12 Mar '13 - 11:34 
AnswerRe: Usage Examples?memberNagy Vilmos12 Mar '13 - 21:18 
GeneralRe: Usage Examples?memberGreg Niswonger13 Mar '13 - 9:36 
GeneralMy vote of 5memberlinuxjr7 Mar '13 - 4:52 
GeneralMy vote of 5memberThe Bhai7 Mar '13 - 4:47 
GeneralRe: My vote of 5memberNagy Vilmos7 Mar '13 - 4:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 20 Mar 2013
Article Copyright 2013 by Nagy Vilmos
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid