/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 freemarker.template;

import freemarker.ext.util.WrapperTemplateModel;

/**
 * <b>Experimental - subject to change:</b> Adds functionality to {@link ObjectWrapper} that creates a plain Java object
 * from a {@link TemplateModel}. This is usually implemented by {@link ObjectWrapper}-s and reverses
 * {@link ObjectWrapper#wrap(Object)}. However, an implementation of this interface should make a reasonable effort to
 * "unwrap" {@link TemplateModel}-s that wasn't the result of object wrapping (such as those created directly in FTL),
 * or which was created by another {@link ObjectWrapper}. The author of an {@link ObjectWrapperAndUnwrapper} should be
 * aware of the {@link TemplateModelAdapter} and {@link WrapperTemplateModel} interfaces, which should be used for
 * unwrapping if the {@link TemplateModel} implements them.
 * 
 * <p>
 * <b>Experimental status warning:</b> This interface is subject to change on non-backward compatible ways, hence, it
 * shouldn't be implemented outside FreeMarker yet.
 * 
 * @since 2.3.22
 */
public interface ObjectWrapperAndUnwrapper extends ObjectWrapper {

    /**
     * Indicates that while the unwrapping is <em>maybe</em> possible, the result surely can't be the instance of the
     * desired class, nor it can be {@code null}.
     * 
     * @see #tryUnwrapTo(TemplateModel, Class)
     * 
     * @since 2.3.22
     */
    Object CANT_UNWRAP_TO_TARGET_CLASS = new Object();

    /**
     * Unwraps a {@link TemplateModel} to a plain Java object.
     * 
     * @return The plain Java object. Can be {@code null}, if {@code null} is the appropriate Java value to represent
     *         the template model. {@code null} must not be used to indicate an unwrapping failure. It must NOT be
     *         {@link #CANT_UNWRAP_TO_TARGET_CLASS}.
     * 
     * @throws TemplateModelException
     *             If the unwrapping fails from any reason.
     * 
     * @see #tryUnwrapTo(TemplateModel, Class)
     * 
     * @since 2.3.22
     */
    Object unwrap(TemplateModel tm) throws TemplateModelException;

    /**
     * Attempts to unwrap a {@link TemplateModel} to a plain Java object that's the instance of the given class (or is
     * {@code null}).
     * 
     * @param targetClass
     *            The class that the return value must be an instance of (except when the return value is {@code null}).
     *            Can't be {@code null}; if the caller doesn't care, it should either use {#unwrap(TemplateModel)}, or
     *            {@code Object.class} as the parameter value.
     *
     * @return The unwrapped value that's either an instance of {@code targetClass}, or is {@code null} (if {@code null}
     *         is the appropriate Java value to represent the template model), or is
     *         {@link #CANT_UNWRAP_TO_TARGET_CLASS} if the unwrapping can't satisfy the {@code targetClass} (nor the
     *         result can be {@code null}). However, {@link #CANT_UNWRAP_TO_TARGET_CLASS} must not be returned if the
     *         {@code targetClass} parameter was {@code Object.class}.
     * 
     * @throws TemplateModelException
     *             If the unwrapping fails for a reason than doesn't fit the meaning of the
     *             {@link #CANT_UNWRAP_TO_TARGET_CLASS} return value.
     * 
     * @see #unwrap(TemplateModel)
     * 
     * @since 2.3.22
     */
    Object tryUnwrapTo(TemplateModel tm, Class targetClass) throws TemplateModelException;

}
