/******************************************************************************* * Copyright (c) 2012 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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 * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.cdi.text.ext.test; import java.util.ArrayList; import java.util.Collection; import java.util.List; import junit.framework.Assert; import junit.framework.TestCase; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; import org.eclipse.jdt.internal.ui.text.JavaWordFinder; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.FindReplaceDocumentAdapter; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector; import org.eclipse.jface.text.hyperlink.IHyperlink; import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.IModelManager; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.sse.ui.StructuredTextEditor; import org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorPart; import org.jboss.tools.cdi.core.ICDIElement; import org.jboss.tools.cdi.text.ext.hyperlink.ITestableCDIHyperlink; import org.jboss.tools.common.EclipseUtil; import org.jboss.tools.common.editor.ObjectMultiPageEditor; import org.jboss.tools.common.model.ui.editor.EditorPartWrapper; import org.jboss.tools.common.model.ui.texteditors.XMLTextEditorStandAlone; import org.jboss.tools.common.text.ext.hyperlink.AbstractHyperlink; import org.jboss.tools.common.text.ext.hyperlink.HyperlinkDetector; import org.jboss.tools.common.text.ext.hyperlink.IHyperlinkRegion; import org.jboss.tools.common.text.ext.util.AxisUtil; import org.jboss.tools.common.util.FileUtil; import org.jboss.tools.jst.web.ui.internal.editor.jspeditor.JSPMultiPageEditor; import org.jboss.tools.jst.web.ui.internal.editor.jspeditor.JSPMultiPageEditorPart; import org.jboss.tools.jst.web.ui.internal.text.ext.hyperlink.ELHyperlinkDetector; import org.jboss.tools.jst.web.ui.editors.WebCompoundEditor; public class CDIHyperlinkTestUtil extends TestCase{ public static void checkRegionsInJar(IProject project, String fullyQualifiedName, List<TestRegion> regionList, AbstractHyperlinkDetector hlDetector) throws Exception { IJavaProject javaProject = EclipseUtil.getJavaProject(project); assertNotNull("Java Project is null", javaProject); IType type = javaProject.findType(fullyQualifiedName); assertNotNull("Type is not found", type); assertTrue("Type must be exist", type.exists()); IEditorInput editorInput = EditorUtility.getEditorInput(type); IEditorPart editorPart = EditorUtility.openInEditor(type); checkRegions(fullyQualifiedName, editorInput, editorPart, regionList, hlDetector); } protected static ISourceViewer getViewer(IEditorPart editor){ if(editor instanceof JavaEditor){ return ((JavaEditor)editor).getViewer(); }else{ Assert.fail("editor must be instanceof JavaEditor"); } return null; } public static void checkRegions(IProject project, String fileName, List<TestRegion> regionList, IHyperlinkDetector hlDetector) throws Exception { IFile file = project.getFile(fileName); assertNotNull("The file \"" + fileName + "\" is not found", file); assertTrue("The file \"" + fileName + "\" is not found", file.isAccessible()); IEditorInput editorInput = new FileEditorInput(file); IEditorPart editorPart = openFileInEditor(file); checkRegions(fileName, editorInput, editorPart, regionList, hlDetector); } public static void checkRegionsForAsYouType(IProject project, String fileName, String newContent, List<TestRegion> regionList, IHyperlinkDetector hlDetector) throws Exception { IFile file = project.getFile(fileName); IFile nFile = project.getFile(newContent); assertNotNull("The file \"" + fileName + "\" is not found", file); assertTrue("The file \"" + fileName + "\" is not found", file.isAccessible()); assertNotNull("The file \"" + newContent + "\" is not found", nFile); assertTrue("The file \"" + newContent + "\" is not found", nFile.isAccessible()); IEditorInput editorInput = new FileEditorInput(file); IEditorPart editorPart = openFileInEditor(file); try{ ISourceViewer viewer = getViewer(editorPart); IDocument document = viewer.getDocument(); String text = FileUtil.getContentFromEditorOrFile(nFile); document.set(text); checkRegions(fileName, editorInput, editorPart, regionList, hlDetector); }finally{ if(editorPart.isDirty()){ editorPart.doSave(new NullProgressMonitor()); } } } private static void checkRegions(String fileName, IEditorInput editorInput, IEditorPart editorPart, List<TestRegion> regionList, IHyperlinkDetector hlDetector) throws Exception { ISourceViewer viewer = null; if(editorPart instanceof JavaEditor){ viewer = ((JavaEditor)editorPart).getViewer(); if(hlDetector instanceof AbstractHyperlinkDetector){ ((AbstractHyperlinkDetector)hlDetector).setContext(new TestContext((ITextEditor)editorPart)); } }else if(editorPart instanceof EditorPartWrapper){ if(((EditorPartWrapper)editorPart).getEditor() instanceof WebCompoundEditor){ WebCompoundEditor wce = (WebCompoundEditor)((EditorPartWrapper)editorPart).getEditor(); viewer = wce.getSourceEditor().getTextViewer(); if(hlDetector instanceof AbstractHyperlinkDetector){ ((AbstractHyperlinkDetector)hlDetector).setContext(new TestContext(wce.getSourceEditor())); } }else if(((EditorPartWrapper)editorPart).getEditor() instanceof XMLTextEditorStandAlone){ XMLTextEditorStandAlone xtesa = (XMLTextEditorStandAlone)((EditorPartWrapper)editorPart).getEditor(); viewer = xtesa.getTextViewer(); if(hlDetector instanceof AbstractHyperlinkDetector){ ((AbstractHyperlinkDetector)hlDetector).setContext(new TestContext(xtesa)); } }else fail("unsupported editor type - "+((EditorPartWrapper)editorPart).getEditor().getClass()); }else if (editorPart instanceof XMLMultiPageEditorPart) { IEditorPart[] parts = ((XMLMultiPageEditorPart)editorPart).findEditors(editorInput); if(parts.length>0) { viewer = ((StructuredTextEditor)parts[0]).getTextViewer(); } } else if (editorPart instanceof JSPMultiPageEditor) { IEditorPart[] parts = ((JSPMultiPageEditorPart)editorPart).findEditors(editorInput); if(parts.length>0) { viewer = ((StructuredTextEditor)parts[0]).getTextViewer(); } } else if(editorPart instanceof ObjectMultiPageEditor) { viewer = ((ObjectMultiPageEditor)editorPart).getSourceEditor().getTextViewer(); } else if(editorPart instanceof StructuredTextEditor) { viewer = ((StructuredTextEditor)editorPart).getTextViewer(); }else fail("unsupported editor type - "+editorPart.getClass()); IDocument document = viewer.getDocument(); assertNotNull("The document for the file \"" + fileName + "\" is not loaded", document); if(regionList.get(0).region == null) loadRegions(regionList, document); int expected = 0; for(TestRegion testRegion : regionList) expected += testRegion.region.getLength()+1; int counter = 0; for (int i = 0; i < document.getLength(); i++) { int lineNumber = document.getLineOfOffset(i); int position = i - document.getLineOffset(lineNumber)+1; lineNumber++; TestData testData = new TestData(document, i); IHyperlink[] links = hlDetector.detectHyperlinks(viewer, testData.getHyperlinkRegion(), true); boolean recognized = links != null; if (recognized) { counter++; TestRegion testRegion = findOffsetInRegions(i, regionList); String information = findRegionInformation(document, i, regionList); if(testRegion == null){ fail("Wrong detection for offset - "+i+" (line - "+lineNumber+" position - "+position+") "+information); }else{ checkTestRegion(links, testRegion, information); } } else { for(TestRegion testRegion : regionList){ if(i >= testRegion.region.getOffset() && i <= testRegion.region.getOffset()+testRegion.region.getLength()) { fail("Wrong detection for region - "+getRegionInformation(document, testRegion)+" offset - "+i+" (line - "+lineNumber+" position - "+position+")"); } } } } assertEquals("Wrong recognized region count: ", expected, counter); } public static void checkTestRegion(IHyperlink[] links, TestRegion testRegion, String information){ for(IHyperlink link : links){ TestHyperlink testLink = findTestHyperlink(testRegion.hyperlinks, link); assertNotNull("Unexpected hyperlink - "+link.getHyperlinkText()+" "+information, testLink); assertEquals("Unexpected hyperlink type "+information, testLink.hyperlink, link.getClass()); assertTrue("Validation fails for hyperlink - "+link.getHyperlinkText()+" "+information, testLink.validateHyperlink(link)); if(testLink.fileName != null){ assertTrue("HyperLink must be inherited from AbstractHyperlink "+information, link instanceof AbstractHyperlink); IFile f = ((AbstractHyperlink)link).getReadyToOpenFile(); assertNotNull("HyperLink must return not null file "+information, f); assertEquals(testLink.fileName, f.getName()); } } for(TestHyperlink testLink : testRegion.hyperlinks){ IHyperlink link = findHyperlink(links, testLink); assertNotNull("Hyperlink - "+testLink.name+" not found "+information, link); } } private static TestHyperlink findTestHyperlink(List<TestHyperlink> testHyperlinks, IHyperlink link){ for(TestHyperlink testLink : testHyperlinks){ if(testLink.name.equals(link.getHyperlinkText())) return testLink; } return null; } private static IHyperlink findHyperlink(IHyperlink[] links, TestHyperlink testLink){ for(IHyperlink link : links){ if(testLink.name.equals(link.getHyperlinkText())) return link; } return null; } private static void loadRegions(List<TestRegion> regionList, IDocument document) throws BadLocationException{ FindReplaceDocumentAdapter adapter = new FindReplaceDocumentAdapter(document); IRegion region = adapter.find(0, "{", true, true, false, false); if(region == null) region = new Region(0,0); for(TestRegion testRegion : regionList){ IRegion newRegion = adapter.find(region.getOffset()+region.getLength(), testRegion.regionText, true, true, false, false); if(newRegion != null){ testRegion.region = newRegion; region = newRegion; }else fail("Can not find string - "+testRegion.regionText); } for(int i = regionList.size()-1; i >= 0; i--){ TestRegion r = regionList.get(i); if(r.hyperlinks.size() == 0) regionList.remove(r); } } public static void checkHyperLinkInXml(IProject project, String fileName, int offset, String hyperlinkClassName) throws Exception { checkHyperLinkInXml(fileName, project, offset, hyperlinkClassName); } public static IHyperlink checkHyperLinkInXml(String fileName, IProject project, int offset, String hyperlinkClassName) throws Exception { IHyperlink[] links = detectHyperlinks(fileName, project, offset); if(links!=null) { for (IHyperlink hyperlink : links) { if(hyperlink.getClass().getName().equals(hyperlinkClassName)) { return hyperlink; } } } fail("Can't find HyperLink"); return null; } public static IHyperlink[] detectHyperlinks(String fileName, IProject project, int offset) { Region region = new Region(offset, 0); IFile file = project.getFile(fileName); assertNotNull("The file \"" + fileName + "\" is not found", file); assertTrue("The file \"" + fileName + "\" is not found", file.isAccessible()); FileEditorInput editorInput = new FileEditorInput(file); IEditorPart part = openFileInEditor(file); if(part instanceof EditorPartWrapper) part = ((EditorPartWrapper)part).getEditor(); ISourceViewer viewer = null; if (part instanceof XMLMultiPageEditorPart) { IEditorPart[] parts = ((XMLMultiPageEditorPart)part).findEditors(editorInput); if(parts.length>0) { viewer = ((StructuredTextEditor)parts[0]).getTextViewer(); } } else if (part instanceof JSPMultiPageEditor) { IEditorPart[] parts = ((JSPMultiPageEditorPart)part).findEditors(editorInput); if(parts.length>0) { viewer = ((StructuredTextEditor)parts[0]).getTextViewer(); } } else if(part instanceof ObjectMultiPageEditor) { viewer = ((ObjectMultiPageEditor)part).getSourceEditor().getTextViewer(); } else if(part instanceof StructuredTextEditor) { viewer = ((StructuredTextEditor)part).getTextViewer(); } return HyperlinkDetector.getInstance().detectHyperlinks(viewer, region, true); } public static IHyperlink[] detectELHyperlinks(String fileName, IProject project, int offset) { Region region = new Region(offset, 0); IFile file = project.getFile(fileName); assertNotNull("The file \"" + fileName + "\" is not found", file); assertTrue("The file \"" + fileName + "\" is not found", file.isAccessible()); FileEditorInput editorInput = new FileEditorInput(file); IEditorPart part = openFileInEditor(file); if(part instanceof EditorPartWrapper) part = ((EditorPartWrapper)part).getEditor(); ISourceViewer viewer = null; if (part instanceof XMLMultiPageEditorPart) { IEditorPart[] parts = ((XMLMultiPageEditorPart)part).findEditors(editorInput); if(parts.length>0) { viewer = ((StructuredTextEditor)parts[0]).getTextViewer(); } } else if (part instanceof JSPMultiPageEditor) { IEditorPart[] parts = ((JSPMultiPageEditorPart)part).findEditors(editorInput); if(parts.length>0) { viewer = ((StructuredTextEditor)parts[0]).getTextViewer(); } } else if(part instanceof ObjectMultiPageEditor) { viewer = ((ObjectMultiPageEditor)part).getSourceEditor().getTextViewer(); } else if(part instanceof StructuredTextEditor) { viewer = ((StructuredTextEditor)part).getTextViewer(); } return new ELHyperlinkDetector().detectHyperlinks(viewer, region, true); } private static TestRegion findOffsetInRegions(int offset, List<TestRegion> regionList){ for(TestRegion testRegion : regionList){ if(offset >= testRegion.region.getOffset() && offset <= testRegion.region.getOffset()+testRegion.region.getLength()) return testRegion; } return null; } private static String findRegionInformation(IDocument document, int offset, List<TestRegion> regionList) throws BadLocationException{ int index = -1; for(int i = 0; i < regionList.size(); i++){ TestRegion testRegion = regionList.get(i); if(offset > testRegion.region.getOffset()+testRegion.region.getLength()){ index = i; } } String info = ""; if(index >= 0) { info = "previous region - " + getRegionInformation(document, regionList.get(index)); } if(index+1 < regionList.size()) info += " next region - " + getRegionInformation(document, regionList.get(index+1)); return info; } private static String getRegionInformation(IDocument document, TestRegion region) throws BadLocationException{ String info = ""; int lineNumber = document.getLineOfOffset(region.region.getOffset()); int position = region.region.getOffset() - document.getLineOffset(lineNumber)+1; lineNumber++; if(region.regionText != null) info += "<"+region.regionText+"> "; info += region.region.getOffset()+" - "+(region.region.getOffset()+region.region.getLength())+" line - "+lineNumber+" position - "+position; return info; } public static IEditorPart openFileInEditor(IFile input) { return openFileInEditor(input, null); } public static IEditorPart openFileInEditor(IFile input, String id) { if (input != null && input.exists()) { try { if(id==null) { IWorkbenchPage page = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage(); return IDE.openEditor(page, input, true); } else { IWorkbenchPage page = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage(); return IDE.openEditor(page, input, id, true); } } catch (PartInitException pie) { pie.printStackTrace(); fail(pie.getMessage()); } } return null; } static class TestData { IDocument document; int offset; IRegion region; String contentType; private IHyperlinkRegion hyperlinkRegion = null; TestData (IDocument document, int offset) { this.document = document; this.offset = offset; init(); } private void init() { this.region = getDocumentRegion(); this.contentType = getContentType(); this.hyperlinkRegion = getHyperlinkRegion(); } private IRegion getDocumentRegion() { IRegion region = null; try { region = JavaWordFinder.findWord(document, offset); } catch (Exception x) { x.printStackTrace(); fail(x.getMessage()); } return region; } public IHyperlinkRegion getHyperlinkRegion() { if (hyperlinkRegion != null) return hyperlinkRegion; return new IHyperlinkRegion() { public String getAxis() { return AxisUtil.getAxis(document, region.getOffset()); } public String getContentType() { return contentType; } public String getType() { return region.toString(); } public int getLength() { return region.getLength(); } public int getOffset() { return region.getOffset(); } public String toString() { return "[" + getOffset() + "-" + (getOffset() + getLength() - 1) + ":" + getType() + ":" + getContentType() + "]"; } }; } /** * Returns the content type of document * * @param document - * assumes document is not null * @return String content type of given document */ private String getContentType() { String type = null; IModelManager mgr = StructuredModelManager.getModelManager(); IStructuredModel model = null; try { model = mgr.getExistingModelForRead(document); if (model != null) { type = model.getContentTypeIdentifier(); } } finally { if (model != null) { model.releaseFromRead(); } } return type; } } static class TestContext implements IAdaptable{ ITextEditor editor; public TestContext(ITextEditor editor){ this.editor = editor; } public Object getAdapter(Class adapter) { if(adapter.equals(ITextEditor.class)) return editor; return null; } } public static class TestRegion{ IRegion region = null; String regionText = null; ArrayList<TestHyperlink> hyperlinks = new ArrayList<TestHyperlink>(); public TestRegion(int offset, int length, TestHyperlink[] testHyperlinks){ region = new Region(offset, length); for(TestHyperlink testHyperlink : testHyperlinks){ hyperlinks.add(testHyperlink); } } public TestRegion(String regionText, TestHyperlink[] testHyperlinks){ this.regionText = regionText; for(TestHyperlink testHyperlink : testHyperlinks){ hyperlinks.add(testHyperlink); } } public IRegion getRegion() { return region; } } public static class TestHyperlink{ Class<? extends IHyperlink> hyperlink; ICDIElement element = null; String[] elementPaths = null; String name; String fileName=null; public TestHyperlink(Class<? extends IHyperlink> hyperlink, String name, String fileName){ this(hyperlink, name); this.fileName = fileName; } public TestHyperlink(Class<? extends IHyperlink> hyperlink, String name){ this.hyperlink = hyperlink; this.name = name; } public TestHyperlink(Class<? extends IHyperlink> hyperlink, String name, ICDIElement element){ this(hyperlink, name); this.element = element; } public TestHyperlink(Class<? extends IHyperlink> hyperlink, String name, String[] elementPaths){ this(hyperlink, name); this.elementPaths = elementPaths; } public boolean validateHyperlink(IHyperlink hyperlink){ if(hyperlink instanceof ITestableCDIHyperlink && ((ITestableCDIHyperlink)hyperlink).getCDIElement() != null && element != null){ assertEquals(element, ((ITestableCDIHyperlink)hyperlink).getCDIElement()); }else if(hyperlink instanceof ITestableCDIHyperlink && ((ITestableCDIHyperlink)hyperlink).getCDIElements() != null && elementPaths != null){ for(ICDIElement element : ((ITestableCDIHyperlink)hyperlink).getCDIElements()){ String elementPath = findElementPath(elementPaths, element); assertNotNull("Unexpected CDI element - "+element.getSourcePath().toString(), elementPath); } for(String elementPath : elementPaths){ ICDIElement element = findCDIElement(((ITestableCDIHyperlink)hyperlink).getCDIElements(), elementPath); assertNotNull("CDI element - "+elementPath+" not found", element); } } return true; } protected String findElementPath(String[] elementPaths, ICDIElement element){ for(String elementPath : elementPaths){ if(elementPath.equals(element.getSourcePath().toString())) return elementPath; } return null; } protected ICDIElement findCDIElement(Collection<? extends ICDIElement> elements, String elementPath){ for(ICDIElement element : elements){ if(elementPath.equals(element.getSourcePath().toString())) return element; } return null; } } }