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; // 7.4.4.0 (2021/06/30) openGionV8事前準備(taglet2→taglet) 017 018import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; // 6.1.0.0 (2014/12/26) refactoring 019 020import jdk.javadoc.doclet.DocletEnvironment ; 021// import jdk.javadoc.doclet.Doclet ; 022// import jdk.javadoc.doclet.Reporter ; 023import javax.lang.model.element.Element ; 024import javax.lang.model.element.Modifier ; 025import javax.lang.model.element.TypeElement; 026import javax.lang.model.element.ElementKind ; 027import javax.lang.model.element.VariableElement; 028import javax.lang.model.element.ExecutableElement; 029// import javax.lang.model.SourceVersion ; 030import javax.lang.model.type.TypeMirror; 031import javax.lang.model.type.TypeKind; 032import javax.lang.model.util.ElementFilter ; 033import javax.lang.model.util.Elements ; 034import javax.lang.model.util.Types ; 035import javax.tools.Diagnostic.Kind ; 036import com.sun.source.doctree.DocCommentTree ; 037import com.sun.source.util.DocTrees ; 038// import com.sun.source.util.DocSourcePositions ; 039import com.sun.source.doctree.DocTree ; 040 041// import java.util.Locale ; 042import java.util.Set; 043import java.util.List; 044import java.util.HashSet; 045import java.util.Arrays; 046// import java.util.stream.Stream; // 6.4.3.4 (2016/03/11) 047// import java.util.stream.Collectors; // 6.4.3.4 (2016/03/11) 048// import java.util.regex.Pattern; // 6.3.9.1 (2015/11/27) final化に伴う整理 049 050// import java.io.IOException; 051// import java.io.File; 052// import java.io.PrintWriter; 053import java.util.stream.Stream; // 6.4.3.4 (2016/03/11) 054import java.util.stream.Collectors; // 6.4.3.4 (2016/03/11) 055import java.util.Map; 056 057// import org.opengion.fukurou.util.FileUtil; 058// import org.opengion.fukurou.util.StringUtil; 059 060/** 061 * ソースコメントから、パラメータ情報を取り出す Doclet クラスです。 062 * og.paramLevel タグと og.cryptography タグを切り出します。 063 * これらは、システムパラメータとしてGE12テーブルに設定される値をクラスより抽出する 064 * のに使用します。 065 * 066 * @version 7.3 067 * @author Kazuhiko Hasegawa 068 * @since JDK11.0, 069 */ 070public class DocTreeSpecific extends AbstractDocTree { 071 private static final String SELECT_PACKAGE = "org.opengion" ; 072 private static final boolean USE_PRIVATE = false ; 073 074 private static final String OG_FOR_SMPL = "og.formSample"; 075 private static final String OG_REV = "og.rev"; 076 private static final String OG_GROUP = "og.group"; 077 private static final String DOC_VERSION = "version"; 078 private static final String DOC_AUTHOR = "author"; 079 private static final String DOC_SINCE = "since"; 080 081// private static final String OG_TAG_NAME = "og.tag"; // 6.1.2.0 (2015/01/24) チェック用 082// private static final String DOC_PARAM = "param"; // 5.1.9.0 (2010/08/01) チェック用 083// private static final String DOC_RETURN = "return"; // 5.1.9.0 (2010/08/01) チェック用 084 085 private static final String CONSTRUCTOR = "コンストラクタ" ; 086 private static final String METHOD = "メソッド" ; 087 088 private String version ; 089 private String outfile ; 090 private int debugLevel ; // 0:なし 1:最小チェック 2:日本語化 3:体裁 4:Verチェック 5:taglibラベル 091 092 private final Set<String> mtdClsSet = new HashSet<>(); 093 094 // 5.1.9.0 (2010/08/01) ソースチェック用(半角文字+空白文字のみ) 095// private static final Pattern PTN = Pattern.compile("[\\w\\s]+"); // 6.3.9.1 (2015/11/27) 096 097// private DocTrees docUtil; 098// private Elements eleUtil ; 099 private Types typUtil ; 100 101 /** 102 * デフォルトコンストラクター 103 * 104 * @og.rev 7.3.0.0 (2021/01/06) PMD refactoring. Each class should declare at least one constructor. 105 */ 106 public DocTreeSpecific() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 107 108 /** 109 * Doclet のエントリポイントメソッドです(昔の startメソッド)。 110 * 111 * @og.rev 7.3.0.0 (2021/01/06) 新しいJavaDoc対応 112 * 113 * @param docEnv ドックレットを1回呼び出す操作環境 114 * 115 * @return 正常実行時 true 116 */ 117 @Override 118 public boolean run( final DocletEnvironment docEnv ) { 119 try( DocTreeWriter writer = new DocTreeWriter( outfile,ENCODE ) ) { 120 writer.printTag( "<?xml version=\"1.0\" encoding=\"", ENCODE , "\" ?>" ); 121 writer.printTag( "<javadoc>" ); 122 writer.printTag( " <version>",version,"</version>" ); 123 writer.printTag( " <description></description>" ); 124 writeContents( docEnv,writer ); 125 writer.printTag( "</javadoc>" ); 126 } 127 catch( final Throwable th ) { 128 reporter.print(Kind.ERROR, th.getMessage()); 129 } 130 131 return true; 132 } 133 134 /** 135 * DocletEnvironmentよりコンテンツを作成します。 136 * 137 * @og.rev 7.3.0.0 (2021/01/06) 新しいJavaDoc対応 138 * @og.rev 8.0.0.0 (2021/07/31) Avoid instantiating new objects inside loops 139 * @og.rev 8.0.2.1 (2021/12/10) コメント分割で『。』と半角の『。』の両方対応しておく。 140 * 141 * @param docEnv ドックレットの最上位 142 * @param writer DocTreeWriterオブジェクト 143 */ 144 private void writeContents( final DocletEnvironment docEnv, final DocTreeWriter writer ) { 145// docUtil = docEnv.getDocTrees(); 146 final DocTrees docUtil = docEnv.getDocTrees(); 147 final Elements eleUtil = docEnv.getElementUtils(); 148 typUtil = docEnv.getTypeUtils(); 149 150 final StringBuilder modiBuf = new StringBuilder(); // 8.0.0.0 (2021/07/31) Avoid instantiating new objects inside loops 151 final StringBuilder buf = new StringBuilder(); // 8.0.0.0 (2021/07/31) Avoid instantiating new objects inside loops 152 153 // クラス単位にループする。 154 for( final TypeElement typEle : ElementFilter.typesIn(docEnv.getIncludedElements())) { 155 final String fullName = String.valueOf( typEle.getQualifiedName() ) ; 156 writer.setClassName( fullName ); 157 158 final String className = String.valueOf( typEle.getSimpleName() ); 159 160// final StringBuilder modiBuf = new StringBuilder(); 161 modiBuf.setLength( 0 ) ; // 8.0.0.0 (2021/07/31) 162 typEle.getModifiers().forEach( modi -> modiBuf.append( modi ).append( ' ' ) ); 163 final ElementKind eleKind = typEle.getKind(); 164 if( ElementKind.CLASS.equals( eleKind ) ) { modiBuf.append( "class" ); } 165 final String modifiers = modiBuf.toString().trim(); 166 167 final TypeMirror superType = typEle.getSuperclass(); 168 final String superClass = TypeKind.NONE.equals( superType.getKind() ) ? "" : superType.toString(); 169 170 final String intFase = Stream.of( typEle.getInterfaces() ) 171 .map( typ -> String.valueOf(typ) ) 172 .collect( Collectors.joining( "," ) ); 173 174 final DocCommentTree docTree = docUtil.getDocCommentTree(typEle); // ドキュメンテーション・コメントが見つからない場合、null が返る。 175 176// final List<? extends DocTree> desc = docTree == null ? EMPTY_LIST : docTree.getFirstSentence(); 177// final List<? extends DocTree> cmnt = docTree == null ? EMPTY_LIST : docTree.getFullBody(); 178 final String[] cmnts = getTitleCmnt( docTree ); // 8.0.2.1 (2021/12/10) 179 180 final Map<String,List<String>> blkTagMap = blockTagsMap(docTree); 181 final String smplTags = getBlockTag( OG_FOR_SMPL, blkTagMap, "" ); 182 final String revTags = getBlockTag( OG_REV , blkTagMap, "\n" ); 183 final String createVer = getBlockTag( DOC_VERSION, blkTagMap, "" ); 184 final String author = getBlockTag( DOC_AUTHOR , blkTagMap, "" ); 185 final String since = getBlockTag( DOC_SINCE , blkTagMap, "" ); 186 final String grpTags = getBlockTag( OG_GROUP , blkTagMap, "," ); 187 188 // 5.7.1.1 (2013/12/13) タグのインデントを止める。 189 writer.printTag( "<classDoc>" ); 190 writer.printTag( " <fullName>" ,fullName ,"</fullName>" ); 191 writer.printTag( " <modifiers>" ,modifiers ,"</modifiers>" ); 192 writer.printTag( " <className>" ,className ,"</className>" ); 193 writer.printTag( " <superClass>" ,superClass ,"</superClass>" ); 194 writer.printTag( " <interface>" ,intFase ,"</interface>" ); 195 writer.printTag( " <createVer>" ,createVer ,"</createVer>" ); 196 writer.printTag( " <author>" ,author ,"</author>" ); 197 writer.printTag( " <since>" ,since ,"</since>" ); 198// writer.printTag( " <description>" ,desc ,"</description>" ); 199 writer.printTag( " <description>" ,cmnts[0] ,"</description>" ); // 8.0.2.1 (2021/12/10) 200// writer.printTag( " <contents>" ,cmnt ,"</contents>" ); 201 writer.printTag( " <contents>" ,cmnts[1] ,"</contents>" ); // 8.0.2.1 (2021/12/10) 202 writer.printTag( " <classGroup>" ,grpTags ,"</classGroup>" ); 203 writer.printTag( " <formSample>" ,smplTags ,"</formSample>" ); 204 writer.printTag( " <history>" ,revTags ,"</history>" ); 205 206 // 5.1.9.0 (2010/08/01) ソースチェック用(コメントや概要が無い場合。スーパークラスは省く) 207// if( debugLevel >= 2 && ( cmnt.isEmpty() || desc.isEmpty() ) && superClass.isEmpty() ) { 208 if( debugLevel >= 2 && ( cmnts[0].isEmpty() || cmnts[1].isEmpty() ) && superClass.isEmpty() ) { // 8.0.2.1 (2021/12/10) 209 // final DocSourcePositions srcPos = docUtil.getSourcePositions(); 210 // System.err.println( "警告2:コメントC=\t" + srcPos ); 211 System.err.println( "②警告2:コメントC=\t" + typEle ); 212 } 213 214 int extendFlag = 0; // 0:オリジナル 1:org.opengion関連Extend 2:Java関連Extend 215 216 // 6.4.3.0 (2016/02/05) PMDチェックのDocletでのフォロー。 217 // checkPMD( typEle ); 218 219 // 5.6.6.0 (2013/07/05) VERSION staticフィールドと、@og.rev コメントの比較チェック 220 // while 以下で、fullName と classDoc を順番に上にさかのぼっているので、先にチェックします。 221 // checkTag2( typEle ); 222 223 mtdClsSet.clear(); 224 TypeElement loopEle = typEle; 225 String superName = fullName; 226 while( loopEle != null ) { 227 writer.setClassName( superName ); 228 229 // 対象クラスの スーパークラスを取得しておく(メソッド内で使うのと、上位に上がってく時に使う) 230 final TypeMirror spType = loopEle.getSuperclass(); 231 232 // AbstractObjectPool<java.sql.Connection> の様な型を削除します。 233// final StringBuilder buf = new StringBuilder().append(spType); 234 buf.setLength( 0 ) ; // 8.0.0.0 (2021/07/31) 235 buf.append(spType) ; // 8.0.0.0 (2021/07/31) 236 237 int st = buf.indexOf("<"); 238 int ed = buf.indexOf(">",st); 239 while( st > 0 ) { 240 buf.delete(st,ed+1); 241 st = buf.indexOf("<"); 242 ed = buf.indexOf(">",st); 243 } 244 superName = buf.toString(); 245 // superName = String.valueOf( spType ); 246 247 final String extClass = ( extendFlag == 0 ) ? "" : superName ; 248 249 // コンストラクタのみフィルタリングして取得する 250 for( final ExecutableElement exEle : ElementFilter.constructorsIn(loopEle.getEnclosedElements()) ) { 251 final DocCommentTree dct = docUtil.getDocCommentTree(exEle); // ドキュメンテーション・コメントが見つからない場合、null が返る。 252 if( dct != null && isAction( exEle,extendFlag ) ) { 253 // checkTag( exEle,dct ); // 5.5.4.1 (2012/07/06) チェックを分離 254 menberTag( exEle,dct,CONSTRUCTOR,writer,extendFlag,extClass ); 255 } 256 } 257 258 // メソッドのみフィルタリングして取得する 259 for( final ExecutableElement exEle : ElementFilter.methodsIn(loopEle.getEnclosedElements())) { 260 final DocCommentTree dct = docUtil.getDocCommentTree(exEle); // ドキュメンテーション・コメントが見つからない場合、null が返る。 261 if( dct != null && isAction( exEle,extendFlag ) ) { 262 // checkTag( exEle,dct ); 263 menberTag( exEle,dct,METHOD,writer,extendFlag,extClass ); 264 } 265 } 266 267 // 対象クラス(オリジナル)から、上に上がっていく。 268 if( superName.startsWith( SELECT_PACKAGE ) ) { 269 extendFlag = 1; 270 } 271 else { 272 break; 273 } 274 275 loopEle = eleUtil.getTypeElement(superName); 276 } 277 writer.printTag( "</classDoc>" ); 278 } 279 } 280 281 /** 282 * メンバークラスのXML化を行うかどうか[true/false]を判定します。 283 * 284 * 以下の条件に合致する場合は、処理を行いません。(false を返します。) 285 * 286 * 1.同一クラスを処理中にEXTENDで継承元をさかのぼる場合、すでに同じシグネチャのメソッドが 287 * 存在している。 288 * 2.USE_PRIVATE が true の時の private メソッド 289 * 3.extendFlag が 0以上(1,2)の時の private メソッド 290 * 4.メソッド名におかしな記号(<など)が含まれている場合 291 * 292 * @og.rev 7.3.0.0 (2021/01/06) 新しいJavaDoc対応 293 * 294 * @param menber ExecutableMemberDocオブジェクト 295 * @param extendFlag 継承状態 [0:オリジナル/1:org.opengion関連Extend/2:Java関連Extend] 296 * 297 * @return XML化を行うかどうか[true/false] 298 */ 299 private boolean isAction( final ExecutableElement menber,final int extendFlag ) { 300// final String menberName = String.valueOf( menber.getSimpleName() ) ; 301 final boolean isPrivate = menber.getModifiers().contains( Modifier.PRIVATE ); 302 final boolean isTypeParam = ! menber.getTypeParameters().isEmpty(); 303 final boolean rtn = ! mtdClsSet.add( String.valueOf( menber ) ) // 5.5.4.1 (2012/07/06) メソッドの重複処理判定は、クラス名も含めて行う 304 || USE_PRIVATE && isPrivate 305 || extendFlag > 0 && isPrivate 306 || isTypeParam; // PMD Useless parentheses. 307 308 return ! rtn ; 309 } 310 311// /** 312// * param,return 等の整合性をチェックします。 313// * 314// * @og.rev 7.3.0.0 (2021/01/06) 新しいJavaDoc対応 315// * 316// * @param exEle ExecutableElementオブジェクト 317// * @param menber DocCommentTreeオブジェクト 318// */ 319// private void checkTag( final ExecutableElement exEle , final DocCommentTree menber ) { 320// // 未実装 321// } 322 323// /** 324// * PMDで、チェックしている処理のうち、Docletでフォローできる分をチェックします。 325// * 326// * ※ このチェックは、警告レベル5 のみ集約していますので、呼出元で、制限します。 327// * 328// * @og.rev 7.3.0.0 (2021/01/06) 新しいJavaDoc対応 329// * 330// * @param typEle TypeElementオブジェクト 331// */ 332// private void checkTag2( final TypeElement typEle ) { 333// String cnstVar = null ; // 初期値 334// String seriUID = null ; 335// final String src = "\tsrc/" + String.valueOf(typEle).replace('.','/') + ".java:100" ; // 行が判らないので、100行目 決め打ち 336// 337// // フィールドのみフィルタリングして取得する 338// for( final VariableElement varEle : ElementFilter.fieldsIn(typEle.getEnclosedElements())) { // フィールドだけに絞る 339// final String key = String.valueOf(varEle); 340// if( "VERSION".equals( key ) ) { 341// cnstVar = String.valueOf( varEle.getConstantValue() ); 342// } 343// else if( "serialVersionUID".equals( key ) ) { 344// seriUID = String.valueOf( varEle.getConstantValue() ) + "L"; // 旧JavaDocと違い、"L" まで取ってこれないみたい 345// } 346// } 347// 348// if( cnstVar == null ) { return; } // VERSION が未定義のクラスは処理しない 349// 350// String maxRev = cnstVar ; // 5.7.1.1 (2013/12/13) 初期値 351// boolean isChange = false; // max が入れ替わったら、true 352// 353// // メソッドのみフィルタリングして取得する 354// for( final ExecutableElement exEle : ElementFilter.methodsIn(typEle.getEnclosedElements())) { 355// final DocCommentTree dct = docUtil.getDocCommentTree(exEle); // ドキュメンテーション・コメントが見つからない場合、null が返る。 356// final Map<String,List<String>> blkTagMap = blockTagsMap(dct); 357// final List<String> revTags = blkTagMap.get("og.rev"); 358// 359// if( revTags != null ) { 360// for( final String tag :revTags ) { // 複数存在しているはず 361// final int idx = tag.indexOf( ' ' ); // 最初のスペース 362// if( idx > 0 ) { 363// final String rev = tag.substring( 0,idx ).trim(); 364// if( maxRev.compareTo( rev ) < 0 ) { // revTags の og.rev が大きい場合 365// maxRev = rev ; 366// isChange = true; 367// } 368// } 369// } 370// } 371// } 372// 373// // VERSION 文字列 の定義があり、かつ、max の入れ替えが発生した場合のみ、警告4:VERSIONが古い 374// if( isChange ) { // 5.7.1.1 (2013/12/13) 入れ替えが発生した場合 375// System.err.println( "警告4:VERSIONが古い=\t" + cnstVar + " ⇒ " + maxRev + src ); 376// } 377// 378// // serialVersionUID の定義がある。 379// if( seriUID != null ) { 380// final StringBuilder buf = new StringBuilder(); 381// // maxRev は、最大の Revか、初期のVERSION文字列 例:5.6.6.0 (2013/07/05) 382// for( int i=0; i<maxRev.length(); i++ ) { // 383// final char ch = maxRev.charAt( i ); 384// if( ch >= '0' && ch <= '9' ) { buf.append( ch ); } // 数字だけ取り出す。 例:566020130705 385// } 386// buf.append( 'L' ); // 強制的に、L を追加する。 387// final String maxSeriUID = buf.toString() ; 388// 389// // 5.7.1.1 (2013/12/13) 値の取出し。Long型を表す "L" も含まれている。 390// if( !maxSeriUID.equals( seriUID ) ) { // 一致しない 391// System.err.println( "警告4:serialVersionUIDが古い=\t" + seriUID + " ⇒ " + maxSeriUID + src ); 392// } 393// } 394// } 395 396// /** 397// * PMDで、チェックしている処理のうち、Docletでフォローできる分をチェックします。 398// * 399// * ※ このチェックは、警告レベル5 のみ集約していますので、呼出元で、制限します。 400// * 401// * @og.rev 7.3.0.0 (2021/01/06) 新しいJavaDoc対応 402// * 403// * @param typEle TypeElementオブジェクト 404// */ 405// private void checkPMD( final TypeElement typEle ) { 406// // 未実装 407// } 408 409 /** 410 * メンバークラス(コンストラクタ、メソッド)をXML化します。 411 * 412 * @og.rev 7.3.0.0 (2021/01/06) 新しいJavaDoc対応 413 * @og.rev 8.0.2.1 (2021/12/10) コメント分割で『。』と半角の『。』の両方対応しておく。 414 * 415 * @param menber ExecutableElementオブジェクト 416 * @param docTree DocCommentTreeオブジェクト 417 * @param menberType メンバータイプ(コンストラクタ、メソッド) 418 * @param writer Tagを書き出すWriterオブジェクト 419 * @param extendFlag 継承状態 [0:オリジナル/1::org.opengion関連Extend/2:Java関連Extend] 420 * @param extClass 継承クラス(オリジナルの場合は、空文字列) 421 */ 422 private void menberTag( final ExecutableElement menber, 423 final DocCommentTree docTree , 424 final String menberType, 425 final DocTreeWriter writer, 426 final int extendFlag , 427 final String extClass ) { 428 429 final String modifiers ; 430 431 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 432 menber.getModifiers().forEach( modi -> buf.append( modi ).append( ' ' ) ); 433 if( ElementKind.METHOD.equals( menber.getKind() ) ) { // メソッドの処理。コンストラクタの場合は、返り値がないので処理しない。 434 buf.append( menber.getReturnType() ); 435 } 436 modifiers = buf.toString(); 437 438 final String menberName = String.valueOf( menber.getSimpleName() ); // コンストラクタの場合は、<init> が返る。 439 440 final StringBuilder sigBuf = new StringBuilder().append( menberName ).append( '(' ) ; 441 boolean flag = false; 442 for( final VariableElement valEle : menber.getParameters() ) { 443 flag = true; 444 final Element ele = typUtil.asElement( valEle.asType() ); // 型が対応する要素を持たない場合はnullを返します。 445 final String key = ele == null // 配列や、プリミティブ型の場合は、null になっている。 446 ? String.valueOf( valEle.asType() ) 447 : String.valueOf( ele.getSimpleName() ); 448 449 sigBuf.append( key ).append( ' ' ) 450 .append( valEle.getSimpleName() ).append( ',' ); 451 } 452 453 if( flag ) { sigBuf.deleteCharAt( sigBuf.length()-1 ); } 454 sigBuf.append( ')' ); 455 final String signature = sigBuf.toString(); 456// final String signature = String.valueOf( menber ); 457 458// final List<? extends DocTree> desc = docTree == null ? EMPTY_LIST : docTree.getFirstSentence(); 459// final List<? extends DocTree> cmnt = docTree == null ? EMPTY_LIST : docTree.getFullBody(); 460 final String[] cmnts = getTitleCmnt( docTree ); // 8.0.2.1 (2021/12/10) 461 462 final Map<String,List<String>> blkTagMap = blockTagsMap(docTree); 463 final String revTags = getBlockTag( OG_REV, blkTagMap, "\n" ); 464 465 // tags は、OG_REV 以外のすべてで、かつ、キーワードも含む。 466 final StringBuilder tagBuf = new StringBuilder(); 467 if( docTree != null ) { 468 for( final DocTree dt : docTree.getBlockTags() ) { 469 final String tag = String.valueOf(dt).trim(); 470 if( !tag.contains( OG_REV ) ) { tagBuf.append( tag ).append( '\n' ); } 471 } 472 } 473 final String tags = tagBuf.toString().trim(); 474 475// final StringBuilder tagBuf = new StringBuilder(); 476// final StringBuilder revBuf = new StringBuilder(); 477// if( docTree != null ) { 478// for( final DocTree dt : docTree.getBlockTags() ) { 479// final String tag = String.valueOf(dt).trim(); 480// if( tag.contains( OG_REV ) ) { revBuf.append( cutTag( tag,OG_REV ) ).append( '\n' ); } 481// else { tagBuf.append( tag ).append( '\n' ); } 482// } 483// } 484// final String revTags = revBuf.toString().trim(); 485// final String tags = tagBuf.toString().trim(); 486 487 final String extend = String.valueOf( extendFlag ); 488 489 // final DocSourcePositions srcPos = docUtil.getSourcePositions(); 490 // final String position = String.valueOf( srcPos.getStartPosition( null,docTree,null ) ); 491 final String position = ""; 492 493 writer.printTag( " <menber>" ); 494 writer.printTag( " <type>" ,menberType ,"</type>" ); 495 writer.printTag( " <name>" ,menberName ,"</name>" ); 496 writer.printTag( " <modifiers>" ,modifiers ,"</modifiers>" ); 497 writer.printTag( " <signature>" ,signature ,"</signature>" ); 498 writer.printTag( " <position>" ,position ,"</position>" ); 499 writer.printTag( " <extendClass>",extClass ,"</extendClass>" ); 500 writer.printTag( " <extendFlag>" ,extend ,"</extendFlag>" ); 501// writer.printTag( " <description>",desc ,"</description>" ); 502 writer.printTag( " <description>",cmnts[0] ,"</description>" ); // 8.0.2.1 (2021/12/10) 503// writer.printTag( " <contents>" ,cmnt ,"</contents>" ); 504 writer.printTag( " <contents>" ,cmnts[1] ,"</contents>" ); // 8.0.2.1 (2021/12/10) 505 writer.printTag( " <tagText>" ,tags ,"</tagText>" ); 506 writer.printTag( " <history>" ,revTags ,"</history>" ); 507 writer.printTag( " </menber>"); 508 } 509 510 /** 511 * サポートされているすべてのオプションを返します。 512 * 513 * @return サポートされているすべてのオプションを含むセット、存在しない場合は空のセット 514 */ 515 @Override 516 public Set<? extends Option> getSupportedOptions() { 517 final Option[] options = { 518 new AbstractOption( "-outfile", "-version", "-debugLevel" ) { 519 520 /** 521 * 必要に応じてオプションと引数を処理します。 522 * 523 * @param opt オプション名 524 * @param arguments 引数をカプセル化したリスト 525 * @return 操作が成功した場合はtrue、そうでない場合はfalse 526 */ 527 @Override 528 public boolean process(final String opt, final List<String> arguments) { 529 if( "-outfile".equalsIgnoreCase(opt) ) { 530 outfile = arguments.get(0); 531 } 532 else if( "-version".equalsIgnoreCase(opt) ) { 533 version = arguments.get(0); 534 } 535 else if( "-debugLevel".equalsIgnoreCase(opt) ) { 536 debugLevel = Integer.parseInt( arguments.get(0) ); 537 } 538 return true; 539 } 540 } 541 }; 542 return new HashSet<>(Arrays.asList(options)); 543 } 544}