All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cz.vutbr.web.domassign.QuadrupleMapNodeData Maven / Gradle / Ivy

Go to download

jStyleParser is a CSS parser written in Java. It has its own application interface that is designed to allow an efficient CSS processing in Java and mapping the values to the Java data types. It parses CSS 2.1 style sheets into structures that can be efficiently assigned to DOM elements. It is intended be the primary CSS parser for the CSSBox library. While handling errors, it is user agent conforming according to the CSS specification.

The newest version!
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;
	}

	
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy