    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.taglet;
    017
    018import org.opengion.fukurou.util.LogWriter;
    019import org.opengion.fukurou.util.StringUtil;
    020
    021import com.sun.javadoc.RootDoc;
    022import com.sun.javadoc.ClassDoc;
    023import com.sun.javadoc.FieldDoc;
    024import com.sun.javadoc.Tag;
    025import java.io.IOException;
    026
    027/**
    028 * ソースコメントから、パラメータ情報を取り出す Doclet クラスです。
    029 * og.paramLevel タグと og.cryptography タグを切り出します。
    030 * これらは、ｼｽﾃﾑパラメータとしてGE12ﾃｰﾌﾞﾙに設定される値をクラスより抽出する
    031 * のに使用します。
    032 *
    033 * @version  4.0
    034 * @author   Kazuhiko Hasegawa
    035 * @since    JDK5.0,
    036 */
    037public final class DocletParam {
    038        private static final String OG_PARAM_LVL    = "og.paramLevel";
    039        private static final String OG_CRYPTOGRAPHY = "og.cryptography";
    040        private static final String ENCODE = "UTF-8";
    041        private static final int    CNST   = 1000;
    042
    043        /**
    044         * すべてが staticメソッドなので、コンストラクタを呼び出さなくしておきます。
    045         *
    046         */
    047        private DocletParam() {}
    048
    049        /**
    050         * Doclet のエントリポイントメソッドです。
    051         *
    052         * @og.rev 5.5.2.0 (2012/05/01) systemIdのbuild.xmlの引数が、** の場合にエラーになるための対応
    053         * @og.rev 5.7.1.1 (2013/12/13) タグのインデントを止める。
    054         *
    055         * @param root ドキュメントルートオブジェクト
    056         *
    057         * @return 正常実行時 true
    058         */
    059        public static boolean start( final RootDoc root ) {
    060                String systemId = DocletUtil.getOption( "-systemId" , root.options() );
    061                String file     = DocletUtil.getOption( "-outfile"  , root.options() );
    062
    063                if( systemId == null || systemId.isEmpty() ) { systemId = "**"; }       // 5.5.2.0 (2012/05/01)
    064
    065                DocletTagWriter writer = null;
    066                try {
    067                        writer = new DocletTagWriter( file,ENCODE );
    068
    069                        // 5.7.1.1 (2013/12/13) タグのインデントを止める。
    070                        writer.printTag( "<?xml version=\"1.0\" encoding=\"", ENCODE, "\" ?>" );
    071                        writer.printTag( "<javadoc>" );
    072                        writer.printTag(   "<systemId>",systemId,"</systemId>" );
    073                        writeContents( root.classes(),writer );
    074                        writer.printTag( "</javadoc>" );
    075                }
    076                catch( IOException ex ) {
    077                        LogWriter.log( ex );
    078                }
    079                finally {
    080                        if( writer != null ) { writer.close(); }
    081                }
    082                return true;
    083        }
    084
    085        /**
    086         * ClassDoc 配列よりコンテンツを作成します。
    087         *
    088         * @og.rev 5.5.4.1 (2012/07/06) コメントは文字列でなく、Tag配列として処理させる。
    089         * @og.rev 5.5.4.1 (2012/07/06) DocletUtil.htmlFilter → StringUtil.htmlFilter に変更
    090         * @og.rev 5.7.1.1 (2013/12/13) タグのインデントを止める。
    091         *
    092         * @param classes       ClassDoc配列
    093         * @param writer        DocletTagWriterオブジェクト
    094         */
    095        private static void writeContents( final ClassDoc[] classes,final DocletTagWriter writer ) {
    096                for(int i=0; i< classes.length; i++) {
    097                        ClassDoc classDoc      = classes[i] ;
    098                        FieldDoc[] fields = classDoc.fields();
    099
    100                        for( int j=0; j<fields.length; j++ ) {
    101                                FieldDoc field = fields[j];
    102                                String param = field.constantValueExpression() ;
    103                                if( param != null && param.length() >=2 &&
    104                                        param.charAt(0) == '"' && param.charAt( param.length()-1 ) == '"' ) {
    105                                                param = param.substring( 1,param.length()-1 );
    106                                }
    107                                param = StringUtil.htmlFilter( param );         // 5.5.4.1 (2012/07/06) DocletUtil → StringUtil に変更
    108
    109                                String paramId  = field.name();
    110                                String seq      = String.valueOf(j*10 + CNST);
    111                                Tag[] title     = field.firstSentenceTags();
    112                                Tag[] cmnt      = field.inlineTags();                                                           // 5.5.4.1 (2012/07/06)
    113                                Tag[] paramLvl  = field.tags(OG_PARAM_LVL);
    114                                Tag[] fgcrypt   = field.tags(OG_CRYPTOGRAPHY);
    115
    116                                // 5.7.1.1 (2013/12/13) タグのインデントを止める。
    117                                writer.printTag(  "<fieldDoc>" );
    118                                writer.printTag(    "<paramId>"         ,paramId        ,"</paramId>"           );
    119                                writer.printTag(    "<seq>"                     ,seq            ,"</seq>"                       );
    120                                writer.printTag(    "<param>"           ,param          ,"</param>"                     );
    121                                writer.printTag(    "<title>"           ,title          ,"</title>"                     );
    122                                writer.printTag(    "<contents>"        ,cmnt           ,"</contents>"          );
    123                                writer.printChar(   "<paramLevel>"      ,paramLvl       ,"</paramLevel>"        );
    124                                writer.printChar(   "<fgcrypt>"         ,fgcrypt        ,"</fgcrypt>"           );
    125                                writer.printTag(  "</fieldDoc>" );
    126                        }
    127
    128                }
    129        }
    130
    131        /**
    132         * カスタムオプションを使用するドックレットの必須メソッド optionLength(String) です。
    133         *
    134         * ドックレットに認識させる各カスタムオプションに、 optionLength がその
    135         * オプションを構成する要素 (トークン) の数を返さなければなりません。
    136         * このカスタムオプションでは、 -tag オプションそのものと
    137         * その値の 2 つの要素で構成されるので、作成するドックレットの
    138         * optionLengthメソッドは、 -tag オプションに対して 2 を返さなくては
    139         * なりません。また、認識できないオプションに対しては、0 を返します。
    140         *
    141         * @param option オプション文字列
    142         *
    143         * @return 要素 (トークン) の数
    144         */
    145        public static int optionLength( final String option ) {
    146                if("-outfile".equalsIgnoreCase(option)) {
    147                        return 2;
    148                }
    149                else if("-systemId".equalsIgnoreCase(option)) {
    150                        return 2;
    151                }
    152                return 0;
    153        }
    154}