Package com.clarkparsia.pellet.rules.builtins

Source Code of com.clarkparsia.pellet.rules.builtins.DateTimeOperators

// Copyright (c) 2006 - 2008, Clark & Parsia, LLC. <http://www.clarkparsia.com>
// This source code is available under the terms of the Affero General Public License v3.
//
// Please see LICENSE.txt for full license terms, including the availability of proprietary exceptions.
// Questions, comments, or requests for clarification: licensing@clarkparsia.com

package com.clarkparsia.pellet.rules.builtins;

import static org.mindswap.pellet.utils.Namespaces.XSD;

import java.math.BigDecimal;

import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.XMLGregorianCalendar;

import org.mindswap.pellet.ABox;
import org.mindswap.pellet.Literal;
import org.mindswap.pellet.utils.ATermUtils;

import aterm.ATermAppl;

import com.clarkparsia.pellet.datatypes.Datatype;
import com.clarkparsia.pellet.datatypes.exceptions.InvalidLiteralException;
import com.clarkparsia.pellet.datatypes.types.datetime.XSDDate;
import com.clarkparsia.pellet.datatypes.types.datetime.XSDDateTime;
import com.clarkparsia.pellet.datatypes.types.datetime.XSDTime;

/**
* <p>
* Title: Date Time Operators
* </p>
* <p>
* Description: Implementations for each of the SWRL date-time operators.
* </p>
* <p>
* Copyright: Copyright (c) 2008
* </p>
* <p>
* Company: Clark & Parsia, LLC. <http://www.clarkparsia.com>
* </p>
*
* @author Ron Alford
*/
public class DateTimeOperators {
 
  private static class Date implements GeneralFunction, StringToStringFunction {
   
    StringFunctionAdapter allBound = new StringFunctionAdapter( this, XSD + "date" );
   
    public boolean apply(ABox abox, Literal[] args) {
      // Assume applicability check means we have the right number of arguments.
      if ( args[0] != null && args[0].getValue() instanceof XMLGregorianCalendar ) {
        XMLGregorianCalendar value = (XMLGregorianCalendar) args[0].getValue();
        Literal[] results = new Literal[ 5 ];
        results[0] = args[0];
        results[1] = createInteger( abox, value.getYear() );
        results[2] = createInteger( abox, value.getMonth() );
        results[3] = createInteger( abox, value.getDay() );
        if ( value.getTimezone() != DatatypeConstants.FIELD_UNDEFINED ) {
          results[4] = abox.addLiteral( ATermUtils.makePlainLiteral( toTZ( value.getTimezone() ) ) );
        } else {
          results[4] = abox.addLiteral( ATermUtils.makePlainLiteral( "" ) );
        }
       
        if ( mergeResults( args, results ) )
          return true;
      } else if ( restBound( args ) ) {
        Literal result = allBound.apply( abox, args[0], argList( args ) );
        if ( result != null ) {
          if ( args[0] == null )
            args[0] = result;
          return true;
        }
      }
     
      return false;
    }

    public String apply(String... args) {
      if ( args.length < 3 || args.length > 4 ) {
        return null;
      }
     
      String tz = "";
      if ( args.length == 4 )
        tz = args[3];
     
      String dateString = toDate( args[0], args[1], args[2] ) + tz;
     
      if ( !checkValue( dateString, XSDDate.getInstance() ) )
        return null;
     
      return dateString;
    }

    public boolean isApplicable(boolean[] boundPositions) {
      return applicability( 4, 5, boundPositions );
    }
   
  }
 
  private static class DateTime implements GeneralFunction, StringToStringFunction {

    StringFunctionAdapter allBound = new StringFunctionAdapter( this, XSD + "dateTime" );
   
    public boolean apply(ABox abox, Literal[] args) {
      // Assume applicability check means we have the right number of arguments.
      if ( restBound( args ) ) {
        Literal result = allBound.apply( abox, args[0], argList( args ) );
        if ( result != null ) {
          if ( args[0] == null )
            args[0] = result;
          return true;
        }
        return false;
      }
     
      if ( args[0].getValue() instanceof XMLGregorianCalendar ) {
        XMLGregorianCalendar value = (XMLGregorianCalendar) args[0].getValue();
        Literal[] results = new Literal[ 8 ];
        results[0] = args[0];
        results[1] = createInteger( abox, value.getYear());
        results[2] = createInteger( abox, value.getMonth() );
        results[3] = createInteger( abox, value.getDay() );
        results[4] = createInteger( abox, value.getHour() );
        results[5] = createInteger( abox, value.getMinute() );
        final BigDecimal fractionalSeconds = value.getFractionalSecond();
        results[6] = createDecimal( abox, (fractionalSeconds == null)
          ? value.getSecond()
          : fractionalSeconds.add( BigDecimal.valueOf( value.getSecond() ) ) );
        if ( value.getTimezone() != DatatypeConstants.FIELD_UNDEFINED ) {
          results[7] = abox.addLiteral( ATermUtils.makePlainLiteral( toTZ( value.getTimezone() ) ) );
        }
       
        if ( mergeResults( args, results ) )
          return true;
      }
     
      return false;
    }
   
    public String apply(String... args) {
      if ( args.length < 6 || args.length > 7 ) {
        return null;
      }
     
      String tz = "";
      if ( args.length == 7 )
        tz = args[6];
     
      String dateTimeString = toDate( args[0], args[1], args[2] ) + "T" + toTime( args[3], args[4], args[5] ) + tz;
     
      if ( !checkValue( dateTimeString, XSDDateTime.getInstance() ) )
        return null;
     
      return dateTimeString;
    }
   

    public boolean isApplicable(boolean[] boundPositions) {
      return applicability( 7, 8, boundPositions );
    }
  }
   
  /**
   * YearMonthDuration  and DayTimeDuration creation are combined into this single class.
   * The swrl spec seems a bit restrictive in not allowing the creation of negative time durations,
   * so if the first argument is prefixed with a minus sign, we create a negative duration.
   *
   */
  private static class Duration implements GeneralFunction, StringToStringFunction {
   
    public static enum DURATIONTYPE {
      FULL( 0, 5 ),
      YEARMONTH( 0, 2 ),
      DAYTIME( 2, 5 );
     
      private int start;
      private int end;
     
      DURATIONTYPE( int start, int end ) {
        this.start = start;
        this.end = end;
      }
     
    }
   
    private static final char[] SEP = { 'Y', 'M', 'D', 'H', 'M', 'S' };
   
    private StringFunctionAdapter allBound;
    private DURATIONTYPE granularity;
   
    public Duration( DURATIONTYPE dur ) {
      this.granularity = dur;
      allBound = new StringFunctionAdapter( this, XSD + "duration" );
    }
   
    public boolean apply(ABox abox, Literal[] args) {
      if ( restBound( args ) ) {
        Literal result = allBound.apply( abox, args[0], argList( args ) );
        if ( result != null ) {
          if ( args[0] == null )
            args[0] = result;
          return true;
        }
        return false;
      }
     
      // Can't do anything with duration values until XSDLib is upgraded.
     
      return false;
     
    }
   
    public String apply(String... args) {
      if ( args.length > SEP.length + granularity.start )
        return null;
     
      StringBuffer result;
      if ( args[ 0 ].charAt( 0 ) != '-' ) {
        result = new StringBuffer( "P" );
      } else {
        result = new StringBuffer( "-P" );
        args[ 0 ] = args[ 0 ].substring( 1 );
      }
     
      boolean seenTime = false;
      int i = granularity.start;
      for ( String arg : args ) {
        if( arg.length() > 0 ) {
          if( i > 2 && seenTime == false ) {
            seenTime = true;
            result.append( 'T' );
          }
         
          result.append( arg );
          result.append( SEP[i] );
        }
        i++;
       
      }
         
      return result.toString();
    }
   
    public boolean isApplicable(boolean[] boundPositions) {
      return applicability( 4, 5, boundPositions );
    }
   
  }
 
  private static class Time implements GeneralFunction, StringToStringFunction {

      StringFunctionAdapter allBound = new StringFunctionAdapter( this, XSD + "time" );
     
      public boolean apply(ABox abox, Literal[] args) {
        if ( restBound( args ) ) {
          Literal result = allBound.apply( abox, args[0], argList( args ) );
          if ( result != null ) {
            if ( args[0] == null )
              args[0] = result;
            return true;
          }
          return false;
        }
       
        if ( args[0].getValue() instanceof XMLGregorianCalendar ) {
          XMLGregorianCalendar value = (XMLGregorianCalendar) args[0].getValue();
          Literal[] results = new Literal[ 5 ];
          results[0] = args[0];
          results[1] = createInteger( abox, value.getHour() );
          results[2] = createInteger( abox, value.getMinute() );
          final BigDecimal fractionalSeconds = value.getFractionalSecond();
          results[3] = createDecimal( abox, (fractionalSeconds == null)
            ? value.getSecond()
            : fractionalSeconds.add( BigDecimal.valueOf( value.getSecond() ) ) );
          if ( value.getTimezone() != DatatypeConstants.FIELD_UNDEFINED ) {
            results[4] = abox.addLiteral( ATermUtils.makePlainLiteral( toTZ( value.getTimezone() ) ) );
          }
         
          if ( mergeResults( args, results ) )
            return true;
        }
       
        return false;
       
      }
     
      public String apply(String... args) {
        if ( args.length < 3 || args.length > 4 ) {
          return null;
        }
       
        String tz = "";
        if ( args.length == 4 )
          tz = args[3];
       
        String timeString = toTime( args[0], args[1], args[2] ) + tz;
       
        if ( !checkValue( timeString, XSDTime.getInstance() ) )
          return null;
       
        return timeString;
      }

      public boolean isApplicable(boolean[] boundPositions) {
        return applicability( 4, 5, boundPositions );
      }
   
  } 
 
  public final static GeneralFunction date = new Date();
 
  public final static GeneralFunction dateTime = new DateTime();
 
  public final static Function dayTimeDuration = new StringFunctionAdapter( new Duration( Duration.DURATIONTYPE.DAYTIME ), XSD + "duration" );
 
  public final static GeneralFunction time = new Time();
 
  public final static Function yearMonthDuration = new StringFunctionAdapter( new Duration( Duration.DURATIONTYPE.YEARMONTH), XSD + "duration" );
 
 
  private static boolean applicability( int minargs, int maxargs, boolean[] boundPositions ) {
    if ( boundPositions.length < minargs || boundPositions.length > maxargs )
      return false;
   
    if ( boundPositions[0] )
      return true;
   
    for ( int i = 1; i < boundPositions.length; i++ ) {
      if ( !boundPositions[i] )
        return false;
    }
    return true;
   
  }
 
  private static Literal[] argList( Literal[] literals ) {
    Literal[] args = new Literal[ literals.length - 1 ];
    for ( int i = 1; i < literals.length; i++ ) {
      args[ i-1 ] = literals[ i ];
    }
    return args;
  }
 
  private static boolean checkValue( String val, Datatype<?> dt ) {
    try {
      dt.getValue(ATermUtils.makeTypedLiteral(val, dt.getName()));
      return true;
    }
    catch (InvalidLiteralException e) {
      return false;
    }
  }
 
  private static Literal createDecimal( ABox abox, Number val ) {
    ATermAppl term = ATermUtils.makeTypedLiteral( val.toString(), XSD + "decimal" );
    return abox.addLiteral( term );
  }
 
  private static Literal createInteger( ABox abox, Number val ) {
    ATermAppl term = ATermUtils.makeTypedLiteral( val.toString(), XSD + "integer" );
    return abox.addLiteral( term );
  }
 
  private static boolean mergeResults( Literal[] args1, Literal[] args2 ) {
    for ( int i = 0; i < args1.length; i++ ) {
      if ( args1[i] == null ) {
        if ( args2[i] == null )
          return false;
        args1[i] = args2[i];
      } else {
        if ( args2[i] != null ) {
          if ( !ComparisonTesters.equal.test( new Literal[]{ args1[i], args2[i] } ) )
            return false;
        }
      }
    }
    return true;
  }
 
  private static String pad( int p, String s ) {
    while ( s.length() < p ) {
      s = "0" + s;
    }
    return s;
  }
 
  private static boolean restBound( Literal[] args ) {
   
    for ( int i = 1; i < args.length; i++ ) {
      if ( args[i] == null )
        return false;
    }
    return true;
  }
 
  private static String toDate( String year, String month, String day ) {
    return pad( 4, year) + "-" + pad( 2, month) + "-" + pad( 2, day );
  }
 
  private static String toTime( String hour, String minute, String second ) {
    String millis = "";
    int point = second.indexOf( '.' );
    if ( point >= 0 ) {
      millis = second.substring( point );
      second = second.substring( 0, point );
    }
   
    return pad( 2, hour ) + ":" + pad( 2, minute ) + ":" + pad( 2, second ) + millis;
  }
 
  private static String toTZ( int tz ) {
    if ( tz == 0 )
      return "Z";
    else
      return String.format( "%+03d:02d", tz / 60 , tz % 60 );
  }
 
}
TOP

Related Classes of com.clarkparsia.pellet.rules.builtins.DateTimeOperators

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.