wiki:TechnicalInfo/Extensions/AddingModelClasses

Version 3 (modified by smartp@…, 11 months ago) (diff)

--

Adding A Custom System Event Type

This page described the steps necessary to extend Raptor with a new, custom, event class type. In overview, the following steps are necessary:

  1. Construct a new Event Type class which extends an existing base event type.
    1. Add necessary fields to the class.
    2. Add a valid hashcode and equals method that generates the business key of the class.
    3. Add a valid copy constructor for the class.
  2. Construct a hibernate xml file that describes how the new event type class will be persistent in the database.
  3. Add the new event type class and hibernate file to the MUA or ICA's class path.

Constructing a new Event Type classs

A template class to construct a GenericEventType is shown below:

package uk.ac.cardiff.model.event;

import uk.ac.cardiff.utility.EqualsUtil;
import uk.ac.cardiff.utility.HashCodeUtil;
import uk.ac.cardiff.utility.StringUtils;

/**
 * The Class GenericAuthenticationEvent.
 * 
 */
public class GenericAuthenticationEvent extends AuthenticationEvent {

    /**
     * The name of a field not included in any of the superclasses and specific to this event.
     */
    private String someField;

    /**
     * Instantiates a new Generic Authentication Event.
     */
    public GenericAuthenticationEvent() {
        super();
    }

    /**
     * New instance.
     * 
     * @return the Generic Authentication Event
     */
    public static GenericAuthenticationEvent newInstance() {
        return new GenericAuthenticationEvent();
    }

    /**
     * Copy constructor.
     * 
     * @param event
     *            the event to copy
     */
    protected GenericAuthenticationEvent(GenericAuthenticationEvent event) {
        super(event);
        someField = event.getSomeField();

    }

    /**
     * Copy method. Alternative to clone. Returns a copied version of this event.
     * 
     * @return the Generic Authentication Event
     */
    public GenericAuthenticationEvent copy() {
        return new GenericAuthenticationEvent(this);
    }

    /**
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if ((obj == null) || (obj.getClass() != this.getClass()))
            return false;
        GenericAuthenticationEvent that = (GenericAuthenticationEvent) obj;
        boolean areEqual = EqualsUtil.areEqual(this.getEventTimeMillis(), that.getEventTimeMillis()) && EqualsUtil.areEqual(this.getEventId(), that.getEventId())
                && EqualsUtil.areEqual(this.getAuthenticationType(), that.getAuthenticationType()) && EqualsUtil.areEqual(this.getServiceHost(), that.getServiceHost())
                && EqualsUtil.areEqual(this.getResourceHost(), that.getResourceHost()) && EqualsUtil.areEqual(this.getPrincipalName(), that.getPrincipalName())
                && EqualsUtil.areEqual(this.getServiceId(), that.getServiceId()) && EqualsUtil.areEqual(this.getEventType(), that.getEventType())
                && EqualsUtil.areEqual(this.getResourceId(), that.getResourceId()) &&
                // all new fields should be included in the quality method under here.
                EqualsUtil.areEqual(this.getSomeField(), that.getSomeField());

        return areEqual;
    }

    /**
     * For hibernate, so the hashcode can be persisted.
     * 
     * @return the hash code
     */
    public int getHashCode() {
        return hashCode();
    }

    /**
     * For hibernate, does nothing as the hascode is computed on the fly from the <code>hashCode</code> method.
     * 
     * @param hashCode
     *            the new hash code
     */
    public void setHashCode(int hashCode) {

    }

    /**
     * create a unique hash, with as uniform a distribution as possible.
     * 
     * @return the int
     */
    @Override
    public int hashCode() {
        int hash = HashCodeUtil.SEED;
        // all inherited fields are hashed here.
        hash = HashCodeUtil.hash(hash, getEventTimeMillis());
        hash = HashCodeUtil.hash(hash, getAuthenticationType());
        hash = HashCodeUtil.hash(hash, getEventId());
        hash = HashCodeUtil.hash(hash, getServiceHost());
        hash = HashCodeUtil.hash(hash, getResourceHost());
        hash = HashCodeUtil.hash(hash, getPrincipalName());
        hash = HashCodeUtil.hash(hash, getEventType());
        hash = HashCodeUtil.hash(hash, getServiceId());
        hash = HashCodeUtil.hash(hash, getResourceId());
        // all new fields part of the business key should be hashed below.
        hash = HashCodeUtil.hash(hash, getSomeField());

        return hash;

    }

    /**
     * Automatic construction of a basic to string method for this class using reflection. Does not require modification unless different behavior is desired.
     */
    public String toString() {
        return StringUtils.buildToString(this);
    }

    /**
     * @param someField
     *            the someField to set
     */
    public void setSomeField(String someField) {
        this.someField = someField;
    }

    /**
     * @return the someField
     */
    public String getSomeField() {
        return someField;
    }

}

The class should be changed to whatever you desire, although the package should stay the same and hence should be placed inside a matching directory structure (allowing other package names may be added in the future).

The new class should contain any new fields which are specific to the new event, but not the same as fields in any of the superclasses. The fields already in the AuthenticationEvent and Event classes are:

  1. authenticationType - AuthenticationEvent.
  2. principalName - AuthenticationEvent.
  3. principalInformation.school - AuthenticationEvent.
  4. principalInformation.affiliation - AuthenticationEvent.
  5. eventTime - Event.
  6. serviceId - Event.
  7. eventType - Event.
  8. serviceHost - Event.
  9. resourceHost - Event.
  10. resourceId - Event.

Each new field should have associated GET and SET methods e.g.:

/**
     * @param someField
     *            the someField to set
     */
    public void setSomeField(String someField) {
        this.someField = someField;
    }

    /**
     * @return the someField
     */
    public String getSomeField() {
        return someField;
    }

The copy constructor (see the comments in the code), should contain a mapping from the input event class to the current event class e.g.

    /**
     * Copy constructor.
     * 
     * @param event
     *            the event to copy
     */
    protected GenericAuthenticationEvent(GenericAuthenticationEvent event) {
        super(event);
        someField = event.getSomeField();
        ...
        otherField = event.getOtherField();

    }

The hashcode() and equals() methods should be completed to include the new fields e.g.

public int hashCode() {
        int hash = HashCodeUtil.SEED;
        // all inherited fields are hashed here.
        hash = HashCodeUtil.hash(hash, getEventTimeMillis());
        hash = HashCodeUtil.hash(hash, getAuthenticationType());
        hash = HashCodeUtil.hash(hash, getEventId());
        hash = HashCodeUtil.hash(hash, getServiceHost());
        hash = HashCodeUtil.hash(hash, getResourceHost());
        hash = HashCodeUtil.hash(hash, getPrincipalName());
        hash = HashCodeUtil.hash(hash, getEventType());
        hash = HashCodeUtil.hash(hash, getServiceId());
        hash = HashCodeUtil.hash(hash, getResourceId());
        // all new fields part of the business key should be hashed below.
        hash = HashCodeUtil.hash(hash, getSomeField());

        return hash;

    }

and

 public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if ((obj == null) || (obj.getClass() != this.getClass()))
            return false;
        GenericAuthenticationEvent that = (GenericAuthenticationEvent) obj;
        boolean areEqual = EqualsUtil.areEqual(this.getEventTimeMillis(), that.getEventTimeMillis()) && EqualsUtil.areEqual(this.getEventId(), that.getEventId())
                && EqualsUtil.areEqual(this.getAuthenticationType(), that.getAuthenticationType()) && EqualsUtil.areEqual(this.getServiceHost(), that.getServiceHost())
                && EqualsUtil.areEqual(this.getResourceHost(), that.getResourceHost()) && EqualsUtil.areEqual(this.getPrincipalName(), that.getPrincipalName())
                && EqualsUtil.areEqual(this.getServiceId(), that.getServiceId()) && EqualsUtil.areEqual(this.getEventType(), that.getEventType())
                && EqualsUtil.areEqual(this.getResourceId(), that.getResourceId()) &&
                // all new fields should be included in the equality method under here.
                EqualsUtil.areEqual(this.getSomeField(), that.getSomeField()) &&
                .....;

        return areEqual;
    }

Hibernate Config File