// Path: fixb/src/main/java/org/fixb/FixException.java
// public class FixException extends RuntimeException {
//     private static final long serialVersionUID = 1;
// 
//     /**
//      * @param tag the field tag that has not been found
//      * @param fixMessage the FIX message that does not contain the tag
//      * @return an instance of FixException for a field-not-found case.
//      */
//     public static FixException fieldNotFound(int tag, String fixMessage) {
//         return new FixException("Field [" + tag + "] was not found in message: " + fixMessage);
//     }
// 
//     /**
//      * @param message the exception message
//      * @param cause the exception cause
//      */
//     public FixException(final String message, final Throwable cause) {
//         super(message, cause);
//     }
// 
//     /**
//      * @param cause the exception cause
//      */
//     public FixException(final Throwable cause) {
//         super(cause.getMessage(), cause);
//     }
// 
//     /**
//      * @param message the exception message
//      */
//     public FixException(final String message) {
//         super(message);
//     }
// }


import com.google.common.base.Optional;
import org.fixb.FixException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.*;
import static java.util.Collections.unmodifiableList;
/*
 * Copyright 2013 YTEQ Ltd.
 *
 * 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.fixb.meta;





/**
 * A FIX block metadata (a set of FIX fields and repeating groups), e.g. CParty.
 *
 * @param <T>
 * @author vladyslav.yatsenko
 */
public class FixBlockMeta<T> {
    private final Class<T> type;
    private final Optional<Constructor<T>> constructor;
    private final List<FixFieldMeta> fields;

    /**
     * The same as FixBlockMeta, but with useConstructor default to false.
     *
     * @param type   the domain object type this FixBlockMeta is for
     * @param fields the fields metadata
     */
    public FixBlockMeta(Class<T> type, List<? extends FixFieldMeta> fields) {
        this(type, fields, false);
    }

    /**
     * @param type           the domain object type this FixBlockMeta is for
     * @param fields         the fields metadata
     * @param useConstructor identifies whether to use constructor for instance initialisations
     */
    @SuppressWarnings("unchecked")
    public FixBlockMeta(Class<T> type, List<? extends FixFieldMeta> fields, boolean useConstructor) {
        this.type = type;
        this.constructor = useConstructor ? Optional.of((Constructor<T>) type.getConstructors()[0]) : Optional.<Constructor<T>>absent();
        this.fields = unmodifiableList(fields);
    }

    /**
     * @return the related domain object type.
     */
    public Class<T> getType() {
        return type;
    }

    /**
     * @return the fields metadata.
     */
    public List<FixFieldMeta> getFields() {
        return fields;
    }

    /**
     * @param values constructor parameter values
     * @return a domain object created using given parameter values.
     */
    public T createModel(Map<FixFieldMeta, Object> values) {
        try {
            return (constructor.isPresent()) ?
                    createModel(constructor.get(), values, 0) :
                    createModel(type, values, 0);
        } catch (Exception e) {
// Path: fixb/src/main/java/org/fixb/FixException.java
// public class FixException extends RuntimeException {
//     private static final long serialVersionUID = 1;
// 
//     /**
//      * @param tag the field tag that has not been found
//      * @param fixMessage the FIX message that does not contain the tag
//      * @return an instance of FixException for a field-not-found case.
//      */
//     public static FixException fieldNotFound(int tag, String fixMessage) {
//         return new FixException("Field [" + tag + "] was not found in message: " + fixMessage);
//     }
// 
//     /**
//      * @param message the exception message
//      * @param cause the exception cause
//      */
//     public FixException(final String message, final Throwable cause) {
//         super(message, cause);
//     }
// 
//     /**
//      * @param cause the exception cause
//      */
//     public FixException(final Throwable cause) {
//         super(cause.getMessage(), cause);
//     }
// 
//     /**
//      * @param message the exception message
//      */
//     public FixException(final String message) {
//         super(message);
//     }
// }


// Path: fixb/src/main/java/org/fixb/meta/FixBlockMeta.java
import com.google.common.base.Optional;
import org.fixb.FixException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.*;
import static java.util.Collections.unmodifiableList;

/*
 * Copyright 2013 YTEQ Ltd.
 *
 * 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.fixb.meta;





/**
 * A FIX block metadata (a set of FIX fields and repeating groups), e.g. CParty.
 *
 * @param <T>
 * @author vladyslav.yatsenko
 */
public class FixBlockMeta<T> {
    private final Class<T> type;
    private final Optional<Constructor<T>> constructor;
    private final List<FixFieldMeta> fields;

    /**
     * The same as FixBlockMeta, but with useConstructor default to false.
     *
     * @param type   the domain object type this FixBlockMeta is for
     * @param fields the fields metadata
     */
    public FixBlockMeta(Class<T> type, List<? extends FixFieldMeta> fields) {
        this(type, fields, false);
    }

    /**
     * @param type           the domain object type this FixBlockMeta is for
     * @param fields         the fields metadata
     * @param useConstructor identifies whether to use constructor for instance initialisations
     */
    @SuppressWarnings("unchecked")
    public FixBlockMeta(Class<T> type, List<? extends FixFieldMeta> fields, boolean useConstructor) {
        this.type = type;
        this.constructor = useConstructor ? Optional.of((Constructor<T>) type.getConstructors()[0]) : Optional.<Constructor<T>>absent();
        this.fields = unmodifiableList(fields);
    }

    /**
     * @return the related domain object type.
     */
    public Class<T> getType() {
        return type;
    }

    /**
     * @return the fields metadata.
     */
    public List<FixFieldMeta> getFields() {
        return fields;
    }

    /**
     * @param values constructor parameter values
     * @return a domain object created using given parameter values.
     */
    public T createModel(Map<FixFieldMeta, Object> values) {
        try {
            return (constructor.isPresent()) ?
                    createModel(constructor.get(), values, 0) :
                    createModel(type, values, 0);
        } catch (Exception e) {
            throw new FixException("Unable to create object from FIX parameters: " + values.values(), e);