# Class MaterialBundle

java.lang.Object
com.university.bookstore.composite.MaterialBundle

All Implemented Interfaces:
  `MaterialComponent`

public class MaterialBundle extends Object implements MaterialComponent
Composite component in the Composite pattern. Represents a bundle of materials that can contain other components (both leaves and other bundles).

This class implements the MaterialComponent interface and can contain other MaterialComponent objects, enabling recursive composition and unified treatment of individual materials and bundles.

Since:
  2024-09-15
Version:
  3.0
Author:
  Navid Mohaghegh

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `MaterialBundle(String bundleName, double bundleDiscount)`
  Creates a new material bundle with the specified name and discount.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addComponent(MaterialComponent component)`
  Adds a component to this bundle.
  `boolean`
  `containsMaterial(Material material)`
  Checks if this bundle contains the specified material.
  `boolean`
  `containsType(Material.MaterialType type)`
  Checks if this bundle contains any materials of the specified type.
  `boolean`
  `equals(Object obj)`
  `double`
  `getBundleDiscount()`
  Gets the bundle discount rate.
  `String`
  `getBundleName()`
  Gets the bundle name.
  `int`
  `getComponentCount()`
  Gets the number of components in this bundle.
  `List<MaterialComponent>`
  `getComponents()`
  Gets all components in this bundle.
  `String`
  `getDescription()`
  Gets a description of this component.
  `double`
  `getDiscountedPrice()`
  Gets the discounted price of this component.
  `double`
  `getDiscountRate()`
  Gets the discount rate applied to this component.
  `int`
  `getItemCount()`
  Gets the total number of items in this component.
  `List<Material>`
  `getMaterials()`
  Gets all materials contained in this component.
  `List<Material>`
  `getMaterialsByType(Material.MaterialType type)`
  Gets all materials of the specified type in this bundle.
  `double`
  `getPrice()`
  Gets the total price of this component.
  `String`
  `getTitle()`
  Gets the title of this component.
  `double`
  `getTotalSavings()`
  Calculates the total savings from the bundle discount.
  `int`
  `hashCode()`
  `boolean`
  `isLeaf()`
  Checks if this component is a leaf (individual material).
  `boolean`
  `removeComponent(MaterialComponent component)`
  Removes a component from this bundle.
  `String`
  `toString()`

  ### Methods inherited from class java.lang.Object

  `getClass, notify, notifyAll, wait, wait, wait`

  ### Methods inherited from interface com.university.bookstore.composite.MaterialComponent

  `isComposite`

- ## Constructor Details

  - ### MaterialBundle

    public MaterialBundle(String bundleName, double bundleDiscount)
    Creates a new material bundle with the specified name and discount.
    Parameters:
      `bundleName` - the name of the bundle
      `bundleDiscount` - the discount rate (0.0 to 1.0)
    Throws:
      `IllegalArgumentException` - if bundleName is null or empty, or discount is invalid

- ## Method Details

  - ### addComponent

    public void addComponent(MaterialComponent component)
    Adds a component to this bundle.
    Parameters:
      `component` - the component to add
    Throws:
      `IllegalArgumentException` - if component is null

  - ### removeComponent

    public boolean removeComponent(MaterialComponent component)
    Removes a component from this bundle.
    Parameters:
      `component` - the component to remove
    Returns:
      true if the component was removed, false if not found

  - ### getComponents

    public List<MaterialComponent> getComponents()
    Gets all components in this bundle.
    Returns:
      list of components (defensive copy)

  - ### getComponentCount

    public int getComponentCount()
    Gets the number of components in this bundle.
    Returns:
      the component count

  - ### getTitle

    public String getTitle()
    Description copied from interface: `MaterialComponent`
    Gets the title of this component. For individual materials, this is the material title. For bundles, this is the bundle name.
    Specified by:
      `getTitle` in interface `MaterialComponent`
    Returns:
      the component title

  - ### getPrice

    public double getPrice()
    Description copied from interface: `MaterialComponent`
    Gets the total price of this component. For individual materials, this is the material price. For bundles, this is the sum of all contained materials.
    Specified by:
      `getPrice` in interface `MaterialComponent`
    Returns:
      the total price

  - ### getDiscountedPrice

    public double getDiscountedPrice()
    Description copied from interface: `MaterialComponent`
    Gets the discounted price of this component. For individual materials, this applies the material's discount. For bundles, this applies the bundle discount to the total price.
    Specified by:
      `getDiscountedPrice` in interface `MaterialComponent`
    Returns:
      the discounted price

  - ### getDescription

    public String getDescription()
    Description copied from interface: `MaterialComponent`
    Gets a description of this component. Provides detailed information about the component and its contents.
    Specified by:
      `getDescription` in interface `MaterialComponent`
    Returns:
      the component description

  - ### getMaterials

    public List<Material> getMaterials()
    Description copied from interface: `MaterialComponent`
    Gets all materials contained in this component. For individual materials, returns a list containing only itself. For bundles, returns all materials in the bundle (recursively).
    Specified by:
      `getMaterials` in interface `MaterialComponent`
    Returns:
      list of all contained materials

  - ### getItemCount

    public int getItemCount()
    Description copied from interface: `MaterialComponent`
    Gets the total number of items in this component. For individual materials, returns 1. For bundles, returns the sum of all contained items.
    Specified by:
      `getItemCount` in interface `MaterialComponent`
    Returns:
      the total item count

  - ### getDiscountRate

    public double getDiscountRate()
    Description copied from interface: `MaterialComponent`
    Gets the discount rate applied to this component.
    Specified by:
      `getDiscountRate` in interface `MaterialComponent`
    Returns:
      the discount rate (0.0 to 1.0)

  - ### isLeaf

    public boolean isLeaf()
    Description copied from interface: `MaterialComponent`
    Checks if this component is a leaf (individual material).
    Specified by:
      `isLeaf` in interface `MaterialComponent`
    Returns:
      true if this is a leaf component

  - ### getBundleName

    public String getBundleName()
    Gets the bundle name.
    Returns:
      the bundle name

  - ### getBundleDiscount

    public double getBundleDiscount()
    Gets the bundle discount rate.
    Returns:
      the discount rate

  - ### getTotalSavings

    public double getTotalSavings()
    Calculates the total savings from the bundle discount.
    Returns:
      the total savings amount

  - ### containsType

    public boolean containsType(Material.MaterialType type)
    Checks if this bundle contains any materials of the specified type.
    Parameters:
      `type` - the material type to check for
    Returns:
      true if the bundle contains materials of the specified type

  - ### getMaterialsByType

    public List<Material> getMaterialsByType(Material.MaterialType type)
    Gets all materials of the specified type in this bundle.
    Parameters:
      `type` - the material type to filter by
    Returns:
      list of materials of the specified type

  - ### containsMaterial

    public boolean containsMaterial(Material material)
    Checks if this bundle contains the specified material.
    Parameters:
      `material` - the material to check for
    Returns:
      true if the bundle contains the material

  - ### equals

    public boolean equals(Object obj)
    Overrides:
      `equals` in class `Object`

  - ### hashCode

    public int hashCode()
    Overrides:
      `hashCode` in class `Object`

  - ### toString

    public String toString()
    Overrides:
      `toString` in class `Object`