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; 019 020import com.sun.javadoc.RootDoc; 021import com.sun.javadoc.ClassDoc; 022import com.sun.javadoc.Type; 023import com.sun.javadoc.Tag; 024import java.util.Map; 025import java.util.HashMap; 026import java.io.IOException; 027 028/** 029 * ソースコメントから、属性情報を取り出す Doclet クラスです。 030 * 031 * @version 4.0 032 * @author Kazuhiko Hasegawa 033 * @since JDK5.0, 034 */ 035public final class DocletPlugin { 036 private static Map<String,AttKeySet> map = new HashMap<String,AttKeySet>(); 037 038 private static final String OG_FOR_SMPL = "og.formSample"; 039 private static final String ENCODE = "UTF-8"; 040 041 /** 042 * すべてが staticメソッドなので、コンストラクタを呼び出さなくしておきます。 043 * 044 */ 045 private DocletPlugin() {} 046 047 /** 048 * Doclet のエントリポイントメソッドです。 049 * 050 * @og.rev 5.7.1.1 (2013/12/13) タグのインデントを止める。 051 * 052 * @param root ドキュメントルートオブジェクト 053 * 054 * @return 正常実行時 true 055 */ 056 public static boolean start( final RootDoc root ) { 057 String version = DocletUtil.getOption( "-version" , root.options() ); 058 String file = DocletUtil.getOption( "-outfile" , root.options() ); 059 060 mapInit(); 061 062 DocletTagWriter writer = null; 063 try { 064 writer = new DocletTagWriter( file,ENCODE ); 065 066 // 5.7.1.1 (2013/12/13) タグのインデントを止める。 067 writer.printTag( "<?xml version=\"1.0\" encoding=\"", ENCODE, "\" ?>" ); 068 writer.printTag( "<javadoc>" ); 069 writer.printTag( "<version>",version,"</version>" ); 070 writer.printTag( "<description></description>" ); 071 writeContents( root.classes(),writer ); 072 writer.printTag( "</javadoc>" ); 073 } 074 catch( IOException ex ) { 075 LogWriter.log( ex ); 076 } 077 finally { 078 if( writer != null ) { writer.close(); } 079 } 080 return true; 081 } 082 083 /** 084 * ClassDoc 配列よりコンテンツを作成します。 085 * インターフェースも処理の対象とします。 086 * 087 * @og.rev 5.5.4.1 (2012/07/06) コメントは文字列でなく、Tag配列として処理させる。 088 * @og.rev 5.7.1.1 (2013/12/13) タグのインデントを止める。 089 * 090 * @param classes ClassDoc配列 091 * @param writer DocletTagWriterオブジェクト 092 */ 093 private static void writeContents( final ClassDoc[] classes,final DocletTagWriter writer ) { 094 for(int i=0; i< classes.length; i++) { 095 ClassDoc classDoc = classes[i] ; 096 if( ! classDoc.isPublic() ) { continue; } 097 098 AttKeySet attSet = getAttGroupName( classDoc ) ; 099 100 if( attSet == null ) { continue; } // map に登録されていない。 101 102 String attKey = attSet.getAttKey( classDoc.name() ); 103 104 if( attKey == null ) { continue; } // 対象クラス名が、一致しない。 105 106 String attClass = classDoc.qualifiedName() ; // Class Full Name 107 Tag[] desc = classDoc.firstSentenceTags(); 108 Tag[] cmnt = classDoc.inlineTags(); // 5.5.4.1 (2012/07/06) 109 Tag[] smplTags = classDoc.tags(OG_FOR_SMPL); 110 111 // 5.7.1.1 (2013/12/13) タグのインデントを止める。 112 writer.printTag( "<classDoc>" ); 113 writer.printTag( "<attClass>" ,attClass ,"</attClass>" ); 114 writer.printTag( "<seq>" ,attSet.getSeq() ,"</seq>" ); 115 writer.printTag( "<attKey>" ,attKey ,"</attKey>" ); 116 writer.printTag( "<valueName>" ,attSet.getValueName() ,"</valueName>" ); 117 writer.printTag( "<description>" ,desc ,"</description>" ); 118 writer.printTag( "<contents>" ,cmnt ,"</contents>" ); 119 writer.printTag( "<formSample>" ,smplTags ,"</formSample>" ); 120 writer.printTag( "</classDoc>" ); 121 } 122 } 123 124 /** 125 * 処理する属性クラスのMapを初期化します。 126 * 指定できるのは、親クラスか、直接のインターフェースです。 127 * 128 * @og.rev 4.3.5.0 (2008/02/01) daemonパッケージ追加 129 * @og.rev 5.5.3.5 (2012/06/21) ChartWriter 削除、TransferExec,TransferRead 追加 130 * @og.rev 5.6.3.3 (2013/04/19) DBTableReport,CalendarData,DBConstValue,JspParserFilter,ConnectIF 追加 131 * 132 */ 133 private static void mapInit() { 134 map.put( "org.opengion.hayabusa.db.Query" , new AttKeySet( "Query" ,0, "queryType" )); 135 map.put( "org.opengion.hayabusa.db.CellRenderer" , new AttKeySet( "Renderer" ,1, "renderer" )); 136 map.put( "org.opengion.hayabusa.db.CellEditor" , new AttKeySet( "Editor" ,2, "editor" )); 137 map.put( "org.opengion.hayabusa.db.DBType" , new AttKeySet( "DBType" ,3, "dbType" )); 138 map.put( "org.opengion.hayabusa.db.TableFilter" , new AttKeySet( "TableFilter" ,4, "tableFilter" )); 139 map.put( "org.opengion.hayabusa.db.Selection" , new AttKeySet( "Selection" ,5, "selection" )); 140 map.put( "org.opengion.hayabusa.html.ViewForm" , new AttKeySet( "ViewForm" ,6, "viewFormType" )); 141 map.put( "org.opengion.hayabusa.io.TableWriter" , new AttKeySet( "TableWriter" ,7, "writerClass" )); 142 map.put( "org.opengion.hayabusa.io.TableReader" , new AttKeySet( "TableReader" ,8, "readerClass" )); 143 map.put( "org.opengion.hayabusa.resource.CalendarQuery" , new AttKeySet( "CalendarQuery" ,10, "calDB" )); 144 map.put( "org.opengion.fukurou.process.HybsProcess" , new AttKeySet( "Process" ,11, "process" )); 145 map.put( "org.opengion.fukurou.transfer.TransferExec" , new AttKeySet( "TransferExec" ,12, "kbExec" )); // 5.5.3.5 (2012/06/21) 146 map.put( "org.opengion.fukurou.transfer.TransferRead" , new AttKeySet( "TransferRead" ,13, "kbRead" )); // 5.5.3.5 (2012/06/21) 147 map.put( "org.opengion.fukurou.util.HybsTimerTask" , new AttKeySet( "Daemon" ,14, "daemon" )); // 4.3.4.4 (2009/01/01) 148 149 map.put( "org.opengion.hayabusa.report.DBTableReport" , new AttKeySet( "DBTableReport" ,15, "tableReport" )); // 5.6.3.3 (2013/04/19) 150 map.put( "org.opengion.hayabusa.resource.CalendarData" , new AttKeySet( "CalendarData" ,16, "calData" )); // 5.6.3.3 (2013/04/19) 151 map.put( "org.opengion.hayabusa.db.DBConstValue" , new AttKeySet( "DBConstValue" ,17, "cnstVal" )); // 5.6.3.3 (2013/04/19) 152 map.put( "org.opengion.fukurou.xml.JspParserFilter" , new AttKeySet( "JspCreate" ,18, "jspParser" )); // 5.6.3.3 (2013/04/19) 153 map.put( "org.opengion.fukurou.util.ConnectIF " , new AttKeySet( "ConnectIF" ,19, "connIF" )); // 5.6.3.3 (2013/04/19) 154 } 155 156 /** 157 * 指定の ClassDoc が、処理する属性クラスのMapに含まれている場合、 158 * その AttKeySet クラスのオブジェクトを返します。 159 * 存在しない場合、null を返します。 160 * 161 * @param classDoc ClassDocオブジェクト 162 * 163 * @return ClassDocに対応する AttKeySetオブジェクト 164 */ 165 private static AttKeySet getAttGroupName( final ClassDoc classDoc ) { 166 if( classDoc == null ) { return null; } 167 168 String classFullName = classDoc.qualifiedName() ; 169 AttKeySet attKey = map.get( classFullName ); 170 if( attKey == null ) { 171 Type type = classDoc.superclassType(); // 親クラスタイプ 172 if( type != null ) { 173 attKey = getAttGroupName( type.asClassDoc() ); // 親クラス 174 } 175 176 if( attKey == null ) { 177 Type[] itface = classDoc.interfaceTypes(); // 直近インターフェース 178 for( int i=0; i<itface.length; i++ ) { 179 attKey = getAttGroupName( itface[i].asClassDoc() ); 180 if( attKey != null ) { break; } 181 } 182 } 183 } 184 return attKey; 185 } 186 187 /** 188 * カスタムオプションを使用するドックレットの必須メソッド optionLength(String) です。 189 * 190 * ドックレットに認識させる各カスタムオプションに、 optionLength がその 191 * オプションを構成する要素 (トークン) の数を返さなければなりません。 192 * このカスタムオプションでは、 -tag オプションそのものと 193 * その値の 2 つの要素で構成されるので、作成するドックレットの 194 * optionLengthメソッドは、 -tag オプションに対して 2 を返さなくては 195 * なりません。また、認識できないオプションに対しては、0 を返します。 196 * 197 * @param option オプション文字列 198 * 199 * @return 要素 (トークン) の数 200 */ 201 public static int optionLength( final String option ) { 202 if("-version".equalsIgnoreCase(option)) { 203 return 2; 204 } 205 else if("-outfile".equalsIgnoreCase(option)) { 206 return 2; 207 } 208 return 0; 209 } 210}