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 }