/*
  Copyright (C) 2006 Helge Hess

  This file is part of JOPE.

  JOPE 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 2, or (at your option) any
  later version.

  JOPE 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 JOPE; see the file COPYING.  If not, write to the
  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.
*/
package org.opengroupware.jope.appserver.publisher;

import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.opengroupware.jope.foundation.NSObject;

/*
 * JoClass
 * 
 * A JoClass represents a set of names as well as declared security info.
 * 
 * It can map to a Java class, but it doesn't need to. Eg it could be a folder
 * object which contains (and 'names') method objects.
 * 
 * Further a JoClass can have 'class' slots. Those are static name=>object
 * mappings accessible to the JoObject.
 */
public class JoClass extends NSObject implements JoObject {
  protected static final Log log = LogFactory.getLog("JoClass");
  
  protected JoClass  joSuperClass;
  protected String[] slotNames;
  protected Object[] slotValues;
  
  public JoClass(JoClass _superClass, Map<String, Object> _slots) {
    this.joSuperClass = _superClass;
    
    if (_slots != null && _slots.size() > 0) {
      this.slotNames  = new String[_slots.size()];
      this.slotValues = new Object[this.slotNames.length];
      
      int i = 0;
      for (String name: _slots.keySet()) {
        this.slotNames[i]  = name;
        this.slotValues[i] = _slots.get(name);
        i++;
      }
    }
  }
  
  /* accessors */
  
  public JoClass joSuperClass() {
    return this.joSuperClass;
  }
  
  /* lookup names for objects of this class */
  
  public Object lookupName(Object _object, String _name, JoContext _ctx) {
    if (_name == null)
      return null;
    
    /* check static slots of class */
    
    if (this.slotNames != null) {
      for (int i = 0; i < this.slotNames.length; i++) {
        if (_name.equals(this.slotNames[i]))
          return this.slotValues[i];
      }
    }
    
    /* check superclass */
    
    if (this.joSuperClass != null)
      return this.joSuperClass.lookupName(_object, _name, _ctx);
    
    /* not found */
    return null;
  }
  
  public boolean declaresName(String _name, boolean _checkSuperClass) {
    if (_name == null)
      return false;
    
    /* check static slots of class */
    
    if (this.slotNames != null) {
      for (int i = 0; i < this.slotNames.length; i++) {
        if (_name.equals(this.slotNames[i]))
          return true;
      }
    }
    
    /* check superclass */
    
    if (_checkSuperClass && this.joSuperClass != null)
      return this.joSuperClass.declaresName(_name, true /* check superclass */);
    
    /* not found */
    return false;
  }
  
  /* Using a JoClass as a JoObject */

  public Object lookupName(String _name, JoContext _ctx, boolean _aquire) {
    log.warn("tried to access JoClass as an JoObject: " + _name);
    return null;
  }
  
  public JoClass joClass() {
    return null; /* the metaclass of a JoClass, not sure whether we need it */
  }


  /* description */
  
  public void appendAttributesToDescription(StringBuffer _d) {
    super.appendAttributesToDescription(_d);
    
    // TODO
  }
}
