synchronized (this) {
if (_isInit)
return;
MarshalFactory marshalFactory = _moduleContext.getMarshalFactory();
ExprFactory exprFactory = _moduleContext.getExprFactory();
try {
boolean callUsesVariableArgs = false;
boolean callUsesSymbolTable = false;
boolean returnNullAsFalse = false;
for (Annotation ann : _methodAnn) {
if (VariableArguments.class.isAssignableFrom(ann.annotationType()))
callUsesVariableArgs = true;
if (UsesSymbolTable.class.isAssignableFrom(ann.annotationType()))
callUsesSymbolTable = true;
if (ReturnNullAsFalse.class.isAssignableFrom(ann.annotationType()))
returnNullAsFalse = true;
}
_isCallUsesVariableArgs = callUsesVariableArgs;
_isCallUsesSymbolTable = callUsesSymbolTable;
_hasEnv = _param.length > 0 && _param[0].equals(Env.class);
int envOffset = _hasEnv ? 1 : 0;
if (envOffset < _param.length)
_hasThis = hasThis(_param[envOffset], _paramAnn[envOffset]);
else
_hasThis = false;
if (_hasThis)
envOffset++;
boolean hasRestArgs = false;
boolean isRestReference = false;
if (_param.length > 0
&& (_param[_param.length - 1].equals(Value[].class)
|| _param[_param.length - 1].equals(Object[].class))) {
hasRestArgs = true;
for (Annotation ann : _paramAnn[_param.length - 1]) {
if (Reference.class.isAssignableFrom(ann.annotationType()))
isRestReference = true;
}
}
_hasRestArgs = hasRestArgs;
_isRestReference = isRestReference;
int argLength = _param.length;
if (_hasRestArgs)
argLength -= 1;
_defaultExprs = new Expr[argLength - envOffset];
_marshalArgs = new Marshal[argLength - envOffset];
_maxArgumentLength = argLength - envOffset;
_minArgumentLength = _maxArgumentLength;
for (int i = 0; i < argLength - envOffset; i++) {
boolean isReference = false;
boolean isPassThru = false;
boolean isNotNull = false;
boolean isExpectString = false;
boolean isExpectNumeric = false;
boolean isExpectBoolean = false;
Class<?> argType = _param[i + envOffset];
for (Annotation ann : _paramAnn[i + envOffset]) {
if (Optional.class.isAssignableFrom(ann.annotationType())) {
_minArgumentLength--;
Optional opt = (Optional) ann;
if (opt.value().equals(Optional.NOT_SET))
_defaultExprs[i] = exprFactory.createDefault();
else if (opt.value().equals("")) {
_defaultExprs[i] = exprFactory.createLiteral(StringValue.EMPTY);
}
else {
_defaultExprs[i] = QuercusParser.parseDefault(exprFactory, opt.value());
}
} else if (Reference.class.isAssignableFrom(ann.annotationType())) {
if (! Value.class.equals(argType)
&& ! Var.class.equals(argType)) {
throw new QuercusException(L.l("reference must be Value or Var for {0}",
_name));
}
isReference = true;
} else if (PassThru.class.isAssignableFrom(ann.annotationType())) {
if (! Value.class.equals(argType)) {
throw new QuercusException(L.l("pass thru must be Value for {0}",
_name));
}
isPassThru = true;
} else if (NotNull.class.isAssignableFrom(ann.annotationType())) {
isNotNull = true;
} else if (Expect.class.isAssignableFrom(ann.annotationType())) {
if (! Value.class.equals(argType)) {
throw new QuercusException(L.l("Expect type must be Value for {0}",
_name));
}
Expect.Type type = ((Expect) ann).type();
if (type == Expect.Type.STRING) {
isExpectString = true;
}
else if (type == Expect.Type.NUMERIC) {
isExpectNumeric = true;
}
else if (type == Expect.Type.BOOLEAN) {
isExpectBoolean = true;
}
}
}
if (isReference) {
_marshalArgs[i] = marshalFactory.createReference();
}
else if (isPassThru) {
_marshalArgs[i] = marshalFactory.createValuePassThru();
}
else if (isExpectString) {
_marshalArgs[i] = marshalFactory.createExpectString();
}
else if (isExpectNumeric) {
_marshalArgs[i] = marshalFactory.createExpectNumeric();
}
else if (isExpectBoolean) {
_marshalArgs[i] = marshalFactory.createExpectBoolean();
}
else {
_marshalArgs[i] = marshalFactory.create(argType, isNotNull);
}
}
_unmarshalReturn = marshalFactory.create(_retType,
false,
returnNullAsFalse);
} finally {
_isInit = true;
}