Database Reference
In-Depth Information
So what's that complex bit of code at the top of our
ojsInit()
method? There is a block of code that
we want to run in the background while our modal
sayWaitDialog
is being displayed. That sounds easier
than it is. You see, a Java GUI application like this is generally
single-threaded
—that is, only one track of
code is processed at a time. This single focus is made even more stubborn by the fact that we are using a
modal dialog. The modal dialog completely dominates the single-threaded processing until the dialog is
removed (made invisible, in our case).
In older versions of Java, I have had to write separate
Thread
pools to handle out-of-band
processing, but in current Java versions, the
SwingUtilities
class provides a standard approach to this
problem. We hand a new
Runnable
instance (
Thread
) to the
SwingUtilities.invokeLater()
method (you
can see this in Listing 12-6), and it delays running the
Thread
until your current code has processed a bit
further. The delay seems to work well enough for our purposes.
You can see the new
Thread
that's created in the
new Runnable()
syntax. This is an anonymous class
definition. In the class definition, we define a single method named
run()
that does our work. You can
see that the
run()
method does the significant initial work of the
Login
class—everything up to waiting
for the user to enter a two-factor authentication code. Most of that work is accomplished in the two calls
to methods in
OracleJavaSecure
,
setAppContext()
and
getAppConnections()
.
The call to
getAppConnections()
is prone to failure under one specific condition that we need to
address—whenever the OS user is not authorized to proxy connect through the Oracle application user.
This can occur under some circumstances with an exception being thrown, and in other circumstances
with the Oracle connection as
appver
user being null. We have added a method in
Oracle Java Secure
to
test whether the
appver
connection is null:
isAppverOK()
. In both sets of circumstances, we need to
inform the user. However, in the delayed
Thread
, it is difficult to catch the exception and do anything
helpful with it. The situation here is one where we only need to notify the user of the fact. They need to
log out and back in as a different user to use the application. Here's how we will tell them: the initial
value we set in
jbInit()
for the
twoFactCodeTextField
is “Your OS User account cannot log in.” If we
succeed at making our proxy connection, then no
Exception
will be thrown, and we will continue on
through our delayed
Thread
. This will set the
twoFactCodeTextField
equal to a blank string. However, if
there is an exception we will not change that value, and the text field will remain as the original error
message. Instead of calling this approach “error reporting,” I would call this “lack of success reporting”.
Keep “lack of success reporting” in mind as a viable approach in cases like this.
At the end of our delayed
Thread
,
run()
method, we make the
sayWaitDialog
invisible. The code
order in
ojsInit()
is opposite of the chronological order of execution. So we end up making the
sayWaitDialog
visible before we make it invisible.
The Continue Button
The last set of activities we want to address are those that occur after the user has entered a two-factor
authentication code and either pressed the enter key or clicked on the Continue button. Both of those
events call the
continueButton_actionPerformed()
method. This method is shown in Listing 12-7. Notice
that we call the same two methods of
OracleJavaSecure
that we called earlier; however, this time we
provide the two-factor authentication code from
twoFactCodeTextField
that the user presumably
received and entered.
Listing 12-7.
Continue with Provided two-factor Authentication
private void continueButton_actionPerformed(ActionEvent e) {
if (twoFactCodeTextField.getText().equals("Bad two-factor code"))
twoFactCodeTextField.setText("");
if (twoFactCodeTextField.getText().equals("") ||
twoFactCodeTextField.getText().equals("Your OS User account cannot log in"))