JWAVE addresses this problem with data proxies. A proxy is an object-oriented design term that refers to a surrogate or placeholder that controls access to another object. A data proxy, then, is a surrogate object that refers to data.
Usually, a JWAVE wrapper function processes data in some way and stores the results. The JWAVE client may wish to use another JWAVE wrapper to perform further analysis on the stored results. To do this, the client needs to be able to reference the data stored on the server. The most efficient way to do this is to ask the server to return a data proxy, which the client can then use in the setParam
method of subsequent function calls from the first wrapper.
Figure 6-1 A Proxy object refers to data stored in a PV-WAVE session. The proxy knows where to find the server (JWaveConnection), the name of the data domain name for the data (ServerDataID).
How the data arrives on the server in the first place is up to the JWAVE application developer. The data could have originated on the client and been uploaded to the server. Or, the data could have been loaded on the server from a file or database, or calculated by a JWAVE wrapper function.
The data referred to by a
JWaveDataProxy
object persists on the server until it is explicitly deleted or the PV-WAVE session is shut down.
JWaveDataProxy object is instantiated with:
JWaveDataProxy
object is:
new JWaveDataProxy(myconnection, 'MYDATA', 'MYDOMAIN')
myconnection
is the previously instantiated JWaveConnection
object (tells the proxy how to find the server), MYDATA
is the name of the data stored on the server, and MYDOMAIN
is the domain. When you construct a
JWaveDataProxy
object in this way, you are only providing the name of the data. This JWaveDataProxy
object refers to a place to store data, but there is no guarantee that there is actually data there. If you do not know that there is already data on the server, you can use the Proxy.store
method to send data to the PV-WAVE session.
JWaveDataProxy
object, and they both are used in conjunction with a JWaveExecute
object. The first way is to supply a
ServerDataID object (which encapsulates the name and domain of a JWaveDataProxy
object) when you use the setParam
method.
setParam(String name, Object value, ServerDataID dataName)
ServerDataID
object when it is sent with the next execute
call.This technique is useful when you have some data on the client, and you want to use that same dataset with several JWAVE wrapper functions. So you use the above
setParam
method to save the data on the first call, and then you use the following setParam
on subsequent calls to associate a named parameter with that stored data:
setParam(String name, ServerDataID dataName)
JWaveDataProxy
objects directly. If you need direct access to the data (like to delete it when you are done) you can use the same ServerDataID
object that identifies the data name in a constructor to a new JWaveDataProxy
object. Another way to create a data proxy is when data is returned by a JWAVE wrapper function. Normally, the JWAVE wrapper returns values back to the client, but you can change this. Before you call the
execute
method, you can use the setReturnParamMode
method to change how returned data will be handled.There are a couple of overloaded methods for
setReturnParamMode
, but the primary one is:
setReturnParamMode(String name, boolean returnVals, ServerDataID dataName)
ServerDataID
object for the data name, then that parameter will be stored on the server when the JWAVE wrapper function returns. You can also use the boolean flag with one of the values JWaveExecute.RETURN_NO_VALUES
or JWaveExecute.RETURN_VALUES
. If you set this flag to
RETURN_NO_VALUES, then no values are returned, but a JWaveDataProxy
object to the stored data is returned.
This technique is useful for "chaining" the output of one JWAVE wrapper to the input of another, as you will see in a later example.
setReturnParamMode
object. If you set the flag to RETURN_VALUES and you set a
ServerDataID
object, then the data is stored and also returned to the client. You can even discard data that you do not want by setting RETURN_NO_VALUES
without a ServerDataID
object.
TIP: For detailed information on all of the constructors, variables, and methods of the JWaveDataProxy class, refer to the Javadoc reference. For information on Javadoc, see Using the JWAVE Javadoc Reference.
Viewable
object back to the client. Figure 6-2 illustrates an inefficient version of this scenario, where data makes two complete round trips between the client and the server. This scenario can be summarized as follows:
JWaveExecute
object executes a JWAVE wrapper function called DATAGEN
on the PV-WAVE server.
JWaveExecute
object, which sends it back to the server as input to another JWAVE wrapper called FILTER
. (The data has made one round trip.)
JWaveView
object, which sends it back to the server as input to another PV-WAVE routine called GRAPHICS
. (The data has now made two round trips.)
Figure 6-2 Inefficient use of JWAVE, as data is physically passed between server and client
In this case, note that the object returned to the client each time is a data proxy, rather than actual data. The client uses the proxy object in subsequent
JWaveExecute
methods (where, in the previous (inefficient) model, the actual data was passed).
Figure 6-3 Efficient use of JWAVE, as data is not physically passed between server and client
JWaveExecute.setReturnParamMode
method. In the next section, we present an example illustrating the use of data proxies.
This example discusses a JWAVE application that:
Figure 6-4 JWAVE scenario using data proxies
NOTE: This client application calls two different JWAVE wrapper functions on the server. From the first wrapper, the client asks for a proxy to be returned. From the second wrapper, the client asks for the actual data values, which it then prints.
The Java
Example 6-1 proxyarry.java: Sends data to the server; retrieves a data proxy; uses the proxy in a subsequent JWaveExecute object
import com.visualnumerics.jwave.*; public class ProxyArray { public static void main(String[] args) { try { // Create a simple array as data float[] arr = new float[10]; for (int i=0; iarr.length; ++i) arr[i] = i; // Connect to JWave server JWaveExecute command = new JWaveExecute("PROX1"); // Set the data as ARRAY1 parameter command.setParam("ARRAY1", arr); // Ask that the result data (named DATA) be stored on the server, // and only return a Proxy ServerDataID saveData = new ServerDataID("SAVE_NAME"); command.setReturnParamMode("DATA", JWaveExecute.RETURN_NO_VALUES, saveData); // Execute PROX1 command.execute(); // Switch to new wrapper function command.setFunction("PROX2"); // Clear previous parameters and return modes command.clearParams(); command.clearReturnParamModes(); // Set input to PROX2 to use data stored by PROX1 // Could also use getReturnProxy("DATA") here rather than saveData command.setParam("ARRAY2", saveData); // Execute PROX2 and get result command.execute(); float[] answer = (float[]) command.getReturnData("DATA"); // Print result for (int i=0; i
answer.length; ++i) System.out.println(answer[i]); } catch (Exception e) { // Report problems System.out.println(e.toString()); } } }
The First JWAVE Wrapper
Example 6-2prox1.pro: Receives an array from the client and multiplies the elements by 1.5. The client asks the server to return a data proxy rather than the actual data.
FUNCTION PROX1, client_data ; Unpack data and parameters sent from the client. arr = GETPARAM(client_data, 'ARRAY1', /Value, Default=11) ; Change the array. mydata = arr * 1.5 ; Return the changed array. RETURN, mydata END
The Second JWAVE Wrapper
Example 6-3prox2.pro: The client asks this server program to process the array it stored previously. The client refers to the data on the server with a proxy. Finally, the client asks the server to send back the actual data so that it can be printed. (This wrapper multiplies the previously stored array by 100.5.)
FUNCTION PROX2, client_data ; Unpack data and parameters sent from the client. arr = GETPARAM(client_data, 'ARRAY2', /Value, Default=11) ; Change the array. mydata = arr * 100.5 ; Return the changed array. RETURN, mydata END
Java Client
% java proxyarr 0.0 150.75 301.5 452.25 603.0 753.75 904.5 1055.25 1206.0 1356.75
Manager routines DMSave and DMRestore to store data between sessions. These JWAVE wrapper procedures are described in Appendix A, JWAVE Wrapper API.
TIP: You can use the Data