<commit_before>package aQute.lib.deployer.obr;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import aQute.bnd.build.ResolverMode;
import aQute.bnd.service.OBRIndexProvider;
import aQute.bnd.service.OBRResolutionMode;
import aQute.bnd.service.Plugin;
import aQute.bnd.service.RepositoryPlugin;
import aQute.lib.filter.Filter;
import aQute.lib.osgi.Jar;
import aQute.libg.generics.Create;
import aQute.libg.reporter.Reporter;
import aQute.libg.version.Version;
import aQute.libg.version.VersionRange;

/**
 * Abstract base class for OBR-based repositories.
 * 
 * <p>
 * The repository implementation is read-only by default. To implement a writable
 * repository, subclasses should override {@link #canWrite()} and {@link #put(Jar)}.
 * 
 * @author <NAME>
 *
 */
public abstract class AbstractBaseOBR implements Plugin, RepositoryPlugin, OBRIndexProvider {
	
	public static final String PROP_NAME = "name";
	public static final String PROP_RESOLUTION_MODE = "mode";
	public static final String PROP_RESOLUTION_MODE_ANY = "any";
	
	public static final String REPOSITORY_FILE_NAME = "repository.xml";
	
	static final String FILE_SCHEME = "file";
	
	protected Reporter reporter;
	protected String name = this.getClass().getName();
	protected Set<OBRResolutionMode> supportedModes = EnumSet.allOf(OBRResolutionMode.class);

	private boolean initialised = false;
	private final Map<String, SortedMap<Version, Resource>> pkgResourceMap = new HashMap<String, SortedMap<Version, Resource>>();
	private final Map<String, SortedMap<Version, Resource>> bsnMap = new HashMap<String, SortedMap<Version, Resource>>();
	
	protected abstract File getOrCreateCacheFile(URI uri) throws IOException;

	protected void addResourceToIndex(Resource resource) {
		addBundleSymbolicNameToIndex(resource);
		addPackagesToIndex(resource);
	}

	protected synchronized void reset() {
		initialised = false;
	}

	/**
	 * Initialise the indexes prior to main initialisation of internal
	 * data structures. This implementation does nothing, but subclasses
	 * may override if they need to perform such initialisation.
	 * @throws Exception 
	 */
	protected void initialiseIndexes() throws Exception {
	}

	protected final synchronized void init() throws Exception {
		if (!initialised) {
			bsnMap.clear();
			pkgResourceMap.clear();
			
			initialiseIndexes();
			
			IResourceListener listener = new IResourceListener() {
				public boolean processResource(Resource resource) {
					addResourceToIndex(resource);
					return true;
				}
			};
			Collection<URL> indexes = getOBRIndexes();
			for (URL indexLocation : indexes) {
				try {
					InputStream stream = indexLocation.openStream();
					readIndex(indexLocation.toString(), stream, listener);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ParserConfigurationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (SAXException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			initialised = true;
		}
	}

	public void setProperties(Map<String, String> map) {
		if (map.containsKey(PROP_NAME))
			name = map.get(PROP_NAME);
		
		if (map.containsKey(PROP_RESOLUTION_MODE)) {
			supportedModes = EnumSet.noneOf(OBRResolutionMode.class);
			StringTokenizer tokenizer = new StringTokenizer(map.get(PROP_RESOLUTION_MODE), ",");
			while (tokenizer.hasMoreTokens()) {
				String token = tokenizer.nextToken().trim();
				if (PROP_RESOLUTION_MODE_ANY.equalsIgnoreCase(token))
					supportedModes = EnumSet.allOf(OBRResolutionMode.class);
				else {
					try {
						supportedModes.add(OBRResolutionMode.valueOf(token));
					} catch (Exception e) {
						if (reporter != null) reporter.error("Unknown OBR resolution mode: " + token);
					}
				}
			}
		}
	}

	public File[] get(String bsn, String rangeStr) throws Exception {
		init();
		
		// If the range is set to "project", we cannot resolve it.<commit_msg>Fixed error handling in OBR repo<commit_after>package aQute.lib.deployer.obr;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import aQute.bnd.build.ResolverMode;
import aQute.bnd.service.OBRIndexProvider;
import aQute.bnd.service.OBRResolutionMode;
import aQute.bnd.service.Plugin;
import aQute.bnd.service.RepositoryPlugin;
import aQute.lib.filter.Filter;
import aQute.lib.osgi.Jar;
import aQute.libg.generics.Create;
import aQute.libg.reporter.Reporter;
import aQute.libg.version.Version;
import aQute.libg.version.VersionRange;

/**
 * Abstract base class for OBR-based repositories.
 * 
 * <p>
 * The repository implementation is read-only by default. To implement a writable
 * repository, subclasses should override {@link #canWrite()} and {@link #put(Jar)}.
 * 
 * @author <NAME>
 *
 */
public abstract class AbstractBaseOBR implements Plugin, RepositoryPlugin, OBRIndexProvider {
	
	public static final String PROP_NAME = "name";
	public static final String PROP_RESOLUTION_MODE = "mode";
	public static final String PROP_RESOLUTION_MODE_ANY = "any";
	
	public static final String REPOSITORY_FILE_NAME = "repository.xml";
	
	static final String FILE_SCHEME = "file";
	
	protected Reporter reporter;
	protected String name = this.getClass().getName();
	protected Set<OBRResolutionMode> supportedModes = EnumSet.allOf(OBRResolutionMode.class);

	private boolean initialised = false;
	private final Map<String, SortedMap<Version, Resource>> pkgResourceMap = new HashMap<String, SortedMap<Version, Resource>>();
	private final Map<String, SortedMap<Version, Resource>> bsnMap = new HashMap<String, SortedMap<Version, Resource>>();
	
	protected abstract File getOrCreateCacheFile(URI uri) throws IOException;

	protected void addResourceToIndex(Resource resource) {
		addBundleSymbolicNameToIndex(resource);
		addPackagesToIndex(resource);
	}

	protected synchronized void reset() {
		initialised = false;
	}

	/**
	 * Initialise the indexes prior to main initialisation of internal
	 * data structures. This implementation does nothing, but subclasses
	 * may override if they need to perform such initialisation.
	 * @throws Exception 
	 */
	protected void initialiseIndexes() throws Exception {
	}

	protected final synchronized void init() throws Exception {
		if (!initialised) {
			bsnMap.clear();
			pkgResourceMap.clear();
			
			initialiseIndexes();
			
			IResourceListener listener = new IResourceListener() {
				public boolean processResource(Resource resource) {
					addResourceToIndex(resource);
					return true;
				}
			};
			Collection<URL> indexes = getOBRIndexes();
			boolean success = false;
			for (URL indexLocation : indexes) {
				try {
					InputStream stream = indexLocation.openStream();
					readIndex(indexLocation.toString(), stream, listener);
					success = true; // At least one could be read
				} catch (Exception e) {
					reporter.error("Unable to read index at URL '%s'.", indexLocation);
				}
			}
			
			if (success)
				initialised = true;
			else
				throw new IllegalStateException(String.format("Unable to initialise any index URLs for repository '%s'.", getName()));
		}
	}

	public void setProperties(Map<String, String> map) {
		if (map.containsKey(PROP_NAME))
			name = map.get(PROP_NAME);
		
		if (map.containsKey(PROP_RESOLUTION_MODE)) {
			supportedModes = EnumSet.noneOf(OBRResolutionMode.class);
			StringTokenizer tokenizer = new StringTokenizer(map.get(PROP_RESOLUTION_MODE), ",");
			while (tokenizer.hasMoreTokens()) {
				String token = tokenizer.nextToken().trim();
				if (PROP_RESOLUTION_MODE_ANY.equalsIgnoreCase(token))
					supportedModes = EnumSet.allOf(OBRResolutionMode.class);
				else {
					try {
						supportedModes.add(OBRResolutionMode.valueOf(token));
					} catch (Exception e) {
						if (reporter != null) reporter.error("Unknown OBR resolution mode: " + token);
					}
				}
			}
		}
	}

	public File[] get(String bsn, String rangeStr) throws Exception {
		init();
		
		// If the range is set to "project", we cannot resolve it.
{'fraction_non_alphanumeric': 0.10354875637423248, 'fraction_numerical': 0.0, 'mean_word_length': 4.577481137550784, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2560440', 'n_tokens_mistral': 3217, 'n_tokens_neox': 2849, 'n_words': 735}