/*
  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.core;

import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.opengroupware.jope.foundation.NSClassLookupContext;

public class WOCompoundResourceManager extends WOResourceManager {
  
  protected WOResourceManager[] resourceManagers;
  protected Map<String, Class>  classCache;
  
  public WOCompoundResourceManager(List<WOResourceManager> _rms, boolean _c) {
    super(_c);
    this.resourceManagers = _rms.toArray(new WOResourceManager[0]);
    this.classCache       = new HashMap<String, Class>(16);
  }
  
  /* component definitions */

  protected WOComponentDefinition definitionForComponent
    (String _name, String[] _langs, NSClassLookupContext _clsctx)
  {
    for (WOResourceManager rm: this.resourceManagers) {
      WOComponentDefinition cdef;
      
      if ((cdef = rm.definitionForComponent(_name, _langs, _clsctx)) != null)
        return cdef;
    }
    
    return null;
  }
  
  /* resources */
  
  public URL urlForResourceNamed(String _name, String[] _ls) {
    for (WOResourceManager rm: this.resourceManagers) {
      URL url;
      
      if ((url = rm.urlForResourceNamed(_name, _ls)) != null)
        return url;
    }
    
    return null;  
  }
  public InputStream inputStreamForResourceNamed(String _name, String[] _ls) {
    for (WOResourceManager rm: this.resourceManagers) {
      InputStream is;
      
      if ((is = rm.inputStreamForResourceNamed(_name, _ls)) != null)
        return is;
    }
    
    return null;  
  }
  
  /* strings */
  
  public ResourceBundle stringTableWithName(String _name, String _fwname, 
                                            String[] _langs)
  {
    for (WOResourceManager rm: this.resourceManagers) {
      ResourceBundle rb;
      
      if ((rb = rm.stringTableWithName(_name, _fwname, _langs)) != null)
        return rb;
    }
    
    return null;
  }
  
  /* class lookup */
  
  public Class lookupClass(String _name) {
    if (log.isDebugEnabled())
      log.debug("lookup class in compound: " + _name);
    if (_name == null) return null;
    
    /* Note: ConcurrentHashMap cannot store null values */
    Class cls = null;
    synchronized(this) {
      cls = this.classCache.get(_name);
      if (cls != null) return cls;
      if (this.classCache.containsKey(_name)) return null;
    }
    
    for (NSClassLookupContext rm: this.resourceManagers) {
      if ((cls = rm.lookupClass(_name)) != null)
        break;
    }
    
    synchronized(this) {
      this.classCache.put(_name, cls);
    }
    
    if (log.isDebugEnabled()) {
      if (cls == null)
        log.debug("did not find class in compound: " + _name);
    }
    return cls;
  }
  
  /* description */
  
  public void appendAttributesToDescription(StringBuffer _d) {
    super.appendAttributesToDescription(_d);
    
    if (this.resourceManagers != null)
      _d.append(" #rms=" + this.resourceManagers.length);
    else
      _d.append(" no-rms");
  }
}
