blob: e6aee7fc51fd0c05bacbdde62465a67ced716701 [file] [log] [blame]
/*
* Copyright (c) 2010-2013, 2015 Eike Stepper (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ibrahim Sallam - initial API and implementation
*/
package org.eclipse.emf.cdo.server.internal.objectivity.mapper;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.server.internal.objectivity.bundle.OM;
import org.eclipse.emf.cdo.server.internal.objectivity.db.ObjyObject;
import org.eclipse.emf.cdo.server.internal.objectivity.db.ObjySchema;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EStructuralFeature;
import com.objy.as.app.Class_Object;
import com.objy.as.app.Numeric_Value;
import com.objy.as.app.Proposed_Basic_Attribute;
import com.objy.as.app.Proposed_Class;
import com.objy.as.app.Proposed_Property;
import com.objy.as.app.VArray_Object;
import com.objy.as.app.d_Access_Kind;
import com.objy.as.app.d_Attribute;
import com.objy.as.app.d_Class;
import com.objy.as.app.d_Module;
import com.objy.as.app.ooBaseType;
import java.util.Date;
/**
* @author Ibrahim Sallam
*/
public abstract class NumericManyTypeMapper extends BasicTypeMapper implements IManyTypeMapper
{
protected abstract Object fromNumericValue(Numeric_Value numericValue, boolean isNull);
protected abstract Numeric_Value toNumericValue(Object value);
protected abstract ooBaseType getObjyBaseType();
private static final ContextTracer TRACER_DEBUG = new ContextTracer(OM.DEBUG, NumericManyTypeMapper.class);
public static NumericManyTypeMapper.TMBoolean TMBOOLEAN = new TMBoolean();
public static NumericManyTypeMapper.TMByte TMBYTE = new TMByte();
public static NumericManyTypeMapper.TMChar TMCHAR = new TMChar();
public static NumericManyTypeMapper.TMDate TMDATE = new TMDate();
public static NumericManyTypeMapper.TMDouble TMDOUBLE = new TMDouble();
public static NumericManyTypeMapper.TMFloat TMFLOAT = new TMFloat();
public static NumericManyTypeMapper.TMInteger TMINTEGER = new TMInteger();
public static NumericManyTypeMapper.TMLong TMLONG = new TMLong();
public static NumericManyTypeMapper.TMShort TMSHORT = new TMShort();
// ---------------------------------
// Schema
// ---------------------------------
private String embeddedClassName()
{
return "oo_" + getObjyBaseType() + "_Class";
}
private d_Class getEmbeddedClass()
{
d_Class embeddedClass = ObjySchema.getTopModule().resolve_class(embeddedClassName());
// System.out.println("OBJY: Resolving className: " + embeddedClassName() + " - d_Class: " + embeddedClass);
return embeddedClass;
}
private boolean createEmbeddedClass()
{
boolean bDone = true;
d_Module top_mod = ObjySchema.getTopModule();
boolean inProcess = top_mod.proposed_classes().hasNext();
Proposed_Class propClass = top_mod.propose_new_class(embeddedClassName());
propClass.add_basic_attribute(com.objy.as.app.d_Module.LAST, d_Access_Kind.d_PUBLIC, // Access kind
embeddedAttributeName, // Attribute name
1, // # elements in fixed-size array
getObjyBaseType() // Type of numeric data
); // Default value
propClass.add_basic_attribute(com.objy.as.app.d_Module.LAST, d_Access_Kind.d_PUBLIC, // Access kind
embeddedAttributeNull, // Attribute name
1, // # elements in fixed-size array
ooBaseType.ooBOOLEAN// Type of numeric data
); // Default value
// System.out.println("OBJY: Propose Creating new class: " + embeddedClassName());
// ObjySchema.getTopModule().propose_new_class(propClass);
if (!inProcess)
{
top_mod.activate_proposals(true, true);
}
return bDone;
}
/**
*
*/
public boolean createSchema(Proposed_Class proposedClass, EStructuralFeature feature)
{
if (TRACER_DEBUG.isEnabled())
{
TRACER_DEBUG.trace("Adding attribute " + feature.getName() + " " + this.getClass().getName());
}
// create an embedded class (attributeType, attributeIsNull).
// TODO - we might need to move this to the .objectivity.schema, since it's
// independent of the model classes.
if (getEmbeddedClass() == null && !createEmbeddedClass())
{
return false;
}
// create array of embedded class type.
proposedClass.add_varray_attribute(com.objy.as.app.d_Module.LAST, d_Access_Kind.d_PUBLIC, // Access kind
getAttributeName(feature), // Attribute name
1, embeddedClassName());
return false;
}
/**
* TODO - this is a simple change to the attribute, make it handle more complex cases. I also don't think it does
* handle the arrays.
*
* @param proposedooClass
* @param feature
*/
public void modifySchema(Proposed_Class proposedooClass, EStructuralFeature feature)
{
Proposed_Property prop = proposedooClass.resolve_property(getAttributeName(feature));
if (prop instanceof Proposed_Basic_Attribute)
{
Proposed_Basic_Attribute attr = (Proposed_Basic_Attribute)prop;
attr.change_base_type(getObjyBaseType());
}
}
/**
* TBD - Fixed size array attributes can't be accessed, so we can't validate This!!! OFJ (Fix it)
*/
public boolean validate(d_Attribute dAttribute, EStructuralFeature feature)
{
System.out.println(">>>OBJYIMPL: NumericManyTypeMapper.validate() - not implemented.");
return true;
// d_Class varrayClass = dAttribute.class_type_of();
// d_Class embeddedClass = varrayClass.
// Class_Position position = embeddedClass.position_in_class(getAttributeName(feature));
// //d_Type type = ooAttribute.type_of();
// d_Type type = embeddedClass.attribute_at_position(position).type_of();
// if (TRACER_DEBUG.isEnabled()) {
// TRACER_DEBUG.trace(getAttributeName(feature) + " "
// + ((Basic_Type) type).base_type() + " basic type "
// + type.is_basic_type() + " - " + getObjyBaseType());
// }
// return type.is_basic_type()
// && ((Basic_Type) type).base_type() == getObjyBaseType();
}
// ---------------------------------
// Object
// ---------------------------------
public void setValue(ObjyObject objyObject, EStructuralFeature feature, int index, Object newValue)
{
// System.out.println("OBJY: Set value in VArray at index: "+ index + " - value: " + newValue);
boolean isNull = newValue == null;
Numeric_Value numericValue = toNumericValue(newValue);
Numeric_Value isNullValue = isNull ? numericTrue : numericFalse;
Class_Object embedded = getArray(objyObject, feature).get_class_obj(index);
embedded.set_numeric(valueAttributePosition, numericValue);
embedded.set_numeric(nullAttributePosition, isNullValue);
}
// get a single object/value at index.
public Object getValue(ObjyObject objyObject, EStructuralFeature feature, int index)
{
Numeric_Value numericValue = null;
Class_Object embedded = getArray(objyObject, feature).get_class_obj(index);
numericValue = embedded.get_numeric(valueAttributePosition);
boolean isNull = embedded.get_numeric(nullAttributePosition).booleanValue();
return fromNumericValue(numericValue, isNull);
}
// remove a single value at index, it will set the value to default, and mark it
// as "null", i.e. unset.
public Object remove(ObjyObject objyObject, EStructuralFeature feature, int index)
{
// we'll just get the original value, and set the value to null.
// Numeric_Value numericValue = null;
long size = (int)getArray(objyObject, feature).size();
for (int i = index; i < size - 1; i++)
{
setValue(objyObject, feature, i, getValue(objyObject, feature, i + 1));
}
// resize the array.
getArray(objyObject, feature).resize(size - 1);
/*
* Class_Object embedded = getArray(objyObject, feature).get_class_obj(index); numericValue =
* embedded.get_numeric(valueAttributePosition); boolean isNull =
* embedded.get_numeric(nullAttributePosition).booleanValue(); Object oldValue = fromNumericValue(numericValue,
* isNull); numericValue = toNumericValue(null); embedded.set_numeric(valueAttributePosition, numericValue);
* embedded.set_numeric(nullAttributePosition, numericTrue);
*/
return null;
}
// add value at index (extend the collection size).
public void add(ObjyObject objyObject, EStructuralFeature feature, int index, Object value)
{
int arraySize = size(objyObject, feature);
// System.out.println("OBJY: Adding object inside VArray at index: "+ index + " - value: " + value);
if (index < arraySize - 1)
{
// throw new UnsupportedOperationException("adding object inside VArray?!!... Implement Me!!!");
// resize the VArray.
VArray_Object array = getArray(objyObject, feature);
array.resize(arraySize + 1);
for (int i = arraySize; i > index; i--)
{
Class_Object newEmbedded = array.get_class_obj(i);
Class_Object oldEmbedded = array.get_class_obj(i - 1);
newEmbedded.set_numeric(valueAttributePosition, oldEmbedded.get_numeric(valueAttributePosition));
newEmbedded.set_numeric(nullAttributePosition, oldEmbedded.get_numeric(nullAttributePosition));
}
}
if (index != -1 && index > arraySize)
{
throw new UnsupportedOperationException("adding object beyond VArray size()?!!... Implement Me!!!");
}
getArray(objyObject, feature).resize(arraySize + 1);
setValue(objyObject, feature, index, value);
}
public// add all objects starting from an index. (extend the collection size).
void addAll(ObjyObject objyObject, EStructuralFeature feature, int index, Object[] values)
{
// System.out.println("OBJY: AddAll objects inside VArray at index: "+ index + " - values: " + values);
int arraySize = size(objyObject, feature);
if (index < arraySize - 1)
{
throw new UnsupportedOperationException("adding objects inside VArray?!!... Implement Me!!!");
}
if (index != -1 && index > arraySize)
{
throw new UnsupportedOperationException("adding objects beyond VArray size()?!!... Implement Me!!!");
}
int newSize = arraySize + values.length;
getArray(objyObject, feature).resize(newSize);
for (int i = 0; i < values.length; i++)
{
setValue(objyObject, feature, arraySize + i, values[i]);
}
}
// clear all collection.
public void clear(ObjyObject objyObject, EStructuralFeature feature)
{
// set the varray size to 0.
getArray(objyObject, feature).resize(0);
}
// this is similar to addAll, but it replaces the existing ones.
public void setAll(ObjyObject objyObject, EStructuralFeature feature, int index, Object[] newValues)
{
VArray_Object array = getArray(objyObject, feature);
array.resize(newValues.length);
for (int i = 0; i < newValues.length; i++)
{
// TODO - we might need to optimize this!!!
setValue(objyObject, feature, i, newValues[i]);
}
}
// get all objects/values starting from an index.
public Object[] getAll(ObjyObject objyObject, EStructuralFeature feature, int index, int chunkSize)
{
int size = size(objyObject, feature);
if (chunkSize != CDORevision.UNCHUNKED)
{
size = Math.min(size, chunkSize);
}
Object[] values = new Object[size];
// TODO - we might need to optimize this!!!!
for (int i = 0; i < size; i++)
{
values[i] = getValue(objyObject, feature, i + index);
}
return values;
}
// return the size of the collection.
public int size(ObjyObject objyObject, EStructuralFeature feature)
{
return (int)getArray(objyObject, feature).size();
}
public void delete(ObjyObject objyObject, EStructuralFeature feature)
{
throw new UnsupportedOperationException("Implement me!!");
}
public void move(ObjyObject objyObject, EStructuralFeature feature, int targetIndex, int sourceIndex)
{
if (targetIndex == sourceIndex)
{
return;
}
// get the object at sourceIndex.
Object value = getValue(objyObject, feature, sourceIndex);
// long size = (int)getArray(objyObject, feature).size();
// TODO - check boundaries...
if (sourceIndex > targetIndex)
{
for (int i = sourceIndex; i > targetIndex; i--)
{
setValue(objyObject, feature, i, getValue(objyObject, feature, i - 1));
}
}
else if (sourceIndex < targetIndex)
{
for (int i = sourceIndex; i < targetIndex; i++)
{
setValue(objyObject, feature, i, getValue(objyObject, feature, i + 1));
}
}
// set the saved value at target
setValue(objyObject, feature, targetIndex, value);
}
public void initialize(Class_Object classObject, EStructuralFeature feature)
{
// TODO - verify if we need to do any initialization!!!
}
protected VArray_Object getArray(ObjyObject objyObject, EStructuralFeature feature)
{
// Class_Position position = getAttributePosition(objyObject, feature);
String attributeName = getAttributeName(feature);
return objyObject.get_varray(attributeName/* position */);
}
// ------------------------------------------------------------------------
// ------------------- Various types --------------------------
// ------------------------------------------------------------------------
// ---------------------------
// Boolean
// ---------------------------
public static class TMBoolean extends NumericManyTypeMapper
{
@Override
protected ooBaseType getObjyBaseType()
{
return ooBaseType.ooBOOLEAN;
}
@Override
protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
{
Boolean value = null;
if (!isNull)
{
value = numericValue.booleanValue();
}
return value;
}
@Override
protected Numeric_Value toNumericValue(Object value)
{
if (value == null)
{
return new Numeric_Value(false);
}
return new Numeric_Value(((Boolean)value).booleanValue());
}
}
// ---------------------------
// Byte
// ---------------------------
public static class TMByte extends NumericManyTypeMapper
{
@Override
public ooBaseType getObjyBaseType()
{
return ooBaseType.ooINT8;
}
@Override
protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
{
Byte value = null;
if (!isNull)
{
value = numericValue.byteValue();
}
return value;
}
@Override
protected Numeric_Value toNumericValue(Object value)
{
if (value == null)
{
return new Numeric_Value(0);
}
return new Numeric_Value(((Byte)value).byteValue());
}
}
// ---------------------------
// Char
// ---------------------------
public static class TMChar extends NumericManyTypeMapper
{
@Override
public ooBaseType getObjyBaseType()
{
return ooBaseType.ooINT8;
}
@Override
protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
{
Character value = null;
if (!isNull)
{
value = numericValue.charValue();
}
return value;
}
@Override
protected Numeric_Value toNumericValue(Object value)
{
if (value == null)
{
return new Numeric_Value(0);
}
return new Numeric_Value(((Character)value).charValue());
}
}
// ---------------------------
// Date
// ---------------------------
public static class TMDate extends NumericManyTypeMapper
{
@Override
public ooBaseType getObjyBaseType()
{
return ooBaseType.ooINT64;
}
@Override
protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
{
Date value = null;
if (!isNull)
{
value = new Date(numericValue.longValue());
}
return value;
}
@Override
protected Numeric_Value toNumericValue(Object value)
{
if (value == null)
{
return new Numeric_Value(0);
}
return new Numeric_Value(((Date)value).getTime());
}
}
// ---------------------------
// Double
// ---------------------------
public static class TMDouble extends NumericManyTypeMapper
{
@Override
public ooBaseType getObjyBaseType()
{
return ooBaseType.ooFLOAT64;
}
@Override
protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
{
Double value = null;
if (!isNull)
{
value = numericValue.doubleValue();
}
return value;
}
@Override
protected Numeric_Value toNumericValue(Object value)
{
if (value == null)
{
return new Numeric_Value(0.0);
}
return new Numeric_Value(((Double)value).doubleValue());
}
}
// ---------------------------
// Float
// ---------------------------
public static class TMFloat extends NumericManyTypeMapper
{
@Override
protected ooBaseType getObjyBaseType()
{
return ooBaseType.ooFLOAT64;
}
@Override
protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
{
Float value = null;
if (!isNull)
{
value = numericValue.floatValue();
}
return value;
}
@Override
protected Numeric_Value toNumericValue(Object value)
{
if (value == null)
{
return new Numeric_Value(0.0);
}
return new Numeric_Value(((Float)value).floatValue());
}
}
// ---------------------------
// Integer
// ---------------------------
public static class TMInteger extends NumericManyTypeMapper
{
@Override
public ooBaseType getObjyBaseType()
{
return ooBaseType.ooINT32;
}
@Override
protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
{
Integer value = null;
if (!isNull)
{
value = numericValue.intValue();
}
return value;
}
@Override
protected Numeric_Value toNumericValue(Object value)
{
if (value == null)
{
return new Numeric_Value(0);
}
return new Numeric_Value(((Integer)value).intValue());
}
}
// ---------------------------
// Long
// ---------------------------
public static class TMLong extends NumericManyTypeMapper
{
@Override
public ooBaseType getObjyBaseType()
{
return ooBaseType.ooINT64;
}
@Override
protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
{
Long value = null;
if (!isNull)
{
value = numericValue.longValue();
}
return value;
}
@Override
protected Numeric_Value toNumericValue(Object value)
{
if (value == null)
{
return new Numeric_Value(0);
}
return new Numeric_Value(((Long)value).longValue());
}
}
// ---------------------------
// Short
// ---------------------------
public static class TMShort extends NumericManyTypeMapper
{
@Override
public ooBaseType getObjyBaseType()
{
return ooBaseType.ooINT16;
}
@Override
protected Object fromNumericValue(Numeric_Value numericValue, boolean isNull)
{
Short value = null;
if (!isNull)
{
value = numericValue.shortValue();
}
return value;
}
@Override
protected Numeric_Value toNumericValue(Object value)
{
if (value == null)
{
return new Numeric_Value(0);
}
return new Numeric_Value(((Short)value).shortValue());
}
}
}