Package fbench.dom

Source Code of fbench.dom.DOMTextModel

//Copyright (c)2005 Holobloc Inc.
//Contributed to the OOONEIDA FBench project under the Common Public License.
package fbench.dom;

import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;

import fbench.LibraryElementView;
//import fbench.XMLCodeGenerator;
import fbench.dom.events.ElementSelectionEvent;
import fbench.tree.DOMTree;

import org.apache.xerces.dom.AttrImpl;
import org.apache.xerces.dom.DocumentImpl;
import org.apache.xerces.dom.events.MutationEventImpl;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.MutationEvent;

/**
* A model for displaying and navigating in a JTextArea the XML source code of
* an IEC 61499 LibraryElement whose underlying model is a DOM Document.
*
* @author JHC
* @version 20080515/DG - Moved Xml writer to its own class.
* @version 20051115/JHC - Made a DOM EventListener displaying only selected
*          Element.
* @version 20050420/JHC
*/
public class DOMTextModel extends ElementModel implements EventListener,
    DOMWriterListener {
  protected JTextArea textarea;
  protected Hashtable<Element, Point> selectionRanges;
  protected Document document;

  private boolean modified = false;

  public DOMTextModel(JTextArea textArea, Document document) {
    super();
    this.textarea = textArea;

    this.textarea.addKeyListener(new KeyListener() {
      public void keyPressed(KeyEvent evt) {
      }

      public void keyReleased(KeyEvent evt) {
      }

      public void keyTyped(KeyEvent evt) {
        setModified(true);
      }
    });
    this.selectionRanges = new Hashtable<Element, Point>();
    setDocument(document);
  }

  public boolean isModified() {
    return modified;
  }

  public void setModified(boolean mod) {
    modified = mod;
  }

  /** Set the document and refresh the display. */
  public void setDocument(Document doc) {
    if (this.document != null) {
      ((DocumentImpl) document).removeEventListener(
          MutationEventImpl.DOM_ATTR_MODIFIED, this, false);
      ((DocumentImpl) document).removeEventListener(
          MutationEventImpl.DOM_CHARACTER_DATA_MODIFIED, this, false);
      ((DocumentImpl) document).removeEventListener(
          MutationEventImpl.DOM_NODE_INSERTED, this, false);
      ((DocumentImpl) document).removeEventListener(
          MutationEventImpl.DOM_NODE_REMOVED, this, false);
      ((DocumentImpl) document).removeEventListener(
          "ElementSelectionEvent", this, false);
    }

    this.document = doc;
    this.selectionRanges.clear();
    // FIXED: Gsha041 added a MutationEvent listener :P
    // ((org.w3c.dom.events.EventTarget)
    // doc).addEventListener("MutationEvent", this,
    // false);
    ((DocumentImpl) document).addEventListener(
        MutationEventImpl.DOM_ATTR_MODIFIED, this, false);
    ((DocumentImpl) document).addEventListener(
        MutationEventImpl.DOM_CHARACTER_DATA_MODIFIED, this, false);
    ((DocumentImpl) document).addEventListener(
        MutationEventImpl.DOM_NODE_INSERTED, this, false);
    ((DocumentImpl) document).addEventListener(
        MutationEventImpl.DOM_NODE_REMOVED, this, false);
    ((DocumentImpl) document).addEventListener("ElementSelectionEvent",
        this, false);

    // textarea.setText("");
    // textarea.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    // Element rootElement = document.getDocumentElement();
    // String root = rootElement.getNodeName();
    // textarea.append("<!DOCTYPE " + root + " SYSTEM
    // \""+this.document.getDoctype().getSystemId()+"\">\n");
    //
    // /*textarea.append("<!DOCTYPE " + root
    // // TODO: change to auck uni website?
    // + " SYSTEM \"http://www.holobloc.com/xml/");
    // textarea.append(root.equals("DataType") ? root : "LibraryElement");
    // textarea.append(".dtd\" >\n");*/
    // write(rootElement, "");

    try {
      textarea.setText(DOMWriter.writeXmlString(this.document, this));
    } catch (XmlException e) {
      e.printStackTrace();
    }
  }

  public void scrollToLine(int lineNum) {
    try {
      textarea.setCaretPosition(textarea.getLineStartOffset(lineNum));
    } catch (BadLocationException blex) {
      // Eg if lineNum = 0.. -1 -> line -1 does not exist... (but return
      // no indent.. cause that is right)
      blex.printStackTrace();
    }
  }

  // /**
  // * Write out the given DOM Element and its children to the text area with
  // * the given indentation.
  // */
  // private void write(Element el, String indent) {
  // Point p = new Point();
  // textarea.append(indent);
  // p.x = textarea.getText().length();
  // textarea.append("<");
  // String nname = el.getNodeName();
  // textarea.append(nname);
  // NamedNodeMap atts = el.getAttributes();
  // int n = atts.getLength();
  // if (n > 0) {
  // for (int i = 0; i < n; i++) {
  // Attr att = (Attr) atts.item(i);
  // textarea.append(" ");
  // textarea.append(att.getName());
  // textarea.append("=\"");
  // String val = att.getValue();
  // val = XMLCodeGenerator.replaceReservedCharacters(val);
  // textarea.append(val);
  // textarea.append("\"");
  // }
  // }
  // NodeList nodes = el.getChildNodes();
  // n = nodes.getLength();
  // if (n == 0) {
  // textarea.append("/>\n");
  // } else {
  // textarea.append(">\n");
  // String newindent = indent + " ";
  // for (int i = 0; i < n; i++)
  // write((Element) nodes.item(i), newindent);
  // textarea.append(indent);
  // textarea.append("</");
  // textarea.append(nname);
  // textarea.append(">\n");
  // }
  // p.y = textarea.getText().length() - 1;
  // selectionRanges.put(el, p);
  // }
  //
  // private String writeElement(Element el, String indent) {
  // StringBuilder str = new StringBuilder();
  // str.append(indent);
  // str.append("<");
  // String nname = el.getNodeName();
  // str.append(nname);
  // NamedNodeMap atts = el.getAttributes();
  // int n = atts.getLength();
  // if (n > 0) {
  // for (int i = 0; i < n; i++) {
  // Attr att = (Attr) atts.item(i);
  // str.append(" ");
  // str.append(att.getName());
  // str.append("=\"");
  // String val = att.getValue();
  // val = XMLCodeGenerator.replaceReservedCharacters(val);
  // str.append(val);
  // str.append("\"");
  // }
  // }
  // NodeList nodes = el.getChildNodes();
  // n = nodes.getLength();
  // if (n == 0) {
  // str.append("/>\n");
  // } else {
  // str.append(">\n");
  // String newindent = indent + " ";
  // for (int i = 0; i < n; i++)
  // str.append(writeElement((Element) nodes.item(i), newindent));
  // str.append(indent);
  // str.append("</");
  // str.append(nname);
  // str.append(">\n");
  // }
  //
  // return str.toString();
  // }

  // private void updateSelRange(int startUpdate, int incrInLength) {
  // Enumeration<Point> points = selectionRanges.elements();
  // // System.out.println("updateSelRange " + StartUpdate + " " +
  // // incrInLength);
  // while (points.hasMoreElements()) {
  // Point p = points.nextElement();
  // // System.out.println("old " + p.toString());
  // if (p.x > startUpdate)
  // p.x += incrInLength;
  // if (p.y > startUpdate)
  // p.y += incrInLength;
  // // System.out.println("new " + p.toString());
  //    }
  //  }

  // /**
  // * @return space between position & start of line
  // */
  // private String getIndentStr(int position) {
  // try {
  // int lineNum = textarea.getLineOfOffset(position);
  // int prevEndIndex = textarea.getLineEndOffset(lineNum - 1);
  // // int startIndex = textarea.getLineStartOffset(lineNum);
  // StringBuilder str = new StringBuilder();
  // for (int i = 0; i < position - prevEndIndex; i++) {
  // str.append(" ");
  // }
  // return str.toString();// textarea.getText(prevEndIndex+1,
  // // position-prevEndIndex+1);
  // } catch (BadLocationException blex) {
  // // Eg if lineNum = 0.. -1 -> line -1 does not exist... (but return
  // // no indent.. cause that is right)
  // blex.printStackTrace();
  // return "";
  // }
  // }

  public void handleEvent(Event evt) {
    // System.out.println("[DOMTextModel] got event:" + evt.toString());
    if (evt instanceof MutationEvent) {
      // This should re-draw all the xml on addition of node etc...
      try {
        MutationEvent mevt = (MutationEvent) evt;
        Element el = null;

        if (mevt.getType().equals(MutationEventImpl.DOM_ATTR_MODIFIED)) {
          AttrImpl attr = (AttrImpl) mevt.getRelatedNode();
          el = attr.getOwnerElement();
        } else
          el = (Element) mevt.getRelatedNode();

        // There's no point replacing the text selectively because it's
        // going to rewrite the whole document anyway...
        this.rewrite();
        Point p = selectionRanges.get(el);
        textarea.setCaretPosition(p.x);

        // // System.out.println("[DOMTextModel] got Mutation:" +
        // // mevt.toString() + " " + mevt.getType());
        // if
        // (mevt.getType().equals(MutationEventImpl.DOM_ATTR_MODIFIED))
        // {
        // // Get Node
        // // AttrImpl attr = (AttrImpl) mevt.getRelatedNode();
        // // Get Parent Element (Cuz node is an Attribute)
        // // Element el = attr.getOwnerElement();
        //
        // // Get location of this element in textarea
        // Point oldRange = selectionRanges.get(el);
        // int position = oldRange.x;
        //
        // // Get the new element text
        // String elString = DOMWriter.writeXmlString(el, this);
        //
        // // Replace only the relevant section of text.
        // textarea.replaceRange("", position, oldRange.y);
        // textarea.insert(elString, position);
        //
        // // Update the stored range -- bugged!!!
        //
        // int difference = elString.length()
        // - (oldRange.y - oldRange.x);
        // for (Point p : selectionRanges.values()) {
        // if (p.x > position) {
        // p.x += difference;
        // if (p.y > position)
        // p.y += difference;
        // }
        // }
        //
        // Point newRange = selectionRanges.get(el);
        // newRange.x = position;
        // newRange.y = position + elString.length();
        // // ----
        //
        // // Set the caret position
        // textarea.requestFocus();
        // textarea.setCaretPosition(newRange.x);
        // // textarea.setSelectionStart(newRange.x);
        // // textarea.setSelectionEnd(newRange.y);
        // } else {
        // this.rewrite();
        // Point p = selectionRanges.get(el);
        // textarea.setCaretPosition(p.x);
        // }

        modified = true;
        // evt.stopPropagation(); // event handled for the last time( is
        // it ?)
      } catch (Exception ex) {
        ex.printStackTrace();
      }

    } else if (evt instanceof ElementSelectionEvent) {
      Element e = ((ElementSelectionEvent) evt).getSelectedElement();
      Point p = selectionRanges.get(e);
      textarea.requestFocus();
      // textarea.setSelectionStart(p.x);
      // textarea.setSelectionEnd(p.y);
      textarea.setCaretPosition(p.x);
    }
  }

  public void setElement(Element el) {
    super.setElement(el);
    ((org.w3c.dom.events.EventTarget) el).addEventListener("MutationEvent",
        this, false);
    if (el == document.getDocumentElement())
      setDocument(document);
    else {
      try {
        textarea.setText(DOMWriter.writeXmlString(el, this));
      } catch (XmlException e) {
        e.printStackTrace();
      }
      // textarea.setText("");
      // write(el, "");
    }
  }

  public void rewrite() {
    try {
      selectionRanges.clear();
      textarea.setText(DOMWriter.writeXmlString(this.document, this));
    } catch (XmlException e) {
      e.printStackTrace();
    }
  }

  public String getText(boolean forSave) {
    if (forSave)
      this.modified = false;
    return textarea.getText();
  }

  /*
   * (non-Javadoc)
   *
   * @see fbench.dom.DOMWriterListener#beginElement(org.w3c.dom.Element, int)
   */
  @Override
  public void beginElement(Element element, int position) {
    selectionRanges.put(element, new Point(position, 0));
  }

  /*
   * (non-Javadoc)
   *
   * @see fbench.dom.DOMWriterListener#endElement(org.w3c.dom.Element, int)
   */
  @Override
  public void endElement(Element element, int position) {
    Point p = selectionRanges.get(element);
    if (p != null)
      p.y = position;
  }
}
TOP

Related Classes of fbench.dom.DOMTextModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.