blob: cccdbad4eb3912548f65e7b8c4f2d332a24c031c [file] [log] [blame]
/***************************************************************************
* Copyright (c) 2004 - 2008 Eike Stepper, Germany.
* 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:
* Eike Stepper - initial API and implementation
**************************************************************************/
package org.eclipse.emf.cdo.internal.common.model;
import org.eclipse.emf.cdo.common.CDODataInput;
import org.eclipse.emf.cdo.common.CDODataOutput;
import org.eclipse.emf.cdo.common.model.CDOClass;
import org.eclipse.emf.cdo.common.model.CDOClassProxy;
import org.eclipse.emf.cdo.common.model.CDOType;
import org.eclipse.emf.cdo.internal.common.bundle.OM;
import org.eclipse.emf.cdo.spi.common.InternalCDOClass;
import org.eclipse.emf.cdo.spi.common.InternalCDOFeature;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import java.io.IOException;
import java.text.MessageFormat;
/**
* @author Eike Stepper
*/
public class CDOFeatureImpl extends CDOTypedElementImpl implements InternalCDOFeature
{
private static final int UNKNOWN_FEATURE_INDEX = Integer.MIN_VALUE;
private static final ContextTracer MODEL_TRACER = new ContextTracer(OM.DEBUG_MODEL, CDOFeatureImpl.class);
private static final ContextTracer PROTOCOL_TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, CDOFeatureImpl.class);
private CDOClass containingClass;
private int featureID;
private int featureIndex = UNKNOWN_FEATURE_INDEX;
private boolean containment;
private Object defaultValue;
/**
* Creates an uninitialized instance.
*/
public CDOFeatureImpl()
{
}
/**
* Creates an attribute feature.
*/
public CDOFeatureImpl(CDOClass containingClass, int featureID, String name, CDOType type, Object defaultValue,
boolean many)
{
super(containingClass.getContainingPackage(), name, type, many, null);
if (type == CDOType.OBJECT)
{
throw new IllegalArgumentException("type == OBJECT");
}
this.containingClass = containingClass;
this.featureID = featureID;
this.defaultValue = defaultValue;
if (MODEL_TRACER.isEnabled())
{
MODEL_TRACER.format("Created attribute {0}", this);
}
}
/**
* Creates a reference feature.
*/
public CDOFeatureImpl(CDOClass containingClass, int featureID, String name, CDOClassProxy referenceTypeProxy,
boolean many, boolean containment)
{
super(containingClass.getContainingPackage(), name, CDOType.OBJECT, many, referenceTypeProxy);
if (referenceTypeProxy == null)
{
throw new IllegalArgumentException("referenceTypeProxy == null");
}
this.containingClass = containingClass;
this.featureID = featureID;
this.containment = containment;
if (MODEL_TRACER.isEnabled())
{
MODEL_TRACER.format("Created reference {0}", this);
}
}
/**
* Reads a feature from a stream.
*/
public CDOFeatureImpl(CDOClass containingClass, CDODataInput in) throws IOException
{
super(containingClass.getContainingPackage(), in);
this.containingClass = containingClass;
featureID = in.readInt();
if (in.readBoolean())
{
defaultValue = getType().readValue(in);
}
containment = in.readBoolean();
if (PROTOCOL_TRACER.isEnabled())
{
PROTOCOL_TRACER.format("Read feature: ID={0}, name={1}, type={2}, many={3}, containment={4}", featureID,
getName(), getType(), isMany(), containment);
}
}
@Override
public void write(CDODataOutput out) throws IOException
{
if (PROTOCOL_TRACER.isEnabled())
{
PROTOCOL_TRACER.format("Writing feature: ID={0}, name={1}, type={2}, many={3}, containment={4}", featureID,
getName(), getType(), isMany(), containment);
}
super.write(out);
out.writeInt(featureID);
if (defaultValue != null)
{
out.writeBoolean(true);
getType().writeValue(out, defaultValue);
}
else
{
out.writeBoolean(false);
}
out.writeBoolean(containment);
}
public CDOClass getContainingClass()
{
return containingClass;
}
public void setContainingClass(CDOClass containingClass)
{
this.containingClass = containingClass;
setContainingPackage(containingClass.getContainingPackage());
}
public int getFeatureID()
{
return featureID;
}
public void setFeatureID(int featureID)
{
this.featureID = featureID;
}
public int getFeatureIndex()
{
if (featureIndex == UNKNOWN_FEATURE_INDEX)
{
featureIndex = ((InternalCDOClass)containingClass).getFeatureIndex(featureID);
}
return featureIndex;
}
public void setFeatureIndex(int featureIndex)
{
this.featureIndex = featureIndex;
}
public String getQualifiedName()
{
return getContainingClass().getQualifiedName() + "." + getName();
}
public Object getDefaultValue()
{
return defaultValue;
}
public void setDefaultValue(Object defaultValue)
{
this.defaultValue = defaultValue;
}
public boolean isContainment()
{
return containment;
}
public void setContainment(boolean containment)
{
this.containment = containment;
}
@Override
public String toString()
{
if (isReference())
{
return MessageFormat.format("CDOFeature(ID={0}, name={1}, type={2})", featureID, getName(),
getReferenceTypeProxy());
}
else
{
return MessageFormat.format("CDOFeature(ID={0}, name={1}, type={2})", featureID, getName(), getType());
}
}
@Override
public void writeValue(CDODataOutput out, Object value) throws IOException
{
if (!getType().canBeNull() && value == null)
{
// TODO Simon: Is this special handling needed?
getType().writeValue(out, getDefaultValue());
}
else
{
super.writeValue(out, value);
}
}
}