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.system.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 */
037@SuppressWarnings(value={"deprecation","removal"})                      // Ver7.0.0.0 , 7.2.2.0 (2020/03/27)
038public final class DocletParam {
039        private static final String OG_PARAM_LVL    = "og.paramLevel";
040        private static final String OG_CRYPTOGRAPHY = "og.cryptography";
041        private static final String ENCODE = "UTF-8";
042        private static final int    CNST   = 1000;
043
044        /**
045         * すべてが staticメソッドなので、コンストラクタを呼び出さなくしておきます。
046         *
047         */
048        private DocletParam() {}
049
050        /**
051         * Doclet のエントリポイントメソッドです。
052         *
053         * @og.rev 5.5.2.0 (2012/05/01) systemIdのbuild.xmlの引数が、** の場合にエラーになるための対応
054         * @og.rev 5.7.1.1 (2013/12/13) タグのインデントを止める。
055         *
056         * @param root ドキュメントルートオブジェクト
057         *
058         * @return 正常実行時 true
059         */
060        public static boolean start( final RootDoc root ) {
061                String systemId = DocletUtil.getOption( "-systemId" , root.options() );
062                final String file     = DocletUtil.getOption( "-outfile"  , root.options() );
063
064                if( systemId == null || systemId.isEmpty() ) { systemId = "**"; }       // 5.5.2.0 (2012/05/01)
065
066                DocletTagWriter writer = null;
067                try {
068                        writer = new DocletTagWriter( file,ENCODE );
069
070                        // 5.7.1.1 (2013/12/13) タグのインデントを止める。
071                        writer.printTag( "<?xml version=\"1.0\" encoding=\"", ENCODE, "\" ?>" );
072                        writer.printTag( "<javadoc>" );
073                        writer.printTag( " <systemId>",systemId,"</systemId>" );
074                        writeContents( root.classes(),writer );
075                        writer.printTag( "</javadoc>" );
076                }
077                catch( final IOException ex ) {
078                        LogWriter.log( ex );
079                }
080                finally {
081                        if( writer != null ) { writer.close(); }
082                }
083                return true;
084        }
085
086        /**
087         * ClassDoc 配列よりコンテンツを作成します。
088         *
089         * @og.rev 5.5.4.1 (2012/07/06) コメントは文字列でなく、Tag配列として処理させる。
090         * @og.rev 5.5.4.1 (2012/07/06) DocletUtil.htmlFilter → StringUtil.htmlFilter に変更
091         * @og.rev 5.7.1.1 (2013/12/13) タグのインデントを止める。
092         *
093         * @param classes       ClassDoc配列
094         * @param writer        DocletTagWriterオブジェクト
095         */
096        private static void writeContents( final ClassDoc[] classes,final DocletTagWriter writer ) {
097                for( int i=0; i< classes.length; i++ ) {
098                        final ClassDoc classDoc      = classes[i] ;
099                        final FieldDoc[] fields = classDoc.fields();
100
101                        for( int j=0; j<fields.length; j++ ) {
102                                final FieldDoc field = fields[j];
103                                String param = field.constantValueExpression() ;
104                                if( param != null && param.length() >=2 &&
105                                        param.charAt(0) == '"' && param.charAt( param.length()-1 ) == '"' ) {
106                                                param = param.substring( 1,param.length()-1 );
107                                }
108                                param = StringUtil.htmlFilter( param );         // 5.5.4.1 (2012/07/06) DocletUtil → StringUtil に変更
109
110                                final String paramId    = field.name();
111                                final String seq                = String.valueOf(j*10 + CNST);
112                                final Tag[] title               = field.firstSentenceTags();
113                                final Tag[] cmnt                = field.inlineTags();                                                           // 5.5.4.1 (2012/07/06)
114                                final Tag[] paramLvl    = field.tags(OG_PARAM_LVL);
115                                final Tag[] fgcrypt             = field.tags(OG_CRYPTOGRAPHY);
116
117                                // 5.7.1.1 (2013/12/13) タグのインデントを止める。
118                                writer.printTag( " <fieldDoc>" );
119                                writer.printTag( "   <paramId>"         ,paramId        ,"</paramId>"           );
120                                writer.printTag( "   <seq>"                     ,seq            ,"</seq>"                       );
121                                writer.printTag( "   <param>"           ,param          ,"</param>"                     );
122                                writer.printTag( "   <title>"           ,title          ,"</title>"                     );
123                                writer.printTag( "   <contents>"        ,cmnt           ,"</contents>"          );
124                                writer.printChar("   <paramLevel>"      ,paramLvl       ,"</paramLevel>"        );
125                                writer.printChar("   <fgcrypt>"         ,fgcrypt        ,"</fgcrypt>"           );
126                                writer.printTag( " </fieldDoc>" );
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}