Package org.jnetpcap.packet.structure

Source Code of org.jnetpcap.packet.structure.AnnotatedBinding

/*
* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Sly Technologies, Inc.
*
* This file is part of jNetPcap.
*
* jNetPcap is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.jnetpcap.packet.structure;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jnetpcap.packet.JBinding;
import org.jnetpcap.packet.JHeader;
import org.jnetpcap.packet.JPacket;
import org.jnetpcap.packet.JRegistry;
import org.jnetpcap.packet.annotate.Bind;

// TODO: Auto-generated Javadoc
/**
* The Class AnnotatedBinding.
*
* @author Mark Bednarczyk
* @author Sly Technologies, Inc.
*/
public class AnnotatedBinding implements JBinding {

  /** The Constant cache. */
  private final static Map<Class<?>, JBinding[]> cache =
      new HashMap<Class<?>, JBinding[]>();

  /**
   * Clear cache.
   */
  public static void clearCache() {
    cache.clear();
  }

  /**
   * Creates the header from class.
   *
   * @param c
   *          the c
   * @return the j header
   */
  private static JHeader createHeaderFromClass(Class<? extends JHeader> c) {
    try {
      JHeader header = c.newInstance();
      return header;
    } catch (InstantiationException e) {
      throw new HeaderDefinitionError(c, "problem in the default constructor",
          e);
    } catch (IllegalAccessException e) {
      throw new HeaderDefinitionError(c, "problem in the default constructor",
          e);
    }
  }

  /**
   * Inspect class.
   *
   * @param c
   *          the c
   * @param errors
   *          the errors
   * @return the j binding[]
   */
  public static JBinding[] inspectClass(
      Class<?> c,
      List<HeaderDefinitionError> errors) {

    if (cache.containsKey(c)) {
      return cache.get(c);
    }

    AnnotatedBindMethod[] bindMethods =
        AnnotatedBindMethod.inspectClass(c, errors);

    return createBindings(c, bindMethods, errors);
  }

  /**
   * Creates the bindings.
   *
   * @param c
   *          the c
   * @param bindMethods
   *          the bind methods
   * @param errors
   *          the errors
   * @return the j binding[]
   */
  private static JBinding[] createBindings(
      Class<?> c,
      AnnotatedBindMethod[] bindMethods,
      List<HeaderDefinitionError> errors) {

    List<JBinding> list = new ArrayList<JBinding>();
    Class<? extends JHeader> target = null;

    for (AnnotatedBindMethod boundMethod : bindMethods) {

      try {

        Bind bind = boundMethod.getMethod().getAnnotation(Bind.class);
        target = bind.to();
        Class<? extends JHeader> source = bind.from();
        Class<? extends JHeader>[] dependencies = bind.dependencies();

        list.add(new AnnotatedBinding(c, source, target, boundMethod,
            dependencies));

      } catch (AnnotatedMethodException e) {
        errors.add(e);
      }

    }

    JBinding[] bindings = list.toArray(new JBinding[list.size()]);
    cache.put(c, bindings);

    return bindings;
  }

  /**
   * Inspect j header class.
   *
   * @param <T>
   *          the generic type
   * @param c
   *          the c
   * @param errors
   *          the errors
   * @return the j binding[]
   */
  public static <T extends JHeader> JBinding[] inspectJHeaderClass(
      Class<T> c,
      List<HeaderDefinitionError> errors) {

    if (cache.containsKey(c)) {
      return cache.get(c);
    }

    AnnotatedBindMethod[] bindMethods =
        AnnotatedBindMethod.inspectJHeaderClass(c, errors);

    Class<T> source = c;
    List<JBinding> list = new ArrayList<JBinding>();
    Class<? extends JHeader> target = null;

    for (AnnotatedBindMethod boundMethod : bindMethods) {

      try {

        Bind bind = boundMethod.getMethod().getAnnotation(Bind.class);
        target = bind.to();
        Class<? extends JHeader>[] dependencies = bind.dependencies();

        list.add(new AnnotatedBinding(c, source, target, boundMethod,
            dependencies));

      } catch (AnnotatedMethodException e) {
        errors.add(e);
      }
    }

    JBinding[] bindings = list.toArray(new JBinding[list.size()]);
    cache.put(c, bindings);

    return bindings;
  }

  /** The annotated bound. */
  private final AnnotatedBindMethod annotatedBound;

  /** The definition class. */
  private final Class<?> definitionClass;

  /** The dependencies. */
  protected final int[] dependencies;

  /**
   * Our working protocol header that we use to peer with packet and dispatch to
   * isBound method.
   */
  private final JHeader header;

  /** The source id. */
  private final int sourceId;

  /** The target class. */
  private final Class<? extends JHeader> targetClass;

  /** The target id. */
  private final int targetId;

  /**
   * Instantiates a new annotated binding.
   *
   * @param definitionClass
   *          the definition class
   * @param source
   *          the source
   * @param target
   *          the target
   * @param bindingMethod
   *          the binding method
   * @param dependencies
   *          the dependencies
   */
  private AnnotatedBinding(
      Class<?> definitionClass,
      Class<? extends JHeader> source,
      Class<? extends JHeader> target,
      AnnotatedBindMethod bindingMethod,
      Class<? extends JHeader>... dependencies) {

    this.definitionClass = definitionClass;
    this.targetClass = target;
    this.annotatedBound = bindingMethod;
    this.dependencies = new int[dependencies.length];
    this.sourceId = JRegistry.lookupId(source);
    this.targetId = JRegistry.lookupId(target);

    /*
     * Convert dependencies array of classes to array int IDs
     */
    int i = 0;
    for (Class<? extends JHeader> c : dependencies) {
      this.dependencies[i++] = JRegistry.lookupId(c);
    }

    header = createHeaderFromClass(target);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jnetpcap.packet.JBinding#getSourceId()
   */
  /**
   * Gets the source id.
   *
   * @return the source id
   * @see org.jnetpcap.packet.JBinding#getSourceId()
   */
  public int getSourceId() {
    return this.sourceId;
  }

  /**
   * Gets the target class.
   *
   * @return the target class
   */
  public Class<? extends JHeader> getTargetClass() {
    return targetClass;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jnetpcap.packet.JBinding#getTargetId()
   */
  /**
   * Gets the target id.
   *
   * @return the target id
   * @see org.jnetpcap.packet.JBinding#getTargetId()
   */
  public int getTargetId() {
    return targetId;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jnetpcap.packet.JBinding#isBound(org.jnetpcap.packet.JPacket, int)
   */
  /**
   * Checks if is bound.
   *
   * @param packet
   *          the packet
   * @param offset
   *          the offset
   * @return true, if is bound
   * @see org.jnetpcap.packet.JBinding#isBound(org.jnetpcap.packet.JPacket, int)
   */
  public boolean isBound(JPacket packet, int offset) {

    packet.getHeader(header);

    return header.isHeaderTruncated() == false && annotatedBound.isBound(packet, offset, header);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.jnetpcap.packet.JDependency#listDependencies()
   */
  /**
   * List dependencies.
   *
   * @return the int[]
   * @see org.jnetpcap.packet.JBinding#listDependencies()
   */
  public int[] listDependencies() {
    return dependencies;
  }

  /**
   * To string.
   *
   * @return the string
   * @see java.lang.Object#toString()
   */
  public String toString() {
    String def = this.definitionClass.getSimpleName();
    String method = this.annotatedBound.getMethod().getName();
    String target = this.targetClass.getSimpleName();

    return def + "." + method + "(JPacket packet, " + target + " header):"
        + "boolean";
  }

  /**
   * Inspect class.
   *
   * @param bindingSuite
   *          the binding suite
   * @param errors
   *          the errors
   * @return the j binding[]
   */
  public static JBinding[] inspectClass(
      Object bindingSuite,
      List<HeaderDefinitionError> errors) {
    return inspectClass(bindingSuite.getClass(), errors);
  }

  /**
   * Inspect object.
   *
   * @param object
   *          the object
   * @param errors
   *          the errors
   * @return the j binding[]
   */
  public static JBinding[] inspectObject(
      Object object,
      List<HeaderDefinitionError> errors) {

    Class<?> c = object.getClass();

    if (cache.containsKey(c)) {
      return cache.get(c);
    }

    AnnotatedBindMethod[] bindMethods =
        AnnotatedBindMethod.inspectObject(object, errors);

    return createBindings(c, bindMethods, errors);

  }

}
TOP

Related Classes of org.jnetpcap.packet.structure.AnnotatedBinding

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.