package org.dbxml.core;

/*
 * dbXML License, Version 1.0
 *
 *
 * Copyright (c) 1999-2001 The dbXML Group, L.L.C.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by
 *        The dbXML Group (http://www.dbxml.com/)."
 *    Alternately, this acknowledgment may appear in the software
 *    itself, if and wherever such third-party acknowledgments normally
 *    appear.
 *
 * 4. The names "dbXML" and "The dbXML Group" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    info@dbxml.com.
 *
 * 5. Products derived from this software may not be called "dbXML",
 *    nor may "dbXML" appear in their name, without prior written
 *    permission of The dbXML Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE DBXML GROUP OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: SystemCollection.java,v 1.37 2001/07/16 03:55:22 tom Exp $
 */

import org.dbxml.server.*;
import org.dbxml.core.*;
import org.dbxml.core.Collection;
import org.dbxml.core.server.*;
import org.dbxml.core.objects.*;
import org.dbxml.xml.*;
import org.dbxml.xml.dom.*;
import org.dbxml.tools.*;

import org.w3c.dom.*;

import java.io.*;
import java.util.*;

/**
 * SystemCollection represents the System Collection.  Beyond
 * standard Collection operations, this class will provide facilities
 * for Schema and SymbolTable management among other things.
 */

public final class SystemCollection extends Collection {
   public static final String CLASSGEN = "classgen";

   public static final String SYSCOL = "system";

   public static final String SYMBOLS = "SysSymbols";
   public static final String OBJECTS = "SysObjects";
   public static final String CONFIGS = "SysConfig";
   public static final String USERS = "SysUsers";
   public static final String GROUPS = "SysGroups";
   public static final String ACCESS = "SysAccess";

   private String classGen = "./classgen";

   public SystemCollection(Database db) {
      super(db);
   }

   void init() throws DBException {
      // Bootstrap the System Collection
      File f = new File(getDatabase().getCollectionRoot(), SYSCOL);
      File cfgDir = new File(System.getProperty(dbXML.PROP_DBXML_HOME), "config");
      
      classGen = getDatabase().getConfig().getAttribute(CLASSGEN, classGen);

      if ( !f.exists() )
         f.mkdirs();

      String SysCol =
         "<collection name=\""+SYSCOL+"\">"
         
         // System Collections
       + "   <collections>"
         
         // Symbol Tables Collection
       + "      <collection name=\""+SYMBOLS+"\" compressed=\"true\">"
       + "         <filer class=\"org.dbxml.core.filer.BTreeFiler\" />"
         // Textual Representation of Hard-coded Symbol Table
       + SymbolTableSymbols.getDefinition()
       + "      </collection>"
         
         // XML Object Configuration Collection
       + "      <collection name=\""+OBJECTS+"\" compressed=\"true\">"
       + "         <filer class=\"org.dbxml.core.filer.BTreeFiler\" />"
       + "      </collection>"

         // System Configuration Collection
       + "      <collection name=\""+CONFIGS+"\" compressed=\"false\" cache=\"false\" >"
       + "         <filer class=\"org.dbxml.core.filer.FSFiler\""
       + "                location=\""+cfgDir.getAbsolutePath()+"\""
       + "                ext=\"xml xsl xsd\" />"
       + "      </collection>"
         
         // User Information Collection
       + "      <collection name=\""+USERS+"\" compressed=\"true\">"
       + "         <filer class=\"org.dbxml.core.filer.BTreeFiler\" />"
       + "      </collection>"
         
         // Group Information Collection
       + "      <collection name=\""+GROUPS+"\" compressed=\"true\">"
       + "         <filer class=\"org.dbxml.core.filer.BTreeFiler\" />"
       + "      </collection>"
         
         // Access Control Collection
       + "      <collection name=\""+ACCESS+"\" compressed=\"true\">"
       + "         <filer class=\"org.dbxml.core.filer.BTreeFiler\" />"
       + "      </collection>"
         
       + "   </collections>"
         
         // System-level XMLObjects
       + "   <xmlobjects>"
       + "      <xmlobject class=\"org.dbxml.core.system.Sequencer\" name=\"sequencer\" />"
       + "   </xmlobjects>"
       + "</collection>";

      try {
         Document sysDoc = DOMParser.toDocument(SysCol);
         Configuration sysCfg = new Configuration(sysDoc.getDocumentElement(), false);
         setConfig(sysCfg);
      }
      catch ( Exception e ) {
         org.dbxml.Debug.println("\u0007FATAL ERROR: Generating System Collection '"+SYSCOL+"'");
         org.dbxml.Debug.printStackTrace(e);
         System.exit(1);
      }
   }

   private String getSymbolTableName(Collection col) {
      String name = col.getCanonicalName();
      int idx = name.indexOf('/', 1);
      name = name.substring(idx+1);
      return name.replace('/', '_');
   }

   /**
    * loadSymbols retrieves the SymbolTable for the specified Collection.
    *
    * @param collection The Collection whose SymbolTable is required
    * @return The requested SymbolTable
    */
   public SymbolTable loadSymbols(Collection collection) throws DBException  {
      String name = getSymbolTableName(collection);

      Collection symCol = getCollection(SYMBOLS);

      SymbolTable symbols = (SymbolTable)symCol.getObject(name);
      if ( symbols == null ) {
         symbols = new SymbolTable();
         saveSymbols(collection, symbols);
      }
      return symbols;
   }

   /**
    * saveSymbols save the SymbolTable for the specified Collection.
    *
    * @param collection The Collection that owns the SymbolTable
    * @param symbols The SymbolTable
    */
   public void saveSymbols(Collection collection, SymbolTable symbols) throws DBException  {
      String name = getSymbolTableName(collection);

      Collection symCol = getCollection(SYMBOLS);

      if ( symbols != null ) {
         symCol.setObject(name, symbols);
         symbols.setDirty(false);
      }
   }
}
