Limit.java :  » Development » JoSQL » org » josql » internal » Java Open Source

Java Open Source » Development » JoSQL 
JoSQL » org » josql » internal » Limit.java
/*
 * Copyright 2004-2007 Gary Bentley 
 * 
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 
 *
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */
package org.josql.internal;

import java.util.List;
import java.util.ArrayList;

import org.josql.expressions.ValueExpression;

import org.josql.Query;
import org.josql.QueryParseException;
import org.josql.QueryExecutionException;

public class Limit
{

    private ValueExpression start = null;
    private ValueExpression rowsCount = null;

    public Limit ()
    {

    }

    public void init (Query  q)
                throws QueryParseException
    {

  // Init the value expressions...
  if (this.start != null)
  {

      this.start.init (q);

      // Should probably check to ensure that accessors aren't used... since
      // we don't have a "current object" to work on!.
      Class c = this.start.getExpectedReturnType (q);

      if (!Utilities.isNumber (c))
      {

    throw new QueryParseException ("The expected return type of the start expression: \"" +
                 this.start +
                 "\" of the LIMIT clause is: " +
                 c.getName () + 
                 " however the expression when evaluated must return a numeric result.");

      }

  }

  this.rowsCount.init (q);

  // Should probably check to ensure that accessors aren't used... since
  // we don't have a "current object" to work on!.

  // Try and determine what the expected type is that we will return.
  Class c = this.rowsCount.getExpectedReturnType (q);

  if (!Utilities.isNumber (c))
  {

      throw new QueryParseException ("The expected return type of the rows count expression: \"" +
             this.rowsCount +
             "\" of the LIMIT clause is: " +
             c.getName () + 
             " however the expression when evaluated must return a numeric result.");

  }

    }

    public List getSubList (List   objs,
          Query  q)
                      throws QueryExecutionException
    {

  // Get the row count.
  Object o = this.rowsCount.evaluate (null,
              q);

  int rows = -1;

  // Ensure that it is a number.
  if ((o != null)
      &&
      (!(o instanceof Number))
     )
  {

      throw new QueryExecutionException ("Return value of rows count expression: \"" +
                 this.rowsCount +
                 "\" for the LIMIT clause is of type: " +
                 o.getClass ().getName () + 
                 " expected it to return a numeric value.");

  }

  if (o != null)
  {

      // There are rounding issues here, but if the user provides a float/double value...
      rows = ((Number) o).intValue ();

  }

  int start = 0;

  // Now get the start value...
  if (this.start != null)
  {

      Object s = this.start.evaluate (null,
              q);

      // Ensure that it is a number.
      if ((s != null)
    &&
    (!(s instanceof Number))
         )
      {

    throw new QueryExecutionException ("Return value of the start expression: \"" +
               this.start +
               "\" for the LIMIT clause is of type: " +
               s.getClass ().getName () + 
               " expected it to return a numeric value.");

      }

      if (s != null)
      {

    // There are rounding issues here, but if the user provides a float/double value...
    start = ((Number) s).intValue ();

    // Whilst for the user rows start at 1, for us they start at 0...
    start--;

      }

  }

  int ls = objs.size ();

  // Now get our sub-list.
  if (start > (ls - 1))
  {

      // Return nothing, outside of the range.
      return new ArrayList ();

  }

  if (rows > 0)
  {

      if ((start + rows) > (ls - 1))
      {

        // Just return the rows starting at start...
        // We return a new list to prevent issues with modifications...
        return new ArrayList (objs.subList (start,
              ls));

      }

      // Here we return start + rows.
      return new ArrayList (objs.subList (start,
            start + rows));

  } else {

      // Just ignore the rows...
      return new ArrayList (objs.subList (start,
            ls));

  }

    }

    public void setStart (ValueExpression v)
    {

  this.start = v;

    }

    public void setRowsCount (ValueExpression v)
    {

  this.rowsCount = v;

    }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.