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
*******************************************************************************/
/*
* Created on 04.11.2003
*
*
*
*/
package at.spardat.xma.mdl.list;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import at.spardat.enterprise.exc.SysException;
import at.spardat.enterprise.util.Types;
import at.spardat.xma.mdl.Atom;
import at.spardat.xma.mdl.ModelChangeEvent;
import at.spardat.xma.mdl.NewModelEvent;
import at.spardat.xma.mdl.NewModelEventFactory;
import at.spardat.xma.mdl.Notification;
import at.spardat.xma.mdl.WModel;
import at.spardat.xma.mdl.util.DNode;
import at.spardat.xma.mdl.util.TransAtomTable;
import at.spardat.xma.mdl.util.TransStringSet;
import at.spardat.xma.mdl.util.TransStringSet1;
import at.spardat.xma.mdl.util.TransStringSetN;
import at.spardat.xma.page.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;
/**
* Widged model to represent a list of choises. It can be used with
* the SWT-widgets Combo and List. The entries of the list have to be provided by the
* programmer. All entries must by {@link Atom}s of the same type.
* The supported types are T_STRING, T_BCD, T_DATE and T_TIMESTAMP.
* There are convinience methods to use Java Strings directly.
* These Strings are converted to Atoms of type T_STRING internally.
* For domain values please use {@link ListDomWM}.
*
* @author s2877
*/
public class ListWM extends WModel implements IListWM {
/**
* Holds selection information.
*/
TransStringSet selection_;
/**
* Two dimensional array of Atom objects managing the data of the table.
* This table has one column.
*/
TransAtomTable table_;
/**
* Disallow the entering of values not in the list of choices by the user.
*/
boolean user_strict_ = true;
/**
* Constructs a ListWM.
* The behaviour can be ajusted with the following styles
*
*
{@link IListWM#S_MULTI_SELECT}
*
{@link IListWM#S_NOT_STRICT}
*
* @param id a numeric id which identifies the WidgetModel within its Page.
* @param pm reference to the enclosing Page
* @param style one of the style-constants listed above or S_NULL.
*/
public ListWM(short id, Page pm, int style) {
super(id, pm);
if ((style & S_NOT_STRICT) != 0) user_strict_ = false;
if ((style & S_MULTI_SELECT) != 0) selection_ = new TransStringSetN();
else selection_ = new TransStringSet1();
table_ = new TransAtomTable(1);
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.Transactional#changed()
*/
public boolean changed() {
return selection_.changed() || table_.changed();
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.Transactional#rollback()
*/
public void rollback() {
selection_.rollback();
table_.rollback();
handle (new ListChangedEvent());
handle (new SelectionChangedEvent(false));
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.Transactional#commit()
*/
public void commit() {
selection_.commit();
table_.commit();
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.WModel#handle(at.spardat.xma.mdl.ModelChangeEvent)
*/
public boolean handle(ModelChangeEvent event) {
return event.execute();
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.list.IListWM#clear()
*/
public void clear() {
table_.clear();
selection_.clear();
handle (new ListChangedEvent ());
handle (new SelectionChangedEvent (false));
}
/*
* @see at.spardat.xma.mdl.util.Descriptive#describe(at.spardat.xma.mdl.util.DNode)
*/
public void describe (DNode n) {
super.describe(n);
n.app("user_strict", user_strict_).comma();
n.app("isMultiSel", isMultiSelect()).comma();
DNode sel = new DNode(n, "selection: ");
sel.app(selection_);
DNode table = new DNode(n, "listData: ");
table.app(table_);
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.WModel#randomlyChange()
*/
public void randomlyChange() {
if (Assert.ON) {
int change = TestUtil.randomInt(0, 8);
switch (change) {
case 0:
// select a random entry
if(size()>0) {
select(getEntry(TestUtil.randomInt(0, size()-1)).toString());
}
break;
case 1:
// deselect a random entry
if(size()>0) {
deselect(getEntry(TestUtil.randomInt(0, size()-1)).toString());
}
break;
case 2:
// deselect all
deselectAll();
break;
case 3:
// select a key randomly choosen
select (TestUtil.randomString(TestUtil.randomInt(0, 3)));
break;
case 4:
// randomly add an entry
if(!this.isUserStrict()){
add(new Atom(TestUtil.randomString(1,64)));
} else {
add(TestUtil.randomString(1,64),new Atom(TestUtil.randomString(1,64)));
}
break;
case 5:
// randomly insert an entry
if(size()>0){
if(!isUserStrict()){
add(TestUtil.randomInt(0,size()-1),new Atom(TestUtil.randomString(1,64)));
} else {
add(TestUtil.randomInt(0,size()-1),TestUtil.randomString(1,64), new Atom(TestUtil.randomString(1,64)));
}
}
break;
case 6:
// update an entry
if (size() > 0) {
int index = TestUtil.randomInt(0, size()-1);
if(!isUserStrict()){
replace(index,new Atom(TestUtil.randomString(1,64)));
} else {
replace(index,TestUtil.randomString(1,64), new Atom(TestUtil.randomString(1,64)));
}
}
break;
case 7:
// delete an entry
if (size() > 0) {
remove(TestUtil.randomInt(0, size()-1));
}
break;
case 8:
// randomly add an entry
if(this.isUserStrict()){
add(TestUtil.randomString(1,64),new Atom(TestUtil.randomString(1,64)));
}
break;
}
}
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.WModel#equalsCS(at.spardat.xma.mdl.WModel, int)
*/
public void equalsCS(WModel mServer, int syncPoint) {
if (Assert.ON) {
ListWM mS = (ListWM) mServer;
// the selection must always be the same
if (!selection_.equals(mS.selection_)) throw new RuntimeException();
// the tables must match
if (!table_.equals(mS.table_)) throw new RuntimeException();
}
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.WModel#estimateMemory()
*/
public int estimateMemory() {
return 200 + table_.size()*50;
}
/**
* Checks if entry matches the supported types and the type of the
* allready added entries.
* @param entry to check its type
* @throws SysException if the type of the entry does not match the type
* of allready existing entries or does not match the supported types.
*/
private void checkType(Atom entry) {
if(table_.size()==0) {
byte type = entry.getType();
if(type!=Types.T_STRING && type!=Types.T_BCD && type!=Types.T_DATE && type!=Types.T_TIMESTAMP &&type!=Types.T_BOOLEAN) {
throw new SysException("type not supported: "+Atom.type2String(type));
}
} else {
byte type = table_.get(0,0).getType();
if(type!=entry.getType()) {
throw new SysException("all entrys must be of the same type");
}
}
}
/**
* Checks if the allready containd entries are atoms of type T_STRING.
* @param entry
* @throws SysException if the list model allready contains entries of different
* types than T_STRING.
*/
private void checkType(String entry) {
if(table_.size()<0) {
byte type = table_.get(0,0).getType();
if(type!=Types.T_STRING) {
throw new SysException("all entrys must be of the same type");
}
}
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.list.IListWM#add(at.spardat.xma.mdl.Atom)
*/
public void add(Atom entry) {
checkType(entry);
boolean added = table_.add(entry.toString(),new Atom[]{entry});
if(added) {
handle(new ListItemAddedEvent(table_.indexOf(entry.toString())));
}
}
/**
* Inserts an entry into the list at the specified position and associates it with a key.
* All selection and entry related methods then work with the key:
* contains(), indexOf(), remove(), deselect(), select(), getSelected(), etc.
*
*
* @param key to add
* @param entry to add
* @see at.spardat.xma.mdl.list.IListWM#add(java.lang.String,at.spardat.xma.mdl.Atom)
*/
public void add(int index,String key, Atom entry) {
if(!isUserStrict()){
throw new IllegalStateException("Programming error: adding of key-value pairs is only allowed if the ListWM is strict!");
}
checkType(entry);
boolean added = table_.add(index, key,new Atom[]{entry});
if(added) {
handle(new ListItemAddedEvent(table_.indexOf(key)));
}
}
/**
* Inserts an entry into the list at the specified position and associates it with a key.
* All selection and entry related methods then work with the key:
* contains(), indexOf(), remove(), deselect(), select(), getSelected(), etc.
* This method can only be used if the model has the style strict, otherwise an exception is thrown!
*
* @param key to add
* @param entry to add
* @see at.spardat.xma.mdl.list.IListWM#add(java.lang.String,at.spardat.xma.mdl.Atom)
*/
public void add(int index,String key, String entry) {
this.add(index, key, new Atom(entry));
}
/**
* Adds an entry to the list and associates it with a key.
* The entry is appended at the end of the selection list.
* All selection and entry related methods then work with the key:
* contains(), indexOf(), remove(), deselect(), select(), getSelected(), etc.
* This method can only be used if the model has the style strict, otherwise an exception is thrown!
*
* @param key to add
* @param entry to add
* @see at.spardat.xma.mdl.list.IListWM#add(java.lang.String,at.spardat.xma.mdl.Atom)
*/
public void add(String key, Atom entry) {
this.add(size(),key, entry);
}
public void add(String entry) {
checkType(entry);
boolean added = table_.add(entry,new Atom[]{new Atom(entry)});
if(added) {
handle(new ListItemAddedEvent(table_.indexOf(entry)));
}
}
/**
* Adds an entry to the list and associates it with a key.
* The entry is appended at the end of the selection list.
* All selection and entry related methods then work with the key:
* contains(), indexOf(), remove(), deselect(), select(), getSelected(), etc.
* This method can only be used if the model has the style strict, otherwise an exception is thrown!
*
* @param key to add
* @param entry to add
* @see at.spardat.xma.mdl.list.IListWM#add(java.lang.String, java.lang.String)
*/
public void add(String key, String entry) {
this.add(key, new Atom(entry));
}
/**
* Adds all the key-value pairs from the map the list.
* The entries are appended at the end of the list.
* This method iterates over the Map and calls:
* at.spardat.xma.mdl.list.IListWM#add(java.lang.String, java.lang.String).
*
* The keys in the Map have to be of the type String, the values have to be of the type String or Atom.
* As the iteration order of a HashMap is undefined, it might be advisable to use a TreeMap or a LinkedHashMap.
*
* All selection and entry related methods then work with the keys:
* contains(), indexOf(), remove(), deselect(), select(), getSelected(), etc.
* This method can only be used if the model has the style strict, otherwise an exception is thrown!
*
* @param map -which is iterated
* @see at.spardat.xma.mdl.list.IListWM#add(Map map)
*/
public void add(Map map) {
Set keys = map.keySet();
for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
Object entry = map.get(key);
if(entry instanceof String){
this.add(key, new Atom((String)entry));
} else if (entry instanceof Atom){
this.add(key, (Atom)entry);
} else {
throw new IllegalStateException("Programming error: the values in the map parameter are neither of the type String nor Atom!");
}
}
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.list.IListWM#add(int, at.spardat.xma.mdl.Atom)
*/
public void add(int index, Atom entry) {
checkType(entry);
boolean added = table_.add(index,entry.toString(),new Atom[]{entry});
if(added) {
handle(new ListItemAddedEvent(index));
}
}
public void add(int index, String entry) {
checkType(entry);
boolean added = table_.add(index,entry,new Atom[]{new Atom(entry)});
if(added) {
handle(new ListItemAddedEvent(index));
}
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.list.IListWM#add(at.spardat.xma.mdl.Atom[])
*/
public void add(Atom[] entries) {
for(int i=0;i= size()) return; //do nothing //KWF 28.01.11
String key = table_.getKey(index);
selection_.remove(key); //also remove it from the selection
table_.remove(index);
handle(new ListItemRemovedEvent(index));
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.list.IListWM#replace(int, at.spardat.xma.mdl.Atom)
*/
public void replace(int index, Atom newEntry) {
checkType(newEntry);
table_.remove(index);
table_.add(index,newEntry.toString(),new Atom[]{newEntry});
handle(new ListItemChangedEvent(index));
}
/**
*
*/
public void replace(int index, String newEntry) {
checkType(newEntry);
table_.remove(index);
table_.add(index,newEntry,new Atom[]{new Atom(newEntry)});
handle(new ListItemChangedEvent(index));
}
/**
* @see at.spardat.xma.mdl.list.IListWM#replace(int, java.lang.String, at.spardat.xma.mdl.Atom)
*
* Replaces an entry (key-value pair) in the list. The old entry at the
* given index position is replaced by the entry given
* as parameter.
* This method can only be used if the model has the style strict, otherwise an exception is thrown!
*
* @param index the index of the entry to replace.
* @param newKey the new key to insert.
* @param newEntry the new entry to insert.
*/
public void replace(int index, String newKey, Atom newEntry) {
if(!isUserStrict()){
throw new IllegalStateException("Programming error: adding of key-value pairs is only allowed if the ListWM is strict!");
}
String key = table_.getKey(index);
selection_.remove(key); //also remove it from the selection
table_.remove(index);
checkType(newEntry);
boolean added = table_.add(index, newKey,new Atom[]{newEntry});
if(added) {
handle(new ListItemChangedEvent(index));
} else {
handle(new ListItemRemovedEvent(index)); //should not happen
}
}
/**
* @see at.spardat.xma.mdl.list.IListWM#replace(int, java.lang.String, java.lang.String)
*
* Replaces an entry (key-value pair) in the list. The old entry at the
* given index position is replaced by the entry given
* as parameter.
*
* This method can only be used if there were already entries added with add(key,entry) - otherwise an exception is thrown!
*
* @param index the index of the entry to replace.
* @param newKey the new key to insert.
* @param newEntry the new entry to insert.
*/
public void replace(int index, String newKey, String newEntry) {
replace(index, newKey, new Atom(newEntry));
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.list.IListWM#contains(at.spardat.xma.mdl.Atom)
*/
public boolean contains(Atom entry) {
return table_.containsKey(entry.toString());
}
public boolean contains(String entry) {
return table_.containsKey(entry);
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.list.IListWM#size()
*/
public int size() {
return table_.size();
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.ISelectable#select(java.lang.String)
*/
public void select(String key) {
if(!isStrict() || table_.containsKey(key)) {
boolean success = selection_.add (key);
if (success) {
handle (new SelectionChangedEvent (false));
}
}
}
/**
* Sets the selection of this ListWM to the given value.
* If value is empty (null or ""), the selection is cleared.
* @param value to select
*/
public void set(String value) {
if(value!=null && value.length()>0) {
select(value);
} else {
deselectAll();
}
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.ISelectable#deselect(java.lang.String)
*/
public void deselect(String key) {
selection_.remove (key);
handle (new SelectionChangedEvent (false));
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.ISelectable#deselectAll()
*/
public void deselectAll() {
selection_.clear();
handle (new SelectionChangedEvent (false));
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.ISelectable#isMultiSelect()
*/
public boolean isMultiSelect() {
return selection_ instanceof TransStringSetN;
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.ISelectable#getSelected()
*/
public String getSelected() {
return selection_.getSome();
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.ISelectable#getSelection()
*/
public String[] getSelection() {
return selection_.getAll();
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.ISelectable#getSelectionCount()
*/
public int getSelectionCount() {
return selection_.size();
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.ISelectable#isSelected(java.lang.String)
*/
public boolean isSelected(String key) {
return selection_.contains(key);
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.ISelectable#isStrict()
*/
public boolean isStrict() {
//every single selection model can be attached to an attrval -> not strict
//multi selection models are allways strict
return selection_ instanceof TransStringSetN;
}
/**
* Returns if the user is allowed to enter values not in the list of choices.
* @return true if the user can enter additional values
*/
public boolean isUserStrict() {
return user_strict_;
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.Synchronization#externalize(at.spardat.xma.serializer.XmaOutput, boolean)
*/
public void externalize(XmaOutput xo, boolean forceFull) throws IOException {
// decide on what to write
byte what = 0;
boolean writeTable = forceFull || table_.changed();
boolean writeSel = forceFull || selection_.changed();
// externalize
if (writeTable) what |= 1;
if (writeSel) what |= 2;
xo.writeByte("tableOrSel", what);
if (writeTable) {
// externalize table
table_.externalize (xo, forceFull);
}
if (writeSel) {
// externalize selection
selection_.externalize (xo, forceFull);
}
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.Synchronization#internalize(at.spardat.xma.serializer.XmaInput)
*/
public void internalize(XmaInput in) throws IOException, ClassNotFoundException {
byte what = in.readByte();
boolean tableChanged = ((what & 1) != 0);
boolean selChanged = ((what & 2) != 0);
if (tableChanged) {
table_.internalize(in);
}
if (selChanged) {
selection_.internalize(in);
}
if (tableChanged) handle (new ListChangedEvent ());
if (selChanged || tableChanged) handle (new SelectionChangedEvent (false));
}
/**
* Notification event sent when one or more entries of the list might
* have changed, removed or added without knowning the precise
* reason of the change.
*/
class ListChangedEvent extends Notification {
/**
* Constructor
*
* @param wModel the widget model
*/
public ListChangedEvent () {
super (ListWM.this, false);
}
}
class ListItemAddedEvent extends Notification {
int index;
/**
* @param destination
* @param fromUI
*/
public ListItemAddedEvent(int index) {
super(ListWM.this, false);
this.index = index;
}
public int getIndex() {
return index;
}
}
class ListItemChangedEvent extends Notification {
int index;
/**
* @param destination
* @param fromUI
*/
public ListItemChangedEvent(int index) {
super(ListWM.this, false);
this.index = index;
}
public int getIndex() {
return index;
}
}
class ListItemRemovedEvent extends Notification {
int index;
/**
* @param destination
* @param fromUI
*/
public ListItemRemovedEvent(int index) {
super(ListWM.this, false);
this.index = index;
}
public int getIndex() {
return index;
}
}
/**
* Notification event that the selection state has changed.
*/
class SelectionChangedEvent extends Notification {
/**
* Constructor
*/
public SelectionChangedEvent (boolean fromUI) {
super (ListWM.this, fromUI);
}
}
/**
* Modificative event that sets an entirely new selection
*/
class NewSelectionEvent extends ModelChangeEvent {
/**
* Constructor
*
* @param selectedKeys the set of keys that are to be selected
* @param fromUI indicates if the events origin is the UI or not
*/
public NewSelectionEvent (Collection selectedKeys, boolean fromUI) {
super (ListWM.this, fromUI);
selectedKeys_ = selectedKeys;
}
/**
* Selects the provided keys. Invalid keys (that are not in the table) are ignored.
*
* @see at.spardat.xma.mdl.ModelChangeEvent#execute()
*/
public boolean execute() {
TransStringSet sel = ((ListWM)wModel_).selection_;
TransAtomTable table = ((ListWM)wModel_).table_;
sel.clear();
Iterator iter = selectedKeys_.iterator();
while (iter.hasNext()) {
String key = (String) iter.next();
if(!isStrict() || table.containsKey(key)) {
sel.add(key);
}
}
return true;
}
private Collection selectedKeys_;
}
/**
* Event class used to notify the dynamic registration of a new ListWM.
* @author gub
* @since 2.1.0
* @see Page#addWModel(WModel)
*/
public static class NewListWMEvent extends NewModelEvent {
int style;
/** empty contructor for deserialization */
public NewListWMEvent() {}
/**
* constructor which initializes dataSource and style
* @param style one of the style-constants listed in {@link IListWM}.
*/
public NewListWMEvent(int style) {
this.style=style;
}
// see at.spardat.xma.mdl.NewModelEvent.getType()
public byte getType() {
return NewModelEventFactory.ListWM;
}
// see at.spardat.xma.mdl.NewModelEvent.createModel()
public WModel createModel(short id,Page page) {
return new ListWM(id,page,style);
}
// see at.spardat.xma.mdl.NewModelEvent.serialize()
public void serialize(XmaOutput out) throws IOException {
super.serialize(out);
out.writeInt("style",style);
}
// see at.spardat.xma.mdl.NewModelEvent.deserialize()
public void deserialize(XmaInput in) throws IOException, ClassNotFoundException {
super.deserialize(in);
style=in.readInt();
}
}
// see at.sparda.xma.mdl.WModel.createNewModelEvent()
public NewModelEvent createNewModelEvent() {
int style = S_NULL;
if(isMultiSelect()) style|=S_MULTI_SELECT;
if(!isUserStrict()) style|=S_NOT_STRICT;
return new NewListWMEvent(style);
}
}