[Mulgara-svn] r1086 - trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa

pag at mulgara.org pag at mulgara.org
Wed Jul 16 22:13:14 UTC 2008


Author: pag
Date: 2008-07-16 15:13:12 -0700 (Wed, 16 Jul 2008)
New Revision: 1086

Added:
   trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPObjectFactoryUnitTest.java
Modified:
   trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalImpl.java
   trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalUnitTest.java
   trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPObjectFactoryImpl.java
Log:
Mistakenly changed SPDecimal to handle floating point, but the bug report leading to this was really about not throwing an exception for floating point values. Now accepting any lexical value for typed literals, and falling back to using untyped data when the semantics are violated, e.g. when a floating point value is giving for an integer, or a string is given for a number.

Modified: trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalImpl.java
===================================================================
--- trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalImpl.java	2008-07-16 15:13:45 UTC (rev 1085)
+++ trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalImpl.java	2008-07-16 22:13:12 UTC (rev 1086)
@@ -67,37 +67,20 @@
   @SuppressWarnings("unused")
   private final static Logger logger = Logger.getLogger(SPDecimalImpl.class);
 
-  private Number n;
+  private Long l;
   
-  private byte decPlaces = 0;
-
   static final int TYPE_ID = 2; // Unique ID
 
 
   SPDecimalImpl(int subtypeId, URI typeURI, long l) {
     super(TYPE_ID, subtypeId, typeURI);
-    n = l;
+    this.l = l;
   }
 
 
-  SPDecimalImpl(int subtypeId, URI typeURI, double d) {
-    super(TYPE_ID, subtypeId, typeURI);
-    n = d;
-  }
-
-
-  SPDecimalImpl(int subtypeId, URI typeURI, Number n) {
-    super(TYPE_ID, subtypeId, typeURI);
-    this.n = n;
-  }
-
-
   SPDecimalImpl(int subtypeId, URI typeURI, ByteBuffer data) {
     super(TYPE_ID, subtypeId, typeURI);
-    // decimal places stored + 1 so that 0 can indicate a Long
-    decPlaces = (byte)(data.get(Constants.SIZEOF_LONG) - 1);
-    if (decPlaces < 0) this.n = data.getLong();
-    else this.n = data.getDouble();
+    this.l = data.getLong();
   }
 
 
@@ -105,10 +88,12 @@
     super(TYPE_ID, subtypeId, typeURI);
     int decPos = lexicalForm.indexOf('.');
     if (decPos < 0) {
-      n = Long.valueOf(lexicalForm);
+      l = Long.valueOf(lexicalForm);
     } else {
-      n = Double.valueOf(lexicalForm);
-      decPlaces = (byte)(lexicalForm.length() - decPos - 1);
+      for (int i = decPos + 1; i < lexicalForm.length(); i++) {
+        if (lexicalForm.charAt(i) != '0') throw new NumberFormatException("Fractional value in integer: " + lexicalForm);
+      }
+      l = Long.valueOf(lexicalForm.substring(0, decPos));
     }
   }
 
@@ -116,15 +101,8 @@
   /* from SPObject interface. */
 
   public ByteBuffer getData() {
-    ByteBuffer data = ByteBuffer.allocate(Constants.SIZEOF_LONG + 1);
-    // decimal places stored + 1 so that 0 can indicate a Long
-    if (n instanceof Long) {
-      data.putLong((Long)n);
-      data.put((byte)0);
-    } else {
-      data.putDouble((Double)n);
-      data.put((byte)(decPlaces + 1));
-    }
+    ByteBuffer data = ByteBuffer.allocate(Constants.SIZEOF_LONG);
+    data.putLong(l);
     data.flip();
     return data;
   }
@@ -136,10 +114,7 @@
 
 
   public String getLexicalForm() {
-    if (n instanceof Long) return n.toString();
-    String result = String.format("%." + decPlaces + "f", (Double)n);
-    if (decPlaces == 0) result += ".";
-    return result;
+    return l.toString();
   }
 
 
@@ -152,19 +127,14 @@
 
     // Compare the longs.
     SPDecimalImpl di = (SPDecimalImpl)o;
-    // unequal type comparisons
-    if (n instanceof Long && di.n instanceof Long) {
-      return compare(n.longValue(), di.n.longValue());
-    } else {
-      return compare(n.doubleValue(), di.n.doubleValue());
-    }
+    return compare(l.longValue(), di.l.longValue());
   }
 
 
   /* from Object. */
 
   public int hashCode() {
-    return (int)(n.longValue() * 7) | (int)(n.longValue() >> 32);
+    return (int)(l * 7) | (int)(l >> 32);
   }
 
 
@@ -174,7 +144,7 @@
 
     try {
       SPDecimalImpl di = (SPDecimalImpl)obj;
-      return n.equals(di.n);
+      return l.equals(di.l);
     } catch (ClassCastException ex) {
       // obj was not an SPDecimalImpl.
       return false;
@@ -185,11 +155,7 @@
     return l1 < l2 ? -1 : (l1 > l2 ? 1 : 0);
   }
 
-  static int compare(double d1, double d2) {
-    return d1 < d2 ? -1 : (d1 > d2 ? 1 : 0);
-  }
 
-
   /** Compares the binary representations of two SPDecimalImpl objects. */
   public static class SPDecimalComparator implements SPComparator {
 
@@ -204,19 +170,7 @@
     }
 
     public int compare(ByteBuffer d1, ByteBuffer d2) {
-      if (d1.get(Constants.SIZEOF_LONG) == 0) {
-        if (d2.get(Constants.SIZEOF_LONG) == 0) {
-          return SPDecimalImpl.compare(d1.getLong(), d2.getLong());
-        } else {
-          return SPDecimalImpl.compare(d1.getLong(), d2.getDouble());
-        }
-      } else {
-        if (d2.get(Constants.SIZEOF_LONG) == 0) {
-          return SPDecimalImpl.compare(d1.getDouble(), d2.getLong());
-        } else {
-          return SPDecimalImpl.compare(d1.getDouble(), d2.getDouble());
-        }
-      }
+      return SPDecimalImpl.compare(d1.getLong(), d2.getLong());
     }
 
   }

Modified: trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalUnitTest.java
===================================================================
--- trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalUnitTest.java	2008-07-16 15:13:45 UTC (rev 1085)
+++ trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalUnitTest.java	2008-07-16 22:13:12 UTC (rev 1086)
@@ -45,27 +45,19 @@
  */
 public class SPDecimalUnitTest extends TestCase {
 
-  private static final String VALID_XSD_DECIMAL1 = "1001";
+  private static final String VALID_XSD_DECIMAL1 = "101";
 
   private static final String VALID_XSD_DECIMAL2 = "1001.";
 
-  private static final String VALID_XSD_DECIMAL3 = "1001.0";
+  private static final String VALID_XSD_DECIMAL3 = "1021.0";
 
-  private static final String VALID_XSD_DECIMAL4 = "1001.2";
+  private static final String VALID_XSD_DECIMAL4 = "-1";
 
-  private static final String VALID_XSD_DECIMAL5 = "1001.230";
+  private static final String VALID_XSD_DECIMAL5 = "0";
 
-  private static final String VALID_XSD_DECIMAL6 = "0.1234";
-
-  private static final String VALID_XSD_DECIMAL7 = "0.123400";
-
-  private static final String VALID_XSD_DECIMAL8 = "-1";
-
-  private static final String VALID_XSD_DECIMAL9 = "0";
-
   private static final String INVALID_XSD_DECIMAL = "x";
   private static final String INVALID_XSD_DECIMAL2 = "0x";
-  private static final String INVALID_XSD_DECIMAL3 = " 10";
+  private static final String INVALID_XSD_DECIMAL3 = "10.10";
 
   /**
    * Constructs a new test with the given name.
@@ -112,10 +104,6 @@
     validTest(VALID_XSD_DECIMAL3, factory);
     validTest(VALID_XSD_DECIMAL4, factory);
     validTest(VALID_XSD_DECIMAL5, factory);
-    validTest(VALID_XSD_DECIMAL6, factory);
-    validTest(VALID_XSD_DECIMAL7, factory);
-    validTest(VALID_XSD_DECIMAL8, factory);
-    validTest(VALID_XSD_DECIMAL9, factory);
 
     SPDecimalImpl dec = (SPDecimalImpl)factory.newSPTypedLiteral(XSD.DECIMAL_URI, VALID_XSD_DECIMAL1);
 
@@ -123,19 +111,16 @@
     ByteBuffer dtBytes = dec.getData();
 
     long dLong = dtBytes.getLong();
-    byte dByte = dtBytes.get();
 
     // Test the correct value is stored
     assertEquals(VALID_XSD_DECIMAL1, Long.toString(dLong));
-    assertEquals((byte)0, dByte);
 
     // Byte buffer to hold our decimal information
-    ByteBuffer buffer = ByteBuffer.wrap(new byte[Constants.SIZEOF_LONG + 1]);
+    ByteBuffer buffer = ByteBuffer.wrap(new byte[Constants.SIZEOF_LONG]);
 
     // If the previous step passed then we know the long value is what we want,
     // so store it in our buffer
     buffer.putLong(dLong);
-    buffer.put((byte)0);
 
     // Reset the buffer for reading
     buffer.flip();
@@ -145,40 +130,22 @@
 
     // Test that the lexical form of the decimal is correct
     assertEquals(VALID_XSD_DECIMAL1, dec.getLexicalForm());
-
-    dec = (SPDecimalImpl)factory.newSPTypedLiteral(XSD.DECIMAL_URI, VALID_XSD_DECIMAL2);
-
-    // Retrieve the byte data of the decimal object
-    dtBytes = dec.getData();
-
-    double dDbl = dtBytes.getDouble();
-    dByte = dtBytes.get();
-
-    // Test the correct value is stored
-    assertEquals(VALID_XSD_DECIMAL2, String.format("%.0f.", dDbl));
-    assertEquals((byte)1, dByte);
   }
 
   private void validTest(String number, SPDecimalFactory factory) throws Exception {
     // Create a decimal object by lexical string
     SPDecimalImpl d = (SPDecimalImpl)factory.newSPTypedLiteral(XSD.DECIMAL_URI, number);
 
+    if (number.contains(".")) number = number.substring(0, number.indexOf('.'));
     // Test that the lexical form of the decimal is correct
     assertEquals(number, d.getLexicalForm());
 
     // Retrieve the byte data of the decimal object
     ByteBuffer dtBytes = d.getData();
 
-    // Retrieve the long and in values from the buffer
-    byte places = (byte)(dtBytes.get(Constants.SIZEOF_LONG) - 1);
-
     // Create a decimal object from the decimal's long
     SPDecimalImpl dDec;
-    if (places < 0) {
-      dDec = new SPDecimalImpl(0, XSD.DECIMAL_URI, dtBytes.getLong());
-    } else {
-      dDec = new SPDecimalImpl(0, XSD.DECIMAL_URI, dtBytes.getDouble());
-    }
+    dDec = new SPDecimalImpl(0, XSD.DECIMAL_URI, dtBytes.getLong());
 
     assertEquals(d, dDec);
 
@@ -211,12 +178,11 @@
     // Create a new factory
     SPDecimalFactory factory = new SPDecimalFactory();
 
-    // 6 < 1 < 5
     SPDecimalImpl t1, t2, t3;
 
-    t1 = (SPDecimalImpl) factory.newSPTypedLiteral(XSD.DECIMAL_URI, VALID_XSD_DECIMAL6);
-    t2 = (SPDecimalImpl) factory.newSPTypedLiteral(XSD.DECIMAL_URI, VALID_XSD_DECIMAL1);
-    t3 = (SPDecimalImpl) factory.newSPTypedLiteral(XSD.DECIMAL_URI, VALID_XSD_DECIMAL5);
+    t1 = (SPDecimalImpl) factory.newSPTypedLiteral(XSD.DECIMAL_URI, VALID_XSD_DECIMAL1);
+    t2 = (SPDecimalImpl) factory.newSPTypedLiteral(XSD.DECIMAL_URI, VALID_XSD_DECIMAL2);
+    t3 = (SPDecimalImpl) factory.newSPTypedLiteral(XSD.DECIMAL_URI, VALID_XSD_DECIMAL3);
 
     assertTrue(t1.compareTo(t1) == 0);
     assertTrue(t1.compareTo(t2) == -1);

Modified: trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPObjectFactoryImpl.java
===================================================================
--- trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPObjectFactoryImpl.java	2008-07-16 15:13:45 UTC (rev 1085)
+++ trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPObjectFactoryImpl.java	2008-07-16 22:13:12 UTC (rev 1086)
@@ -177,8 +177,14 @@
 
 
   public SPTypedLiteral newSPTypedLiteral(String lexicalForm, URI typeURI) {
-    return SPTypedLiteralRegistry.getSPTypedLiteralFactory(typeURI).
-        newSPTypedLiteral(typeURI, lexicalForm);
+    try {
+      return SPTypedLiteralRegistry.getSPTypedLiteralFactory(typeURI).
+          newSPTypedLiteral(typeURI, lexicalForm);
+    } catch (Exception e) {
+      // catch any parsing problems, and store in an "untyped" way
+      return SPTypedLiteralRegistry.getSPTypedLiteralFactory(UnknownSPTypedLiteralImpl.TYPE_ID).
+          newSPTypedLiteral(typeURI, lexicalForm);
+    }
   }
 
 

Added: trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPObjectFactoryUnitTest.java
===================================================================
--- trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPObjectFactoryUnitTest.java	                        (rev 0)
+++ trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPObjectFactoryUnitTest.java	2008-07-16 22:13:12 UTC (rev 1086)
@@ -0,0 +1,166 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is the Kowari Metadata Store.
+ *
+ * The Initial Developer of the Original Code is Edwin Shin.
+ * Copyright (C) 2005. All Rights Reserved.
+ *
+ * Contributor(s): N/A.
+ *
+ * [NOTE: The text of this Exhibit A may differ slightly from the text
+ * of the notices in the Source Code files of the Original Code. You
+ * should use the text of this Exhibit A rather than the text found in the
+ * Original Code Source Code for Your Modifications.]
+ *
+ */
+
+package org.mulgara.store.stringpool.xa;
+
+// JUnit
+import junit.framework.*;
+
+// Internal Packages
+import org.mulgara.query.rdf.XSD;
+import org.mulgara.store.stringpool.SPTypedLiteral;
+
+/**
+ * Unit test for SPObjectFactory.
+ * TODO: Address all the public methods. This is only testing the recently modified methods.
+ *
+ * @created Jul 16, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SPObjectFactoryUnitTest extends TestCase {
+
+  static final String INT_STR = "123";
+  static final String FLOAT_STR = "123.4";
+  static final String BOOL_STR = "true";
+  static final String DATE_STR = "1971-12-20";
+
+  SPObjectFactoryImpl factory;
+
+  /**
+   * Constructs a new test with the given name.
+   *
+   * @param name the name of the test
+   */
+  public SPObjectFactoryUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   *
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new SPObjectFactoryUnitTest("testValid"));
+    suite.addTest(new SPObjectFactoryUnitTest("testInvalid"));
+    return suite;
+  }
+
+  /**
+   * Default test runner.
+   *
+   * @param args The command line arguments
+   * @throws Exception
+   */
+  public static void main(String[] args) {
+    junit.textui.TestRunner.run(suite());
+  }
+
+  /**
+   * Tests that valid xsd:decimal values are accepted and processed correctly.
+   */
+  public void testValid() throws Exception {
+    SPDecimalImpl spi = (SPDecimalImpl)factory.newSPTypedLiteral(INT_STR, XSD.INTEGER_URI);
+    SPFloatImpl spf = (SPFloatImpl)factory.newSPTypedLiteral(FLOAT_STR, XSD.FLOAT_URI);
+    SPBooleanImpl sps = (SPBooleanImpl)factory.newSPTypedLiteral(BOOL_STR, XSD.BOOLEAN_URI);
+    SPDateImpl spd = (SPDateImpl)factory.newSPTypedLiteral(DATE_STR, XSD.DATE_URI);
+
+    assertEquals(INT_STR, spi.getLexicalForm());
+    assertEquals(FLOAT_STR, spf.getLexicalForm());
+    assertEquals(BOOL_STR, sps.getLexicalForm());
+    assertEquals(DATE_STR, spd.getLexicalForm());
+  }
+
+  /**
+   * Tests invalid xsd:decimal values.
+   */
+  public void testInvalid() throws Exception {
+    SPTypedLiteral[] spi = new SPTypedLiteral[4];
+    spi[0] = null;
+    spi[1] = factory.newSPTypedLiteral(FLOAT_STR, XSD.INTEGER_URI);
+    spi[2] = factory.newSPTypedLiteral(BOOL_STR, XSD.INTEGER_URI);
+    spi[3] = factory.newSPTypedLiteral(DATE_STR, XSD.INTEGER_URI);
+
+    SPTypedLiteral[] spf = new SPTypedLiteral[4];
+    spf[0] = null;
+    spf[1] = null;
+    spf[2] = factory.newSPTypedLiteral(BOOL_STR, XSD.FLOAT_URI);
+    spf[3] = factory.newSPTypedLiteral(DATE_STR, XSD.FLOAT_URI);
+
+    SPTypedLiteral[] spb = new SPTypedLiteral[4];
+    spb[0] = factory.newSPTypedLiteral(INT_STR, XSD.BOOLEAN_URI);
+    spb[1] = factory.newSPTypedLiteral(FLOAT_STR, XSD.BOOLEAN_URI);
+    spb[2] = null;
+    spb[3] = factory.newSPTypedLiteral(DATE_STR, XSD.BOOLEAN_URI);
+
+    SPTypedLiteral[] spd = new SPTypedLiteral[4];
+    spd[0] = factory.newSPTypedLiteral(INT_STR, XSD.DATE_URI);
+    spd[1] = factory.newSPTypedLiteral(FLOAT_STR, XSD.DATE_URI);
+    spd[2] = factory.newSPTypedLiteral(BOOL_STR, XSD.DATE_URI);
+    spd[3] = null;
+    
+    for (int i = 0; i < 4; i++) {
+      if (spi[i] != null) {
+        assertFalse("Wrong int type for i=" + i, spi[i] instanceof SPDecimalImpl);
+        assertEquals(XSD.INTEGER_URI, spi[i].getTypeURI());
+      }
+      if (spf[i] != null) {
+        assertFalse("Wrong float type for i=" + i, spf[i] instanceof SPFloatImpl);
+        assertEquals(XSD.FLOAT_URI, spf[i].getTypeURI());
+      }
+      if (spb[i] != null) {
+        assertFalse("Wrong boolean type for i=" + i, spb[i] instanceof SPBooleanImpl);
+        assertEquals(XSD.BOOLEAN_URI, spb[i].getTypeURI());
+      }
+      if (spd[i] != null) {
+        assertFalse("Wrong date type for i=" + i, spd[i] instanceof SPDateImpl);
+        assertEquals(XSD.DATE_URI, spd[i].getTypeURI());
+      }
+
+    }
+  }
+
+  /**
+   * Initialise members.
+   *
+   * @throws Exception if something goes wrong
+   */
+  public void setUp() throws Exception {
+    super.setUp();
+    factory = new SPObjectFactoryImpl();
+  }
+
+  /**
+   * The teardown method for JUnit
+   *
+   * @throws Exception EXCEPTION TO DO
+   */
+  public void tearDown() throws Exception {
+    super.tearDown();
+  }
+}




More information about the Mulgara-svn mailing list