In this series of articles we will try to consider in detail the main aspects of using this bundle. We used this combine to implement one of the subtasks of the project to develop an intelligent system for automated management of educational planning. For a better understanding, it is worth saying a few words about the project itself.
Any minor changes in the curriculum lead to huge labor costs for its processing and coordination in the university services, so department heads are reluctant to change them. The goal of the project is to create an agent for the head of the department, which will allow you to create a curriculum and make changes to it so that the user does not feel the burden of the routine work of redesigning the curriculum in case of making certain adjustments.
As planned, an agent who is an assistant and a consultant is attached to each participant in the curriculum development process (for example, the head of the department).
JADE (Java Agent Development Framework) was chosen as a tool to easily implement such agents and process their behavior.
As a DBMS,
Caché was used by InterSystems. We chose the DBMS for several reasons. First, this DBMS supports the object-based approach to data access, which greatly facilitates the work (apart from the fact that it allows you to create projections of classes in various languages, but this will be discussed below). Secondly, in this system it is easy to configure areas of access for users, which is useful later. And finally, InterSystems strongly supports developers who use their products, and also provides licenses for universities
for free .
')
It was decided to make the system cross-platform, for convenience and mobility in future use. To implement the web-interface of the system, flex technology was chosen (extending the basic flash capabilities).
As a result, at the first stage of development a number of tasks were highlighted, which will be discussed later (we will consider these problems in this series of articles):
- Cache class model development
- implementation of the relationship between Cache and Java
- web interface development
- implementing java-web interface
To solve the fourth task, the GraniteDS framework was chosen, the work with which will be described in more detail in the next article.
As a result, the resulting architecture can be represented as follows:

In addition to the above, a binding agent is installed on the client, which ensures constant communication with the JADE agent and informs the user about the events and messages that are transmitted by the main agent.
In the first part, we will focus our attention on the Cache-Java interaction.
Consider a fragment of the Caché database structure used for the functioning of an agent for the head of the department in a multi-agent curriculum management system (MAS UUP). Stored classes were designed and implemented in the studio Caché.

The Caché database fragment for the agent of the head of the department consists of six stored classes, the main of which is the class of disciplines (cDiscipline), which includes all the necessary characteristics of the discipline for the curriculum. From the above diagram, it is clear that disciplines are divided into cycles and semesters, which, in turn, are included with the disciplines in the curriculum in a certain direction. Discipline can be basic and have several other disciplines in its structure, which is implemented by the relation of Parent. Communication discipline with class cControlForm determines the form of control of the discipline (exam or test). The curriculum also contains a list of the changes made to it (the cLogs class).
For the subsequent implementation of a bunch of stored Caché classes with application logic in java, using the
standard projection mechanism , classes of java projections were generated. Below is the code for creating a java projection in the Caché class.
Projection PrjName As %Projection.Java(ROOTDIR = "c:\Out\"); //PrjName – , ROOTDIR – java
As noted, the organization of communication with the Caché database is made using the java-projection mechanism, as well as the libraries supplied with Caché for communication via JDBC.
To facilitate development at this stage, a layer of m-classes was created, allowing to get rid of the classes of java-projections (c-classes).

Why is this done? The classes of java-projections for the described system, generated by Caché, are presented in this diagram as a package of classes "Java c-classes". The Java m-classes package contains classes, each of which corresponds to a class from the Java c-classes package. Java m- classes repeat only the properties of classes from the c- package, and in addition contain their own get () and set () methods. This approach is convenient with constant changes in the Caché classes, because after the slightest change in Caché, it is enough to regenerate the Java projection of the required Caché class and then replace it (and changing the m-classes is much easier than editing the newly created projection). In addition, this approach at this stage helps with the organization of microtransactions. For example, it allows you to easily roll back changes in m-classes that have not yet been saved in c- (in particular, it is necessary for the algorithm). And if we also take into account the fact that Java does not directly support cloning, such microtransactions greatly facilitate the work. In addition, Granite DS to create ActionScript projections requires some changes to the main class (this will be discussed in the second part of the article), and making such changes to the m-class is easier than rewriting partially the structure of the c-class. Therefore, this approach greatly facilitates the work at the main stage of development, while, at the optimization stage, this solution can be reworked.
So, for example, from the point of view of efficiency and memory, this approach does not look very attractive. And in the future, you will most likely have to move away from it by implementing the Serializable interface in c-classes, which is necessary for the operation of Granite DS.
The CacheTransform class is the link between the Caché database and the java classes. In this class, there are two ways to work with the Caché database: through JDBC and through java projections. To ensure communication with the database via JDBC, the CacheTransform class implements the database connection function. The implementation of this function uses the Database class object supplied in the cachedb library. Below is the code of the function to connect to the database.
public Boolean InitCon(String port, String user, String pass) { try { username=user; password=pass; url="jdbc:Cache://localhost:"+port+"/IKIT"; dbconnection = CacheDatabase.getDatabase(url, username, password); connect=true; try{ setParams(port,user,pass); }catch (IOException er){System.out.println("[Error of IO]: "+er);} return true; } catch (CacheException e) { e.printStackTrace(); return false; } }
The InitCon function accepts the basic connection parameters (port is the port number, user is the user name, pass is the password for connecting to Caché), enters them into the corresponding global variables and tries to connect to the database. If the connection is successful, the current parameters are entered into the configuration file by the function setParams (port, user, pass). Also, it is worth noting that the url uses localhost, since the java-application itself and the database are located on the same machine, and further it is worth unifying this function so that it accepts both the address of the machine that the database is running on and the database area (in this example, - IKIT).
Next, consider the order of reading data from the database Caché. In the CacheTransform class, for each java projection class, a pair of functions is implemented, one of which loads one class object by Id, and the other all class objects. Below is
sample code for loading objects of the cControlForm class. It is clear from the example that the _open function of the java-projection class is used for loading one object by Id, and the openByQuery function of the dbconnection object of the Database class is called to load all objects to which the SQL query is transmitted. It is worth noting that IKIT.cControlForm.% ID returns a collection of objects. Then the TranformCF method is called in both functions:
As can be seen from the description, this method accepts an object of c-class and in case of successful conversion returns an object of m-class. In particular, this method works with the ControlForm class.
The procedure for storing data in the Caché database is similar to the loading process and is also implemented in the CacheTransform class. Below is an example for saving data of the cControlForm class.
In the example, the input argument of the RevTranformCF function is 1 or 0. When act is one, an object of the cControlForm class is loaded from the database, otherwise a new object of the cControlForm class is created. Next, the values ​​are assigned to the attributes of the cControlForm object and the save function is called.
The method call of the CacheTransform class object is performed in the UserService class, which implements the IUserService interface, which is used in turn by the ActionScript classes of the web application. More about this bundle will be discussed in the next part of the article.
Summing up this part of the article, we can say that in our case, working with Java projections Cache greatly facilitated the work, because it allows you to bypass the “Cache class” - “Data” - “Java class” link, assigning the main work with DBMS data. The projections are more convenient from the point of view of the OOP, since there is direct work with the classes and there is no need to create manually the structure of java-classes for data processing. So, for example, instead of SQL queries, which often return data, the type of which you need to know in advance, use the get (), set () methods to get typed data. In addition, the regeneration of projection classes when compiling the Cache class eliminates the need to make significant changes to the Java classes, which would be observed when using JDBC communication.
As for the main structure, at the optimization stage, it will be necessary to unify the functions of reading and writing, as well as to move from duplicates to pure projections.
In the next part of the article we will talk about the general structure of the project that implements the Caché-Java connections - Flex, the interaction mechanisms, as well as the tools used for this. The work of the system itself can be found
here .