//{HEADER
/**
* This class is part of jnex 'Nexirius Application Framework for Java'
*
* Copyright (C) Nexirius GmbH, CH-4450 Sissach, Switzerland (www.nexirius.ch)
*
* <p>This library is free software; you can redistribute it and/or<br>
* modify it under the terms of the GNU Lesser General Public<br>
* License as published by the Free Software Foundation; either<br>
* version 2.1 of the License, or (at your option) any later version.</p>
*
* <p>This library is distributed in the hope that it will be useful,<br>
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU<br>
* Lesser General Public License for more details.</p>
*
* <p>You should have received a copy of the GNU Lesser General Public<br>
* License along with this library; if not, write to the Free Software<br>
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</p>
* </blockquote>
*
* <p>
* Nexirius GmbH, hereby disclaims all copyright interest in<br>
* the library jnex' 'Nexirius Application Framework for Java' written<br>
* by Marcel Baumann.</p>
*/
//}HEADER
package com.nexirius.framework.datamodel;
import com.nexirius.util.TextToken;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.util.Enumeration;
import java.util.Hashtable;
/**
* This class holds an arbitrary number of ModelFlagContainers.
*
* @author Marcel Baumann
*/
public class ModelStatus {
private Hashtable stateList = null;
/**
* Creates a new empty flag list
*/
public ModelStatus() {
}
/**
* Creates a new flag list and initialises it with the flags from another flag list)
*
* @param other All the flags from the other status are copied into the new instance.
*/
public ModelStatus(ModelStatus other) {
if (other.stateList != null) {
this.stateList = (Hashtable) other.stateList.clone();
}
}
private Hashtable getStateList() {
if (stateList == null) {
stateList = new Hashtable();
}
return stateList;
}
/**
* Return the state of a given flag as Boolean.
*
* @return If the flag does not exist it returns null
*/
public Boolean getStatusFlagAsBoolean(ModelFlag flag) {
if (stateList == null) {
return null;
}
return (Boolean) stateList.get(flag);
}
/**
* Returns the state of the given flag as boolean
*
* @return If the flag does not exist it returns false
*/
public boolean getFlag(ModelFlag flag) {
if (!hasFlag(flag)) {
return false;
}
return getStatusFlagAsBoolean(flag).booleanValue();
}
/**
* Set the state of an existing flag to a new status or add a new flag to the list.
*
* @param flag if this flag is not yet in the table a new flag is created ant true is returned
* @param on the new value
*/
public boolean setFlag(ModelFlag flag, boolean on) {
return setFlag(flag, new Boolean(on));
}
/**
* Set the state of an existing flag to a new status or add a new flag to the list.
*
* @param flag if this flag is not yet in the table a new flag is created ant true is returned
* @param on the new value
*/
public boolean setFlag(ModelFlag flag, Boolean on) {
if (!hasFlag(flag) || getFlag(flag) != on.booleanValue()) {
getStateList().put(flag, on);
return true;
}
return false;
}
/**
* Set the state of an existing flag to a new status or add a new flag to the list.
*/
public void setFlag(ModelFlagContainer flagcontainer) {
setFlag(flagcontainer.getFlag(), flagcontainer.getStatus());
}
/**
* Set all the flags from an array.
*/
public void setFlags(ModelFlagContainer flagcontainer[]) {
for (int i = 0; i < flagcontainer.length; ++i) {
setFlag(flagcontainer[i]);
}
}
/**
* Set all flags from a given status (does not remove the existing flags which are
* not members of the given status).
*
* @param other All the flags of this container are set accordingly.
*/
public void setFlagsFrom(ModelStatus other) {
setFlags(other.getAllFlags());
}
/**
* Set all flags from a given status (removes the existing flags which are
* not members of the given status).
*
* @param other All the flags of this container are copied.
*/
public void assign(ModelStatus other) {
if (other.stateList == null) {
this.stateList = null;
} else {
this.stateList = (Hashtable) other.stateList.clone();
}
}
/**
* Check whether the given flag is part of the status.
*/
public boolean hasFlag(ModelFlag flag) {
return getStatusFlagAsBoolean(flag) != null;
}
/**
* Returns all flags in an array.
*/
public synchronized ModelFlagContainer[] getAllFlags() {
if (stateList == null) {
return new ModelFlagContainer[0];
}
ModelFlagContainer ret[] = new ModelFlagContainer[this.stateList.size()];
Enumeration e = this.stateList.keys();
int i = 0;
while (e.hasMoreElements()) {
ModelFlag flag = (ModelFlag) e.nextElement();
ret[i++] = new ModelFlagContainer(flag, getStatusFlagAsBoolean(flag));
}
return ret;
}
/**
* Returns a predefined icon identifier for the current state.
*/
String getIconId(DataModel m) {
StringBuffer ret = new StringBuffer();
if (getFlag(ModelFlag.ERROR) || getFlag(ModelFlag.INVALID)) {
ret.append(ModelFlag.ERROR.toString());
}
if (getFlag(ModelFlag.CHANGED)) {
ret.append(ModelFlag.CHANGED.toString());
}
if (ret.length() == 0) {
return "DEFAULT";
}
return ret.toString();
}
/**
* Returns true if the EMPTY or the ERROR flag is set
*/
public boolean isExceptional() {
return getFlag(ModelFlag.ERROR) || getFlag(ModelFlag.EMPTY);
}
/**
* Returns "ERROR" if the error flag is set else returns "" if the EMPTY flag is set
* else returns null.
*/
public String getExceptionalStringId() {
if (getFlag(ModelFlag.ERROR)) {
return ModelFlag.ERROR.toString();
} else if (getFlag(ModelFlag.EMPTY)) {
return "";
}
return null;
}
/**
* Returns true if the EMPTY flag is set
*/
public boolean isEmpty() {
return getFlag(ModelFlag.EMPTY);
}
/**
* Returns true if the ERROR flag is set
*/
public boolean isError() {
return getFlag(ModelFlag.ERROR);
}
/**
* Returns true if the TRANSIENT flag is set
*/
public boolean isTransient() {
return getFlag(ModelFlag.TRANSIENT);
}
/**
* Returns true if the GRAY flag is set
*/
public boolean isGray() {
return getFlag(ModelFlag.GRAY);
}
/**
* Returns a string representation which is mainly used for debugging purposes.
*/
public String toString() {
ModelFlagContainer c[] = getAllFlags();
StringBuffer ret = new StringBuffer("ModelStatus ");
for (int i = 0; i < c.length; ++i) {
ret.append(c[i].toString() + " ");
}
return ret.toString();
}
/**
* Two model states are equal if their flags are the same id and state.
*/
public boolean equals(Object other) {
if (other != null && other instanceof ModelStatus) {
ModelStatus o = (ModelStatus) other;
if (stateList == null) {
return o.stateList == null;
}
if (o == null || o.stateList == null) {
return false;
}
if (stateList.size() == o.stateList.size()) {
ModelFlagContainer c[] = getAllFlags();
for (int i = 0; i < c.length; ++i) {
Boolean statusFlagAsBoolean = o.getStatusFlagAsBoolean(c[i].getFlag());
if (statusFlagAsBoolean == null || !statusFlagAsBoolean.equals(c[i].getStatus())) {
return false;
}
}
return true;
}
}
return false;
}
/**
* Persistance interface read function
*
* @param in The stream where the status reads from
* @throws Exception If the stream is not interpreted correctly
*/
public void readDataFrom(PushbackInputStream in, DataModel model) throws Exception {
boolean nextFlag = false;
while (true) {
int c = in.read();
if (c < 0) {
return;
}
switch (c) {
case ' ':
continue;
case '+':
nextFlag = true;
break;
case '-':
nextFlag = false;
break;
default:
in.unread(c);
return;
}
TextToken token = TextToken.nextToken(in);
if (token == null) {
throw new Exception("Expecting ModelFlag identifier but have null");
}
if (!token.isString()) {
throw new Exception("Expecting ModelFlag identifier but have: " + token);
}
model.setFlag(new ModelFlag(token.getString()), nextFlag);
}
}
/**
* Persistance interface write function
*
* @param out The stream where the status writes to
* @throws Exception If the stream is not writeable
*/
public void writeDataTo(OutputStream out) throws Exception {
if (stateList == null) {
return;
}
ModelFlagContainer c[] = getAllFlags();
for (int i = 0; i < c.length; ++i) {
if (c[i].getStatus().booleanValue()) {
out.write('+');
} else {
out.write('-');
}
TextToken flagName = new TextToken(c[i].getFlag().getName());
flagName.writeTo(out);
}
}
}