/******************************************************************
 * File:        DataContext.java
 * Created by:  Dave Reynolds
 * Created on:  29 Nov 2013
 * 
 * (c) Copyright 2013, Epimorphics Limited
 *
 *****************************************************************/

package com.epimorphics.dclib.framework;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.epimorphics.dclib.templates.TemplateFactory;
import com.epimorphics.util.EpiException;
import com.hp.hpl.jena.shared.PrefixMapping;

/**
 * Packages access to the background context of reference data, templates and
 * prefix definitions need to process a data set. 
 * 
 * @author <a href="mailto:dave@epimorphics.com">Dave Reynolds</a>
 */
public class DataContext {
    protected Map<String, Template> templates = new HashMap<String, Template>();
    protected PrefixMapping prefixes;
    protected BindingEnv env = new BindingEnv();
    protected DataContext parent;
    protected Map<String, MapSource> sources = new HashMap<>();
    
    public DataContext() {
    }
    
    public DataContext(DataContext parent) {
        this.parent = parent;
        env = new BindingEnv( parent.getGlobalEnv() );
        prefixes = parent.prefixes;
    }
    
    public void setPrefixes(PrefixMapping prefixes) {
        this.prefixes = prefixes;
    }
    
    /**
     * Expand a prefixes in the given URI string using the reference prefix definitions.
     */
    public String expandURI(String uri) {
        if (prefixes != null) {
            return prefixes.expandPrefix(uri);
        } else {
            return uri;
        }
    }
    
    /**
     * Get the global binding environment with default parameter settings
     */
    public BindingEnv getGlobalEnv() {
        return env;
    }
    
    /**
     * Register a new template
     */
    public void registerTemplate(Template template) {
        String name = template.getName();
        if (name != null) {
            templates.put(name, template);
        } else {
            throw new EpiException("Can't register a nameless template: " + template);
        }
    }

    /**
     * Register a template from a file
     */
    public void registerTemplate(String src) throws IOException {
        Template template = TemplateFactory.templateFrom(src, this);
        if (template.getName() == null) {
            templates.put(src, template);
        } else {
            templates.put(template.getName(), template);
        }
    }
    
    /**
     * Find a named template
     */
    public Template getTemplate(String name) {
        Template template = templates.get(name);
        if (template == null && parent != null) {
            template = parent.getTemplate(name);
        }
        return template;
    }
    
    /**
     * Register a new data source
     */
    public void registerSource(MapSource source) {
        String name = source.getName();
        if (name != null) {
            sources.put(name, source);
        } else {
            throw new EpiException("Can't register a nameless source: " + source);
        }
    }
    
    /**
     * Find a named source
     */
    public MapSource getSource(String name) {
        MapSource source = sources.get(name);
        if (source == null && parent != null) {
            source = parent.getSource(name);
        }
        return source;
    }
}

@@ -358,23 +358,133 @@
 va.util.
-HashMap
+ArrayList;%0Aimport java.util.Collections;%0Aimport java.util.Comparator;%0Aimport java.util.HashMap;%0Aimport java.util.List
 ;%0Aimport
@@ -2902,32 +2902,611 @@
  %7D%0A    %0A    /**%0A
+     * Return a list of all known templates, ordered by name%0A     */%0A    public List%3CTemplate%3E listTemplates() %7B%0A        List%3CTemplate%3E results = new ArrayList%3C%3E();%0A        results.addAll( templates.values() );%0A        if (parent != null) %7B%0A            results.addAll( parent.listTemplates() );%0A        %7D%0A        Collections.sort(results, new Comparator%3CTemplate%3E() %7B%0A            @Override%0A            public int compare(Template o1, Template o2) %7B%0A                return o1.getName().compareTo(o2.getName());%0A            %7D%0A        %7D);%0A        return results;%0A    %7D%0A    %0A    /**%0A
      * Register 

Support for listing templates available within a context