blob: 0ec2ef82b8ea18a96ca9e3b5ecbe7b4053836736 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2013, 2017 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.services.util.dataaccess;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.RLanguage;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RVector;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
import org.eclipse.statet.rj.data.impl.DefaultRObjectFactory;
import org.eclipse.statet.rj.services.FQRObjectRef;
import org.eclipse.statet.rj.services.FunctionCall;
import org.eclipse.statet.rj.services.RService;
/**
* Adapter interface to load R data in one- or two-dimensional fragments.
*
* @param <TRObject> type of R object
* @param <TFragmentObject> type of R object value fragments
* @since 2.0 (provisional)
*/
public abstract class AbstractRDataAdapter<TRObject extends RObject, TFragmentObject extends RObject> {
public static final int ROW_COUNT= 1 << 0;
public static final int STORE_TYPE= 1 << 2;
protected static final String API_R_PREFIX= "rj:::sda002"; //$NON-NLS-1$
protected static void addXRef(final FunctionCall fcall, final FQRObjectRef ref) {
fcall.add("x.env", ref.getEnv()); //$NON-NLS-1$
fcall.add("x.expr", DefaultRObjectFactory.INSTANCE.createExpression( //$NON-NLS-1$
"x.env$" + ((RLanguage) ref.getName()).getSource() )); //$NON-NLS-1$
}
public abstract TRObject validate(RObject rObject)
throws UnexpectedRDataException;
public abstract TRObject validate(RObject rObject, TRObject referenceObject, int flags)
throws UnexpectedRDataException;
public abstract long getRowCount(TRObject rObject);
public abstract long getColumnCount(TRObject rObject);
public void check(final FQRObjectRef ref, final TRObject referenceObject,
final RService r, final IProgressMonitor monitor) throws CoreException,
UnexpectedRDataException {
final RObject result;
{ final FunctionCall fcall= r.createFunctionCall(API_R_PREFIX + ".checkDataStruct"); //$NON-NLS-1$
addXRef(fcall, ref);
fcall.addChar("xClass1", referenceObject.getRClassName()); //$NON-NLS-1$
fcall.add("xDim", DefaultRObjectFactory.INSTANCE.createNumVector(new double[] { //$NON-NLS-1$
getRowCount(referenceObject),
getColumnCount(referenceObject),
}));
result= fcall.evalData(monitor);
}
if (RDataUtils.checkSingleLogiValue(result) == false) {
throw new UnexpectedRDataException("It seems something changed.");
}
}
public TFragmentObject loadData(final FQRObjectRef ref, final TRObject referenceObject,
final LazyRStore.Fragment<TFragmentObject> fragment, final String rowMapping,
final RService r,
final IProgressMonitor monitor) throws CoreException, UnexpectedRDataException {
final RObject fragmentObject;
{ final FunctionCall fcall= r.createFunctionCall(getLoadDataFName());
addXRef(fcall, ref);
fcall.add("idxs", DefaultRObjectFactory.INSTANCE.createNumVector(new double[] { //$NON-NLS-1$
fragment.getRowBeginIdx() + 1,
fragment.getRowEndIdx(),
fragment.getColumnBeginIdx() + 1,
fragment.getColumnEndIdx(),
}));
if (rowMapping != null) {
fcall.addChar("rowMapping", rowMapping); //$NON-NLS-1$
}
fragmentObject= fcall.evalData(monitor);
}
return validateData(fragmentObject, referenceObject, fragment);
}
protected abstract String getLoadDataFName();
protected abstract TFragmentObject validateData(RObject rObject, TRObject referenceObject,
LazyRStore.Fragment<TFragmentObject> fragment)
throws UnexpectedRDataException;
public void setData(final FQRObjectRef ref, final TRObject referenceObject,
final RDataAssignment assignment, final String rowMapping,
final RService r,
final IProgressMonitor monitor) throws CoreException, UnexpectedRDataException {
{ final FunctionCall fcall= r.createFunctionCall(getSetDataFName());
addXRef(fcall, ref);
fcall.add("idxs", DefaultRObjectFactory.INSTANCE.createNumVector(new double[] { //$NON-NLS-1$
assignment.getRowBeginIdx() + 1,
assignment.getRowEndIdx(),
assignment.getColumnBeginIdx() + 1,
assignment.getColumnEndIdx(),
}));
if (rowMapping != null) {
fcall.addChar("rowMapping", rowMapping); //$NON-NLS-1$
}
fcall.add("values", DefaultRObjectFactory.INSTANCE.createVector( //$NON-NLS-1$
assignment.getData() ));
fcall.evalVoid(monitor);
}
}
protected abstract String getSetDataFName();
public RVector<?> loadRowNames(final FQRObjectRef ref, final TRObject referenceObject,
final LazyRStore.Fragment<RVector<?>> fragment, final String rowMapping,
final RService r, final IProgressMonitor monitor) throws CoreException,
UnexpectedRDataException {
final RObject fragmentObject;
{ final FunctionCall fcall= r.createFunctionCall(getLoadRowNamesFName());
addXRef(fcall, ref);
fcall.add("idxs", DefaultRObjectFactory.INSTANCE.createNumVector(new double[] { //$NON-NLS-1$
fragment.getRowBeginIdx() + 1,
fragment.getRowEndIdx(),
}));
if (rowMapping != null) {
fcall.addChar("rowMapping", rowMapping); //$NON-NLS-1$
}
fragmentObject= fcall.evalData(monitor);
}
return validateRowNames(fragmentObject, referenceObject, fragment);
}
protected abstract String getLoadRowNamesFName();
protected RVector<?> validateRowNames(final RObject rObject, final TRObject referenceObject,
final LazyRStore.Fragment<RVector<?>> fragment)
throws UnexpectedRDataException {
if (rObject.getRObjectType() == RObject.TYPE_NULL) {
return null;
}
final RVector<?> vector= RDataUtils.checkRVector(rObject);
RDataUtils.checkLengthEqual(vector.getData(), fragment.getRowCount());
return vector;
}
}