package blade.migrate.core; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.WeakHashMap; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jst.jsp.core.internal.java.JSPTranslation; import org.eclipse.jst.jsp.core.internal.java.JSPTranslator; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; import org.w3c.dom.NodeList; public class JSPFileChecker extends JavaFileChecker { public JSPFileChecker(File file) { super(file); getTranslation(file); } private JSPTranslationPrime createJSPTranslation() { IDOMModel jspModel = null; try { // try to find the file in the current workspace, if it can't find it then fall back to copy final IFile jspFile = WorkspaceUtil.getFileFromWorkspace(getFile(), getWorkspaceHelper()); jspModel = (IDOMModel) StructuredModelManager.getModelManager() .getModelForRead(jspFile); final IDOMDocument domDocument = jspModel.getDocument(); final IDOMNode domNode = (IDOMNode) domDocument .getDocumentElement(); final IProgressMonitor npm = new NullProgressMonitor(); final JSPTranslator translator = new JSPTranslatorPrime(); if (domNode != null) { translator.reset((IDOMNode) domDocument.getDocumentElement(), npm); } else { translator.reset((IDOMNode) domDocument.getFirstChild(), npm); } translator.translate(); final IJavaProject javaProject = JavaCore .create(jspFile.getProject()); _translation = new JSPTranslationPrime(javaProject, translator, jspFile); return _translation; } catch (Exception e) { e.printStackTrace(); } finally { if (jspModel != null) { jspModel.releaseFromRead(); } } return null; } @Override protected SearchResult createSearchResult(int startOffset, int endOffset, int startLine, int endLine, boolean fullMatch) { IDOMModel jspModel = null; try { final JSPTranslationPrime translation = getTranslation(getFile()); final int jspStartOffset = translation.getJspOffset(startOffset); final int jspEndOffset = translation.getJspOffset(endOffset); jspModel = (IDOMModel) StructuredModelManager.getModelManager() .getModelForRead(translation._jspFile); final IDOMDocument domDocument = jspModel.getDocument(); final IStructuredDocument structuredDocument = domDocument .getStructuredDocument(); final int jspStartLine = structuredDocument .getLineOfOffset(jspStartOffset) + 1; final int jspEndLine = structuredDocument .getLineOfOffset(jspEndOffset) + 1; return super.createSearchResult(jspStartOffset, jspEndOffset, jspStartLine, jspEndLine, fullMatch); } catch (Exception e) { e.printStackTrace(); } finally { if (jspModel != null) { jspModel.releaseFromRead(); } } return super.createSearchResult(startOffset, endOffset, startLine, endLine, fullMatch); } @Override protected char[] getJavaSource() { JSPTranslation translation = getTranslation(getFile()); return translation.getJavaText().toCharArray(); } private JSPTranslationPrime getTranslation(File file) { try { synchronized (_map) { WeakReference<JSPTranslationPrime> translationRef = _map.get(file); if (translationRef == null || translationRef.get() == null) { final JSPTranslationPrime newTranslation = createJSPTranslation(); _map.put(file, new WeakReference<JSPTranslationPrime>(newTranslation)); _translation = newTranslation; } else { _translation = translationRef.get(); } } } catch (Exception e) { throw new IllegalArgumentException(e); } return _translation; } private WorkspaceHelper getWorkspaceHelper() { if (_workspaceHelper == null) { _workspaceHelper = new WorkspaceHelper(); } return _workspaceHelper; } public List<SearchResult> findJSPTags(String tagName , String[] attrNames , String[] attrValues) { if (tagName == null || tagName.isEmpty()) { throw new IllegalArgumentException("tagName can not be null or empty"); } if ((attrNames != null && attrValues != null) && attrNames.length != attrValues.length) { throw new IllegalArgumentException("If attrValues is specified it must match the attrNames array in lengh"); } final List<SearchResult> searchResults = new ArrayList<>(); final IFile jspFile = getTranslation(getFile())._jspFile; IDOMModel jspModel = null; try { jspModel = (IDOMModel) StructuredModelManager .getModelManager().getModelForRead(jspFile); final IDOMDocument domDocument = jspModel.getDocument(); final IStructuredDocument structuredDocument = domDocument .getStructuredDocument(); final NodeList nodeList = domDocument.getElementsByTagName(tagName); for (int i = 0; i < nodeList.getLength(); i++) { final IDOMNode domNode = (IDOMNode) nodeList.item(i); if (attrNames == null) { int startOffset = domNode.getStartOffset(); int endOffset = domNode.getEndOffset(); int jspStartLine = structuredDocument.getLineOfOffset(startOffset) + 1; int jspEndLine = structuredDocument.getLineOfOffset(endOffset) + 1; searchResults.add(super.createSearchResult( startOffset,endOffset, jspStartLine,jspEndLine, true)); } else { for (int j = 0; j < attrNames.length; j++) { final IDOMNode attrNode = (IDOMNode) domNode .getAttributes().getNamedItem(attrNames[j]); if (attrNode != null) { if (attrValues != null && !(attrValues[j].equals(attrNode.getNodeValue()))) { continue; } int startOffset = attrNode.getStartOffset(); int endOffset = attrNode.getEndOffset(); int jspStartLine = structuredDocument.getLineOfOffset(startOffset) + 1; int jspEndLine = structuredDocument.getLineOfOffset(endOffset) + 1; searchResults.add(super.createSearchResult( startOffset, endOffset, jspStartLine,jspEndLine, true)); } } } } } catch (IOException | CoreException e) { e.printStackTrace(); } finally { if (jspModel != null) { jspModel.releaseFromRead(); } } return searchResults; } /** * A simple subclass to hold a reference to the original jspFile */ private class JSPTranslationPrime extends JSPTranslation { private IFile _jspFile; public JSPTranslationPrime(IJavaProject javaProject, JSPTranslator translator, IFile jspFile) { super(javaProject, translator); _jspFile = jspFile; } } private class JSPTranslatorPrime extends JSPTranslator { @Override protected void handleIncludeFile(String filename) { try { super.handleIncludeFile(filename); } catch (Exception e) { // suppress errors in handling include files } } } private static Map<File, WeakReference<JSPTranslationPrime>> _map = new WeakHashMap<>(); private JSPTranslationPrime _translation; private WorkspaceHelper _workspaceHelper; }