/*
 * 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 java.util.Map;
import java.util.ResourceBundle;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.ext.util.WrapperTemplateModel;

/**
 * Maps Java objects to the type-system of FreeMarker Template Language (see the {@link TemplateModel}
 * interfaces). Thus this is what decides what parts of the Java objects will be accessible in the templates and how.
 * 
 * <p>For example, with a {@link BeansWrapper} both the items of {@link Map} and the JavaBean properties (the getters)
 * of an object are accessible in template uniformly with the {@code myObject.foo} syntax, where "foo" is the map key or
 * the property name. This is because both kind of object is wrapped by {@link BeansWrapper} into a
 * {@link TemplateHashModel} implementation that will call {@link Map#get(Object)} or the getter method, transparently
 * to the template language.
 * 
 * @see Configuration#setObjectWrapper(ObjectWrapper)
 */
@SuppressFBWarnings(value="IC_SUPERCLASS_USES_SUBCLASS_DURING_INITIALIZATION", justification="BC")
public interface ObjectWrapper {
    
    /**
     * An {@link ObjectWrapper} that exposes the object methods and JavaBeans properties as hash elements, and has
     * custom handling for Java {@link Map}-s, {@link ResourceBundle}-s, etc. It doesn't treat
     * {@link org.w3c.dom.Node}-s and Jython objects specially, however. As of 2.3.22, using
     * {@link DefaultObjectWrapper} with its {@code incompatibleImprovements} property set to 2.3.22 (or higher) is
     * recommended instead.
     * 
     * @deprecated Use {@link BeansWrapperBuilder#build()} instead; this instance isn't read-only
     *    and thus can't be trusted.
     */
    @Deprecated
    ObjectWrapper BEANS_WRAPPER = BeansWrapper.getDefaultInstance();

    /**
     * The legacy default object wrapper implementation, focusing on backward compatibility and out-of-the W3C DOM
     * wrapping box extra features. See {@link DefaultObjectWrapper} for more information.
     * 
     * @deprecated Use {@link DefaultObjectWrapperBuilder#build()} instead; this instance isn't read-only and thus can't
     *             be trusted.
     */
    @Deprecated
    ObjectWrapper DEFAULT_WRAPPER = DefaultObjectWrapper.instance;

    /**
     * Object wrapper that uses {@code SimpleXXX} wrappers only.
     * It behaves like the {@link #DEFAULT_WRAPPER}, but for objects
     * that it does not know how to wrap as a {@code SimpleXXX} it 
     * throws an exception. It makes no use of reflection-based 
     * exposure of anything, which may makes it a good candidate for security-restricted applications.
     * 
     * @deprecated No replacement as it was seldom if ever used by anyone; this instance isn't
     *    read-only and thus can't be trusted.
     */
    @Deprecated
    ObjectWrapper SIMPLE_WRAPPER = SimpleObjectWrapper.instance;
    
    /**
     * Makes a {@link TemplateModel} out of a non-{@link TemplateModel} object, usually by "wrapping" it into a
     * {@link TemplateModel} implementation that delegates to the original object.
     * 
     * @param obj The object to wrap into a {@link TemplateModel}. If it already implements {@link TemplateModel},
     *      it should just return the object as is. If it's {@code null}, the method should return {@code null}
     *      (however, {@link BeansWrapper}, has a legacy option for returning a null model object instead, but it's not
     *      a good idea).
     * 
     * @return a {@link TemplateModel} wrapper of the object passed in. To support un-wrapping, you may consider the
     *     return value to implement {@link WrapperTemplateModel} and {@link AdapterTemplateModel}.  
     *     The default expectation is that the {@link TemplateModel} isn't less thread safe than the wrapped object.
     *     If the {@link ObjectWrapper} returns less thread safe objects, that should be clearly documented, as it
     *     restricts how it can be used, like, then it can't be used to wrap "shared variables"
     *     ({@link Configuration#setSharedVaribles(Map)}).
     */
    TemplateModel wrap(Object obj) throws TemplateModelException;
    
}
