// 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/FixFieldExtractor.java
// public interface FixFieldExtractor<M> {
// 
//     /**
//      * Reads a tag of the FIX field identified by the given tag. If optional is true then in case of not found field
//      * null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage a FIX message object
//      * @param type       a type to return
//      * @param tag        a FIX field tag to read the tag from
//      * @param optional   determines whether a not found field should generate an exception
//      * @param <T>        the type of the result
//      * @throws FixException
//      */
//     <T> T getFieldValue(M fixMessage, Class<T> type, int tag, boolean optional);
// 
//     /**
//      * Reads all repeating groups from the given FIX message identified by the given tag. If optional is true then in
//      * case of
//      * non found groups null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage  the FIX message object
//      * @param type        the collection type to return
//      * @param groupTag    the FIX group tag to read from
//      * @param elementType type of the resulting collection elements (has the same meaning as the type parameter in
//      *                    getFieldValue)
//      * @param elementTag  the group delimiter tag (or the tag of a single element)
//      * @param optional    determines whether a not found group should generate an exception
//      * @param <T>         type or the resulting collection elements
//      */
//     <T, C extends Collection<T>> C getGroups(M fixMessage,
//                                              Class<C> type,
//                                              int groupTag,
//                                              Class<T> elementType,
//                                              int elementTag,
//                                              boolean optional);
// 
//     /**
//      * Reads all repeating block groups from the given FIX message identified by the given tag. If optional is true
//      * then in case of
//      * non found groups null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage    the FIX message object
//      * @param type          the collection type to return
//      * @param groupTag      the FIX group tag to read from
//      * @param componentMeta the FIX mapping metadata for a single repeating group
//      * @param optional      determines whether a not found group should generate an exception
//      * @param <T>           type or the resulting collection elements
//      */
//     <T, C extends Collection<T>> C getGroups(M fixMessage,
//                                              Class<C> type,
//                                              int groupTag,
//                                              FixBlockMeta<T> componentMeta,
//                                              boolean optional);
// }
// 
// Path: fixb/src/main/java/org/fixb/impl/CollectionFactory.java
// public class CollectionFactory {
//     /**
//      * Creates an empty instance of the given collection type.
//      * If the given an class in an interface, an ArrayList will be created for java.util.List
//      * or java.util.Collection interfaces, and HashSet for java.util.Set interface.
//      */
//     @SuppressWarnings("unchecked")
//     public static <T extends Collection<?>> T createCollection(Class<T> collClass) {
//         if (!collClass.isInterface() && !Modifier.isAbstract(collClass.getModifiers())) {
//             try {
//                 return collClass.newInstance();
//             } catch (InstantiationException | IllegalAccessException e) {
//                 throw new FixException(e.getMessage(), e);
//             }
//         } else if (List.class.isAssignableFrom(collClass)) {
//             return (T) new ArrayList<>();
//         } else if (Set.class.isAssignableFrom(collClass)) {
//             return (T) new HashSet<>();
//         } else if (Collection.class.isAssignableFrom(collClass)) {
//             return (T) new ArrayList<>();
//         } else {
//             throw new IllegalArgumentException("Unknown collection type: " + collClass);
//         }
//     }
// }


import org.fixb.FixException;
import org.fixb.FixFieldExtractor;
import org.fixb.impl.CollectionFactory;
import org.fixb.meta.*;
import org.joda.time.*;
import org.joda.time.format.DateTimeFormatterBuilder;
import quickfix.*;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
/*
 * 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.quickfix;



/**
 * An implementation of FixFieldExtractor that is used to extract data from quickfix.Message objects.
 *
 * @author vladyslav.yatsenko
 * @see quickfix.Message
 */
public class QuickFixFieldExtractor implements FixFieldExtractor<Message> {
    @Override
    public <T> T getFieldValue(Message message, Class<T> type, int tag, boolean optional) {
        T fieldValue = getFieldValueFromMap(message, type, tag);
        if (fieldValue == null) {
            if (!optional) {
// 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/FixFieldExtractor.java
// public interface FixFieldExtractor<M> {
// 
//     /**
//      * Reads a tag of the FIX field identified by the given tag. If optional is true then in case of not found field
//      * null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage a FIX message object
//      * @param type       a type to return
//      * @param tag        a FIX field tag to read the tag from
//      * @param optional   determines whether a not found field should generate an exception
//      * @param <T>        the type of the result
//      * @throws FixException
//      */
//     <T> T getFieldValue(M fixMessage, Class<T> type, int tag, boolean optional);
// 
//     /**
//      * Reads all repeating groups from the given FIX message identified by the given tag. If optional is true then in
//      * case of
//      * non found groups null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage  the FIX message object
//      * @param type        the collection type to return
//      * @param groupTag    the FIX group tag to read from
//      * @param elementType type of the resulting collection elements (has the same meaning as the type parameter in
//      *                    getFieldValue)
//      * @param elementTag  the group delimiter tag (or the tag of a single element)
//      * @param optional    determines whether a not found group should generate an exception
//      * @param <T>         type or the resulting collection elements
//      */
//     <T, C extends Collection<T>> C getGroups(M fixMessage,
//                                              Class<C> type,
//                                              int groupTag,
//                                              Class<T> elementType,
//                                              int elementTag,
//                                              boolean optional);
// 
//     /**
//      * Reads all repeating block groups from the given FIX message identified by the given tag. If optional is true
//      * then in case of
//      * non found groups null will be returned, otherwise should throw a FixException.
//      *
//      * @param fixMessage    the FIX message object
//      * @param type          the collection type to return
//      * @param groupTag      the FIX group tag to read from
//      * @param componentMeta the FIX mapping metadata for a single repeating group
//      * @param optional      determines whether a not found group should generate an exception
//      * @param <T>           type or the resulting collection elements
//      */
//     <T, C extends Collection<T>> C getGroups(M fixMessage,
//                                              Class<C> type,
//                                              int groupTag,
//                                              FixBlockMeta<T> componentMeta,
//                                              boolean optional);
// }
// 
// Path: fixb/src/main/java/org/fixb/impl/CollectionFactory.java
// public class CollectionFactory {
//     /**
//      * Creates an empty instance of the given collection type.
//      * If the given an class in an interface, an ArrayList will be created for java.util.List
//      * or java.util.Collection interfaces, and HashSet for java.util.Set interface.
//      */
//     @SuppressWarnings("unchecked")
//     public static <T extends Collection<?>> T createCollection(Class<T> collClass) {
//         if (!collClass.isInterface() && !Modifier.isAbstract(collClass.getModifiers())) {
//             try {
//                 return collClass.newInstance();
//             } catch (InstantiationException | IllegalAccessException e) {
//                 throw new FixException(e.getMessage(), e);
//             }
//         } else if (List.class.isAssignableFrom(collClass)) {
//             return (T) new ArrayList<>();
//         } else if (Set.class.isAssignableFrom(collClass)) {
//             return (T) new HashSet<>();
//         } else if (Collection.class.isAssignableFrom(collClass)) {
//             return (T) new ArrayList<>();
//         } else {
//             throw new IllegalArgumentException("Unknown collection type: " + collClass);
//         }
//     }
// }


// Path: fixb-quickfix/src/main/java/org/fixb/quickfix/QuickFixFieldExtractor.java
import org.fixb.FixException;
import org.fixb.FixFieldExtractor;
import org.fixb.impl.CollectionFactory;
import org.fixb.meta.*;
import org.joda.time.*;
import org.joda.time.format.DateTimeFormatterBuilder;
import quickfix.*;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/*
 * 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.quickfix;



/**
 * An implementation of FixFieldExtractor that is used to extract data from quickfix.Message objects.
 *
 * @author vladyslav.yatsenko
 * @see quickfix.Message
 */
public class QuickFixFieldExtractor implements FixFieldExtractor<Message> {
    @Override
    public <T> T getFieldValue(Message message, Class<T> type, int tag, boolean optional) {
        T fieldValue = getFieldValueFromMap(message, type, tag);
        if (fieldValue == null) {
            if (!optional) {
                throw new FixException("Field [" + tag + "] was not found in message");