Coverage Report - org.seasar.cubby.routing.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.routing.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  
  * @author baba
 40  
  * @since 1.0.0
 41  
  */
 42  24
 abstract class ClassCollector implements ClassHandler {
 43  
 
 44  12
         private final Map<String, Strategy> strategies = new HashMap<String, Strategy>();
 45  
 
 46  
         private final NamingConvention namingConvention;
 47  
 
 48  
         /**
 49  
          * {@link ClassCollector}を作成します。
 50  
          * 
 51  
          * @param namingConvention
 52  
          *            命名規約
 53  
          */
 54  12
         protected ClassCollector(final NamingConvention namingConvention) {
 55  12
                 this.namingConvention = namingConvention;
 56  12
                 addStrategy("file", new FileSystemStrategy());
 57  12
                 addStrategy("jar", new JarFileStrategy());
 58  12
                 addStrategy("zip", new ZipFileStrategy());
 59  12
                 addStrategy("code-source", new CodeSourceFileStrategy());
 60  12
         }
 61  
 
 62  
         /**
 63  
          * 登録されているストラテジを返します。
 64  
          * 
 65  
          * @return 登録されているストラテジ
 66  
          */
 67  
         public Map<String, Strategy> getStrategies() {
 68  0
                 return strategies;
 69  
         }
 70  
 
 71  
         /**
 72  
          * {@link Strategy} を返します。
 73  
          * 
 74  
          * @param protocol
 75  
          * @return {@link Strategy}
 76  
          */
 77  
         protected Strategy getStrategy(final String protocol) {
 78  24
                 return strategies.get(URLUtil.toCanonicalProtocol(protocol));
 79  
         }
 80  
 
 81  
         /**
 82  
          * {@link Strategy}を追加します。
 83  
          * 
 84  
          * @param protocol
 85  
          * @param strategy
 86  
          */
 87  
         protected void addStrategy(final String protocol, final Strategy strategy) {
 88  48
                 strategies.put(protocol, strategy);
 89  48
         }
 90  
 
 91  
         /**
 92  
          * 自動登録を行います。
 93  
          */
 94  
         public void collect() {
 95  12
                 final String[] rootPackageNames = namingConvention
 96  
                                 .getRootPackageNames();
 97  12
                 if (rootPackageNames != null) {
 98  24
                         for (int i = 0; i < rootPackageNames.length; ++i) {
 99  12
                                 final String rootDir = rootPackageNames[i].replace('.', '/');
 100  12
                                 for (final Iterator<?> it = ClassLoaderUtil
 101  36
                                                 .getResources(rootDir); it.hasNext();) {
 102  24
                                         final URL url = (URL) it.next();
 103  24
                                         final Strategy strategy = getStrategy(URLUtil
 104  
                                                         .toCanonicalProtocol(url.getProtocol()));
 105  24
                                         strategy.collect(rootDir, url);
 106  24
                                 }
 107  
                         }
 108  12
                         webSphereClassLoaderFix();
 109  
                 }
 110  12
         }
 111  
 
 112  
         /**
 113  
          * Jarファイルからコンポーネントの登録を行います。
 114  
          * <p>
 115  
          * WebSphere のクラスローダーはJarファイル中のディレクトリエントリを<code>ClassLoader#getResource()</code>で
 116  
          * 返してくれないので、 S2のJarと同じ場所にあるJarファイルからコンポーネントの登録を行います。
 117  
          * </p>
 118  
          */
 119  
         protected void webSphereClassLoaderFix() {
 120  12
                 final URL url = ResourceUtil.getResourceNoException(getClass()
 121  
                                 .getName().replace('.', '/')
 122  
                                 + ".class");
 123  12
                 if ("wsjar".equals(url.getProtocol())) {
 124  0
                         final File s2JarFile = new File(JarFileUtil.toJarFile(url)
 125  
                                         .getName());
 126  0
                         final File libDir = s2JarFile.getParentFile();
 127  0
                         final File[] jarFiles = libDir.listFiles(new FilenameFilter() {
 128  0
                                 public boolean accept(File dir, String name) {
 129  0
                                         return name.endsWith(".jar");
 130  
                                 }
 131  
                         });
 132  0
                         for (int i = 0; i < jarFiles.length; ++i) {
 133  0
                                 final JarFile jarFile = JarFileUtil.create(jarFiles[i]);
 134  0
                                 ClassTraversal.forEach(jarFile, this);
 135  
                         }
 136  
                 }
 137  12
         }
 138  
 
 139  
         /**
 140  
          * プロトコルに応じた自動登録を行なうストラテジです。
 141  
          * 
 142  
          */
 143  
         protected interface Strategy {
 144  
                 /**
 145  
                  * 自動登録を行います。
 146  
                  * 
 147  
                  * @param path
 148  
                  *            パス
 149  
                  * @param url
 150  
                  *            URL
 151  
                  */
 152  
                 void collect(String path, URL url);
 153  
         }
 154  
 
 155  
         /**
 156  
          * ファイルシステム用の {@link Strategy}です。
 157  
          */
 158  12
         protected class FileSystemStrategy implements Strategy {
 159  
 
 160  
                 /**
 161  
                  * {@inheritDoc}
 162  
                  */
 163  
                 public void collect(String path, URL url) {
 164  24
                         File rootDir = getRootDir(path, url);
 165  24
                         String[] rootPackageNames = namingConvention.getRootPackageNames();
 166  48
                         for (int i = 0; i < rootPackageNames.length; ++i) {
 167  24
                                 ClassTraversal.forEach(rootDir, rootPackageNames[i],
 168  
                                                 ClassCollector.this);
 169  
                         }
 170  24
                 }
 171  
 
 172  
                 protected File getRootDir(String path, URL url) {
 173  24
                         File file = URLUtil.toFile(url);
 174  24
                         String[] names = StringUtil.split(path, "/");
 175  120
                         for (int i = 0; i < names.length; ++i) {
 176  96
                                 file = file.getParentFile();
 177  
                         }
 178  24
                         return file;
 179  
                 }
 180  
         }
 181  
 
 182  
         /**
 183  
          * jarファイル用の {@link Strategy}です。
 184  
          */
 185  12
         protected class JarFileStrategy implements Strategy {
 186  
 
 187  
                 /**
 188  
                  * {@inheritDoc}
 189  
                  */
 190  
                 public void collect(final String path, final URL url) {
 191  0
                         final JarFile jarFile = createJarFile(url);
 192  0
                         ClassTraversal.forEach(jarFile, ClassCollector.this);
 193  0
                 }
 194  
 
 195  
                 /**
 196  
                  * {@link JarFile}を作成します。
 197  
                  * 
 198  
                  * @param url
 199  
                  * @return {@link JarFile}
 200  
                  */
 201  
                 protected JarFile createJarFile(final URL url) {
 202  0
                         return JarFileUtil.toJarFile(url);
 203  
                 }
 204  
         }
 205  
 
 206  
         /**
 207  
          * WebLogic固有の<code>zip:</code>プロトコルで表現されるURLをサポートするストラテジです。
 208  
          */
 209  12
         protected class ZipFileStrategy implements Strategy {
 210  
 
 211  
                 /**
 212  
                  * {@inheritDoc}
 213  
                  */
 214  
                 public void collect(final String path, final URL url) {
 215  0
                         final JarFile jarFile = createJarFile(url);
 216  0
                         ClassTraversal.forEach(jarFile, ClassCollector.this);
 217  0
                 }
 218  
 
 219  
                 /**
 220  
                  * {@link JarFile}を作成します。
 221  
                  * 
 222  
                  * @param url
 223  
                  * @return {@link JarFile}
 224  
                  */
 225  
                 protected JarFile createJarFile(final URL url) {
 226  0
                         final String jarFileName = ZipFileUtil.toZipFilePath(url);
 227  0
                         return JarFileUtil.create(new File(jarFileName));
 228  
                 }
 229  
         }
 230  
 
 231  
         /**
 232  
          * OC4J固有の<code>code-source:</code>プロトコルで表現されるURLをサポートするストラテジです。
 233  
          */
 234  12
         protected class CodeSourceFileStrategy implements Strategy {
 235  
 
 236  
                 /**
 237  
                  * {@inheritDoc}
 238  
                  */
 239  
                 public void collect(final String path, final URL url) {
 240  0
                         final JarFile jarFile = createJarFile(url);
 241  0
                         ClassTraversal.forEach(jarFile, ClassCollector.this);
 242  0
                 }
 243  
 
 244  
                 /**
 245  
                  * {@link JarFile}を作成します。
 246  
                  * 
 247  
                  * @param url
 248  
                  * @return {@link JarFile}
 249  
                  */
 250  
                 protected JarFile createJarFile(final URL url) {
 251  0
                         final URL jarUrl = URLUtil.create("jar:file:" + url.getPath());
 252  0
                         return JarFileUtil.toJarFile(jarUrl);
 253  
                 }
 254  
         }
 255  
 }