/******************************************************************************* * 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 java.util.ArrayList; import java.util.List; import org.eclipse.core.filebuffers.FileBuffers; import org.eclipse.core.filebuffers.LocationKind; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; 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.YangCorePlugin; import com.cisco.yangide.core.dom.ASTNamedNode; import com.cisco.yangide.core.dom.Module; import com.cisco.yangide.core.dom.ModuleImport; import com.cisco.yangide.core.dom.QName; import com.cisco.yangide.core.indexing.ElementIndexReferenceInfo; import com.cisco.yangide.core.indexing.ElementIndexReferenceType; import com.cisco.yangide.core.model.YangFile; import com.cisco.yangide.core.model.YangModelManager; import com.cisco.yangide.ext.refactoring.CreateYangFileChange; import com.cisco.yangide.ext.refactoring.RefactorUtil; import com.cisco.yangide.ext.refactoring.YangCompositeChange; import com.cisco.yangide.ext.refactoring.nls.Messages; /** * @author Konstantin Zaitsev * @date Aug 18, 2014 */ public class ChangeRevisionRefactoring extends Refactoring { private IFile file; private Module module; private String revision; private String description; private boolean createNewFile; private List<IPath> references; public ChangeRevisionRefactoring(IFile file, Module module) { this.file = file; this.module = module; this.references = new ArrayList<>(); this.createNewFile = true; } @Override public String getName() { return Messages.ChangeRevisionRefactoring_name; } /** * @return the module */ public Module getModule() { return module; } @Override public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { return new RefactoringStatus(); } @Override public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { return new RefactoringStatus(); } @Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { String editName = Messages.ChangeRevisionRefactoring_changeName; YangCompositeChange composite = new YangCompositeChange(editName); composite.markAsSynthetic(); if (createNewFile) { String source = FileBuffers.getTextFileBufferManager() .getTextFileBuffer(file.getFullPath(), LocationKind.IFILE).getDocument().get(); ASTNamedNode revisionNode = module.getRevisionNode(); source = source.substring(0, revisionNode.getStartPosition()) + getFormattedRevision() + source.substring(revisionNode.getEndPosition() + 1, source.length()); IPath path = file.getFullPath(); path = path.removeFileExtension(); path = path.removeLastSegments(1).append(module.getName() + "@" + revision + ".yang"); //$NON-NLS-1$ //$NON-NLS-2$ composite.add(new CreateYangFileChange(path, source)); } else { ASTNamedNode revisionNode = module.getRevisionNode(); composite.addTextEdit(file.getFullPath().toString(), editName, editName, revisionNode.getNameStartPosition(), revisionNode.getNameLength(), "\"" + revision + "\""); //$NON-NLS-1$//$NON-NLS-2$ composite.addTextEdit(file.getFullPath().toString(), editName, editName, revisionNode.getDescriptionNode().getStartPosition(), revisionNode.getDescriptionNode().getLength() + 1, "description \"" //$NON-NLS-1$ + description + "\";"); //$NON-NLS-1$ } YangCompositeChange refComposite = new YangCompositeChange( Messages.ChangeRevisionRefactoring_updateReferenceChangeName); composite.add(refComposite); QName qname = new QName(module.getName(), null, module.getName(), module.getRevision()); ElementIndexReferenceInfo[] infos = YangModelManager.getIndexManager().searchReference(qname, ElementIndexReferenceType.IMPORT, file.getProject()); for (ElementIndexReferenceInfo info : infos) { if (references.contains(new Path(info.getPath()))) { YangFile yangFile = YangCorePlugin .createYangFile(ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(info.getPath()))); Module refModule = yangFile.getModule(); ModuleImport refImport = refModule.getImportByName(module.getName()); refComposite.addTextEdit(info.getPath(), editName, editName, refImport.getStartPosition(), refImport.getLength() + 1, getFormattedImport(refImport)); } } return composite; } /** * @return the revision */ public String getRevision() { return revision; } /** * @param revision the revision to set */ public void setRevision(String revision) { this.revision = revision; } /** * @return the description */ public String getDescription() { return description; } /** * @param description the description to set */ public void setDescription(String description) { this.description = description; } /** * @return the createNewFile */ public boolean isCreateNewFile() { return createNewFile; } /** * @param createNewFile the createNewFile to set */ public void setCreateNewFile(boolean createNewFile) { this.createNewFile = createNewFile; } /** * @return the file */ public IFile getFile() { return file; } /** * @return the references */ public List<IPath> getReferences() { return references; } /** * @param references the references to set */ public void setReferences(List<IPath> references) { this.references = references; } private String getFormattedRevision() { StringBuilder sb = new StringBuilder(); sb.append("revision \"").append(revision).append("\" {\n"); //$NON-NLS-1$ //$NON-NLS-2$ if (description != null && !description.isEmpty()) { sb.append("description \"").append(description).append("\";\n"); //$NON-NLS-1$ //$NON-NLS-2$ } String reference = module.getRevisionNode().getReference(); if (reference != null && !reference.isEmpty()) { sb.append("reference \"").append(reference).append("\";\n"); //$NON-NLS-1$//$NON-NLS-2$ } sb.append("}\n"); //$NON-NLS-1$ return RefactorUtil.formatCodeSnipped(sb.toString(), 1).trim(); } private String getFormattedImport(ModuleImport moduleImport) { StringBuilder sb = new StringBuilder(); sb.append("import ").append(module.getName()).append("\" {\n"); //$NON-NLS-1$ //$NON-NLS-2$ sb.append("prefix ").append(moduleImport.getPrefix()).append(";\n"); //$NON-NLS-1$ //$NON-NLS-2$ sb.append("revision-date \"").append(revision).append("\";\n"); //$NON-NLS-1$//$NON-NLS-2$ sb.append("}\n"); //$NON-NLS-1$ return RefactorUtil.formatCodeSnipped(sb.toString(), 1).trim(); } }