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 * @param root エントリポイント?RootDocオブジェク? 059 * 060 * @return 正常実行時 true 061 */ 062 public static boolean start( final RootDoc root ) { 063 String version = DocletUtil.getOption( "-version" , root.options() ); 064 String file = DocletUtil.getOption( "-outfile" , root.options() ); 065 066 DocletTagWriter writer = null; 067 try { 068 writer = new DocletTagWriter( file,ENCODE ); 069 070 writer.printTag( "<?xml version=\"1.0\" encoding=\"", ENCODE, "\" ?>" ); 071 writer.printTag( "<javadoc>" ); 072 writer.printTag( " <version>",version,"</version>" ); 073 writer.printTag( " <description></description>" ); 074 writeContents( root.classes(),writer ); 075 writer.printTag( "</javadoc>" ); 076 } 077 catch( 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.6.6.1 (2013/07/12) og.group を?tagGroup として独立させる? 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 String classFullName = classDoc.qualifiedName() ; 099 100 if( ! classDoc.isPublic() || 101 classFullName.indexOf( OG_TAG_CLASS ) < 0 ) { continue; } 102 103 Tag[] desc = classDoc.firstSentenceTags(); 104 // String cmnt = DocletUtil.htmlFilter( classDoc.commentText() ); // 5.5.4.1 (2012/07/06) 105 Tag[] cmnt = classDoc.inlineTags(); // 5.5.4.1 (2012/07/06) 106 Tag[] smplTags = classDoc.tags(OG_FOR_SMPL); 107 Tag[] grpTags = classDoc.tags(OG_GROUP); 108 109 writer.printTag( "<classDoc>" ); 110 writer.printTag( " <tagClass>" ,classFullName ,"</tagClass>" ); 111 // 5.6.6.1 (2013/07/12) og.group を?tagGroup として独立させる? 112 writer.printTag( " <tagGroup>" ,makeGroupTag( grpTags ) ,"</tagGroup>" ); 113 writer.printTag( " <description>" ); 114 // writer.printTag( makeGroupTag( grpTags ) ); // 5.6.6.1 (2013/07/12) 115 writer.printTag( desc ); 116 writer.printTag( "</description>" ); 117 writer.printTag( " <contents>" ,cmnt ,"</contents>" ); 118 writer.printTag( " <formSample>" ,smplTags ,"</formSample>" ); 119 120 map.clear(); 121 String className = classDoc.name(); 122 while( ! "BodyTagSupport".equals( className ) && 123 ! "TagSupport".equals( className ) ) { 124 String extendFlag = "false"; 125 if( "HTMLTagSupport".equals( className ) ) { 126 extendFlag = "true" ; 127 } 128 MethodDoc[] methods = classDoc.methods(); 129 for(int j=0; j < methods.length; j++) { 130 if( ! methods[j].isPublic() ) { continue; } 131 Tag[] tags = methods[j].tags(OG_TAG_NAME); 132 if(tags.length > 0) { 133 String methodName = DocletUtil.removeSetter( methods[j].name() ); 134 if( map.containsKey( methodName ) ) { continue; } 135 map.put( methodName,className ); 136 Tag[] ftag = methods[j].firstSentenceTags(); 137 // cmnt = DocletUtil.htmlFilter( methods[j].commentText() ); // 5.5.4.1 (2012/07/06) 138 cmnt = methods[j].inlineTags(); // 5.5.4.1 (2012/07/06) 139 140 writer.printTag( " <method>" ); 141 writer.printTag( " <name>" ,methodName ,"</name>" ); 142 writer.printTag( " <htmlExtend>" ,extendFlag ,"</htmlExtend>" ); 143 writer.printTag( " <description>",ftag ,"</description>" ); 144 writer.printTag( " <contents>" ); 145 writer.printTag( cmnt ); 146 writer.printTag( tags ); 147 writer.printTag( " </contents>" ); 148 writer.printTag( " </method>"); 149 } 150 } 151 Type type = classDoc.superclassType(); 152 if( type == null ) { break; } 153 classDoc = type.asClassDoc() ; 154 className = classDoc.name(); 155 } 156 writer.printTag( " </classDoc>" ); 157 } 158 } 159 160 /** 161 * タグ配?を受け取り?タグ出力します? 162 * ?のタグを?力する?合に、カンマ区??で連結します? 163 * 164 * @og.rev 5.5.4.1 (2012/07/06) DocletUtil.htmlFilter ?StringUtil.htmlFilter に変更 165 * @og.rev 5.6.6.1 (2013/07/12) og.group の表示方法を変更する? 166 * 167 * @param tag タグ配? 168 * 169 * @return タグ出力文字? 170 */ 171 private static String makeGroupTag( final Tag[] tag ) { 172 StringBuilder but = new StringBuilder( 200 ); 173 for( int i=0; i<tag.length; i++ ) { 174 // String data = DocletUtil.htmlFilter( tag[i].text() ); 175 String data = StringUtil.htmlFilter( tag[i].text() ); // 5.5.4.1 (2012/07/06) DocletUtil ?StringUtil に変更 176 if( i > 0 ) { but.append( "," ); } 177 // but.append( data ); 178 but.append( "? ).append( data ).append( "? ); // 5.6.6.1 (2013/07/12) og.group の表示方法を変更 179 } 180 return but.toString() ; // 5.6.6.1 (2013/07/12) 181 // if( but.length() > 0 ) { 182 // return "? + but.toString() + "? ; 183 // } 184 // else { 185 // return ""; 186 // } 187 } 188 189 /** 190 * カスタ?プションを使用するドックレ?の??メソ? optionLength(String) です? 191 * 192 * ドックレ?に認識させる?スタ?プションに?optionLength がその 193 * オプションを構?する要?(ト?クン) の数を返さなければなりません? 194 * こ?カスタ?プションでは?-tag オプションそ?も?と 195 * そ?値の 2 つの要?構?される?で、作?するドックレ?の 196 * optionLengthメソ?は?-tag オプションに対して 2 を返さなくては 197 * なりません。また?認識できな?プションに対しては? を返します? 198 * 199 * @param option カスタ?プションのキーワー? 200 * 201 * @return 要?(ト?クン) の数 202 */ 203 public static int optionLength( final String option ) { 204 if(option.equalsIgnoreCase("-version")) { 205 return 2; 206 } 207 else if(option.equalsIgnoreCase("-outfile")) { 208 return 2; 209 } 210 return 0; 211 } 212 }