|
From: Elmer G. <ega...@us...> - 2004-07-26 22:55:16
|
Update of /cvsroot/javaowl/JavaOWL/src/org/javaowl/models/prevalence In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22946/src/org/javaowl/models/prevalence Modified Files: PrevalentGraph.java StorageGraph.java Added Files: AddTripleCommand.java DeleteTripleCommand.java StorageUtil.java Log Message: Working in prevalence. Index: PrevalentGraph.java =================================================================== RCS file: /cvsroot/javaowl/JavaOWL/src/org/javaowl/models/prevalence/PrevalentGraph.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PrevalentGraph.java 22 Jul 2004 02:47:41 -0000 1.1 --- PrevalentGraph.java 26 Jul 2004 22:55:02 -0000 1.2 *************** *** 20,24 **** package org.javaowl.models.prevalence; ! public class PrevalentGraph { } --- 20,148 ---- package org.javaowl.models.prevalence; ! import java.io.IOException; ! ! import org.prevayler.implementation.SnapshotPrevayler; ! ! import com.hp.hpl.jena.graph.Graph; ! import com.hp.hpl.jena.graph.Triple; ! import com.hp.hpl.jena.graph.Node; ! import com.hp.hpl.jena.graph.TripleMatch; ! import com.hp.hpl.jena.graph.TransactionHandler; ! import com.hp.hpl.jena.graph.BulkUpdateHandler; ! import com.hp.hpl.jena.graph.Capabilities; ! import com.hp.hpl.jena.graph.GraphEventManager; ! import com.hp.hpl.jena.graph.Reifier; ! import com.hp.hpl.jena.graph.query.QueryHandler; ! import com.hp.hpl.jena.shared.PrefixMapping; ! import com.hp.hpl.jena.shared.AddDeniedException; ! import com.hp.hpl.jena.shared.DeleteDeniedException; ! import com.hp.hpl.jena.util.iterator.ExtendedIterator; ! ! public class PrevalentGraph implements Graph, Runnable{ ! ! private final SnapshotPrevayler prevayler; ! private final Graph storageGraph; ! ! public PrevalentGraph(String directory) throws IOException, ClassNotFoundException { ! prevayler = new SnapshotPrevayler(new StorageGraph(), directory); ! storageGraph = (StorageGraph) prevayler.system(); ! } ! ! public void run() { ! for (;;) { ! try { ! try { ! Thread.sleep(1000 * 60 * 60 * 24); ! } catch (InterruptedException ignore) { ! //Ignore ! } ! prevayler.takeSnapshot(); ! System.err.println("Snapshot taken at " + new java.util.Date() + "..."); ! } catch (IOException e) { ! e.printStackTrace(); ! } ! } ! } ! ! public boolean dependsOn(Graph other) { ! return storageGraph.dependsOn(other); ! } ! ! public QueryHandler queryHandler() { ! return storageGraph.queryHandler(); ! } ! ! public TransactionHandler getTransactionHandler() { ! return storageGraph.getTransactionHandler(); ! } ! ! public BulkUpdateHandler getBulkUpdateHandler() { ! return storageGraph.getBulkUpdateHandler(); ! } ! ! public Capabilities getCapabilities() { ! return storageGraph.getCapabilities(); ! } ! ! public GraphEventManager getEventManager() { ! return storageGraph.getEventManager(); ! } ! ! public Reifier getReifier() { ! return storageGraph.getReifier(); ! } ! ! public PrefixMapping getPrefixMapping() { ! return storageGraph.getPrefixMapping(); ! } ! ! public ExtendedIterator find(TripleMatch m) { ! return storageGraph.find(m); ! } ! ! public ExtendedIterator find(Node s, Node p, Node o) { ! return storageGraph.find(s, p, o); ! } ! ! public boolean isIsomorphicWith(Graph g) { ! return storageGraph.isIsomorphicWith(g); ! } ! ! public boolean contains(Node s, Node p, Node o) { ! return storageGraph.contains(s, p, o); ! } + public boolean contains(Triple t) { + return storageGraph.contains(t); + } + + public void close() { + storageGraph.close(); + } + + public boolean isEmpty() { + return storageGraph.isEmpty(); + } + + public int size() { + return storageGraph.size(); + } + + public void delete(Triple t) throws DeleteDeniedException { + try { + prevayler.executeCommand(new DeleteTripleCommand(t)); + } catch (Exception e) { + e.printStackTrace(); + throw new DeleteDeniedException(e.toString()); + } + } + + public void add(Triple t) throws AddDeniedException { + try { + prevayler.executeCommand(new AddTripleCommand(t)); + } catch (Exception e) { + e.printStackTrace(); + throw new AddDeniedException(e.toString()); + } + } } --- NEW FILE: StorageUtil.java --- /* (c) Copyright 2003, Hewlett-Packard Development Company, LP [See end of file] */ package org.javaowl.models.prevalence; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.zip.CRC32; import com.hp.hpl.jena.datatypes.RDFDatatype; import com.hp.hpl.jena.datatypes.TypeMapper; import com.hp.hpl.jena.db.GraphRDB; import com.hp.hpl.jena.db.IDBConnection; import com.hp.hpl.jena.db.RDFRDBException; import com.hp.hpl.jena.db.impl.DBIDInt; import com.hp.hpl.jena.graph.Graph; import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Node_Literal; import com.hp.hpl.jena.graph.Node_URI; import com.hp.hpl.jena.graph.Node_Variable; import com.hp.hpl.jena.graph.impl.LiteralLabel; import com.hp.hpl.jena.rdf.model.AnonId; import com.hp.hpl.jena.shared.*; import com.hp.hpl.jena.vocabulary.RDF; import org.apache.xerces.util.XMLChar; public class StorageUtil { /** true if the database engine will trim trailing spaces in strings. to * prevent this, append EOS to strings that should not be trimmed. */ protected boolean STRINGS_TRIMMED; /** EOS is appended to most RDB strings to deal with string trimming. if * STRINGS_TRIMMED is false, EOS is null. otherwise, EOS is EOS_CHAR. * EOS_LEN is the length of EOS (0 or 1). */ protected String EOS = ""; protected char EOS_CHAR = ':'; protected int EOS_LEN = 0; /** the quote character used to delimit characters and strings. */ protected char QUOTE_CHAR = '\"'; /** * Indicates whether search pattern used to select system objects by name should * be upper-case. */ protected boolean DB_NAMES_TO_UPPER = false; /** true if URI's are to be compressed by storing prefixes (an approximation * of a namespace) in the JENA_PREFIX table. note that "short" prefixes are * not stored, i.e., the prefix length not more than URI_COMPRESS_LENGTH. */ protected boolean URI_COMPRESS; /** if URI_COMPRESS is true, compress prefixes that are longer than this.*/ protected int URI_COMPRESS_LENGTH = 100; /** The maximum size of an object that can be stored in a Statement table */ protected int LONG_OBJECT_LENGTH; /** The maximum possible value for LONG_OBJECT_LENGTH (db-dependent) */ protected int LONG_OBJECT_LENGTH_MAX; /** The SQL type to use for storing ids (compatible with wrapDBID) */ protected String ID_SQL_TYPE; /** Set to true if the insert operations already check for duplications */ protected boolean SKIP_DUPLICATE_CHECK; /** Set to true if IDs are allocated prior to insert */ protected boolean PRE_ALLOCATE_ID; /** The name of the sql definition file for this database/layout combo */ protected String SQL_FILE; /** The name of the sql definition file for this database/layout combo */ protected String DEFAULT_SQL_FILE = "etc/generic_generic.sql"; // ======================================================================= // Common variables // ======================================================================= /** * Holds prefix for names of Jena database tables. */ protected String TABLE_NAME_PREFIX = "jena_"; /** * Holds maximum length of table and index names in database. */ protected int TABLE_NAME_LENGTH_MAX; /** * Holds the length of the longest jena table or index name. * This is really a hack and should be better architected. * The currently known longest possible name is: * <prefix>GnTm_StmtXSP where prefix is the table * name prefix (which isn't counted here), n is the * graph identifier, m is the table number within that * graph and XSP refers to the subject-predicate index. * If we assume n and m might be two digits, we get 14. */ protected int JENA_LONGEST_TABLE_NAME_LENGTH = 14; /** Set to true to enable cache of pre-prepared statements */ protected boolean CACHE_PREPARED_STATEMENTS = true; /** The name of the layout type this driver supports */ protected String LAYOUT_TYPE = "TripleStore"; /** Default name of the table that holds system property graph asserted statements **/ protected String SYSTEM_STMT_TABLE; /** Name of the long literal table **/ protected String LONG_LIT_TABLE; /** Name of the long URI table **/ protected String LONG_URI_TABLE; /** Name of the prefix table **/ protected String PREFIX_TABLE; /** Name of the graph table **/ protected String GRAPH_TABLE; /** If not null, newly-created graphs share tables with the identified graph **/ protected String STORE_WITH_MODEL = null; /** Name of the graph holding default properties (the one's that a newly-created * graph will have by default **/ protected final String DEFAULT_PROPS = "JENA_DEFAULT_GRAPH_PROPERTIES"; /** Unique numeric identifier of the graph holding default properties **/ protected final int DEFAULT_ID = 0; /** Driver version number */ protected final String VERSION = "2.0alpha"; /** Database layout version */ protected String LAYOUT_VERSION = "2.0"; // ======================================================================= // Instance variables // ======================================================================= /** * Instance of SQLCache used by Driver for hard-coded db commands */ protected SQLCache m_sql = null; /** Cache a reference to the system property graph (java) **/ protected SpecializedGraph m_sysProperties = null; protected IDBConnection m_dbcon = null; protected LRUCache prefixCache = null; public static final int PREFIX_CACHE_SIZE = 50; /* * The following routines are responsible for encoding nodes * as database structures. For each node type stored (currently, * literals, URI, blank), there are two possible encodings * depending on the node size. Small nodes may be stored * within a statement table. If the node is long (will not * fit within the statement table), it is be stored in a * separate table for that node type. * * In addition, for resources (URI, blank nodes), the URI * may be optionally compressed. Below, the possibilites * are enumerated. * * Literal Encoding in Statement Tables * Short Literal: Lv:[langLen]:[datatypeLen]:[langString][datatypeString]value[:] * Long Literal: Lr:dbid * Literal Encoding in Long Literal Table * Literal: Lv:[langLen]:[datatypeLen]:[langString][datatypeString]head[:] hash tail * * Comments: * L indicates a literal * v indicates a value * r indicates a reference to another table * : is used as a delimiter. note that MySQL trims trailing white space for * certain VARCHAR columns so an extra delimiter is appended when necessary * for those columns. it is not required for dbid, however. * dbid references the long literal table * langLen is the length of the language identifier for the literal * langString is the language identifier * datatypeLen is the length of the datatype for the literal * datatypeString is the datatype for the literal * value is the lexical form of the string * head is a prefix of value that can be indexed * hash is the CRC32 hash value for the tail * tail is the remainder of the value that cannot be indexed * * * * URI Encoding in Statement Tables * Short URI: Uv:[pfx_dbid]:URI[:] * Long URI: Ur:[pfx_dbid]:dbid * URI Encoding in Long URI Table * URI: Uv:head[:] hash tail * * Comments: * U indicates a URI * pfx_dbid references the prefix table. if the prefix is too * short (i.e., the length of the prefix is less than * URI_COMPRESS_LENGTH), the URI is not compressed and * pfx_dbid is null. * URI is the complete URI * other notation same as for literal encoding * * Blank Node Encoding in Statement Tables * Short URI: Bv:[pfx_dbid]:bnid[:] * Long URI: Br:[pfx_dbid]:dbid * Blank Encoding in Long URI Table * URI: Bv:head[:] hash tail * * Comments: * B indicates a blank node * bnid is the blank node identifier * other notation same as above * Note: currently, blank nodes are always stored uncompressed (pfix_dbid is null). * * Variable Node Encoding in Statement Tables * Variable Node: Vv:name * * Comments: * V indicates a variable node * v indicates a value * name is the variable name * Note: the length must be less than LONG_OBJECT_LENGTH * * ANY Node Encoding in Statement Tables * Variable Node: Av: * * Prefix Encoding in Prefix Table * Prefix: Pv:val[:] [hash] [tail] * * Comments: * P indicates a prefix * other notation same as above * hash and tail are only required for long prefixes. * */ protected static String RDBCodeURI = "U"; protected static String RDBCodeBlank = "B"; protected static String RDBCodeLiteral = "L"; protected static String RDBCodeVariable = "V"; protected static String RDBCodeANY = "A"; protected static String RDBCodePrefix = "P"; protected static String RDBCodeValue = "v"; protected static String RDBCodeRef = "r"; protected static String RDBCodeDelim = ":"; protected static char RDBCodeDelimChar = ':'; protected static String RDBCodeInvalid = "X"; /** * Convert a node to a string to be stored in a statement table. * @param Node The node to convert to a string. Must be a concrete node. * @param addIfLong If the node is a long object and is not in the database, add it. * @return the string or null if failure. */ public String nodeToRDBString ( Node node, boolean addIfLong ) throws RDFRDBException { String res = null; if ( node.isURI() ) { String uri = new String(((Node_URI) node).getURI()); if ( uri.startsWith(RDBCodeURI) ) { throw new RDFRDBException ("URI Node looks like a blank node: " + uri ); } // TODO: need to write special version of splitNamespace for rdb. // or else, need a guarantee that splitNamespace never changes. // the problem is that if the splitNamespace algorithm changes, // then URI's may be encoded differently. so, URI's in existing // databases may become inaccessible. int pos = 0; boolean noCompress; String pfx; String qname; if ( URI_COMPRESS == true ) { pos = dbSplitNamespace(uri); noCompress = (pos == uri.length()) || (pos <= URI_COMPRESS_LENGTH); } else noCompress = true; if ( noCompress ) { pfx = RDBCodeDelim + RDBCodeDelim; qname = uri; } else { // see if it's cached DBIDInt pfxid = URItoPrefix(uri, pos, addIfLong); if ( pfxid == null ) return res; pfx = RDBCodeDelim + ((DBIDInt) pfxid).getIntID() + RDBCodeDelim; qname = uri.substring(pos); } int encodeLen = RDBCodeURI.length() + 1 + pfx.length() + EOS_LEN; boolean URIisLong = objectIsLong(encodeLen,qname); if ( URIisLong ) { int dbid; // belongs in URI table DBIDInt URIid = getURIID(qname,addIfLong); if ( URIid == null ) return res; dbid = URIid.getIntID(); res = new String(RDBCodeURI + RDBCodeRef + pfx + dbid); } else { res = RDBCodeURI + RDBCodeValue + pfx + qname + EOS; } } else if ( node.isLiteral() ){ // TODO: may need to encode literal value when datatype is not a string. Node_Literal litNode = (Node_Literal) node; LiteralLabel ll = litNode.getLiteral(); String lval = ll.getLexicalForm(); String lang = ll.language(); String dtype = ll.getDatatypeURI(); String ld = litLangTypeToRDBString(lang,dtype); int encodeLen = RDBCodeLiteral.length() + 2 + ld.length() + EOS_LEN; boolean litIsLong = objectIsLong(encodeLen,lval); if ( litIsLong ) { int dbid; // belongs in literal table DBIDInt lid = getLiteralID(litNode,addIfLong); if ( lid == null ) return res; dbid = lid.getIntID(); res = new String(RDBCodeLiteral + RDBCodeRef + RDBCodeDelim + dbid); } else { res = new String(RDBCodeLiteral + RDBCodeValue + RDBCodeDelim + ld + lval + EOS); } } else if ( node.isBlank() ) { String bnid = node.getBlankNodeId().toString(); String delims = "::"; int encodeLen = RDBCodeBlank.length() + 1 + delims.length() + EOS_LEN; boolean BisLong = objectIsLong(encodeLen,bnid); if ( BisLong ) { int dbid; // belongs in URI table DBIDInt URIid = getBlankID(bnid,addIfLong); if ( URIid == null ) return res; dbid = URIid.getIntID(); res = new String(RDBCodeBlank + RDBCodeRef + delims + dbid); } else { res = new String(RDBCodeBlank + RDBCodeValue + delims + bnid + EOS); } } else if ( node.isVariable() ){ String name = ((Node_Variable)node).getName(); int len = name.length(); if ( (len + 3 + EOS_LEN) > LONG_OBJECT_LENGTH ) throw new JenaException ("Variable name too long: " + name ); res = RDBCodeVariable + RDBCodeValue + RDBCodeDelim + name + EOS; } else if ( node.equals(Node.ANY) ) { res = RDBCodeANY + RDBCodeValue + RDBCodeDelim; } else { throw new RDFRDBException ("Expected Concrete Node, got " + node.toString() ); } return res; } /** * Convert an RDB string to the node that it encodes. Return null if failure. * @param RDBstring The string to convert to a node. * @return The node or null if failure. */ public Node RDBStringToNode ( String RDBString ) throws RDFRDBException { Node res = null; int len = RDBString.length(); if ( len < 3 ) throw new RDFRDBException("Bad RDBString Header: " + RDBString); String nodeType = RDBString.substring(0,1); String valType = RDBString.substring(1,2); if ( (!(valType.equals(RDBCodeRef) || valType.equals(RDBCodeValue))) || (RDBString.charAt(2) != RDBCodeDelimChar) ) throw new RDFRDBException("Bad RDBString Header: " + RDBString); int pos = 3; int npos; if ( nodeType.equals(RDBCodeURI) ) { ParseInt pi = new ParseInt(pos); String prefix = ""; RDBStringParseInt(RDBString, pi, false); if ( pi.val != null ) { if ( URI_COMPRESS == false ) throw new RDFRDBException("Bad URI: Prefix Compression Disabled: " + RDBString); prefix = IDtoPrefix(pi.val.intValue()); if ( prefix == null ) throw new RDFRDBException("Bad URI Prefix: " + RDBString); } pos = pi.pos + 1; String qname; if ( valType.equals(RDBCodeRef) ) { qname = IDtoURI(RDBString.substring(pos)); if ( qname == null ) throw new RDFRDBException("Bad URI: " + RDBString); } else qname = RDBString.substring(pos,len - EOS_LEN); res = Node.createURI(prefix + qname); } else if ( nodeType.equals(RDBCodeLiteral) ) { ParseInt pi = new ParseInt(pos); String litString = null; if ( valType.equals(RDBCodeRef) ) { RDBStringParseInt(RDBString,pi,true); if ( pi.val != null ) litString = IDtoLiteral(pi.val.intValue()); if ( litString == null ) throw new RDFRDBException("Bad Literal Reference: " + RDBString); } else litString = RDBString.substring(pos,len-EOS_LEN); len = litString.length(); String lang; String dtype; int langLen = 0; int dtypeLen = 0; LiteralLabel llabel; pi.pos = 0; RDBStringParseInt(litString, pi, false); if ( pi.val == null ) langLen = 0; else langLen = pi.val.intValue(); pi.pos = pi.pos + 1; RDBStringParseInt(litString, pi, false); if ( pi.val == null ) dtypeLen = 0; else dtypeLen = pi.val.intValue(); pos = pi.pos + 1; if ( (pos + langLen + dtypeLen) > len ) throw new RDFRDBException("Malformed Literal: " + litString); lang = litString.substring(pos,pos+langLen); pos = pos + langLen; dtype = litString.substring(pos,pos+dtypeLen); pos = pos + dtypeLen; String val = litString.substring(pos); if ( (dtype == null) || (dtype.equals("")) ) { llabel = new LiteralLabel(val, lang == null ? "" : lang); } else { RDFDatatype dt = TypeMapper.getInstance().getSafeTypeByName(dtype); llabel = new LiteralLabel(val, lang == null ? "" : lang, dt); } res = Node.createLiteral(llabel); } else if ( nodeType.equals(RDBCodeBlank) ) { String bstr = null; if ( valType.equals(RDBCodeValue) ) { bstr = RDBString.substring(4,len-EOS_LEN); } else { bstr = IDtoBlank(RDBString.substring(4)); if ( bstr == null ) throw new RDFRDBException("Bad URI: " + RDBString); } res = Node.createAnon( new AnonId (bstr) ); } else if ( nodeType.equals(RDBCodeVariable) ) { String vname = RDBString.substring(3,len-EOS_LEN); res = Node.createVariable(vname); } else if ( nodeType.equals(RDBCodeANY) ) { res = Node.ANY; } else throw new RDFRDBException ("Invalid RDBString Prefix, " + RDBString ); return res; } /** This is cuurently a copy of Util.splitNamespace. It was * copied rather than used directly for two reasons. 1) in the * future it may be desirable to use a different split algorithm * for persistence. 2) the util version could change at any time, * which would render existing databases inaccessible. having a * copy allows the db version to evolve in a controlled way. * * Given an absolute URI, determine the split point between the namespace part * and the localname part. * If there is no valid localname part then the length of the * string is returned. * The algorithm tries to find the longest NCName at the end * of the uri, not immediately preceeded by the first colon * in the string. * @param uri * @return the index of the first character of the localname */ public static int dbSplitNamespace(String uri) { char ch; int lg = uri.length(); if (lg == 0) return 0; int j; int i; for (i = lg - 1; i >= 1; i--) { ch = uri.charAt(i); if (!XMLChar.isNCName(ch)) break; } for (j = i + 1; j < lg; j++) { ch = uri.charAt(j); if (XMLChar.isNCNameStart(ch)) { if (uri.charAt(j - 1) == ':' && uri.lastIndexOf(':', j - 2) == -1) continue; // split "mailto:me" as "mailto:m" and "e" ! else break; } } return j; } class ParseInt { int pos; Integer val; ParseInt(int p) {pos = p;} } private void RDBStringParseInt ( String RDBString, ParseInt pi, boolean toEnd ) { int npos = toEnd ? RDBString.length() : RDBString.indexOf(RDBCodeDelimChar,pi.pos); if ( npos < 0 ) { throw new RDFRDBException("Bad RDB String: " + RDBString); } String intStr = RDBString.substring(pi.pos,npos); pi.pos = npos; if ( intStr.equals("") ) pi.val = null; else try { pi.val = new Integer(intStr); } catch (NumberFormatException e1) { throw new RDFRDBException("Bad RDB String: " + RDBString); } return; } private DBIDInt URItoPrefix ( String uri, int pos, boolean add ) { DBIDInt res; Object key = prefixCache.getByValue(uri.substring(0,pos)); if ( key == null ) { RDBLongObject lobj = PrefixToLongObject(uri,pos); res = getLongObjectID(lobj, PREFIX_TABLE, add); if ( res != null ) prefixCache.put(res,uri.substring(0,pos)); } else res = (DBIDInt) key; return res; } private RDBLongObject PrefixToLongObject ( String prefix, int split ) { RDBLongObject res = new RDBLongObject(); int headLen; int avail; res.head = RDBCodePrefix + RDBCodeValue + RDBCodeDelim; headLen = res.head.length(); avail = INDEX_KEY_LENGTH - (headLen + EOS_LEN); if ( split > avail ) { res.head = res.head + prefix.substring(0,avail); res.tail = prefix.substring(avail,split); res.hash = stringToHash(res.tail); } else { res.head = res.head + prefix.substring(0,split); res.tail = ""; } res.head = res.head + EOS; return res; } /** * Encode a literal node's lang and datatype as a string of the * form ":[langLen]:[datatypeLen]:[langString][dataTypeString]" * @return the string. */ public String litLangTypeToRDBString ( String lang, String dtype ) throws RDFRDBException { String res = RDBCodeDelim; res = ((lang == null) ? "" : Integer.toString(lang.length())) + RDBCodeDelim; res = res + ((dtype == null) ? "" : Integer.toString(dtype.length())) + RDBCodeDelim; res = res + (lang == null ? "" : lang) + (dtype == null ? "" : dtype); return res; } /** * Check if an object is long, i.e., it exceeds the length * limit for storing in a statement table. * @return true if literal is long, else false. */ protected boolean objectIsLong ( int encodingLen, String objAsString ) { return ( (encodingLen + objAsString.length()) > LONG_OBJECT_LENGTH); } class RDBLongObject { String head; /* prefix of long object that can be indexed */ long hash; /* hash encoding of tail */ String tail; /* remainder of long object */ } protected RDBLongObject literalToLongObject ( Node_Literal node ) { RDBLongObject res = new RDBLongObject(); int headLen; int avail; LiteralLabel l = node.getLiteral(); String lang = l.language(); String dtype = l.getDatatypeURI(); String val = l.getLexicalForm(); String langType = litLangTypeToRDBString(lang,dtype); res.head = RDBCodeLiteral + RDBCodeValue + RDBCodeDelim + langType; headLen = res.head.length(); avail = INDEX_KEY_LENGTH - (headLen + EOS_LEN); if ( val.length() > avail ) { res.head = res.head + val.substring(0,avail); res.tail = val.substring(avail); res.hash = stringToHash(res.tail); } else { res.head = res.head + val; res.tail = ""; } res.head = res.head + EOS; return res; } protected long stringToHash ( String str ) { CRC32 checksum = new CRC32(); checksum.update(str.getBytes()); return checksum.getValue(); } /** * Return the database ID for the URI, if it exists */ public DBIDInt getBlankID(String bstr, boolean add) throws RDFRDBException { RDBLongObject lobj = URIToLongObject (bstr,RDBCodeBlank); return getLongObjectID(lobj, LONG_URI_TABLE, add); } /** * Return the database ID for the URI, if it exists */ public DBIDInt getURIID(String qname, boolean add) throws RDFRDBException { RDBLongObject lobj = URIToLongObject (qname,RDBCodeURI); return getLongObjectID(lobj, LONG_URI_TABLE, add); } protected RDBLongObject URIToLongObject ( String qname, String code ) { RDBLongObject res = new RDBLongObject(); int headLen; int avail; res.head = code + RDBCodeValue + RDBCodeDelim; headLen = res.head.length(); avail = INDEX_KEY_LENGTH - (headLen + EOS_LEN); if ( qname.length() > avail ) { res.head = res.head + qname.substring(0,avail); res.tail = qname.substring(avail); res.hash = stringToHash(res.tail); } else { res.head = res.head + qname; res.tail = ""; } res.head = res.head + EOS; return res; } /** * Return the database ID for the literal, if it exists */ public DBIDInt getLiteralID(Node_Literal lnode, boolean add) throws RDFRDBException { RDBLongObject lobj = literalToLongObject (lnode); return getLongObjectID(lobj, LONG_LIT_TABLE, add); } public DBIDInt getLongObjectID(RDBLongObject lobj, String table, boolean add) throws RDFRDBException { try { String opName = "getLongObjectID"; if ( lobj.tail.length() > 0 ) opName += "withChkSum"; PreparedStatement ps = m_sql.getPreparedSQLStatement(opName, table); ps.setString(1,lobj.head); if ( lobj.tail.length() > 0 ) ps.setLong(2, lobj.hash); ResultSet rs = ps.executeQuery(); DBIDInt result = null; if (rs.next()) { result = wrapDBID(rs.getObject(1)); } else { if ( add ) result = addRDBLongObject(lobj, table); } m_sql.returnPreparedSQLStatement(ps, opName); return result; } catch (SQLException e1) { // /* DEBUG */ System.out.println("Literal truncation (" + l.toString().length() + ") " + l.toString().substring(0, 150)); throw new RDFRDBException("Failed to find literal", e1); } } /** * Insert a long object into the database. * This assumes the object is not already in the database. * @return the db index of the added literal */ public DBIDInt addRDBLongObject(RDBLongObject lobj, String table) throws RDFRDBException { try { int argi = 1; String opname = "insertLongObject"; PreparedStatement ps = m_sql.getPreparedSQLStatement(opname, table); int dbid = 0; // init only needed to satisy java compiler if ( PRE_ALLOCATE_ID ) { dbid = getInsertID(table); ps.setInt(argi++,dbid); } ps.setString(argi++, lobj.head); if ( lobj.tail.length() > 0 ) { ps.setLong(argi++, lobj.hash); ps.setString(argi++, lobj.tail); } else { ps.setNull(argi++,java.sql.Types.BIGINT); ps.setNull(argi++,java.sql.Types.VARCHAR); } /* if (isBlob || (len == 0) ) { // First convert the literal to a UTF-16 encoded byte array // (this wouldn't be needed for jdbc 2.0 drivers but not all db's have them) byte[] temp = lit.getBytes("UTF-8"); int lenb = temp.length; //System.out.println("utf-16 len = " + lenb); byte[] litData = new byte[lenb + 4]; litData[0] = (byte)(lenb & 0xff); litData[1] = (byte)((lenb >> 8) & 0xff); litData[2] = (byte)((lenb >> 16) & 0xff); litData[3] = (byte)((lenb >> 24) & 0xff); System.arraycopy(temp, 0, litData, 4, lenb); // Oracle has its own way to insert Blobs if (isBlob && m_driver.getDatabaseType().equalsIgnoreCase("Oracle")) { //TODO fix to use Blob // For now, we do not support Blobs under Oracle throw new RDFRDBException("Oracle driver does not currently support large literals."); } else { ps.setBinaryStream(argi++, new ByteArrayInputStream(litData), litData.length); } } */ ps.executeUpdate(); //m_sql.returnPreparedSQLStatement(ps,opname); if ( !PRE_ALLOCATE_ID ) dbid = getInsertID(table); return wrapDBID(new Integer(dbid)); } catch (Exception e1) { /* DEBUG */ System.out.println("Problem on long object (l=" + lobj.head + ") " + e1 ); // System.out.println("ID is: " + id); throw new RDFRDBException("Failed to add long object ", e1); } } /** * Return the prefix string that has the given prefix id. * @param prefixID - the dbid of the prefix. * @return the prefix string or null if it does not exist. */ protected String IDtoPrefix ( int prefixID ) { // check cache DBIDInt dbid = new DBIDInt(prefixID); Object res = prefixCache.get(dbid); if ( res != null) return (String) res; else return IDtoString ( prefixID, PREFIX_TABLE, RDBCodePrefix); } /** * Return the Blank node string that has the given database id. * @param bnID - the dbid of the blank node, as a string. * @return the Blank node string or null if it does not exist. */ protected String IDtoBlank(String bnID) { return IDtoString(bnID, LONG_URI_TABLE, RDBCodeBlank); } /** * Return the URI string that has the given database id. * @param uriID - the dbid of the uri, as a string. * @return the uri string or null if it does not exist. */ protected String IDtoURI(String uriID) { return IDtoString(uriID, LONG_URI_TABLE, RDBCodeURI); } /** * Return the long literal string that has the given database id. * @param litID - the dbid of the literal.. * @return the long literal string or null if it does not exist. */ protected String IDtoLiteral ( int litID ) { return IDtoString ( litID, LONG_LIT_TABLE, RDBCodeLiteral); } protected String IDtoString ( String dbidAsString, String table, String RDBcode ) { int dbID; String res = null; try { dbID = Integer.parseInt(dbidAsString); } catch (NumberFormatException e1) { throw new RDFRDBException("Invalid Object ID: " + dbidAsString); } return IDtoString (dbID, table, RDBcode); } protected String IDtoString ( int dbID, String table, String RDBcode ) { String res = null; RDBLongObject lobj = IDtoLongObject(dbID, table); if ( lobj == null ) throw new RDFRDBException("Invalid Object ID: " + dbID); // debug check if ( !lobj.head.substring(0,3).equals(RDBcode + RDBCodeValue + RDBCodeDelim) ) throw new RDFRDBException("Malformed URI in Database: " + lobj.head); res = lobj.head.substring(3,lobj.head.length() - EOS_LEN); if ( lobj.tail != null ) res = res + lobj.tail; return res; } protected RDBLongObject IDtoLongObject ( int dbid, String table ) { RDBLongObject res = null; try { String opName = "getLongObject"; PreparedStatement ps = m_sql.getPreparedSQLStatement(opName, table); ps.setInt(1,dbid); ResultSet rs = ps.executeQuery(); if (rs.next()) { res = new RDBLongObject(); res.head = rs.getString(1); res.tail = rs.getString(2); } m_sql.returnPreparedSQLStatement(ps,opName); } catch (SQLException e1) { // /* DEBUG */ System.out.println("Literal truncation (" + l.toString().length() + ") " + l.toString().substring(0, 150)); throw new RDFRDBException("Failed to find literal", e1); } return res; } protected RDBLongObject IDtoLongObject ( String idAsString, String table ) { RDBLongObject res = null; int dbid; try { dbid = Integer.parseInt(idAsString); } catch (NumberFormatException e1) { throw new RDFRDBException("Invalid Object ID: " + idAsString); } return IDtoLongObject(dbid,table); } /** * Convert the raw SQL object used to store a database identifier into a java object * which meets the DBIDInt interface. */ public DBIDInt wrapDBID(Object id) throws RDFRDBException { if (id instanceof Number) { return new DBIDInt(((Number)id).intValue()); } else if (id == null) { return null; } else { throw new RDFRDBException("Unexpected DB identifier type: " + id); //return null; } } } /* * (c) Copyright 2000, 2001 Hewlett-Packard Development Company, LP * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ Index: StorageGraph.java =================================================================== RCS file: /cvsroot/javaowl/JavaOWL/src/org/javaowl/models/prevalence/StorageGraph.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** StorageGraph.java 22 Jul 2004 02:47:42 -0000 1.1 --- StorageGraph.java 26 Jul 2004 22:55:02 -0000 1.2 *************** *** 20,24 **** package org.javaowl.models.prevalence; ! public class StorageGraph { } --- 20,99 ---- package org.javaowl.models.prevalence; ! import com.hp.hpl.jena.graph.Graph; ! import com.hp.hpl.jena.graph.Triple; ! import com.hp.hpl.jena.graph.Node; ! import com.hp.hpl.jena.graph.TripleMatch; ! import com.hp.hpl.jena.graph.TransactionHandler; ! import com.hp.hpl.jena.graph.BulkUpdateHandler; ! import com.hp.hpl.jena.graph.Capabilities; ! import com.hp.hpl.jena.graph.GraphEventManager; ! import com.hp.hpl.jena.graph.Reifier; ! import com.hp.hpl.jena.graph.query.QueryHandler; ! import com.hp.hpl.jena.mem.GraphMem; ! import com.hp.hpl.jena.shared.ReificationStyle; ! import com.hp.hpl.jena.shared.PrefixMapping; ! import com.hp.hpl.jena.shared.AddDeniedException; ! import com.hp.hpl.jena.shared.DeleteDeniedException; ! import com.hp.hpl.jena.util.iterator.ExtendedIterator; + import org.prevayler.implementation.AbstractPrevalentSystem; + + class StorageGraph extends AbstractPrevalentSystem implements Graph { + + private final Graph graph = new GraphMem(ReificationStyle.Standard); + + public boolean dependsOn(Graph other) { + return graph.dependsOn(other); + } + public QueryHandler queryHandler() { + return graph.queryHandler(); + } + public TransactionHandler getTransactionHandler() { + return graph.getTransactionHandler(); + } + public BulkUpdateHandler getBulkUpdateHandler() { + return graph.getBulkUpdateHandler(); + } + public Capabilities getCapabilities() { + return graph.getCapabilities(); + } + public GraphEventManager getEventManager() { + return graph.getEventManager(); + } + public Reifier getReifier() { + return graph.getReifier(); + } + public PrefixMapping getPrefixMapping() { + return graph.getPrefixMapping(); + } + public ExtendedIterator find(TripleMatch m) { + return graph.find(m); + } + public ExtendedIterator find(Node s, Node p, Node o) { + return graph.find(s, p, o); + } + public boolean isIsomorphicWith(Graph g) { + return graph.isIsomorphicWith(g); + } + public boolean contains(Node s, Node p, Node o) { + return graph.contains(s, p, o); + } + public boolean contains(Triple t) { + return graph.contains(t); + } + public void close() { + } + public boolean isEmpty() { + return graph.isEmpty(); + } + public int size() { + return graph.size(); + } + + public void delete(Triple t) throws DeleteDeniedException { + graph.delete(t); + } + public void add(Triple t) throws AddDeniedException { + graph.add(t); + } } --- NEW FILE: DeleteTripleCommand.java --- /* * DeleteTripleCommand.java Copyright (C) 2004 Gerardo Horvilleur Martinez, Elmer * Garduno Hernandez * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.javaowl.models.prevalence; import com.hp.hpl.jena.graph.Triple; import org.prevayler.Command; import org.prevayler.PrevalentSystem; import java.io.Serializable; class DeleteTripleCommand implements Command { private final Triple triple; DeleteTripleCommand(Triple triple) { this.triple = triple; } public Serializable execute(PrevalentSystem system) throws Exception { ((StorageGraph) system).delete(triple); return null; } } --- NEW FILE: AddTripleCommand.java --- /* * AddTripleCommand.java Copyright (C) 2004 Gerardo Horvilleur Martinez, Elmer * Garduno Hernandez * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.javaowl.models.prevalence; import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Triple; import com.hp.hpl.jena.util.PrintUtil; import org.prevayler.Command; import org.prevayler.PrevalentSystem; import java.io.Serializable; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.IOException; class AddTripleCommand implements Command { private final transient Triple triple; AddTripleCommand(Triple triple) { this.triple = triple; } public Serializable execute(PrevalentSystem system) throws Exception { ((StorageGraph) system).add(triple); return null; } private void writeObject(ObjectOutputStream out) throws IOException { //String subject = triple.getSubject().equals(Node.NULL) ? null : // m_driver.nodeToRDBString(t.getSubject(),true); //String predicate = triple.getPredicate().equals(Node.NULL) ? null : // m_driver.nodeToRDBString(t.getPredicate(),true); //String object = triple.getObject().equals(Node.NULL) ? null : // m_driver.nodeToRDBString(t.getObject(),true); //System.out.println(PrintUtil.print(triple)); //System.out.println(triple.getSubject() + "^" + triple.getSubject().getClass()); //System.out.println(triple.getPredicate() + "^" + triple.getPredicate().getClass()); //System.out.println(triple.getObject() + "^" + triple.getObject().getClass()); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { } } |