Eclipse -- VII -- Introducción a UML con el Plugin UML2

Puede encontrar la versión original de este artículo en Inglés en:

http://dev.eclipse.org/

Prerequisitos

Para empezar a utilizar UML2 (y seguir el ejemplo de este artículo), debe tener instalados Eclipse 3.1, EMF 2.1, y UML2 1.1.

Introducción

Este artículo le llevará por los pasos básicos para crear modelos utilizando UML2. Utilizando un sencillo modelo (el modelo ExtendedPO2, sigilosamente 'tomado prestado' del libro EMF 'bible') como ejemplo, veremos todo lo nocesario para crear algunos de los elementos más comunes que componen un modelo. Por cada tipo de elemento, primero veremos su proceso de creación utilizando el editor UML y luego exploraremos como conseguir lo mismo utilizando código Java. Abajo puede ver el modelo ExtendedPO2:


Figura 1: Aspecto del Modelo ExtendedPO2

Empezando

Antes de empezar, necesitará crear un sencillo proyecto en su espacio de trabajo. Este proyecto servirá como contenedor para el modelo que vamos a crear utilizando el editor UML2. Sigua estos pasos para crear el proyecto para este artículo:

  1. Seleccione en el menú Window > Open Perspective > Other...
  2. Seleccione el botón de la perspectiva Resource y pulse el botón OK.
  3. Seleccione en el menú File > New > Project...
  4. Seleccione el asistente Project dentro de la categoria Simple y pulse el botón Next >.
  5. Introduzca un nombre de proyecto (por ejemplo "Getting Started with UML2") y pulse elbotón Finish.

En este punto su espacio de trabajo se debería paracer a esto:


Figura 2: Aspecto del espacio de trabajo tras crear el proyecto

Bien, esto debería ser suficiente para permitirnos empezar con el editor UML2. Ahora, para seguir con la aproximación programática de la creación de modelos, asumamos, que usted ha creado una clase (llamada, digamos GettingStartedWithUML2) en la que usted puede escribir algún código para construir nuestro modelo de ejemplo. Los fragmentos de código que mostraremos asumen que usted ha definido los siguientes métodos de utilidad para ofrecer al usuario información sobre el programa:

public static boolean DEBUG = true;

protected static void out(String output) {

    if (DEBUG) {
      System.out.println(output);
    }
}

protected static void err(String error) {
      System.err.println(error);
}
	

Se puede utilizar una bandera de depuración estática para activar o desactivar la salida de información por el stream de salida del sistema . Los errores siempre se imprimirán por el stream de error estándar del sistema .

Todo bien hasta ahora! En cada una de las siguientes secciones veremos como crear un tipo diferente de elemento UML2, empezando con los modelos.

Crear Modelos

En la raíz de todo modelo UML2 hay un elemento model. Contiene un conjunto (jerarquico) de elementos que juntos describen el sistema físico que está siendo modelado. Para crear un modelo utilizando el editor UML2, sigua estos pasos:

  1. Seleccione un proyecto en la vista del navegador (por ejemplo Getting Started with UML2) y seleccione el menú File > New > Other....
  2. Seleccione el asistente UML2 Model dentro de la categoría Example EMF Model Creation Wizards y pulse el botón Next >.
  3. Inntroduzca un nombre de fichero (por ejemplo ExtendedPO2.uml2 y pulse el botón Next >.
  4. Seleccione Model para el objeto modelo y pulse el botón Finish.
  5. Seleccione en el menú Window > Show View > Properties.
  6. Seleccione el elemento Model en el editor UML2.
  7. Introduzca un valor (por ejemplo epo2 para la propiedad Name en la vista Properties.

En este punto su espacio de trabajo se debería parecer a esto:


Figura 3: Aspecto del espacio de trabajo tras crear el modelo

Ahora veamos como realizar la misma tarea utilizando código Java. El siguiente fragmento de código muestra un método que programáticamente crea y devuelve un modelo con el nombre especificado.

    protected static Model createModel(String name) {
    Model model = UML2Factory.eINSTANCE.createModel();
    model.setName(name);

    out("Model '" + model.getQualifiedName() + "' created.");

    return model;
    }

Primero, le pedimos a la factoría de objetos UML2 que cree un modelo , y seleccionamos su nombre . Luego, sacamos la información para que el usuario sepa que el modelo se ha creado satisfactoriamente. Finalmente, devolvemos el modelo . Observará, si no lo ha echo ya, que todos los fragmentos de código de este artículo siguen este patrón: crear el elemento (y seleccionar algunas de sus propiedades), informar al usuario y retornar.

Todos los elementos con nombre (un modelo es un tipo de elemento con nombre) tienen un nombre "simple" y un nombre cualificado. El nombre cualificado es el nombre "simple" precedido con los nombres "simples" de todos los espacios de nombre de los contenidos en el elemento. Observe que el nombre cualificado de un elemento sólo está definido si todos los espacios de nombres que contiene tienen nombres "simples" que no están vacíos.

Bien, veamos este método en acción. Por ejemplo, podríamos crear un modello llamado epo2 de esta forma:

Model epo2Model = createModel("epo2");

Crear Paquetes

Un paquete es un espacio de nombres para sus miembros (elementos packageable), y podría contener otros paquetes. Un paquete puede importar miembros individuales de otros paquetes, o todos los miembros de otros paquetes. Para crear un paquete utilizando el editor UML2, siga estos pasos:

  1. Seleccione un paquete (por ejemplo Package foo) en el editor UML2.
  2. Pulse con el botón derecho y seleccione la opción New Child > Owned Member Package en el menú contextual.
  3. Introduzca un valor (por ejemplo "bar") para la propiedad Name en la vista Properties.

Realmente no necesitamos crear un paquete porque nuestro modelo de ejemplo no contiene ninguno, excepto por supuesto, el paquete raíz (es decir, el modelo). Esto es: 'un modelo es un tipo de paquete'.

Veamos como realizar la misma tarea utilizando código Java. El siguiente fragmento de código muestra un método que programáticamente crea y devuelve un paquete con el nombre especificado en un paquete anidado especificado:

    protected static org.eclipse.uml2.Package createPackage(org.eclipse.uml2.Package nestingPackage, String name) {
    org.eclipse.uml2.Package package_ = nestingPackage.createNestedPackage(name);
            out("Package '" + package_.getQualifiedName() + "' created.");
            return package_;
     }
 	

Aquí, en vez de pedirle a la factoría que cree un paquete por nosotros, hemos utilizado uno de los métodos del API UML2 .

En UML2, existe un método factoría de la forma create<feature name>(EClass) o create<feature name>() por cada característica que pueda contener otros elementos (es decir cada característica contenedora). Además, existen métodos de factoría más convenientes para los tipos que se crean más comunmente (como los paquetes). En este caso, el paquete tiene una característica (ownedMember) que puede contener elementos 'empaquetables', por eso podríamos obtener la clase Ecore del tipo del elemento 'empaquetable' que queremos crear (es decir, Package) desde el paquete Ecore de UML2. y pasarlo al método factoría createOwnedMember(EClass). En su lugar, utilizamos el método de factoría más conveniente createNestedPackage(String) que implícitamente crea un paquete y acepta el nombre de paquete deseado como argumento. Detrás de la escena, el paquete creará un paquete anidado, seleccionará su nombre, lanzará una notificación (con un tipo de evento igual a 0), y añadirá el paquete a la lista de miembros propietarios.

Bien, veamos este método en acción. Por ejemplo, podríamos crear un parquete llamado bar dentro del paquete foo de esta forma:

org.eclipse.uml2.Package barPackage = createPackage(fooPackage, "bar");

Crear Tipos Primitivos

Un tipo primitivo define un tipo de datos, sin ninguna subestructura importante. Los tipos primitivos usados en UML incluyen Boolean, Integer, UnlimitedNatural, y String. Para crear un tipo primitivo usando el editor UML2, siga estos pasos:

  1. Seleccione un paquete (por ejemplo Model epo2) en el editor the UML2.
  2. Pulse con el botón derecho y seleccione New Child > Owned Member Primitive Type en el menú contextual.
  3. Introduzca un valor (por ejemplo int en la propiedad Name en la vista Properties.

Cree el resto de tipos primitivos del modelo ExtendedPO2 utilizando el editor UML2.

En este punto, su espacio de trabajo se debería parecer a esto:


Figura 4: Aspecto del espacio de trabajo tras crear los tipos primitivos

Veamos cómo realizar la misma tarea utilizando código Java. El siguiente fragmento de código muestra un método que crea y devuelve programáticamente un tipo primitivo con el nombre especificado en el paquete especificado.

    protected static PrimitiveType createPrimitiveType(	org.eclipse.uml2.Package package_, String name) {
	    PrimitiveType primitiveType = (PrimitiveType) package_.createOwnedPrimitiveType(name);

        out("Primitive type '" + primitiveType.getQualifiedName() + "' created.");
	
        return primitiveType;
    }

Aquí hemos llamado al método factoría de conveniencia createOwnedPrimitiveType(String) para pedirle al paquete que cree un tipo primitivo con el nombre especificado como uno de su miembros.

Bien, veamos este método en acción. Por ejemplo, podríamos crear un tipo primitivo llamado int en el modelo epo2 de esta forma:

PrimitiveType intPrimitiveType = createPrimitiveType(epo2Model, "int");

Escriba el código para crear programáticamente el resto de los tipos primitivos del modelo ExtendedPO2.

Crear Enumeraciones

Una enumeración es tipo de datos cuyos ejemplares podrían ser de cualquiera de las enumeraciones literales definidas por el usuario. Para crear una enumeración utilizando el editor UML2, siga estos pasos:

  1. Seleccione un paquete (por ejemplo Model epo2) en el editor UML2.
  2. Pulse con el botón derecho y seleccione la opción New Child > Owned Member Enumeration en el menú contextual.
  3. Introduzca un valor (por ejemplo OrderStatus en la propiedad Name en la vista Properties.

En este punto, su espacio de trabajo se debería parecer a esto:


Figura 5: Aspecto del espacio de trabajo tras crear la enumeración

Veamos cómo realizar la misma tarea utilizando código Java. El siguiente fragmento de código muestra un método que crea y devuelve programáticamente una enumeración con el nombre especificado en el paquete especificado:

    protected static Enumeration createEnumeration(org.eclipse.uml2.Package package_, String name) {
    Enumeration enumeration = (Enumeration) package_.createOwnedEnumeraton(name);

        out("Enumeration '" + enumeration.getQualifiedName() + "' created.");

        return enumeration;
    }

Aquí hemos llamado al método factoría de conveniencia createOwnedEnumeration(String) para pedirle al paquete que cree una enumeración con el nombre especificado como uno de sus miembros.

Bien, veamos este método en acción. Por ejemplo, podríamos crear una enumeración llamada OrderStatus en el modelo eop2 de esta forma:

Enumeration orderStatusEnumeration = createEnumeration(epo2Model,"OrderStatus");

Crear Literales de Enumeraciones

Un literal de enumeración es un valor de dato definido por el usuario para una enumeración. Para crear un literal de enumeración utilizando el editor UML2, siga estos pasos:

  1. Seleccione una enumeración (por ejemplo Enumeration OrderStatus) en el editor UML2.
  2. Pulse con el botón derecho y seleccione la opción New Child > Enumeration Literal en el menú contextual.
  3. Introduzca un valor (por ejemplo Pending) para la propiedad Name en la vista Properties.

Cree el resto de literales de enumeración del modelo ExtendedPO2 utilizando el editor UML2.

En este punto, su espacio de trabajo se debería parecer a esto:


Figura 6: Aspecto del espacio de trabajo tras crear los literales de enumeración

Veamos cómo realizar la misma tarea utilizando código Java. El siguiente fragmento de código muestra un método que crea y devuelve programáticamente un literal de enumeración con el nombre especificado en el paquete especificado:

    protected static EnumerationLiteral createEnumerationLiteral(Enumeration enumeration, String name) {
    EnumerationLiteral enumerationLiteral = enumeration.createOwnedLiteral(name);

        out("Enumeration literal '" + enumerationLiteral.getQualifiedName()	+ "' created.");

        return enumerationLiteral;
    }
	

Aquí hemos llamado al método factoría de conveniencia createOwnedLiteral(String) para pedirle a la enumeración que cree un literal de enumeración con el nombre especificado como uno de sus literales.

Bien, veamos este método en acción. Por ejemplo podríamos crear un literal de enumeración llamado Pending en la enumeración OrderStatus, de esta forma:

createEnumerationLiteral(orderStatusEnumeration, "Pending");

Escriba el código para crear programáticamente el resto de literales de enumeración del modelo ExtendedPO2.

Crear Clases

Una clase ese un tipo de clasificador cuyas características son atributos (algunos de los cuales podrían representar los finales navegables de asociaciones) y operaciones. Para crear una clase utilizando el editor UML2, siga estos pasos:

  1. Seleccione un paquete (por ejemplo Model epo2) en el editor UML2.
  2. Pulse con el botón derecho y seleccione la opción New Child > Owned Member Class en el menú contextual.
  3. Introduzca un valor (por ejemplo Supplier para la propiedad Name en la vista Properties.

Cree el resto de clases del modelo ExtendedPO2 utilizando el editor UML2.

En este punto, su espacio de trabajo se debería parecer a esto:


Figura 7: Aspecto del espacio de trabajo tras crear las clases

Veamos cómo realizar la misma tarea utilizando código Java. El siguiente fragmento de código muestra un método que crea y devuelve programáticamente una clase con el nombre especificado en el paquete especificado:

    protected static org.eclipse.uml2.Class createClass(org.eclipse.uml2.Package package_, String name, boolean isAbstract) {
    org.eclipse.uml2.Class class_ = package_.createOwnedClass(name,	isAbstract);

        out("Class '" + class_.getQualifiedName() + "' created.");

       return class_;
    }

Aquí hemos llamado al método de factoría de conveniencia createOwnedClass(String, boolean) para pedirle al paquete que cree una clase con el nombre especificado como uno de sus miembros, y seleccione el atributo isAbstract de la clase basándose en el argumento boolean especificado.

Podría habrer observado que hemos puesto referencias completamente cualificadas para los interfaces de Package y Class. Esto es recomendable para que estos tipos no se confundan con java.lang.Class y java.lang.Package, que son importados explícitamente en Java.

Bien, veamos este método en acción. Por ejemplo podríamos crear una clase no-abstracta llamada Supplier en el modelo epo2 de esta forma:

org.eclipse.uml2.Class supplierClass = createClass(epo2Model,"Supplier", false);

Escriba el código para crear programáticamente el resto de las clases del modelo ExtendedPO2.

Crear Generalizaciones

Una generalización es una relación taxonómica entre una clasificador especifico y un clasificador más general donde cada ejemplar del clasificador especifico también es un ejemplar indirecto, y hereda las características, del clasificador general. Para crear una generalización utilizando el editor UML2, siga estos pasos:

  1. Seleccione un clasificador (por ejemplo Class USAddress) en el editor UML2).
  2. Pulse con el botón derecho y seleccione la opción New Child > Generalization en el menú contextual.
  3. Seleccione un valor (por ejemplo epo2::Address) para la propiedad General en la vista Properties.

Cree el resto de generalizaciones del modelo ExtendedPO2 utilizando el editor UML2.

En este punto, su espacio de trabajo se debería parecer a esto:


Figura 8: Aspecto del espacio de trabajo tras crear las generalizaciones

Veamos cómo realizar la misma tarea utilizando código Java. El siguiente fragmento de código muestra un método que crea y devuelve programáticamente una generalización con el nombre especificado en el paquete especificado:

    protected static Generalization createGeneralization(Classifier specificClassifier, Classifier generalClassifier) {
    Generalization generalization = specificClassifier.createGeneralization(generalClassifier);

        out("Generalization " + specificClassifier.getQualifiedName() + " ->> "
            + generalClassifier.getQualifiedName() + " created.");

        return generalization;
    }
	

Aquí hemos llamado a un método de factoría de conveniencia sobre el clasificador específico que crea una generalización como uno de sus hijos y selecciona el clasificador general con el argumento especificado.

Bien, veamos este método en acción. Por ejemplo, podríamos crear una generalización entre la clase específica USAddress y la clase general Address de esta forma:

createGeneralization(usAddressClass, addressClass);

Escriba el código para crear programáticamente el resto de las generalizaciones del modelo ExtendedPO2.

Crear Atributos

Cuando una propiedad pertenece a un clasificador representa un atributo; en este caso relaciona un ejemplar de un clasificador con un valor o conjunto de valores del tipo del atributo.

Entre los tipos de Classifier que pueden tener atributos en UML2 se incluyen Artifact, DataType, Interface, Signal, y StructuredClassifier (y sus subtipos).

Para crear un atributo utilizando el editor UML2, siga estos pasos:

  1. Seleccione un clasificador (por ejemplo, Class Supplier) en el editor UML2.
  2. Pulse con el botón derecho y seleccione la opción New Child > Owned Attribute Property en el menú contextual.
  3. Introduzca un valor (por ejemplo name para la propiedad Name en la vista Properties.
  4. Seleccione un valor (por ejemplo epo2::String) para la propiedad Type.
  5. Seleccione la propiedad (por ejemplo Property name) en el editor UML2.
  6. Pulse con el botón derecho y seleccione la opción New Child > Lower Value Literal Integer en el menú contextual.

Los valores inferior y superior para elementos múltiples (como las propiedades) están representados como valores de especificación (objetos de primera-clase) en UML 2.0. El valor por defecto para los límites inferior y superior es 1, a menos que exista un valor de especificación hijo, en cuyo caso se utiliza su valor. Observe que para ser tratado como un límite, el valor inferior debe ser un entero literal y el valor superior debe ser un natural ilimitado literal.

Cree el resto de atributos que faltan en el modelo ExtendedPO2 utilizando el editor EML2.

En este punto su espacio de trabajo se debería parecer a esto:


Figura 9: Aspecto del espacio de trabajo tras crear los atributos

Veamos como realizar la misma tarea utilizando código Java. El siguiente fragmento de código muestra un método que crea programáticamente en la clase específicada un atributo y lo devuelve con el límite superior, el límite inferior, el tipo y el nombre especificados:

    protected static Property createAttribute(org.eclipse.uml2.Class class_,
        String name, Type type, int lowerBound, int upperBound) {

    Property attribute = class_.createOwnedAttribute(name, type,
        lowerBound, upperBound);

        StringBuffer sb = new StringBuffer();

        sb.append("Attribute '");

        sb.append(attribute.getQualifiedName());

        sb.append("' : ");

        sb.append(type.getQualifiedName());

        sb.append(" [");
        sb.append(lowerBound);
        sb.append("..");
        sb.append(MultiplicityElement.UNLIMITED_UPPER_BOUND == upperBound
            ? "*"	: String.valueOf(upperBound));
        sb.append("]");

        sb.append(" created.");

        out(sb.toString());

        return attribute;
    }
	

Aquí hemos llamado al método de factoría de conveniencia createOwnedAttribute(String, Type, int, int) para pedirle a la clase que cree una propiedad como uno de sus propios atributos, seleccione el tipo del atributo al tipo especificado, y seleccione los límites inferior y superior del atributo (el método factoría crea un entero literal y un natural ilimitado literal, respectivamente, y selecciona sus valores con el valor entero especificado).

La constante MultiplicityElement.UNLIMITED_UPPER_BOUND representa el valor ilimitado para el límite superior (-1), y está en EMF.

Bien, veamos este método en acción. Por ejemplo, podríamos crear un atributo con multiplicidad 0...1 del tipo String llamado name en la clase Supplier de esta forma:

createAttribute(supplierClass, "name", stringPrimitiveType, 0, 1);

Escriba código para crear programáticamente el resto de atributos de las clases del modelo ExtendedPO2.

Crear Asociaciones

Una asociación especifica una relación semántica que puede ocurrir entre dos o más ejemplares con tipo; sus finales están representados por propiedades, cada una de las cuales está conectada al tipo del final. Cuando una propiedad pertenece a una asociación representa un final no-navegable de la asociación, en cuyo caso el tipo de la propiedad es el tipo de la asociación final.

La noción de navegabilidad de la asociación final se ha separado de la propiedad en la (prontamente) finalizada especificación UML 2.0, para que una propiedad que pertence a una asociación no sea necesariamente no-navegable como ocurre en UML2 2.0.

Para crear una asociación utilizando el editor UML2, siga estos pasos:

  1. Seleccione un paquete (por ejemplo Model epo2) en el editor UML2.
  2. Pulse con el botón derecho y seleccione la opción New Child > Owned Member Association en el menú contextual.
  3. Introduzca un valor (por ejemplo Supplier_orders para la propiedad Name en la vista Properties.
  4. Seleccione la asociación recién creada (Association Supplier_orders) en el editor UML2.
  5. Pulse con el botón derecho y seleccione la opción New Child > Property en el menú contextual.
  6. Seleccione un valor (por ejemplo epo2::Supplier) para la propiedad Type en la vista Properties.
  7. Seleccione una clase (por ejemplo Class Supplier) en el editor UML2.
  8. Pulse con el botón derecho y seleccione la opción New Child > Owned Attribute Property en el menú contextual.
  9. Seleccione un valor (por ejemplo, Composite) para la propiedad Aggregation en el vista Properties.
  10. Seleccione un valor (por ejemplo, epo2::Supplier_orders) para la propiedad Association.
  11. Introduzca un valor (por ejemplo orders) para la propiedad Name.
  12. Seleccione un valor (por ejemplo, epo2::PurchaseOrder) para la propiedad Type.
  13. Seleccione la propiedad (navegable) (por ejemplo Property orders) en el editor UML2.
  14. Pulse con el botón derecho y seleccione la opción New Child > Lower Value Literal Integer en el menú contextual.
  15. Seleccione la propiedad (navegable) (por ejemplo, Property orders) en el editor UML2.
  16. Pulse con el botón derecho y seleccione la opción New Child > Upper Value Literal Unlimited Natural en el menú contextual.
  17. Introduzca un valor (por ejemplo -1 para la propiedad Value en la vista Properties.

Cree el resto de asociaciones del modelo ExtendedPO2 utilizando el editor UML2.

En este punto su espacio de trabajo se debería parecer a esto:


Figura 10: Aspecto del espacio de trabajo tras crear las asociaciones

Veamos como realizar la misma tarea utilizando código Java. El siguiente fragmento de código muestra un método que crea programáticamente una asociación en la clase específicada y la devuelve con el límite superior, el límite inferior, los nombres de roles, los tipos de agregaciones, y las navegabilidades.

    protected static Association createAssociation(Type type1,
        boolean end1IsNavigable, AggregationKind end1Aggregation,
        String end1Name, int end1LowerBound, int end1UpperBound,
        Type type2, boolean end2IsNavigable,
        AggregationKind end2Aggregation, String end2Name,
        int end2LowerBound, int end2UpperBound) {

    Association association = type1.createAssociation(end1IsNavigable,
        end1Aggregation, end1Name, end1LowerBound, end1UpperBound, type2,
        end2IsNavigable, end2Aggregation, end2Name, end2LowerBound,
        end2UpperBound);

        StringBuffer sb = new StringBuffer();

        sb.append("Association ");

        if (null == end1Name || 0 == end1Name.length()) {
            sb.append('{');
            sb.append(type1.getQualifiedName());
            sb.append('}');
        } else {
            sb.append("'");
            sb.append(type1.getQualifiedName());
            sb.append(NamedElement.SEPARATOR);
            sb.append(end1Name);
            sb.append("'");
        }

        sb.append(" [");
        sb.append(end1LowerBound);
        sb.append("..");
        sb.append(MultiplicityElement.UNLIMITED_UPPER_BOUND == end1UpperBound
            ? "*" : String.valueOf(end1UpperBound));
        sb.append("] ");

        sb.append(end2IsNavigable ? '<' : '-');
        sb.append('-');
        sb.append(end1IsNavigable  ? '>' : '-');
        sb.append(' ');

        if (null == end2Name || 0 == end2Name.length()) {
            sb.append('{');
            sb.append(type2.getQualifiedName());
            sb.append('}');
        } else {
            sb.append("'");
            sb.append(type2.getQualifiedName());
            sb.append(NamedElement.SEPARATOR);
            sb.append(end2Name);
            sb.append("'");
        }

        sb.append(" [");
        sb.append(end2LowerBound);
        sb.append("..");
        sb.append(MultiplicityElement.UNLIMITED_UPPER_BOUND == end2UpperBound
            ? "*" : String.valueOf(end2UpperBound));
        sb.append("]");

        sb.append(" created.");

        out(sb.toString());

        return association;
    }
	

Aquí hemos llamado a un método de factoría de conveniencia sobre el primer tipo final que crea una asociación (y su final) entre él y otro tipo como uno de sus hermanos (es decir, como un hijo de su paquete) y con los límites inferior y superior, los nombres de roles, los tipos de agregaciones, y la navegabilidad especificados. Los propietarios de los finales de la asociación (propiedades) están basados en las navegabilidades especificadas (los finales navegables pertenecen a los tipos finales y los finales no navegables pertenecen a la asociación (hasta UML2 2.0).

La constante NamedElement.SEPARATOR representa el separador estándar (::) utilizado en los nombres cualificados.

Bien, veamos este método en acción. Por ejemplo, podríamos crear una composición unidireccional (composite association) entre las clases Supplier y PurchaseOrder del modelo epo2 de esta forma:

createAssociation(supplierClass, true, AggregationKind.COMPOSITE_LITERAL, 
    "orders", 0, MultiplicityElement.UNLIMITED_UPPER_BOUND, purchaseOrderClass,
    false, AggregationKind.NONE_LITERAL, "", 1, 1);

Escriba el código para crear programáticamente el resto de asociaciones del modelo ExtendedPO2.

Grabar el Modelo

Ahora que hemos empleado todo este tiempo en crear un modelo, será mejor que grabemos nuestro trabajo. Cuando se crea un modelo utilizando el asistente de modelo UML2, se crea un recurso por lo que lo único que tenemos que hacer es serializar los contenidos del modelo como un XML a nuestro fichero en disco (es decir a ExtendedPO2.uml2). Para grabar el modelo utilizando el editor UML2, siga estos pasos:

  1. Seleccione el menú File > Save.

Es así de simple. Programáticamente, tenemos que hacer un poco más de trabajo porque hasta ahora hemos ido creando nuestro modelo en el vacío, es decir sin ningún recurso contenedor. El siguiente fragmento de código muestra un método que graba un paquete específico a un recurso con una URI especificada.

    protected static void save(org.eclipse.uml2.Package package_, URI uri) {
    Resource resource = new ResourceSetImpl().createResource(uri);
    resource.getContents().add(package_);

        try {
        resource.save(null);
            out("Done.");
        } catch (IOException ioe) {
        err(ioe.getMessage());
        }
    }

Aquí hemos creado un conjunto de recursos y un recurso con la URI especificada, hemos añadido el paquete al contenido del recurso y hemos pedido al recurso que se grabe él mismo utilizando las opciones por defecto. Si ocurre una excepción, se lo notificamos al usuario mediante un método de utilidad.

Bien, veamos este método en acción. Por ejemplo, podríamos grabar el modelo epo2 a un recurso con la URI ExtendedPO2.uml2 (relativo a una URI pasada como argumento) de esta forma:

    save(epo2Model, URI.createURI(args[0]).appendSegment("ExtendedPO2").
        appendFileExtension(UML2Resource.FILE_EXTENSION));
	

La constante UML2Resource.FILE_EXTENSION representa la extensíón de fichero para los recursos UML2 (.uml2). Observe que el interface UML2Resource contiene varias constantes que podría encontrar muy útiles cuando trabaje con recursos UML2.

Conclusión

¡Felicidades! Si ha llegado hasta aquí habrá crea un sencillo modelo programáticamente y/o utilizando el editor UML2. Se podría haber dicho mucho más, pero el propósito de este artículo era sólo introducirle en el trabajo con UML2.

Para obtener más información sobre UML2, visite su home page o únase a los newsgroup.

Código Fuente

Para ejecutar el ejemplo o ver el código fuente de este artículo, descomprima el fichero uml2.articles_200508041102.zip en su directorio home de Eclipse e importe el plug-in com.ibm.uml2.articles en su espacio de trabajo como un proyecto binario con contenido enlazado (File > Import… > External Plug-ins and Fragments). Puede ejecutar la clase GettingStartedWithUML2 como una aplicación Java con un URI de fichero (por ejemplo "file:/home/juan/java/Getting Started with UML2") como un argumento de programa.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP