text: /*
  * Copyright 2003-2010 Tufts University  Licensed under the
   * Educational Community License, Version 2.0 (the "License"); you may
   * not use this file except in compliance with the License. You may
   * obtain a copy of the License at
   * 
   * http://www.osedu.org/licenses/ECL-2.0
   * 
   * Unless required by applicable law or agreed to in writing,
   * software distributed under the License is distributed on an "AS IS"
   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
   * or implied. See the License for the specific language governing
   * permissions and limitations under the License.
   */
  
  /*
   * XMLView.java
   *
   * Created on June 11, 2003, 4:49 PM
   */
  
  package tufts.vue.action;
  
  /**
   *
   * @author  Jay Briedis
   */
  
  import javax.swing.*;
  import java.awt.event.*;
  import java.io.*;
  import java.util.regex.*;
  import java.util.ArrayList;
  import java.awt.Font;
  import java.awt.Color;
  import javax.swing.text.StyledDocument;
  import javax.swing.text.SimpleAttributeSet;
  import javax.swing.text.StyleConstants;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.transform.TransformerException;
  import javax.xml.transform.TransformerFactory;
  import javax.xml.transform.Transformer;
  import org.w3c.dom.Document;
  
  import javax.xml.transform.dom.DOMSource;
  
  import javax.xml.transform.stream.StreamResult;
  
  import tufts.vue.*;
  
  
  public class XMLView extends AbstractAction{ 
      
      private static  String fileName = "default.xml";
      private XMLTextPane xmlArea = null;
      private StyledDocument doc = null;
      private ArrayList braces = null;
      
      
      public XMLView() {
      }
   
      public XMLView(String label) {
          super(label);
          putValue(Action.SHORT_DESCRIPTION,label);
      }
      
      class XMLTextPane extends JTextPane implements Scrollable{
          public boolean getScrollableTracksViewportWidth() {
               return false;
           }
          
      }
      
      public void actionPerformed(ActionEvent e)
      {   
          System.out.println("Action["+e.getActionCommand()+"] invoked...");
          
          if(VUE.getTabbedPane().getSelectedComponent() instanceof MapViewer) {
  
              ActionUtil.marshallMap(new File(fileName));
              
              //create html view from default.xml
              File xmlFile = new File(fileName);
              xmlArea = new XMLTextPane();
              doc = (StyledDocument)xmlArea.getDocument();
              
              xmlArea.setText("");
              xmlArea.setEditable(false);
              xmlArea.setFont(new Font("SansSerif", Font.PLAIN, 14));
              DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
              org.w3c.dom.Document xmlDoc = null;
              try{
                  DocumentBuilder documentBuilder = factory.newDocumentBuilder();
                  xmlDoc = documentBuilder.parse(fileName);
              }catch(Exception ex){
                  System.out.println("problem creating dom object from xml file: "+ex);
              }
              
              try {
                  xmlArea.setText(docToString(xmlDoc));
              }
              catch (TransformerException te){
                  System.out.println("transformer exception: "+te);
              }
              
              JScrollPane pane = new JScrollPane(xmlArea);
              
              String mapName = VUE.getActiveMap().getLabel();
              JTabbedPane tabPane = VUE.getTabbedPane();
              for(int i = 0; i < tabPane.getComponentCount(); i++){
                  if(tabPane.getTitleAt(i).equals(mapName +".xml")){
                      VUE.getTabbedPane().setSelectedIndex(i);
                      return;
                  }
              }
  
              VUE.getTabbedPane().addTab(mapName+".xml", pane);
              VUE.getTabbedPane().setSelectedIndex(VUE.getTabbedPane().getComponentCount()-1);
              //setAttributes();
              
              pane.repaint();
              System.out.println("Action["+e.getActionCommand()+"] completed.");
          }
      }
      /*
      private void setAttributes(){
          SimpleAttributeSet att = new SimpleAttributeSet();
          StyleConstants.setForeground(att, Color.blue);
          for(int i = 0; i < braces.size(); i++)
              doc.setCharacterAttributes(Integer.parseInt((String)braces.get(i)), 1, att, false);
      }*/
      
      private String docToString(org.w3c.dom.Document xmlDoc) throws TransformerException{
          
          DOMSource domSource=new DOMSource(xmlDoc);
          
          StringWriter stringWriter = new StringWriter();
          StreamResult result = new StreamResult(stringWriter);
          
          
          TransformerFactory factory = TransformerFactory.newInstance();
          Transformer transformer = factory.newTransformer();
          
          transformer.transform(domSource, result);        
          
          Pattern p = Pattern.compile("</|<|>");
          String lookUp = stringWriter.toString();
          Matcher m = p.matcher(lookUp);
          StringBuffer sb = new StringBuffer();
          int indent = -2;
          //braces = new ArrayList(); 
          while(m.find()){
              String group = m.group();
              String tab = "";
              String tabInd = "          ";
              
              if(group.equals("</")){
                  
                  for(int i = 0; i < indent; i++)
                      tab += tabInd;
                  indent--;
                  m.appendReplacement(sb, "\n" + tab + "</");
              }
              else if(group.equals("<")){
                  indent++;
                  for(int i = 0; i < indent; i++)
                      tab += tabInd;
                  
                  m.appendReplacement(sb, "\n" + tab + "<");
              }
              else if(group.equals(">")){
                  indent++;
                  for(int i = 0; i < indent; i++)
                      tab += tabInd;
                  if(m.end() < lookUp.length()){
                      Pattern pat = Pattern.compile("\\w|#");
                      Matcher match = pat.matcher(lookUp.substring(m.end(), m.end()+1));
                      boolean b = match.matches();
  
                      if(b)
                      {   m.appendReplacement(sb, ">\n" + tab);
                          
                      }
                      else{
                          m.appendReplacement(sb, ">");
                          
                      }indent--;
                  }
              }
              else if(group.equals(">#")){
                  indent++;
                  for(int i = 0; i < indent; i++)
                      tab += tabInd;
                  
                  m.appendReplacement(sb, ">\n" + tab + "     #" );
                  indent--;
              }
              else if(group.equals(">\\w")){
                  indent++;
                  for(int i = 0; i < indent; i++)
                      tab += tabInd; 
                  
                  m.appendReplacement(sb, ">\n" + tab + "     $1" );
                  indent--;
              }
          }
          m.appendTail(sb);
          
          return sb.toString();
      }
  }
  