/*******************************************************************************
* This file is part of logisim-evolution.
*
* logisim-evolution is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* logisim-evolution is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with logisim-evolution. If not, see <http://www.gnu.org/licenses/>.
*
* Original code by Carl Burch (http://www.cburch.com), 2011.
* Subsequent modifications by :
* + Haute École Spécialisée Bernoise
* http://www.bfh.ch
* + Haute École du paysage, d'ingénierie et d'architecture de Genève
* http://hepia.hesge.ch/
* + Haute École d'Ingénierie et de Gestion du Canton de Vaud
* http://www.heig-vd.ch/
* The project is currently maintained by :
* + REDS Institute - HEIG-VD
* Yverdon-les-Bains, Switzerland
* http://reds.heig-vd.ch
*******************************************************************************/
package com.cburch.logisim.data;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class AttributeSets {
private static class FixedSet extends AbstractAttributeSet {
private List<Attribute<?>> attrs;
private Object[] values;
private int readOnly = 0;
FixedSet(Attribute<?>[] attrs, Object[] initValues) {
if (attrs.length != initValues.length) {
throw new IllegalArgumentException(
"attribute and value arrays must have same length");
}
if (attrs.length > 32) {
throw new IllegalArgumentException(
"cannot handle more than 32 attributes");
}
this.attrs = Arrays.asList(attrs);
this.values = initValues.clone();
}
@Override
protected void copyInto(AbstractAttributeSet destSet) {
FixedSet dest = (FixedSet) destSet;
dest.attrs = this.attrs;
dest.values = this.values.clone();
dest.readOnly = this.readOnly;
}
@Override
public List<Attribute<?>> getAttributes() {
return attrs;
}
@Override
public <V> V getValue(Attribute<V> attr) {
int index = attrs.indexOf(attr);
if (index < 0) {
return null;
} else {
@SuppressWarnings("unchecked")
V ret = (V) values[index];
return ret;
}
}
@Override
public boolean isReadOnly(Attribute<?> attr) {
int index = attrs.indexOf(attr);
if (index < 0)
return true;
return isReadOnly(index);
}
private boolean isReadOnly(int index) {
return ((readOnly >> index) & 1) == 1;
}
@Override
public void setReadOnly(Attribute<?> attr, boolean value) {
int index = attrs.indexOf(attr);
if (index < 0)
throw new IllegalArgumentException("attribute "
+ attr.getName() + " absent");
if (value)
readOnly |= (1 << index);
else
readOnly &= ~(1 << index);
}
@Override
public <V> void setValue(Attribute<V> attr, V value) {
int index = attrs.indexOf(attr);
if (index < 0)
throw new IllegalArgumentException("attribute "
+ attr.getName() + " absent");
if (isReadOnly(index))
throw new IllegalArgumentException("read only");
// if (isAttrLabel(attr)) {
// String val = (String) value;
// if (!SyntaxChecker.isVariableNameAcceptable(val)) {
// SyntaxChecker.showNonAcceptableNameMessage();
// values[index] = "";
// } else {
// values[index] = val;
// }
// } else {
@SuppressWarnings("unchecked")
V oldvalue = (V) values[index];
values[index] = value;
// }
fireAttributeValueChanged(attr, value, oldvalue);
}
}
private static class SingletonSet extends AbstractAttributeSet {
private List<Attribute<?>> attrs;
private Object value;
private boolean readOnly = false;
SingletonSet(Attribute<?> attr, Object initValue) {
this.attrs = new ArrayList<Attribute<?>>(1);
this.attrs.add(attr);
this.value = initValue;
}
@Override
protected void copyInto(AbstractAttributeSet destSet) {
SingletonSet dest = (SingletonSet) destSet;
dest.attrs = this.attrs;
dest.value = this.value;
dest.readOnly = this.readOnly;
}
@Override
public List<Attribute<?>> getAttributes() {
return attrs;
}
@Override
public <V> V getValue(Attribute<V> attr) {
int index = attrs.indexOf(attr);
@SuppressWarnings("unchecked")
V ret = (V) (index >= 0 ? value : null);
return ret;
}
@Override
public boolean isReadOnly(Attribute<?> attr) {
return readOnly;
}
@Override
public void setReadOnly(Attribute<?> attr, boolean value) {
int index = attrs.indexOf(attr);
if (index < 0)
throw new IllegalArgumentException("attribute "
+ attr.getName() + " absent");
readOnly = value;
}
@Override
public <V> void setValue(Attribute<V> attr, V value) {
int index = attrs.indexOf(attr);
if (index < 0)
throw new IllegalArgumentException("attribute "
+ attr.getName() + " absent");
if (readOnly)
throw new IllegalArgumentException("read only");
@SuppressWarnings("unchecked")
V oldvalue = (V) this.value;
this.value = value;
fireAttributeValueChanged(attr, value, oldvalue);
}
}
public static void copy(AttributeSet src, AttributeSet dst) {
if (src == null || src.getAttributes() == null)
return;
for (Attribute<?> attr : src.getAttributes()) {
@SuppressWarnings("unchecked")
Attribute<Object> attrObj = (Attribute<Object>) attr;
Object value = src.getValue(attr);
dst.setValue(attrObj, value);
}
}
public static AttributeSet fixedSet(Attribute<?>[] attrs,
Object[] initValues) {
if (attrs.length > 1) {
return new FixedSet(attrs, initValues);
} else if (attrs.length == 1) {
return new SingletonSet(attrs[0], initValues[0]);
} else {
return EMPTY;
}
}
public static <V> AttributeSet fixedSet(Attribute<V> attr, V initValue) {
return new SingletonSet(attr, initValue);
}
public static final AttributeSet EMPTY = new AttributeSet() {
public void addAttributeListener(AttributeListener l) {
}
@Override
public Object clone() {
return this;
}
public boolean containsAttribute(Attribute<?> attr) {
return false;
}
public Attribute<?> getAttribute(String name) {
return null;
}
public List<Attribute<?>> getAttributes() {
return Collections.emptyList();
}
public <V> V getValue(Attribute<V> attr) {
return null;
}
public boolean isReadOnly(Attribute<?> attr) {
return true;
}
public boolean isToSave(Attribute<?> attr) {
return true;
}
public void removeAttributeListener(AttributeListener l) {
}
public void setReadOnly(Attribute<?> attr, boolean value) {
throw new UnsupportedOperationException();
}
public <V> void setValue(Attribute<V> attr, V value) {
}
};
private AttributeSets() {
}
}