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.util;
017
018 import java.io.IOException;
019 import java.io.File;
020
021 import java.util.List;
022 import java.util.ArrayList;
023 import java.util.Enumeration;
024 import java.util.jar.JarFile;
025 import java.util.jar.JarEntry;
026 import java.net.URL;
027
028 /**
029 * ã“ã?クラスã¯ã€æŒ‡å®šã?ãƒ?‚£ãƒ¬ã‚¯ãƒˆãƒªãƒ‘スã‹ã‚‰ .class ファイルを検索ã™ã‚‹ã‚¯ãƒ©ã‚¹ã§ã™ã?
030 * 検索パスã¯ã€å®Ÿãƒ•ァイルã¨ã€zipファイルã®å†?ƒ¨ã€jar ファイルã®å†?ƒ¨ã‚‚å«ã¿ã¾ã™ã?
031 * æ¤œç´¢çµæžœã¯ã€?class ã‚’å–り除ãã?ファイルパスをã?ã™ã¹ã¦ãƒ‰ãƒƒãƒ?.)ã«å¤‰æ›ã—ãŸå½¢å¼ã«ã—ã¾ã™ã?
032 * ã“れã¯ã€ã»ã¨ã‚“ã©ã‚¯ãƒ©ã‚¹ã®ãƒ•ルパスæ–?—å?ã«ç›¸å½“ã—ã¾ã™ã?
033 * ã“ã“ã§å–å¾—ã•れãŸãƒ•ァイルåよりã?実クラスオブジェクトã?作æ?ãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã?
034 *
035 * ã“ã?クラス㮠main メソãƒ?ƒ‰ã¯ã€ã‚¯ãƒ©ã‚¹ãƒ‘スã‹ã‚‰æŒ?®šã?åå‰ã‚’æŒã¤ã‚¯ãƒ©ã‚¹ä»¥ä¸‹ã?ãƒ?‚£ãƒ¬ã‚¯ãƒˆãƒªã‚ˆã‚Š
036 * ファイルを検索ã—ã¾ã™ã?通常ã€ã“ã®ã‚¯ãƒ©ã‚¹ã®ä½¿ã?–¹ã¨ã—ã¦ã€å–å¾—ã—ãŸã‚¯ãƒ©ã‚¹ãƒ•ァイルå?æ–?—å?)
037 * ã‹ã‚‰ã€å¼•æ•°ãªã—コンストラクタを呼ã³å‡ºã—ã¦ã€å®Ÿã‚ªãƒ–ジェクトを生æ?ã•ã›ã‚‹ã?ã§ã€??常ã®ãƒ•ォルãƒ?
038 * ã‹ã‚‰æ¤œç´¢ã™ã‚‹ã‚ˆã‚Šã€ã‚¯ãƒ©ã‚¹ãƒ‘スå†?‹ã‚‰æ¤œç´¢ã™ã‚‹ãƒšã?スãŒå¤šã„ãŸã‚ã€ã‚µãƒ³ãƒ—ルをãã®ã‚ˆã†ã«è¨å®?
039 * ã—ã¦ã?¾ã™ã?
040 *
041 * @og.rev 4.0.0.0 (2004/12/31) æ–°è¦ä½œæ?
042 * @og.group åˆæœŸåŒ?
043 *
044 * @version 4.0
045 * @author Kazuhiko Hasegawa
046 * @since JDK5.0,
047 */
048 public final class FindClassFiles {
049 private final List<String> list = new ArrayList<String>();
050 private final int baseLen;
051
052 private static final String SUFIX = ".class" ;
053 private static final int SUFIX_LEN = SUFIX.length();
054
055 /**
056 * 検索パスを指定ã—ã¦æ§‹ç¯‰ã™ã‚‹ã?コンストラクタã§ã™ã?
057 * ã“ã“ã§è¦‹ã¤ã‹ã£ãŸãƒ‘ス以下ã? classファイル(æ‹¡å¼µåã?å°æ–‡å—ã§ã€?class )を検索ã—ã¾ã™ã?
058 * ã“ã?ファイルåã? ファイルパスã‚?ドッãƒ?.)ã«ç½®ãæ›ãˆã?.class ã‚’å–り除ã?Ÿæ ¼ç´ã—ã¦ãŠãã¾ã™ã?
059 *
060 * @og.rev 4.0.3.0 (2007/01/07) UNIXパス検索時ã?ã€ãƒ•ァイルパスã®å–得方法ã?ä¸å?åˆå¯¾å¿?
061 * @og.rev 5.0.0.0 (2009/08/03) UNIXパス検索時ã?ã€ãƒ•ァイルパスã®å–得方法ã?ä¸å?åˆå¯¾å¿?
062 *
063 * @param filepath 対象ã¨ãªã‚‹ãƒ•ァイル群を検索ã™ã‚‹ã€ãƒ•ァイルパス
064 * @param prefix 検索対象ファイルã®ãƒ—レフィãƒ?‚¯ã‚¹
065 */
066 public FindClassFiles( final String filepath,final String prefix ) {
067 // jar:file:/実ディレクトリ!å…ˆé?クラス ã¾ãŸã?ã€file:/実ディレクトリ
068
069 // String dir = null;
070 String dir = filepath; // 5.5.2.6 (2012/05/25) findbugs対�
071 if( filepath.startsWith( "jar:" ) || filepath.startsWith( "file:" )
072 // || ( filepath.charAt(0) == '/' && filepath.charAt(2) == ':' ) ) {
073 || ( filepath.charAt(0) == '/' ) ) { // 4.4.0.0 (2009/08/02)
074 int stAdrs = filepath.indexOf( '/' );
075 if( filepath.charAt(stAdrs+2) == ':' ) { // 4.0.3.0 (2007/01/07)
076 stAdrs++;
077 }
078 int edAdrs = filepath.lastIndexOf( '!' );
079 if( edAdrs < 0) {
080 edAdrs = filepath.length() - 1;
081 }
082
083 dir = filepath.substring( stAdrs,edAdrs );
084 }
085
086 File basefile = new File( dir );
087 String baseFilename = basefile.getAbsolutePath() ;
088 baseLen = baseFilename.length() - prefix.length();
089 findFilename( basefile );
090 }
091
092 /**
093 * ファイルパスã‚?ドッãƒ?.)ã«ç½®ãæ›ãˆã?.class ã‚’å–り除ã?Ÿå½¢å¼?クラスã®å®Œå?ç³»)ã®æ–?—å?é…å?
094 *
095 * @return ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ã‚¹ã®æ–?—å?é…å?
096 */
097 public String[] getFilenames() {
098 return list.toArray( new String[list.size()] );
099 }
100
101 /**
102 * ファイルをå?帰çš?«æ¤œç´¢ã—ã¾ã™ã?
103 * æŒ?®šã?ファイルオブジェクト㌠ファイルã®å ´åˆã?ã€?class ã§ã‚れã°Listã«è¿½åŠ?—ã€?
104 * .zip ã?.jar ã§ã¯ã€findJarFiles を呼ã³å‡ºã—ã¾ã™ã?
105 * ファイルã§ãªã??åˆã?ã€??列をå–り出ã—ã?自åˆ??身をå?帰çš?«å‘¼ã³å‡ºã—ã¾ã™ã?
106 *
107 * @param file ファイル
108 */
109 private void findFilename( final File file ) {
110 if( file.isFile() ) {
111 String name = file.getAbsolutePath();
112 if( name.endsWith( SUFIX ) ) {
113 list.add( name.substring( baseLen,name.length()-SUFIX_LEN ).replace( File.separatorChar,'.' ) );
114 }
115 else if( name.endsWith( ".jar" ) || name.endsWith( ".zip" ) ) {
116 findJarFiles( name );
117 }
118 }
119 else {
120 File[] filelist = file.listFiles();
121 for( int i=0; i<filelist.length; i++ ) {
122 findFilename( filelist[i] );
123 }
124 }
125 }
126
127 /**
128 * jar/zipファイルを検索ã—ã¾ã™ã?
129 * 圧縮ファイルã§ã¯ã€?šŽå±¤ã§ã¯ãªãã?Enumeration ã¨ã—ã¦ãƒ•ァイルをå–りå?ã—ã¾ã™ã?
130 * æ‹¡å¼µåã§åˆ¤æ–ã—ã¦ã€Listã«è¿½åŠ?—ã¦ã?ã¾ã™ã?
131 *
132 * @og.rev 5.5.2.6 (2012/05/25) JarFile ã‚’ã?Closer#zipClose( ZipFile ) メソãƒ?ƒ‰ã‚’利用ã—ã¦ã€close ã—ã¾ã™ã?
133 *
134 * @param filename ファイルå?
135 */
136 private void findJarFiles( final String filename ) {
137 // 5.5.2.6 (2012/05/25) findbugs対�
138 JarFile jarFile = null;
139 try {
140 // JarFile jarFile = new JarFile( filename );
141 jarFile = new JarFile( filename );
142 Enumeration<JarEntry> en = jarFile.entries() ;
143 while( en.hasMoreElements() ) {
144 JarEntry ent = en.nextElement();
145 if( ! ent.isDirectory() ) {
146 String name = ent.getName();
147 if( name.endsWith( SUFIX ) ) {
148 list.add( name.substring( 0,name.length()-SUFIX_LEN ).replace( '/','.' ) );
149 }
150 }
151 }
152 }
153 catch( IOException ex ) {
154 String errMsg = "ファイルèªã¿å–りストリーãƒ?«å¤±æ•—ã—ã¾ã—ãŸã€?
155 + " File=" + filename
156 + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg ä¿®æ£
157 throw new RuntimeException( errMsg,ex );
158 }
159 // 5.5.2.6 (2012/05/25) findbugs対�
160 finally {
161 Closer.zipClose( jarFile );
162 }
163 }
164
165 /**
166 * サンプルメイン
167 * ã“ã“ã§ã¯ã€å¼•æ•°ã«é€šå¸¸ã®ãƒ•ァイルã§ã¯ãªãã?クラスパスよりå–å¾—ã—ã¾ã™ã?
168 * 通常ã€å–å¾—ã•れãŸãƒ•ァイルåã?ã€ã‚¯ãƒ©ã‚¹ã®å®Œå?ç³»ã®æ–?—å?ãªã®ã§ã€ã‚¯ãƒ©ã‚¹ãƒ‘スよりå–å¾?
169 * ã—ã¦ã?‚‹é™ã‚Šã€ãã®ã¾ã¾ オブジェクトを構築ã§ãã‚‹ã“ã¨ã‚’æ„味ã—ã¾ã™ã?
170 *
171 * @param args 引数
172 */
173 public static void main( final String[] args ) {
174 try {
175 ClassLoader loader = Thread.currentThread().getContextClassLoader();
176 Enumeration<URL> enume = loader.getResources( args[0] ); // 4.3.3.6 (2008/11/15) Genericsè¦å‘Šå¯¾å¿?
177 while( enume.hasMoreElements() ) {
178 URL url = enume.nextElement(); // 4.3.3.6 (2008/11/15) Genericsè¦å‘Šå¯¾å¿?
179 // jar:file:/実ディレクトリ!å…ˆé?クラス ã¾ãŸã?ã€file:/実ディレクトリ
180 System.out.println( "url=" + url.getFile() );
181
182 FindClassFiles filenames = new FindClassFiles( url.getFile(),args[0] );
183 String[] names = filenames.getFilenames();
184 for( int i=0; i<names.length; i++ ) {
185 System.out.println( names[i] );
186 }
187 }
188 }
189 catch( IOException ex ) {
190 String errMsg = "ファイルèªã¿å–りストリーãƒ?«å¤±æ•—ã—ã¾ã—ãŸã€?
191 + ex.getMessage();
192 throw new RuntimeException( errMsg,ex );
193 }
194 }
195 }