1 17 18 package org.apache.avalon.repository.impl; 19 20 21 import java.io.File ; 22 import java.util.ArrayList ; 23 import java.util.List ; 24 25 import java.net.URL ; 26 import java.net.URLClassLoader ; 27 28 import javax.naming.directory.Attributes ; 29 30 import org.apache.avalon.repository.Artifact; 31 import org.apache.avalon.repository.Repository; 32 import org.apache.avalon.repository.RepositoryException; 33 import org.apache.avalon.repository.RepositoryRuntimeException; 34 import org.apache.avalon.repository.meta.FactoryDescriptor; 35 import org.apache.avalon.repository.meta.MetaException; 36 import org.apache.avalon.repository.util.LoaderUtils; 37 import org.apache.avalon.repository.util.RepositoryUtils; 38 39 46 public class DefaultRepository implements Repository 47 { 48 52 55 private final File m_cache; 56 57 private final LoaderUtils m_loader; 58 59 62 private final List m_descriptors = new ArrayList (); 63 64 68 71 private URL [] m_hosts; 72 73 76 private String [] m_roots; 77 78 81 private boolean m_online; 82 83 87 94 DefaultRepository( 95 File cache, String [] hosts, boolean online, Artifact[] candidates ) 96 throws RepositoryException 97 { 98 if( cache == null ) throw new NullPointerException ( "cache" ); 99 if( hosts == null ) throw new NullPointerException ( "hosts" ); 100 if( candidates == null ) throw new NullPointerException ( "candidates" ); 101 102 m_cache = cache; 103 m_roots = RepositoryUtils.getCleanPaths( hosts ); 104 m_hosts = getHosts( m_roots ); 105 m_online = online; 106 m_loader = new LoaderUtils( online ); 107 108 setupRegistry( candidates ); 109 110 } 111 112 116 125 public Attributes getAttributes( Artifact artifact ) 126 throws RepositoryException 127 { 128 if( null == artifact ) 129 throw new NullPointerException ( "artifact" ); 130 131 try 132 { 133 return RepositoryUtils.getAsAttributes( 134 RepositoryUtils.getProperties( 135 getResource( artifact, "meta" ) ) ); 136 } 137 catch( Throwable e ) 138 { 139 final String error = 140 "Unable to retrieve the metadata for the artifact :" 141 + artifact; 142 throw new RepositoryException( error, e ); 143 } 144 } 145 146 152 public Artifact[] getCandidates( Class service ) 153 { 154 ArrayList list = new ArrayList (); 155 String classname = service.getName(); 156 FactoryDescriptor[] descriptors = getFactoryDescriptors(); 157 for( int i=0; i<descriptors.length; i++ ) 158 { 159 FactoryDescriptor descriptor = descriptors[i]; 160 final String key = descriptor.getInterface(); 161 if( classname.equals( key ) ) 162 { 163 list.add( descriptor.getArtifact() ); 164 } 165 } 166 return (Artifact[]) list.toArray( new Artifact[0] ); 167 } 168 169 175 public URL getResource( Artifact artifact ) 176 throws RepositoryException 177 { 178 return m_loader.getResource( 179 artifact, m_roots, m_cache, true ); 180 } 181 182 189 private URL getResource( Artifact artifact, String mime ) 190 throws RepositoryException 191 { 192 return m_loader.getResource( 193 artifact, mime, m_roots, m_cache, true ); 194 } 195 196 205 public ClassLoader getClassLoader( Artifact artifact ) 206 throws RepositoryException 207 { 208 return getClassLoader( 209 ClassLoader.getSystemClassLoader(), artifact ); 210 } 211 212 221 public ClassLoader getClassLoader( ClassLoader parent, Artifact artifact ) 222 throws RepositoryException 223 { 224 if( null == parent ) 225 throw new NullPointerException ( "parent" ); 226 if( null == artifact ) 227 throw new NullPointerException ( "artifact" ); 228 229 Attributes attributes = getAttributes( artifact ); 230 FactoryDescriptor relational = null; 231 try 232 { 233 relational = new FactoryDescriptor( attributes ); 234 } 235 catch( MetaException me ) 236 { 237 final String error = 238 "Could not create a relational descriptor from the artifact: " 239 + artifact; 240 throw new RepositoryException( error, me ); 241 } 242 243 URL [] apis = 244 getURLs( 245 relational.getDependencies( 246 FactoryDescriptor.API_KEY ) ); 247 ClassLoader api = buildClassLoader( apis, parent ); 248 249 URL [] spis = 250 getURLs( 251 relational.getDependencies( 252 FactoryDescriptor.SPI_KEY ) ); 253 ClassLoader spi = buildClassLoader( spis, api ); 254 255 URL [] imps = 256 getURLs( artifact, 257 relational.getDependencies( 258 FactoryDescriptor.IMP_KEY ) ); 259 return buildClassLoader( imps, spi ); 260 } 261 262 266 public String toString() 267 { 268 StringBuffer buffer = new StringBuffer ( m_cache.toString() ); 269 for( int i=0; i<m_hosts.length; i++ ) 270 { 271 buffer.append( ", " ); 272 buffer.append( m_hosts[i] ); 273 } 274 return buffer.toString(); 275 } 276 277 281 private URL [] getHosts( String [] paths ) 282 { 283 URL [] hosts = new URL [ paths.length ]; 284 for( int i=0; i<paths.length; i++ ) 285 { 286 String path = paths[i]; 287 try 288 { 289 hosts[i] = new URL ( path ); 290 } 291 catch( Throwable e ) 292 { 293 final String error = 294 "Internal error while attempting to construct url for host: " 295 + path; 296 throw new RepositoryRuntimeException( error, e ); 297 } 298 } 299 return hosts; 300 } 301 302 private ClassLoader buildClassLoader( 303 URL [] urls, ClassLoader parent ) 304 { 305 if( 0 == urls.length ) return parent; 306 return new URLClassLoader ( urls, parent ); 307 } 308 309 private URL [] getURLs( Artifact[] artifacts ) 310 throws RepositoryException 311 { 312 URL [] urls = new URL [ artifacts.length ]; 313 for( int i=0; i<urls.length; i++ ) 314 { 315 urls[i] = getResource( artifacts[i] ); 316 } 317 return urls; 318 } 319 320 private URL [] getURLs( Artifact primary, Artifact[] artifacts ) 321 throws RepositoryException 322 { 323 URL [] urls = new URL [ artifacts.length +1 ]; 324 for( int i=0; i<artifacts.length; i++ ) 325 { 326 urls[i] = getResource( artifacts[i] ); 327 } 328 urls[ artifacts.length ] = getResource( primary ); 329 return urls; 330 } 331 332 private void setupRegistry( Artifact[] artifacts ) throws RepositoryException 333 { 334 for( int i=0; i<artifacts.length; i++ ) 335 { 336 Artifact artifact = artifacts[i]; 337 registerArtifact( artifact ); 338 } 339 } 340 341 private void registerArtifact( Artifact artifact ) throws RepositoryException 342 { 343 Attributes attributes = getAttributes( artifact ); 344 FactoryDescriptor descriptor = new FactoryDescriptor( attributes ); 345 final String key = descriptor.getInterface(); 346 if( null == key ) 347 { 348 final String error = 349 "Artifact [" + artifact + "] does not declare a exported interface."; 350 throw new RepositoryException( error ); 351 } 352 else if( !m_descriptors.contains( descriptor ) ) 353 { 354 m_descriptors.add( descriptor ); 355 } 356 } 357 358 private FactoryDescriptor[] getFactoryDescriptors() 359 { 360 return (FactoryDescriptor[]) 361 m_descriptors.toArray( new FactoryDescriptor[0] ); 362 } 363 364 } 365 | Popular Tags |