/*
  Copyright (C) 2008 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.ofs;

import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.opengroupware.jope.ofs.config.IJoConfigurationProvider;
import org.opengroupware.jope.ofs.config.JoConfigContext;
import org.opengroupware.jope.ofs.fs.IOFSFileInfo;
import org.opengroupware.jope.ofs.htaccess.HtConfigBuilder;
import org.opengroupware.jope.ofs.htaccess.HtConfigFile;
import org.opengroupware.jope.ofs.htaccess.HtConfigParser;

/**
 * OFSHtAccessFile
 * <p>
 * Wraps an Apache style .htaccess file as a JoObject. Note that .htaccess is
 * not a valid OFS name, must be 'config.htaccess' or something similiar.
 * <p>
 * This object is just the Jo controller object, the actual HtAccess
 * functionality is in the 'htaccess' subpackage.
 */
public class OFSHtAccessFile extends OFSBaseObject
  implements IJoConfigurationProvider
{
  protected static final Log cfglog = LogFactory.getLog("JoConfig");
  
  protected HtConfigFile configFile; /* 'da cache */
  
  
  /* config file */
  
  /**
   * This method parses and caches the HtConfigFile object represented by this
   * OFS node.
   * 
   * @return an HtConfigFile or null if the parsing failed
   */
  public HtConfigFile configFile() {
    if (this.configFile != null)
      return this.configFile;
    
    /* attempt to retrieve from global cache */
    
    IOFSFileInfo info = this.fileInfo();
    
    if (this.fileManager != null) {
      this.configFile = (HtConfigFile)
        this.fileManager.getCachedObject("OFSHtAccessFile", info);
      if (this.configFile != null)
        return this.configFile;
    }
    
    /* parse new */

    HtConfigParser parser = new HtConfigParser(this.openStream());
    parser.parse();
    if (parser.lastException() != null) {
      log.error("errors parsing config file: " + this.fileInfo(),
          parser.lastException());
    }
    this.configFile = parser.parsedFile();
    
    if (this.fileManager != null)
      this.fileManager.cacheObject("OFSHtAccessFile", info, this.configFile);
    return this.configFile;
  }
  
  
  /* config provider */
  
  /**
   * Walks over the configuration file and creates a Map containing the
   * configured values by evaluating the directives.
   * 
   * @param _cursor    - the object the configuration was looked up in
   * @param _lookupCtx - the context the lookup is relative to
   * @param _ctx       - the IJoContext all this is happening in
   * @return a configuration, or null if no values were added
   */
  public Map<String, ?> buildConfiguration
    (Object _cursor, JoConfigContext _lookupCtx)
  {
    HtConfigFile lCfgFile = this.configFile();
    if (lCfgFile == null) {
      log.debug("got no parsed representation of config: " + this);
      return null;
    }
    
    return HtConfigBuilder.sharedBuilder
      .buildConfiguration(_lookupCtx, lCfgFile);
  }
}
