/******************************************************************************* * 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; import java.io.IOException; import java.io.InputStreamReader; import java.util.jar.JarFile; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.preference.IPreferenceStore; import com.cisco.yangide.core.YangCorePlugin; import com.cisco.yangide.core.YangModelException; import com.cisco.yangide.core.dom.ASTNode; import com.cisco.yangide.core.dom.BaseReference; 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.dom.SubModuleInclude; import com.cisco.yangide.core.dom.TypeReference; 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.ElementIndexType; import com.cisco.yangide.core.model.YangModelManager; import com.cisco.yangide.core.parser.YangFormattingPreferences; import com.cisco.yangide.core.parser.YangParserUtil; import com.cisco.yangide.ui.YangUIPlugin; import com.cisco.yangide.ui.preferences.YangPreferenceConstants; /** * @author Konstantin Zaitsev * @date Aug 1, 2014 */ public final class RefactorUtil { /** * Protect from initialization. */ private RefactorUtil() { // empty block } /** * @param project project * @param node reference node * @return index information about original node that used as reference or <code>null</code> if * node not found. * @see RefactorUtil#resolveIndexInfo(ElementIndexInfo) */ public static ElementIndexInfo getByReference(IProject project, ASTNode node) { QName qname = null; ElementIndexType type = null; if (node instanceof UsesNode) { qname = ((UsesNode) node).getGrouping(); type = ElementIndexType.GROUPING; } else if (node instanceof TypeReference) { qname = ((TypeReference) node).getType(); type = ElementIndexType.TYPE; } else if (node instanceof BaseReference) { qname = ((BaseReference) node).getType(); type = ElementIndexType.IDENTITY; } else if (node instanceof ModuleImport) { ModuleImport moduleImport = (ModuleImport) node; qname = new QName(moduleImport.getName(), moduleImport.getPrefix(), moduleImport.getName(), moduleImport.getRevision()); type = ElementIndexType.MODULE; } else if (node instanceof SubModuleInclude) { SubModuleInclude include = (SubModuleInclude) node; qname = new QName(include.getName(), null, include.getName(), include.getRevision()); type = ElementIndexType.SUBMODULE; } if (qname != null) { ElementIndexInfo[] infos = YangModelManager.search(qname.getModule(), qname.getRevision(), qname.getName(), type, project, null); if (infos.length > 0) { return infos[0]; } } return null; } /** * @param info index info * @return resolved AST node or <code>null</code> if node not found */ public static ASTNode resolveIndexInfo(ElementIndexInfo info) { try { Module module = null; if (info.getEntry() != null && !info.getEntry().isEmpty()) { module = YangCorePlugin.createJarEntry(new Path(info.getPath()), info.getEntry()).getModule(); } else { module = getModule(info.getPath()); } return module.getNodeAtPosition(info.getStartPosition()); } catch (YangModelException e) { return null; } } /** * @param info index info * @return resolved AST node or <code>null</code> if node not found */ public static ASTNode resolveIndexInfo(ElementIndexReferenceInfo info) { try { return getModule(info.getPath()).getNodeAtPosition(info.getStartPosition()); } catch (YangModelException e) { return null; } } /** * @param info index info * @return string content of AST node or <code>null</code> if node not found * @throws CoreException IO errors */ public static String loadIndexInfoContent(ElementIndexInfo info) throws CoreException { ASTNode node = resolveIndexInfo(info); if (node != null) { if (info.getEntry() != null && !info.getEntry().isEmpty()) { try (JarFile jarFile = new JarFile(new Path(info.getPath()).toFile())) { try (InputStreamReader reader = new InputStreamReader( jarFile.getInputStream(jarFile.getEntry(info.getEntry())), "UTF-8")) { //$NON-NLS-1$ char[] cbuf = new char[node.getBodyLength()]; reader.skip(node.getBodyStartPosition()); reader.read(cbuf, 0, node.getBodyLength()); return new String(cbuf); } } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, YangRefactoringPlugin.PLUGIN_ID, "Error", e)); //$NON-NLS-1$ } } else { IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(info.getPath())); return loadNodeContent(node, file); } } return null; } /** * @param node AST node * @param file file where node located * @return string content of node body * @throws CoreException IO errors */ public static String loadNodeContent(ASTNode node, IFile file) throws CoreException { try (InputStreamReader reader = new InputStreamReader(file.getContents(), "UTF-8")) { //$NON-NLS-1$ char[] cbuf = new char[node.getBodyLength()]; reader.skip(node.getBodyStartPosition()); reader.read(cbuf, 0, node.getBodyLength()); return new String(cbuf); } catch (IOException | CoreException e) { throw new CoreException(new Status(IStatus.ERROR, YangRefactoringPlugin.PLUGIN_ID, "Error", e)); //$NON-NLS-1$ } } /** * Format code snippet according formating preferences. * * @param snipped code snippet * @param indentationLevel indentation level * @return formatted code */ public static String formatCodeSnipped(String snipped, int indentationLevel) { YangFormattingPreferences pref = new YangFormattingPreferences(); IPreferenceStore store = YangUIPlugin.getDefault().getPreferenceStore(); pref.setSpaceForTabs(store.getBoolean(YangPreferenceConstants.FMT_INDENT_SPACE)); pref.setIndentSize(store.getInt(YangPreferenceConstants.FMT_INDENT_WIDTH)); pref.setCompactImport(store.getBoolean(YangPreferenceConstants.FMT_COMPACT_IMPORT)); pref.setFormatComment(store.getBoolean(YangPreferenceConstants.FMT_COMMENT)); pref.setFormatStrings(store.getBoolean(YangPreferenceConstants.FMT_STRING)); pref.setMaxLineLength(store.getInt(YangPreferenceConstants.FMT_MAX_LINE_LENGTH)); return YangParserUtil.formatYangSource(pref, snipped.toCharArray(), indentationLevel, System.getProperty("line.separator")); //$NON-NLS-1$ } /** * @param node node to calculate * @return node level */ public static int getNodeLevel(ASTNode node) { int nodeLevel = -1; ASTNode parent = node; while (parent != null) { parent = parent.getParent(); nodeLevel++; } return nodeLevel >= 0 ? nodeLevel : 0; } private static Module getModule(String path) throws YangModelException { return YangCorePlugin.createYangFile(path).getModule(); } }