|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object ca.macewan.lmsreporter.api.AbstractAnalyzer
Convenience class that implements the Analyzer
interface. It offers a
default implementation for all interface methods except run
(as required by
Runnable
, which Analyzer
extends).
Additionally, this class provides some utility methods to work with WebCT™ global
database CSV files, to fire AnalysisEvent
events, and to access the source
and output files.
A typical implementation can simply extend this class and implement the run
method
to perform the analysis. In the run method, use the updateXXXX
methods to notify the
user of progress and errors. Also, check regularly for isRunning
, so the
run
method can pre-emptively return, allowing the analysis to be canceled gracefully.
Field Summary | |
protected AnalysisEvent |
ae
The event object used (and re-used) for sending events. |
Constructor Summary | |
AbstractAnalyzer()
Constructor, which should always run. |
Method Summary | |
void |
addAnalysisListener(AnalysisListener al)
Adds an AnalysisListener to the list of listeners. |
void |
analyze()
The method called by the application to start the analysis process. |
protected void |
finishAnalysis(String info)
Convenience method to notify the application that your analysis is done. |
protected void |
fireAnalysisUpdate()
Sends the AnalysisEvent ae to all registered
AnalysisListeners . |
String |
getCopyright()
Returns a short copyright information string for your Analyzer . |
String |
getDescription()
The application will read a description for this Analyzer object which will be used
in the analyzer selection list. |
protected File |
getGlobalDBFile()
Returns the WebCT™ comma-separated Global Database file to process. |
protected List |
getGlobalDBKeys()
Utility method to read the first significant line of the global database file and return the database field names as a List . |
protected File |
getOutputFile()
Returns the output file to save the analysis results in. |
Component |
getSettingsUI()
Called when the implementing class is selected by the user. |
protected File |
getSnapshotFile()
Returns the WebCT™ IMS Enterprise XML snapshot file to process. |
boolean |
isRunning()
Returns true if the analysis is currently running. |
boolean |
isWaitingForUI()
Returns true if the analysis is currently suspended,
waiting for some user interface action to complete. |
void |
postProcess()
Called immediately after the analyze method. |
void |
preProcess()
Called immediately before the analyze method. |
protected HashMap |
readGlobalDB()
Utility method to read the whole global database CSV file into a HashMap . |
protected HashMap |
readGlobalDBField(String fieldName)
Reads the global database file, and creates a HashMap where
the keys are each user's WebCT ID, and the values are the value of the requested field as strings. |
protected HashMap |
readGlobalDBField(String fieldName,
double phaseStart,
double phaseLength)
Creates a HashMap with the values of the requested field
(see readGlobalDBField(String) for more information). |
void |
removeAnalysisListener(AnalysisListener al)
Removes an AnalysisListener from the list of listeners. |
abstract void |
run()
Runs the actual analysis. |
void |
setDescription(String desc)
The application may set a description for this Analyzer object which will be used
in the analyzer selection list. |
protected void |
setRunning(boolean isRunning)
Causes isRunning to return the value passed in here. |
void |
setSources(File snapshotFile,
File globalDBFile,
File outFile)
Accepts and stores the two input files and the output file used by the analysis. |
void |
setWaitingForUI(boolean waitForUI)
Called by the application when the additional user interface action has completed. |
void |
stopAnalysis(String info)
Cause the analysis to stop prematurely. |
String |
toString()
Overrides Object.toString() to provide a human-readable description
to be displayed in the application's analysis selection list. |
protected void |
updateProgress(double progress)
Utility method to aid in the sending of progress AnalysisEvents . |
protected void |
updateProgress(double progress,
String info)
Utility method to aid in the sending of progress AnalysisEvents . |
protected void |
updateWithError(Throwable t)
Utility method to aid in the sending of error AnalysisEvents . |
protected void |
updateWithUIRequest(Component c,
String ttl)
If, for some reason, your analysis needs to interact with the user in the midst of the anlysis process, this method will help send the appropriate AnalysisEvent . |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
protected AnalysisEvent ae
fireAnalysisUpdate
.
Constructor Detail |
public AbstractAnalyzer()
Method Detail |
public void setSources(File snapshotFile, File globalDBFile, File outFile)
getSnapshotFile
,
getGlobalDBFile
and getOutputFile
to gain access to these files.
setSources
in interface Analyzer
snapshotFile
- The WebCT IMS Enterprise snapshot export file.globalDBFile
- The WebCT Global Database CVS export file.outFile
- The output file.public final void analyze()
run
method.
Please note that this method is final
, so it can't be overridden. This is to ensure
the method can properly initialize some event stuff and the new thread. If you need to do things
before run
starts, use preProcess
instead.
analyze
in interface Analyzer
public void preProcess() throws AnalysisException
analyze
method.
Any last-minute prep work that didn't fit in the settings user interface produced by
getSettingsUI
should be done here.
preProcess
in interface Analyzer
AnalysisException
- Most checked exceptions that may occur in this method should be wrapped
inside an AnalysisException
for proper notification to the user.public void postProcess() throws AnalysisException
analyze
method.
Any cleanup work that couldn't be done in the analysis itself should be done here.
postProcess
in interface Analyzer
AnalysisException
- Most checked exceptions that may occur in this method should be wrapped
inside an AnalysisException
for proper notification to the user.public Component getSettingsUI()
javax.swing.JPanel
or something,
that gives the user the opprtunity to set options on the Analyzer
object before the analysis starts.
getSettingsUI
in interface Analyzer
public boolean isRunning()
true
if the analysis is currently running. Works as advertised.
isRunning
in interface Analyzer
protected void setRunning(boolean isRunning)
isRunning
to return the value passed in here.
You do not need to set running to true
when your analysis starts, since this class'
analyze
method already does that for you. You should, however, set running
to false
from any method if you need to cancel the analysis. Your analysis implementation
has the responsibility to return gracefully when isRunning
returns
false
.
public boolean isWaitingForUI()
true
if the analysis is currently suspended,
waiting for some user interface action to complete.
javax.swing.JPanel
, for example. Add any listeners you need to
handle user input.
AnalysisEvent
of type
TYPE_REQUEST_UI_DISPLAY
with the component as
its argument. You can use the updateWithUIRequest
convenience method
to achieve this goal without worrying about the details.
isWaitingForUI
returns false
.
For example:
while (isWaitingForUI()) { try { Thread.currentThread().sleep(<some reasonable amount of time>); } catch (InterruptedException e) { } }
isWaitingForUI
in interface Analyzer
public void setWaitingForUI(boolean waitForUI)
isWaitingForUI
for more information.
setWaitingForUI
in interface Analyzer
waitForUI
- true
or false
.protected File getSnapshotFile()
setSources
as well.
protected File getGlobalDBFile()
setSources
as well.
protected File getOutputFile()
setSources
as well.
protected void finishAnalysis(String info)
run
method. It fires
a AnalysisEvent.TYPE_FINISHED
event and sets
runnig to false
.
info
- Some informational message to display to the user along with the event.public void stopAnalysis(String info)
false
and
sends an event of type AnalysisEvent.TYPE_FINISHED
back
to the application.
false
. Your run
method should check isRunning
frequently and return gracefully if it returns
false
.
stopAnalysis
in interface Analyzer
info
- Some informational message regarding this stop request.public abstract void run()
AnalysisEvent.TYPE_FINISHED
event at the end. (See
finishAnalysis
.)
while (isRunning() && stillReadingData) { // Read data step. updateProgress(progressValue); } if (!isRunning()) { return; } while (isRunning() && stillProducingOutput) { // Write data step. updateProgress(progressValue); } if (!isRunning()) { return; } // Some finishing-up code. finishAnalysis("Analysis complete");
run
in interface Runnable
protected HashMap readGlobalDB() throws IOException
HashMap
. The map's keys are the users WebCT IDs,
and each value is another HashMap
with the global
database field names as keys and the user record's values as strings. If a field in the
database is empty, the map value will be an empty string (""), and not
null
.
OutOfMemoryErrors
. If you are just interested
in the value of one or two fields, it is much more resource-efficient to use
readGlobalDBField(String)
instead.
IOException
- If anything goes wrong reading the file, including when
getGlobalDBFile
returns null
.protected HashMap readGlobalDBField(String fieldName) throws IOException
HashMap
where
the keys are each user's WebCT ID, and the values are the value of the requested field as strings.
If a field in the database is empty, the map value will be an empty string (""), and
not null
. If the field doesn't exist, all values will be empty strings, and
no exception is thrown.
fieldName
- The global database field to read into the values of the resulting map.
IOException
- If anything goes wrong reading the file, including when
getGlobalDBFile
returns null
.protected HashMap readGlobalDBField(String fieldName, double phaseStart, double phaseLength) throws IOException
HashMap
with the values of the requested field
(see readGlobalDBField(String)
for more information).
The only difference with the other version of the method is that this version lets you continue
progress tracking inside the method. To accomplish this, pass the current state of progress when you
call the method as argument phaseStart
and the amount of progress covered by this method
as phaseLength
, so that progressLevelAfterMethodRuns = phaseStart + phaseLength
.
Please note that this value is not returned or in any other way available, so keep track of
progress levels yourself based on phaseStart
and phaseLength
.
fieldName
- The global database field to read into the values of the resulting map.phaseStart
- The level of analysis progress when the method is called.phaseLength
- The amount of analysis progress covered by this method.
IOException
- If anything goes wrong reading the file, including when
getGlobalDBFile
returns null
.protected List getGlobalDBKeys() throws IOException
List
.
IOException
- If anything goes wrong reading the file, including when
getGlobalDBFile
returns null
.public void addAnalysisListener(AnalysisListener al)
AnalysisListener
to the list of listeners. You don't need to
override this unless you need some really special event handling.
addAnalysisListener
in interface Analyzer
al
- The listener to be added to the list.public void removeAnalysisListener(AnalysisListener al)
AnalysisListener
from the list of listeners. You don't need to
override this unless you need some really special event handling.
removeAnalysisListener
in interface Analyzer
al
- The listener to be removed from the list.protected void updateProgress(double progress)
AnalysisEvents
.
The method sets all the appropriate event fields, including a generic information string
based on an estimate of the remaining time for the analysis to complete. It then fires the
event as well, so no need to call fireAnalysisUpdate
yourself.
progress
- The current progress level to be reported.protected void updateProgress(double progress, String info)
AnalysisEvents
.
The method sets all the appropriate event fields, including the information string you pass.
It then fires the event as well, so no need to call fireAnalysisUpdate
yourself.
progress
- The current progress level to be reported.info
- The information string to include in the event.protected void updateWithError(Throwable t)
AnalysisEvents
.
The method sets all the appropriate event fields, including the
Throwable
you pass. This should typically be a checked
exception, but the method doesn't make any restrictions. It fires the event as well, so
no need to call fireAnalysisUpdate
yourself.
t
- The error to be reported.protected void updateWithUIRequest(Component c, String ttl)
AnalysisEvent
. It also puts the
object in a waiting state so that isWaitingForUI
returns true
.
You are responsible for creating the user interface elements, to be passed as a single component to this
method. You also provide a title string to caption the resulting dialog. You are also responsible for
adding any listeners to your user interface elements so you can respond to the user input. Finally
you need to make sure your run
method is suspended while the user interface is being
displayed. See isWaitingForUI
for more information.
c
- The component containing your user interface elements.ttl
- The title to caption the resulting application dialog.protected void fireAnalysisUpdate()
AnalysisEvent
ae
to all registered
AnalysisListeners
. If you are using the updateXXXX
methods, you don't need to call this method. Only if you set the fields of the ae
field yourself do you need to call this method to send the event.
public void setDescription(String desc)
Analyzer
object which will be used
in the analyzer selection list.
setDescription
in interface Analyzer
desc
- The description of this Analyzer
.public String getDescription()
Analyzer
object which will be used
in the analyzer selection list.
toString
,
but the implementation of toString
returns getDescription()
, so overriding
either method will allow you to control the result.
setDescription
in your
initialization code rather than overriding this method.
getDescription
in interface Analyzer
Analyzer
.public String getCopyright()
Analyzer
. The default implementation
returns null
, so override at will. The information is displayed near your Analyzer's settings
interface in a small label, with callous disregard for the length of the text. Keep it short.
getCopyright
in interface Analyzer
Analyzer
.public String toString()
Object.toString()
to provide a human-readable description
to be displayed in the application's analysis selection list. This implementation simply returns
getDescription
()
.
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |