DCL Manual

DCL Manual

Ricardo Terra

Marco Túlio Valente

Luis Fernando Miranda

Federal University of Minas Gerais

September 19, 2012


Table of Contents

1. Introduction
1. Requirements
2. Installing DCL
3. Defining Modules
1. Specific Class
2. Package
3. Package and Subpackage
4. Inheritance
5. Regular Expression
6. Mixed
4. Architectural Constraints
1. Divergences
1. Kind of Constraints
2. Examples
1. Access
2. Declare
3. Handle
4. Create
5. Extend
6. Implement
7. Derive
8. Throw
9. Useannotation
10. Depend
2. Absences
1. Kind of Constraints
2. Examples
1. Extend
2. Implement
3. Derive
4. Throw
5. Useannotation

1. Introduction

    DCL (Dependency Constraint Language) is a declarative, statically checked domain-specific language that supports the definition of structural constraints between modules. The main purpose of the proposed language is to support the definition of constraints between modules, restricting the spectrum of dependencies that are allowed in object-oriented systems.

    1.1. Requirements

    To use DCL, you must have installed the IDE Eclipse. The plugin has primarily been tested with Eclipse 3.7 and should work with 3.x releases, but let us know if you have any problems.
    The plugin runs under Java 1.5/5.0, or newer.

2. Installing DCL

    To install DCL, please follow the steps below:

    1. In Eclipse, click on Help > Install New Software...
    2. Click Add....
    3. Enter the following:
      • Name: DCL
      • URL: http://aserg.labsoft.dcc.ufmg.br/dclsuite/update
      • and click OK.
    4. You should see Architecture Conformance Tools item under the field name.
      Click on the triangle next to it to make dclsuite visible in the tree.
    5. Click the checkbox next to it to select it, and click Next.
    6. After reviewing the items to be installed, go next.
    7. After accepting the license, finish.
    8. The plugin is not digitally signed. Go ahead and install it anyway.
    9. Click Restart Now to make Eclipse restart itself.
    10. Done. DCLsuite is now ready for use.

    The procedure above is also explained using this video.

3. Defining Modules

    Basically, a module is a set of classes.

    3.1. Specific Class

    It is possible to define a module with one or more specific classes.

    Example. Assume the following definitions:

      1: module Math: java.lang.Math
      2: module Exception: java.lang.RuntimeException, java.io.IOException

    In this example, module Math (line 1) includes only class java.lang.Math. In line 2, module Exception consists of classes java.lang.RuntimeException and java.io.IOException.

    3.2. Package

    The operator * selects all classes of a package.

    Example. Assume the following definition:

      1: module View: org.foo.view.*

    Module View contains all classes of package org.foo.view.

    3.3. Package and Subpackage

    It is also possible to define a module as having all classes in packages with the specified prefix.

    Example. Assume the following definition:

      1: module Model: org.foo.model.**

    Module Model includes all classes of package org.foo.model and its internal packages, such as org.foo.model.dao, org.foo.model.dao.impl, org.foo.model.dto, etc.

    3.4. Inheritance

    The operator + selects subtypes of a given type.

    Example. Assume the following definition:

      1: module Remote: java.rmi.UnicastRemoteObject+

    Module Remote denotes all subclasses of java.rmi.UnicastRemoteObject.

    3.5. Regular Expression

    The definition can be specified using a regular expression delimited by quotation marks.

    Example. Assume the following definition:

      1: module Frame: "org.foo.[a-zA-Z0-9/.]*Frame"

    Module Frame consists of all classes whose qualified name begins with org.foo. and ends with Frame.

    3.6. Mixed

    It is possible to combine definitions by using commas.

    Example. Assume the following definition:

      1: module DataStructure: org.foo.util.*, org.foo.view.Tree

    Module DataStructure includes all classes of package org.foo.util and class Tree of package org.foo.view.

4. Architectural Constraints

    4.1. Divergences

    A divergence occurs when a dependency that exists in the source code violates a particular constraint defined by the architect. For example, when developers create an instance of a class A (using the new operator) in a module that has not been defined as a factory for this type.

      4.1.1. Kinds of Constraints

      In order to capture divergences, DCL supports the definition of the following kinds of constraints between modules:

      only MA can-dep MA : Only classes of module MA can depend on types defined in module MB. The literal dep refers to dependency type, which can be either more generic (depend) or more specific (access, declare, create, extend, implement, throw, and useannotation). For example, the constraint only DAOFactory can-create DAO defines that only a factory class can create data access objects.

      MA can-dep-only MB: Classes of module MA can depend only on types defined in module MB. For example, the constraint Util can-depend-only Util, $java defines that utility classes can only depend on their own classes or Java API classes.

      MA cannot-dep MB: Classes of module MA cannot depend on types defined in module MB. For example, the constraint Facade cannot-handle DTO defines that facade classes cannot manipulate entity classes.

      4.1.2. Examples

        4.1.2.5. extend (using only can)
        A constraint in the form only MA can-extend MB indicates that only classes declared in module MA can extend classes declared in module MB.

        Example. Assume the following DCL constraints:

         1: module Servlets: org.foo.controller.servlets.*
         2: module BaseHttpServlet: javax.servlet.http.HttpServlet
         3: only Servlets can-extend BaseHttpServlet 

        In this example, module Servlets contains all classes from package org.foo.controller.servlets (line 1) and module BaseHttpServlet refers to the class javax.servlet.http.HttpServlet, which is the default Java class to handle requests and responses using the HTTP protocol (line 2). Then, in line 3, a restriction ensures that only classes from module Servlets are allowed to extend the class javax.servlet.http.HttpServlet. Otherwise, DCL will report an architectural violation (divergence).

    4.2. Absences

    An absence occurs when the source code does not establish a dependency that is prescribed by a particular constraint. For example, when classes of package P do not implement an interface I, as determined by the intended architecture of the system.

      4.2.1. Kinds of Constraints

      In order to capture absences, DCL supports the definition of the following constraints:

      MA must-dep MB: Classes of module MA must depend on types defined in module MB. For example, the constraint DTO must-implement java.io.Serializable defines that entity classes must implement Java’s serializable interface.

      4.2.2. Examples

        4.2.2.1. extend (using must)
        A constraint in the form MA must-extend MB indicates that all classes declared in module MA must extend a class declared in module MB.

        Example. Assume the following DCL constraints:

         1: module Servlets: org.foo.controller.servlets.*
         2: module BaseHttpServlet: javax.servlet.http.HttpServlet
         3: Servlets must-extend BaseHttpServlet

        In this example, module Servlets contains the classes of package org.foo.controller.servlets (line 1) and module BaseHttpServlet refers to class javax.servlet.http.HttpServlet, which is the standard class to handle requests and responses using HTTP protocol. Then, in line 3, a constraint requires that the classes of module Servlets extend the class javax.servlet.http.HttpServlet. Otherwise, DCL will report an architectural violation (absence).