package aQute.bnd.deployer.repository; import static aQute.bnd.deployer.repository.RepoConstants.DEFAULT_CACHE_DIR; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import aQute.bnd.service.Actionable; /** * A simple read-only OBR-based repository that uses a list of index locations * and a basic local cache. * <p> * <h2>Properties</h2> * <ul> * <li><b>locations:</b> comma-separated list of index URLs. <b>NB:</b> surround * with single quotes!</li> * <li><b>name:</b> repository name; defaults to the index URLs. * <li><b>cache:</b> local cache directory. May be omitted, in which case the * repository will only be able to serve resources with {@code file:} URLs.</li> * <li><b>location:</b> (deprecated) alias for "locations". * </ul> * <p> * <h2>Example</h2> * * <pre> * -plugin: * aQute.lib.repository.FixedIndexedRepo;locations='http://www.example.com/ * repository.xml';cache=${workspace}/.cache * </pre> * * @author Neil Bartlett */ public class FixedIndexedRepo extends AbstractIndexedRepo implements Actionable { private static final String EMPTY_LOCATION = ""; public static final String PROP_LOCATIONS = "locations"; public static final String PROP_CACHE = "cache"; private String locations; protected File cacheDir = new File( System.getProperty("user.home") + File.separator + DEFAULT_CACHE_DIR); public synchronized void setProperties(Map<String,String> map) { super.setProperties(map); locations = map.get(PROP_LOCATIONS); String cachePath = map.get(PROP_CACHE); if (cachePath != null) { cacheDir = new File(cachePath); if (!cacheDir.isDirectory()) try { throw new IllegalArgumentException(String.format( "Cache path '%s' does not exist, or is not a directory.", cacheDir.getCanonicalPath())); } catch (IOException e) { throw new IllegalArgumentException("Could not get cacheDir canonical path", e); } } } @Override protected List<URI> loadIndexes() throws Exception { List<URI> result; try { if (locations != null) result = parseLocations(locations); else result = Collections.emptyList(); } catch (MalformedURLException e) { throw new IllegalArgumentException( String.format("Invalid location, unable to parse as URL list: %s", locations), e); } return result; } public synchronized File getCacheDirectory() { return cacheDir; } public void setCacheDirectory(File cacheDir) { if (cacheDir == null) throw new IllegalArgumentException("null cache directory not permitted"); this.cacheDir = cacheDir; } @Override public synchronized String getName() { if (name != null && !name.equals(this.getClass().getName())) return name; return locations; } public String getLocation() { if (locations == null) return EMPTY_LOCATION; else return locations.toString(); } public void setLocations(String locations) throws MalformedURLException, URISyntaxException { parseLocations(locations); // for verification right syntax this.locations = locations; } public File getRoot() { return cacheDir; } /** * Provide a menu to refresh. The target is Repository [, Symbolic Name * (String) [, version (Version)]]. */ @Override public Map<String,Runnable> actions(Object... target) throws Exception { Map<String,Runnable> map = new HashMap<String,Runnable>(); map.put("Refresh", new Runnable() { @Override public void run() { try { refresh(); } catch (Exception e) { throw new RuntimeException(e); } } }); return map; } @Override public String tooltip(Object... target) throws Exception { // TODO Auto-generated method stub return null; } @Override public String title(Object... target) throws Exception { // TODO Auto-generated method stub return null; } }