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 }