/*
* Copyright 2011 Robert W. Vawter III <bob@vawter.org>
*
* 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 org.jsonddl.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.jsonddl.JsonDdlObject;
public class Protected {
private static final Class<?> unmodifiableListClass;
private static final Class<?> unmodifiableMapClass;
static {
unmodifiableListClass = Collections.unmodifiableList(Arrays.asList(1, 2, 3)).getClass();
Map<Object, Object> testMap = new LinkedHashMap<Object, Object>();
testMap.put(new Object(), new Object());
testMap.put(new Object(), new Object());
unmodifiableMapClass = Collections.unmodifiableMap(testMap).getClass();
}
public static <J extends JsonDdlObject<J>> J object(J value) {
if (value instanceof JsonDdlObject.Builder) {
return ((JsonDdlObject.Builder<J>) value).build();
}
return value;
}
public static <T> List<T> object(List<T> values) {
if (values == null) {
return null;
}
switch (values.size()) {
case 0:
return Collections.emptyList();
case 1:
return Collections.singletonList(object(values.get(0)));
default:
if (unmodifiableListClass.equals(values.getClass())) {
return values;
}
ArrayList<T> toReturn = new ArrayList<T>(values.size());
for (T value : values) {
toReturn.add(object(value));
}
return Collections.unmodifiableList(toReturn);
}
}
public static <K, V> Map<K, V> object(Map<K, V> values) {
if (values == null) {
return null;
}
switch (values.size()) {
case 0:
return Collections.emptyMap();
case 1: {
Map.Entry<K, V> entry = values.entrySet().iterator().next();
return Collections.singletonMap(object(entry.getKey()), object(entry.getValue()));
}
default: {
if (unmodifiableMapClass.equals(values.getClass())) {
return values;
}
Map<K, V> toReturn = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : values.entrySet()) {
toReturn.put(object(entry.getKey()), object(entry.getValue()));
}
return Collections.unmodifiableMap(toReturn);
}
}
}
@SuppressWarnings("unchecked")
public static <T> T object(T value) {
if (value == null) {
return null;
}
if (value instanceof Boolean) {
return value;
}
if (value instanceof Number) {
return value;
}
if (value instanceof String) {
return value;
}
if (value instanceof Enum<?>) {
return value;
}
if (value instanceof JsonDdlObject.Builder) {
return (T) ((JsonDdlObject.Builder<?>) value).build();
}
if (value instanceof JsonDdlObject) {
return value;
}
if (value instanceof List) {
return (T) object((List<?>) value);
}
if (value instanceof Map) {
return (T) object((Map<?, ?>) value);
}
throw new IllegalArgumentException("Cannot protect type of " + value.getClass().getName());
}
}