/******************************************************************************* * 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.refactoring.code; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.Refactoring; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import com.cisco.yangide.core.dom.ASTNamedNode; import com.cisco.yangide.core.dom.ASTNode; import com.cisco.yangide.core.dom.GroupingDefinition; import com.cisco.yangide.core.dom.Module; import com.cisco.yangide.core.dom.QName; import com.cisco.yangide.core.dom.UsesNode; import com.cisco.yangide.core.indexing.ElementIndexInfo; import com.cisco.yangide.core.indexing.ElementIndexReferenceInfo; import com.cisco.yangide.core.indexing.ElementIndexReferenceType; import com.cisco.yangide.core.model.YangModelManager; import com.cisco.yangide.ext.refactoring.RefactorUtil; import com.cisco.yangide.ext.refactoring.YangCompositeChange; import com.cisco.yangide.ext.refactoring.YangRefactoringPlugin; /** * @author Konstantin Zaitsev * @date Aug 6, 2014 */ public class InlineGroupingRefactoring extends Refactoring { private ASTNamedNode node; private boolean deleteGrouping; private boolean inlineAll; private IFile file; public InlineGroupingRefactoring(IFile file, ASTNamedNode node) { this.file = file; this.node = node; this.inlineAll = node instanceof GroupingDefinition; } @Override public String getName() { return "Inline Grouping"; } @Override public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { return new RefactoringStatus(); } @Override public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { return new RefactoringStatus(); } /** * @return the node */ public ASTNamedNode getNode() { return node; } /** * @return the deleteGrouping */ public boolean isDeleteGrouping() { return deleteGrouping; } /** * @param deleteGrouping the deleteGrouping to set */ public void setDeleteGrouping(boolean deleteGrouping) { this.deleteGrouping = deleteGrouping; } /** * @return the inlineAll */ public boolean isInlineAll() { return inlineAll; } /** * @param inlineAll the inlineAll to set */ public void setInlineAll(boolean inlineAll) { this.inlineAll = inlineAll; } @Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { String editName = "Inline grouping"; IFile groupFile = file; ASTNamedNode groupNode = node; String groupContent = null; // get content of grouping element if (node instanceof UsesNode) { ElementIndexInfo ref = RefactorUtil.getByReference(file.getProject(), node); groupContent = RefactorUtil.loadIndexInfoContent(ref); groupNode = (ASTNamedNode) RefactorUtil.resolveIndexInfo(ref); groupFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(ref.getPath())); } else { groupContent = RefactorUtil.loadNodeContent(groupNode, groupFile); } groupContent = trimGroupContent(groupContent); groupContent = formatGroupContent(groupContent, node); if (groupContent == null || groupNode == null) { throw new CoreException( new Status(IStatus.ERROR, YangRefactoringPlugin.PLUGIN_ID, "Cannot get grouping content")); } YangCompositeChange composite = new YangCompositeChange("Inline"); composite.markAsSynthetic(); if (!isInlineAll()) { // in this case UsesNode is selected composite.addTextEdit(file.getFullPath().toString(), editName, editName, node.getStartPosition(), node.getLength() + 1, groupContent); } else { // inline all occurrence if (isDeleteGrouping()) { // delete orignal group composite.addTextEdit(groupFile.getFullPath().toString(), editName, "Delete grouping declaration", groupNode.getStartPosition(), groupNode.getLength() + 1, ""); } Module module = (Module) groupNode.getModule(); QName qname = new QName(module.getName(), null, groupNode.getName(), module.getRevision()); ElementIndexReferenceInfo[] infos = YangModelManager.getIndexManager().searchReference(qname, ElementIndexReferenceType.USES, groupFile.getProject()); pm.beginTask("Inline references", infos.length); for (ElementIndexReferenceInfo info : infos) { ASTNode usesNode = RefactorUtil.resolveIndexInfo(info); String content = formatGroupContent(groupContent, usesNode); composite.addTextEdit(info.getPath(), editName, editName, usesNode.getStartPosition(), usesNode.getLength() + 1, content); pm.worked(1); } pm.done(); } return composite; } /** * Removed brackets from group body content. * * @param content * @return trimmed group body */ private String trimGroupContent(String content) { if (content == null) { return null; } String str = content.trim(); if (str.indexOf('{') >= 0) { str = str.substring(str.indexOf('{') + 1, str.length()); } if (str.lastIndexOf('}') >= 0) { str = str.substring(0, str.lastIndexOf('}')); } return str; } /** * @param content content to forma * @param node ast node for replacement to calculate indentation level * @return formatted string */ private String formatGroupContent(String content, ASTNode node) { if (content == null) { return null; } return RefactorUtil.formatCodeSnipped(content, RefactorUtil.getNodeLevel(node)); } }