All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
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.
cz.vutbr.web.domassign.QuadrupleMapNodeData Maven / Gradle / Ivy
package cz.vutbr.web.domassign;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import cz.vutbr.web.css.CSSProperty;
import cz.vutbr.web.css.Declaration;
import cz.vutbr.web.css.NodeData;
import cz.vutbr.web.css.Term;
import cz.vutbr.web.csskit.OutputUtil;
/**
* Implementation of NodeData by four distinct HashMaps. According to tests,
* it is about 25% faster then SingleDataMap when retrieving values and inheriting
* but occupies up to 100% more memory.
*
* @author kapy
*
*/
public class QuadrupleMapNodeData extends BaseNodeDataImpl {
private static final int COMMON_DECLARATION_SIZE = 7;
private Map propertiesOwn;
private Map propertiesInh;
private Map> valuesOwn;
private Map> valuesInh;
private Map sourcesOwn;
private Map sourcesInh;
public QuadrupleMapNodeData() {
this.propertiesOwn = new HashMap(css.getTotalProperties(), 1.0f);
this.propertiesInh = new HashMap(css.getTotalProperties(), 1.0f);
this.valuesOwn = new HashMap>(css.getTotalProperties(), 1.0f);
this.valuesInh = new HashMap>(css.getTotalProperties(), 1.0f);
this.sourcesOwn = new HashMap(css.getTotalProperties(), 1.0f);
this.sourcesInh = new HashMap(css.getTotalProperties(), 1.0f);
}
public T getProperty(String name) {
return this.getProperty(name, true);
}
public T getProperty(String name, boolean includeInherited) {
CSSProperty inh = null, tmp = null;
if(includeInherited)
inh = propertiesInh.get(name);
tmp = propertiesOwn.get(name);
if(tmp==null) tmp = inh;
// this will cast to inferred type
// if there is no inferred type, cast to CSSProperty is safe
// otherwise the possibility having wrong left side of assignment
// is roughly the same as use wrong dynamic class cast
@SuppressWarnings("unchecked")
T retval = (T) tmp;
return retval;
}
public Term> getValue(String name, boolean includeInherited) {
if (includeInherited) {
final Term> own = valuesOwn.get(name);
if (own != null)
return own;
else
{
Term> inherited = null;
if (!propertiesOwn.containsKey(name))
inherited = valuesInh.get(name);
return inherited;
}
}
else
return valuesOwn.get(name);
}
public > T getValue(Class clazz, String name, boolean includeInherited) {
if(includeInherited) {
final T own = clazz.cast(valuesOwn.get(name));
if (own != null)
return own;
else
{
T inherited = null;
if (!propertiesOwn.containsKey(name))
inherited = clazz.cast(valuesInh.get(name));
return inherited;
}
}
else
return clazz.cast(valuesOwn.get(name));
}
public > T getValue(Class clazz, String name) {
return getValue(clazz, name, true);
}
public String getAsString(String name, boolean includeInherited) {
boolean usedInherited = false;
CSSProperty prop = propertiesOwn.get(name);
if (prop == null && includeInherited) {
prop = propertiesInh.get(name);
usedInherited = true;
}
if (prop == null)
return null;
else if (!prop.toString().isEmpty())
return prop.toString();
else {
Term> val = usedInherited ? valuesInh.get(name) : valuesOwn.get(name);
return (val == null) ? null : val.toString();
}
}
public NodeData push(Declaration d) {
Map properties =
new HashMap(COMMON_DECLARATION_SIZE);
Map> terms =
new HashMap>(COMMON_DECLARATION_SIZE);
boolean result = transformer.parseDeclaration(d, properties, terms);
// in case of false do not insert anything
if(!result) return this;
//set the sources and store the properties
for(Entry entry: properties.entrySet()) {
propertiesOwn.put(entry.getKey(), entry.getValue());
sourcesOwn.put(entry.getKey(), d);
}
// remove operators from terms and store the values
for(Entry> entry: terms.entrySet()) {
Term> t = entry.getValue();
if (t.getOperator() != null)
t = t.shallowClone().setOperator(null);
valuesOwn.put(entry.getKey(), t);
}
return this;
}
public NodeData inheritFrom(NodeData parent) throws ClassCastException {
if(parent==null)
return this;
if(!(parent instanceof QuadrupleMapNodeData))
throw new ClassCastException(
"Cant't inherit from NodeData different from "
+ this.getClass().getName() + "("+ parent.getClass().getName()+")");
QuadrupleMapNodeData nd = (QuadrupleMapNodeData) parent;
// inherit values
for(String key:nd.propertiesInh.keySet()) {
CSSProperty value = nd.propertiesInh.get(key);
CSSProperty cur = this.propertiesOwn.get(key);
if(value.inherited() || (cur != null && cur.equalsInherit())) {
this.propertiesInh.put(key, value);
// remove old value to be sure
this.valuesInh.remove(key);
Term> term = nd.valuesInh.get(key);
if(term!=null) this.valuesInh.put(key, term);
Declaration src = nd.sourcesInh.get(key);
if (src != null) this.sourcesInh.put(key, src);
}
}
for(String key:nd.propertiesOwn.keySet()) {
CSSProperty value = nd.propertiesOwn.get(key);
CSSProperty cur = this.propertiesOwn.get(key);
if(value.inherited() || (cur != null && cur.equalsInherit())) {
this.propertiesInh.put(key, value);
// remove old value to be sure
this.valuesInh.remove(key);
Term> term = nd.valuesOwn.get(key);
if(term!=null) this.valuesInh.put(key, term);
Declaration src = nd.sourcesOwn.get(key);
if(src!=null) this.sourcesInh.put(key, src);
}
}
return this;
}
public NodeData concretize() {
// inherited firstly, replace them with defaults
for(String key: propertiesInh.keySet()) {
CSSProperty p = propertiesInh.get(key);
if(p.equalsInherit()) {
propertiesInh.put(key, css.getDefaultProperty(key));
Term> value = css.getDefaultValue(key);
if(value!=null) valuesInh.put(key, value);
}
}
// own after, replace them with inherited or default
for(String key:propertiesOwn.keySet()) {
CSSProperty p = propertiesOwn.get(key);
if(p.equalsInherit()) {
CSSProperty rp = propertiesInh.get(key);
if(rp==null) rp = css.getDefaultProperty(key);
propertiesOwn.put(key, rp);
Term> value = valuesInh.get(key);
if(value==null) value = css.getDefaultValue(key);
if(value!=null) valuesOwn.put(key, value);
Declaration source = sourcesInh.get(key);
if(source!=null) sourcesOwn.put(key, source);
} else if (p.equalsInitial()) {
CSSProperty rp = css.getDefaultProperty(key);
propertiesOwn.put(key, rp);
Term> value = css.getDefaultValue(key);
if (value != null)
valuesOwn.put(key, value);
} else if (p.equalsUnset()) {
if (p.inherited()) {
CSSProperty rp = propertiesInh.get(key);
if(rp==null) rp = css.getDefaultProperty(key);
propertiesOwn.put(key, rp);
Term> value = valuesInh.get(key);
if(value==null) value = css.getDefaultValue(key);
if(value!=null) valuesOwn.put(key, value);
} else {
CSSProperty rp = css.getDefaultProperty(key);
propertiesOwn.put(key, rp);
Term> value = css.getDefaultValue(key);
if (value != null)
valuesOwn.put(key, value);
}
}
}
return this;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Set tmp = new LinkedHashSet();
tmp.addAll(propertiesInh.keySet());
tmp.addAll(propertiesOwn.keySet());
List keys = new ArrayList(tmp);
Collections.sort(keys);
for(String key:keys) {
// always use own value if exists
CSSProperty prop = propertiesOwn.get(key);
if(prop==null) prop = propertiesInh.get(key);
Term> value = valuesOwn.get(key);
if(value==null) value = valuesInh.get(key);
sb.append(key).append(OutputUtil.PROPERTY_OPENING);
if(value!=null) sb.append(value.toString());
else sb.append(prop.toString());
sb.append(OutputUtil.PROPERTY_CLOSING);
}
return sb.toString();
}
@Override
public Collection getPropertyNames()
{
final Set props = new LinkedHashSet();
props.addAll(propertiesInh.keySet());
props.addAll(propertiesOwn.keySet());
final List keys = new ArrayList(props);
Collections.sort(keys);
return keys;
}
@Override
public Declaration getSourceDeclaration(String name)
{
return sourcesOwn.get(name);
}
@Override
public Declaration getSourceDeclaration(String name, boolean includeInherited)
{
Declaration ret = sourcesOwn.get(name);
if (includeInherited && ret == null)
ret = sourcesInh.get(name);
return ret;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((propertiesInh == null) ? 0 : propertiesInh.hashCode());
result = prime * result
+ ((propertiesOwn == null) ? 0 : propertiesOwn.hashCode());
result = prime * result
+ ((valuesInh == null) ? 0 : valuesInh.hashCode());
result = prime * result
+ ((valuesOwn == null) ? 0 : valuesOwn.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof QuadrupleMapNodeData))
return false;
QuadrupleMapNodeData other = (QuadrupleMapNodeData) obj;
if (propertiesInh == null) {
if (other.propertiesInh != null)
return false;
} else if (!propertiesInh.equals(other.propertiesInh))
return false;
if (propertiesOwn == null) {
if (other.propertiesOwn != null)
return false;
} else if (!propertiesOwn.equals(other.propertiesOwn))
return false;
if (valuesInh == null) {
if (other.valuesInh != null)
return false;
} else if (!valuesInh.equals(other.valuesInh))
return false;
if (valuesOwn == null) {
if (other.valuesOwn != null)
return false;
} else if (!valuesOwn.equals(other.valuesOwn))
return false;
return true;
}
}