Up Previous Next Title Page Index Contents

8.2 Using the API from a client program

In order to access the MetaEdit+ API from your client program, you need to have a SOAP framework for your programming language or platform installed. As SOAP is a widely recognized standard, these frameworks are available for most platforms.

As an example, we describe here the setting up of the SOAP framework for Java 2 Standard Edition. Please note that the following instructions expect you to have a working knowledge of Java and the Java 2 development environment. It is also assumed that you already have the Java 2 SDK installed.

To set up the SOAP framework, the following two components are needed (both of them can be downloaded from xml.apache.org):
The Apache Xerces2 XML parser for Java (version 2.5.0 was used for this example).
The Apache Axis SOAP library (for this example, we used version 1.1).
Once you have installed both these additional libraries, consider the example Java code in Listing 1.


 1  import java.util.*;
 2
 3  class APIExampleApp {
 4    public static void main(String[] args) throws Exception {
 5 
 6      com.metacase.MetaEditAPI service =
 7        new com.metacase.MetaEditAPILocator();
 8      com.metacase.MetaEditAPIPortType port =
 9        service.getMetaEditAPIPort();
10      com.metacase.METype graphType =
11        new com.metacase.METype();
12      com.metacase.MEOop[] graphs;
13      com.metacase.METype objectType =
14        new com.metacase.METype();
15      com.metacase.MEAny[] props = new com.metacase.MEAny[1];
16      com.metacase.MEAny[] values = new com.metacase.MEAny[1];
17      com.metacase.MEAny area = new com.metacase.MEAny();
18      com.metacase.MEAny np = new com.metacase.MEAny();
19      com.metacase.MEAny objectInfo =
20        new com.metacase.MEAny();
21      com.metacase.MEOop newObject = new com.metacase.MEOop();
22      com.metacase.MEAny tempAny;
23
24      graphType.setName("WatchFamily");
25      graphs = port.allGoodInstances(graphType);
26      objectType.setName("Note [Watch]");
27      tempAny = new com.metacase.MEAny();
28      tempAny.setMeType("MENull");
29      tempAny.setMeValue("");
30      props[0] = tempAny;
31      tempAny = new com.metacase.MEAny();
32      tempAny.setMeType("Text");
33      tempAny.setMeValue("'A new note created by the API'");
34      values[0] = tempAny;
35      np.setMeType("MENull");
36      np.setMeValue("");
37      area.setMeType("MENull");
38      area.setMeValue("");
39      objectInfo =
40        port.instProps(objectType, props, values, np, area);
41      StringTokenizer st = new
42        StringTokenizer(objectInfo.getMeValue(), "_", false);
43      newObject.setAreaID(Integer.parseInt(st.nextToken()));
44      newObject.setObjectID(Integer.parseInt(st.nextToken()));
45      port.addToGraph(newObject, graphs[0]);
46    }
47  }

Listing 1. Sample Java application using the API.

This small application adds a new ‘Note’ object with some text into the ‘2004Models’ WatchFamily diagram that can be found from ‘demo’ repository. To understand how this is done, please read on and follow the code from line 24 onwards. First we retrieve all graphs of type WatchFamily and store them in an array (lines 24 – 25). Then we start to set the variables that are needed for creating a new object: object type (line 26), properties (lines 27 – 30) and their values (lines 31 – 34), possible existing non-property (lines 35 – 36) and the database area (lines 37 – 38). When these have been set, the creation request can be sent (lines 39 – 40) and the return value – an MEAny pointing to the new object – is stored to a temporary variable.

Before we proceed, let us have a closer look at the parameters of the instProps method found in line 40. The instProps method can be used either – as in this case – to create new instances of any non-property type or to change property values of an existing instance. The first parameter is the non-property type of the instance we are creating or changing. Whether this is a creation or change operation depends on the fourth argument. If this MEAny has an MENull as its value, a new instance will be created; it the MEAny has an MEOop as its value, we change the instance referred to by that argument. The last argument is an MEAny denoting the home project for the instance, used only when creating a new instance.

Somewhat more complicated are the second and third arguments, which provide the new or modified instance’s properties and their values. The second parameter is the collection of the MEAnys that refer to the properties to be created or changed. Each MEAny in this collection can contain either an MEOop that refers to a certain existing property, in which case that existing property is used (e.g. to set up property sharing). Alternatively, and more normally, each element can be an MEAny containing an MENull, in which case when creating a new non-property, a new property of the default type will be created, and when modifying an existing non-property, its existing properties will be left in place. The third parameter then carries a collection of values that are assigned to the properties defined by the previous argument. The datatype of the elements of this collection is also MEAny. The structure of these collections is presented in Figure 8–1.

Figure 8–1. The array structures of parameters of the instProp method.

Most API functions return an MEOop directly, but in this case the function has to also be able to return an MENull value if the object creation failed, and so must return its value as an MEAny. From this MEAny we read the area and object id to reconstruct a true MEOop for the new object (lines 41 – 44). Once we have that, we can add the new object to the WatchFamily graph (we can use the first graph in the array as we know that there is only WatchFamily graph in our demo repository).

When compiling the code, we must remember to introduce the additional libraries. As an example of how this is done, see the batch file sample in Listing 2.
 1  set path=%path%;c:\java\j2sdk\bin
 2  set axisdir=c:\java\axis-1_1
 3  set xercesdir=c:\java\xerces-2_5_0
 4
 5  set classpath=%axisdir%\lib\axis.jar;
 6  %axisdir%\lib\axis-ant.jar;
 7  %axisdir%\lib\commons-logging.jar;
 8  %axisdir%\lib\log4j-1.2.8.jar;
 9  %axisdir%\lib\saaj.jar;%axisdir%\lib\wsdl4j.jar;
10  %axisdir%\lib\jaxrpc.jar;%xercesdir%\xmlParserAPIs.jar;
11  %xercesdir%\xercesImpl.jar;.
12	
13  java org.apache.axis.wsdl.WSDL2Java -p com.metacase MetaEditAPI.wsdl
14
15  javac APIExampleApp.java com\metacase\*.java

Listing 2. Sample script for compiling Java code with SOAP extensions.

In the first three lines we set the paths for the Java compiler and Axis and Xerces libraries – remember to change these to match your installation directories. The classpath for the libraries is set in lines 5 – 11, which should be unwrapped to a single line. Please note that the path setting for log4j*.jar depends on the Axis version you are using, so check the .jar file names in your installation. The next step is to use Axis’s WSDL2Java to translate the MetaEdit+ WSDL file into Java code. This is done in line 13 (note that in this example the WSDL file is expected to be in the same directory as the sample Java code). The output from WSDL2Java is stored in the com\metacase directory. Finally, in line 15, we compile our APIExampleApp along with the WSDL2Java output.

To try out this API example, login to MetaEdit+, open the API Tool, and start the API server. Once that is running, execute the APIExampleApp. Now, go back to MetaEdit+ and open the ‘2004Models’ WatchFamily diagram. As we remember, we have so far only added the concept of the new ‘Note’ into this diagram, but not a representation for it. To create a new representation for the new concept, select Graph | Import Graph, and the new ‘Note’ symbol with text ‘A new note created by the API’ will appear. If your Diagram Editor window is not large enough, the symbol may be created outside the window border – just zoom to fit or resize the window to find it.

Up Previous Next Title Page Index Contents