OutputParameter.java
/*
** Module : OutputParameter.java
** Abstract : Data wrapper which associates with a variable or a DMO property
**
** Copyright (c) 2016-2024, Golden Code Development Corporation.
**
** -#- -I- --Date-- ---------------------------------Description---------------------------------
** 001 OM 20160114 Created initial version.
** 002 CA 20181229 Added wrap which forces the BDT type expected by the parameter definition.
** 003 CA 20190508 OutputParameter.wrap must be fully generic.
** CA 20190526 Fixed runtime and conversion support for legacy class properties used as
** OUTPUT or INPUT-OUTPUT arguments.
** 004 CA 20190927 Added support for direct Java access from 4GL code.
** 005 CA 20210609 Reworked INPUT/INPUT-OUTPUT parameters to a new approach, where they are explicitly
** initialized at the method's execution, and not at the caller's arguments.
** CA 20210818 Fixed memptr parameter runtime - they share the 'pointer structure' with the passed
** argument.
** 006 DDF 20240408 Pass the type of the parameter and use it to wrap it directly to avoid generating
** a constructor for that type.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.util;
import java.util.function.*;
import com.goldencode.p2j.oo.lang._BaseObject_;
import com.goldencode.p2j.persist.*;
/**
* A utility class which associates a variable or DMO property with a data wrapper object.
* Static methods of this class are invoked by business logic to manage the hidden assignment of
* an INPUT-OUTPUT or an OUTPUT parameter to original variable or the database field with which
* it is associated, upon return from a procedure or function.
*/
public final class OutputParameter
{
/**
* Creates wrapper for a legacy instance property and returns instance of T type. This form can
* be used only with both OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
*
* @param propType
* The legacy property's data type.
* @param instance
* The legacy object instance.
* @param property
* The property's name.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
object<? extends _BaseObject_> instance,
String property,
boolean io)
{
return new PropertyReference(instance, property).wrap(io);
}
/**
* Creates wrapper for a legacy instance property and returns instance of T type. This form can
* be used only with OUTPUT parameters.
*
* @param propType
* The legacy property's data type.
* @param instance
* The legacy object instance.
* @param property
* The property's name.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
object<? extends _BaseObject_> instance,
String property)
{
return new PropertyReference(instance, property).wrap(false);
}
/**
* Creates wrapper for a legacy static property and returns instance of T type. This form can
* be used only with both OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
*
* @param propType
* The legacy property's data type.
* @param className
* The fully qualified legacy class name.
* @param property
* The property's name.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
String className,
String property,
boolean io)
{
return new PropertyReference(className, property).wrap(io);
}
/**
* Creates wrapper for a legacy static property and returns instance of T type. This form can
* be used only with OUTPUT parameters.
*
* @param propType
* The legacy property's data type.
* @param className
* The fully qualified legacy class name.
* @param property
* The property's name.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
String className,
String property)
{
return new PropertyReference(className, property).wrap(false);
}
/**
* Creates wrapper for a legacy instance property and returns instance of T type. This form can
* be used only with both OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
*
* @param propType
* The legacy property's data type.
* @param instance
* The legacy object instance.
* @param property
* The property's name.
* @param index
* The extent property's subscript.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
object<? extends _BaseObject_> instance,
String property,
NumberType index,
boolean io)
{
return new PropertyReference(instance, property, index).wrap(io);
}
/**
* Creates wrapper for a legacy instance property and returns instance of T type. This form can
* be used only with OUTPUT parameters.
*
* @param propType
* The legacy property's data type.
* @param instance
* The legacy object instance.
* @param property
* The property's name.
* @param index
* The extent property's subscript.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
object<? extends _BaseObject_> instance,
String property,
NumberType index)
{
return new PropertyReference(instance, property, index).wrap(false);
}
/**
* Creates wrapper for a legacy static property and returns instance of T type. This form can
* be used only with both OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
*
* @param propType
* The legacy property's data type.
* @param className
* The fully qualified legacy class name.
* @param property
* The property's name.
* @param index
* The extent property's subscript.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
String className,
String property,
NumberType index,
boolean io)
{
return new PropertyReference(className, property, index).wrap(io);
}
/**
* Creates wrapper for a legacy static property and returns instance of T type. This form can
* be used only with OUTPUT parameters.
*
* @param propType
* The legacy property's data type.
* @param className
* The fully qualified legacy class name.
* @param property
* The property's name.
* @param index
* The extent property's subscript.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
String className,
String property,
NumberType index)
{
return new PropertyReference(className, property, index).wrap(false);
}
/**
* Creates wrapper for a legacy instance property and returns instance of T type. This form can
* be used only with both OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
*
* @param propType
* The legacy property's data type.
* @param instance
* The legacy object instance.
* @param property
* The property's name.
* @param index
* The extent property's subscript.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
object<? extends _BaseObject_> instance,
String property,
int index,
boolean io)
{
return new PropertyReference(instance, property, index).wrap(io);
}
/**
* Creates wrapper for a legacy instance property and returns instance of T type. This form can
* be used only with OUTPUT parameters.
*
* @param propType
* The legacy property's data type.
* @param instance
* The legacy object instance.
* @param property
* The property's name.
* @param index
* The extent property's subscript.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
object<? extends _BaseObject_> instance,
String property,
int index)
{
return new PropertyReference(instance, property, index).wrap(false);
}
/**
* Creates wrapper for a legacy static property and returns instance of T type. This form can
* be used only with both OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
*
* @param propType
* The legacy property's data type.
* @param className
* The fully qualified legacy class name.
* @param property
* The property's name.
* @param index
* The extent property's subscript.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
String className,
String property,
int index,
boolean io)
{
return new PropertyReference(className, property, index).wrap(io);
}
/**
* Creates wrapper for a legacy static property and returns instance of T type. This form can
* be used only with OUTPUT parameters.
*
* @param propType
* The legacy property's data type.
* @param className
* The fully qualified legacy class name.
* @param property
* The property's name.
* @param index
* The extent property's subscript.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> propType,
String className,
String property,
int index)
{
return new PropertyReference(className, property, index).wrap(false);
}
/**
* Creates wrapper and returns instance of T type. This form can be used only with both
* OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
* <p>
* This will convert the BDT instance to a Java-compatible reference, and wrap it into a
* {@link jobject} instance.
*
* @param type
* The expected Java type to be wrapped in {@link jobject}
* @param variable
* The variable to be wrapped.
*
* @return instance of the T type.
*/
public static <T> jobject<T> wrapToJava(Class<T> type, BaseDataType variable)
{
return wrapToJava(type, variable, false);
}
/**
* Creates wrapper and returns instance of T type. This form can be used only with both
* OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
* <p>
* This will convert the BDT instance to a Java-compatible reference, and wrap it into a
* {@link jobject} instance.
*
* @param type
* The expected Java type to be wrapped in {@link jobject}
* @param variable
* The variable to be wrapped.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T> jobject<T> wrapToJava(Class<T> type, BaseDataType variable, boolean io)
{
jobject<T> init = jobject.toJava(type, variable);
// TODO: input-output ???
jobject<T> wrapper = createVariable(jobject.class,
init,
variable,
(bdt) -> new VariableAssigner(bdt, variable));
return wrapper;
}
/**
* Creates wrapper and returns instance of T type. This form can be used only with both
* OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
* <p>
* This will convert the {@link jobject} instance to a legacy BDT reference, only if the
* variable holds a Java instance which can be converted to a legacy BDT value.
*
* @param type
* The expected BDT type.
* @param variable
* The variable to be wrapped.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrapFromJava(Class<T> type, jobject<?> variable)
{
return wrapFromJava(type, variable, false);
}
/**
* Creates wrapper and returns instance of T type. This form can be used only with both
* OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
* <p>
* This will convert the {@link jobject} instance to a legacy BDT reference, only if the
* variable holds a Java instance which can be converted to a legacy BDT value.
*
* @param type
* The expected BDT type.
* @param variable
* The variable to be wrapped.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrapFromJava(Class<T> type,
jobject<?> variable,
boolean io)
{
T init = jobject.fromJava(type, variable);
// TODO: input-output ???
T wrapper = createVariable(type, init, variable, (bdt) -> new VariableAssigner(bdt, variable));
return wrapper;
}
/**
* Creates variable wrapper and returns instance of T type. This form can be used only with
* OUTPUT parameters.
*
* @param type
* The {@link BaseDataType} of the parameter definition. The returned value will have
* this datatype.
* @param variable
* The variable to be wrapped.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> type, BaseDataType variable)
{
return wrap(type, variable, false);
}
/**
* Creates wrapper and returns instance of T type. This form can be used only with both
* OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
*
* @param type
* The {@link BaseDataType} of the parameter definition. The returned value will have
* this datatype.
* @param variable
* The variable to be wrapped.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(Class<T> type, BaseDataType variable, boolean io)
{
BaseDataType init = io ? variable : null;
T wrapper = createVariable(type, init, variable, (bdt) -> new VariableAssigner(bdt, variable));
return wrapper;
}
/**
* Creates wrapper and returns instance of T type.
*
* @param dmo
* Proxy for record whose field is being accessed.
* @param property
* Name of dmo field.
* @param bdt
* The {@link BaseDataType} of the field. The returned value will have this datatype.
* This argument can be detected dynamically at runtime but, for performance reasons,
* it is computed and passed in at conversion time.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(DataModelObject dmo, String property, Class<T> bdt)
{
return wrap(dmo, property, bdt, null);
}
/**
* Creates wrapper and returns instance of T type.
*
* @param dmo
* Proxy for record whose field is being accessed.
* @param property
* Name of dmo field.
* @param bdt
* The {@link BaseDataType} of the field. The returned value will have this datatype.
* This argument can be detected dynamically at runtime but, for performance reasons,
* it is computed and passed in at conversion time.
* @param index
* Index to access, if property represents an extent field.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(DataModelObject dmo,
String property,
Class<T> bdt,
int index)
{
return wrap(dmo, property, bdt, new integer(index));
}
/**
* Creates wrapper and returns instance of T type.
*
* @param dmo
* Proxy for record whose field is being accessed.
* @param property
* Name of dmo field.
* @param bdt
* The {@link BaseDataType} of the field. The returned value will have this datatype.
* This argument can be detected dynamically at runtime but, for performance reasons,
* it is computed and passed in at conversion time.
* @param index
* Index to access, if property represents an extent field.
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(DataModelObject dmo,
String property,
Class<T> bdt,
NumberType index)
{
return wrap(dmo, property, bdt, index, false);
}
/**
* Creates wrapper and returns instance of T type.
*
* @param dmo
* Proxy for record whose field is being accessed.
* @param property
* Name of dmo field.
* @param bdt
* The {@link BaseDataType} of the field. The returned value will have this datatype.
* This argument can be detected dynamically at runtime but, for performance reasons,
* it is computed and passed in at conversion time.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(DataModelObject dmo,
String property,
Class<T> bdt,
boolean io)
{
return wrap(dmo, property, bdt, null, io);
}
/**
* Creates wrapper and returns instance of T type.
*
* @param dmo
* Proxy for record whose field is being accessed.
* @param property
* Name of dmo field.
* @param bdt
* The {@link BaseDataType} of the field. The returned value will have this datatype.
* This argument can be detected dynamically at runtime but, for performance reasons,
* it is computed and passed in at conversion time.
* @param index
* Index to access, if property represents an extent field.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(DataModelObject dmo,
String property,
Class<T> bdt,
int index,
boolean io)
{
return wrap(dmo, property, bdt, new integer(index), io);
}
/**
* Creates wrapper and returns instance of T type.
*
* @param dmo
* Proxy for record whose field is being accessed.
* @param property
* Name of dmo field.
* @param type
* The {@link BaseDataType} of the field. The returned value will have this datatype.
* This argument can be detected dynamically at runtime but, for performance reasons,
* it is computed and passed in at conversion time.
* @param index
* Index to access, if property represents an extent field.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
public static <T extends BaseDataType> T wrap(DataModelObject dmo,
String property,
Class<T> type,
NumberType index,
boolean io)
{
FieldReference field = new FieldReference(dmo, property, index);
return wrap(field, io, type);
}
/**
* Creates variable wrapper and returns instance of T type. This form can be used only with
* OUTPUT parameters.
*
* @param variable
* The variable to be wrapped.
*
* @return instance of the T type.
*/
static <T extends BaseDataType> T wrap(T variable)
{
return wrap(variable, false);
}
/**
* Creates wrapper and returns instance of T type. This form can be used only with both
* OUTPUT and INPUT-OUTPUT parameters (depending on {@code io} parameter).
*
* @param variable
* The variable to be wrapped.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local
* variable in the called function will be initialized with the current value of the
* original variable. Otherwise (simple OUTPUT), the parameter is initialized to
* default value for respective datatype (follows the semantics of OUTPUT parameter
* passing from 4GL).
*
* @return instance of the T type.
*/
static <T extends BaseDataType> T wrap(T variable, boolean io)
{
T init = (T) (io ? variable : null);
T wrapper = (T) createVariable(variable.getClass(),
init,
variable,
(bdt) -> new VariableAssigner(bdt, variable));
return wrapper;
}
/**
* Creates wrapper and returns instance of T type.
*
* @param field
* The field reference.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local variable in the
* called function will be initialized with the current value of the original variable. Otherwise
* (simple OUTPUT), the parameter is initialized to default value for respective datatype
* (follows the semantics of OUTPUT parameter passing from 4GL).
* @param type
* The {@link BaseDataType} of the field. The returned value will have this datatype.
*
* @return instance of the T type.
*/
static <T extends BaseDataType> T wrap(FieldReference field, boolean io, Class<?> type)
{
BaseDataType init = io ? field.get() : null;
T wrapper = createVariable((Class<T>) type,
init,
null,
(bdt) -> new FieldAssigner(bdt, field));
return wrapper;
}
/**
* Creates wrapper and returns instance of T type.
*
* @param ref
* The property reference.
* @param io
* Specifies an INPUT-OUTPUT parameter if {@code true}. In this case, the local variable in the
* called function will be initialized with the current value of the original variable. Otherwise
* (simple OUTPUT), the parameter is initialized to default value for respective datatype
* (follows the semantics of OUTPUT parameter passing from 4GL).
*
* @return instance of the T type.
*/
static <T extends BaseDataType> T wrap(PropertyReference ref, boolean io)
{
return ref.wrap(io);
}
/**
* Create a new variable of type T as an anonymous class, which will act as a temporary transport for the
* parameter assigner, which will be resolved and initialized only when the method is actually executed.
*
* @param cls
* The parameter's type.
* @param init
* The initial value (applied only if not <code>null</code>).
* @param variable
* The caller's variable.
* @param assigner
* The assigner function which will be supplied by the anonymous class
* {@link BaseDataType#getAssigner()} implementation.
*
* @return The new variable to be sent as an argument to the called method.
*/
static <T extends BaseDataType> T createVariable(Class<T> cls,
BaseDataType init,
BaseDataType variable,
Function<BaseDataType, AbstractSimpleParameter> assigner)
{
if (cls.isAnonymousClass())
{
cls = (Class<T>) cls.getSuperclass();
}
BaseDataType bdt;
if (cls == blob.class)
{
bdt = new blob()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == memptr.class)
{
bdt = new memptr()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == raw.class)
{
bdt = new raw()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == comhandle.class)
{
bdt = new comhandle()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == date.class)
{
bdt = new date()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == datetime.class)
{
bdt = new datetime()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == datetimetz.class)
{
bdt = new datetimetz()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == handle.class)
{
bdt = new handle()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == jobject.class)
{
bdt = new jobject()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == logical.class)
{
bdt = new logical()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == decimal.class)
{
bdt = new decimal()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == int64.class)
{
bdt = new int64()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == integer.class)
{
bdt = new integer()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == recid.class)
{
bdt = new recid()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == object.class)
{
bdt = new object(((object) variable).type())
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == ObjectVar.class)
{
bdt = new ObjectVar(((ObjectVar) variable).type())
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == rowid.class)
{
bdt = new rowid()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == character.class)
{
bdt = new character()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == longchar.class)
{
bdt = new longchar()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else if (cls == clob.class)
{
bdt = new clob()
{
@Override
Supplier<AbstractParameter> getAssigner()
{
return () -> assigner.apply(this);
}
};
}
else
{
throw new IllegalArgumentException("Type " + cls.getName() +
" is not recognized for OUTPUT/INPUT-OUTPUT arguments!");
}
if (cls == memptr.class)
{
((memptr) bdt).asParameter((memptr) variable);
}
else
{
bdt.assign(init == null ? BaseDataType.generateDefault(cls) : init);
}
return (T) bdt;
}
}