Package org.openrdf.sail.rdbms.schema

Source Code of org.openrdf.sail.rdbms.schema.IdSequence

/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.sail.rdbms.schema;

import static org.openrdf.model.datatypes.XMLDatatypeUtil.isCalendarDatatype;
import static org.openrdf.model.datatypes.XMLDatatypeUtil.isNumericDatatype;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;

import org.openrdf.model.BNode;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.vocabulary.RDF;

/**
* @author James Leigh
*/
public abstract class IdSequence {

  private static final String UTF_8 = "UTF-8";

  private static ThreadLocal<MessageDigest> md5 = new ThreadLocal<MessageDigest>() {

    @Override
    protected MessageDigest initialValue() {
      try {
        return MessageDigest.getInstance("MD5");
      }
      catch (NoSuchAlgorithmException e) {
        throw new AssertionError(e);
      }
    }

  };

  /** 255 */
  private int LONG = 255;

  private int MOD = 16;

  private HashTable table;

  public int getMod() {
    return MOD;
  }

  public abstract int getShift();

  public abstract int getJdbcIdType();

  public abstract String getSqlType();

  public HashTable getHashTable() {
    return table;
  }

  public void setHashTable(HashTable table) {
    this.table = table;
  }

  public abstract void init()
    throws SQLException;

  public abstract Number maxId(ValueType type);

  public abstract Number minId(ValueType type);

  public int code(Literal value) {
    return shift(minId(valueOf(value)));
  }

  public long hashOf(Value value) {
    final long span = 1152921504606846975l;
    MessageDigest digest = md5.get();
    long type = hashLiteralType(digest, value);
    long hash = type * 31 + hash(digest, value.stringValue());
    return hash & span | valueOf(value).index() * (span + 1);
  }

  public abstract Number nextId(Value value);

  public boolean isLiteral(Number id) {
    return valueOf(id).isLiteral();
  }

  public boolean isLong(Number id) {
    return valueOf(id).isLong();
  }

  public boolean isURI(Number id) {
    return valueOf(id).isURI();
  }

  public Number idOf(Value value) {
    return idOf(hashOf(value));
  }

  public abstract Number idOf(Number number);

  public ValueType valueOf(Number id) {
    int idx = shift(id);
    ValueType[] values = ValueType.values();
    if (idx < 0 || idx >= values.length) {
      throw new IllegalArgumentException("Invalid ID " + id);
    }
    return values[idx];
  }

  protected abstract int shift(Number id);

  protected long hash(MessageDigest digest, String str) {
    try {
      digest.update(str.getBytes(UTF_8));
      return new BigInteger(1, digest.digest()).longValue();
    }
    catch (UnsupportedEncodingException e) {
      throw new AssertionError(e);
    }
  }

  protected long hashLiteralType(MessageDigest digest, Value value) {
    if (value instanceof Literal) {
      Literal lit = (Literal)value;
      if (lit.getDatatype() != null) {
        return hash(digest, lit.getDatatype().stringValue());
      }
      if (lit.getLanguage() != null) {
        return hash(digest, lit.getLanguage());
      }
    }
    return 0;
  }

  private boolean isZoned(Literal lit) {
    String stringValue = lit.stringValue();
    int length = stringValue.length();
    if (length < 1) {
      return false;
    }
    if (stringValue.charAt(length - 1) == 'Z') {
      return true;
    }
    if (length < 6) {
      return false;
    }
    if (stringValue.charAt(length - 3) != ':') {
      return false;
    }
    char chr = stringValue.charAt(length - 6);
    return chr == '+' || chr == '-';
  }

  private ValueType valueOf(BNode value) {
    return ValueType.BNODE;
  }

  protected ValueType valueOf(Literal lit) {
    String lang = lit.getLanguage();
    URI dt = lit.getDatatype();
    int length = lit.stringValue().length();
    if (lang != null) {
      // language
      if (length > LONG) {
        return ValueType.LANG_LONG;
      }
      return ValueType.LANG;
    }
    if (dt == null) {
      // simple
      if (length > LONG) {
        return ValueType.SIMPLE_LONG;
      }
      return ValueType.SIMPLE;
    }
    if (isNumericDatatype(dt)) {
      return ValueType.NUMERIC;
    }
    if (isCalendarDatatype(dt)) {
      // calendar
      if (isZoned(lit)) {
        return ValueType.DATETIME_ZONED;
      }
      return ValueType.DATETIME;
    }
    if (RDF.XMLLITERAL.equals(dt)) {
      return ValueType.XML;
    }
    if (length > LONG) {
      return ValueType.TYPED_LONG;
    }
    return ValueType.TYPED;
  }

  private ValueType valueOf(URI value) {
    if (value.stringValue().length() > LONG) {
      return ValueType.URI_LONG;
    }
    return ValueType.URI;
  }

  protected ValueType valueOf(Value value) {
    if (value instanceof URI) {
      return valueOf((URI)value);
    }
    if (value instanceof Literal) {
      return valueOf((Literal)value);
    }
    assert value instanceof BNode : value;
    return valueOf((BNode)value);
  }
}
TOP

Related Classes of org.openrdf.sail.rdbms.schema.IdSequence

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.