#はじめに
前回UMLモデリングツールastah*(Community版)でプラグイン開発環境を試してみた(1)で、チュートリアルに従って、クラス数を表示するところまで進めました。
今回は、チュートリアルから外れて、クラスの種々の情報を取得してみたいと思います。
#やってみること
クラスの名前や属性、操作の詳細をコンソールに出力します。
個人的には、独自のコード出力をしてみたいので、それを念頭に進めます。
#準備
- 前回作成したプログラムファイル(CountClassAction.java)をコピーし、PrintClassAction.javaを作成。
- astahのメニューから呼び出す部分をCountClassActionからPrintClassActionに変更
前回同様に、プラグインプロジェクトのルートフォルダでビルドを実行。
前回のjavaファイルをコピーして、クラス名を変更して、ビルドし直しただけなので、
もちろん、実行しても同じ動きをしました。
#class名を取得して表示する
元のコードを、次のように書き換えました。選択されている行が変更後の箇所です。
変更前は、前回のコードと比較してください。すみません。
図1 元のサンプルコード
変更前のサンプルは、「全クラスリストのCount」をメッセージボックスに出していたのですが、
変更後は、全クラスリストをfor文で回してクラス名を出力、最後に「Finished」とメッセージボックスを出すようにしました。
再び、ビルドと、launchします。
いざ実行!
すんなり動きました。
でも、よく見ると、期待と違う動きをしています。
全クラスリストから、クラス名を表示しているのですが、途中途中に 「T」 という名前のクラスがあります。
左側の構造ツリーの「Comparable<T>
」の 「T」 が一つのクラスとして出てしまっているみたいです。
コードを読んでみたところ、getAllClasses()関数内のgetNestedClasses()が怪しそうです。
APIドキュメントで調べたところ、インナークラスなるものを取得するとのこと。
なので、NestedClassesの取得を下記のようにコメントアウトして、実行すると、
見事に、クラス名のリストを取得できました。
#クラス名以外の基本的な情報もすべて取得してみる
では、クラス名以外も表示してみます。
先ほどのコードを以下のように改造しました。以下は、ファイル全文です。
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();
}
}
全クラスのについて、名前や属性、操作、可視性などの情報を取得して表示しています。
実際の実行結果の画面キャプチャがこちら。
十分に情報が取得できています。
#さいごに
今回はここまでにしますが、
取得したものを表にまとめると、
<クラスの値> 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() |
以上のようで、なかなか、順調です。