package com.dbxml.db.admin;

/*
 * dbXML - Native XML Database
 * Copyright (C) 1999-2004  The dbXML Group, L.L.C.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Id: DocWrapper.java,v 1.7 2004/08/22 04:18:40 bradford Exp $
 */

import com.dbxml.db.admin.swing.SyntaxTextArea;
import com.dbxml.db.client.CollectionClient;
import com.dbxml.labrador.util.XMLWriter;
import com.dbxml.util.UTF8;
import com.dbxml.xml.dom.DOMHelper;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * DocWrapper
 */

public class DocWrapper {
   public static final int TYPE_NONE = -1;
   public static final int TYPE_NODE = 0;
   public static final int TYPE_TEXT = 1;

   private static final Map extMap = new HashMap();

   static {
      addExtension(SyntaxTextArea.LANG_BATCHFILE, "bat,cmd");
      addExtension(SyntaxTextArea.LANG_CPP, "cpp,cc,hpp,hh,c++");
      addExtension(SyntaxTextArea.LANG_C, "c,h");
      addExtension(SyntaxTextArea.LANG_EIFFEL, "e");
      addExtension(SyntaxTextArea.LANG_IDL, "idl");
      addExtension(SyntaxTextArea.LANG_HTML, "html,htm,asp,cfm,jsp");
      addExtension(SyntaxTextArea.LANG_JAVASCRIPT, "js");
      addExtension(SyntaxTextArea.LANG_JAVA, "java");
      addExtension(SyntaxTextArea.LANG_MAKEFILE, "mak");
      addExtension(SyntaxTextArea.LANG_PATCH, "patch");
      addExtension(SyntaxTextArea.LANG_PERL, "pl,pm");
      addExtension(SyntaxTextArea.LANG_PHP, "php");
      addExtension(SyntaxTextArea.LANG_PROPERTIES, "prop,ini,props,properties");
      addExtension(SyntaxTextArea.LANG_PYTHON, "py");
      addExtension(SyntaxTextArea.LANG_SHELLSCRIPT, "sh,ksh,csh,tcsh");
      addExtension(SyntaxTextArea.LANG_SQL, "sql");
      addExtension(SyntaxTextArea.LANG_TEX, "tex");
      addExtension(SyntaxTextArea.LANG_TSQL, "tsql");
      addExtension(SyntaxTextArea.LANG_XML, "xml,xsd,xsl,dtd,svg");
      addExtension(SyntaxTextArea.LANG_XPATH, "xp,xpath");
      addExtension(SyntaxTextArea.LANG_TEXT, "txt,doc,me");
   }

   protected Object obj;
   protected CollectionClient col;
   protected File file;
   protected String name;
   protected boolean storable;
   protected String language;

   protected DocWrapper() {
   }

   public DocWrapper(Object obj, CollectionClient col, File file, String name, boolean storable, String language) {
      this.obj = obj;
      this.col = col;
      this.file = file;
      this.name = name;
      this.storable = storable;
      this.language = language;
   }

   public DocWrapper(Object obj, CollectionClient col, File file, String name, boolean storable) {
      this(obj, col, file, name, storable, SyntaxTextArea.LANG_XML);
   }

   public DocWrapper(Object obj, CollectionClient col, File file, String name, boolean storable, boolean guessLanguage) {
      this.obj = obj;
      this.col = col;
      this.file = file;
      this.name = name;
      this.storable = storable;
      if ( name != null && guessLanguage )
         language = guessLanguage(name);
   }

   private static void addExtension(String language, String extString) {
      StringTokenizer st = new StringTokenizer(extString, ",");
      while ( st.hasMoreTokens() )
         extMap.put(st.nextToken().trim().toLowerCase(), language);
   }

   protected static String guessLanguage(String filename) {
      int idx = filename.lastIndexOf(".");
      if ( idx != -1 ) {
         String ext = filename.substring(idx + 1).trim().toLowerCase();
         String lang = (String)extMap.get(ext);
         if ( lang != null )
            return lang;
      }
      return SyntaxTextArea.LANG_TEXT;
   }

   public String getLocation() {
      try {
         if ( col != null )
            return col.getCanonicalName();
         else if ( file != null )
            return file.getAbsolutePath();
      }
      catch ( Exception e ) {
         Admin.getInstance().addMessage(e.toString());
         return null;
      }
      return null;
   }

   public void setCollection(CollectionClient col) {
      this.col = col;
   }

   public CollectionClient getCollection() {
      return col;
   }

   public void setFile(File file) {
      this.file = file;
   }

   public File getFile() {
      return file;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String getName() {
      return name;
   }

   public String getLanguage() {
      return language;
   }

   public int getDocumentType() {
      if ( obj instanceof Node )
         return TYPE_NODE;
      else if ( obj instanceof String )
         return TYPE_TEXT;
      else
         return TYPE_NONE;
   }

   public void setDocument(Document res) {
      obj = res;
   }

   public void setNode(Node node) {
      if ( obj instanceof String )
         obj = XMLWriter.toString(node);
      else
         obj = node;
   }

   public void setText(String text) {
      if ( obj instanceof Document || obj instanceof Node ) {
         try {
            obj = DOMHelper.parseText(text);
         }
         catch ( Exception e ) {
            Admin.getInstance().addMessage(e.toString());
            obj = null;
         }
      }
      else
         obj = text;
   }

   public boolean isStorable() {
      return storable;
   }

   public boolean store() {
      if ( storable ) {
         try {
            if ( col != null ) {
               if ( col.getCollectionType() == CollectionClient.TYPE_DOCUMENTS )
                  col.setDocumentAsText(getName(), getText());
               else
                  col.setValue(getName(), UTF8.toUTF8(getText()));
            }
            else if ( file != null ) {
               File target = new File(file, getName());
               FileOutputStream fos = new FileOutputStream(target);
               BufferedOutputStream bos = new BufferedOutputStream(fos, 4096);
               OutputStreamWriter osw = new OutputStreamWriter(bos, "UTF8");
               osw.write(getText());
               osw.flush();
               osw.close();
            }
            return true;
         }
         catch ( Exception e ) {
            Admin.getInstance().addMessage(e.toString());
            return false;
         }
      }
      return false;
   }

   public Document getDocument() {
      try {
         if ( obj instanceof Document )
            return (Document)obj;
         else if ( obj instanceof Node )
            return ((Node)obj).getOwnerDocument();
         else {
            Document d = DOMHelper.parseText((String)obj);
            d.normalize();
            return d;
         }
      }
      catch ( Exception e ) {
         Admin.getInstance().addMessage(e.toString());
         return null;
      }
   }

   public Node getNode() {
      try {
         if ( obj instanceof Node )
            return (Node)obj;
         else {
            Document d = DOMHelper.parseText((String)obj);
            d.normalize();
            return d;
         }
      }
      catch ( Exception e ) {
         Admin.getInstance().addMessage(e.toString());
         return null;
      }
   }

   public String getText() {
      if ( obj instanceof Node )
         return XMLWriter.toString((Node)obj);
      else
         return (String)obj;
   }
}

