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}