001    // Copyright 2008 Waterken Inc. under the terms of the MIT X license found at
002    // http://www.opensource.org/licenses/mit-license.html
003    package org.ref_send.scope;
004    
005    import java.io.Serializable;
006    
007    import org.joe_e.Selfless;
008    import org.joe_e.array.ConstArray;
009    
010    /**
011     * A <code>{ name : value }</code> record.
012     * @param <T> nominal type
013     */
014    public class
015    Scope<T> implements Selfless, Serializable {
016        static private final long serialVersionUID = 1L;
017    
018        /**
019         * structural type
020         */
021        public final Layout<T> meta;
022    
023        /**
024         * each corresponding value
025         */
026        public final ConstArray<?> values;
027    
028        Scope(final Layout<T> meta, final ConstArray<?> values) {
029            if (meta.names.length()!=values.length()){throw new RuntimeException();}
030    
031            this.meta = meta;
032            this.values = values;
033        }
034        
035        /**
036         * Constructs an instance.
037         * @param meta      {@link #meta}
038         * @param values    {@link #values}
039         */
040        static public <T> Scope<T>
041        make(final Layout<T> meta, final ConstArray<?> values) {
042            return new Scope<T>(meta, values);
043        }
044    
045        // java.lang.Object interface
046    
047        /**
048         * Is the given object equal to this one?
049         * @param o compared to object
050         * @return {@code true} if equal, else {@code false}
051         */
052        public boolean
053        equals(final Object o) {
054            return o instanceof Scope &&
055                   values.equals(((Scope<?>)o).values) &&
056                   meta.names.equals(((Scope<?>)o).meta.names);
057        }
058    
059        /**
060         * Calculates the hash code.
061         */
062        public int
063        hashCode() { return 0x4EF5C09E + meta.hashCode() + values.hashCode(); }
064    
065        // org.ref_send.scope.Scope interface
066    
067        /**
068         * Gets the corresponding value.
069         * @param name  name to lookup
070         * @return corresponding value, or {@code null} if none
071         */
072        public <R> R
073        get(final String name) {
074            final int i = meta.find(name);
075            if (-1 == i) { return null; }
076            final @SuppressWarnings("unchecked") R r = (R)values.get(i);
077            return r;
078        }
079    }