    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *        http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.fukurou.taglet2;
    017
    018
    019import jdk.javadoc.doclet.DocletEnvironment      ;
    020// import jdk.javadoc.doclet.Doclet  ;
    021// import jdk.javadoc.doclet.Reporter ;
    022// import javax.lang.model.element.Element      ;
    023import javax.lang.model.element.Modifier ;
    024import javax.lang.model.element.TypeElement;
    025// import javax.lang.model.element.ElementKind  ;
    026import javax.lang.model.element.VariableElement;
    027// import javax.lang.model.SourceVersion ;
    028import javax.lang.model.util.ElementFilter ;
    029// import javax.lang.model.util.Elements ;
    030import javax.tools.Diagnostic.Kind ;
    031import com.sun.source.doctree.DocCommentTree  ;
    032import com.sun.source.util.DocTrees  ;
    033import com.sun.source.doctree.DocTree  ;
    034
    035// import java.util.Locale ;
    036import java.util.Set;
    037import java.util.List;
    038import java.util.HashSet;
    039import java.util.Arrays;
    040import java.util.Map;
    041
    042// import java.io.IOException;
    043// import java.io.File;
    044// import java.io.PrintWriter;
    045
    046// import org.opengion.fukurou.util.FileUtil;
    047// import org.opengion.fukurou.util.StringUtil;
    048
    049/**
    050 * ソースコメントから、パラメータ情報を取り出す Doclet クラスです。
    051 * og.paramLevel タグと og.cryptography タグを切り出します。
    052 * これらは、ｼｽﾃﾑパラメータとしてGE12ﾃｰﾌﾞﾙに設定される値をクラスより抽出する
    053 * のに使用します。
    054 *
    055 * @version  7.3
    056 * @author      Kazuhiko Hasegawa
    057 * @since        JDK11.0,
    058 */
    059public class DocTreeParam extends AbstractDocTree {
    060        private static final String OG_PARAM_LVL    = "og.paramLevel";
    061        private static final String OG_CRYPTOGRAPHY = "og.cryptography";
    062
    063        private static final int    CNST   = 1000;
    064
    065        private String systemId = "**" ;
    066        private String outfile;
    067
    068//      private DocTrees docUtil;
    069
    070        /**
    071         * Doclet のエントリポイントメソッドです(昔の startメソッド)。
    072         *
    073         * @og.rev 7.3.0.0 (2021/01/06) 新しいJavaDoc対応
    074         *
    075         * @param docEnv ドックレットを1回呼び出す操作環境
    076         *
    077         * @return 正常実行時 true
    078         */
    079        @Override
    080        public boolean run( final DocletEnvironment docEnv ) {
    081                try( DocTreeWriter writer = new DocTreeWriter( outfile,ENCODE ) ) {
    082                        writer.printTag( "<?xml version=\"1.0\" encoding=\"", ENCODE , "\" ?>" );
    083                        writer.printTag( "<javadoc>" );
    084                        writer.printTag( " <systemId>" , systemId , "</systemId>" );
    085                        writeContents( docEnv,writer );
    086                        writer.printTag( "</javadoc>" );
    087                }
    088                catch( final Throwable th ) {
    089                        reporter.print(Kind.ERROR, th.getMessage());
    090                }
    091
    092                return true;
    093        }
    094
    095        /**
    096         * DocletEnvironmentよりコンテンツを作成します。
    097         *
    098         * @og.rev 7.3.0.0 (2021/01/06) 新しいJavaDoc対応
    099         *
    100         * @param docEnv        ドックレットの最上位
    101         * @param writer        DocTreeWriterオブジェクト
    102         */
    103        private void writeContents( final DocletEnvironment docEnv, final DocTreeWriter writer ) {
    104                // get the DocTrees utility class to access document comments
    105//              docUtil = docEnv.getDocTrees();
    106                final DocTrees docUtil = docEnv.getDocTrees();
    107//              final Elements eleUtil  = docEnv.getElementUtils();
    108
    109                // クラス単位にループする。
    110                for( final TypeElement typEle : ElementFilter.typesIn(docEnv.getIncludedElements())) {
    111                        int cnt = 0;
    112                        final String fullName = String.valueOf( typEle.getQualifiedName() ) ;
    113//                      final String fullName = String.valueOf(typEle);
    114//                      System.out.println(typEle.getKind() + ":" + fullName);
    115                        writer.setClassName( fullName );
    116
    117                        // フィールドのみフィルタリングして取得する
    118                        for( final VariableElement varEle : ElementFilter.fieldsIn(typEle.getEnclosedElements())) {             // フィールドだけに絞る
    119                                if( varEle.getModifiers().contains( Modifier.PUBLIC )) {                                                                                // public だけに絞る
    120                                        final DocCommentTree docTree = docUtil.getDocCommentTree(varEle);               // ﾄﾞｷｭﾒﾝﾃｰｼｮﾝ･ｺﾒﾝﾄが見つからない場合、null が返る。
    121
    122                                        final String paramId                            = String.valueOf(varEle);
    123                                        final String seq                                        = String.valueOf(cnt*10 + CNST);
    124                                        final List<? extends DocTree> title     = docTree == null ? EMPTY_LIST : docTree.getFirstSentence();
    125                                        final List<? extends DocTree> cmnt      = docTree == null ? EMPTY_LIST : docTree.getFullBody();
    126
    127                                        final String param = String.valueOf( varEle.getConstantValue() );
    128
    129                                        final Map<String,List<String>> blkTagMap = blockTagsMap(docTree);
    130                                        final String paramLvl = getBlockTag( OG_PARAM_LVL   , blkTagMap, "" ).split(":")[0];    // 取得した値を ':' で分割した最初の文字列。
    131                                        final String fgcrypt  = getBlockTag( OG_CRYPTOGRAPHY, blkTagMap, "" ).split(":")[0];
    132
    133//                                      String paramLvl = "";
    134//                                      String fgcrypt  = "";
    135//                                      if( docTree != null ) {
    136//                                              for( final DocTree dt : docTree.getBlockTags() ) {
    137//                                                      final String tag = String.valueOf(dt);
    138//                                                      if( tag.contains( OG_PARAM_LVL ) ) {
    139//                                                              paramLvl = cut( tag,' ',':' );
    140//                                                      }
    141//                                                      else if( tag.contains( OG_CRYPTOGRAPHY ) ) {
    142//                                                              fgcrypt = cut( tag,' ',':' );
    143//                                                      }
    144//                                              }
    145//                                      }
    146
    147                                        writer.printTag( " <fieldDoc>" );
    148                                        writer.printTag( "   <paramId>"         ,paramId        ,"</paramId>"           );
    149                                        writer.printTag( "   <seq>"                     ,seq            ,"</seq>"                       );
    150                                        writer.printTag( "   <param>"           ,param          ,"</param>"                     );
    151                                        writer.printTag( "   <title>"           ,title          ,"</title>"                     );
    152                                        writer.printTag( "   <contents>"        ,cmnt           ,"</contents>"          );
    153                                        writer.printTag( "   <paramLevel>"      ,paramLvl       ,"</paramLevel>"        );
    154                                        writer.printTag( "   <fgcrypt>"         ,fgcrypt        ,"</fgcrypt>"           );
    155                                        writer.printTag( " </fieldDoc>" );
    156
    157                                        cnt++;
    158                                }
    159                        }
    160                }
    161        }
    162
    163        /**
    164         * サポートされているすべてのオプションを返します。
    165         *
    166         * @return サポートされているすべてのオプションを含むセット、存在しない場合は空のセット
    167         */
    168        @Override
    169        public Set<? extends Option> getSupportedOptions() {
    170                final Option[] options = {
    171                        new AbstractOption( "-outfile", "-systemId" ) {
    172
    173                                /**
    174                                 * 必要に応じてオプションと引数を処理します。
    175                                 *
    176                                 * @param  opt オプション名
    177                                 * @param  arguments 引数をカプセル化したリスト
    178                                 * @return 操作が成功した場合はtrue、そうでない場合はfalse
    179                                 */
    180                                @Override
    181                                public boolean process(final String opt, final List<String> arguments) {
    182                                        if( "-outfile".equalsIgnoreCase(opt) ) {
    183                                                outfile = arguments.get(0);
    184                                        }
    185                                        else if( "-systemId".equalsIgnoreCase(opt) ) {
    186                                                systemId = arguments.get(0);
    187                                        }
    188                                        return true;
    189                                }
    190                        }
    191                };
    192                return new HashSet<>(Arrays.asList(options));
    193        }
    194}