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 * ※ Tomcat8.0.3 ã§ã¯ã€ClassLoader ã® getResources(String)ã§å–å¾—ã™ã‚‹URLåãŒã€? 061 * /C:/opengionV6/uap/webapps/gf/WEB-INF/classes/org/opengion/plugin/ 062 * ã®å½¢å¼ã§ã€æœ€å¾Œã? "/" ã‚’å–る為ã€filepath.length() - 1 処ç?—ã¦ã?¾ã—ãŸãŒã? 063 * Tomcat8.0.5 ã§ã¯ã€?C:/opengionV6/uap/webapps/gf/WEB-INF/classes/org/opengion/plugin 064 * ã®å½¢å¼ã§ã€æœ€å¾Œã? "/" ãŒãªããªã£ã¦ã?¾ã™ã? 065 * æœ?¾Œã? "/" ãŒã‚ã£ã¦ã‚‚ãªãã¦ã‚‚ã?new File(String) ã§ãƒ?‚£ãƒ¬ã‚¯ãƒˆãƒªã®ã‚ªãƒ–ジェクトを 066 * 作æ?ã§ãã‚‹ãŸã‚ã€filepath.length() ã«å¤‰æ›´ã—ã¾ã™ã? 067 * 068 * @og.rev 4.0.3.0 (2007/01/07) UNIXパス検索時ã?ã€ãƒ•ァイルパスã®å–得方法ã?ä¸å?åˆå¯¾å¿? 069 * @og.rev 5.0.0.0 (2009/08/03) UNIXパス検索時ã?ã€ãƒ•ァイルパスã®å–得方法ã?ä¸å?åˆå¯¾å¿? 070 * @og.rev 5.0.0.0 (2009/08/03) UNIXパス検索時ã?ã€ãƒ•ァイルパスã®å–得方法ã?ä¸å?åˆå¯¾å¿? 071 * @og.rev 5.7.5.0 (2014/04/04) ファイルåã?å–得方法ã?ä¿®æ£ 072 * 073 * @param filepath 対象ã¨ãªã‚‹ãƒ•ァイル群を検索ã™ã‚‹ã€ãƒ•ァイルパス 074 * @param keyword 検索対象ファイルã®ã‚ーワーãƒ? 075 */ 076 // public FindClassFiles( final String filepath,final String prefix ) { 077 public FindClassFiles( final String filepath,final String keyword ) { 078 // jar:file:/実ディレクトリ!å…ˆé?クラス ã¾ãŸã?ã€file:/実ディレクトリ ã¾ãŸã?ã€?実ディレクトリ 079 080 // String dir = null; 081 String dir = filepath; // 5.5.2.6 (2012/05/25) findbugs対å¿? 082 if( filepath.startsWith( "jar:" ) || filepath.startsWith( "file:" ) 083 // || ( filepath.charAt(0) == '/' && filepath.charAt(2) == ':' ) ) { 084 || ( filepath.charAt(0) == '/' ) ) { // 4.4.0.0 (2009/08/02) 085 int stAdrs = filepath.indexOf( '/' ); 086 if( filepath.charAt(stAdrs+2) == ':' ) { // 4.0.3.0 (2007/01/07) 087 stAdrs++; 088 } 089 int edAdrs = filepath.lastIndexOf( '!' ); 090 if( edAdrs < 0) { 091 // edAdrs = filepath.length() - 1; 092 edAdrs = filepath.length(); // 5.7.5.0 (2014/04/04) æœ?¾Œã? "/" ã¯ã‚ã£ã¦ã‚‚ãªãã¦ã‚‚よã?? 093 } 094 dir = filepath.substring( stAdrs,edAdrs ); 095 } 096 097 File basefile = new File( dir ); 098 String baseFilename = basefile.getAbsolutePath() ; 099 // baseLen = baseFilename.length() - prefix.length(); 100 baseLen = baseFilename.length() - keyword.length(); 101 findFilename( basefile ); 102 } 103 104 /** 105 * ファイルパスã‚?ドッãƒ?.)ã«ç½®ãæ›ãˆã?.class ã‚’å–り除ã?Ÿå½¢å¼?クラスã®å®Œå?ç³»)ã®æ–?—å?é…å? 106 * 107 * @return ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ã‚¹ã®æ–?—å?é…å? 108 */ 109 public String[] getFilenames() { 110 return list.toArray( new String[list.size()] ); 111 } 112 113 /** 114 * ファイルをå?帰çš?«æ¤œç´¢ã—ã¾ã™ã? 115 * æŒ?®šã?ファイルオブジェクト㌠ファイルã®å ´åˆã?ã€?class ã§ã‚れã°Listã«è¿½åŠ?—ã€? 116 * .zip ã?.jar ã§ã¯ã€findJarFiles を呼ã³å‡ºã—ã¾ã™ã? 117 * ファイルã§ãªã??åˆã?ã€??列をå–り出ã—ã?自åˆ??身をå?帰çš?«å‘¼ã³å‡ºã—ã¾ã™ã? 118 * 119 * @param file ファイル 120 */ 121 private void findFilename( final File file ) { 122 if( file.isFile() ) { 123 String name = file.getAbsolutePath(); 124 if( name.endsWith( SUFIX ) ) { 125 list.add( name.substring( baseLen,name.length()-SUFIX_LEN ).replace( File.separatorChar,'.' ) ); 126 } 127 else if( name.endsWith( ".jar" ) || name.endsWith( ".zip" ) ) { 128 findJarFiles( name ); 129 } 130 } 131 else { 132 File[] filelist = file.listFiles(); 133 for( int i=0; i<filelist.length; i++ ) { 134 findFilename( filelist[i] ); 135 } 136 } 137 } 138 139 /** 140 * jar/zipファイルを検索ã—ã¾ã™ã? 141 * 圧縮ファイルã§ã¯ã€?šŽå±¤ã§ã¯ãªãã?Enumeration ã¨ã—ã¦ãƒ•ァイルをå–りå?ã—ã¾ã™ã? 142 * æ‹¡å¼µåã§åˆ¤æ–ã—ã¦ã€Listã«è¿½åŠ?—ã¦ã?ã¾ã™ã? 143 * 144 * @og.rev 5.5.2.6 (2012/05/25) JarFile ã‚’ã?Closer#zipClose( ZipFile ) メソãƒ?ƒ‰ã‚’利用ã—ã¦ã€close ã—ã¾ã™ã? 145 * 146 * @param filename ファイルå? 147 */ 148 private void findJarFiles( final String filename ) { 149 // 5.5.2.6 (2012/05/25) findbugs対å¿? 150 JarFile jarFile = null; 151 try { 152 // JarFile jarFile = new JarFile( filename ); 153 jarFile = new JarFile( filename ); 154 Enumeration<JarEntry> en = jarFile.entries() ; 155 while( en.hasMoreElements() ) { 156 JarEntry ent = en.nextElement(); 157 if( ! ent.isDirectory() ) { 158 String name = ent.getName(); 159 if( name.endsWith( SUFIX ) ) { 160 list.add( name.substring( 0,name.length()-SUFIX_LEN ).replace( '/','.' ) ); 161 } 162 } 163 } 164 } 165 catch( IOException ex ) { 166 String errMsg = "ファイルèªã¿å–りストリーãƒ?«å¤±æ•—ã—ã¾ã—ãŸã€? 167 + " File=" + filename 168 + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg ä¿®æ£ 169 throw new RuntimeException( errMsg,ex ); 170 } 171 // 5.5.2.6 (2012/05/25) findbugs対å¿? 172 finally { 173 Closer.zipClose( jarFile ); 174 } 175 } 176 177 /** 178 * サンプルメイン 179 * ã“ã“ã§ã¯ã€å¼•æ•°ã«é€šå¸¸ã®ãƒ•ァイルã§ã¯ãªãã?クラスパスよりå–å¾—ã—ã¾ã™ã? 180 * 通常ã€å–å¾—ã•れãŸãƒ•ァイルåã?ã€ã‚¯ãƒ©ã‚¹ã®å®Œå?ç³»ã®æ–?—å?ãªã®ã§ã€ã‚¯ãƒ©ã‚¹ãƒ‘スよりå–å¾? 181 * ã—ã¦ã?‚‹é™ã‚Šã€ãã®ã¾ã¾ オブジェクトを構築ã§ãã‚‹ã“ã¨ã‚’æ„味ã—ã¾ã™ã? 182 * 183 * @param args 引数 184 */ 185 public static void main( final String[] args ) { 186 try { 187 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 188 Enumeration<URL> enume = loader.getResources( args[0] ); // 4.3.3.6 (2008/11/15) Genericsè¦å‘Šå¯¾å¿? 189 while( enume.hasMoreElements() ) { 190 URL url = enume.nextElement(); // 4.3.3.6 (2008/11/15) Genericsè¦å‘Šå¯¾å¿? 191 // jar:file:/実ディレクトリ!å…ˆé?クラス ã¾ãŸã?ã€file:/実ディレクトリ 192 System.out.println( "url=" + url.getFile() ); 193 194 FindClassFiles filenames = new FindClassFiles( url.getFile(),args[0] ); 195 String[] names = filenames.getFilenames(); 196 for( int i=0; i<names.length; i++ ) { 197 System.out.println( names[i] ); 198 } 199 } 200 } 201 catch( IOException ex ) { 202 String errMsg = "ファイルèªã¿å–りストリーãƒ?«å¤±æ•—ã—ã¾ã—ãŸã€? 203 + ex.getMessage(); 204 throw new RuntimeException( errMsg,ex ); 205 } 206 } 207 }