blob: 15ed3bf1b750dfb4177ab484485c30e13e25612e [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2009, 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.rj.server.client;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.rj.data.RList;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RObjectFactory;
import org.eclipse.statet.rj.data.impl.RLanguageImpl;
import org.eclipse.statet.rj.data.impl.RNullImpl;
import org.eclipse.statet.rj.services.FunctionCall;
import org.eclipse.statet.rj.services.RService;
@NonNullByDefault
public class FunctionCallImpl implements FunctionCall {
private final String name;
private final List<@Nullable String> argNames= new ArrayList<>();
private final List<RObject> argValues= new ArrayList<>();
private final AbstractRJComClient rjs;
private final RObjectFactory rObjectFactory;
public FunctionCallImpl(final AbstractRJComClient client, final String name,
final RObjectFactory rObjectFactory) {
this.rjs= client;
this.rObjectFactory= rObjectFactory;
this.name= name;
}
@Override
public FunctionCall add(final @Nullable String arg, final String expression) {
if (expression == null) {
throw new NullPointerException();
}
this.argNames.add(arg);
final RObject data= new RLanguageImpl((byte) 0, expression, null);
this.argValues.add(data);
return this;
}
@Override
public FunctionCall add(final String expression) {
return this.add(null, expression);
}
@Override
public FunctionCall add(final @Nullable String arg, final RObject data) {
if (data == null) {
throw new NullPointerException();
}
this.argNames.add(arg);
this.argValues.add(data);
return this;
}
@Override
public FunctionCall add(final RObject data) {
return this.add(null, data);
}
@Override
public FunctionCall addLogi(final @Nullable String arg, final boolean logical) {
final RObject data= this.rObjectFactory.createVector(
this.rObjectFactory.createLogiData(new boolean[] { logical }) );
this.argNames.add(arg);
this.argValues.add(data);
return this;
}
@Override
public FunctionCall addLogi(final boolean logical) {
return addLogi(null, logical);
}
@Override
public FunctionCall addInt(final @Nullable String arg, final int integer) {
final RObject data= this.rObjectFactory.createVector(
this.rObjectFactory.createIntData(new int[] { integer }) );
this.argNames.add(arg);
this.argValues.add(data);
return this;
}
@Override
public FunctionCall addInt(final int integer) {
return addInt(null, integer);
}
@Override
public FunctionCall addNum(final @Nullable String arg, final double numeric) {
final RObject data= this.rObjectFactory.createVector(
this.rObjectFactory.createNumData(new double[] { numeric }) );
this.argNames.add(arg);
this.argValues.add(data);
return this;
}
@Override
public FunctionCall addNum(final double numeric) {
return this.addNum(null, numeric);
}
@Override
public FunctionCall addChar(final @Nullable String arg, final String character) {
final RObject data= this.rObjectFactory.createVector(
this.rObjectFactory.createCharData(new String[] { character }));
this.argNames.add(arg);
this.argValues.add(data);
return this;
}
@Override
public FunctionCall addChar(final String character) {
return this.addChar(null, character);
}
@Override
public FunctionCall addCplx(final @Nullable String arg, final double real, final double imaginary) {
final RObject data= this.rObjectFactory.createVector(
this.rObjectFactory.createCplxData(new double[] { real }, new double[] {imaginary }) );
this.argNames.add(arg);
this.argValues.add(data);
return this;
}
@Override
public FunctionCall addCplx(final double real, final double imaginary) {
return addCplx(null, real, imaginary);
}
@Override
public FunctionCall addNull(final @Nullable String arg) {
this.argNames.add(arg);
this.argValues.add(RNullImpl.INSTANCE);
return this;
}
@Override
public FunctionCall addNull() {
return this.addNull(null);
}
private RList prepareArgs(final ProgressMonitor m) throws StatusException {
// TODO step by step upload for large objects
final String[] names= this.argNames.toArray(new @Nullable String[this.argNames.size()]);
final RObject[] values= this.argValues.toArray(new RObject[this.argValues.size()]);
assert (names.length == values.length);
return this.rObjectFactory.createList(values, names);
}
@Override
public void evalVoid(final ProgressMonitor m) throws StatusException {
final RList args= prepareArgs(m);
this.rjs.evalVoid(this.name, args, null, m);
}
@Override
public void evalVoid(final @Nullable RObject envir,
final ProgressMonitor m) throws StatusException {
final RList args= prepareArgs(m);
this.rjs.evalVoid(this.name, args, envir, m);
}
@Override
public RObject evalData(final ProgressMonitor m) throws StatusException {
final RList args= prepareArgs(m);
return this.rjs.evalData(this.name, args, null, null, 0, RService.DEPTH_INFINITE, m);
}
@Override
public RObject evalData(final @Nullable String factoryId, final int options, final int depth,
final ProgressMonitor m) throws StatusException {
final RList args= prepareArgs(m);
return this.rjs.evalData(this.name, args, null, factoryId, options, depth, m);
}
@Override
public RObject evalData(final @Nullable RObject envir,
final @Nullable String factoryId, final int options, final int depth,
final ProgressMonitor m) throws StatusException {
final RList args= prepareArgs(m);
return this.rjs.evalData(this.name, args, envir, factoryId, options, depth, m);
}
@Override
public void evalAssign(final String target,
final ProgressMonitor m) throws StatusException {
final RList args= prepareArgs(m);
this.rjs.assignData(this.name, args, target, null, m);
}
@Override
public String toString() {
final StringBuilder call= new StringBuilder();
call.append(this.name);
call.append('(');
if (this.argNames.size() > 0) {
for (int i= 0; i < this.argNames.size(); i++) {
final String argName= this.argNames.get(i);
if (argName != null) {
call.append('\n');
call.append(argName);
call.append("= "); //$NON-NLS-1$
}
final Object value= this.argValues.get(i);
if (value instanceof String) {
call.append((String) value);
}
else if (value instanceof RObject) {
call.append("\n<DATA>\n"); //$NON-NLS-1$
call.append(value.toString());
call.append("\n</DATA>"); //$NON-NLS-1$
}
}
call.append("\n"); //$NON-NLS-1$
}
call.append(')');
return call.toString();
}
}