/* * Copyright 2008 Google Inc. * * 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.google.template.soy.data; import com.google.template.soy.data.restricted.BooleanData; import com.google.template.soy.data.restricted.FloatData; import com.google.template.soy.data.restricted.IntegerData; import com.google.template.soy.data.restricted.NullData; import com.google.template.soy.data.restricted.StringData; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; /** * Abstract base class for all nodes in a Soy data tree. * * <p>Important: Even though this class is not marked 'final', do not extend this class. * */ public abstract class SoyData extends SoyAbstractValue { /** * Creates deprecated SoyData objects from standard Java data structures. * * @param obj The existing object or data structure to convert. * @return A SoyData object or tree that corresponds to the given object. * @throws SoyDataException If the given object cannot be converted to SoyData. * @deprecated It's best to pass whatever object you have directly to the Soy templates you're * using -- Soy understands primitives, lists, and maps natively, and if you install runtime * support you can also pass protocol buffers. If you're interacting directly with the Soy * runtime and need SoyValue objects, use SoyValueConverter instead. */ @Deprecated public static SoyData createFromExistingData(Object obj) { // Important: This is frozen for backwards compatibility, For future changes (pun not intended), // use SoyValueConverter, which works with the new interfaces SoyValue and SoyValueProvider. if (obj == null) { return NullData.INSTANCE; } else if (obj instanceof SoyData) { return (SoyData) obj; } else if (obj instanceof String) { return StringData.forValue((String) obj); } else if (obj instanceof Boolean) { return BooleanData.forValue((Boolean) obj); } else if (obj instanceof Integer) { return IntegerData.forValue((Integer) obj); } else if (obj instanceof Long) { return IntegerData.forValue((Long) obj); } else if (obj instanceof Map<?, ?>) { @SuppressWarnings("unchecked") Map<String, ?> objCast = (Map<String, ?>) obj; return new SoyMapData(objCast); } else if (obj instanceof Iterable<?>) { return new SoyListData((Iterable<?>) obj); } else if (obj instanceof Double) { return FloatData.forValue((Double) obj); } else if (obj instanceof Float) { // Automatically convert float to double. return FloatData.forValue((Float) obj); } else if (obj instanceof Future<?>) { // Note: In the old SoyData, we don't support late-resolution of Futures. We immediately // resolve the Future object here. For late-resolution, use SoyValueConverter.convert(). try { return createFromExistingData(((Future<?>) obj).get()); } catch (InterruptedException e) { throw new SoyDataException( "Encountered InterruptedException when resolving Future object.", e); } catch (ExecutionException e) { throw new SoyDataException( "Encountered ExecutionException when resolving Future object.", e); } } else { throw new SoyDataException( "Attempting to convert unrecognized object to Soy data (object type " + obj.getClass().getName() + ")."); } } }