-
Notifications
You must be signed in to change notification settings - Fork 1
Architecture
The project architecture is defined by three main components:
The BPMN Metadata Extractor represents the core of the project, it takes a BPMN model as input and he computes all the required metrics, saving them into a JSON file.
When all the metrics are computed, the BPMN Metadata Extractor sends the final JSON file to the Extractor Rest API, where it will be processed in order to be correctly downloaded by the user.
The User Interface is a simple interface that allows the user to select a BPMN file from his local folders and download its respective JSON file filled with all the extracted metrics.
The Metric Extractor is the main component of the whole project, its purpose is to read a BPMN file and extract different kinds of data from it. The data is used by the program to compute all the Basic and Advanced Metrics, the Metrics will then be stored into a Json file. The process ends when all the information stored into the Json file are saved into a MySql database, bound to their related BPMN model.
All the Metric Extractor components are described in the Project Class Diagram section of this page.
The following picture describes the Metric Extractor Class Diagram.
In the next sections we will explain how these packages work on their own and how they collaborate.
We now focus on the bpmnMetadataExtractor package:
The BpmnModelReader class is the main class of the project. It starts the execution of the metrics computation when a new BPMN file is opened by the BpmnFileOpener, it builds a new Json file and it sets up a new Database Connection.
private void test() {
//Create a new modelInstance out of the new read BPMN file
BpmnModelInstance modelInstance = Bpmn.readModelFromFile(loadedFile);
//Build a new JsonEncoder, basicExtractor and advExtractor
JsonEncoder jsonEncoder = new JsonEncoder(loadedFile.getName());
BpmnBasicMetricsExtractor basicExtractor = new BpmnBasicMetricsExtractor(modelInstance, jsonEncoder);
BpmnAdvancedMetricsExtractor advExtractor = new BpmnAdvancedMetricsExtractor(basicExtractor, jsonEncoder);
//Run all the metrics computation and saves them into the Json file
basicExtractor.runMetrics();
advExtractor.runMetrics();
jsonEncoder.getBasicMetricsValues();
jsonEncoder.getAdvancedMetricsValues();
jsonEncoder.getHeaderValues();
//Connect to db and saves metrics into it
MySqlInterface db = new MySqlInterface();
db.connect();
db.saveMetrics(jsonEncoder);
db.closeConnection();
}
public static void main(String[] args){
//run test() on new modelReader
BpmnFileOpener fileOpener = new BpmnFileOpener();
BpmnModelReader modelReader = new BpmnModelReader(fileOpener.openFile());
modelReader.test();
}The BpmnFileOpener class is used to allow the user to choose a BPMN model to read. Once the user selects a BPMN model, its relative path is used by the extractor to locate the model from which it will start to extract data. The following piece of code shows how the BpmnFileOpener class works:
public String openFile() {
JFileChooser chooser = new JFileChooser(System.getProperty("user.dir"));
FileNameExtensionFilter filter = new FileNameExtensionFilter("File BPMN", "bpmn");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open file: " + chooser.getSelectedFile().getName());
} else {
System.exit(0);
}
return chooser.getSelectedFile().getAbsolutePath();
} The BpmnBasicMetricsExtractor class computes all the basic metrics out of the data extracted from the BPMN model. There are more than 200 differents functions that operate to extract metrics, once they come up with a result, it is added to the Json file. The following piece of code shows how the metrics are extracted by their respective method and added into the Json file under the "Basic Metrics" section.
public void runMetrics() {
this.json.addBasicMetric("NT", this.getTasks());
this.json.addBasicMetric("NCD", this.getComplexDecisions());
this.json.addBasicMetric("NDOin", this.getDataObjectsInput());
...
}The BpmnAdvancedMetricsExtractor class works basically like the BpmnBasicMetricsExtractor, there are only two differences:
in order to extract some advanced metrics, this class needs to have some specific basic metrics values, so, a basicMetricExtractor is used by the class to provide those metrics.
The second difference is that the BpmnAdvancedMetricsExtractor class uses external classes to compute some metrics that are more complicated than others, those complex metrics may also need dedicated functions or algorithms to be implemented.
The extracted advanced metrics are added into the Json file under the "Advanced Metrics" section in the same way of the basic metrics:
public void runMetrics() {
json.addAdvancedMetric("CLA", getConnectivityLevelBetweenActivities());
json.addAdvancedMetric("CLP", getConnectivityLevelBetweenPartecipants());
json.addAdvancedMetric("PDOPin", getProportionOfIncomingDataObjectsAndTotalDataObjects());
...
}The JsonEncoder class is used by the extractor to initialize a Json file which will be lately filled with all the metrics extracted from the BPMN file. It also provides methods to add basic and advanced metrics into it and also a method to create unique ID based on the BPMN model file name and the time of creation.
The Json file is structured like so:
{
"Header":{},
"Basic Metrics":{},
"Advanced Metrics":{}
}The Header contains the unique ID of the Json, its creation date and the BPMN model name. The ID will be really important when we will save this Json file into the database, infact, it will serve as a bind for all the metrics extracted from the same BPMN model.
The Basic Metrics part contains all the extracted basic metrics and the Advanced Metrics part contains all the extracted advanced metrics.
All we did to initialize the Json file is:
public void initializeJSON(){
JSONObject header = new JSONObject();
JSONObject basicMetrics = new JSONObject();
JSONObject advancedMetrics = new JSONObject();
this.json.put("Header", header).put("Basic Metrics", basicMetrics).put("Advanced Metrics", advancedMetrics);
}The JsonEncoder class also offers several method that will be used when we will export data from the Json file into the database. The method used to get Header's data is the following:
public ArrayList<String> getHeaderValues() {
JSONObject header = this.json.getJSONObject("Header");
JSONArray namesArray = header.names();
ArrayList<String> values = new ArrayList<String>();
for (int i = 0; i < namesArray.length(); ++i) {
values.add(header.getString(namesArray.getString(i)));
}
return values;
}To get the basic and advanced metrics the method used is the same of the Header.
The MySqlInterface class provides a way to connect the program to a MySql Database to permanently save all the extracted metrics to keep them organized and structured.
The following method creates a connection to the database:
public void connect() {
try {
Class.forName(DRIVER_CLASS);
System.out.println("Connecting to database...");
connection = DriverManager.getConnection(CONN_STRING,USERNAME,PASSWORD);
System.out.println("Connected");
statement = connection.createStatement();
} catch (SQLException | ClassNotFoundException e){
System.err.println(e);
closeConnection();
}
}To save basic metrics into the database we use this method:
private String insertBasicMetricsString(JsonEncoder json) {
String insertInto = "INSERT INTO BASIC_METRICS VALUES ("; //Query start
ArrayList<Integer> basicMetricsValues = json.getBasicMetricsValues(); //Method called from the JsonEncoder class
insertInto += "'" + json.getModelId() + "', ";
for (int value : basicMetricsValues) {
insertInto += "'" + Integer.toString(value) + "', ";
}
String toReturn = insertInto.substring(0, insertInto.length()-2);
toReturn += ")";
return toReturn;
}Once we finish to insert all the metrics in the database we need to close the previously opened connection, to do so, we used this method:
public void closeConnection() {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) { /*ignored*/ }
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) { /*ignored*/ }
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) { /*ignored*/ }
}
System.out.println("Closing connection to database");
}The database structure is described in the next paragraph by using an ER Diagram.
The following picture describes the ER Diagram of the MySql Database.
The Model_Infos table stores the ID, name and upload date of every model that has been through the extraction phase.
The ID is used as a primary key for the Model_Infos table and as secondary key for the Basic_Metrics and Advanced_Metrics tables, so that every extracted metric is bound to its related BPMN model, all the metrics are stored in the Basic_Metrics and the_ Advanced_Metrics_ tables divided by their kind.
The Metric_Infos table is used to store name, description and source of all the extracted metrics, those information will be attached to every metric in order to give the user a comprehensive list of metrics and their detailed explanations.
The Extractor Rest API package provides a way for the bpmnMetadataExtractor to enstablish a safe communication with the User Interface.
The following method it is used by the rest API to send the selected BPMN model to the BPMN Metadata Extractor in order to be elaborated. When the extraction is completed, the same method sends back the processed JSON file to the user.
@Path("/fileUpload")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response extractMetrics(
@FormDataParam("model") InputStream uploadedInputStream,
@FormDataParam("model") FormDataContentDisposition fileDetail) {
BpmnModelReader metricsExtractor = new BpmnModelReader();
String fileName = fileDetail.getFileName().substring(0, fileDetail.getFileName().lastIndexOf('.'));
String json = metricsExtractor.getJsonMetrics(uploadedInputStream, fileName);
return Response.ok((Object)json).
header("Content-Disposition","attachment; filename = " + fileName + ".json").
build();
}The UserInterface workpackage consists of a simple web interface that represents a point of access for users that want to use the BPMN Metadata Extractor.
Currently the web interface is basically a simple HTML page that allows the user to upload a BPMN model from its local device and to download the resultant JSON file.
The User Interface sends the BPMN Model using the following HTML form:
<form action="extractorRest/api/fileUpload" method="post" enctype="multipart/form-data">Which is directly linked to the path of the extractMetrics() method of the Extractor Rest API using the
action="extractorRest/api/fileUpload" attribute.
Wiki
Component Architecture
Technology Used
Tests




