Help us understand the problem. What is going on with this article?

UMLモデリングツールastah*(Community版)でプラグイン開発環境を試してみた(2)

More than 1 year has passed since last update.

はじめに

前回UMLモデリングツールastah*(Community版)でプラグイン開発環境を試してみた(1)で、チュートリアルに従って、クラス数を表示するところまで進めました。
今回は、チュートリアルから外れて、クラスの種々の情報を取得してみたいと思います。

やってみること

クラスの名前や属性、操作の詳細をコンソールに出力します。
個人的には、独自のコード出力をしてみたいので、それを念頭に進めます。

準備

  • 前回作成したプログラムファイル(CountClassAction.java)をコピーし、PrintClassAction.javaを作成。    image.png
  • astahのメニューから呼び出す部分をCountClassActionからPrintClassActionに変更 image.png

前回同様に、プラグインプロジェクトのルートフォルダでビルドを実行。
image.png

そして、同様に起動。
image.png

前回のjavaファイルをコピーして、クラス名を変更して、ビルドし直しただけなので、
もちろん、実行しても同じ動きをしました。

class名を取得して表示する

元のコードを、次のように書き換えました。選択されている行が変更後の箇所です。
変更前は、前回のコードと比較してください。すみません。
image.png
図1 元のサンプルコード

変更前のサンプルは、「全クラスリストのCount」をメッセージボックスに出していたのですが、
変更後は、全クラスリストをfor文で回してクラス名を出力、最後に「Finished」とメッセージボックスを出すようにしました。

再び、ビルドと、launchします。

いざ実行!
すんなり動きました。

image.png

でも、よく見ると、期待と違う動きをしています。
全クラスリストから、クラス名を表示しているのですが、途中途中に 「T」 という名前のクラスがあります。
左側の構造ツリーの「Comparable<T>」の 「T」 が一つのクラスとして出てしまっているみたいです。

コードを読んでみたところ、getAllClasses()関数内のgetNestedClasses()が怪しそうです。
APIドキュメントで調べたところ、インナークラスなるものを取得するとのこと。
なので、NestedClassesの取得を下記のようにコメントアウトして、実行すると、
image.png

見事に、クラス名のリストを取得できました。

image.png

クラス名以外の基本的な情報もすべて取得してみる

では、クラス名以外も表示してみます。
先ほどのコードを以下のように改造しました。以下は、ファイル全文です。

PrintClassAction.java
package com.azuki.actions;

import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import com.change_vision.jude.api.inf.AstahAPI;
import com.change_vision.jude.api.inf.exception.ProjectNotFoundException;
import com.change_vision.jude.api.inf.model.IClass;
import com.change_vision.jude.api.inf.model.IModel;
import com.change_vision.jude.api.inf.model.IAttribute;
import com.change_vision.jude.api.inf.model.IMultiplicityRange;
import com.change_vision.jude.api.inf.model.IOperation;
import com.change_vision.jude.api.inf.model.IGeneralization;
import com.change_vision.jude.api.inf.model.INamedElement;
import com.change_vision.jude.api.inf.model.ITemplateBinding;
import com.change_vision.jude.api.inf.model.IClassifierTemplateParameter;
import com.change_vision.jude.api.inf.model.IRealization;
import com.change_vision.jude.api.inf.model.IParameter;
import com.change_vision.jude.api.inf.model.IPackage;
import com.change_vision.jude.api.inf.project.ProjectAccessor;
import com.change_vision.jude.api.inf.ui.IPluginActionDelegate;
import com.change_vision.jude.api.inf.ui.IWindow;

public class PrintClassAction implements IPluginActionDelegate {
  public Object run(IWindow window) throws UnExpectedException {
    try {
      AstahAPI api = AstahAPI.getAstahAPI();
      ProjectAccessor projectAccessor = api.getProjectAccessor();
      IModel iCurrentProject = projectAccessor.getProject();
      List<IClass> classeList = new ArrayList<IClass>();
      getAllClasses(iCurrentProject, classeList);
      // changed code from here.
            for(IClass c : classeList){
                System.out.println("\n---CLASS---------------------------");
                System.out.println(getClassOption(c) + getClassTypeName(c) + getTemplateParameter(c) + ":" + getBaseClassName(c) + getInterfaceClassName(c));
                System.out.println("/*****************");
                System.out.println( getClassDefinition(c) );
                System.out.println("******************/");

                if( getClassIsActive(c) == true ){ System.out.println("IsActive"); }

                System.out.println("------ASSOCIATIONS-----------------");
                IAttribute[] assos = getAssociations(c);
                for( int i = 0; i < assos.length ; i++ ){
            System.out.println(getAssociation(assos[i]));
            }

                System.out.println("------ATTRIBUTES-------------------");
        IAttribute[] atts = getAttributes(c);
        for( int i = 0; i < atts.length ; i++ ){
            System.out.println(getAttribute(atts[i]));
            }

                System.out.println("------OPERATIONS-------------------");
        IOperation[] opes = c.getOperations();
        for( int i = 0; i < opes.length ; i++ ){
            System.out.println(getOperation(opes[i]));
        }
      }
      JOptionPane.showMessageDialog(window.getParent(),"Finished");
      // changed code to here.
    } catch (ProjectNotFoundException e) {
      String message = "Please open a project";
      JOptionPane.showMessageDialog(window.getParent(), message,
          "Warning", JOptionPane.WARNING_MESSAGE);
      throw new CalculateUnExpectedException();
    } catch (Exception e) {
      JOptionPane.showMessageDialog(window.getParent(),
          "Exception occured", "Alert", JOptionPane.ERROR_MESSAGE);
      throw new UnExpectedException();
    }
    return null;
  }

  public class CalculateUnExpectedException extends UnExpectedException {
  }

  private void getAllClasses(INamedElement element, List<IClass> classList)
      throws ClassNotFoundException, ProjectNotFoundException {
    if (element instanceof IPackage) {
      for(INamedElement ownedNamedElement : ((IPackage)element).getOwnedElements()) {
        getAllClasses(ownedNamedElement, classList);
      }
    } else if (element instanceof IClass) {
      classList.add((IClass)element);
    }
  }

    // My Methods

    private String getClassTypeName(IClass _class){
        return _class.getName();
    }

    private String getClassOption(IClass _class){
        StringBuilder buff = new StringBuilder();
        if( _class.isAbstract() == true ){ buff.append("abstract "); }
        if( _class.isPublicVisibility() == true ){ buff.append("public "); }
        if( _class.isPackageVisibility() == true ){ buff.append("internal "); }
        if( _class.isProtectedVisibility() == true ){ buff.append("C# class can not to be protected. "); }
        if( _class.isPrivateVisibility() == true ){ buff.append("C# class can not to be private. "); }
        return buff.toString();
    }

    private String getTemplateParameter(IClass _class){
        StringBuilder buff = new StringBuilder();
        IClassifierTemplateParameter[] ctemps = _class.getTemplateParameters();
        if( ctemps.length > 0 ){ buff.append("<"); }
        for( int i = 0; i < ctemps.length ; i++ ){
            buff.append(ctemps[i].getName());
            if( i < ctemps.length - 1 ){ buff.append(","); }
        }
        if( ctemps.length > 0 ){ buff.append(">"); }
        return buff.toString();
    }

    private boolean getClassIsActive(IClass _class){
        return _class.isActive();
    }

    private String getClassDefinition(IClass _class){
        return _class.getDefinition();
    }

    private String getBaseClassName(IClass _class){
        StringBuilder buff = new StringBuilder();
        IGeneralization[] gens = _class.getGeneralizations();
        for( int i = 0 ; i < gens.length ; i++ ){
            buff.append(gens[i].getSuperType().getName() + " ");
            if( i < gens.length-1 ){
                buff.append(" , ");
            }
        }
        return buff.toString();
    }

        private String getInterfaceClassName(IClass _class){
        StringBuilder buff = new StringBuilder();
        IRealization[] ifs = _class.getClientRealizations();
        for( int i = 0 ; i < ifs.length ; i++ ){
            buff.append(ifs[i].getSupplier().getName() + " ");
            if( i < ifs.length-1 ){
                buff.append(" , ");
            }
        }
        return buff.toString();
    }

    private IAttribute[] getAssociations(IClass _class){
        IAttribute[] atts = _class.getAttributes();
        int count = 0;
        for( int i = 0; i < atts.length ; i++ ){
            if( atts[i].getAssociation() != null ){
                count++;
            }
        }
        IAttribute data[] = new IAttribute[count];
        int add = 0;
        for( int i = 0; i < atts.length ; i++ ){
            if( atts[i].getAssociation() != null ){
                data[add++] = atts[i];
            }
        }
        return data;
    }

    private IAttribute[] getAttributes(IClass _class){
        IAttribute[] atts = _class.getAttributes();
        int count = 0;
        for( int i = 0; i < atts.length ; i++ ){
            if( atts[i].getAssociation() == null ){
                count++;
            }
        }
        IAttribute data[] = new IAttribute[count];
        int add = 0;
        for( int i = 0; i < atts.length ; i++ ){
            if( atts[i].getAssociation() == null ){
                data[add++] = atts[i];
            }
        }
        return data;
    }

    private String getAssociation(IAttribute _att){
        if( _att.getAssociation() != null ){
            StringBuilder buff = new StringBuilder();
            buff.append(getAttributeOption(_att));
            boolean isList = isList(_att);
            if( isList == true ){  buff.append("List<"); }
            buff.append(_att.getType() + " ");
            if( isList == true ){  buff.append("> "); }
            buff.append(_att.getName() + " ");
            buff.append(";");
            return buff.toString();
        }
        return "";
    }

    private String getAttribute(IAttribute _att){
        if( _att.getAssociation() == null ){
            StringBuilder buff = new StringBuilder();
            buff.append(getAttributeOption(_att));
            boolean isList = isList(_att);
            if( isList == true ){  buff.append("List<"); }
            buff.append(_att.getType() + " ");
            if( isList == true ){  buff.append("> "); }
            buff.append(_att.getName() + " ");
            buff.append(";");
            return buff.toString();
        }
        return "";
    }

    private boolean isList(IAttribute _att){
        boolean _list = false;
        IMultiplicityRange[] multis = _att.getMultiplicity();
        for( int i = 0; i < multis.length ; i++ ){ // fukusuu aru ?
            if( multis[i].getUpper() > 1 ){
                _list = true;
            }
        }
        return _list;
    }

    private String getAttributeOption(IAttribute _att){
        StringBuilder buff = new StringBuilder();
        if( _att.isStatic() == true ){ buff.append("static "); }
        if( _att.isPublicVisibility() == true ){ buff.append("public "); }
        if( _att.isPackageVisibility() == true ){ buff.append("internal "); }
        if( _att.isProtectedVisibility() == true ){ buff.append("protected "); }
        if( _att.isPrivateVisibility() == true ){ buff.append("private "); }
        return buff.toString();
    }

    public String getOperation(IOperation _ope){
        StringBuilder buff = new StringBuilder();
        buff.append(getOpearationOption(_ope));
        buff.append(_ope.getReturnTypeExpression() + " ");
        buff.append(_ope.getName() + "(" );
        buff.append(getOperationAttributes(_ope));
        buff.append("){\n" + _ope.getDefinition() + "\n}");
        return buff.toString();
    }

    private String getOpearationOption(IOperation _ope){
        StringBuilder buff = new StringBuilder();
        if( _ope.isStatic() == true ){ buff.append("static "); }
        if( _ope.isAbstract() == true ){ buff.append("abstract "); }
        if( _ope.isPublicVisibility() == true ){ buff.append("public "); }
        if( _ope.isPackageVisibility() == true ){ buff.append("internal "); }
        if( _ope.isProtectedVisibility() == true ){ buff.append("protected "); }
        if( _ope.isPrivateVisibility() == true ){ buff.append("private "); }
        return buff.toString();
    }

    private String getOperationAttributes(IOperation _ope){
        StringBuilder buff = new StringBuilder();
        IParameter[] params = _ope.getParameters();
        for( int i = 0; i < params.length; i++ ){
            if( params[i].getDirection().equals("out") == true ){ buff.append("out "); } else if( params[i].getDirection().equals("inout") == true ){ buff.append("ref "); }
            buff.append(params[i].getType().getName() + " ");
            buff.append(params[i].getName());
            if( i < params.length-1 ){
                buff.append(" , ");
            }
        }
        return buff.toString();
    }

}

全クラスのについて、名前や属性、操作、可視性などの情報を取得して表示しています。
実際の実行結果の画面キャプチャがこちら。

image.png

十分に情報が取得できています。

さいごに

今回はここまでにしますが、
取得したものを表にまとめると、

<クラスの値> IClass型

取得したい内容 取得メソッド
名前 getName()
可視性 isPublicVisibility(),isProtectedVisibility(), isPrivateVisibility(),isPackageVisibility()
抽象クラスか    isAbstract()
テンプレートの指定 getTemplateParameters()
アクティブクラスか isActive()
定義 getDefinition()
ベースクラス getGeneralizations()のgetSuperType().getName()
インタフェース getClientRealizations()のgetSupplier().getName()

<属性/関連の値> IAttribute型

取得したい内容 取得メソッド
名前 getName()
可視性 isPublicVisibility(),isProtectedVisibility(), isPrivateVisibility(),isPackageVisibility()
型    getType()
多重度 getMultiplicity()
初期値 getInitialValue()
集約かどうか isAggregate()
コンポジション isComposite()
派生しているか  isDerived()
限定子  getQualifiers()

<操作の値>

取得したい内容 取得メソッド
名前 getName()
可視性 isPublicVisibility(),isProtectedVisibility(), isPrivateVisibility(),isPackageVisibility()
戻り値の型 getReturnTypeExpression()
抽象クラスか    isAbstract()
引数の名前 getParameters()のgetName()
引数の型 getParameters()のgetType().getName()
操作の定義 getDefinition()

以上のようで、なかなか、順調です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした