Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* 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:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
// @(#) $Id: SimpleWM.java 3240 2009-03-03 16:10:56Z gub $
package at.spardat.xma.mdl.simple;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import at.spardat.properties.XProperties;
import at.spardat.xma.mdl.*;
import at.spardat.xma.mdl.util.DNode;
import at.spardat.xma.page.*;
import at.spardat.xma.serializer.XmaInput;
import at.spardat.xma.serializer.XmaOutput;
import at.spardat.xma.test.TestUtil;
import at.spardat.xma.util.Assert;
import at.spardat.enterprise.fmt.AParseException;
import at.spardat.enterprise.fmt.IFmt;
import at.spardat.enterprise.util.*;
/**
* Implements ISimpleWM.
*/
public class SimpleWM extends WModel implements ISimpleWM {
/**
* One of the type codes in enterprise.util.Types.
*/
protected byte type_;
/**
* A string encoded value of a particular type. This instance is never null.
*/
protected String value_ = "";
/**
* A copy of a value to support change tracking.
*/
private String savedValue_;
/**
* Indicates if sloppySetters_ has been computed
*/
private static boolean sloppySettersComputed_ = false;
/**
* Indicates that set-methods should do nothing on type-violations. This behaviour is supported
* just for compatibility. In future version, sloppySetters_ will always be false.
*/
private static boolean sloppySetters_ = false;
/**
* Constructs a SimpleWM.
*
* @param id a numeric id which identifies the WidgetModel within its Page.
* @param type a type constant.
* @param pm the Page this model belongs to
*/
public SimpleWM (short id, byte type, Page pm) {
super (id, pm);
if (type < Types.FIRST || type > Types.LAST) throw new IllegalArgumentException();
type_ = type;
if (!sloppySettersComputed_) {
sloppySettersComputed_ = true;
sloppySetters_ = settersShouldBeSloppy(pm);
}
}
/**
* Determines if setters should ignore type violations.
*/
protected boolean settersShouldBeSloppy(Page pm){
// This method is overridden in SimpleWMClient, so this implementation is called
// only on server side.
XProperties node = XProperties.getNodeOfPackage("xma.runtime");
return "true".equals (node.get("sloppyModelSetters", "false"));
}
/**
* Sets this TextModel to the empty string.
*/
public void clear() {
handle (new ClearEvent ());
}
/**
* Returns true if this model holds a value.
*
* @return true if this has a non empty value.
*/
public boolean hasValue() {
return value_.length() > 0;
}
/**
* Returns the type constant.
*
* @return the type constant, see {@link at.spardat.enterprise.util.Types}.
*/
public byte getType() {
return type_;
}
/**
* @see IAtomic#toString()
*/
public String toString() {
return Atom.toStringImpl (type_, value_);
}
/**
* Maps this to string representation using a IFmt object.
* The provided formatter is only used if it is type compatible
* with the type of this IAtomic. Otherwise, or if formatter is
* null, the internal String encoding is returned.
*
* @param formatter the IFmt formatter. May be null.
* @return non null String.
*/
public String toString (IFmt formatter) {
if (formatter == null) return value_;
if (formatter.mayBeAppliedTo(type_)) {
return formatter.format(value_);
} else
return value_;
}
/**
* Sets the value of this model from a string. Clears this if value==null.
* Does nothing if getType() is not equal to T_STRING.
*
* @param value the string to set
*/
public void set (String value) {
if (value == null) clear();
else {
setInternalFromEvent (new StringChangeEvent (value));
}
}
/**
* Calls handle for an change event and decides if IllegalStateExceptions should
* be thrown.
*/
private void setInternalFromEvent (ModelChangeEvent ev) {
boolean success = handle (ev);
if (!sloppySetters_ && !success) throw new IllegalStateException ("type mismatch");
}
/**
* Extracts a double from this. Returns 0.0 if getType() is not equal to T_BCD or !hasValue().
*
* @return double
*/
public double toDouble () {
if (type_ != Types.T_BCD || !hasValue()) return 0.0;
return Double.parseDouble(value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toFloat()
*/
public float toFloat() {
if (type_ != Types.T_BCD || !hasValue()) return 0.0F;
return Float.parseFloat(value_);
}
/**
* Sets the value from a double. Does nothing if getType() is not equal to T_BCD.
* Also does nothing if the provided double is NaN or Infinity.
*
* @param value the value to set
* @param precision the number of places after the comma used when converting
* the double to a string.
*/
public void set (double value, int precision) {
setInternalFromEvent (new BcdChangeEvent (value, precision));
}
/**
* Sets the value from a double. Does nothing if getType() is not equal to T_BCD.
* Also does nothing if the provided double is NaN or Infinity. If the provided
* double (which is binary coded) would result in an unexact decimal
* representation, the fractional part of the result is stripped so that there
* are no more then 15 significant digits.
*
* @param value the value to set
*/
public void set (double value) {
setInternalFromEvent (new BcdChangeEvent (value, -1));
}
/**
* @see at.spardat.xma.mdl.simple.ISimpleWM#set(java.math.BigDecimal)
*/
public void set (BigDecimal value) {
setInternalFromEvent (new Bcd2ChangeEvent(value));
}
/**
* @see at.spardat.xma.mdl.IAtomic#toBigDecimal()
*/
public BigDecimal toBigDecimal() {
if (type_ != Types.T_BCD || !hasValue()) return null;
return new BigDecimal (value_);
}
/**
* Returns the value of this as int if the type of this is T_BCD. Returns
* 0 if the type is not T_BCD.
*
* @see at.spardat.xma.mdl.IAtomic#toInt()
*/
public int toInt () {
if (type_ != Types.T_BCD || !hasValue()) return 0;
return Integer.parseInt(value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toLong()
*/
public long toLong() {
if (type_ != Types.T_BCD || !hasValue()) return 0;
return Long.parseLong (value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toByte()
*/
public byte toByte() {
if (type_ != Types.T_BCD || !hasValue()) return 0;
return Byte.parseByte (value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toShort()
*/
public short toShort() {
if (type_ != Types.T_BCD || !hasValue()) return 0;
return Short.parseShort (value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toByte()
*/
public Byte toBYTE() {
if (type_ != Types.T_BCD || !hasValue()) return null;
return new Byte(value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toSHORT()
*/
public Short toSHORT() {
if (type_ != Types.T_BCD || !hasValue()) return null;
return new Short(value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toINTEGER()
*/
public Integer toINTEGER() {
if (type_ != Types.T_BCD || !hasValue()) return null;
return new Integer(value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toLONG()
*/
public Long toLONG() {
if (type_ != Types.T_BCD || !hasValue()) return null;
return new Long(value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toFLOAT()
*/
public Float toFLOAT() {
if (type_ != Types.T_BCD || !hasValue()) return null;
return new Float (value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#toDOUBLE()
*/
public Double toDOUBLE() {
if (type_ != Types.T_BCD || !hasValue()) return null;
return new Double(value_);
}
/**
* @see at.spardat.xma.mdl.simple.ISimpleWM#set(java.lang.Boolean)
*/
public void set(Boolean val) {
if (val == null) clear();
else set (val.booleanValue());
}
/**
* @see at.spardat.xma.mdl.simple.ISimpleWM#set(java.lang.Byte)
*/
public void set (Byte val) {
if (val == null) clear();
else set (val.intValue());
}
/**
* @see at.spardat.xma.mdl.simple.ISimpleWM#set(java.lang.Short)
*/
public void set (Short val) {
if (val == null) clear();
else set (val.intValue());
}
/**
* @see at.spardat.xma.mdl.simple.ISimpleWM#set(java.lang.Integer)
*/
public void set (Integer val) {
if (val == null) clear();
else set (val.intValue());
}
/**
* @see at.spardat.xma.mdl.simple.ISimpleWM#set(java.lang.Long)
*/
public void set(Long val) {
if (val == null) clear();
else set (val.doubleValue());
}
/**
* @see at.spardat.xma.mdl.simple.ISimpleWM#set(java.lang.Float)
*/
public void set (Float val) {
if (val == null) clear();
else set (val.doubleValue());
}
/**
* @see at.spardat.xma.mdl.simple.ISimpleWM#set(java.lang.Double)
*/
public void set (Double val) {
if (val == null) clear();
else set (val.doubleValue());
}
/**
* Sets this from an int. Does nothing if the type of this is not T_BCD.
*
* @param value the provided integer to set.
*/
public void set (int value) {
setInternalFromEvent (new BcdChangeEvent (value, -1));
}
/**
* Returns a newly constructed java.util.Date object representing the value of this.
*
* @return null if the type is not equal to T_DATE or T_TIMESTAMP or !hasValue().
*/
public Date toDate () {
return Atom.toDateImpl (type_, value_);
}
/**
* Sets this from a provided java.util.Date. This method does nothing if the type
* is not equal to T_DATE or T_TIMESTAMP.
*
* @param value the value to set
*/
public void set (Date value) {
if (value == null) clear();
else {
if (type_ == Types.T_DATE) setInternalFromEvent (new DateChangeEvent (value));
else if (type_ == Types.T_TIMESTAMP) setInternalFromEvent (new TimeStampChangeEvent (value));
else throw new IllegalStateException ("type mismatch");
}
}
/**
* Returns true if getType() equals T_BOOLEAN and the stored value equals TRUE. If
* there is no value stored or the stored value is not TRUE, false is returned.
*
* @return boolean indicating the value in this.
*/
public boolean isTrue() {
if (type_ != Types.T_BOOLEAN) return false;
if (!hasValue()) return false;
return value_.equals("J");
}
/**
* If getType() equals T_BOOLEAN, this method sets a boolean value, otherwise it does nothing.
*
* @param value the boolean value to set
*/
public void set (boolean value) {
setInternalFromEvent (new BooleanChangeEvent (value, false));
}
/**
* @see at.spardat.xma.mdl.WModel#changed()
*/
public boolean changed() {
return savedValue_ != null;
}
/**
* @see at.spardat.xma.mdl.WModel#commit()
*/
public void commit() {
savedValue_ = null;
}
/**
* @see at.spardat.xma.mdl.WModel#handle(ModelChangeEvent)
*/
public boolean handle (ModelChangeEvent event) {
return event.execute();
}
/**
* @see at.spardat.xma.mdl.WModel#rollback()
*/
public void rollback() {
if (savedValue_ != null) {
value_ = savedValue_;
savedValue_ = null;
handle (new ChangedEvent (false));
}
}
/**
* @see at.spardat.xma.mdl.Synchronization#externalize(at.spardat.xma.serializer.XmaOutput, boolean)
*/
public void externalize (XmaOutput xo, boolean forceFull) throws IOException {
// the content
xo.writeString("val", value_);
}
/**
* @see at.spardat.xma.mdl.Synchronization#internalize(at.spardat.xma.serializer.XmaInput)
*/
public void internalize (XmaInput in) throws IOException, ClassNotFoundException {
value_ = in.readString ();
// discard history
savedValue_ = null;
handle (new ChangedEvent (false));
}
/**
* This method requires that a legal internal representation has been constructed and manages
* the state in value_ and savedValue_. If there is no saved state (savedValue_ equals null) and
* the provided value is different, the state is saved before. If there is a value provided
* which equals the saved state, the saved state is cleared. Either way, the provided value
* becomes the one stored in instance variable value_.
*
* @param value the new value to set
*/
protected void setInternal (String value) {
if (value == null) value = "";
if (value_.equals(value)) return;
if (savedValue_ == null) {
// no save state
savedValue_ = value_;
value_ = value;
} else {
// there is a saved state
if (savedValue_.equals(value)) {
// mark this as unchanged
savedValue_ = null;
}
value_ = value;
}
}
/**
* @see at.spardat.xma.mdl.util.Descriptive#describe(at.spardat.xma.mdl.util.DNode)
*/
public void describe (DNode n) {
super.describe(n);
n.app("type", Atom.type2String(type_)).comma().app("value", value_).comma().app("saved", savedValue_).comma().app("changed", savedValue_ != null);
}
/**
* Makes random changes to this
*/
public void randomlyChange () {
if (Assert.ON) {
if (TestUtil.draw(0.1)) clear();
else {
if (type_ == Types.T_BOOLEAN) set (TestUtil.draw(0.5));
else if (type_ == Types.T_STRING) set (TestUtil.randomString(TestUtil.randomInt(0, 10)));
else if (type_ == Types.T_BCD) set (TestUtil.randomDouble(-1000, 1000), TestUtil.randomInt(0, 5));
else if (type_ == Types.T_DATE) set(new java.util.Date());
}
}
}
/**
* @see at.spardat.xma.mdl.WModel#equalsCS(at.spardat.xma.mdl.WModel, int)
*/
public void equalsCS (WModel mServer, int syncPoint) {
if (Assert.ON) {
SimpleWM ms = (SimpleWM) mServer;
if (!value_.equals(ms.value_)) throw new RuntimeException();
}
}
/**
* Estimates the number of bytes this object consumes in memory.
*/
public int estimateMemory () {
return MemoryEstimator.sizeOfObject(4) + MemoryEstimator.sizeOf(value_);
}
/**
* @see at.spardat.xma.mdl.IAtomic#getEncodedValue()
*/
public String getEncodedValue () {
return value_;
}
/**
* Programmer initiated change of T_STRING typed SimpleWM
*/
class StringChangeEvent extends ModelChangeEvent {
public StringChangeEvent (String newString) {
super (SimpleWM.this, false);
newString_ = newString;
}
/**
* @see at.spardat.xma.mdl.ModelChangeEvent#execute()
*/
public boolean execute() {
if (newString_ == null) return false;
if (type_ != Types.T_STRING) return false;
setInternal(newString_);
return true;
}
private String newString_;
}
/**
* Programmer initiated change of a T_BCD model providing a double
*/
class BcdChangeEvent extends ModelChangeEvent {
/**
* Constructor.
*
* @param numNK number of digits after the comma to be used
* when the provided double is converted to a String
* (which has to be done since widget models are
* string encoded). If numNK
* equals -1, the number of the resulting places
* after the comma is unknown. Although the caller
* can be sure that the result does not consist of
* more then 15 significant digits after the comma.
*/
public BcdChangeEvent (double value, int numNK) {
super (SimpleWM.this, false);
value_ = value;
numNK_ = numNK;
}
/**
* @see at.spardat.xma.mdl.ModelChangeEvent#execute()
*/
public boolean execute() {
if (type_ != Types.T_BCD) return false;
if (Double.isInfinite(value_) || Double.isNaN(value_)) return false;
setInternal(NumberUtil.double2String(value_));
return true;
}
private double value_;
private int numNK_;
}
/**
* Programmer initiated change of a T_BCD model providing a BigDecimal
*/
class Bcd2ChangeEvent extends ModelChangeEvent {
private BigDecimal fBigDecimal;
/**
* Constructor.
*
* @param bigDecimal the BigDecimal to set. if null, this
* is cleared
*/
public Bcd2ChangeEvent (BigDecimal bigDecimal) {
super (SimpleWM.this, false);
fBigDecimal = bigDecimal;
}
/**
* @see at.spardat.xma.mdl.ModelChangeEvent#execute()
*/
public boolean execute() {
if (type_ != Types.T_BCD) return false;
if (fBigDecimal == null) clear();
else setInternal (fBigDecimal.toString());
return true;
}
}
/**
* Change of T_BOOLEAN typed SimpleWM
*/
class BooleanChangeEvent extends ModelChangeEvent {
/**
* Constructor
*
* @param value the new value
* @param fromUI indicates whether the source of change is the ui or the programmer
*/
public BooleanChangeEvent (boolean value, boolean fromUI) {
super (SimpleWM.this, fromUI);
value_ = value;
}
/**
* @see at.spardat.xma.mdl.ModelChangeEvent#execute()
*/
public boolean execute() {
if (type_ != Types.T_BOOLEAN) return false;
setInternal(value_ ? "J" : "N");
return true;
}
private boolean value_;
}
/**
* Programmer initiated change of a T_DATE typed SimpleWM
*/
class DateChangeEvent extends ModelChangeEvent {
/**
* Constructor
*/
public DateChangeEvent (Date date) {
super (SimpleWM.this, false);
date_ = date;
}
/**
* @see at.spardat.xma.mdl.ModelChangeEvent#execute()
*/
public boolean execute() {
if (date_ == null) return false;
if (type_ != Types.T_DATE) return false;
setInternal(DateUtil.date2Internal(date_));
return true;
}
private Date date_;
}
/**
* Programmer initiated change of a T_TIMESTAMP typed SimpleWM
*/
class TimeStampChangeEvent extends ModelChangeEvent {
/**
* Constructor
*/
public TimeStampChangeEvent (Date date) {
super (SimpleWM.this, false);
date_ = date;
}
/**
* @see at.spardat.xma.mdl.ModelChangeEvent#execute()
*/
public boolean execute() {
if (date_ == null) return false;
if (type_ != Types.T_TIMESTAMP) return false;
setInternal(TimeStampUtil.date2Internal(date_));
return true;
}
private Date date_;
}
/**
* Resets the value of the model in order that !hasValue() holds
* afterwards.
*
* @author YSD, 28.10.2003
*/
class ClearEvent extends ModelChangeEvent {
/**
* Konstruktor
*/
public ClearEvent () {
super (SimpleWM.this, false);
}
/**
* @see at.spardat.xma.mdl.ModelChangeEvent#execute()
*/
public boolean execute () {
setInternal ("");
return true;
}
}
/**
* A event which is created if the user modifies text in a UI-control attached
* to a SimpleUIDelegateClient.
*/
class UserModifiedTextEvent extends ModelChangeEvent {
/**
* Constructor
*
* @param newText the new contents of the UI-control after the modification
*/
public UserModifiedTextEvent (String newText) {
super (SimpleWM.this, true);
newText_ = newText;
}
/**
* Reflects the new text in the Widget Model. If the new text is
* not accepted by the Formatter, this method returns false.
*
* @see at.spardat.xma.mdl.ModelChangeEvent#execute()
*/
public boolean execute() {
SimpleWMClient model = (SimpleWMClient) wModel_;
if (!model.doUITransfer()) return false;
// get formatter
IFmt formatter = model.getFmtInternal();
if (formatter == null) {
// no formatter; set the text directly
setInternal(newText_);
} else {
if (formatter.isOneWay()) return false;
String internal = null;
try {
internal = formatter.parse(newText_);
} catch (AParseException ex) {
parseException_ = ex;
return false;
}
setInternal(internal);
}
return true;
}
private String newText_;
private AParseException parseException_;
}
/**
* Indicates that something has changed without specifying details.
*
* @author YSD, 03.05.2003 19:13:09
*/
class ChangedEvent extends Notification {
public ChangedEvent (boolean fromUI) {
super (SimpleWM.this, fromUI);
}
}
/**
* Event class used to notify the dynamic registration of a new SimpleWM.
* @author gub
* @since 2.1.0
* @see Page#addWModel(WModel)
*/
public static class NewSimpleWMEvent extends NewModelEvent {
byte modelType;
/** empty contructor for deserialization */
public NewSimpleWMEvent() {}
/**
* constructor which initializes the modelType
* @param modelType must be one of the type constants defined in {@link Types}
*/
public NewSimpleWMEvent(byte modelType) {
this.modelType=modelType;
}
// see at.spardat.xma.mdl.NewModelEvent.getType()
public byte getType() {
return NewModelEventFactory.SimpleWM;
}
// see at.spardat.xma.mdl.NewModelEvent.createModel()
public WModel createModel(short id,Page page) {
return new SimpleWM(id,modelType,page);
}
// see at.spardat.xma.mdl.NewModelEvent.serialize()
public void serialize(XmaOutput out) throws IOException {
super.serialize(out);
out.writeByte("modelType",modelType);
}
// see at.spardat.xma.mdl.NewModelEvent.deserialize()
public void deserialize(XmaInput in) throws IOException, ClassNotFoundException {
super.deserialize(in);
modelType=in.readByte();
}
}
// see at.sparda.xma.mdl.WModel.createNewModelEvent()
public NewModelEvent createNewModelEvent() {
return new NewSimpleWMEvent(type_);
}
}