• Non ci sono risultati.

CONSTANTINE: CONSTraints ANalysis and Toolkit IN Eclipse.

N/A
N/A
Protected

Academic year: 2021

Condividi "CONSTANTINE: CONSTraints ANalysis and Toolkit IN Eclipse."

Copied!
24
0
0

Testo completo

(1)

STEPS WP1D.3&4

CONSTANTINE:

A CONSTraints ANalysis Tool IN Eclipse

Written by Responsibility Roberto Micalizio Verified by Mauro Pasquinelli Approved by Valter Basso Documentation Manager

Approval evidence is kept within the documentation management system.

DOCUMENTAZIONE RISERVATA ATS STEPS

“ai sensi dell’Articolo 22 del contratto di finanziamento no 14013 del 02/12/2008 è vietata qualsiasi

rivelazione, diffusione o divulgazione del presente materiale senza il preventivo consenso scritto degli originatori.”

(2)

CHANGE RECORDS

ISSUE DATE § CHANGE RECORDS AUTHOR

(3)

TABLE OF CONTENTS 1. INTRODUCTION... 5 2. LIST OF DOCUMENTS... 6 2.1 Applicable Documents... 6 2.2 Reference Documents... 6 2.3 Acronyms... 6

3. OBJECTIVE OF THE RESEARCH... 7

4. OBJECT CONSTRAINT LANGUAGE (OCL)... 8

5. CONSTRAINT TYPES... 9

5.1 Concept level constraints... 10

5.2 Property level constraints... 12

5.3 Category level constraints... 14

5.4 Property2Property constraints... 14

5.5 General and Project-level Constraints...15

6. IMPLEMENTATION... 15

6.1 Transforming OCL annotations into running code...15

7. VALIDATING A BASELINE AND PRODUCING A REPORT...18

8. Conclusions... 19

Index of Figures Figure 1 The Constantine Architecture...8

Figure 2 Meta-model view for the topological design...10

Figure 3 Meta-model: Properties and Categories...12

Figure 4 Meta-model: abstraction of the topological view...13

(4)

TABLE OF ANNEX

APPENDICES : ANNEXE 1...20 APPENDICES : ANNEXE 2...22

(5)

1.

INTRODUCTION

This document summarizes the contribution of the UNITO team to the STEPS project within WP1D.3. Particular attention is devoted to discuss the challenges that have been faced during the design and the implementation of the CONSTANTINE module.

The document is organized as follows. In section 3 we lay out the main motivations at the basis of the research and the goals that we want to obtain. In this section we also introduce the high-level architecture of the CONSTANTINE module highlighting that such a module must be able to deal with at least two classes of different users: knowledge engineers, who are the experts of the data model, and space engineers (i.e., designers), who are the experts of specific disciplines.

In section 4 we briefly introduce the OCL language, proposed by the OMG as a way to fill the gaps of knowledge that affect UML models. It is well known, in fact, that some aspects of the reality cannot be precisely modeled through pure UML. To overcome the problem UML models are in some cases accompanied by annotations in natural language that make the models more precise. This approach to the problem, however, has proved to be ineffective as natural language can be easily misunderstood; OCL is a formal language to express conditions among the classes and their relation within a given UML model.

In section 5 we characterize the set of constraints that are relevant for the STEPS project. In this section we provide a number of examples about the representation of high-level constraints by means OCL.

In section 6 we provide some details about the implementation of OCL constraints into a piece of code that can actually be used at runtime. In particular we propose the adoption of Aspect-Oriented java to realize an efficient implementation of constraints.

(6)

2.

LIST OF DOCUMENTS

2.1

Applicable Documents

2.2

Reference Documents

RD 01 STEPS WP1D.3&4 Conceptual Data Model Reference for STPES WP1D activities RD 02 Object Constraint Language, OMG, February 2010

RD 03 DRESDEN OCL2 FOR ECLIPSE

RD 04 AspectJ in Action, Practical Aspect-Oriented Programming

2.3

Acronyms

AspectJ Aspect-Oriented Java DB Data-Base

DOCL Dresden OCL Toolkit

CONSTANTINE Constraints Analysis Tool in Eclipse OCL Object Constraint Language

OMG Object Management Group UML Unified Modeling Language

UNITO Università di Torino, Dipartimento di Informatica, Gruppo Torasso. VR Virtual Reality

(7)

3.

OBJECTIVE OF THE RESEARCH

Document [RD 01] discusses the conceptual data model used inside the WP1D.3. The basic idea of such a model is to organize data according to general concepts (such as Engineering Data Item, or Property), which are valid in any project. Data are therefore stored into a DB which reflects such a general conceptual model. The advantage of this approach is that data can be easily exploited by different users and for different purposes. In fact, data stored into the DB could represent the current baseline for a project whose design phase is still active, or they can represent data of past projects.

It is important to note that the users of the DB are not only engineers, who may want to update the current baseline of an active project or who could retrieve solutions adopted in past projects; but are also applicative software, especially software supporting the design process or rendering programs, such as XXX, which visualizes in VR portions of the artifact at hand.

In [RD 01] the class diagram formalism of UML has been adopted to formally define the conceptual data model. UML has been chosen because it is de facto a standard for the design of data schemas, whose semantic is well-known and not ambiguous. UML, however, has some limitations. Its expressive power, in fact, it is not sufficient to represent all the aspects of the reality. In other words, there are constraints that cannot be modelled just in terms of classes and relations between classes.

This weakness of UML may arise some critical problems when the purpose of organizing data into a DB is not just to store them efficiently, but also to reason about them and to check their consistency. That is, UML is a good solution when one is interested in storing data, but it is not sufficient when data must be verified. In fact, one the objective of the WP1D.3 is to support an engineer during the design process; ideally, whenever the designer makes a choice, that choice has to be validated in order to establish whether it conflicts with the choices the designer has already made, or with the decisions taken by other engineers.

Inside the WP1D3, UNITO’s task has been to find a way to overcome the UML’s weaknesses and to develop a tool (indeed a proof of concepts) for validating decisions made by designers.

Figure 1 summarizes the Constantine architecture that we have used as a guideline throughout the STEPS project, especially in the second half of the project.

The Constantine Validator module is in charge of assessing the correctness of data against a set of constraints; only when data are consistent with the constraints, they can be stored into the centralized DB. To accomplish its job, the Validator exploits the constraints provided on one side by the annotated UML schema (defined by a knowledge engineer), and on the other side by the designer. In section 5.5 we will specify the characteristics of these two types of users, the designer and the knowledge engineer, and in which way the constraints they define are different. The data to be validated are provided by the designer. If during the validation process no violation is detected, Constantine allows the store of the data into the DB; otherwise, Constantine provides the designer with a report containing all the violations that have been detected. The designer is therefore in charge of adjusting the data baseline according to the suggestions provided with the report.

In the rest of the document we will focus on the characterization of the constraints to be used during the validation process, and on the issues we have faced to implement them. In particular, we will explain why we have adopted OCL to annotate in a formal way the UML schema, and how we have implemented them.

(8)

Figure 1 The Constantine Architecture

4.

OBJECT CONSTRAINT LANGUAGE (OCL)

The first problem faced by UNITO was to fill the gaps in the expressive power of UML. A practical way to solve this problem was to manually annotate the UML schema of the conceptual model in order to give a guideline for subsequent the implementation phase. The problem with this solution is natural language annotations are not very effective: they can be ambiguous or misunderstood, moreover the implementation could accomplish them only partially (or ignore them completely), but verifying the compliance of an implementation to the annotations of an UML schema is not easy.

An alternative solution to natural language annotations is OCL [RD 02]: a formal language designed to annotate UML schemas, and which allows the definition of constraints between classes and between their relations.

OCL is a pure specification language; therefore, an OCL expression is guaranteed to be without side effects. When an OCL expression is evaluated, it simply returns a value. It cannot change anything in the model. This means that the state of the system will never change because of the evaluation of an OCL expression, even though an OCL expression can be used to specify a state change (e.g., in a post-condition).

OCL is not a programming language; therefore, it is not possible to write program logic or flow control in OCL. It is not possible to invoke processes or activate non-query operations within OCL. Because OCL is substantially a modeling language, OCL expressions are not by definition directly executable.

(9)

The evaluation of an OCL expression is instantaneous. This means that the states of objects in a model cannot change during evaluation.

OCL can be used for a number of different purposes: - as a query language,

- to specify invariants on classes and types in the class model, - to specify type invariant for Stereotypes,

- to describe pre- and post conditions on Operations and Methods, - to describe Guards,

- to specify target (sets) for messages and actions, - to specify constraints on operations, and

- to specify derivation rules for attributes for any expression over a UML model.

5.

CONSTRAINT TYPES

Once selected the language to be used for annotating constraints on the UML schema, the next problem to be faced is about the types of constraints that are relevant for our purpose.

Since in WP1D.3 the conceptual model represents the meta-model of engineering data, and hence there are neither “actors” nor “actions”, UNITO has mainly employed OCL to specify invariants on classes and in particular between the relations of classes.

Invariant conditions are a special case of constraints which specifies conditions which must always hold during lifecycle of a run of the system.

A first important result obtained by UNITO, in cooperation with TAS-I, is the categorization of the meta-model constraints into four types:

1. Concept level constraints 2. Property level constraints 3. Category level constraints 4. Property2Property constraints

In the following we will discuss each of them and provide some insights on how these constraints can be encoded in OCL. To better understand the OCL code it is necessary to consider Figure 2 showing the meta-model view for the topological design as it has been defined in [RD 01].

(10)

Figure 2 Meta-model view for the topological design.

5.1

Concept level constraints

These constraints are intended to complement the UML’s expressive power by specifying those relations which cannot be modeled through the class diagram formalism. The idea is to use this type of constraints to refine the UML schema and provide a better representation of the reality.

Example 1

ElementOccurrence shall have one and only one of the following relations: “rootElement”, “usage”

(11)

context ElementOccurrence

inv elementOccurrenceConsistency:

(self.rootElement->size()=0 implies self.usage->size()=1) or (self.rootElement->size()=1 implies self.usage->size()=0)

It is apparent that an OCL constraint can be easily read. The basic intent of OCL, in fact, is to be a common language that customers and designers can adopt to exchange ideas and formalize requirements. The semantic of OCL is quite intuitive and relies on the concept of navigation through the classes.

Let us have a look closer to the constraint. The reserved word context it is used to indicate the starting point of the constraint. In this example, the constraint is about the ElementOccurrence class. The statement inv denotes the constraint type; i.e., an invariant condition that must always be satisfied; the following string elementOccurrenceConsistency is optional and represents the constraint name. After this preamble, it follows the constraints body:

(self.rootElement->size()=0 implies self.usage->size()=1) or (self.rootElement->size()=1 implies self.usage->size()=0)

self is another reserved word and denotes the current class; i.e., ElementOccurrence; self is therefore a

shortcut to denote the starting point; from self it is possible to start the surf of the relations the class ElementOccurrence is associated with. For instance, self.usage means follows the usage relation. OCL provides the knowledge engineer with a number of aggregating functions such as sum, count, size and so on. In particular, the function sum, when applied to a relation, computes the number of times with which that relation is instantiated in a given instance of ElementOccurrence. Thus, since we want to create a mutual exclusion relation between rootElement and usage, it is sufficient to state that whenever rootElement is not instanced, then usage must be instanced (self.rootElement->size()=0 implies self.usage->size()=1) or vice versa (self.rootElement->size()=1 implies self.usage->size()=0).

Example 2

An ElementDefinition has either interfaces which do not require interfaces ends, or interfaces defined by at least two interface-ends. context ElementDefinition inv interfaceEndDefinitionConsistency: (self.containedInterfaces.interfaceType.realizedBy->size()=0)or (self.containedInterfaces.interfaceType.realizedBy->size()>=2 and self.containedInterfaces.interfaceType.realizedBy-> includesAll(self.externalInterfaceEnds) )

This constraint is slightly more complex than the previous one. Just to establish whether an ElementDefinition has interfaces without interface-ends it is necessary to navigate from ElementDefinition to InterfaceUsage through the relation containedInterfaces, from InterfaceUsage to InterfaceDefinition through the relation interfaceType, and finally from InterfaceDefinition to InterfaceEndDefinitions; only at this point it is possible to count the number of instantiations of relation realizedBy. In case such a number is zero, the constraint is trivially satisfied. If the result is one, there is no way to satisfy the constraints. Otherwise, if the number of instantiations is equal of greater than 2, than it must be verified that all the interfaces of the ElementDefinition at hand (self.externalInterfaceEnds) are included in the subset of realizations individuated by self.containedInterfaces.interfaceType.realizedBy.

(12)

5.2

Property level constraints

These constraints are intended to verify the values assigned to (a subset of) properties in the input baseline. For example, the min and max values for basic properties (e.g., mass>0); or containment constraints which relate the value of a property in a container item C with the values of properties in the items that are contained in C (e.g. through the relations existing between ElementDefinition and ElementUsage, or ElementOccurrences).

To better understand this kind of constraints it is necessary to consider the portions of conceptual model given in Figure 3 and Figure 4 from [RD 01].

(13)

Figure 4 Meta-model: abstraction of the topological view.

Example 3

The value of property ‘mass’ must always be positive.

context VpValue

inv: self.valueProperty.name='Mass' implies self.value>0

This constraint is very simple and does not require specific comments.

A similar constraint can be defined by exploiting the unit of measurement, making it much more general

context TopologicalDesign

inv: self.properties.select(v | v.unit='Kg')->size()>0

We use the class TopologicalDesign which is a generalization of all the topological classes in Figure 2; in this way the constraint holds for all of them. Since there is not an explicit reference to the mass property, the constraint holds for any property whose unit of measurement is Kg.

Example 4

The mass of an object is at least as big as the sum of the masses of the contained objects.

context ElementDefinition

(14)

The constraint is satisfied either when a topological class has not the property mass, or when the value of this property is greater the sum of the masses of the contained elements. To determine such a sum the constraints first collects all the properties of the contained elements (self.containedElements.properties.) then select the property whose name is ‘Mass’ (.select(h|h.valueProperty.name='Mass').value) and finally calculates the sum of these values.

5.3

Category level constraints

Constraints related to TypicalProperty of Categories which impose limits on values for properties/parameters only if associated to a specific category.

Example 5

If an ElementDefinition is associated with the “fourWheeledLocSystem” category then the “numberOfWheels” property shall have a value equals to 4.

context ElementDefinition

inv: self.category.unique_id='fourWheeledLocSystem' implies

self.properties.(select(h|h.valueProperty.name='numberOfWheels')).value->size()=1 and

self.properties.(select(h|h.valueProperty.name='numberOfWheels')).value->sum()=4 and self.category.typicalParameter.name='numberOfWheels'

This constraint verifies whether any instance of ElementDefinition which has the category fourWheeledLocSystem has a property named numberOfWheel whose value is four.

5.4

Property2Property constraints

This kind of constraints define relations between specific values/parameters of different items, imposed at design stage (e.g. preliminary evaluations).

Example 6

The mass of the WaterTank must be at least the mass of the estimated water load H2O multiplied by 0.02; mass(WaterTank)>= mass(H2O)*0.02

context ElementDefinition inv:

self.name =’WaterTank’ implies

self.properties.valueProperty.name='Mass'->size()>0 and

self.properties.select(v | v.valueProperty.name='Mass').value->sum()>=

self.containedElements.select(h|h.name=’H2O’).valueProperty.name=’Mass’.value->sum()*0.02

This constraint imposes that whenever an ElementDefinition has name WaterTank, then it must have a property named ‘Mass’, whose value is equal or greater than the mass of another ElementDefinition, named H2O and contained in WaterTank, multiplied by 0.02.

(15)

It is important to note that OCL has not been devised to make computations, but just to verify whether certain conditions hold or not. For instance, if the previous constraint is assessed when the mass property of H2O has been set whereas the mass property of instance WaterTank has not assigned yet, the constraint cannot be used to infer the a possible value for the mass property of WaterTank, and in this particular situation the constraint would be violated.

5.5

General and Project-level Constraints

The previous list of constraint types is useful to denote the “language” that Constantine must be able to speak. In fact, we are interested to develop a tool for the validation of a baseline of data against a set of constraints, but constraints must have the form discussed above.

Besides such a categorization of constraints, it is also important to note that not all the constraints are at the same level. There are in fact constraint whose validity is general; they are meaningful in any projects. There are other constraints which are meaningful for just a specific project. For instance, a project requirement could be encoded as a constraint in order to guarantee its accomplishment.

This distinction between general and project-level constraints is orthogonal with respect to the categorization given so far. However, we can say that concept-level constraints are typically general constraints as they are used to refine the UML; so their validity is not limited to a specific project. Conversely, property2property-level constraints are typically project-level constraints as they are defined to specify requirements that the specific project at hand has to satisfy. Finally, property and category-level constraints may either be general or project-level constraints. The distinction between general and project-level constraints is useful to determine when a given constraint can be defined and from whom. In fact, it is reasonable to assume that general constraints, used to make the UML schema more complete, can only be defined by a knowledge engineer who has a precise knowledge both of the data model and of OCL. Since these constraints have a general validity they should hidden to the users of the data (i.e., the designers), who should not be able to disable or modify them.

Differently, project-level constraints are specific to a project, so they should be added during the design process as in principle they encode project requirements. During the design process, an designer may need to disable some project-level constraints, or to slightly change them in order to assess alternative solutions.

It follows that an important requisite of Constantine is the ability to protect general constraints while allowing the generation of project-level constraints during the design process. In the following section we will provide some insight about the implementation of Constantine, highlighting the challenges that have been faced and the problems that still remain open.

6.

IMPLEMENTATION

6.1

Transforming OCL annotations into running code

So far we have described the types of constraints that Constantine must be able to deal with. However, an OCL constraint is still an annotation of the UML schema. How can we translate these annotations into a piece of code to be used at runtime?

We have examined different tools that operate such a translation: - Octopus

- Dresden OCL Toolkit - Eclipse-OCL

(16)

produces java code which can be edited and modified by a programmer. In particular, DOCL produces Aspect-Oriented code and, as we will discuss later on, this is another advantage of the tool.

Since DOCL produces java code, java has also been selected as programming language for Constantine. Moreover, DOCL is provided as a plug-in of the Eclipse IDE, so Eclipse has been chosen as development platform. Eclipse was an advantageous choice also because it offers the programmer many tools for managing UML schemas. In particular, the programmer can draw a class diagram and Eclipse will automatically generate the corresponding java code: for each class in the diagram a corresponding java class is generated. Eclipse was therefore an appealing development platform in any case.

As said above, DOCL produces Aspect-Oriented java code, AspectJ for short. AspectJ is an implementation of aspect-oriented programming (AOP), a new methodology that specifically targeted the management of crosscutting

concerns. The crosscutting concerns that are common to many of the applications’ core modules involve features

such as logging, checking, remote management, and path optimization.

AOP is a new methodology that provides separation of crosscutting concerns by introducing a new unit of modularization—an aspect—that crosscuts other modules. With AOP you implement crosscutting concerns in aspects instead of fusing them in the core modules. An aspect weaver, which is a compiler-like entity, composes the final system by combining the core and crosscutting modules through a process called weaving. The result is that AOP modularizes the crosscutting concerns in a clear-cut fashion, yielding a system architecture that is easier to design, implement, and maintain.

Thus the great advantage of using DOCL is that there is a clear distinction between the code implementing the OCL constraints and the core modules of Constantine. This means that even though the constraints can change over time, this is the case of project-level constraints, there is no need to change Constantine. In ANNEXE 1 we show an example of AspectJ code, in particular we the code represents the implementation of the constraint presented in Example 3 and stating that the mass property must always be greater than zero.

There are two fundamental points in an AspectJ code. The point cut, which indicates the subject of the aspect, and the trigger, which actually activates the AspectJ code. In the specific case reported in ANNEXE 1, we have that the point cut is about the property field of any instance of the class TopologicalDesign; while the trigger is denoted by the special word after; this means that as soon as a property of an instanced TopologicalDesign is changed (i.e., after the change), the AspectJ code is triggered and verifies whether the new property corresponds to a negative mass. If this is the case, the OCL constraint has been violated and the violation is collected in order to be presented to the user; otherwise, the constraint is satisfied. It is important to note the AspectJ code is activated whenever the property field is changed, independently of the point in which the change happens.

AspectJ code is very efficient, but it has some limitations too. One of the biggest limitations is that AspectJ is always completely instanced code. That is, an aspect is not class, but it is always an instance. This means that when we define two constraints such as ‘mass always positive’ and ‘length always positive’, even though there are very similar, we cannot exploit a single aspect and instantiate the aspect once for mass and once for length. Indeed, we have to create two instanced aspects, one explicitly mentioning mass, and one mentioning length. This peculiarity arises some issues especially to manage the project-level constraints which can be defined dynamically.

The problem with the project-level constraints is that they are defined by designers, who are experts in specific disciplines, but they are neither OCL experts, nor they have a complete vision of the conceptual organization of data. Indeed, it is not requested that designers know the internal organization of data, and to prevent any data corruption, it would be better to forbid the designer to access to the UML schema. This means that they cannot annotate the UML schema with OCL constraints and run DOCL to generate AspectJ code. In fact, only the knowledge engineer is requested to be an OCL expert and to have a perfect knowledge of the UML schema. Only the knowledge engineer can therefore directly invoke DOCL to generate AspectJ code.

Thus we have found a different way to allow a designer to assert constraints. In particular we have developed a GUI (see Figure 1) through which a designer can define a constraint. Since we have already classified the

(17)

constraint types, we have developed for each constraint type a simple “wizard” which drives the designer in the constraint definition process.

For instance, Figure 5 shows the wizard that has been implemented for the definition of a Property-level constraint; in this particular case for constraining the range of values assumed by the Mass property. The designer has to define the constraint name (point 1), the lower and upper bound of the property range (points 2 and 4). Another example of wizard for specifying a dependency between the property of an object-container and another property of the contained objects is showed in Figure 6.

Figure 5 The wizard for the definition of a Property-level Constraint

Figure 6 Another wizard for the definition of a Property-level Constraint

The wizards are therefore used to help the designers in specifying high-level constraints. However these constraints have be realized as AspectJ code. How can AspectJ code be generated?

To solve this problem we have investigated two alternative solutions. The first solution consists in translating the constraint introduced by the user into an OCL constraint and then invoking DOCL to create the corresponding

(18)

For these reasons we have adopted a different solution based on AspectJ templates. In short, for each wizard we have implemented, we have also realized a corresponding AspectJ template, which is an incomplete AspectJ code. Once the user defines a constraint through a wizard, the associated AspectJ template is selected, completed with the information provided by the user, and finalized into a new AspectJ code completely defined. In ANNEXE 2 an example of AspectJ template is reported; the example highlights the labels used as placeholders that will be replaced when the template is “instantiated” into a complete AspectJ code.

7.

VALIDATING A BASELINE AND PRODUCING A REPORT

Now we are in the position for discussing how the validation process is actually accomplished. It is important to observe that, since the java aspects are like listeners a change in the data structures occurs, they play a central role in the validation process; in fact, the java aspects are responsible for the detection of any constraint violations. The Constantine validator therefore consists of two main elements: the set AspectJ code implementing the constraints, and a Data Structure Manager. This last module is in charge of parsing an XML file containing a database baseline, and organizing the data into appropriate structures, which actually reflects the organization of data given in the conceptual data-model. During this process, the Data Structure Manager modifies the structures monitored by the AspectJ code. Thus every change activate an appropriate java aspect which verifies whether the change is correct or not. As discussed above, in case of a detected violation, the aspect generates an annotation (see the example in ANNEXE 1), which is maintained by the Data Structure Manager in a list of annotations. At the end of the parsing process, the Data Structure Manager checks whether the list of annotations is empty or not. If the list is empty, the baseline has been validated and can be stored into the DB. Otherwise, the baseline has not passed the consistency check, and a report is returned to the sender of the baseline.

We have used XML to encode the report, this choice is motivated by the fact that the sender of a baseline could not only be a human being, but also an applicative program and hence a report consisting of a non-formatted text could represent an issue. It follows an example of XML code reporting the detection of a constraint violation.

<violation>

<violation_id>VIOL17</violation_id>

<description>name: PLR MotorWheel id: ed_5 Mass: -35.0 out of range: [0.0, unbounded]

</description>

<violated_constraint>POS_MASS</violated_constraint>

<threatened_engineering_data_item>ed_5</threatened_engineering_data_item> <threatened_value_property>vp_1</threatened_value_property>

</violation>

The field violation_id is just an identification of the violation automatically generated by the AspectJ. The field

description is brief summary about the violation that has been detected; it reports the name of the engineering

data item that is inconsistent, it’s id, and the property which is the cause of the violation, in this case a negative mass has been found. The field description could be used to generate a sort of explanation for a human, in fact, it is possible to explain that PLR_MotorWheel is inconsistent since its mass (-35.0) is out the range of expected values ([0.0, unbounded]).

The other fields in the violation tag are conceived to be used by a piece of software. In fact, they are identifier, respectively, for: the constraint that has been violated, the engineering data item which is responsible of the violation, and the value property which cause the violation.

By means of the pieces of information included into such a kind of report, the sender of the baseline can understand why the baseline is not consistent with respect to the constraints, and how it can correct the baseline. Of course, when more engineers work together on the same project, and when each of the is an expert of a specific discipline, it may be possible that the decisions taken by an engineer could be in conflict with the decisions taken by another engineer. The advantage of Constantine is that it has a global view of the project so it can detect harmful interactions among the decisions made at different steps of the design process and by different engineers. However, the solution of these conflicts is out the scope of Constantine. To solve a conflict, in fact, two or more

(19)

engineers may need to revise their own decisions, and possibly, some project requirements may need to be revised too.

8.

CONCLUSIONS

The work done by UNITO within the WP1D.3 has obtained different results, and Constantine is one of the most important. The experience we have gained for the implementation of Constantine have taught us what are the potentialities and limitations of OCL.

On the one side, OCL is a useful formalism that operates directly on the UML schema, this means that at the conceptual level one can have both the definition of classes and the constraints between them. On the other side, however, it is still a too high-level formalism, so its expressiveness, though very powerful, is not sufficient yet to deal with all the aspects that are involved in the design of a complex artifact. For instance, OCL can just deal with scalar values, such as string, integer, or real values, but it cannot deal with matrices. Since some of the engineering data are actually matrices or arrays, it follows that some important constraints cannot directly be defined in OCL.

Of course, constraints and control mechanisms dealing with complex data structures could always be implemented in a specific programming language, but in this way the conceptual model of the data would be incomplete, and the knowledge about the organization of data and constraints among them would be sparse in part inside the UML schema and in part in pieces of code. Such a situation should be avoided as far as possible since it makes very difficult to have a clear vision of the data model; moreover, any change to the data model would require to reconsider the implemented control mechanisms.

As a final remark, it is important to say that Constantine is just a proof of concepts. Namely, we have used Constantine as a way to prove the effectiveness of OCL in filling the gaps of the UML formalism. The current implementation, however, is still not complete and can be improved in different ways. First of all, only the concept-level and property-concept-level constraints have been actually considered. The management of the other two types of constraints is not very different, but due to time and budget limits, it has not been implemented.

Moreover, it would be possible to use Constantine to define discipline-specific constraints that can be exported and used in different projects. This would improve the reuse of knowledge and could reduce the design time as engineers could exploit the experiences that other engineers have gained in previous projects. The current implementation already allows the export of the user-defined constraints as XML files, but a precise definition of what can (or cannot) be included into such a kind of exported material is still to be discussed.

(20)

APPENDICES : ANNEXE 1

An example of AspectJ code implementing the OCL constraint in Example 3.

package stepsmodel.categories.constraints; import steps.core.constraints.Annotation; /**

* <p>Generated Aspect to enforce OCL constraint.</p> *

* @author OCL22Java of Dresden OCL2 for Eclipse * @Generated

*/

public privileged aspect POS_MASS {

/**

* <p>Pointcut for all changes of the attribute {@link stepsmodel.topological.TopologicalDesign#properties}.</p> */

protected pointcut propertiesSetter(stepsmodel.topological.TopologicalDesign aClass) : set(* stepsmodel.topological.TopologicalDesign.properties) && this(aClass);

private void setAnnotation(stepsmodel.categories.impl.EngineeringDataItemImpl aClass, double vfloat, String vpid){ Annotation annotate = new Annotation("POS_MASS","****************************"+

"\nViolated Constraint: POS_MASS \n\tcontext EngineeringDataItem\n"+

"inv: self.properties.select(v | v.valueProperty.name='Mass').value->sum()> 0.0 and\n" + "\tself.properties.select(v | v.valueProperty.name='Mass').value->sum()< unbounded"+

"\nout of range: [0.0, unbounded]\n" +

"name: " + aClass.getName()+ " id: "+ aClass.getUniqueId() +

" Mass: " + vfloat + "\n****************************\n"); aClass.addAnnotation(annotate); annotate.setConstraintName("POS_MASS"); annotate.setThreatenedEngineeringDataItem(aClass.getUniqueId()); annotate.setThreatenedValueProperty(vpid); annotate.setViolatedConstraint("POS_MASS"); annotate.setDescrition(

"name: " + aClass.getName()+ " id: "+ aClass.getUniqueId() +

" Mass: " + vfloat +

"\nout of range: [0.0, unbounded]\n");

annotate.setOCLView(

"context EngineeringDataItem\n"+

"\t inv: self.properties.select(v | v.valueProperty.name='Mass').value->sum()> 0.0 and\n" + "\t self.properties.select(v | v.valueProperty.name='Mass').value->sum()< unbounded"

);

} /**

* <p><code>Checks an invariant on the class TopologicalDesign defined by the constraint * <code>context EngineeringDataItem

* inv: self.properties.select(v | v.valueProperty.name='Mass').value->sum()> 0.0 and

self.properties.select(v | v.valueProperty.name='Mass').value->sum()< unbounded </code></p> */

after(stepsmodel.categories.impl.EngineeringDataItemImpl aClass) : otherSetter(aClass) { if (!active) return;

java.util.ArrayList<stepsmodel.categories.VpValue> result2; result2 = new java.util.ArrayList<stepsmodel.categories.VpValue>();

String vpid = "";

for (stepsmodel.categories.VpValue v : aClass.getProperties()) { if (v.getValueProperty().getName().equals("Mass")) { result2.add(v); vpid = v.getValueProperty().getUniqueId(); } } java.util.ArrayList<Float> result1; result1 = new java.util.ArrayList<Float>();

for (stepsmodel.categories.VpValue $implicitCollect0$ : result2) { result1.add((float)$implicitCollect0$.getValue());

(21)

if (result1.size()>0){

double vfloat = (Double) tudresden.ocl20.pivot.tools.codegen.ocl2java.types.util.OclCollections.sum(result1); if (!((new Double(0.0).floatValue()) < vfloat)) {setAnnotation(aClass, vfloat, vpid);}//if 0.0

}//if(result1.size()>0)

} }//aspect

(22)

APPENDICES : ANNEXE 2

An example of AspectJ template.

public privileged aspect ASPECTNAME { /**

* <p>Describes all Constructors of the class {@link stepsmodel.topological.TopologicalDesign}.</p> */

protected pointcut allTopologicalDesignConstructors(stepsmodel.topological.TopologicalDesign aClass): execution(stepsmodel.topological.impl.TopologicalDesignImpl.new(..)) && this(aClass);

/**

* <p>Pointcut for all changes of the attribute {@link stepsmodel.topological.TopologicalDesign#properties}.</p> */

protected pointcut propertiesSetter(stepsmodel.topological.TopologicalDesign aClass) : set(* stepsmodel.topological.TopologicalDesign.properties) && this(aClass);

private void setAnnotation(stepsmodel.categories.impl.EngineeringDataItemImpl aClass, double vfloat, String vpid){ //if (!fired)

Annotation annotate = new Annotation("ASPECTNAME","****************************"+ "\nViolated Constraint: ASPECTNAME \n\tcontext EngineeringDataItem\n"+

"inv: self.properties.select(v | v.valueProperty.name='VALUEPROPERTYNAME').value->sum()>

LOWLIMIT and\n" +

"\tself.properties.select(v | v.valueProperty.name='VALUEPROPERTYNAME').value->sum()<

HIGHLIMIT"+

"\nout of range: [LOWLIMIT, HIGHLIMIT]\n" +

"name: " + aClass.getName()+ " id: "+ aClass.getUniqueId() + " VALUEPROPERTYNAME: " + vfloat + "\n****************************\n"); aClass.addAnnotation(annotate); annotate.setConstraintName("ASPECTNAME"); annotate.setThreatenedEngineeringDataItem(aClass.getUniqueId()); annotate.setThreatenedValueProperty(vpid); annotate.setViolatedConstraint("ASPECTNAME"); annotate.setDescrition(

"name: " + aClass.getName()+ " id: "+ aClass.getUniqueId() + " VALUEPROPERTYNAME: " + vfloat +

"\nout of range: [LOWLIMIT, HIGHLIMIT]\n"); annotate.setOCLView(

"context EngineeringDataItem\n"+

"\t inv: self.properties.select(v | v.valueProperty.name='VALUEPROPERTYNAME').value->sum()> LOWLIMIT and\n" +

"\t self.properties.select(v | v.valueProperty.name='VALUEPROPERTYNAME').value->sum()< HIGHLIMIT" ); } /**

* <p><code>Checks an invariant on the class TopologicalDesign defined by the constraint * <code>context EngineeringDataItem

* inv: self.properties.select(v | v.valueProperty.name='VALUEPROPERTYNAME').value->sum()> LOWLIMIT and self.properties.select(v | v.valueProperty.name='VALUEPROPERTYNAME').value->sum()< HIGHLIMIT </code></p> */

after(stepsmodel.categories.impl.EngineeringDataItemImpl aClass) : otherSetter(aClass) { if (!active) return;

java.util.ArrayList<stepsmodel.categories.VpValue> result2; result2 = new java.util.ArrayList<stepsmodel.categories.VpValue>();

String vpid = "";

for (stepsmodel.categories.VpValue v : aClass.getProperties()) { if (v.getValueProperty().getName().equals("VALUEPROPERTYNAME")) { result2.add(v); vpid = v.getValueProperty().getUniqueId(); } // no else } java.util.ArrayList<Float> result1; result1 = new java.util.ArrayList<Float>();

for (stepsmodel.categories.VpValue $implicitCollect0$ : result2) { result1.add((float)$implicitCollect0$.getValue());

(23)

if (result1.size()>0){

double vfloat = (Double) tudresden.ocl20.pivot.tools.codegen.ocl2java.types.util.OclCollections.sum(result1); if (!((new Double(LOWLIMIT).floatValue()) LSIGN vfloat)) {setAnnotation(aClass, vfloat, vpid);} if (!(vfloat RSIGN new Double(HIGHLIMIT).floatValue())) {setAnnotation(aClass, vfloat, vpid);} }//if(result1.size()>0)

}

(24)

Riferimenti

Documenti correlati

In un bambino sopra i sei mesi di età con eterometria degli arti inferiori è d’obbligo indagare in prima istanza l’eventualità di una lussazione congenita dell’anca, ipotesi

nel 1223, poi, nell’atmosfera di ripristino della documentazione e della legalità at- tuatasi nel regno di Sicilia dopo la proclamazione delle costituzioni di capua da parte

This procedure involves repeated integra- tion of the set of differential equations (8.49) and then evaluating the objective function (8.48), a rather time-consuming operation. 5 2

There are three fundamental structures that are used for the algorithmic resolution of problems: selection, iterations and sequence (sequence of instructions) (the GOTO present in

language and online community targeted primarily at children... Scratch:

Loriano Storchi loriano@storchi.org http:://www.storchi.org/... FLOWCHART AND

Progetto di un nuovo sistema di controllo della sosta nella città di

[r]