Package org.eclipse.jst.pagedesigner.commands.range

Source Code of org.eclipse.jst.pagedesigner.commands.range.DesignEdit

/*******************************************************************************
* Copyright (c) 2006 Sybase, Inc. and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.pagedesigner.commands.range;

import java.util.Stack;
import java.util.Vector;

import org.eclipse.core.runtime.Assert;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.dnd.TemplateTransfer;
import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.css2.CSSUtil;
import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
import org.eclipse.jst.pagedesigner.dom.DOMRange;
import org.eclipse.jst.pagedesigner.dom.EditHelper;
import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
import org.eclipse.jst.pagedesigner.dom.EditValidateUtil;
import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
import org.eclipse.jst.pagedesigner.utils.DOMUtil;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
* @author mengbo
*/
public abstract class DesignEdit {

    private Stack _selections;

  private DOMRange _range;

  private GraphicalViewer _viewer;

  private IDOMPosition _operationPosition;

  private final Document _document;

  private Stack _processedResult;

  /**
   * @param range
   * @param viewer
   */
  public DesignEdit(DOMRange range, GraphicalViewer viewer) {
    setRange(range);
    _viewer = viewer;
    _operationPosition = getRange().getStartPosition();
    _document = ((IDOMNode) _operationPosition.getContainerNode())
        .getModel().getDocument();
  }

 
  /**
   * @return the target document
   */
  protected final Document getDocument() {
        return _document;
    }

    /**
     * @return the result
     */
    protected abstract boolean operate();

  /**
   * @param node
   * @return the text
   */
  protected abstract Text processText(WorkNode node);

  /**
   * @param node
   * @return the node
   */
  protected abstract Node processNode(WorkNode node);

  /**
   * @param node
   * @return the node
   */
  protected abstract Node processContainer(WorkNode node);

  /**
   * @return the dom range
   */
  public DOMRange getRange() {
    return _range;
  }

  void setRange(DOMRange range) {
    range = EditHelper.normal(range);
    IDOMPosition start = EditHelper.ensureDOMPosition(range
        .getStartPosition());
    IDOMPosition end = EditHelper.ensureDOMPosition(range.getEndPosition());
    _range = new DOMRange(start, end);
    EditValidateUtil.validRange(range);
  }

  /**
   * @return the clipboard
   */
  protected Clipboard getClipboard() {
    return new Clipboard(_viewer.getControl().getDisplay());
  }

  /**
   * @return the position
   */
  public IDOMPosition getOperationPosition() {
    // try
    // {
    // Assert.isTrue(_operationPosition != null &&
    // _operationPosition.getContainerNode() != null &&
    // _operationPosition.getOffset() > -1);
    // if (_operationPosition.isText())
    // {
    // int length = ((Text)
    // _operationPosition.getContainerNode()).getLength();
    // Assert.isTrue(_operationPosition.getOffset() >= 0 &&
    // _operationPosition.getOffset() <= length);
    // }
    // }
    // catch (Exception e)
    // {
    // // "Error", "Error in operation location move"
    // PDPlugin.getAlerts().confirm("Alert.DesignEdit.opLocationValidTitle",
    // "Alert.DesignEdit.opLocationValidMessage"); //$NON-NLS-1$
    // //$NON-NLS-2$
    // }

    return _operationPosition;
  }

  /**
   * @param position
   */
  protected void setOperationPosition(IDOMPosition position) {
    if (!EditValidateUtil.validPosition(position)) {
      return;
    }
    position = EditHelper.ensureDOMPosition(position);
    _operationPosition = position;
  }

  /**
   * @return the result of performing the edit
   */
  public boolean perform() {
    boolean result = false;

    result = operate();
    return result;
  }

  /**
   * @return Returns the _viewer.
   */
  public GraphicalViewer getViewer() {
    return _viewer;
  }

  private Stack collectNodes() {
    Node node;
    Stack result = new Stack();
    IDOMPosition start = getRange().getStartPosition(), end = getRange()
        .getEndPosition();
    int pos[] = new int[] { EditModelQuery.getIndexedRegionLocation(start),
        EditModelQuery.getIndexedRegionLocation(end), };
    if (!EditModelQuery.isSame(start, end)) {
      Node ancestor = EditModelQuery.getInstance().getCommonAncestor(
          start, end);
      WorkNode rootWorkNode = new WorkNode(ancestor, pos[0], pos[1]);
      rootWorkNode.setRoot(true);
      result.push(rootWorkNode);
      try {
        // Loop all the children of the ancestor, and and the result
        // will be collected
        if (EditModelQuery.isText(ancestor)) {
          Stack temp = new Stack();
          EditHelper.getInstance().collectNodes(ancestor, pos[0],
              pos[1], ancestor, temp);
          WorkNode wNode = (WorkNode) temp.remove(0);
          wNode.setParent(rootWorkNode);
          result.push(wNode);
        } else {
          node = ancestor.getFirstChild();
          Stack temp = new Stack();
          while (node != null) {
            EditHelper.getInstance().collectNodes(node, pos[0],
                pos[1], ancestor, temp);
            while (temp.size() > 0) {
              WorkNode wNode = (WorkNode) temp.remove(0);
              if (wNode.getNode().getParentNode() == ancestor) {
                wNode.setParent(rootWorkNode);
              }
              result.push(wNode);
            }
            node = node.getNextSibling();
          }
        }
      } catch (Exception e) {
        result.clear();
      }
    }
    return result;
  }

  /**
   * @return Returns the result.
   */
  public Stack getSelections() {
    if (_selections == null) {
      _selections = collectNodes();
    }
    return _selections;
  }

  /**
   * @return the result stack
   */
  public Stack getProcessedResult() {
    if (_processedResult == null) {
      _processedResult = new Stack();
      WorkNode rootNode = getRootWorkNode();
      if (rootNode != null) {
        processNodes(rootNode, _processedResult);
      }
    }
    return _processedResult;
  }

  /**
   * @return the root work node
   */
  protected final WorkNode getRootWorkNode() {
    WorkNode result = null;
    if (getSelections().size() > 0) {
      WorkNode node = (WorkNode) getSelections().get(0);
      while (node.getParent() != null) {
        node = node.getParent();
      }
      result = node;
      Assert.isTrue(node.isRoot());
    }
    return result;
  }

  /**
   * @param node
   * @param result
   * @return true if node
   */
  private final boolean processText(WorkNode node, Stack result) {
    boolean done = false;
    if (EditModelQuery.isText(node.getNode())) {
      Node text = processText(node);
      if (text != null) {
        result.add(text);
      }
      getSelections().remove(node);
      done = true;
    }
    return done;
  }

  /**
   * @param node
   * @param result
   */
  private final void processContainer(WorkNode node, Stack result) {
    processContainer(node);
    getSelections().remove(node);
  }

  /**
   * @param node
   * @param result
   * @return true if done
   */
  private final boolean processChildren(WorkNode node, Stack result) {
    boolean done = false;
    if (getFirstSelectedChild(node) != null) {
      Stack myResult = new Stack();
      {
        WorkNode child = null;
        while ((child = getFirstSelectedChild(node)) != null) {
          {
            processNodes(child, myResult);
          }
        }
        Node newParent = processContainer(node);
        newParent = toBeParent(newParent, myResult);
        result.push(newParent);
      }
      getSelections().remove(node);
      done = true;
    }
    return done;
  }

  /**
   * @param node
   * @param result
   * @return true if done
   */
  private final boolean processChildren1(WorkNode node, Stack result) {
    boolean done = false;
    if (node.getNode().hasChildNodes()) {
      Stack myResult = new Stack();
      {
        Node childNode = node.getNode().getFirstChild();
        Node next = null;
        while (childNode != null) {
          next = childNode.getNextSibling();
          int x1 = EditModelQuery.getNodeStartIndex(childNode) - 1;
          int x2 = EditModelQuery.getNodeEndIndex(childNode) + 1;
          processNodes(new WorkNode(childNode, x1, x2), myResult);
          childNode = next;
        }
        Node newParent = processContainer(node);
        newParent = toBeParent(newParent, myResult);
        result.push(newParent);
      }
      getSelections().remove(node);
      done = true;
    }
    return done;
  }

  /**
   * Process the nodes that are selected, the result is a collection of nodes
   * that either are clones or the nodes cuted.
   *
   * @param node
   * @param result
   */
  protected final void processNodes(WorkNode node, Stack result) {
    WorkNode child = null;
    if (node.isRoot()) {
      while ((child = getFirstSelectedChild(node)) != null) {
        processNodes(child, result);
      }
    } else {
      if (node.isWholeSelected()
          || //
          (!EditModelQuery.isText(node.getNode()) && EditModelQuery
              .getInstance().isSingleRegionNode(node.getNode()))
          || //
          EditModelQuery.isWidget(node.getNode())) {
        Node temp = processNode(node);
        if (temp != null) {
          result.push(temp);
          getSelections().remove(node);
        } else {
          if (!processText(node, result)) {
            if (!processChildren1(node, result)) {
              processContainer(node, result);
            }
          }
        }
      } else {
        if (!processText(node, result)) {
          if (!processChildren(node, result)) {
            processContainer(node, result);
          }
        }
      }
    }
  }

  /**
   * @param result
   */
  protected void setClipboard(Stack result) {
    Node[] nodes = (Node[]) result.toArray(new Node[result.size()]);
    StringBuffer sb = new StringBuffer();
    for (int i = 0, size = nodes.length; i < size; i++) {
      DOMUtil.nodeToString(nodes[i], sb);
    }
    getClipboard().setContents(
        new Object[] { result, sb.toString() },
        new Transfer[] { TemplateTransfer.getInstance(),
            TextTransfer.getInstance() });
  }

  private Node toBeParent(Node parent, Stack children) {
    while (children.size() > 0) {
      parent.appendChild((Node) children.remove(0));
    }
    return parent;
  }

  private WorkNode getFirstSelectedChild(WorkNode node) {
    for (int i = 0, n = getSelections().size(); i < n; i++) {
      WorkNode wNode = (WorkNode) getSelections().get(i);
      if (wNode.getParent() == node) {
        return wNode;
      }
    }
    return null;
  }

  /**
   * @param rootNode
   * @param result
   * @return the node
   */
  Node collectStyleNodes(Node rootNode, Vector result) {
    Element element = null;
    if (rootNode instanceof Element) {
      element = (Element) rootNode;
    } else if (rootNode.getParentNode() != null) {
      element = (Element) rootNode.getParentNode();
    }
    ICSSStyle style = CSSUtil.getCSSStyle(element);

    Node node = EditModelQuery.getDocumentNode(rootNode).createElement(
        "span"); //$NON-NLS-1$
    for (int i = 0, n = result.size(); i < n; i++) {
      node.appendChild((Node) result.elementAt(i));
    }
    ((Element) node).setAttribute(IHTMLConstants.ATTR_STYLE, CSSUtil
        .resolveCSSStyle(style));
    result.removeAllElements();
    result.add(node);
    return node;
  }

  /**
   * @param rootNode
   * @param result
   * @return the node
   */
  protected final Node collectOtherStyles(Node rootNode, Vector result) {
    Node cur = rootNode, prev = null, appendPoint = null;
    if (EditValidateUtil.validNode(rootNode)) {
      while (!EditModelQuery.isDocument(cur)) {
        if (!EditValidateUtil.validNode(cur)) {
          return null;
        }
        String name = cur.getNodeName() != null ? cur.getNodeName()
            .toLowerCase() : ""; //$NON-NLS-1$
        if (EditModelQuery.HTML_STYLE_NODES.contains(name)) {
          if (prev != null) {
            Node newone = cur.cloneNode(false);
            newone.appendChild(prev);
            prev = newone;
          } else {
            prev = cur.cloneNode(false);
            appendPoint = prev;
          }
        }
        cur = cur.getParentNode();
      }
      if (appendPoint != null) {
        for (int i = 0, n = result.size(); i < n; i++) {
          appendPoint.appendChild((Node) result.elementAt(i));
        }
        result.removeAllElements();
        result.add(prev);
      }
    }
    return prev;
  }
}
TOP

Related Classes of org.eclipse.jst.pagedesigner.commands.range.DesignEdit

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.