Coverage Report - org.seasar.cubby.convention.impl.ClassCollector
 
Classes in this File Line Coverage Branch Coverage Complexity
ClassCollector
79%
27/34
60%
6/10
0
ClassCollector$1
0%
0/2
N/A
0
ClassCollector$CodeSourceFileStrategy
17%
1/6
N/A
0
ClassCollector$FileSystemStrategy
100%
11/11
100%
4/4
0
ClassCollector$JarFileStrategy
20%
1/5
N/A
0
ClassCollector$Strategy
N/A
N/A
0
ClassCollector$ZipFileStrategy
17%
1/6
N/A
0
 
 1  
 /*
 2  
  * Copyright 2004-2008 the Seasar Foundation and the Others.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package org.seasar.cubby.convention.impl;
 17  
 
 18  
 import java.io.File;
 19  
 import java.io.FilenameFilter;
 20  
 import java.net.URL;
 21  
 import java.util.HashMap;
 22  
 import java.util.Iterator;
 23  
 import java.util.Map;
 24  
 import java.util.jar.JarFile;
 25  
 
 26  
 import org.seasar.framework.convention.NamingConvention;
 27  
 import org.seasar.framework.util.ClassLoaderUtil;
 28  
 import org.seasar.framework.util.ClassTraversal;
 29  
 import org.seasar.framework.util.JarFileUtil;
 30  
 import org.seasar.framework.util.ResourceUtil;
 31  
 import org.seasar.framework.util.StringUtil;
 32  
 import org.seasar.framework.util.URLUtil;
 33  
 import org.seasar.framework.util.ZipFileUtil;
 34  
 import org.seasar.framework.util.ClassTraversal.ClassHandler;
 35  
 
 36  
 /**
 37  
  * クラスを抽出するクラスです。
 38  
  * 
 39  
  */
 40  2
 abstract class ClassCollector implements ClassHandler {
 41  
 
 42  1
         private final Map<String, Strategy> strategies = new HashMap<String, Strategy>();
 43  
 
 44  
         private final NamingConvention namingConvention;
 45  
 
 46  
         /**
 47  
          * {@link ClassCollector}を作成します。
 48  
          */
 49  1
         public ClassCollector(NamingConvention namingConvention) {
 50  1
                 this.namingConvention = namingConvention;
 51  1
                 addStrategy("file", new FileSystemStrategy());
 52  1
                 addStrategy("jar", new JarFileStrategy());
 53  1
                 addStrategy("zip", new ZipFileStrategy());
 54  1
                 addStrategy("code-source", new CodeSourceFileStrategy());
 55  1
         }
 56  
 
 57  
         /**
 58  
          * 登録されているストラテジを返します。
 59  
          * 
 60  
          * @return 登録されているストラテジ
 61  
          */
 62  
         public Map<String, Strategy> getStrategies() {
 63  0
                 return strategies;
 64  
         }
 65  
 
 66  
         /**
 67  
          * {@link Strategy} を返します。
 68  
          * 
 69  
          * @param protocol
 70  
          * @return {@link Strategy}
 71  
          */
 72  
         protected Strategy getStrategy(String protocol) {
 73  2
                 return (Strategy) strategies.get(URLUtil.toCanonicalProtocol(protocol));
 74  
         }
 75  
 
 76  
         /**
 77  
          * {@link Strategy}を追加します。
 78  
          * 
 79  
          * @param protocol
 80  
          * @param strategy
 81  
          */
 82  
         protected void addStrategy(String protocol, Strategy strategy) {
 83  4
                 strategies.put(protocol, strategy);
 84  4
         }
 85  
 
 86  
         /**
 87  
          * 自動登録を行います。
 88  
          */
 89  
         public void collect() {
 90  1
                 final String[] rootPackageNames = namingConvention
 91  
                                 .getRootPackageNames();
 92  1
                 if (rootPackageNames != null) {
 93  2
                         for (int i = 0; i < rootPackageNames.length; ++i) {
 94  1
                                 final String rootDir = rootPackageNames[i].replace('.', '/');
 95  1
                                 for (final Iterator<?> it = ClassLoaderUtil.getResources(rootDir); it
 96  3
                                                 .hasNext();) {
 97  2
                                         final URL url = (URL) it.next();
 98  2
                                         final Strategy strategy = getStrategy(URLUtil
 99  
                                                         .toCanonicalProtocol(url.getProtocol()));
 100  2
                                         strategy.collect(rootDir, url);
 101  2
                                 }
 102  
                         }
 103  1
                         webSphereClassLoaderFix();
 104  
                 }
 105  1
         }
 106  
 
 107  
         /**
 108  
          * Jarファイルからコンポーネントの登録を行います。
 109  
          * <p>
 110  
          * WebSphere のクラスローダーはJarファイル中のディレクトリエントリを<code>ClassLoader#getResource()</code>で
 111  
          * 返してくれないので、 S2のJarと同じ場所にあるJarファイルからコンポーネントの登録を行います。
 112  
          * </p>
 113  
          */
 114  
         protected void webSphereClassLoaderFix() {
 115  1
                 final URL url = ResourceUtil.getResourceNoException(getClass()
 116  
                                 .getName().replace('.', '/')
 117  
                                 + ".class");
 118  1
                 if ("wsjar".equals(url.getProtocol())) {
 119  0
                         final File s2JarFile = new File(JarFileUtil.toJarFile(url)
 120  
                                         .getName());
 121  0
                         final File libDir = s2JarFile.getParentFile();
 122  0
                         final File[] jarFiles = libDir.listFiles(new FilenameFilter() {
 123  0
                                 public boolean accept(File dir, String name) {
 124  0
                                         return name.endsWith(".jar");
 125  
                                 }
 126  
                         });
 127  0
                         for (int i = 0; i < jarFiles.length; ++i) {
 128  0
                                 final JarFile jarFile = JarFileUtil.create(jarFiles[i]);
 129  0
                                 ClassTraversal.forEach(jarFile, this);
 130  
                         }
 131  
                 }
 132  1
         }
 133  
 
 134  
         /**
 135  
          * プロトコルに応じた自動登録を行なうストラテジです。
 136  
          * 
 137  
          */
 138  
         protected interface Strategy {
 139  
                 /**
 140  
                  * 自動登録を行います。
 141  
                  * 
 142  
                  * @param path
 143  
                  * @param url
 144  
                  */
 145  
                 void collect(String path, URL url);
 146  
         }
 147  
 
 148  
         /**
 149  
          * ファイルシステム用の
 150  
          * {@link org.seasar.framework.container.cooldeploy.CoolComponentAutoRegister.Strategy}です。
 151  
          * 
 152  
          */
 153  1
         protected class FileSystemStrategy implements Strategy {
 154  
 
 155  
                 public void collect(String path, URL url) {
 156  2
                         File rootDir = getRootDir(path, url);
 157  2
                         String[] rootPackageNames = namingConvention.getRootPackageNames();
 158  4
                         for (int i = 0; i < rootPackageNames.length; ++i) {
 159  2
                                 ClassTraversal.forEach(rootDir, rootPackageNames[i],
 160  
                                                 ClassCollector.this);
 161  
                         }
 162  2
                 }
 163  
 
 164  
                 /**
 165  
                  * ルートディレクトリを返します。
 166  
                  * 
 167  
                  * @param path
 168  
                  * @param url
 169  
                  * @return ルートディレクトリ
 170  
                  */
 171  
                 protected File getRootDir(String path, URL url) {
 172  2
                         File file = URLUtil.toFile(url);
 173  2
                         String[] names = StringUtil.split(path, "/");
 174  8
                         for (int i = 0; i < names.length; ++i) {
 175  6
                                 file = file.getParentFile();
 176  
                         }
 177  2
                         return file;
 178  
                 }
 179  
         }
 180  
 
 181  
         /**
 182  
          * jarファイル用の {@link ClassCollector.Strategy}です。
 183  
          * 
 184  
          */
 185  1
         protected class JarFileStrategy implements Strategy {
 186  
 
 187  
                 public void collect(String path, URL url) {
 188  0
                         JarFile jarFile = createJarFile(url);
 189  0
                         ClassTraversal.forEach(jarFile, ClassCollector.this);
 190  0
                 }
 191  
 
 192  
                 /**
 193  
                  * {@link JarFile}を作成します。
 194  
                  * 
 195  
                  * @param url
 196  
                  * @return {@link JarFile}
 197  
                  */
 198  
                 protected JarFile createJarFile(URL url) {
 199  0
                         return JarFileUtil.toJarFile(url);
 200  
                 }
 201  
         }
 202  
 
 203  
         /**
 204  
          * WebLogic固有の<code>zip:</code>プロトコルで表現されるURLをサポートするストラテジです。
 205  
          */
 206  1
         protected class ZipFileStrategy implements Strategy {
 207  
 
 208  
                 public void collect(String path, URL url) {
 209  0
                         final JarFile jarFile = createJarFile(url);
 210  0
                         ClassTraversal.forEach(jarFile, ClassCollector.this);
 211  0
                 }
 212  
 
 213  
                 /**
 214  
                  * {@link JarFile}を作成します。
 215  
                  * 
 216  
                  * @param url
 217  
                  * @return {@link JarFile}
 218  
                  */
 219  
                 protected JarFile createJarFile(URL url) {
 220  0
                         final String jarFileName = ZipFileUtil.toZipFilePath(url);
 221  0
                         return JarFileUtil.create(new File(jarFileName));
 222  
                 }
 223  
         }
 224  
 
 225  
         /**
 226  
          * OC4J固有の<code>code-source:</code>プロトコルで表現されるURLをサポートするストラテジです。
 227  
          */
 228  1
         protected class CodeSourceFileStrategy implements Strategy {
 229  
 
 230  
                 public void collect(String path, URL url) {
 231  0
                         final JarFile jarFile = createJarFile(url);
 232  0
                         ClassTraversal.forEach(jarFile, ClassCollector.this);
 233  0
                 }
 234  
 
 235  
                 /**
 236  
                  * {@link JarFile}を作成します。
 237  
                  * 
 238  
                  * @param url
 239  
                  * @return {@link JarFile}
 240  
                  */
 241  
                 protected JarFile createJarFile(final URL url) {
 242  0
                         final URL jarUrl = URLUtil.create("jar:file:" + url.getPath());
 243  0
                         return JarFileUtil.toJarFile(jarUrl);
 244  
                 }
 245  
         }
 246  
 }