001 /* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CODITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014 015 package org.apache.commons.classscan.builtin; 016 017 import java.io.File; 018 import java.util.Collection; 019 import java.util.Iterator; 020 021 import org.apache.commons.classscan.ClassFile; 022 import org.apache.commons.classscan.ResourceFile; 023 import org.apache.commons.classscan.spi.model.SpiClassPathElement; 024 import org.apache.commons.classscan.spi.model.SpiMetaRegistry; 025 026 public class FileClassPathElement implements SpiClassPathElement { 027 028 private final File baseLocation; 029 030 FileClassPathElement(File baseLocation) { 031 this.baseLocation= baseLocation; 032 } 033 034 private static class FileCursor { 035 final private FileCursor prior; 036 final private File[] files; 037 private int fileIdx; 038 private final int priorLength; 039 private final StringBuilder sb; 040 041 FileCursor(FileCursor prior, File dir, StringBuilder sb) { 042 this.prior = prior; 043 files= dir.listFiles(); 044 this.sb = sb; 045 if(prior!=null) { 046 sb.append('/'); 047 } 048 priorLength = sb.length(); 049 } 050 051 File nextFile() { 052 if(fileIdx==files.length) { 053 return null; 054 } 055 File file = files[fileIdx++]; 056 sb.setLength(priorLength); 057 sb.append(file.getName()); 058 return file; 059 } 060 061 FileCursor pop() { 062 return prior; 063 } 064 } 065 066 @Override 067 public Iterator<ClassFile> iterator() { 068 069 return new ClassFileIterator() { 070 StringBuilder sb = new StringBuilder(); 071 FileCursor cursor= new FileCursor(null, baseLocation, sb); 072 073 ClassFile getNext() { 074 for(;;) { 075 File file = cursor.nextFile(); 076 if(file == null) { 077 cursor = cursor.pop(); 078 if(cursor==null) { 079 return null; 080 } 081 continue; 082 } 083 084 String path = sb.toString(); 085 if(file.isDirectory()) { 086 String fileName = file.getName(); 087 if( ClassNameHelper.isValidIdentifier(fileName) ) { 088 cursor= new FileCursor(cursor, file, sb); 089 } 090 continue; 091 } 092 093 if(file.canRead()) { 094 String className= ClassNameHelper.getClassNameFromFileName(file.getName()); 095 if(className!=null) { 096 return new FileClassFile(file, path); 097 } 098 continue; 099 } 100 } 101 } 102 }; 103 } 104 105 @Override 106 public String getLocation() { 107 return baseLocation.toURI().toString(); 108 } 109 110 @Override 111 public Collection<SpiClassPathElement> getAdditionalLocations(SpiMetaRegistry registry) { 112 return null; 113 } 114 115 @Override 116 public ResourceFile getResource(String fileName) { 117 File file= new File(baseLocation, fileName); 118 if(file.isFile()) { 119 return new FileResourceFile(file, fileName); 120 } 121 return null; 122 } 123 }