001package com.hammurapi.extract;
002
003import java.util.Collections;
004import java.util.Map;
005import java.util.Set;
006
007import com.hammurapi.extract.ComparisonResult.Type;
008
009/**
010 * Extracts value at index.
011 * @author Pavel Vlasov.
012 *
013 * @param <T>
014 */
015public class IndexedExtractor<T, C> implements Extractor<T, T, C>, Mappable<T,T,C> {
016        
017        private int idx;
018
019        public IndexedExtractor(int idx) {
020                this.idx = idx;
021        }
022
023        public Set<Integer> parameterIndices() {
024                return Collections.singleton(idx);
025        }
026
027        @Override
028        public int hashCode() {
029                final int prime = 31;
030                int result = 1;
031                result = prime * result + idx;
032                return result;
033        }
034
035        @SuppressWarnings("unchecked")
036        @Override
037        public boolean equals(Object obj) {
038                if (this == obj)
039                        return true;
040                if (obj == null)
041                        return false;
042                if (getClass() != obj.getClass())
043                        return false;
044                IndexedExtractor other = (IndexedExtractor) obj;
045                if (idx != other.idx)
046                        return false;
047                return true;
048        }
049
050
051        public T extract(C context, Map<C, Map<Extractor<T, ? super T, C>, ? super T>> cache, T... obj) {
052                return obj[idx];
053        }
054
055        public boolean isContextDependent() {
056                return false;
057        }
058
059        @Override
060        public String toString() {
061                return "IndexedExtractor [idx=" + idx + "]";
062        }
063
064        @Override
065        public ComparisonResult compareTo(Extractor<T, T, C> other) {
066                if (other instanceof IndexedExtractor) {
067                        int otherIdx = ((IndexedExtractor<T, C>) other).idx;
068                        if (otherIdx==idx) {
069                                return ComparisonResult.EQUAL_NM;
070                        }
071                        int[] map = new int[otherIdx+1];
072                        map[otherIdx]= idx;
073                        return new ComparisonResult(Type.EQUAL, map);
074                }
075                return ComparisonResult.NOT_EQUAL_NM;
076        }                       
077
078        @Override
079        public double getCost() {
080                return 0;
081        }
082
083        @Override
084        public Extractor<T, T, C> map(int[] map) {
085                for (int i=0; i<map.length; ++i) {
086                        if (map[i]==idx) {
087                                return new IndexedExtractor<T, C>(i);
088                        }
089                }
090                return null;
091        }
092        
093        public int getIndex() {
094                return idx;
095        }
096}