### Navigation

- index
- next |
- previous |
- astah* Plug-in 開発チュートリアル v1.0 documentation »

# クラスの総数を表示するプラグインを作ってみましょう

単純なプラグインを作成しました。そのプラグインをベースに実践的なプラグインを作成してみましょう。設計されたモデルの品質を評価する指標の一つに、クラスの総数を利用することがあります。Hello Worldの代わりに、astah*モデル内のクラスの総数を表示するプラグインを変更してみましょう。

astah*モデル内のクラスの総数とは、下記のastah*モデルの場合は、3つです。

プラグインによって追加したメニューを押下すると､:

    「There are 3 classes」

と表示されるようにしてみましょう。

## モデル情報を取得してみましょう

astah*のモデル情報を取得するために、astah* APIを活用してみましょう。astah* APIとは、astah*のモデルデータを活用するアプリケーションを開発するためのJavaインターフェース群です。astah* APIの詳細については、本体に付属するastah* API利用ガイドを参照してください。

これから書くコードでは、ProjectAccessorから現在開いているastah*モデルのルートモデルを取得し、再帰的にすべてのクラスを取得します。それではクラスの総数をメッセージダイアログに表示するようにHelloWorldプラグインを修正してみましょう。

まず、CountClassActionクラスを作成しましょう。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    /*
     * パッケージ名は、生成したプラグインのパッケージ名よりも下に移してください。
     * プラグインのパッケージ名=> com.example
     *   com.change_vision.astah.extension.plugin => X
     *   com.example                              => O
     *   com.example.internal                     => O
     *   learning                                 => X
     */
    package com.example.actions;

    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.JOptionPane;
    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.INamedElement;
    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.project.ProjectAccessorFactory;
    import com.change_vision.jude.api.inf.ui.IPluginActionDelegate;
    import com.change_vision.jude.api.inf.ui.IWindow;

    public class CountClassAction implements IPluginActionDelegate {
        public Object run(IWindow window) throws UnExpectedException {
            try {
                ProjectAccessor projectAccessor = ProjectAccessorFactory.getProjectAccessor();
                IModel iCurrentProject = projectAccessor.getProject();
                List<IClass> classeList = new ArrayList<IClass>();
                getAllClasses(iCurrentProject, classeList);
                JOptionPane.showMessageDialog(window.getParent(),
                		"There are " + classeList.size() + " classes.");
            } 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);
                for(IClass nestedClasses : ((IClass)element).getNestedClasses()) {
                    getAllClasses(nestedClasses, classList);
                }
            }
        }
    }

次に､plugin.xmlファイルにCountClassActionクラスを使ったメニューに変更しましょう。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?xml version="1.0" encoding="UTF-8"?>
    <plugin>
      <extension point="com.change_vision.astah.ui.actionSets">
        <actionSet
            label="%action_set_label "
            visible="true"
            id="com.example.actions.actionSet1">
          <menu
            label="%sample_menu"
            id="sampleMenu"
            path="tool/sampleMenu">
          </menu>
          <action
            label="%count_classes"
            icon="icons/sample.gif"
            class="com.example.actions.CountClassAction"
            tooltip="Count classes"
            menubarPath="tool/sampleMenu/"
            id="com.example.actions.CountClassdAction">
          </action>
        </actionSet>
      </extension>
    </plugin>

最後に､plugin.propertiesに追加したメニューのラベルを追加します｡:

    count_classes=Count classes(C)

これで､クラスの数をカウント結果を表示できます。

## デバッグしてみましょう

ネストクラスのクラス1とパッケージ0以下のクラス2を、再帰的に取得できるかデバッグしながら、確認してみましょう。デバッグをするには次のコマンドを実行します。:

    > astah-debug

すると、44000ポートがリモートデバッグ用のポートとして開かれた状態で起動します。IDEなどからこのポートに接続し、リモートデバッグします。

### Eclipseを使ったリモートデバッグの例

Eclipseの場合は、下記のように設定します。

設定後､Debugボタンを押すとリモートデバッグが開始されます。適当な場所にブレークポイントを設定し､実行すると、デバッグが行われます。なお、リモートデバッグの詳細については、本書で扱う範囲外のため、割愛します。

### Navigation

- index
- next |
- previous |
- astah* Plug-in 開発チュートリアル v1.0 documentation »