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

com.google.web.bindery.autobean.shared.impl.SplittableList Maven / Gradle / Ivy

/*
 * Copyright 2011 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.web.bindery.autobean.shared.impl;

import com.google.web.bindery.autobean.shared.Splittable;
import com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.Coder;
import com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.EncodeState;

import java.util.AbstractList;

/**
 * A list implementation that lazily reifies its constituent elements.
 * 
 * @param  the element type
 */
public class SplittableList extends AbstractList implements HasSplittable {
  static  Q reify(EncodeState state, Splittable data, int index, Coder coder) {
    if (data.isNull(index)) {
      return null;
    }
    @SuppressWarnings("unchecked")
    Q toReturn = (Q) coder.decode(state, data.get(index));
    data.setReified(String.valueOf(index), toReturn);
    return toReturn;
  }

  static void set(EncodeState state, Splittable data, int index, Coder coder, Object value) {
    data.setReified(String.valueOf(index), value);
    if (value == null) {
      Splittable.NULL.assign(data, index);
      return;
    }
    Splittable backing = coder.extractSplittable(state, value);
    if (backing == null) {
      /*
       * External data type, such as an ArrayList or a concrete implementation
       * of a setter's interface type. This means that a slow serialization pass
       * is necessary.
       */
      data.setReified(AbstractAutoBean.UNSPLITTABLE_VALUES_KEY, true);
    } else {
      backing.assign(data, index);
    }
  }

  private Splittable data;
  private final Coder elementCoder;
  private final EncodeState state;

  public SplittableList(Splittable data, Coder elementCoder, EncodeState state) {
    assert data.isIndexed() : "Expecting indexed data";
    this.data = data;
    this.elementCoder = elementCoder;
    this.state = state;
  }

  @Override
  public void add(int index, E element) {
    set(state, data, index, elementCoder, element);
  }

  @Override
  public E get(int index) {
    if (data.isReified(String.valueOf(index))) {
      @SuppressWarnings("unchecked")
      E toReturn = (E) data.getReified(String.valueOf(index));
      return toReturn;
    }
    // javac generics bug
    return SplittableList. reify(state, data, index, elementCoder);
  }

  public Splittable getSplittable() {
    return data;
  }

  @Override
  public E remove(int index) {
    E toReturn = get(index);
    // XXX This is terrible, use Array.splice
    int newSize = data.size() - 1;
    for (int i = index; i < newSize; i++) {
      data.get(i + 1).assign(data, i);
      data.setReified(String.valueOf(i), data.getReified(String.valueOf(i + 1)));
    }
    data.setSize(newSize);
    return toReturn;
  }

  @Override
  public E set(int index, E element) {
    E previous = get(index);
    set(state, data, index, elementCoder, element);
    return previous;
  }

  @Override
  public int size() {
    return data.size();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy