com.strobel.assembler.Collection Maven / Gradle / Ivy
/*
* Collection.java
*
* Copyright (c) 2013 Mike Strobel
*
* This source code is based on Mono.Cecil from Jb Evain, Copyright (c) Jb Evain;
* and ILSpy/ICSharpCode from SharpDevelop, Copyright (c) AlphaSierraPapa.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0.
* A copy of the license can be found in the License.html file at the root of this distribution.
* By using this source code in any fashion, you are agreeing to be bound by the terms of the
* Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*/
package com.strobel.assembler;
import com.strobel.core.IFreezable;
import com.strobel.core.VerifyArgument;
import java.util.AbstractList;
import java.util.ArrayList;
/**
* @author Mike Strobel
*/
public class Collection extends AbstractList implements IFreezable {
private final ArrayList _items;
private boolean _isFrozen;
public Collection() {
_items = new ArrayList<>();
}
@Override
public final int size() {
return _items.size();
}
@Override
public final E get(final int index) {
return _items.get(index);
}
@Override
public final boolean add(final E e) {
verifyNotFrozen();
add(size(), e);
return true;
}
@Override
public final E set(final int index, final E element) {
verifyNotFrozen();
VerifyArgument.notNull(element, "element");
beforeSet(index, element);
return _items.set(index, element);
}
@Override
public void add(final int index, final E element) {
verifyNotFrozen();
VerifyArgument.notNull(element, "element");
addCore(index, element);
}
protected final void addCore(final int index, final E element) {
final boolean append = index == size();
_items.add(index, element);
afterAdd(index, element, append);
}
@Override
public final E remove(final int index) {
verifyNotFrozen();
final E e = _items.remove(index);
if (e != null) {
afterRemove(index, e);
}
return e;
}
@Override
public final void clear() {
verifyNotFrozen();
beforeClear();
_items.clear();
}
@Override
public final boolean remove(final Object o) {
verifyNotFrozen();
@SuppressWarnings("SuspiciousMethodCalls")
final int index = _items.indexOf(o);
return index >= 0 &&
remove(index) != null;
}
protected void afterAdd(final int index, final E e, final boolean appended) {}
protected void beforeSet(final int index, final E e) {}
protected void afterRemove(final int index, final E e) {}
protected void beforeClear() {}
//
@Override
public boolean canFreeze() {
return !isFrozen();
}
@Override
public final boolean isFrozen() {
return _isFrozen;
}
@Override
public final void freeze() {
freeze(true);
}
public final void freeze(final boolean freezeContents) {
if (!canFreeze()) {
throw new IllegalStateException(
"Collection cannot be frozen. Be sure to check canFreeze() before calling " +
"freeze(), or use the tryFreeze() method instead."
);
}
freezeCore(freezeContents);
_isFrozen = true;
}
protected void freezeCore(final boolean freezeContents) {
if (freezeContents) {
for (final E item : _items) {
if (item instanceof IFreezable) {
((IFreezable) item).freezeIfUnfrozen();
}
}
}
}
protected final void verifyNotFrozen() {
if (isFrozen()) {
throw new IllegalStateException("Frozen collections cannot be modified.");
}
}
protected final void verifyFrozen() {
if (!isFrozen()) {
throw new IllegalStateException(
"Collection must be frozen before performing this operation."
);
}
}
@Override
public final boolean tryFreeze() {
if (!canFreeze()) {
return false;
}
try {
freeze();
return true;
}
catch (final Throwable t) {
return false;
}
}
@Override
public final void freezeIfUnfrozen() throws IllegalStateException {
if (isFrozen()) {
return;
}
freeze();
}
//
}