content: /*
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you 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.apache.chemistry.opencmis.client.api;
  
  import java.net.URI;
  import java.net.URL;
  import java.util.Calendar;
  import java.util.Date;
  
  import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
  
  /**
   * Query Statement.
   * <p>
   * Sample code:
   * 
   * <pre>
   * Calendar cal = ...
   * Folder folder = ...
   * 
   * QueryStatement qs = 
   *   session.createQueryStatement("SELECT ?, ? FROM ? WHERE ? &gt; TIMESTAMP ? AND IN_FOLDER(?) OR ? IN (?)");
   * 
   * qs.setProperty(1, "cmis:document", "cmis:name");
   * qs.setProperty(2, "cmis:document", "cmis:objectId");
   * qs.setType(3, "cmis:document");
   * 
   * qs.setProperty(4, "cmis:document", "cmis:creationDate");
   * qs.setDateTime(5, cal);
   * 
   * qs.setId(6, folder);
   * 
   * qs.setProperty(7, "cmis:document", "cmis:createdBy");
   * qs.setString(8, "bob", "tom", "lisa"); 
   * 
   * String statement = qs.toQueryString();
   * </pre>
   */
  public interface QueryStatement extends Cloneable {
  
      /**
       * Sets the designated parameter to the query name of the given type ID.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param typeId
       *            the type ID
       */
      void setType(int parameterIndex, String typeId);
  
      /**
       * Sets the designated parameter to the query name of the given type.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param type
       *            the object type
       */
      void setType(int parameterIndex, ObjectType type);
  
      /**
       * Sets the designated parameter to the query name of the given property.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param propertyId
       *            the property ID
       */
      void setProperty(int parameterIndex, String typeId, String propertyId);
  
      /**
       * Sets the designated parameter to the query name of the given property.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param propertyDefinition
       *            the property definition
       */
      void setProperty(int parameterIndex, PropertyDefinition<?> propertyDefinition);
  
      /**
       * Sets the designated parameter to the given number.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param num
       *            the number
       */
      void setNumber(int parameterIndex, Number... num);
  
      /**
       * Sets the designated parameter to the given string.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param str
       *            the string
       */
      void setString(int parameterIndex, String... str);
  
      /**
       * Sets the designated parameter to the given string. It does not escape
       * backslashes ('\') in front of '%' and '_'.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param str
       *            the LIKE string
       */
      void setStringLike(int parameterIndex, String str);
  
      /**
       * Sets the designated parameter to the given string in a CMIS contains
       * statement.
       * <p>
       * Note that the CMIS specification requires two levels of escaping. The
       * first level escapes ', ", \ characters to \', \" and \\. The characters
       * *, ? and - are interpreted as text search operators and are not escaped
       * on first level. If *, ?, - shall be used as literals, they must be passed
       * escaped with \*, \? and \- to this method.
       * <p>
       * For all statements in a CONTAINS() clause it is required to isolate those
       * from a query statement. Therefore a second level escaping is performed.
       * On the second level grammar ", ', - and \ are escaped with a \. See the
       * spec for further details.
       * <p>
       * 
       * Summary:
       * <table class="chemistry-table">
       * <caption>Escaping Summary</caption>
       * <tr>
       * <th>input</th>
       * <th>first level escaping</th>
       * <th>second level escaping</th>
       * </tr>
       * <tr>
       * <td>*</td>
       * <td>*</td>
       * <td>*</td>
       * </tr>
       * <tr>
       * <td>?</td>
       * <td>?</td>
       * <td>?</td>
       * </tr>
       * <tr>
       * <td>-</td>
       * <td>-</td>
       * <td>-</td>
       * </tr>
       * <tr>
       * <td>\</td>
       * <td>\\</td>
       * <td>\\\\<br>
       * <em>(for any other character following other than * ? -)</em></td>
       * </tr>
       * <tr>
       * <td>\*</td>
       * <td>\*</td>
       * <td>\\*</td>
       * </tr>
       * <tr>
       * <td>\?</td>
       * <td>\?</td>
       * <td>\\?</td>
       * </tr>
       * <tr>
       * <td>\-</td>
       * <td>\-</td>
       * <td>\\-+</td>
       * </tr>
       * <tr>
       * <td>'</td>
       * <td>\'</td>
       * <td>\\\'</td>
       * </tr>
       * <tr>
       * <td>"</td>
       * <td>\"</td>
       * <td>\\\"</td>
       * </tr>
       * </table>
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param str
       *            the CONTAINS string
       */
      void setStringContains(int parameterIndex, String str);
  
      /**
       * Sets the designated parameter to the given object ID.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param id
       *            the object ID
       */
      void setId(int parameterIndex, ObjectId... id);
  
      /**
       * Sets the designated parameter to the given URI.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param uri
       *            the URI
       */
      void setUri(int parameterIndex, URI... uri);
  
      /**
       * Sets the designated parameter to the given URL.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param url
       *            the URL
       */
      void setUrl(int parameterIndex, URL... url);
  
      /**
       * Sets the designated parameter to the given boolean.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param bool
       *            the boolean
       */
      void setBoolean(int parameterIndex, boolean... bool);
  
      /**
       * Sets the designated parameter to the given DateTime value.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param cal
       *            the DateTime value as Calendar object
       */
      void setDateTime(int parameterIndex, Calendar... cal);
  
      /**
       * Sets the designated parameter to the given DateTime value.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param date
       *            the DateTime value as Date object
       */
      void setDateTime(int parameterIndex, Date... date);
  
      /**
       * Sets the designated parameter to the given DateTime value.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param ms
       *            the DateTime value in milliseconds from midnight, January 1,
       *            1970 UTC.
       */
      void setDateTime(int parameterIndex, long... ms);
  
      /**
       * Sets the designated parameter to the given DateTime value with the prefix
       * 'TIMESTAMP '.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param cal
       *            the DateTime value as Calendar object
       */
      void setDateTimeTimestamp(int parameterIndex, Calendar... cal);
  
      /**
       * Sets the designated parameter to the given DateTime value with the prefix
       * 'TIMESTAMP '.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param date
       *            the DateTime value as Date object
       */
      void setDateTimeTimestamp(int parameterIndex, Date... date);
  
      /**
       * Sets the designated parameter to the given DateTime value with the prefix
       * 'TIMESTAMP '.
       * 
       * @param parameterIndex
       *            the parameter index (one-based)
       * @param ms
       *            the DateTime value in milliseconds from midnight, January 1,
       *            1970 UTC.
       */
      void setDateTimeTimestamp(int parameterIndex, long... ms);
  
      /**
       * Returns the query statement.
       * 
       * @return the query statement, not {@code null}
       */
      String toQueryString();
  
      /**
       * Executes the query with {@code searchAllVersions} set to {@code false}.
       * 
       * @see Session#query(String, boolean)
       */
      ItemIterable<QueryResult> query();
  
      /**
       * Executes the query.
       * 
       * @param searchAllVersions
       *            {@code true} if all document versions should be included in
       *            the search results, {@code false} if only the latest document
       *            versions should be included in the search results
       * 
       * 
       * @see Session#query(String, boolean)
       */
      ItemIterable<QueryResult> query(boolean searchAllVersions);
  
      /**
       * Executes the query.
       * 
       * @param searchAllVersions
       *            {@code true} if all document versions should be included in
       *            the search results, {@code false} if only the latest document
       *            versions should be included in the search results
       * @param context
       *            the operation context to use
       * 
       * @see Session#query(String, boolean, OperationContext)
       */
      ItemIterable<QueryResult> query(boolean searchAllVersions, OperationContext context);
  }
  