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 */ 016 package org.opengion.fukurou.taglet; 017 018 import org.opengion.fukurou.util.LogWriter; 019 import org.opengion.fukurou.util.StringUtil; 020 021 import com.sun.javadoc.RootDoc; 022 import com.sun.javadoc.ClassDoc; 023 import com.sun.javadoc.MethodDoc; 024 import com.sun.javadoc.Type; 025 import com.sun.javadoc.Tag; 026 import java.util.Map; 027 import java.util.HashMap; 028 import java.io.IOException; 029 030 /** 031 * ソースコメントから?タグ??を取り??Doclet クラスです? 032 * こ? Doclet は?:org.opengion.hayabusa.taglib" のみ対象として処?ます? 033 * og.formSample , og.tag , og.group タグを?り?します? 034 * 035 * @version 4.0 036 * @author Kazuhiko Hasegawa 037 * @since JDK5.0, 038 */ 039 public final class DocletTaglib { 040 private static Map<String,String> map = new HashMap<String,String>(); 041 042 private static final String OG_FOR_SMPL = "og.formSample"; 043 private static final String OG_TAG_NAME = "og.tag"; 044 private static final String OG_GROUP = "og.group"; 045 046 private static final String OG_TAG_CLASS = "org.opengion.hayabusa.taglib"; 047 private static final String ENCODE = "UTF-8"; 048 049 /** 050 * すべて?staticメソ?なので、コンストラクタを呼び出さなくしておきます? 051 * 052 */ 053 private DocletTaglib() {} 054 055 /** 056 * Doclet のエントリポイントメソ?です? 057 * 058 * @og.rev 5.7.1.1 (2013/12/13) タグのイン?トを止める? 059 * 060 * @param root エントリポイント?RootDocオブジェク? 061 * 062 * @return 正常実行時 true 063 */ 064 public static boolean start( final RootDoc root ) { 065 String version = DocletUtil.getOption( "-version" , root.options() ); 066 String file = DocletUtil.getOption( "-outfile" , root.options() ); 067 068 DocletTagWriter writer = null; 069 try { 070 writer = new DocletTagWriter( file,ENCODE ); 071 072 // 5.7.1.1 (2013/12/13) タグのイン?トを止める? 073 writer.printTag( "<?xml version=\"1.0\" encoding=\"", ENCODE, "\" ?>" ); 074 writer.printTag( "<javadoc>" ); 075 writer.printTag( "<version>",version,"</version>" ); 076 writer.printTag( "<description></description>" ); 077 writeContents( root.classes(),writer ); 078 writer.printTag( "</javadoc>" ); 079 } 080 catch( IOException ex ) { 081 LogWriter.log( ex ); 082 } 083 finally { 084 if( writer != null ) { writer.close(); } 085 } 086 return true; 087 } 088 089 /** 090 * ClassDoc 配?よりコン??作?します? 091 * 092 * @og.rev 5.5.4.1 (2012/07/06) コメント???でなく?Tag配?として処?せる? 093 * @og.rev 5.6.6.1 (2013/07/12) og.group を?tagGroup として独立させる? 094 * @og.rev 5.7.1.1 (2013/12/13) cmnt と tags の間に改行をセ? 095 * @og.rev 5.7.1.1 (2013/12/13) タグのイン?トを止める? 096 * 097 * @param classes ClassDoc配? 098 * @param writer DocletTagWriterオブジェク? 099 */ 100 private static void writeContents( final ClassDoc[] classes,final DocletTagWriter writer ) { 101 for(int i=0; i< classes.length; i++) { 102 ClassDoc classDoc = classes[i] ; 103 String classFullName = classDoc.qualifiedName() ; 104 105 if( ! classDoc.isPublic() || 106 classFullName.indexOf( OG_TAG_CLASS ) < 0 ) { continue; } 107 108 Tag[] desc = classDoc.firstSentenceTags(); 109 // String cmnt = DocletUtil.htmlFilter( classDoc.commentText() ); // 5.5.4.1 (2012/07/06) 110 Tag[] cmnt = classDoc.inlineTags(); // 5.5.4.1 (2012/07/06) 111 Tag[] smplTags = classDoc.tags(OG_FOR_SMPL); 112 Tag[] grpTags = classDoc.tags(OG_GROUP); 113 114 // 5.7.1.1 (2013/12/13) タグのイン?トを止める? 115 writer.printTag( "<classDoc>" ); 116 writer.printTag( "<tagClass>" ,classFullName ,"</tagClass>" ); 117 // 5.6.6.1 (2013/07/12) og.group を?tagGroup として独立させる? 118 writer.printTag( "<tagGroup>" ,makeGroupTag( grpTags ) ,"</tagGroup>" ); 119 writer.printTag( "<description>" ,desc ,"</description>" ); 120 // writer.printTag( "<description>" ); 121 //// writer.printTag( makeGroupTag( grpTags ) ); // 5.6.6.1 (2013/07/12) 122 // writer.printTag( desc ); 123 // writer.printTag( "</description>" ); 124 writer.printTag( "<contents>" ,cmnt ,"</contents>" ); 125 writer.printTag( "<formSample>" ,smplTags ,"</formSample>" ); 126 127 map.clear(); 128 String className = classDoc.name(); 129 while( ! "BodyTagSupport".equals( className ) && 130 ! "TagSupport".equals( className ) ) { 131 String extendFlag = "false"; 132 if( "HTMLTagSupport".equals( className ) ) { 133 extendFlag = "true" ; 134 } 135 MethodDoc[] methods = classDoc.methods(); 136 for(int j=0; j < methods.length; j++) { 137 if( ! methods[j].isPublic() ) { continue; } 138 Tag[] tags = methods[j].tags(OG_TAG_NAME); 139 if(tags.length > 0) { 140 String methodName = DocletUtil.removeSetter( methods[j].name() ); 141 if( map.containsKey( methodName ) ) { continue; } 142 map.put( methodName,className ); 143 Tag[] ftag = methods[j].firstSentenceTags(); 144 // cmnt = DocletUtil.htmlFilter( methods[j].commentText() ); // 5.5.4.1 (2012/07/06) 145 cmnt = methods[j].inlineTags(); // 5.5.4.1 (2012/07/06) 146 147 // 5.7.1.1 (2013/12/13) タグのイン?トを止める? 148 writer.printTag( "<method>" ); 149 writer.printTag( "<name>" ,methodName ,"</name>" ); 150 writer.printTag( "<htmlExtend>" ,extendFlag ,"</htmlExtend>" ); 151 writer.printTag( "<description>",ftag ,"</description>" ); 152 // 5.7.1.1 (2013/12/13) cmnt と tags の間に改行をセ? 153 writer.printTag( "<contents>" ,cmnt ,"" ); 154 writer.printTag( "" ,tags ,"</contents>" ); 155 // writer.printTag( " <contents>" ); 156 // writer.printTag( cmnt ); 157 // writer.printTag( tags ); 158 // writer.printTag( " </contents>" ); 159 writer.printTag( "</method>"); 160 } 161 } 162 Type type = classDoc.superclassType(); 163 if( type == null ) { break; } 164 classDoc = type.asClassDoc() ; 165 className = classDoc.name(); 166 } 167 writer.printTag( " </classDoc>" ); 168 } 169 } 170 171 /** 172 * タグ配?を受け取り?タグ出力します? 173 * ?のタグを?力する?合に、カンマ区??で連結します? 174 * 175 * @og.rev 5.5.4.1 (2012/07/06) DocletUtil.htmlFilter ?StringUtil.htmlFilter に変更 176 * @og.rev 5.6.6.1 (2013/07/12) og.group の表示方法を変更する? 177 * 178 * @param tag タグ配? 179 * 180 * @return タグ出力文字? 181 */ 182 private static String makeGroupTag( final Tag[] tag ) { 183 StringBuilder but = new StringBuilder( 200 ); 184 for( int i=0; i<tag.length; i++ ) { 185 // String data = DocletUtil.htmlFilter( tag[i].text() ); 186 String data = StringUtil.htmlFilter( tag[i].text() ); // 5.5.4.1 (2012/07/06) DocletUtil ?StringUtil に変更 187 if( i > 0 ) { but.append( "," ); } 188 // but.append( data ); 189 but.append( "? ).append( data ).append( "? ); // 5.6.6.1 (2013/07/12) og.group の表示方法を変更 190 } 191 return but.toString() ; // 5.6.6.1 (2013/07/12) 192 // if( but.length() > 0 ) { 193 // return "? + but.toString() + "? ; 194 // } 195 // else { 196 // return ""; 197 // } 198 } 199 200 /** 201 * カスタ?プションを使用するドックレ?の??メソ? optionLength(String) です? 202 * 203 * ドックレ?に認識させる?スタ?プションに?optionLength がその 204 * オプションを構?する要?(ト?クン) の数を返さなければなりません? 205 * こ?カスタ?プションでは?-tag オプションそ?も?と 206 * そ?値の 2 つの要?構?される?で、作?するドックレ?の 207 * optionLengthメソ?は?-tag オプションに対して 2 を返さなくては 208 * なりません。また?認識できな?プションに対しては? を返します? 209 * 210 * @param option カスタ?プションのキーワー? 211 * 212 * @return 要?(ト?クン) の数 213 */ 214 public static int optionLength( final String option ) { 215 if(option.equalsIgnoreCase("-version")) { 216 return 2; 217 } 218 else if(option.equalsIgnoreCase("-outfile")) { 219 return 2; 220 } 221 return 0; 222 } 223 }