ログイン
検索
メインメニュー
フォーラム一覧   -   トピック一覧
   astah*の使い方
     APIを用いてジェネリクスが含まれる型の属性を取得する方法について
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 トピック
mas061
投稿日時: 2014-1-28 22:17
新米
登録日: 2013-6-17
居住地:
投稿: 5
APIを用いてジェネリクスが含まれる型の属性を取得する方法について
APIを用いて、色々と試したりプラグインを作っています。
タイトルの件につきまして質問させてください。

現在、Javaコードから読み込んだastahモデルから、
APIを用いてモデル情報を取得しようとしています。
その中で、「List<Hoge>」のような型を持つ属性の型情報を取得する方法がわかりません。

ジェネリクスを用いない属性につきましては、IAttributeクラスの
getTypeから取得できています。
ジェネリクスの型情報を取得する方法を教えてください。

以上、よろしくお願いします。
midori
投稿日時: 2014-1-30 11:54
開発者
登録日: 2006-5-8
居住地: 福井
投稿: 312
Re: APIを用いてジェネリクスが含まれる型の属性を取得する方法について
mas061さん、APIのご利用、ありがとうございます。








「List<Hoge>」を型に持つ属性の場合も、IAttributeのgetType()で型を取得できます。以下のコードは、「List<Hoge>」のモデルを取得します。

IClass type = iAttribute.getType();


「List<Hoge>」という文字列を取得する場合は、IAttributeのgetTypeExpression()をご利用ください。

String typeExpression = iAttribute.getTypeExpression();
mas061
投稿日時: 2014-2-3 22:18
新米
登録日: 2013-6-17
居住地:
投稿: 5
Re: APIを用いてジェネリクスが含まれる型の属性を取得する方法について
midoriさん

お返事ありがとうございます。
無事、getTypeExpression()にて、目的の表現が取れました。

なお、getTypeで取得したIClasモデルからList<Hoge>表現にたどり着く方法はあるのでしょうか?
今回の目的にはgetTypeExpressionが最適でしたが、少し気になりました。
Sueyoshi
投稿日時: 2014-2-4 14:16
CVメンバ
登録日: 2013-8-27
居住地:
投稿: 76
Re: APIを用いてジェネリクスが含まれる型の属性を取得する方法について
現在公開されているものから取得を試みましたが、
現状のものでは難しいので、サンプルコードを書きました。

APIにおいてIClassから以下のサンプルコードをご使用くださいませ。

    private static String getBoundsClassString(IClass boundsClass) {
        if(isAnonymousBoundClass(boundsClass)) {
            StringBuilder sb = new StringBuilder();
            ITemplateBinding[] templateBindings = boundsClass.getTemplateBindings();
            for (int i = 0; i < templateBindings.length; i++) {
                sb.append(getTemplateBindingString(templateBindings[i]));
                if (i + 1 != templateBindings.length) {
                    sb.append(" , ");
                }
            }
            return sb.toString();
        } else {
            return boundsClass.getName();
        }
    }
    
    public static boolean isAnonymousBoundClass(IClass boundsClass) {
        return boundsClass != null 
        && boundsClass.getName().equals("") 
        && boundsClass.getTemplateBindings() != null 
        && boundsClass.getTemplateBindings().length != 0;
    }
    
    private static String getTemplateBindingString(ITemplateBinding templateBinding) {
        StringBuilder sb = new StringBuilder();
        IClass template = templateBinding.getTemplate();
        if (template == null) {
            return sb.toString();
        }
        sb.append(templateBinding.getTemplate().getName());
        sb.append("<");
        Map actualMap = templateBinding.getActualMap();
        IClassifierTemplateParameter[] templateParameters = template.getTemplateParameters();
        for (IClassifierTemplateParameter param : templateParameters) {
            Object actual = actualMap.get(param);
            if (actual instanceof IClass) {
                sb.append(((IClass)actual).getName());
            } else if (actual instanceof String) {
                sb.append(actual);
            } else {
                Object defaultValue = param.getDefaultValue();
                if (defaultValue instanceof IClass) {
                    if (isAnonymousBoundClass((IClass)defaultValue)) {
                        ITemplateBinding defaultTemplateBinding = ((IClass)defaultValue).getTemplateBindings()[0];
                        sb.append(getTemplateBindingString(defaultTemplateBinding));
                    } else {
                        sb.append(((IClass)defaultValue).getName());
                    }
                } else if (defaultValue instanceof String) {
                    sb.append(defaultValue);
                } else {
                    sb.append("?");
                }
            }
            sb.append(param.getTypeModifier());
        }
        if ("<".equals(sb.toString())) {
            sb.append("?");
        }
        sb.append(">");
        return sb.toString();
    }

しかしながら、文字列取得が回りくどいと思いますので、
今後IClassにジェネリクスが含まれる型の文字列の取得の
メソッドを追加することを検討いたします。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を