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

com.twelvemonkeys.servlet.AbstractServletMapAdapter Maven / Gradle / Ivy

There is a newer version: 2.3
Show newest version
package com.twelvemonkeys.servlet;

import com.twelvemonkeys.util.CollectionUtil;

import java.util.*;

/**
 * AbstractServletMapAdapter
 *
 * @author Harald Kuhr
 * @author last modified by $Author: haku $
 * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/main/java/com/twelvemonkeys/servlet/AbstractServletMapAdapter.java#1 $
 */
abstract class AbstractServletMapAdapter extends AbstractMap> {
    // TODO: This map is now a little too lazy.. Should cache entries too (instead?) !

    private final static List NULL_LIST = new ArrayList();

    private transient Map> mCache = new HashMap>();
    private transient int mSize = -1;
    private transient AbstractSet>> mEntries;

    protected abstract Iterator keysImpl();

    protected abstract Iterator valuesImpl(String pName);

    @Override
    public List get(Object pKey) {
        if (pKey instanceof String) {
            return getValues((String) pKey);
        }
        return null;
    }

    private List getValues(String pName) {
        List values = mCache.get(pName);

        if (values == null) {
            //noinspection unchecked
            Iterator headers = valuesImpl(pName);
            if (headers == null) {
                mCache.put(pName, NULL_LIST);
            }
            else {
                values = toList(headers);
                mCache.put(pName, values);
            }
        }

        return values == NULL_LIST ? null : values;
    }

    private static List toList(final Iterator pValues) {
        List list = new ArrayList();
        CollectionUtil.addAll(list, pValues);
        return Collections.unmodifiableList(list);
    }

    @Override
    public int size() {
        if (mSize == -1) {
            computeSize();
        }
        return mSize;
    }

    private void computeSize() {
        Iterator names = keysImpl();
        mSize = 0;
        for (;names.hasNext(); names.next()) {
            mSize++;
        }
    }

    public Set>> entrySet() {
        if (mEntries == null) {
            mEntries = new AbstractSet>>() {
                public Iterator>> iterator() {
                    return new Iterator>>() {
                        Iterator mHeaderNames = keysImpl();

                        public boolean hasNext() {
                            return mHeaderNames.hasNext();
                        }

                        public Entry> next() {
                            // TODO: Replace with cached lookup
                            return new HeaderEntry(mHeaderNames.next());
                        }

                        public void remove() {
                            throw new UnsupportedOperationException();
                        }
                    };
                }

                public int size() {
                    return AbstractServletMapAdapter.this.size();
                }
            };
        }

        return mEntries;
    }

    private class HeaderEntry implements Entry> {
        String mHeaderName;

        public HeaderEntry(String pHeaderName) {
            mHeaderName = pHeaderName;
        }

        public String getKey() {
            return mHeaderName;
        }

        public List getValue() {
            return get(mHeaderName);
        }

        public List setValue(List pValue) {
            throw new UnsupportedOperationException();
        }

        @Override
        public int hashCode() {
            List value;
            return (mHeaderName   == null ? 0 :   mHeaderName.hashCode()) ^
                   ((value = getValue()) == null ? 0 : value.hashCode());
        }

        @Override
        public boolean equals(Object pOther) {
            if (pOther == this) {
                return true;
            }

            if (pOther instanceof Entry) {
                Entry other = (Entry) pOther;
                return ((other.getKey() == null && getKey() == null) ||
                        (getKey() != null && getKey().equals(other.getKey()))) &&
                        ((other.getValue() == null && getValue() == null) ||
                                (getValue() != null && getValue().equals(other.getValue())));
            }

            return false;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy