|
|
Advanced Tutorial - Saving And Restoring The Model - Outputting the model
SUMMARY
This step makes the application pretty much standalone. With it a user will be able to save applications in a consistent format and open them again at any time
FURTHER READING The 'Carousel' tutorial looks at allowing this data to be saved remotely into a file or a database. Now we want to expand on the previous step and write the code to save and restore the model data. Start by editing the Finish class. Listing 1 - Finish.java
...
public void save()
{
String filename = null;
boolean create = createMdl.get().toString().indexOf( "Create" ) > -1;
if ( create && ( checkValidations() != XBaseValidator.LEVEL_IGNORE ) )
return;
if ( create )
filename = filenameText.getText();
else
filename = ( String ) filenameMdl.get();
String contents = getModelText();
saveFile( filename, contents );
if( create ) {
XBaseModel appsMdl = ( XBaseModel )rootModel.get( "applications" );
XBaseModel newMdl = new XBaseModel( appsMdl, filename, filename );
}
pageMgr.showPage( "welcome", "content" );
Navigator.getInstance().reset();
}
private String getModelText()
{
XBaseModel mdl = ( XBaseModel )rootModel.get( "mortapp" );
StringWriter sw = new StringWriter();
XDataSource.outputModel( sw, mdl );
return "<Datasets>" + sw.toString() + "</Datasets>";
}
public void saveFile( String name, String contents )
{
String filename = System.getProperty( "user.dir" ) + File.separator + "files"
+ File.separator + name;
try {
FileOutputStream fos = new FileOutputStream( filename );
OutputStreamWriter osw = new OutputStreamWriter( fos, "UTF8" );
BufferedWriter bw = new BufferedWriter( osw );
bw.write( contents );
bw.flush();
bw.close();
}
catch ( IOException ex ) {
ex.printStackTrace();
}
}
...
The getModelText function retrieves the mortapp model node which is being used by the personal and finance pages and outputs it's contents to a StringWriter. The contents of the StringWriter are then wrapped in a Datasets node in order to be read again. The saveFile method outputs the contents of the model to the file specified in the text component using UTF-8 encoding. At the end of the save function, the create flag is checked once more and if it is true, the applications model node has the new file name appended to it so that the list on the Welcome page will display it. Run the application selecting the create radio from the welcome page and save the model data. The data will appear something like the following... Listing 2 - The model output
<Datasets>
<data id="mortapp">
<data value="Sole" id="numapplicants"/>
<data id="customer1">
<data value="Joe" id="firstname"/>
<data value="Bloggs" id="surname"/>
<data value="10/10/1970" id="dob"/>
<data value="Mr" id="title"/>
</data>
<data id="finance">
<data value="250000" id="propvalue"/>
<data value="200000" id="mortamt"/>
</data>
</data>
</Datasets>
Now, in order to restore the model state we need to edit the Welcome class. Listing 3 - Welcome.java
...
public void openFile()
{
String filename = ( String )fileList.getSelectedObject();
String contents = getFileContents( filename );
restoreState( contents );
filenameMdl.set( filename );
updateBindings();
}
private String getFileContents( String fname )
{
String filename = System.getProperty( "user.dir" ) + File.separator
+ "files" + File.separator + fname;
StringBuffer contents = new StringBuffer();
try {
FileInputStream fos = new FileInputStream( filename );
InputStreamReader osw = new InputStreamReader( fos, "UTF8" );
BufferedReader bw = new BufferedReader( osw );
String temp = bw.readLine();
while ( temp != null ) {
if ( temp != null )
contents.append( temp );
temp = bw.readLine();
}
bw.close();
}
catch ( IOException ex ) {
ex.printStackTrace();
}
return contents.toString();
}
private void restoreState( String contents )
{
( ( XBaseModel )rootModel.get( "mortapp" ) ).clear();
StringReader sr = new StringReader( contents );
XmlElement ele = XmlSource.read( sr );
if ( ele != null ) {
XOptionalDataSource ds = new XOptionalDataSource( project );
ds.loadTable( ele, rootModel );
}
}
...
The getFileContents function reads the specified file and returns it's contents. The restoreState function initialises the mortapp and the xui_state model nodes. It then populates and XmlElement with the XML contents and uses the XOptionalDataSource class to load the contents into the XModel. In order to trigger the call to open file we will make use of the pageDeactivated function as shown in listing 4. Listing 4 - Welcome.java
...
public void pageDeactivated()
{
String create = ( String )createMdl.get();
if ( createRadio.getText().compareTo( create ) == 0 ) {
( ( XBaseModel ) rootModel.get( "mortapp" ) ).clear();
updateBindings();
saveBoundComponentValues();
} else {
openFile();
}
}
...
If an application is being created, initialise the xui_state and mortapp model nodes. The call to updateBindings restores the bindings on the welcome page and the call to saveBoundComponentValues saves the welcome page state. One last change needs to be made in order to be able to run the application. The personal page is holding a reference to the mortapp/numapplicants model node. This now needs to be retrieved in the pageActivated function because of the initialisation which is taking place on the welcome page. Listing 5 - Personal.java
...
public void pageActivated() {
joint = (XModel)rootModel.get( "mortapp/numapplicants" );
...
Run the application select the Open radio and the file which was saved previously and the application will populate with the contents. |