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 java.lang.reflect.Field;
019
020 import com.sun.javadoc.Tag;
021 import com.sun.javadoc.Doc;
022 import com.sun.javadoc.MethodDoc;
023 import com.sun.javadoc.ClassDoc;
024 import com.sun.javadoc.PackageDoc;
025 import com.sun.javadoc.ProgramElementDoc;
026
027 /**
028 * Doclet をå?ç�?�™るã?ログラãƒ?�§共通して使用される簡易メソãƒ?ƒ‰群(ユーãƒ?‚£リãƒ?‚£クラス)ですã?
029 *
030 * @version 4.0
031 * @author Kazuhiko Hasegawa
032 * @since JDK5.0,
033 */
034 public final class DocletUtil {
035 /** リターンコーãƒ? System.getProperty("line.separator") */
036 public static final String CR = System.getProperty("line.separator");
037
038 private static final String CLS = "org.opengion.hayabusa.common.BuildNumber"; // package.class
039 private static final String FLD = "VERSION_NO"; // field
040 private static String versionNo = null; // æœ??にä¸?º¦ã�?�‘取得しておきますã?
041
042 /**
043 * すべてã�?staticメソãƒ?ƒ‰なので、コンストラクタを呼び出さなくしておきますã?
044 *
045 */
046 private DocletUtil() {}
047
048 /**
049 * 入力文字å?の HTML æ–?—をフィルタリングしますã?
050 * "&" はã€?&#38;" ã€?<" はã€?&lt;" ã€?>" はã€?&gt;" に変換しますã?
051 * StringUtil.htmlFilter との違いはã€?;' â†?";" への変換があることですã?
052 *
053 * @og.rev 5.5.4.1 (2012/07/06) DocletUtil.htmlFilter â†?StringUtil.htmlFilter に変更のため、å»?¢
054 *
055 * @param input String
056 *
057 * @return 変換後文字å?
058 */
059 // public static String htmlFilter( final String input ) {
060 // if( input == null ) { return ""; }
061 //
062 // int len = input.length();
063 //
064 // StringBuilder rtn = new StringBuilder( len + 50 );
065 // char ch;
066 // for(int i=0; i<len; i++) {
067 // ch = input.charAt(i);
068 // switch( ch ) {
069 // case '<' : rtn.append("<"); break;
070 // case '>' : rtn.append(">"); break;
071 // case '"' : rtn.append("""); break;
072 // case '\'' : rtn.append("'"); break;
073 // case '&' : rtn.append("&"); break;
074 // case ';' : rtn.append(";"); break;
075 // default : rtn.append(ch);
076 // }
077 // }
078 // return( rtn.toString() );
079 // }
080
081 /**
082 * target æ–?—å?に含まれる from æ–?—å?ã‚?to æ–?—å?に置き換えますã?
083 *
084 * @param target å…??æ–?—å?
085 * @param from 置換å?FROM
086 * @param to 置換å?TO
087 *
088 * @return 変換後文字å?
089 */
090 public static String replace( final String target,final String from,final String to ) {
091 if( target == null || from == null || to == null ) { return target; }
092 StringBuilder strBuf = new StringBuilder( 200 );
093
094 int start = 0;
095 int end = target.indexOf( from,start );
096 while( end >= 0 ) {
097 strBuf.append( target.substring( start,end ) );
098 strBuf.append( to );
099 start = end + from.length();
100 end = target.indexOf( from,start );
101 }
102 strBuf.append( target.substring( start ) );
103
104 return strBuf.toString();
105 }
106
107 /**
108 * コメント部のæ–?—å?を取得しますã?
109 *
110 * @og.rev 5.5.4.1 (2012/07/06) コメントã?æ–?—å?でなくã?Tag配å?として処ç�?�•せるã€?
111 *
112 * @param cmnt String
113 *
114 * @return コメント文字å?
115 */
116 // public static String commentText( final String cmnt ) {
117 // if( cmnt == null ) { return ""; }
118 //
119 // String rtn = cmnt;
120 // int indx = cmnt.indexOf( "{@value}" );
121 // if( indx >= 0 ) {
122 // rtn = cmnt.substring( indx+8 ); // {@value} 以前を削除
123 // }
124 // return htmlFilter( rtn );
125 // }
126
127 /**
128 * セãƒ?‚¿ーメソãƒ?ƒ‰の setXXXX の set を削除しã?次のæ–?—を小文字化しますã?
129 * つまりã?セãƒ?‚¿ーメソãƒ?ƒ‰から属æ?値を推測しますã?
130 * (è¶?‰¹殊å?ç�?セãƒ?‚¿ーメソãƒ?ƒ‰のset以下2文字目が大æ–?—ã?場合ã?ã€?
131 * ?‘文字目も大æ–?—とè€?�ˆて小文字化を行いませんã€?
132 * 例えば、setSYS ã‚?setUSER など、RequestValueTag.javaに使用するケースですã?
133 *
134 * @param target 処ç�?¯¾象となる文字å?
135 *
136 * @return オプションæ–?—å?
137 */
138 public static String removeSetter( final String target ) {
139 if( target != null && target.startsWith( "set" ) ) {
140 char[] chs = target.toCharArray();
141 if( chs.length > 4 && !( chs[4] >= 'A' && chs[4] <= 'Z' ) ) {
142 chs[3] = Character.toLowerCase( chs[3] ) ;
143 }
144 return new String( chs,3,chs.length-3 );
145 }
146 return target;
147 }
148
149 /**
150 * オプション配å?æ–?—å?より、指定ã?キーに対応するオプション値を返しますã?
151 *
152 * @param key キー
153 * @param options オプション配å?æ–?—å?
154 *
155 * @return オプションæ–?—å?
156 */
157 public static String getOption( final String key , final String[][] options ) {
158 String rtn = "";
159 if( key == null || options == null ) { return rtn; }
160
161 for( int i=0; i<options.length; i++ ) {
162 if( key.equalsIgnoreCase( options[i][0] ) ) {
163 rtn = options[i][1];
164 break ;
165 }
166 }
167 return rtn ;
168 }
169
170 /**
171 * {@og.value package.class#field} 形式ã?valueタグを文字å?に置き換えますã?
172 *
173 * 処ç�?š„には、リフレクションで、å?を取得しますã?値は、staticフィールドã?み取得可能ですã?
174 *
175 * @og.rev 5.5.4.1 (2012/07/06) 新規追åŠ?
176 * @og.rev 5.5.5.6 (2012/08/31) クラス名ã?取得で、ProgramElementDoc で処ç�?�™るよã�?�«変更
177 *
178 * @param tag Tagオブジェクãƒ?
179 *
180 * @return valueタグの解析結果のæ–?—å?
181 */
182 public static String valueTag( final Tag tag ) {
183 String txt = tag.text();
184 if( txt != null ) {
185 String cls = null; // package.class
186 String fld = null; // field
187
188 // package.class#field 形式ã?解析ã?
189 int adrs = txt.indexOf('#') ;
190 if( adrs > 0 ) {
191 cls = txt.substring( 0,adrs ); // package.class
192 fld = txt.substring( adrs+1 ); // field
193 }
194 else if( adrs == 0 ) {
195 fld = txt.substring( 1 ); // #field
196 }
197 else {
198 String errMsg = "警å‘?{@value package.class#field} 形式ã? フィールド名 #field がありませんã€? + CR
199 + tag.position() + " : " + txt + CR ;
200 System.err.println( errMsg );
201 // # を付け忘れたとè€?�ˆ、è?åˆ??身のクラスを利用
202 fld = txt; // field
203 }
204
205 // package.class をきちんと作æ?するã€?
206 Doc doc = tag.holder();
207 // if( doc.isMethod() ) {
208 // MethodDoc mdoc = (MethodDoc)doc;
209 // ClassDoc cdoc = mdoc.containingClass();
210 // if( cls == null ) { // package.class が登録されてã�?�ªã�??合ã?
211 // cls = cdoc.qualifiedName() ;
212 // }
213 // else if( cls.indexOf('.') < 0 ) { // class のみが登録されてã�?‚‹場合ã?findClass で、package 込の正式クラス名を検索するã€?
214 // ClassDoc pdoc = cdoc.findClass( cls );
215 // cls = pdoc.qualifiedName() ;
216 // }
217 // }
218
219 // 5.5.5.6 (2012/08/31) ProgramElementDoc で処ç�?�™るよã�?�«変更
220 if( doc instanceof ProgramElementDoc ) {
221 ProgramElementDoc pdoc = (ProgramElementDoc)doc;
222 ClassDoc cdoc = pdoc.containingClass();
223 if( cdoc != null ) {
224 if( cls == null ) { // package.class が登録されてã�?�ªã�??合ã?
225 cls = cdoc.qualifiedName() ;
226 }
227 else if( cls.indexOf('.') < 0 ) { // class のみが登録されてã�?‚‹場合ã?findClass で、package 込の正式クラス名を検索するã€?
228 ClassDoc fdoc = cdoc.findClass( cls );
229 if( fdoc != null ) {
230 cls = fdoc.qualifiedName() ;
231 }
232 }
233 }
234 else {
235 if( cls == null ) { // package.class が登録されてã�?�ªã�??合ã?
236 cls = pdoc.qualifiedName() ;
237 }
238 }
239 }
240
241 // 5.6.3.3 (2013/04/19) メソãƒ?ƒ‰化で共有しますã?
242 txt = getStaticField( cls,fld );
243
244 // try {
245 // Field fldObj = Class.forName( cls ).getDeclaredField( fld );
246 // // privateフィールドへのアクセスã€?セキュリãƒ?‚£ーマネージャーによってアクセス制限がかけられてã�?�ªã�??å�?
247 // if( !fldObj.isAccessible() ) { fldObj.setAccessible( true ); }
248 // txt = String.valueOf( fldObj.get( null ) ); // static フィールドã?、引数 null で値を取å¾?
249 // }
250 // catch( Exception ex ) {
251 // String errMsg = "警å‘?{@value package.class#field} 形式ã?対象がありませんã€? + CR
252 // + tag.position() + " : " + tag.text() + CR
253 // + ex.getMessage() + CR;
254 // System.err.println( errMsg );
255 // }
256 }
257 return txt ;
258 }
259
260 /**
261 * {@og.doc03Link queryType Query_**** クラス} 形式ã?doc03Linkタグをリンクæ–?—å?に置き換えますã?
262 *
263 * <a href="/gf/jsp/DOC03/index.jsp?command=NEW&GAMENID=DOC03&VERNO=X.X.X.X&VALUENAME=queryType" target="CONTENTS">Query_**** クラス</a>
264 * のようなリンクを作æ?しますã?
265 * 第ä¸?¼•数は、VALUENAME の引数ですã?
266 * それ以降ã?ãƒ?‚ストã?、リンクæ–?—å?のドキュメントになりますã?
267 * DOC03 画面へのリンクを作æ?するに当たりã?バã?ジョンがå¿?¦�ですã?org.opengion.hayabusa.common.BuildNumber#VERSION_NO から取得しますがã€?
268 * パッケージの優先é?の関係で、リフレクションを使用しますã?
269 *
270 * @og.rev 5.6.3.3 (2013/04/19) 新規作æ?
271 *
272 * @param tag Tagオブジェクãƒ?
273 *
274 * @return valueタグの解析結果のæ–?—å?
275 */
276 public static String doc03LinkTag( final Tag tag ) {
277 if( versionNo == null ) { versionNo = getStaticField( CLS , FLD ); }
278
279 String txt = tag.text();
280 if( txt != null ) {
281 String valnm = null; // VALUENAME
282 String body = null; // ドキュメンãƒ?
283
284 int adrs = txt.indexOf(' ') ; // æœ??のスペã?スでåˆ?›¢しますã?
285 if( adrs > 0 ) {
286 valnm = txt.substring( 0,adrs ); // VALUENAME
287 body = txt.substring( adrs+1 ); // ドキュメンãƒ?
288 }
289 else {
290 valnm = txt; // VALUENAME
291 body = txt; // ドキュメンãƒ?
292 }
293
294 txt = "<a href=\"/gf/jsp/DOC03/index.jsp?command=NEW&GAMENID=DOC03"
295 + "&VERNO=" + versionNo
296 + "&VALUENAME=" + valnm
297 + "\" target=\"CONTENTS\">"
298 + body
299 + "</a>" ;
300 }
301 return txt ;
302 }
303
304 /**
305 * パッケージ.クラスå�?と、フィールド名 から、staticフィールドã?値を取得しますã?
306 *
307 * Field fldObj = Class.forName( cls ).getDeclaredField( fld ); で、Fieldオブジェクトを呼出しã?
308 * String.valueOf( fldObj.get( null ) ); で、å?を取得してã�?�¾すã?
309 * static フィールドã?、引数 null で値を取得できますã?
310 *
311 * 例ï¼?
312 * String cls = "org.opengion.hayabusa.common.BuildNumber"; // package.class
313 * String fld = "VERSION_NO"; // field
314 *
315 * @og.rev 5.6.3.3 (2013/04/19) 新規作æ?
316 *
317 * @param cls パッケージ.クラスå�?
318 * @param fld フィールド名
319 * @return 取得å?
320 */
321 public static String getStaticField( final String cls , final String fld ) {
322
323 String txt = null;
324 try {
325 Field fldObj = Class.forName( cls ).getDeclaredField( fld );
326 // privateフィールドへのアクセスã€?セキュリãƒ?‚£ーマネージャーによってアクセス制限がかけられてã�?�ªã�??å�?
327 if( !fldObj.isAccessible() ) { fldObj.setAccessible( true ); }
328 txt = String.valueOf( fldObj.get( null ) ); // static フィールドã?、引数 null で値を取å¾?
329 }
330 catch( Exception ex ) {
331 String errMsg = "package.class = " + cls + " field = " + fld + " の取得に失敗しましたã€?
332 + ex.getMessage() + CR;
333 System.err.println( errMsg );
334 }
335
336 return txt ;
337 }
338 }