| /*=============================================================================# |
| # Copyright (c) 2009, 2022 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(); |
| } |
| |
| } |