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 CONDITIONS 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 package org.apache.commons.classscan.builtin; 015 016 import java.io.InputStream; 017 import java.util.Collection; 018 import java.util.HashMap; 019 import java.util.Iterator; 020 import java.util.Map; 021 022 import org.apache.commons.classscan.ClassPathElement; 023 import org.apache.commons.classscan.ClassFile; 024 import org.apache.commons.classscan.model.MetaClass; 025 import org.apache.commons.classscan.spi.model.SpiMetaClass; 026 import org.apache.commons.classscan.spi.model.SpiMetaClassLoader; 027 import org.apache.commons.classscan.spi.model.SpiMetaClassPathElement; 028 import org.apache.commons.classscan.spi.model.SpiMetaRegistry; 029 import org.apache.commons.classscan.util.NameSet; 030 import org.slf4j.Logger; 031 import org.slf4j.LoggerFactory; 032 033 public class DefaultMetaClassPathElement implements SpiMetaClassPathElement { 034 035 private static final Logger logger = LoggerFactory.getLogger(DefaultMetaClassPathElement.class); 036 037 private final String baseUrl; 038 private Map<String, SpiMetaClass> workClasses = new HashMap<String, SpiMetaClass>(); 039 private NameSet<SpiMetaClass> sealedClasses; 040 041 public DefaultMetaClassPathElement(SpiMetaRegistry metaRegistry, ClassPathElement classPathElement) { 042 this.baseUrl = classPathElement.getLocation(); 043 044 for(ClassFile classPathFile : classPathElement) { 045 addFile(metaRegistry, classPathFile); 046 } 047 } 048 049 private void addFile(SpiMetaRegistry metaRegistry, ClassFile classPathFile) { 050 String className = classPathFile.getClassName(); 051 try { 052 InputStream byteStream = classPathFile.getBytes(); 053 try { 054 SpiMetaClass mc= metaRegistry.createMetaClass(this, className, byteStream); 055 addMetaClass(mc); 056 } 057 finally { 058 byteStream.close(); 059 } 060 } catch (Exception e) { 061 logger.info("Exception while loading "+className, e); 062 } 063 } 064 065 void addMetaClass(SpiMetaClass mc) { 066 String name= mc.getName(); 067 if (workClasses.containsKey(name)) { 068 return; 069 } 070 workClasses.put(name, mc); 071 } 072 073 @Override 074 public boolean resolve(SpiMetaClassLoader classLoader) { 075 if( workClasses.isEmpty() ) { 076 sealedClasses = NameSet.emptyNameSet(); 077 } 078 else { 079 Iterator<Map.Entry<String, SpiMetaClass>> metaClasses = workClasses.entrySet().iterator(); 080 while(metaClasses.hasNext()) { 081 Map.Entry<String, SpiMetaClass> entry = metaClasses.next(); 082 if(!entry.getValue().resolve(classLoader)) { 083 logger.info("Could not resolve dependencies of "+entry.getKey()); 084 metaClasses.remove(); 085 } 086 } 087 sealedClasses = new NameSet<SpiMetaClass>(SpiMetaClass.class, workClasses.values()); 088 } 089 090 workClasses = null; 091 if( sealedClasses.isEmpty() ) { 092 logger.info("No classes in "+baseUrl); 093 return false; 094 } 095 return true; 096 } 097 098 @Override 099 public MetaClass resolveMetaClass(SpiMetaClassLoader classLoader, String className) { 100 if(workClasses==null) { 101 return sealedClasses.getValue(className); 102 } 103 SpiMetaClass workClass = workClasses.get(className); 104 if( workClass != null && workClass.resolve(classLoader) ) { 105 return workClass; 106 } 107 return null; 108 } 109 110 @Override 111 public Collection<? extends MetaClass> getMetaClasses() { 112 return sealedClasses; 113 } 114 115 @Override 116 public MetaClass getMetaClass(String className) { 117 return sealedClasses.getValue(className); 118 } 119 120 @Override 121 public String getName() { 122 return baseUrl; 123 } 124 }