/*
  This file is licensed 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 org.xmlunit.builder;

import javax.xml.transform.Source;

import org.xmlunit.builder.Input.Builder;

/**
 * {@link Builder} for Jaxb-Object and creating a {@code JAXBSource}.
 */
public abstract class JaxbBuilder implements Builder {

    private final Object object;
    private Object marshaller;
    private boolean useObjectFactory;

    /**
     * Creates a builder based on the given object.
     * @param object the object to build a source of
     */
    protected JaxbBuilder(final Object object) {
        this.object = object;
    }

    /**
     * Sets a non-default {@code Marshaller} to use when creating the {@link Source}.
     * @param marshaller the Marshaller to use
     * @return this
     */
    public JaxbBuilder withMarshaller(final Object marshaller) {
        this.marshaller = marshaller;
        return this;
    }

    /**
     * Whether the given Object has no {@code XmlRootElement} annotation and is not an instants of {@code JAXBElement} it
     * must be wrapped by a {@code JAXBElement}.
     * <p>
     * This method will find the {@code ObjectFactory} class (normally generated by jaxb) and use the first matching
     * factory-method for the given Object to create the {@code JAXBElement}-Wrapper.
     * <p>
     * If no ObjectFactory and method exists for the given object, the default behavior (same behavior as by
     * {@code JAXB}) will be used to create the {@code JAXBElement}-Wrapper for the given Object.
     * <p>
     * If you don't use the {@code xjc:simple} flag to generate your JAXB-Objects, the use of the OjectFactory is most likely
     * required to generate Schema-Valid XML.
     * @return this
     */
    public JaxbBuilder useObjectFactory() {
        this.useObjectFactory = true;
        return this;
    }

    /**
     * Provides the configured object.
     * @return the configured object
     * @since 2.9.0
     */
    protected final Object getObject() {
        return object;
    }

    /**
     * Provides the custom Marshaller.
     * @return the configured Marshaller
     * @since 2.9.0
     */
    protected final Object getMarshaller() {
        return marshaller;
    }

    /**
     * Provides whether the given Object has no {@code XmlRootElement} annotation and is not an instants of {@code JAXBElement} it
     * must be wrapped by a {@code JAXBElement}.
     * @return whether the given Object has no {@code XmlRootElement} annotation and is not an instants of {@code JAXBElement} it
     * must be wrapped by a {@code JAXBElement}.
     * @since 2.9.0
     */
    protected final boolean getUseObjectFactory() {
        return useObjectFactory;
    }

}
