1 /******************************************************************************* 2 * Copyright (c) 2005, 2008 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.pde.internal.ui.wizards.product; 15 16 import org.eclipse.jface.text.*; 17 import org.eclipse.pde.internal.core.text.IDocumentAttributeNode; 18 import org.eclipse.pde.internal.core.text.IDocumentElementNode; 19 import org.eclipse.pde.internal.core.util.PDEXMLHelper; 20 import org.eclipse.text.edits.*; 21 22 public class TextEditUtilities { 23 getInsertOperation(IDocumentElementNode node, IDocument doc)24 public static TextEdit getInsertOperation(IDocumentElementNode node, IDocument doc) { 25 node = getHighestNodeToBeWritten(node, doc); 26 if (node.getParentNode() == null) 27 return new InsertEdit(0, node.write(true)); 28 29 if (node.getOffset() > -1) { 30 // this is an element that was of the form <element/> 31 // it now needs to be broken up into <element><new/></element> 32 return new ReplaceEdit(node.getOffset(), node.getLength(), node.write(false)); 33 } 34 // try to insert after last sibling that has an offset 35 TextEdit op = insertAfterSibling(node, doc); 36 37 // insert as first child of its parent if op is null 38 return (op != null) ? op : insertAsFirstChild(node, doc); 39 } 40 addAttributeOperation(IDocumentAttributeNode attr, String newValue, IDocument doc)41 public static TextEdit addAttributeOperation(IDocumentAttributeNode attr, String newValue, IDocument doc) { 42 int offset = attr.getValueOffset(); 43 if (offset > -1) 44 return new ReplaceEdit(offset, attr.getValueLength(), PDEXMLHelper.getWritableString(newValue)); 45 46 IDocumentElementNode node = attr.getEnclosingElement(); 47 if (node.getOffset() > -1) { 48 int len = getNextPosition(doc, node.getOffset(), '>'); 49 return new ReplaceEdit(node.getOffset(), len + 1, node.writeShallow(shouldTerminateElement(doc, node.getOffset() + len))); 50 } 51 return getInsertOperation(node, doc); 52 } 53 shouldTerminateElement(IDocument doc, int offset)54 private static boolean shouldTerminateElement(IDocument doc, int offset) { 55 try { 56 return doc.get(offset - 1, 1).toCharArray()[0] == '/'; 57 } catch (BadLocationException e) { 58 } 59 return false; 60 } 61 getHighestNodeToBeWritten(IDocumentElementNode node, IDocument doc)62 private static IDocumentElementNode getHighestNodeToBeWritten(IDocumentElementNode node, IDocument doc) { 63 IDocumentElementNode parent = node.getParentNode(); 64 if (parent == null) 65 return node; 66 if (parent.getOffset() > -1) { 67 try { 68 String endChars = doc.get(parent.getOffset() + parent.getLength() - 2, 2); 69 return ("/>".equals(endChars)) ? parent : node; //$NON-NLS-1$ 70 } catch (BadLocationException e) { 71 return node; 72 } 73 74 } 75 return getHighestNodeToBeWritten(parent, doc); 76 } 77 insertAfterSibling(IDocumentElementNode node, IDocument doc)78 private static InsertEdit insertAfterSibling(IDocumentElementNode node, IDocument doc) { 79 IDocumentElementNode sibling = node.getPreviousSibling(); 80 for (;;) { 81 if (sibling == null) 82 break; 83 if (sibling.getOffset() > -1) { 84 node.setLineIndent(sibling.getLineIndent()); 85 String sep = TextUtilities.getDefaultLineDelimiter(doc); 86 return new InsertEdit(sibling.getOffset() + sibling.getLength(), sep + node.write(true)); 87 } 88 sibling = sibling.getPreviousSibling(); 89 } 90 return null; 91 } 92 insertAsFirstChild(IDocumentElementNode node, IDocument doc)93 private static InsertEdit insertAsFirstChild(IDocumentElementNode node, IDocument doc) { 94 int offset = node.getParentNode().getOffset(); 95 int length = getNextPosition(doc, offset, '>'); 96 node.setLineIndent(node.getParentNode().getLineIndent() + 3); 97 String sep = TextUtilities.getDefaultLineDelimiter(doc); 98 return new InsertEdit(offset + length + 1, sep + node.write(true)); 99 } 100 getNextPosition(IDocument doc, int offset, char ch)101 private static int getNextPosition(IDocument doc, int offset, char ch) { 102 int i = 0; 103 try { 104 for (i = 0; i + offset < doc.getLength(); i++) { 105 if (ch == doc.get(offset + i, 1).toCharArray()[0]) 106 break; 107 } 108 } catch (BadLocationException e) { 109 } 110 return i; 111 } 112 113 } 114