/** * Copyright (C) 2013 Red Hat, Inc. (jdcasey@commonjava.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.commonjava.cartographer.INTERNAL.graph.discover; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Alternative; import javax.inject.Named; import org.commonjava.cartographer.graph.ViewParams; import org.commonjava.cartographer.CartoDataException; import org.commonjava.cartographer.spi.graph.discover.DiscoverySourceManager; import org.commonjava.maven.galley.TransferException; import org.commonjava.maven.galley.model.ConcreteResource; import org.commonjava.maven.galley.model.Location; import org.commonjava.maven.galley.model.Resource; import org.commonjava.maven.galley.model.SimpleLocation; import org.commonjava.maven.galley.model.VirtualResource; import org.commonjava.maven.galley.spi.transport.LocationExpander; import org.commonjava.maven.galley.spi.transport.LocationResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ApplicationScoped @Alternative @Named public class SourceManagerImpl implements DiscoverySourceManager, LocationExpander, LocationResolver { private final Logger logger = LoggerFactory.getLogger( getClass() ); private final Map<String, String> aliases = new HashMap<String, String>(); /** * Alias the given URL with a new short-handed key for use in various cartographer recipes. * * @param alias * @param url */ public SourceManagerImpl withAlias( final String alias, final String url ) { aliases.put( alias, url ); return this; } /** * Alias the given URL with a new short-handed key for use in various cartographer recipes. * * @param alias * @param url */ public boolean addSourceAlias( final String alias, final String url ) { if ( aliases.containsKey( alias ) ) { return false; } aliases.put( alias, url ); return true; } /** * Add the aliases given in the {@link Map} object to the current mapping. * * @param aliases */ public SourceManagerImpl withAliases( final Map<String, String> aliases ) { this.aliases.putAll( aliases ); return this; } /** * Add the aliases given in the {@link Properties} object to the current mapping. * * @param aliases */ public SourceManagerImpl withAliases( final Properties aliases ) { for ( final Enumeration<?> names = aliases.propertyNames(); names.hasMoreElements(); ) { final String name = (String) names.nextElement(); this.aliases.put( name, aliases.getProperty( name ) ); } return this; } @Override public URI createSourceURI( final String source ) { try { final String value = aliases.get( source ); final String u = value == null ? source : value; return new URL( u ).toURI(); } catch ( final URISyntaxException e ) { logger.error( String.format( "Invalid source URI: %s. Reason: %s", source, e.getMessage() ), e ); } catch ( final MalformedURLException e ) { logger.error( String.format( "Invalid source URL: %s. Reason: %s", source, e.getMessage() ), e ); } return null; } @Override public boolean activateWorkspaceSources( final ViewParams params, final String... sources ) throws CartoDataException { logger.debug( "Original source locations: {}", params.getActiveSources() ); boolean result = false; for ( final String source : sources ) { final URI src = createSourceURI( source ); if ( src != null ) { if ( params.getActiveSources() .contains( src ) ) { continue; } logger.debug( "Adding source location: {}", src ); params.addActiveSource( src ); result = result || params.getActiveSources() .contains( src ); } } return result; } @Override public boolean activateWorkspaceSources( final ViewParams params, final Collection<? extends Location> sources ) throws CartoDataException { logger.debug( "Original source locations: {}", params.getActiveSources() ); boolean result = false; for ( final Location source : sources ) { final URI src = createSourceURI( source.getUri() ); if ( src != null ) { if ( params.getActiveSources() .contains( src ) ) { continue; } logger.debug( "Adding source location: {}", src ); params.addActiveSource( src ); result = result || params.getActiveSources() .contains( src ); } } return result; } @Override public String getFormatHint() { return "Any valid URL supported by a configured galley transport"; } @Override public Map<String, String> getAliasMap() { return Collections.unmodifiableMap( aliases ); } @Override public Location createLocation( final Object source ) { final String value = aliases.get( source.toString() ); return new SimpleLocation( value == null ? source.toString() : value ); } @Override public List<? extends Location> createLocations( final Object... sources ) { final List<SimpleLocation> locations = new ArrayList<SimpleLocation>(); for ( final Object source : sources ) { final String value = aliases.get( source.toString() ); locations.add( new SimpleLocation( value == null ? source.toString() : value ) ); } return locations; } @Override public List<? extends Location> createLocations( final Collection<Object> sources ) { final List<SimpleLocation> locations = new ArrayList<SimpleLocation>(); for ( final Object source : sources ) { final String value = aliases.get( source.toString() ); locations.add( new SimpleLocation( value == null ? source.toString() : value ) ); } return locations; } @Override public List<Location> expand( final Location... locations ) { logger.debug( "Expanding location array: {}", Arrays.toString( locations ) ); final List<Location> result = new ArrayList<Location>(); for ( final Location source : locations ) { final String value = aliases.get( source.getUri() ); if ( value == null ) { result.add( source ); } else { result.add( new SimpleLocation( value ) ); } } logger.debug( "Result: {}", result ); return result; } @Override public <T extends Location> List<Location> expand( final Collection<T> locations ) throws TransferException { logger.debug( "Expanding location collection: {}", locations ); final List<Location> result = new ArrayList<Location>(); for ( final Location source : locations ) { final String value = aliases.get( source.getUri() ); if ( value == null ) { result.add( source ); } else { result.add( new SimpleLocation( value ) ); } } logger.debug( "Result: {}", result ); return result; } @Override public VirtualResource expand( final Resource resource ) throws TransferException { logger.debug( "Expanding virtual: {}", resource ); final List<ConcreteResource> res = new ArrayList<ConcreteResource>(); if ( resource instanceof VirtualResource ) { final VirtualResource virtual = (VirtualResource) resource; for ( final ConcreteResource concrete : virtual ) { res.addAll( expandConcrete( concrete ) ); } } else { res.addAll( expandConcrete( (ConcreteResource) resource ) ); } final VirtualResource result = new VirtualResource( res ); logger.debug( "Result: {}", result ); return result; } private List<ConcreteResource> expandConcrete( final ConcreteResource concrete ) { final Location source = concrete.getLocation(); final List<ConcreteResource> result = new ArrayList<ConcreteResource>(); for ( final Location loc : expand( source ) ) { result.add( new ConcreteResource( loc, concrete.getPath() ) ); } return result; } @Override public Location resolve( final String spec ) throws TransferException { return createLocation( spec ); } }