Package de.fuberlin.wiwiss.d2rq.map

Source Code of de.fuberlin.wiwiss.d2rq.map.TranslationTable$TableTranslator

package de.fuberlin.wiwiss.d2rq.map;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import com.hp.hpl.jena.rdf.model.Resource;

import de.fuberlin.wiwiss.d2rq.D2RQException;
import de.fuberlin.wiwiss.d2rq.csv.TranslationTableParser;
import de.fuberlin.wiwiss.d2rq.values.Translator;
import de.fuberlin.wiwiss.d2rq.vocab.D2RQ;

/**
* Represents a d2rq:TranslationTable.
*
* @author Richard Cyganiak (richard@cyganiak.de)
* @author zazi (http://github.com/zazi)
*/
public class TranslationTable extends MapObject {
  private Collection<Translation> translations = new ArrayList<Translation>();
  private String javaClass = null;
  private String href = null;

  public TranslationTable(Resource resource) {
    super(resource);
  }

  /**
   * Returns the number of defined mappings.
   */
  public int size() {
    return this.translations.size();
  }

  /**
   * Adds a translation mapping.
   * @param dbValue the value on the database side (usually coming from a DB column)
   * @param rdfValue the value on the RDF side (a string or URI)
   */
  public void addTranslation(String dbValue, String rdfValue) {
    assertArgumentNotNull(dbValue, D2RQ.databaseValue,
        D2RQException.TRANSLATION_MISSING_DBVALUE);
    assertArgumentNotNull(rdfValue, D2RQ.rdfValue,
        D2RQException.TRANSLATION_MISSING_RDFVALUE);
    this.translations.add(new Translation(dbValue, rdfValue));
  }

  /**
   * Sets a translation class. The translation class must implement
   * the {@link Translator} interface. This method will take care
   * of generating an instance of the class.
   * @param className name of a class implementing {@link Translator}
   */
  public void setJavaClass(String className) {
    assertNotYetDefined(this.javaClass, D2RQ.javaClass,
        D2RQException.TRANSLATIONTABLE_DUPLICATE_JAVACLASS);
    this.javaClass = className;
  }
 
  public void setHref(String href) {
    assertNotYetDefined(this.href, D2RQ.href,
        D2RQException.TRANSLATIONTABLE_DUPLICATE_HREF);
    this.href = href;
  }
 
  public Translator translator() {
    validate();
    if (this.javaClass != null) {
      return instantiateJavaClass();
    }
    if (this.href != null) {
      return new TableTranslator(new TranslationTableParser(href).parseTranslations());     
    }
    return new TableTranslator(this.translations);
  }

  public void validate() throws D2RQException {
    if (!this.translations.isEmpty() && this.javaClass != null) {
      throw new D2RQException("Can't combine d2rq:translation and d2rq:javaClass on " + this,
          D2RQException.TRANSLATIONTABLE_TRANSLATION_AND_JAVACLASS);
    }
    if (!this.translations.isEmpty() && this.href != null) {
      throw new D2RQException("Can't combine d2rq:translation and d2rq:href on " + this,
          D2RQException.TRANSLATIONTABLE_TRANSLATION_AND_HREF);
    }
    if (this.href != null && this.javaClass != null) {
      throw new D2RQException("Can't combine d2rq:href and d2rq:javaClass on " + this,
          D2RQException.TRANSLATIONTABLE_HREF_AND_JAVACLASS);
    }
  }
 
  public String toString() {
    return "d2rq:TranslationTable " + super.toString();
  }
 
  private Translator instantiateJavaClass() {
    try {
      Class<?> translatorClass = Class.forName(this.javaClass);
      if (!checkTranslatorClassImplementation(translatorClass)) {
        throw new D2RQException("d2rq:javaClass " + this.javaClass + " must implement " + Translator.class.getName());
      }
      if (hasConstructorWithArg(translatorClass)) {
        return invokeConstructorWithArg(translatorClass, resource());
      }
      if (hasConstructorWithoutArg(translatorClass)) {
        return invokeConstructorWithoutArg(translatorClass);
      }
      throw new D2RQException("No suitable public constructor found on d2rq:javaClass " + this.javaClass);
    } catch (ClassNotFoundException e) {
      throw new D2RQException("d2rq:javaClass not on classpath: " + this.javaClass);
    }
  }

  /**
   * Checks whether the Translator class or a super class of it implements the
   * Translator class interface.
   *
   * @param translatorClass
   *    a specific translator class or a more generic parent
   * @return true, if the currently checked translator class implements the
   *   Translator class interface
   */
  private boolean checkTranslatorClassImplementation(Class<?> translatorClass) {
    if (implementsTranslator(translatorClass)) {
      return true;
    }
    if (translatorClass.getSuperclass() == null) {
      return false;
    }
    return this.checkTranslatorClassImplementation(translatorClass
        .getSuperclass());
  }

  private boolean implementsTranslator(Class<?> aClass) {
    for (int i = 0; i < aClass.getInterfaces().length; i++) {
      if (aClass.getInterfaces()[i].equals(Translator.class)) {
        return true;
      }
    }
    return false;
  }

  private boolean hasConstructorWithArg(Class<?> aClass) {
    try {
      aClass.getConstructor(new Class[]{Resource.class});
      return true;
    } catch (NoSuchMethodException nsmex) {
      return false;
    }
  }
 
  private Translator invokeConstructorWithArg(Class<?> aClass, Resource r) {
    try {
      Constructor<?> c = aClass.getConstructor(new Class[]{Resource.class});
      return (Translator) c.newInstance(new Object[]{r});
    } catch (Exception ex) {
      throw new RuntimeException(ex);
    }
  }

  private boolean hasConstructorWithoutArg(Class<?> aClass) {
    try {
      aClass.getConstructor(new Class[]{});
      return true;
    } catch (NoSuchMethodException nsmex) {
      return false;
    }
  }
 
  private Translator invokeConstructorWithoutArg(Class<?> aClass) {
    try {
      Constructor<?> c = aClass.getConstructor(new Class[]{});
      return (Translator) c.newInstance(new Object[]{});
    } catch (Exception ex) {
      throw new RuntimeException(ex);
    }
  }

  public static class Translation {
    private String dbValue;
    private String rdfValue;
    public Translation(String dbValue, String rdfValue) {
      this.dbValue = dbValue;
      this.rdfValue = rdfValue;
    }
    public String dbValue() { return this.dbValue; }
    public String rdfValue() { return this.rdfValue; }
    public int hashCode() { return this.dbValue.hashCode() ^ this.rdfValue.hashCode(); }
    public boolean equals(Object otherObject) {
      if (!(otherObject instanceof Translation)) return false;
      Translation other = (Translation) otherObject;
      return this.dbValue.equals(other.dbValue)
          && this.rdfValue.equals(other.rdfValue);
    }
    public String toString() {
      return "'" + this.dbValue + "'=>'" + this.rdfValue + "'";
    }
  }
 
  private class TableTranslator implements Translator {
    private Map<String,Translation> translationsByDBValue = new HashMap<String,Translation>();
    private Map<String,Translation> translationsByRDFValue = new HashMap<String,Translation>();
    TableTranslator(Collection<Translation> translations) {
      for (Translation translation: translations) {
        translationsByDBValue.put(translation.dbValue, translation);
        translationsByRDFValue.put(translation.rdfValue, translation);
      }
    }
    public String toDBValue(String rdfValue) {
      Translation translation = translationsByRDFValue.get(rdfValue);
      return (translation == null) ? null : translation.dbValue();
    }
    public String toRDFValue(String dbValue) {
      Translation translation = translationsByDBValue.get(dbValue);
      return (translation == null) ? null : translation.rdfValue();
    }
  }
}
TOP

Related Classes of de.fuberlin.wiwiss.d2rq.map.TranslationTable$TableTranslator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.