/* * Copyright (c) 2010 Mysema Ltd. * All rights reserved. * */ package com.mysema.rdfbean.rdb; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Locale; import java.util.Map; import com.mysema.rdfbean.CORE; import com.mysema.rdfbean.model.LIT; import com.mysema.rdfbean.model.NODE; import com.mysema.rdfbean.model.Nodes; import com.mysema.rdfbean.model.RDF; import com.mysema.rdfbean.model.RDFS; import com.mysema.rdfbean.model.RepositoryException; import com.mysema.rdfbean.model.UID; import com.mysema.rdfbean.owl.OWL; /** * MD5IdFactory is a MD5 hash based implementation of the IdFactory interface * * @author tiwe * @version $Id$ */ public class MD5IdFactory implements IdFactory { private final Map<UID, String> uid2string = new HashMap<UID, String>(); public MD5IdFactory() { register("rdf", Nodes.get(RDF.NS)); register("rdfs", Nodes.get(RDFS.NS)); register("owl", Nodes.get(OWL.NS)); register("xsd", Nodes.get(RDF.NS)); register("core", Arrays.asList(CORE.localId)); } private void register(String prefix, Collection<UID> all) { for (UID id : all) { uid2string.put(id, prefix + ":" + id.ln()); } } private String getReadableURI(UID uid) { String rv = uid2string.get(uid); if (rv == null) { rv = uid.getId(); } return rv; } @Override public Long getId(NODE node) { int mask; String value; if (node.isLiteral()) { LIT literal = node.asLiteral(); if (literal.getLang() != null) { mask = 0; value = literal.getValue() + literal.getLang(); } else { mask = 1; value = literal.getValue() + getReadableURI(literal.getDatatype()); } } else if (node.isBNode()) { mask = 2; value = node.getValue(); } else { mask = 3; value = getReadableURI(node.asURI()); } try { MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(value.getBytes("UTF-8")); byte[] hash = digest.digest(); byte[] longBytes = new byte[8]; System.arraycopy(hash, 0, longBytes, 0, longBytes.length); longBytes[0] = (byte) (mask(longBytes[0], mask)); return new BigInteger(longBytes).longValue(); } catch (NoSuchAlgorithmException e) { throw new RepositoryException(e); } catch (UnsupportedEncodingException e) { throw new RepositoryException(e); } } int mask(byte b, int mask) { switch (mask) { case 0: return (b & ~3); // 00 case 1: return (b & ~3) | 1; // 10 case 2: return (b & ~3) | 2; // 01 default: return (b & ~3) | 3; // 11 } } @Override public Integer getId(Locale locale) { try { MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(locale.toString().getBytes("UTF-8")); byte[] hash = digest.digest(); byte[] intBytes = new byte[4]; System.arraycopy(hash, 0, intBytes, 0, intBytes.length); return new BigInteger(intBytes).intValue(); } catch (NoSuchAlgorithmException e) { throw new RepositoryException(e); } catch (UnsupportedEncodingException e) { throw new RepositoryException(e); } } }