Package com.caucho.quercus.env

Source Code of com.caucho.quercus.env.JavaMapAdapter$MapIterator

/*
* Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT.  See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
*   Free Software Foundation, Inc.
*   59 Temple Place, Suite 330
*   Boston, MA 02111-1307  USA
*
* @author Scott Ferguson
*/

package com.caucho.quercus.env;

import com.caucho.quercus.QuercusRuntimeException;
import com.caucho.quercus.program.JavaClassDef;

import java.util.*;

/**
* Represents a marshalled Map argument.
*/
public class JavaMapAdapter<K,V>
  extends JavaAdapter<Map<K,V>>
{
  /**
   *
   */
  private static final long serialVersionUID = 1L;

  private Map<K,V> _map;
 
  private long _nextAvailableIndex;

  public JavaMapAdapter(Env env, Map<K,V> map)
  {
    this(env, map, env.getJavaClassDefinition(map.getClass()));
  }
 
  public JavaMapAdapter(Env env, Map<K,V> map, JavaClassDef def)
  {
    super(env, map, def);
    _map = map;
   
    updateNextAvailableIndex();
  }

  /**
   * Clears the array
   */
  @Override
  public void clear()
  {
    _map.clear();
   
    _nextAvailableIndex = 0;
  }

  public int size()
  {
    return _map.size();
  }

  /**
   * Converts to a java object.
   */
  @SuppressWarnings("unchecked")
  @Override
  public <T> T toJavaObject(Env env, Class<T> type)
  {
    if (type.isAssignableFrom(_map.getClass())) {
      return (T)_map;
    }
    else {
      env.warning(L.l("Can't assign {0} to {1}",
              _map.getClass().getName(), type.getName()));
   
      return null;
    }
  }

  /**
   * Copy for assignment.
   */
  @Override
  public Value copy()
  {
    try {
      return new JavaMapAdapter<K,V>(getEnv(), _map, getClassDef());
    }
    catch (Exception e) {
      throw new QuercusRuntimeException(e);
    }
  }

  /**
   * Copy for serialization
   */
  @Override
  public Value copy(Env env, IdentityHashMap<Value,Value> map)
  {
    return new JavaMapAdapter<K,V>(env, _map, getClassDef());
  }
 
  /**
   * Returns the size.
   */
  @Override
  public int getSize()
  {
    return size();
  }

  /**
   * Gets a new value.
   */
  @Override
  public Value get(Value key)
  {
    Object obj = _map.get(key.toJavaObject());
   
    if (obj != null)
      return wrapJava(_map.get(key.toJavaObject()));
    else
      return UnsetValue.UNSET;
  }
 
  /**
   * Removes a value.
   */
  @Override
  public Value remove(Value key)
  {
    updateNextAvailableIndex();

    if (key.isLongConvertible() || key instanceof BooleanValue) {
    //if (key instanceof LongValue) {
      long pos = key.toLong();
     
      Object value = _map.remove(Long.valueOf(pos));
     
      if (value != null) {
        if (pos + 1 == _nextAvailableIndex)
          updateNextAvailableIndex();
       
        return wrapJava(value);
      }
    }
    else {
      Object value = _map.remove(key.toJavaObject());
     
      if (value != null)
        return wrapJava(value);
    }
   
    return UnsetValue.UNSET;
  }
 
  /**
   * Creatse a tail index.
   */
  @Override
  public Value createTailKey()
  {
    updateNextAvailableIndex();
    return LongValue.create(_nextAvailableIndex);
  }
 
  /**
   * Adds a new value.
   */
  @Override
  @SuppressWarnings("unchecked")
  public Value putImpl(Value key, Value value)
  {
    K keyObject;
   
    if (key.isLongConvertible() || key instanceof BooleanValue) {
      keyObject = (K)Long.valueOf(key.toLong());
    }
    else {
      keyObject = (K)key.toJavaObject();
    }

    Value val = wrapJava(_map.put(keyObject, (V)value.toJavaObject()));

    updateNextAvailableIndex(keyObject);
   
    return val;
  }

  /**
   * Returns the corresponding valeu if this array contains the given key
   *
   * @param key  the key to search for in the array
   *
   * @return the value if it is found in the array, NULL otherwise
   */
  public Value containsKey(Value key)
  {
    return BooleanValue.create(_map.containsKey(key.toJavaObject()));
  }
 
  @Override
  public Iterator<Value> getKeyIterator(Env env)
  {
    return new KeyIterator();
  }

  @Override
  public Iterator<Value> getValueIterator(Env env)
  {
    return new ValueIterator();
  }
 
  @Override
  public Iterator<Map.Entry<Value, Value>> getIterator(Env env)
  {
    return new MapIterator();
  }

  /**
   * Returns a set of all the of the entries.
   */
  @Override
  public Set<Map.Entry<Value,Value>> entrySet()
  {
    return new MapSet();
  }
 
  /**
   * Returns a collection of the values.
   */
  @Override
  @SuppressWarnings("unchecked")
  public Set<Map.Entry> objectEntrySet()
  {
    return (Set<Map.Entry>)_map.entrySet();
  }

  /**
   * Returns a collection of the values.
   */
  @Override
  public Collection<Value> values()
  {
    return new ValueCollection();
  }

  /**
   * Updates _nextAvailableIndex on a remove of the highest value
   */
  private void updateNextAvailableIndex()
  {
    _nextAvailableIndex = 0;

    for (Object key : _map.keySet()) {
      updateNextAvailableIndex(key);
    }
  }
 
  /**
   * Updates _nextAvailableIndex.
   */
  private void updateNextAvailableIndex(Object objectKey)
  {
    if (objectKey instanceof Long) {
      long key = ((Long)objectKey).longValue();
   
      if (_nextAvailableIndex <= key)
        _nextAvailableIndex = key + 1;
    }
  }

  public class MapSet
    extends AbstractSet<Map.Entry<Value,Value>>
  {
    MapSet()
    {
    }

    @Override
    public int size()
    {
      return getSize();
    }

    @Override
    public Iterator<Map.Entry<Value,Value>> iterator()
    {
      return new MapIterator();
    }
  }

  public class MapIterator
    implements Iterator<Map.Entry<Value,Value>>
  {
    private Iterator<Map.Entry<K,V>> _iterator;

    public MapIterator()
    {
      _iterator = _map.entrySet().iterator();
    }

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

    public Map.Entry<Value,Value> next()
    {
      Map.Entry entry = _iterator.next();
     
      Value key = wrapJava(entry.getKey());
      Value value = wrapJava(entry.getValue());

      return new ArrayValue.Entry(key, value);
    }

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

  public class ValueCollection
    extends AbstractCollection<Value>
  {
    ValueCollection()
    {
    }

    @Override
    public int size()
    {
      return getSize();
    }

    @Override
    public Iterator<Value> iterator()
    {
      return new ValueIterator();
    }
  }

  public class ValueIterator
    implements Iterator<Value>
  {
    private Iterator _iterator;

    public ValueIterator()
    {
      _iterator = _map.values().iterator();
    }

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

    public Value next()
    {
      return wrapJava(_iterator.next());
    }

    public void remove()
    {
      throw new UnsupportedOperationException();
    }
  }
 
  public class KeyIterator
    implements Iterator<Value>
  {
    private Iterator _iterator;

    public KeyIterator()
    {
      _iterator = _map.keySet().iterator();
    }

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

    public Value next()
    {
      return wrapJava(_iterator.next());
    }

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

}
TOP

Related Classes of com.caucho.quercus.env.JavaMapAdapter$MapIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.