remove ConfigSubstitution, it was a serialization compat shim

The serialization-pocalypse removes the need for this shim.
This commit is contained in:
Havoc Pennington 2012-04-12 13:21:10 -04:00
parent 388d85fb5d
commit f0e4dfd806
6 changed files with 19 additions and 241 deletions

View File

@ -200,20 +200,16 @@ final class ConfigConcatenation extends AbstractConfigValue implements Unmergeab
return new ConfigConcatenation(origin(), newPieces);
}
@SuppressWarnings("deprecation")
@Override
protected boolean canEqual(Object other) {
return other instanceof ConfigConcatenation || other instanceof ConfigSubstitution;
return other instanceof ConfigConcatenation;
}
@SuppressWarnings("deprecation")
@Override
public boolean equals(Object other) {
// note that "origin" is deliberately NOT part of equality
if (other instanceof ConfigConcatenation) {
return canEqual(other) && this.pieces.equals(((ConfigConcatenation) other).pieces);
} else if (other instanceof ConfigSubstitution) {
return equals(((ConfigSubstitution) other).delegate());
} else {
return false;
}

View File

@ -104,20 +104,16 @@ final class ConfigReference extends AbstractConfigValue implements Unmergeable {
return new ConfigReference(origin(), newExpr, prefixLength + prefix.length());
}
@SuppressWarnings("deprecation")
@Override
protected boolean canEqual(Object other) {
return other instanceof ConfigReference || other instanceof ConfigSubstitution;
return other instanceof ConfigReference;
}
@SuppressWarnings("deprecation")
@Override
public boolean equals(Object other) {
// note that "origin" is deliberately NOT part of equality
if (other instanceof ConfigReference) {
return canEqual(other) && this.expr.equals(((ConfigReference) other).expr);
} else if (other instanceof ConfigSubstitution) {
return equals(((ConfigSubstitution) other).delegate());
} else {
return false;
}

View File

@ -1,178 +0,0 @@
/**
* Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com>
*/
package com.typesafe.config.impl;
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import com.typesafe.config.ConfigException;
import com.typesafe.config.ConfigOrigin;
import com.typesafe.config.ConfigValueType;
/**
* ConfigSubstitution is now a shim for back-compat with serialization. i.e. an
* old version may unserialize one of these. We now split into ConfigReference
* and ConfigConcatenation.
*/
@Deprecated
final class ConfigSubstitution extends AbstractConfigValue implements Unmergeable, Serializable {
private static final long serialVersionUID = 1L;
// this is a list of String and SubstitutionExpression where the
// SubstitutionExpression has to be resolved to values, then if there's more
// than one piece everything is stringified and concatenated
final private List<Object> pieces;
// this is just here to avoid breaking serialization
@SuppressWarnings("unused")
@Deprecated
final private int prefixLength = 0;
// this is just here to avoid breaking serialization
@SuppressWarnings("unused")
@Deprecated
final private boolean ignoresFallbacks = false;
// we chain the ConfigSubstitution back-compat stub to a new value
private transient AbstractConfigValue delegate = null;
private void createDelegate() {
if (delegate != null)
throw new ConfigException.BugOrBroken("creating delegate twice: " + this);
List<AbstractConfigValue> values = ConfigConcatenation.valuesFromPieces(origin(), pieces);
if (values.size() == 1) {
delegate = values.get(0);
} else {
delegate = new ConfigConcatenation(origin(), values);
}
if (!(delegate instanceof Unmergeable))
throw new ConfigException.BugOrBroken("delegate must be Unmergeable: " + this
+ " delegate was: " + delegate);
}
AbstractConfigValue delegate() {
if (delegate == null)
throw new NullPointerException("failed to create delegate " + this);
return delegate;
}
ConfigSubstitution(ConfigOrigin origin, List<Object> pieces) {
super(origin);
this.pieces = pieces;
createDelegate();
}
@Override
public ConfigValueType valueType() {
return delegate().valueType();
}
@Override
public Object unwrapped() {
return delegate().unwrapped();
}
@Override
protected AbstractConfigValue newCopy(ConfigOrigin newOrigin) {
return delegate().newCopy(newOrigin);
}
@Override
protected boolean ignoresFallbacks() {
return delegate().ignoresFallbacks();
}
@Override
protected AbstractConfigValue mergedWithTheUnmergeable(Unmergeable fallback) {
return delegate().mergedWithTheUnmergeable(fallback);
}
@Override
protected AbstractConfigValue mergedWithObject(AbstractConfigObject fallback) {
return delegate().mergedWithObject(fallback);
}
@Override
protected AbstractConfigValue mergedWithNonObject(AbstractConfigValue fallback) {
return delegate().mergedWithNonObject(fallback);
}
@Override
public Collection<? extends AbstractConfigValue> unmergedValues() {
return ((Unmergeable) delegate()).unmergedValues();
}
@Override
AbstractConfigValue resolveSubstitutions(ResolveContext context) throws NotPossibleToResolve {
return context.resolve(delegate());
}
@Override
ResolveStatus resolveStatus() {
return delegate().resolveStatus();
}
@Override
AbstractConfigValue relativized(Path prefix) {
return delegate().relativized(prefix);
}
@Override
protected boolean canEqual(Object other) {
return other instanceof ConfigSubstitution || other instanceof ConfigReference
|| other instanceof ConfigConcatenation;
}
@Override
public boolean equals(Object other) {
// note that "origin" is deliberately NOT part of equality
if (other instanceof ConfigSubstitution) {
return canEqual(other)
&& this.pieces.equals(((ConfigSubstitution) other).pieces);
} else {
return delegate().equals(other);
}
}
@Override
public int hashCode() {
return delegate().hashCode();
}
@Override
protected void render(StringBuilder sb, int indent, boolean formatted) {
delegate().render(sb, indent, formatted);
}
// This ridiculous hack is because some JDK versions apparently can't
// serialize an array, which is used to implement ArrayList and EmptyList.
// maybe
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6446627
private Object writeReplace() throws ObjectStreamException {
// switch to LinkedList
return new ConfigSubstitution(origin(), new java.util.LinkedList<Object>(pieces));
}
// generate the delegate when we deserialize to avoid thread safety
// issues later
private void readObject(java.io.ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();
createDelegate();
}
// this is a little cleaner but just causes compat issues probably
// private Object readResolve() throws ObjectStreamException {
// replace ourselves on deserialize
// return delegate();
// }
}

View File

@ -17,7 +17,7 @@ class ConfigSubstitutionTest extends TestUtils {
val options = ConfigResolveOptions.noSystem()
ResolveContext.resolve(v, v, options).asInstanceOf[AbstractConfigObject].toConfig
}
private def resolveWithoutFallbacks(s: ConfigSubstitution, root: AbstractConfigObject) = {
private def resolveWithoutFallbacks(s: AbstractConfigValue, root: AbstractConfigObject) = {
val options = ConfigResolveOptions.noSystem()
ResolveContext.resolve(s, root, options)
}
@ -26,7 +26,7 @@ class ConfigSubstitutionTest extends TestUtils {
val options = ConfigResolveOptions.defaults()
ResolveContext.resolve(v, v, options).asInstanceOf[AbstractConfigObject].toConfig
}
private def resolve(s: ConfigSubstitution, root: AbstractConfigObject) = {
private def resolve(s: AbstractConfigValue, root: AbstractConfigObject) = {
val options = ConfigResolveOptions.defaults()
ResolveContext.resolve(s, root, options)
}

View File

@ -271,31 +271,11 @@ class ConfigValueTest extends TestUtils {
}
@Test
def configSubstitutionEquality() {
def configReferenceEquality() {
val a = subst("foo")
val sameAsA = subst("foo")
val b = subst("bar")
assertTrue("wrong type " + a, a.isInstanceOf[ConfigSubstitution])
assertTrue("wrong type " + b, b.isInstanceOf[ConfigSubstitution])
checkEqualObjects(a, a)
checkEqualObjects(a, sameAsA)
checkNotEqualObjects(a, b)
}
@Test
def configSubstitutionNotSerializable() {
val a = subst("foo")
checkNotSerializable(a)
}
@Test
def configReferenceEquality() {
val a = subst("foo").delegate()
val sameAsA = subst("foo").delegate()
val b = subst("bar").delegate()
val c = subst("foo", optional = true).delegate()
val c = subst("foo", optional = true)
assertTrue("wrong type " + a, a.isInstanceOf[ConfigReference])
assertTrue("wrong type " + b, b.isInstanceOf[ConfigReference])
@ -310,17 +290,17 @@ class ConfigValueTest extends TestUtils {
@Test
def configReferenceNotSerializable() {
val a = subst("foo").delegate()
val a = subst("foo")
assertTrue("wrong type " + a, a.isInstanceOf[ConfigReference])
checkNotSerializable(a)
}
@Test
def configConcatenationEquality() {
val a = substInString("foo").delegate()
val sameAsA = substInString("foo").delegate()
val b = substInString("bar").delegate()
val c = substInString("foo", optional = true).delegate()
val a = substInString("foo")
val sameAsA = substInString("foo")
val b = substInString("bar")
val c = substInString("foo", optional = true)
assertTrue("wrong type " + a, a.isInstanceOf[ConfigConcatenation])
assertTrue("wrong type " + b, b.isInstanceOf[ConfigConcatenation])
@ -334,26 +314,11 @@ class ConfigValueTest extends TestUtils {
@Test
def configConcatenationNotSerializable() {
val a = substInString("foo").delegate()
val a = substInString("foo")
assertTrue("wrong type " + a, a.isInstanceOf[ConfigConcatenation])
checkNotSerializable(a)
}
@Test
def configSubstitutionEqualsItsDelegates() {
val a = subst("foo")
assertTrue("wrong type " + a, a.isInstanceOf[ConfigSubstitution])
val aD = a.delegate()
assertTrue("wrong type " + aD, aD.isInstanceOf[ConfigReference])
val b = substInString("bar")
assertTrue("wrong type " + b, b.isInstanceOf[ConfigSubstitution])
val bD = b.delegate()
assertTrue("wrong type " + bD, bD.isInstanceOf[ConfigConcatenation])
checkEqualObjects(a, aD)
checkEqualObjects(b, bD)
}
@Test
def configDelayedMergeEquality() {
val s1 = subst("foo")

View File

@ -563,24 +563,23 @@ abstract trait TestUtils {
ConfigFactory.parseString(s, options).asInstanceOf[SimpleConfig]
}
protected def subst(ref: String, optional: Boolean): ConfigSubstitution = {
protected def subst(ref: String, optional: Boolean): ConfigReference = {
val path = Path.newPath(ref)
val pieces = java.util.Collections.singletonList[Object](new SubstitutionExpression(path, optional))
new ConfigSubstitution(fakeOrigin(), pieces)
new ConfigReference(fakeOrigin(), new SubstitutionExpression(path, optional))
}
protected def subst(ref: String): ConfigSubstitution = {
protected def subst(ref: String): ConfigReference = {
subst(ref, false)
}
protected def substInString(ref: String, optional: Boolean): ConfigSubstitution = {
protected def substInString(ref: String, optional: Boolean): ConfigConcatenation = {
import scala.collection.JavaConverters._
val path = Path.newPath(ref)
val pieces = List[AnyRef]("start<", new SubstitutionExpression(path, optional), ">end")
new ConfigSubstitution(fakeOrigin(), pieces.asJava)
val pieces = List[AbstractConfigValue](stringValue("start<"), subst(ref, optional), stringValue(">end"))
new ConfigConcatenation(fakeOrigin(), pieces.asJava)
}
protected def substInString(ref: String): ConfigSubstitution = {
protected def substInString(ref: String): ConfigConcatenation = {
substInString(ref, false)
}