| /******************************************************************************* |
| * Copyright (c) 2006, 2007 IBM Corporation 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 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.jsp.ui.tests.contentassist; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| |
| import junit.framework.TestCase; |
| |
| 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.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.ASTNode; |
| import org.eclipse.jdt.core.dom.ASTParser; |
| import org.eclipse.jdt.core.dom.ASTVisitor; |
| import org.eclipse.jdt.core.dom.SimpleType; |
| import org.eclipse.jdt.core.dom.VariableDeclarationFragment; |
| import org.eclipse.jdt.core.dom.VariableDeclarationStatement; |
| import org.eclipse.jface.text.Position; |
| import org.eclipse.jst.jsp.core.internal.domdocument.DOMModelForJSP; |
| import org.eclipse.jst.jsp.core.internal.java.IJSPTranslation; |
| import org.eclipse.jst.jsp.core.internal.java.JSPTranslation; |
| import org.eclipse.jst.jsp.core.internal.java.JSPTranslationAdapter; |
| import org.eclipse.jst.jsp.core.internal.modelhandler.ModelHandlerForJSP; |
| import org.eclipse.jst.jsp.core.internal.provisional.JSP11Namespace; |
| import org.eclipse.jst.jsp.ui.tests.other.ScannerUnitTests; |
| import org.eclipse.jst.jsp.ui.tests.util.FileUtil; |
| import org.eclipse.jst.jsp.ui.tests.util.ProjectUnzipUtility; |
| import org.eclipse.jst.jsp.ui.tests.util.ProjectUtil; |
| import org.eclipse.osgi.service.datalocation.Location; |
| 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.xml.core.internal.provisional.document.IDOMModel; |
| |
| /** |
| * This class unit tests the sed JSPTranslation mechanism. |
| * That includes JSPTranslationAdapterFactory, JSPTranslationAdapter, and JSPTranslation. |
| * It uses the jsp_include_test.jsp, because of the more complicated translation and offsets. |
| * |
| * @author pavery |
| */ |
| public class JSPTranslationTest extends TestCase { |
| |
| private ProjectUnzipUtility fProjUtil = null; |
| private boolean isSetup = false; |
| |
| private HashMap fXMLJSPPositions; |
| |
| public JSPTranslationTest(String name) { |
| super(name); |
| } |
| public JSPTranslationTest() { |
| super("JSPTranslationTest"); |
| } |
| |
| protected void setUp() throws Exception { |
| super.setUp(); |
| if (!this.isSetup) { |
| doSetup(); |
| this.isSetup = true; |
| } |
| } |
| |
| private void doSetup() throws Exception { |
| fProjUtil = new ProjectUnzipUtility(); |
| |
| // root of workspace directory |
| Location platformLocation = Platform.getInstanceLocation(); |
| |
| File zipFile = FileUtil.makeFileFor(ProjectUnzipUtility.PROJECT_ZIPS_FOLDER, "includes_tests.zip", ProjectUnzipUtility.PROJECT_ZIPS_FOLDER); |
| fProjUtil.unzipAndImport(zipFile, platformLocation.getURL().getPath()); |
| fProjUtil.initJavaProject("INCLUDES_TESTS"); |
| } |
| |
| public void testPageDirectiveSessionVariableInFile() throws JavaModelException { |
| String jspTestFilePathString = "INCLUDES_TESTS/test189924.jsp"; |
| ProjectUtil.copyBundleEntryIntoWorkspace("/testfiles/189924/test189924.jsp", jspTestFilePathString); |
| IPath jspTestFilePath = new Path(jspTestFilePathString); |
| IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(jspTestFilePath); |
| |
| verifyTranslationHasNoSessionVariables(file); |
| } |
| private void verifyTranslationHasNoSessionVariables(IFile file) throws JavaModelException { |
| IDOMModel model = null; |
| try { |
| model = (IDOMModel) getStructuredModelForRead(file); |
| setupAdapterFactory(model); |
| |
| JSPTranslationAdapter adapter = (JSPTranslationAdapter) model.getDocument().getAdapterFor(IJSPTranslation.class); |
| ICompilationUnit cu = adapter.getJSPTranslation().getCompilationUnit(); |
| cu.makeConsistent(new NullProgressMonitor()); |
| IType[] types = cu.getAllTypes(); |
| for (int i = 0; i < types.length; i++) { |
| IJavaElement[] members = types[i].getChildren(); |
| for (int k = 0; k < members.length; k++) { |
| // check fields for name "session" |
| if (members[k].getElementType() == IJavaElement.FIELD) { |
| assertFalse("field named \"session\" exists", members[k].getElementName().equals(JSP11Namespace.ATTR_NAME_SESSION)); |
| } |
| /* |
| * check "public void |
| * _jspService(javax.servlet.http.HttpServletRequest |
| * request, javax.servlet.http.HttpServletResponse |
| * response)" for local variables named "session" |
| */ |
| else if (members[k].getElementType() == IJavaElement.METHOD && members[k].getElementName().startsWith("_jspService")) { |
| ICompilationUnit compilationUnit = ((IMethod) members[k]).getCompilationUnit(); |
| compilationUnit.makeConsistent(new NullProgressMonitor()); |
| ASTParser parser = ASTParser.newParser(AST.JLS3); |
| parser.setSource(cu); |
| ASTNode node = parser.createAST(null); |
| node.accept(new ASTVisitor() { |
| public boolean visit(VariableDeclarationStatement node) { |
| Iterator fragments = node.fragments().iterator(); |
| while (fragments.hasNext()) { |
| VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.next(); |
| if (fragment.getName().getFullyQualifiedName().equals(JSP11Namespace.ATTR_NAME_SESSION)) { |
| String typeName = ((SimpleType) node.getType()).getName().getFullyQualifiedName(); |
| assertFalse("local variable of type \"javax.servlet.http.HttpSession\" and named \"session\" exists", typeName.equals("javax.servlet.http.HttpSession")); |
| } |
| } |
| return super.visit(node); |
| } |
| }); |
| } |
| } |
| } |
| } |
| finally { |
| if (model != null) |
| model.releaseFromRead(); |
| } |
| } |
| |
| public void testPageDirectiveSessionVariableInSegment() throws JavaModelException { |
| String jspTestFilePathString = "INCLUDES_TESTS/test189924.jsp"; |
| ProjectUtil.copyBundleEntryIntoWorkspace("/testfiles/189924/test189924.jsp", jspTestFilePathString); |
| jspTestFilePathString = "INCLUDES_TESTS/includer.jsp"; |
| ProjectUtil.copyBundleEntryIntoWorkspace("/testfiles/189924/includer.jsp", jspTestFilePathString); |
| IPath jspTestFilePath = new Path(jspTestFilePathString); |
| IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(jspTestFilePath); |
| |
| verifyTranslationHasNoSessionVariables(file); |
| } |
| |
| public void testTranslatePositions() { |
| |
| IDOMModel model = getIncludeTestModelForRead(); |
| JSPTranslationAdapter adapter = (JSPTranslationAdapter) model.getDocument().getAdapterFor(IJSPTranslation.class); |
| JSPTranslation translation = adapter.getJSPTranslation(); |
| try { |
| HashMap java2jsp = translation.getJava2JspMap(); |
| assertEquals("java2jsp map size:", 11, java2jsp.size()); |
| |
| HashMap jsp2java = translation.getJsp2JavaMap(); |
| assertEquals("jsp2java map size:", 3, jsp2java.size()); |
| |
| // some test positions (out.print("" + | );) |
| |
| // we need to ignore the classname length in our comparisons |
| // with java offsets that we get from the translation |
| // since it can vary depending on workspace location |
| int classnameLength = translation.getClassname().length(); |
| |
| int jspTestPosition = translation.getJspText().indexOf("<%= ") + 4; |
| int javaOffset = translation.getJavaOffset(jspTestPosition) - classnameLength; |
| assertEquals("JSPTranslation java offset:", 1009, javaOffset); |
| |
| // (<%= | %>) |
| int javaTestPostition = translation.getJavaText().indexOf("out.print(\"\"+\n \n);") + 14; |
| // dont' need to worry about classname length here because we are comparing |
| // with a position in the JSP document (which doesn't contain classname) |
| int jspOffset = translation.getJspOffset(javaTestPostition); |
| assertEquals("JSPTranslation jsp offset:", 564, jspOffset); |
| } |
| finally { |
| if (model != null) |
| model.releaseFromRead(); |
| } |
| } |
| |
| |
| public void testJSPTranslationText() { |
| |
| IDOMModel model = getIncludeTestModelForRead(); |
| ScannerUnitTests.verifyLengths(model, model.getStructuredDocument().get()); |
| JSPTranslationAdapter adapter = (JSPTranslationAdapter) model.getDocument().getAdapterFor(IJSPTranslation.class); |
| JSPTranslation translation = adapter.getJSPTranslation(); |
| // named as .bin so no line conversion occurs (\n is in use) |
| InputStream in = getClass().getResourceAsStream("translated_text.bin"); |
| String knownTranslationText = loadChars(in); |
| try { |
| // improvements: may need finer tuned text compares later |
| // for different types of translations (includes, xml-jsp in script, attributes, etc...) |
| String text = translation.getJavaText(); |
| |
| assertNotNull("JSP translation text:", text); |
| assertEquals("JSP translation text does not match expected", knownTranslationText, text); |
| } |
| finally { |
| if (model != null) |
| model.releaseFromRead(); |
| } |
| } |
| |
| public void testJSPTranslationAdapter() { |
| IDOMModel model = getIncludeTestModelForRead(); |
| JSPTranslationAdapter adapter = (JSPTranslationAdapter) model.getDocument().getAdapterFor(IJSPTranslation.class); |
| JSPTranslation translation = adapter.getJSPTranslation(); |
| |
| try { |
| IJavaProject proj = adapter.getJavaProject(); |
| assertNotNull("couldn't get java project:" + proj); |
| |
| translation = adapter.getJSPTranslation(); |
| assertNotNull("couldn't get translation:", translation); |
| } |
| finally { |
| if (model != null) |
| model.releaseFromRead(); |
| } |
| } |
| |
| /** |
| * Makes sure both beans are translated even though they are |
| * right next to each other with no space. |
| * |
| * https://bugs.eclipse.org/bugs/show_bug.cgi?id=103004 |
| */ |
| public void testUseBeanNoSpace() { |
| IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("INCLUDES_TESTS/useBean_tester.jsp")); |
| DOMModelForJSP sModel = (DOMModelForJSP)getStructuredModelForRead(f); |
| try { |
| setupAdapterFactory(sModel); |
| JSPTranslationAdapter adapter = (JSPTranslationAdapter) sModel.getDocument().getAdapterFor(IJSPTranslation.class); |
| JSPTranslation translation = adapter.getJSPTranslation(); |
| String javaText = translation.getJavaText(); |
| boolean bean1 = javaText.indexOf("javax.swing.JButton x = null;") != -1; |
| boolean bean2 = javaText.indexOf("javax.swing.JButton y = null;") != -1; |
| assertTrue(bean1); |
| assertTrue(bean2); |
| } |
| finally { |
| if(sModel != null) |
| sModel.releaseFromRead(); |
| } |
| } |
| |
| /** |
| * https://bugs.eclipse.org/bugs/show_bug.cgi?id=86382 |
| */ |
| public void testXMLJSPTranslationText() { |
| IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("INCLUDES_TESTS/xml-jsp/most-tags-xml-jsp.jsp")); |
| DOMModelForJSP sModel = (DOMModelForJSP)getStructuredModelForRead(f); |
| try { |
| setupAdapterFactory(sModel); |
| JSPTranslationAdapter adapter = (JSPTranslationAdapter) sModel.getDocument().getAdapterFor(IJSPTranslation.class); |
| JSPTranslation translation = adapter.getJSPTranslation(); |
| |
| String javaText = translation.getJavaText(); |
| |
| // named as .bin so no line conversion occurs (\n is in use) |
| InputStream in = getClass().getResourceAsStream("translated_xml_jsp.bin"); |
| String knownTranslationText = loadChars(in); |
| |
| assertEquals(knownTranslationText, javaText); |
| } |
| finally { |
| if(sModel != null) |
| sModel.releaseFromRead(); |
| } |
| } |
| |
| public void testXMLJSPMapping() { |
| IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("INCLUDES_TESTS/xml-jsp/most-tags-xml-jsp.jsp")); |
| DOMModelForJSP sModel = (DOMModelForJSP)getStructuredModelForRead(f); |
| try { |
| setupAdapterFactory(sModel); |
| JSPTranslationAdapter adapter = (JSPTranslationAdapter) sModel.getDocument().getAdapterFor(IJSPTranslation.class); |
| JSPTranslation translation = adapter.getJSPTranslation(); |
| |
| HashMap jsp2java = translation.getJsp2JavaMap(); |
| Object[] jspRanges = jsp2java.keySet().toArray(); |
| Position jspPos = null; |
| Position javaPos = null; |
| for (int i = 0; i < jspRanges.length; i++) { |
| jspPos = (Position)jspRanges[i]; |
| javaPos = (Position)jsp2java.get(jspPos); |
| //System.out.println("jsp:" + printPos(jspPos) + " >> java:" + printPos(javaPos)); |
| checkPosition(jspPos, javaPos); |
| } |
| } |
| finally { |
| if(sModel != null) |
| sModel.releaseFromRead(); |
| } |
| } |
| |
| public void testXMLJSPCDATAText() { |
| IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("INCLUDES_TESTS/cdata/cdata.jsp")); |
| DOMModelForJSP sModel = (DOMModelForJSP)getStructuredModelForRead(f); |
| try { |
| setupAdapterFactory(sModel); |
| JSPTranslationAdapter adapter = (JSPTranslationAdapter) sModel.getDocument().getAdapterFor(IJSPTranslation.class); |
| JSPTranslation translation = adapter.getJSPTranslation(); |
| |
| String transText = translation.getJavaText(); |
| |
| // named as .bin so no line conversion occurs (\n is in use) |
| InputStream in = getClass().getResourceAsStream("translated_xml_jsp_cdata.bin"); |
| String knownText = loadChars(in); |
| |
| assertEquals(knownText, transText); |
| } |
| finally { |
| if(sModel != null) |
| sModel.releaseFromRead(); |
| } |
| } |
| |
| private void checkPosition(Position jspPos, Position javaPos) { |
| |
| HashMap expected = getXMLJSPPositions(); |
| Object[] keys =expected.keySet().toArray(); |
| Position expectedJspPos= null; |
| Position expectedJavaPos = null; |
| boolean found = false; |
| for (int i = 0; i < keys.length; i++) { |
| expectedJspPos = (Position)keys[i]; |
| if(jspPos.equals(expectedJspPos)) { |
| expectedJavaPos = (Position)expected.get(expectedJspPos); |
| found = true; |
| } |
| } |
| assertTrue("expected JSP position missing: " + jspPos, found); |
| assertNotNull("no expected java position for jspPos: " + printPos(jspPos), expectedJavaPos); |
| assertEquals("unexpected java position for jsp position "+printPos(jspPos)+" was:" + printPos(javaPos) + " but expected:" + printPos(expectedJavaPos), javaPos, expectedJavaPos); |
| } |
| private String printPos(Position pos) { |
| return pos != null ? "[" + pos.offset +":"+ pos.length + "]" : "null"; |
| } |
| private HashMap getXMLJSPPositions() { |
| if(fXMLJSPPositions == null) { |
| fXMLJSPPositions = new HashMap(); |
| fXMLJSPPositions.put(new Position(882,52), new Position(920,31)); |
| fXMLJSPPositions.put(new Position(961,7), new Position(952,7)); |
| fXMLJSPPositions.put(new Position(1018,14), new Position(89,14)); |
| fXMLJSPPositions.put(new Position(640,2), new Position(888,2)); |
| fXMLJSPPositions.put(new Position(406,24), new Position(759,24)); |
| fXMLJSPPositions.put(new Position(685,19), new Position(897,19)); |
| fXMLJSPPositions.put(new Position(650,26), new Position(861,26)); |
| fXMLJSPPositions.put(new Position(563,9), new Position(848,9)); |
| fXMLJSPPositions.put(new Position(461,23), new Position(784,23)); |
| fXMLJSPPositions.put(new Position(522,8), new Position(822,8)); |
| fXMLJSPPositions.put(new Position(323,44), new Position(274,45)); |
| fXMLJSPPositions.put(new Position(245,43), new Position(229,44)); |
| } |
| return fXMLJSPPositions; |
| } |
| |
| private static String loadChars(InputStream input) { |
| |
| StringBuffer s = new StringBuffer(); |
| try { |
| int c = -1; |
| while ((c = input.read()) >= 0) { |
| if (c > 255) |
| break; |
| s.append((char) c); |
| } |
| input.close(); |
| } |
| catch (IOException e) { |
| System.out.println("An I/O error occured while loading :"); |
| System.out.println(e); |
| } |
| return s.toString(); |
| } |
| |
| /** |
| * add the factory for JSPTranslationAdapter here |
| * @param sm |
| */ |
| private void setupAdapterFactory(IStructuredModel sm) { |
| ModelHandlerForJSP.ensureTranslationAdapterFactory(sm); |
| } |
| |
| /** |
| * IMPORTANT - release model (model.releaseFromRead()) after use |
| * @param file |
| * @return |
| */ |
| private IStructuredModel getStructuredModelForRead(IFile file) { |
| try { |
| IModelManager modelManager = StructuredModelManager.getModelManager(); |
| return modelManager.getModelForRead(file); |
| } |
| catch (IOException ioex) { |
| System.out.println("couldn't open file > " + file); |
| } |
| catch (CoreException e) { |
| e.printStackTrace(); |
| } |
| return null; |
| } |
| |
| private IDOMModel getIncludeTestModelForRead() { |
| |
| IPath jspTestFilePath = new Path("INCLUDES_TESTS/jsp_include_test.jsp"); |
| IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(jspTestFilePath); |
| IDOMModel xmlModel = (IDOMModel) getStructuredModelForRead(file); |
| setupAdapterFactory(xmlModel); |
| return xmlModel; |
| } |
| } |