Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.crashnote.external.config.impl.SimpleConfigList Maven / Gradle / Ivy
Go to download
Reports exceptions from Java apps on Appengine to crashnote.com
/**
* Copyright (C) 2011-2012 Typesafe Inc.
*/
package com.crashnote.external.config.impl;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import com.crashnote.external.config.ConfigException;
import com.crashnote.external.config.ConfigList;
import com.crashnote.external.config.ConfigOrigin;
import com.crashnote.external.config.ConfigRenderOptions;
import com.crashnote.external.config.ConfigValue;
import com.crashnote.external.config.ConfigValueType;
final class SimpleConfigList extends AbstractConfigValue implements ConfigList, Serializable {
private static final long serialVersionUID = 1L;
final private List value;
final private boolean resolved;
SimpleConfigList(final ConfigOrigin origin, final List value) {
this(origin, value, ResolveStatus
.fromValues(value));
}
SimpleConfigList(final ConfigOrigin origin, final List value,
final ResolveStatus status) {
super(origin);
this.value = value;
this.resolved = status == ResolveStatus.RESOLVED;
// kind of an expensive debug check (makes this constructor pointless)
if (status != ResolveStatus.fromValues(value))
throw new ConfigException.BugOrBroken(
"SimpleConfigList created with wrong resolve status: " + this);
}
@Override
public ConfigValueType valueType() {
return ConfigValueType.LIST;
}
@Override
public List unwrapped() {
final List list = new ArrayList();
for (final AbstractConfigValue v : value) {
list.add(v.unwrapped());
}
return list;
}
@Override
ResolveStatus resolveStatus() {
return ResolveStatus.fromBoolean(resolved);
}
private SimpleConfigList modify(final NoExceptionsModifier modifier, final ResolveStatus newResolveStatus) {
try {
return modifyMayThrow(modifier, newResolveStatus);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new ConfigException.BugOrBroken("unexpected checked exception", e);
}
}
private SimpleConfigList modifyMayThrow(final Modifier modifier, final ResolveStatus newResolveStatus)
throws Exception {
// lazy-create for optimization
List changed = null;
int i = 0;
for (final AbstractConfigValue v : value) {
final AbstractConfigValue modified = modifier.modifyChildMayThrow(null /* key */, v);
// lazy-create the new list if required
if (changed == null && modified != v) {
changed = new ArrayList();
for (int j = 0; j < i; ++j) {
changed.add(value.get(j));
}
}
// once the new list is created, all elements
// have to go in it. if modifyChild returned
// null, we drop that element.
if (changed != null && modified != null) {
changed.add(modified);
}
i += 1;
}
if (changed != null) {
return new SimpleConfigList(origin(), changed, newResolveStatus);
} else {
return this;
}
}
@Override
SimpleConfigList resolveSubstitutions(final ResolveContext context) throws NotPossibleToResolve {
if (resolved)
return this;
if (context.isRestrictedToChild()) {
// if a list restricts to a child path, then it has no child paths,
// so nothing to do.
return this;
} else {
try {
return modifyMayThrow(new Modifier() {
@Override
public AbstractConfigValue modifyChildMayThrow(final String key, final AbstractConfigValue v)
throws NotPossibleToResolve {
return context.resolve(v);
}
}, ResolveStatus.RESOLVED);
} catch (NotPossibleToResolve e) {
throw e;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new ConfigException.BugOrBroken("unexpected checked exception", e);
}
}
}
@Override
SimpleConfigList relativized(final Path prefix) {
return modify(new NoExceptionsModifier() {
@Override
public AbstractConfigValue modifyChild(final String key, final AbstractConfigValue v) {
return v.relativized(prefix);
}
}, resolveStatus());
}
@Override
protected boolean canEqual(final Object other) {
return other instanceof SimpleConfigList;
}
@Override
public boolean equals(final Object other) {
// note that "origin" is deliberately NOT part of equality
if (other instanceof SimpleConfigList) {
// optimization to avoid unwrapped() for two ConfigList
return canEqual(other) && value.equals(((SimpleConfigList) other).value);
} else {
return false;
}
}
@Override
public int hashCode() {
// note that "origin" is deliberately NOT part of equality
return value.hashCode();
}
@Override
protected void render(final StringBuilder sb, final int indent, final ConfigRenderOptions options) {
if (value.isEmpty()) {
sb.append("[]");
} else {
sb.append("[");
if (options.getFormatted())
sb.append('\n');
for (final AbstractConfigValue v : value) {
if (options.getOriginComments()) {
indent(sb, indent + 1, options);
sb.append("# ");
sb.append(v.origin().description());
sb.append("\n");
}
if (options.getComments()) {
for (final String comment : v.origin().comments()) {
indent(sb, indent + 1, options);
sb.append("# ");
sb.append(comment);
sb.append("\n");
}
}
indent(sb, indent + 1, options);
v.render(sb, indent + 1, options);
sb.append(",");
if (options.getFormatted())
sb.append('\n');
}
sb.setLength(sb.length() - 1); // chop or newline
if (options.getFormatted()) {
sb.setLength(sb.length() - 1); // also chop comma
sb.append('\n');
indent(sb, indent, options);
}
sb.append("]");
}
}
@Override
public boolean contains(final Object o) {
return value.contains(o);
}
@Override
public boolean containsAll(final Collection> c) {
return value.containsAll(c);
}
@Override
public AbstractConfigValue get(final int index) {
return value.get(index);
}
@Override
public int indexOf(final Object o) {
return value.indexOf(o);
}
@Override
public boolean isEmpty() {
return value.isEmpty();
}
@Override
public Iterator iterator() {
final Iterator i = value.iterator();
return new Iterator() {
@Override
public boolean hasNext() {
return i.hasNext();
}
@Override
public ConfigValue next() {
return i.next();
}
@Override
public void remove() {
throw weAreImmutable("iterator().remove");
}
};
}
@Override
public int lastIndexOf(final Object o) {
return value.lastIndexOf(o);
}
private static ListIterator wrapListIterator(
final ListIterator i) {
return new ListIterator() {
@Override
public boolean hasNext() {
return i.hasNext();
}
@Override
public ConfigValue next() {
return i.next();
}
@Override
public void remove() {
throw weAreImmutable("listIterator().remove");
}
@Override
public void add(final ConfigValue arg0) {
throw weAreImmutable("listIterator().add");
}
@Override
public boolean hasPrevious() {
return i.hasPrevious();
}
@Override
public int nextIndex() {
return i.nextIndex();
}
@Override
public ConfigValue previous() {
return i.previous();
}
@Override
public int previousIndex() {
return i.previousIndex();
}
@Override
public void set(final ConfigValue arg0) {
throw weAreImmutable("listIterator().set");
}
};
}
@Override
public ListIterator listIterator() {
return wrapListIterator(value.listIterator());
}
@Override
public ListIterator listIterator(final int index) {
return wrapListIterator(value.listIterator(index));
}
@Override
public int size() {
return value.size();
}
@Override
public List subList(final int fromIndex, final int toIndex) {
final List list = new ArrayList();
// yay bloat caused by lack of type variance
for (final AbstractConfigValue v : value.subList(fromIndex, toIndex)) {
list.add(v);
}
return list;
}
@Override
public Object[] toArray() {
return value.toArray();
}
@Override
public T[] toArray(final T[] a) {
return value.toArray(a);
}
private static UnsupportedOperationException weAreImmutable(final String method) {
return new UnsupportedOperationException(
"ConfigList is immutable, you can't call List.'" + method + "'");
}
@Override
public boolean add(final ConfigValue e) {
throw weAreImmutable("add");
}
@Override
public void add(final int index, final ConfigValue element) {
throw weAreImmutable("add");
}
@Override
public boolean addAll(final Collection extends ConfigValue> c) {
throw weAreImmutable("addAll");
}
@Override
public boolean addAll(final int index, final Collection extends ConfigValue> c) {
throw weAreImmutable("addAll");
}
@Override
public void clear() {
throw weAreImmutable("clear");
}
@Override
public boolean remove(final Object o) {
throw weAreImmutable("remove");
}
@Override
public ConfigValue remove(final int index) {
throw weAreImmutable("remove");
}
@Override
public boolean removeAll(final Collection> c) {
throw weAreImmutable("removeAll");
}
@Override
public boolean retainAll(final Collection> c) {
throw weAreImmutable("retainAll");
}
@Override
public ConfigValue set(final int index, final ConfigValue element) {
throw weAreImmutable("set");
}
@Override
protected SimpleConfigList newCopy(final ConfigOrigin newOrigin) {
return new SimpleConfigList(newOrigin, value);
}
final SimpleConfigList concatenate(final SimpleConfigList other) {
final ConfigOrigin combinedOrigin = SimpleConfigOrigin.mergeOrigins(origin(), other.origin());
final List combined = new ArrayList(value.size()
+ other.value.size());
combined.addAll(value);
combined.addAll(other.value);
return new SimpleConfigList(combinedOrigin, combined);
}
// serialization all goes through SerializedConfigValue
private Object writeReplace() throws ObjectStreamException {
return new SerializedConfigValue(this);
}
}