public class DatatypePropertyMapping implements Mapping {

	String propertyURL;
	String datatypeURL;
	public DatatypePropertyMapping(String url, String datatypeURL)
	{
		propertyURL = url;
		this.datatypeURL = datatypeURL;
	}
	@Override
	public String getURL() {
		return propertyURL;
	}
	public String getDatatypeURL() { 
		return datatypeURL;
	}
	public String toString()
	{
		return String.format("Datatype property: <%s> {%s}",propertyURL);
	}
} public class ExceptionMapping implements Mapping{

    String cosa="";
    String obj="";
    
    public ExceptionMapping(String _cosa, String _obj)
    {
        cosa=_cosa;
        obj=_obj;
    }
    
    @Override
    public String getURL() {
        return cosa;
    }
    
} public class IndividualMapping implements Mapping {
    final String url;

    public IndividualMapping(String url) {
	this.url = url;
    }

    @Override
    public String getURL() {
	return url;
    }
    
    @Override
    public String toString() {
        return String.format("Individiual <%s>", url);
    }
} public class Main {

    //Determines whether it will be a stream-parsing (if big=true) or a block conversion (big=false)
    static boolean big = false;
    // Establishes the file with the mappings
    static String mapping_file = "mappings.default";
    // Input file name to be read from;
    static String input_file = "";
    // Output file name to be written to
    static String output_file = "";
    // If the output is to be shown in console
    static boolean bOutputInConsole = true;
    //Determines if the parsing is going to be lenient or strict
    public static boolean lenient = false;
    // The mappings to be used
    public static Mappings mappings;
    // The base namespace of the dataset
    public static String DATA_NAMESPACE = "http://tbx2rdf.lider-project.eu/data/iate/";
    //the system id used for relative URI
    //public static String systemIdForRelativeURI;
    

    /**
     * Main method. 
     */
    public static void main(String[] args) {
        PropertyConfigurator.configure("log4j.properties");

        try {
			readConfigurationFile(args[0]);
			mappings = Mappings.readInMappings(mapping_file);

	        if (big) {
	            convertBigFile();
	        } else {
	            convertSmallFile();
	        }
		} catch (Exception e) {
			e.printStackTrace();
		}
        
        /*boolean ok = parseParams(args);
        if (!ok) {
            System.exit(-1);
        }*/
        
        //READ MAPPINGS
        //System.err.println("Using mapping file: " + mapping_file + "\n");
        /*mappings = Mappings.readInMappings(mapping_file);

        if (big) {
            convertBigFile();
        } else {
            convertSmallFile();
        }*/

    }

    private static void readConfigurationFile(String propFile) throws Exception {
    	File fileProp = new File(propFile);
		Properties prop = new Properties();
		prop.load(new FileInputStream(fileProp));
		
		String bigFile = prop.getProperty("bigfile", "false");
		big = Boolean.parseBoolean(bigFile);
		
		String tbxfile = prop.getProperty("tbxfile");
		input_file = tbxfile;
		File file = new File(input_file);
        if (!file.exists()) {
            System.err.println("The file " + input_file + " does not exist");
            throw new FileNotFoundException("The file " + input_file + " does not exist");
        }
		
        String output = prop.getProperty("output", "").trim();
		if(output.length()==0) {
			output_file = input_file.replaceAll("\\.(xml|tbx)", "\\.rdf");
	        if (!output_file.endsWith(".rdf")) {
	            output_file += ".rdf";
	        }
		}
        
        String namespace = prop.getProperty("namespace", "");
        if(namespace.length()==0) {
        	throw new Exception("namespace value is missing in the property file");
        }
		DATA_NAMESPACE = namespace;
		
		String mappings = prop.getProperty("mappings", "mappings.default");
		mapping_file = mappings;
		
		//recap al values that will be used
		System.out.println("The following values will be used:");
		System.out.println("\tbig = "+big);
		System.out.println("\tinput_file = "+input_file);
		System.out.println("\toutput_file = "+output_file);
		System.out.println("\tnamespace = "+DATA_NAMESPACE);
		System.out.println("\tmapping_file = "+mapping_file);
		
	}

	/**
     * Parses the command line parameters
     */
    /*public static boolean parseParams(String[] args) {
        String ejecutando = "";
        for (String ejecutandox : args) {
            ejecutando += " " + ejecutandox;
        }
        if (args.length == 0) {
            System.err.println("Usage: TBX2RDF_Converter <INPUT_FILE> (--output=<OUTPUT_FILE>)? (--mappings=<MAPPING_FILE>)? (--big=true)? (--datanamespace=<DATA_NAMESPACE>)?");
            System.err.println("If no OUTPUT_FILE is provided, then <OUTPUT FILE>s/.xml/.rdf/ will be assumed as output file.");
            System.err.println("If no MAPPING_FILE is provided, then mappings.default will be used.");
            return false;
        }
        input_file = args[0];                                           //First argument, input file
        File file = new File(input_file);
        if (!file.exists())
        {
            System.err.println("The file " + input_file + " does not exist");
            return false;
        }
        
        output_file = input_file.replaceAll("\\.(xml|tbx)", "\\.rdf");
        if (!output_file.endsWith(".rdf")) {
            output_file += ".rdf";
        }
        String arg, key, value;
        for (int i = 1; i < args.length; i++) {
            arg = args[i];
            Pattern p = Pattern.compile("^--(output|mappings|datanamespace|big|lenient)=(.*?)$");
            Matcher matcher;
            matcher = p.matcher(arg);
            if (matcher.matches()) {
                key = matcher.group(1);
                value = matcher.group(2);
                if (key.equals("output")) {
                    output_file = value;
                    bOutputInConsole = false;
                    System.err.println("OUTPUT_FILE set to" + output_file + "\n");
                }
                if (key.equals("mappings")) {
                    mapping_file = value;
                    System.err.println("MAPPING_FILE set to" + mapping_file + "\n");
                }
                if (key.equals("datanamespace")) {
                    DATA_NAMESPACE = value;
                    System.err.println("DATA_NAMESPACE set to" + DATA_NAMESPACE + "\n");
                }
                if (key.equals("big")) {
                    if (value.equals("true")) {
                        big = true;
                    }
                    System.err.println("Processing large file");
                }
                if (key.equals("lenient")) {
                    if (value.equals("true")) {
                        lenient = true;
                    }
                    System.err.println("Processing in lenient mode");
                }
            }
        }
        return true;
    }*/

    /**
     * This is the conversion to be invoked for large files, that will be processed in a stream
     * The output is serialized as the conversion is being done     
     */
    public static boolean convertBigFile() {
        try {
            bOutputInConsole = false;
            System.err.println("Doing the conversion of a big file\n");
            TBX2RDF_Converter converter = new TBX2RDF_Converter();
            PrintStream fos;
            if (output_file.isEmpty() || bOutputInConsole) {
                fos = System.out;
            } else {
                fos = new PrintStream(output_file, "UTF-8");
            }
            if (fos == null) {
                System.err.println("output file could not be open");
                return false;
            }
            converter.convertAndSerializeLargeFile(input_file, fos, mappings);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * Standard conversion
     * This is the conversion invoked from the web service. 
     * Input file is read as a whole and kept in memory.
     */
    public static boolean convertSmallFile() {
        try {
            System.out.println("Doing the standard conversion (not a big file)\n");
            //READ TBX XML
            System.out.println("Opening file " + input_file + "\n");
            BufferedReader reader = new BufferedReader(new FileReader(input_file));
            TBX2RDF_Converter converter = new TBX2RDF_Converter();
            TBX_Terminology terminology = converter.convert(reader, mappings);
            //WRITE. This one has been obtained from 
            System.out.println("Writting output to " + output_file + "\n");
//            final Model model = terminology.getModel("file:" + output_file);
            final Model model = terminology.getModel(Main.DATA_NAMESPACE);           
            RDFDataMgr.write(new FileOutputStream(output_file), model, Lang.TURTLE);
            reader.close();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return false;
        }
        return true;

    }
} public interface Mapping {

	public String getURL();
	
} public class Mappings {

    // omg.
    HashMap<String, HashMap<String, HashMap<String, Mapping>>> mappings;
    
    //
    HashMap<String, IndividualMapping> individualMappings = new HashMap<>();
    
    //
    public String defaultLanguage = "en";

    
    public Mappings() {
        mappings = new HashMap<String, HashMap<String, HashMap<String, Mapping>>>();
    }
    
    /**
     * Reads the mappings in a mapping file
     *
     * @param mapping_file Name of the file to be read
     * @return Nothing, but the global mappings HashMap is updated
     */
    public static Mappings readInMappings(String mapping_file) throws IOException {
        return readInMappings(new FileReader(mapping_file));
    }

    /**
     * Creates a Mappings object from a reader
     */
    public static Mappings readInMappings(Reader fstream) throws IOException {
        final Mappings mappings = new Mappings();
        final BufferedReader br = new BufferedReader(fstream);
        final Pattern mapping1 = Pattern.compile("^(\\S*?)\\s+<(\\S*?)>$");
        final Pattern mapping2 = Pattern.compile("^(\\S*?)\\s+(\\S*?)\\s+(\\S*?)\\s+<(\\S*)>\\s+OP(\\s*\\{(.*?)\\})?$");
        final Pattern mapping3 = Pattern.compile("^(\\S*?)\\s+(\\S*?)\\s+(\\S*?)\\s+<(\\S*)>\\s+DP(\\s*<(.*?)>)?$");
        final Pattern mapping4 = Pattern.compile("^(\\S*?)\\s+(\\S*?)\\s+(\\S*?)\\s+<(\\S*)>\\s+EX(\\s*\\{(.*?)\\})?$");

        String strLine;
        Matcher matcher;
        while ((strLine = br.readLine()) != null) {
            strLine = strLine.trim();

            if ((matcher = mapping1.matcher(strLine)).find()) {
                mappings.addMapping(matcher.group(1), new IndividualMapping(matcher.group(2)));
            } else if ((matcher = mapping3.matcher(strLine)).find()) {
                mappings.addMapping(matcher.group(1), matcher.group(2), matcher.group(3), new DatatypePropertyMapping(matcher.group(4), matcher.group(6)));
            } else if ((matcher = mapping2.matcher(strLine)).find()) {
                final Set<String> set = new HashSet<String>();
                if (matcher.group(6) != null) {
                    final String[] values = matcher.group(6).split(",");
                    for (int i = 0; i < values.length; i++) {
                        set.add(values[i]);
                    }
                    final ObjectPropertyMapping objectPropertyMapping = new ObjectPropertyMapping(matcher.group(4), set, mappings.individualMappings);
                    mappings.addMapping(matcher.group(1), matcher.group(2), matcher.group(3), objectPropertyMapping);
                } else {
                    final ObjectPropertyMapping objectPropertyMapping = new ObjectPropertyMapping(matcher.group(4), mappings.individualMappings);
                    mappings.addMapping(matcher.group(1), matcher.group(2), matcher.group(3), objectPropertyMapping);

                }
            } else if ((matcher = mapping4.matcher(strLine)).find()) {
                final ExceptionMapping em = new ExceptionMapping(matcher.group(4), "");
                mappings.addMapping(matcher.group(1), matcher.group(2), matcher.group(3), em);
                //                  System.out.println("XXXXXXXXXXXXX " + matcher.group(1) + " "+matcher.group(2)+" "+matcher.group(3)+" "+matcher.group(4) );

            } else {
                throw new RuntimeException("Bad line in mapping file: " + strLine);
            }
        }
        br.close();
        return mappings;
    }


    public void addMapping(String name, IndividualMapping target) {
        individualMappings.put(name, target);
    }

    public void addMapping(String element, String attribute, String value, Mapping mapping) {

        //System.out.print("Adding mapping for: "+element+" "+attribute+" "+value+" "+mapping);
        HashMap<String, HashMap<String, Mapping>> element2attr;

        HashMap<String, Mapping> attr2mappings;

        if (mappings.containsKey(element)) {
            element2attr = mappings.get(element);
        } else {
            element2attr = new HashMap<String, HashMap<String, Mapping>>();
            mappings.put(element, element2attr);
        }

        if (element2attr.containsKey(attribute)) {
            attr2mappings = element2attr.get(attribute);
        } else {
            attr2mappings = new HashMap<String, Mapping>();
            element2attr.put(attribute, attr2mappings);
        }

        attr2mappings.put(value, mapping);

    }

    /**
     * Gets the mapping for an element, attribute and value
     * @param element XML element, for example "descrip"
     * @param attribute XML attribute, for example, "subjectField"
     * @param value String literal with the value
     */
    public Mapping getMapping(String element, String attribute, String value) {
        HashMap<String, HashMap<String, Mapping>> element2attr;

        HashMap<String, Mapping> attr2mappings;

        if (mappings.containsKey(element)) {
            element2attr = mappings.get(element);

            if (element2attr.containsKey(attribute)) {
                attr2mappings = element2attr.get(attribute);

                if (attr2mappings.containsKey(value)) {
                    return attr2mappings.get(value);
                } else {
                    return null;
                }

            } else {
                return null;
            }

        } else {
            return null;
        }

    }
} public class ObjectPropertyMapping implements Mapping {

	final Map<String, IndividualMapping> indivMappingRef;
	String propertyURL;

	Set<String> allowedValues;

	public ObjectPropertyMapping(String url, Set<String> values, Map<String, IndividualMapping> indivMappingRef) {
		propertyURL = url;
		allowedValues = values;
		this.indivMappingRef = Collections.unmodifiableMap(indivMappingRef);
	}

	public ObjectPropertyMapping(String url, Map<String, IndividualMapping> indivMappingRef) {
		propertyURL = url;
		allowedValues = null;
		this.indivMappingRef = Collections.unmodifiableMap(indivMappingRef);
	}

	@Override
	public String getURL() {
		return propertyURL;
	}
    
	public boolean allowed(String value) {

		if (allowedValues.isEmpty() || allowedValues.contains(value)) {
			return true;
		}

		return false;
	}

    public IndividualMapping getMapping(String value) {
        return indivMappingRef.get(value);
    }

    public boolean hasRange() {
	    return allowedValues != null;
    }

    @Override
	public String toString() {
		return String.format("ObjectProperty <%s>", propertyURL);
	}

} public class TBXFormatException extends RuntimeException {
    public TBXFormatException() {
    }

    public TBXFormatException(String message) {
        super(message);
    }

    public TBXFormatException(Throwable cause) {
        super(cause);
    }

    public TBXFormatException(String message, Throwable cause) {
        super(message, cause);
    }
} public class SubjectField extends impID {
    
    String topic;
    
    public SubjectField(String _id, String _topic)
    {
        String newid= "http://tbx2rdf.lider-project.eu/data/iate/subjectField/"+_id;
        setID(newid);
        topic=_topic;
    }
    
    @Override
    public void toRDF(Model model, Resource parent) {
        final Resource res = model.createResource(getID());
        res.addProperty(RDF.type, TBX.SubjectField);
        res.addProperty(RDFS.label, topic);        
    }

    /**
     * Obtains a human readable name for the topic
     */
    public String getTopicString()
    {
        return topic;
    }
    
    
} public class SubjectFields {


    public static Map<String, String> mapa = new HashMap();
    public static Map<String, SubjectField> mapauris = new HashMap();
    
    public static void main(String[] args)  {
        System.out.println("Subject Fields");
        SubjectFields sf= new SubjectFields();
        List<SubjectField> lsf=sf.readInternalFile();
        Model model = generateSubjectFields();
        StringWriter sw = new StringWriter();
        RDFDataMgr.write(sw, model, RDFFormat.NTRIPLES);
        String str = sw.toString();
        System.out.println(str);
        
    } 
    
    /**
     * Loads and generates resources for the subject fields
     * @return A Jena model
     */
    public static Model generateSubjectFields()
    {
        SubjectFields sfs= new SubjectFields();
        List<SubjectField> subjectFields=sfs.readInternalFile();
        Model model = ModelFactory.createDefaultModel();
        for(SubjectField sf : subjectFields)
        {
            sf.toRDF(model, null);
        }
        return model;
    }
    
    

    /**
     * Reads the list of subject fields
     */
    public List<SubjectField> readInternalFile()
    {
        List<SubjectField> lsf = new ArrayList();
        try{
            InputStream in = this.getClass().getResourceAsStream("subjectFields.txt");
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String str="";
            while ((str = br.readLine()) != null) {
                StringTokenizer tokens=new StringTokenizer(str, ",");
                if (tokens.countTokens()!=2) 
                    continue;
                String s1=tokens.nextToken();
                String s2=tokens.nextToken();
                mapa.put(s1,s2);
                SubjectField sf=new SubjectField(s1,s2);
                mapauris.put(s1,sf);
                lsf.add(sf);
            }
        }catch(Exception e)
        {
            e.printStackTrace();
            return lsf;
        }
        return lsf;
    }
    
} public class TBX {
    private static Model defaultModel = ModelFactory.createDefaultModel();
     public static Resource SkosConcept = defaultModel.createResource("http://www.w3.org/2004/02/skos/core#Concept");
     public static Resource Context = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#Context");
     public static Resource Descrip = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#Descrip");
     public static Resource MartifHeader = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#MartifHeader");
     public static Resource Admin = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#Admin");
     public static Resource TermNote = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#TermNote");
     public static Resource Transaction = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#transaction");
     public static Resource SubjectField = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#SubjectField");
     
     
     public static Property subjectField = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#subjectField");
     public static Property description = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#description");
     public static Property target = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#target");
     public static Property type = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#type");
     public static Property context = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#context");
     public static Property value = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#value");
     public static Property status = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#status");
     public static Property definition = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#definition");
     public static Property source = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#source");
     public static Property xref = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#xreference");
     public static Property datatype = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#datatype");
     public static Property language = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#language");
     public static Property note = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#note");
     public static Property encodingDesc = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#encodingDesc");
     public static Property revisionDesc = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#revisionDesc");
     public static Property publicationStmt = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#publicationStmt");
     public static Property sourceDesc = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#sourceDesc");
     public static Property admin = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#admin");
     public static Property termNote = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#termNote");
     public static Property transaction = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#transaction");
     public static Property reliabilityCode = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode");
     public static Property termType = defaultModel.createProperty("http://www.lexinfo.net/ontology/2.0/lexinfo#termType");//http://tbx2rdf.lider-project.eu/tbx#termType
     public static Property partOfSpeech = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#partOfSpeech");
     public static Property grammaticalNumber = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#grammaticalNumber");
     public static Property transactionType = defaultModel.createProperty("http://tbx2rdf.lider-project.eu/tbx#transactionType");
     
     //These are not being used!
     public static Resource reliabilityCode1 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode1");
     public static Resource reliabilityCode2 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode2");
     public static Resource reliabilityCode3 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode3");
     public static Resource reliabilityCode4 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode4");
     public static Resource reliabilityCode5 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode5");
     public static Resource reliabilityCode6 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode6");
     public static Resource reliabilityCode7 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode7");
     public static Resource reliabilityCode8 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode8");
     public static Resource reliabilityCode9 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode9");
     public static Resource reliabilityCode10 = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#reliabilityCode10");
     public static Resource noun = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#noun");
     public static Resource properNoun = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#properNoun");
     public static Resource adverb = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#adverb");
     public static Resource adjective = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#adjective");
     public static Resource verb = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#verb");
     public static Resource other = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#other");
     public static Resource singular = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#singular");
     public static Resource plural = defaultModel.createResource("http://tbx2rdf.lider-project.eu/tbx#plural");
     
     
     
     
    /**
     * Adds the most common prefixes to the generated model
     * 
     */
    public static void addPrefixesToModel(Model model)
    {
        model.setNsPrefix("tbx", "http://tbx2rdf.lider-project.eu/tbx#");
        model.setNsPrefix("ontolex", "http://www.w3.org/ns/lemon/ontolex#");
        model.setNsPrefix("skos", "http://www.w3.org/2004/02/skos/core#");
        model.setNsPrefix("odrl", "http://www.w3.org/ns/odrl/2/"); //http://w3.org/ns/odrl/2/
        model.setNsPrefix("dct", "http://purl.org/dc/terms/");
        model.setNsPrefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
        model.setNsPrefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
        model.setNsPrefix("cc", "http://creativecommons.org/ns#");
        model.setNsPrefix("ldr", "http://purl.oclc.org/NET/ldr/ns#");
        model.setNsPrefix("void", "http://rdfs.org/ns/void#");
        model.setNsPrefix("dcat", "http://www.w3.org/ns/dcat#");
        model.setNsPrefix("prov", "http://www.w3.org/ns/prov#");
        model.setNsPrefix("decomp", "http://www.w3.org/ns/lemon/decomp#");
        
    }    
     
}
import com.hp.hpl.jena.graph.NodeFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Selector;
import com.hp.hpl.jena.rdf.model.SimpleSelector;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.DCTerms;
import com.hp.hpl.jena.vocabulary.RDFS;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.log4j.Logger;
import org.w3c.dom.NodeList;
import tbx2rdf.DatatypePropertyMapping;
import tbx2rdf.ExceptionMapping;
import tbx2rdf.IndividualMapping;
import tbx2rdf.Main;
import tbx2rdf.Mapping;
import tbx2rdf.Mappings;
import tbx2rdf.ObjectPropertyMapping;
import tbx2rdf.TBXFormatException;
import tbx2rdf.datasets.iate.SubjectField;
import tbx2rdf.datasets.iate.SubjectFields;
import tbx2rdf.vocab.TBX;
package tbx2rdf.types.abs;


/**
 * 
 * @author John McCrae
 */
public abstract class impIDLangTypeTgtDtyp extends impIDLang {

    private final static Logger logger = Logger.getLogger(impIDLangTypeTgtDtyp.class);
    
    
	public final Mapping type;
	public String target;
	public String datatype;
	public NodeList value;

	public impIDLangTypeTgtDtyp(Mapping type, String lang, Mappings mappings, NodeList value) {
		super(lang, mappings);
		this.type = type;
		this.value = value;
	}

	@Override
	public void toRDF(Model model, Resource parent) {
		if (type instanceof ObjectPropertyMapping) {
			final ObjectPropertyMapping opm = (ObjectPropertyMapping) type;
			final String valueString = value == null ? null : nodelistToString(value);
			if (target != null && !opm.hasRange()) {
				try {
					final URI uri = new URI(target);
					parent.addProperty(model.createProperty(opm.getURL()), model.createResource(uri.toString()));
				} catch (URISyntaxException x) {
					throw new TBXFormatException("Bad URL " + target);
				}
			} else if (opm.hasRange()) {
				final IndividualMapping im = opm.getMapping(valueString);
				if (im == null) {
					throw new TBXFormatException("Mapping not in declared property range or value URI not declared: " + valueString + " " + opm.getURL());
				}
                                    parent.addProperty(model.createProperty(opm.getURL()),
                                    model.createResource(im.getURL()));
			} else {
				try {
					final URI uri = new URI(valueString);
				} catch (URISyntaxException x) {
					throw new TBXFormatException("Bad URI or could not otherwise understand object property value: " + valueString);
				}
			}
		} else if (type instanceof DatatypePropertyMapping) {
			final DatatypePropertyMapping dpm = (DatatypePropertyMapping)type;
			if (datatype != null) {
				parent.addProperty(model.createProperty(type.getURL()), nodelistToString(value), NodeFactory.getType(datatype));
			} else if(dpm.getDatatypeURL() != null) { 
				parent.addProperty(model.createProperty(type.getURL()), nodelistToString(value), NodeFactory.getType(dpm.getDatatypeURL()));
			} else if (value.getLength() <= 1) {
				parent.addProperty(model.createProperty(type.getURL()), nodelistToString(value), lang);
			} else {
				parent.addProperty(model.createProperty(type.getURL()), nodelistToString(value), XMLLiteral);
			}
		} else if (type instanceof ExceptionMapping){
                    final ExceptionMapping em = (ExceptionMapping)type;
                    try {
                        Class<?> c = Class.forName("tbx2rdf.ExceptionMethods");
                        Object o = c.newInstance();
                        Class[] paramTypes = new Class[1];
                        paramTypes[0]=String.class;
                        Method m = c.getDeclaredMethod(em.getURL(), paramTypes);
                        String res=(String) m.invoke(o, nodelistToString(value));
                        Resource r=model.createResource(res);
                        parent.addProperty(TBX.subjectField,r);
                        
                        //Special procedure for IATE subject fields. THIS SHOULD NOT BE HERE because it is breaking the converter neutrality
                        if(r.toString().contains("http://tbx2rdf.lider-project.eu/data/iate/subjectField/"))
                        {
                            String urisf = r.getURI().toString();
                            urisf = urisf.substring(urisf.lastIndexOf("/")+1, urisf.length());
                            SubjectField sf = SubjectFields.mapauris.get(urisf);
                            if (sf!=null)
                                model.add(r,RDFS.label, sf.getTopicString());
                        }
                        //End of the special procedure for IATE subject fields
                        
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                else {
                    logger.warn("Unexpected mapping type when processing " + parent.getURI()  );
                    if (Main.lenient==false)