/******************************************************************************* * Copyright (c) 2014, 2015 Cisco Systems, 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 * *******************************************************************************/ package com.cisco.yangide.ext.model.editor.sync; import org.eclipse.text.edits.DeleteEdit; import org.eclipse.text.edits.InsertEdit; import org.eclipse.text.edits.ReplaceEdit; import com.cisco.yangide.core.dom.ASTCompositeNode; import com.cisco.yangide.core.dom.ASTNode; import com.cisco.yangide.core.dom.Module; import com.cisco.yangide.core.dom.SimpleNode; import com.cisco.yangide.ext.model.editor.Activator; import com.cisco.yangide.ext.refactoring.RefactorUtil; /** * @author Konstantin Zaitsev * @date Aug 28, 2014 */ public class SourceNodePropertyUpdater<T extends ASTNode> { protected final DiagramModelAdapter adapter; public SourceNodePropertyUpdater(DiagramModelAdapter adapter) { this.adapter = adapter; } public void updateProperty(T node, String name, Object newValue, int startPosition) { if (isHandleProperty(name)) { SimpleNode<Object> prop = getProperty(node, name); if (prop == null) { // insert new property int pos = node.getBodyStartPosition() + 1; adapter.performEdit( new InsertEdit(pos, System.lineSeparator() + formatTag(node, name, (String) newValue))); } else { // update property adapter.performEdit(new ReplaceEdit(prop.getStartPosition(), prop.getLength() + 1, formatTag(node, name, (String) newValue).trim())); } } else { updateDefaultProperty(node, name, newValue, startPosition); } } protected boolean isHandleProperty(String name) { return false; } protected void updateDefaultProperty(ASTNode node, String name, Object newValue, int startPosition) { SimpleNode<String> prop = null; switch (name) { case "description": prop = node.getDescriptionNode(); break; case "reference": prop = node.getReferenceNode(); break; case "status": prop = node.getStatusNode(); break; case "organization": prop = ((Module) node).getOrganization(); break; case "contact": prop = ((Module) node).getContact(); break; default: Activator.logError("unknoun tag: " + name); return; } if (prop == null) { // insert new property int pos = startPosition; if (name.equals("status")) { if (node.getReferenceNode() != null) { pos = node.getReferenceNode().getEndPosition() + 1; } else if (node.getDescriptionNode() != null) { pos = node.getDescriptionNode().getEndPosition() + 1; } } else if (name.equals("reference") && node.getDescriptionNode() != null) { pos = node.getDescriptionNode().getEndPosition() + 1; } adapter.performEdit(new InsertEdit(pos, System.lineSeparator() + formatTag(node, name, (String) newValue))); } else if (newValue == null || ((String) newValue).isEmpty()) { // delete property if (prop != null) { adapter.performEdit(new DeleteEdit(prop.getStartPosition(), prop.getLength() + 1)); } } else { // update property if (prop != null) { adapter.performEdit(new ReplaceEdit(prop.getStartPosition(), prop.getLength() + 1, formatTag(node, name, (String) newValue).trim())); } } } protected ASTNode getAboveChildNode(ASTCompositeNode parent, ASTNode node) { ASTNode result = null; for (ASTNode child : parent.getChildren()) { if (child == node) { return result; } result = child; } return null; } protected String formatTag(ASTNode node, String name, String value) { return trimTrailingSpaces( RefactorUtil.formatCodeSnipped(name + " \"" + value + "\";", adapter.getIndentLevel(node))); } protected String trimTrailingSpaces(String str) { int len = str.length(); char[] val = str.toCharArray(); while ((len > 0) && (val[len - 1] <= ' ')) { len--; } return (len < str.length()) ? str.substring(0, len) : str; } protected String empty2Quote(String str) { return str == null || str.trim().isEmpty() ? ("\"" + str + "\"") : str; } @SuppressWarnings("unchecked") protected SimpleNode<Object> getProperty(ASTNode node, String name) { if (node instanceof ASTCompositeNode) { for (ASTNode child : ((ASTCompositeNode) node).getChildren()) { if (child instanceof SimpleNode && child.getNodeName().equals(name)) { return (SimpleNode<Object>) child; } } } return null; } }