package org.eclipse.osbp.dsl.tests.hist.dtos;

import java.beans.PropertyChangeListener;
import java.io.Serializable;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.tests.hist.dtos.HAddressDto;
import org.eclipse.osbp.dsl.tests.hist.dtos.HBaseUUIDDto;
import org.eclipse.osbp.runtime.common.annotations.Dispose;
import org.eclipse.osbp.runtime.common.annotations.DomainReference;
import org.eclipse.osbp.runtime.common.annotations.FilterDepth;

@SuppressWarnings("all")
public class HOrderDto extends HBaseUUIDDto implements IDto, Serializable, PropertyChangeListener {
  private String orderNumber;
  
  @DomainReference
  @FilterDepth(depth = 0)
  private HAddressDto deliveryAddress;
  
  @DomainReference
  @FilterDepth(depth = 0)
  private HAddressDto invoiceAddress;
  
  public HOrderDto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link HOrder} to the dto {@link HOrderDto}.
   * 
   */
  protected void installLazyCollections() {
    super.installLazyCollections();
  }
  
  /**
   * Checks whether the object is disposed.
   * @throws RuntimeException if the object is disposed.
   */
  private void checkDisposed() {
    if (isDisposed()) {
      throw new RuntimeException("Object already disposed: " + this);
    }
  }
  
  /**
   * Calling dispose will destroy that instance. The internal state will be 
   * set to 'disposed' and methods of that object must not be used anymore. 
   * Each call will result in runtime exceptions.<br/>
   * If this object keeps composition containments, these will be disposed too. 
   * So the whole composition containment tree will be disposed on calling this method.
   */
  @Dispose
  public void dispose() {
    if (isDisposed()) {
      return;
    }
    super.dispose();
  }
  
  /**
   * Returns the orderNumber property or <code>null</code> if not present.
   */
  public String getOrderNumber() {
    return this.orderNumber;
  }
  
  /**
   * Sets the <code>orderNumber</code> property to this instance.
   * 
   * @param orderNumber - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setOrderNumber(final String orderNumber) {
    firePropertyChange("orderNumber", this.orderNumber, this.orderNumber = orderNumber );
  }
  
  /**
   * Returns the deliveryAddress property or <code>null</code> if not present.
   */
  public HAddressDto getDeliveryAddress() {
    return this.deliveryAddress;
  }
  
  /**
   * Sets the <code>deliveryAddress</code> property to this instance.
   * 
   * @param deliveryAddress - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setDeliveryAddress(final HAddressDto deliveryAddress) {
    checkDisposed();
    firePropertyChange("deliveryAddress", this.deliveryAddress, this.deliveryAddress = deliveryAddress);
  }
  
  /**
   * Returns the invoiceAddress property or <code>null</code> if not present.
   */
  public HAddressDto getInvoiceAddress() {
    return this.invoiceAddress;
  }
  
  /**
   * Sets the <code>invoiceAddress</code> property to this instance.
   * 
   * @param invoiceAddress - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setInvoiceAddress(final HAddressDto invoiceAddress) {
    checkDisposed();
    firePropertyChange("invoiceAddress", this.invoiceAddress, this.invoiceAddress = invoiceAddress);
  }
  
  public void propertyChange(final java.beans.PropertyChangeEvent event) {
    Object source = event.getSource();
    
    // forward the event from embeddable beans to all listeners. So the parent of the embeddable
    // bean will become notified and its dirty state can be handled properly
    { 
    	super.propertyChange(event);
    }
  }
}
