<?php

require_once 'common/collection/HashMap.php';

/**
 * Basic Bean.
 * 
 * This class holds a Bean.
 * It provides a list of special accesor methods, some in a Java-like manner: 
 * <ul>
 * <li>getX(): X is the name of the attribute to look for.</li>
 * <li>setX(Y): sets value Y to attribute X.</li>
 * <li>isX() - like getX(), but returns a boolean.</li>
 * <li>addToX(Y) - adds Y to X collection.</li>
 * <li>inX(Y) - checks if collection X contains value Y.</li>
 * </ul>
 * The constants allows to change the method prefixes easily. This is not 
 * recommended. However, some people like to "localize" this prefixes.
 * 
 * @author  $Author: pruna $
 * @package common/bean
 * @version $Revision: 1.3 $
 * @created 26-Dec-2005
 * @modified $Date: 2005/12/06 02:56:45 $
 */
class Bean extends HashMap {
    
    /**
     * @const 
     */
    const PREFIX_GET = 'get';
    
    /**
     * @const 
     */
    const PREFIX_SET = 'set';
    
    /**
     * @const 
     */
    const PREFIX_IS = 'is';
    
    /**
     * @const 
     */
    const PREFIX_ADD_TO = 'addTo';
    
    /**
     * @const 
     */
    const PREFIX_IN = 'in';
    
    /**
     * Provides several methods to access collection content.
     *
     * @access    public
     * @param     string    $methodName   Method that was called.
     * @param     array     $params       Parameters passed to method
     * @return    mixed
     */
    public function __call($methodName, $params) {
        if ((($att = $this->attribName(self::PREFIX_GET, $methodName)) !== null) 
            && $this->containsKey($att)) {
            return $this->get($att);
        } elseif ((($att = $this->attribName(self::PREFIX_SET, $methodName)) !== null) 
            && $this->containsKey($att)) {
            return $this->set($att, $params[0]);
        } elseif ((($att = $this->attribName(self::PREFIX_IS, $methodName)) !== null) 
            && $this->containsKey($att)) {
            return (boolean)$this->get($att);
        } elseif ((($att = $this->attribName(self::PREFIX_ADD_TO, $methodName)) !== null) 
            && $this->containsKey($att) && is_array($this->get($att))) {
            $collection = $this->get($att);
            $collection[] = $params[0];
            return $this->set($att, $collection);
        } elseif ((($att = $this->attribName(self::PREFIX_ADD_TO, $methodName)) !== null) 
            && $this->containsKey($att) 
            && ObjectInspector::isA($this->get($att), 'ArrayList')) {
            // or isCollection
            return $this->get($att)->add($params[0]);
        } elseif ((($att = $this->attribName(self::PREFIX_IN, $methodName)) !== null) 
            && $this->containsKey($att) && is_array($this->get($att))) {
            return in_array($params[0], $this->get($att));
        } elseif ((($att = $this->attribName(self::PREFIX_IN, $methodName)) !== null) 
            && $this->containsKey($att) 
            && ObjectInspector::isA($this->get($att), 'ArrayList')) {
            return $this->get($att)->contains($params[0]);
        } else {
            parent::__call($methodName, $params);
        }
    }
    
    /**
     * Auxiliar method to get attribute name from method name.
     *
     * @access  protected
     * @param   mixed     $methodPrefix     Method prefix
     * @param   mixed     $invoked          Full method name
     * @return  mixed     Attribute name or null
     */
    protected function attribName($methodPrefix, $invoked) {
        if ((strlen($invoked) > strlen($methodPrefix)) 
            && (substr($invoked, 0, strlen($methodPrefix)) == $methodPrefix)) {
            return strtolower(substr($invoked, strlen($methodPrefix), 1)) 
                . substr($invoked, strlen($methodPrefix) + 1);
        }
        return null;
    }
    
}

?>