/*
 * 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.
 *
 * $Header:$
 */

package org.apache.beehive.controls.system.jdbc.parser;

import org.apache.beehive.controls.api.context.ControlBeanContext;
import org.apache.beehive.controls.system.jdbc.TypeMappingsFactory;

import java.lang.reflect.Method;

/**
 * The abstract base class for fragments generated during parsing.
 */
public abstract class SqlFragment {

    /**
     * True if this fragment shouldn't be cached since the prepared statement may change on each invocation.
     * @return true if this fragment shouldn't be cached by the parser
     */ 
    boolean isDynamicFragment() {
        return false;
    }

    /**
     * Does this fragment contain a parameter value for a prepared statement
     * @return true if this fragement doesn't contain a prepared statement value.
     */
    boolean hasParamValue() {
        return false;
    }

    /**
     * True if this fragment evaluates to a JdbcControl.ComplexSqlFragment, i.e.
     * a value type which needs additional evaluation after reflection.
     * 
     * @param context Control bean context.
     * @param method Method.
     * @param args Method args.
     * @return true if evaluates to a complex sql fragment.
     */
    protected boolean hasComplexValue(ControlBeanContext context, Method method, Object[] args) {
        return false;
    }

    /**
     * Get the SQL data type for the parameter value contained within this fragment.
     * @return The SQL data type for this fragment.
     */
    int getParamSqlDataType() {
        return TypeMappingsFactory.TYPE_UNKNOWN;
    }

    /**
     * Get the prepared statement parameter value contained within this fragment.
     *
     * @param context A ControlBeanContext instance
     * @param method The annotated method
     * @param args The method's parameters
     * @return null if this fragment doesn't contain a parameter value.
     */
    Object[] getParameterValues(ControlBeanContext context, Method method, Object[] args)  {
        return null;
    }

    /**
     * Get the text for a prepared statement generated by this fragment.
     * @param context A ControlBeanContext instance
     * @param method The annotated method
     * @param args The method's parameters
     * @return A String containing the prepared statement text generated by this fragment
     */
    abstract String getPreparedStatementText(ControlBeanContext context, Method method, Object[] args);

    /**
     * Must be implemented for JUnit testing.
     * @return The String value of this fragment.
     */
    public String toString() {
        assert false : "Classes which extend SqlFragment must implement toString()";
        return null;
    }
}
