/*
* Copyright 2008-2016 the original author or authors.
*
* 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.nominanuda.zen.obj;
import static com.nominanuda.zen.obj.JsonSerializer.JSON_SERIALIZER;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import com.nominanuda.zen.seq.ReadOnlyCollection;
import com.nominanuda.zen.stereotype.Value;
public class ArrImpl implements Arr {
private final List<Any> members;
public ArrImpl(BinRange range, List<Any> members) {
this(members);
}
public ArrImpl() {
this(new LinkedList<>());
}
private ArrImpl(List<Any> members) {
this.members = members;
}
@Override
public int indexOf(Object v, int start) {
int len = size();
for(int i = start; i < len; i++) {
if(Value.nullSafeEquals(v, members.get(i))) {
return i;
}
}
return -1;
}
@Override
public Iterator<Object> iterator() {
final Iterator<Any> i = members.iterator();
return new Iterator<Object>() {
public Object next() {
final Any e = i.next();
return e.toJavaObjModel();
}
@Override
public boolean hasNext() {
return i.hasNext();
}
};
}
ReadOnlyCollection<? extends Any> members() {
return ReadOnlyCollection.wrap(members);
}
@SuppressWarnings("unchecked")
@Override
public Object store(int idx, Object v) {
Any a = Any.toStruObjModel(v);
members.set(idx, a);
return v;
}
@Override
public Object fetch(int idx) {
Any a = fetchAny(idx);
return a.toJavaObjModel();
}
@Override
public Any fetchAny(int idx) {
Any a = members.get(idx);
return a == null ? Val.NULL : a;
}
@Override
public Object del(int idx) {
Any removed = members.remove(idx);
return removed == null ? null : removed.toJavaObjModel();
}
@Override
public <T> T push(T v) {
pushAny(Any.toStruObjModel(v));
return v;
}
@Override
public <T extends Any> T pushAny(T any) {
members.add(any);
return any;
}
@Override
public int len() {
return members.size();
}
/**
*
* @param arr
* @return true if all members are {@link Value#nullSafeEquals(Object, Object)} in the same iteration order
*/
@Override
public boolean equals(Object arr) {
if(!(arr instanceof Arr)) {
return false;
}
Arr other = (Arr)arr;
if(other.len() != size()) {
return false;
}
Iterator<? extends Any> otherItr = ((ArrImpl)other).members().iterator();
Iterator<? extends Any> thisItr = members().iterator();
while(thisItr.hasNext()/* && otherItr.hasNext() see size comparison above*/) {
if(! Value.nullSafeEquals(thisItr.next(), otherItr.next())) {
return false;
}
}
return true;
}
@Override
public Arr copy() {
ArrayList<Any> l = new ArrayList<>(size());
for(Any el : members) {
l.add(el.copy());
}
return new ArrImpl(l);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result += prime * size();
if(members.size() > 0) {
result += members.get(0).hashCode();
}
return result;
}
@Override
public JsonType getType() {
return JsonType.arr;
}
@Override
public Arr reset() {
members.clear();
return this;
}
@Override
public void sendTo(JixHandler sink) {
sink.startArr();
for(Any member : members) {
member.sendTo(sink);
}
sink.endArr();
}
@Override
public String toString() {
return JSON_SERIALIZER.toString(this);
}
@Override
public Obj newObj() {
return new ObjImpl();
}
@Override
public Arr newArr() {
return new ArrImpl();
}
@SuppressWarnings("unchecked")
@Override
public <T> TArr<T> newArr(Class<T> cl) {
return (TArr<T>)new ArrImpl();
}
@Override
public ListIterator<Object> listIterator() {
final ListIterator<Any> i = members.listIterator();
return new ListIterator<Object>() {
@Override
public boolean hasNext() {
return i.hasNext();
}
@Override
public Object next() {
final Any e = i.next();
return e.toJavaObjModel();
}
@Override
public boolean hasPrevious() {
return i.hasPrevious();
}
@Override
public Object previous() {
final Any e = i.previous();
return e.toJavaObjModel();
}
@Override
public int nextIndex() {
return i.nextIndex();
}
@Override
public int previousIndex() {
return i.previousIndex();
}
@Override
public void remove() {
i.remove();
}
@Override
public void set(Object e) {
Any a = Any.toStruObjModel(e);
i.set(a);
}
@Override
public void add(Object e) {
Any a = Any.toStruObjModel(e);
i.add(a);
}
};
}
}