| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.profiler.j2ee; |
| |
| import org.netbeans.api.java.project.JavaProjectConstants; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.api.project.ProjectUtils; |
| import org.netbeans.api.project.SourceGroup; |
| import org.netbeans.lib.profiler.client.ClientUtils; |
| import org.netbeans.lib.profiler.common.Profiler; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.JSPServletFinder; |
| import org.netbeans.modules.j2ee.spi.ejbjar.EarProvider; |
| import org.netbeans.modules.profiler.nbimpl.project.ProjectUtilities; |
| import org.netbeans.modules.web.api.webmodule.WebModule; |
| import org.netbeans.modules.web.api.webmodule.WebProjectConstants; |
| import org.openide.ErrorManager; |
| import org.openide.filesystems.FileObject; |
| import org.openide.filesystems.FileUtil; |
| import org.openide.util.NbBundle; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.xml.sax.EntityResolver; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.text.MessageFormat; |
| import java.util.*; |
| import java.util.ArrayList; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import org.netbeans.modules.profiler.api.java.JavaProfilerSource; |
| import org.openide.util.Lookup; |
| |
| |
| /** |
| * |
| * @author Jiri Sedlacek |
| */ |
| @NbBundle.Messages({ |
| "WebProjectUtils_CannotFindServletMsg=Cannot resolve servlet class generated from {0}. It will not be included into root methods.", |
| "WebProjectUtils_CannotFindServletClassMsg=Cannot find servlet class {0} defined in deployment descriptor. Its methods will not be included into root methods.", |
| "WebProjectUtils_CannotFindFilterClassMsg=Cannot find filter class {0} defined in deployment descriptor. Its methods will not be included into root methods.", |
| "WebProjectUtils_CannotFindListenerClassMsg=Cannot find listener class {0} defined in deployment descriptor. Its methods will not be included into root methods." |
| }) |
| public class WebProjectUtils { |
| //~ Static fields/initializers ----------------------------------------------------------------------------------------------- |
| private static final Logger LOGGER = Logger.getLogger(WebProjectUtils.class.getName()); |
| |
| private static final Map<ClientUtils.SourceCodeSelection, String> jspClass2NameMap = new HashMap<ClientUtils.SourceCodeSelection, String>(); |
| private static final String[][] jspServletMethods = new String[][] { |
| { |
| "_jspService", |
| "(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)V" |
| } |
| }; |
| |
| //~ Methods ------------------------------------------------------------------------------------------------------------------ |
| |
| public static Document getDeploymentDescriptorDocument(FileObject deploymentDescriptorFile) { |
| Document deploymentDescriptorDocument = null; |
| |
| try { |
| DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); |
| dbfactory.setValidating(false); |
| |
| DocumentBuilder builder = dbfactory.newDocumentBuilder(); |
| |
| builder.setEntityResolver(new EntityResolver() { |
| public InputSource resolveEntity(String publicId, String systemId) |
| throws SAXException, IOException { |
| StringReader reader = new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); // NOI18N |
| InputSource source = new InputSource(reader); |
| source.setPublicId(publicId); |
| source.setSystemId(systemId); |
| |
| return source; |
| } |
| }); |
| |
| deploymentDescriptorDocument = builder.parse(FileUtil.toFile(deploymentDescriptorFile)); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| |
| return deploymentDescriptorDocument; |
| } |
| |
| public static Collection<Document> getDeploymentDescriptorDocuments(Project project, boolean subprojects) { |
| Collection<Document> documents = new ArrayList<Document>(); |
| |
| for (FileObject ddFile : getDeploymentDescriptorFileObjects(project, subprojects)) { |
| Document d = getDeploymentDescriptorDocument(ddFile); |
| if (d != null) documents.add(d); |
| } |
| |
| return documents; |
| } |
| |
| public static Collection<FileObject> getDeploymentDescriptorFileObjects(Project project, boolean subprojects) { |
| Collection<FileObject> descriptors = new ArrayList<FileObject>(); |
| |
| for (WebModule wm : getWebModules(project, subprojects)) { |
| FileObject d = wm.getDeploymentDescriptor(); |
| if (d != null) descriptors.add(d); |
| } |
| |
| return descriptors; |
| } |
| |
| public static Collection<FileObject> getDocumentBaseFileObjects(Project project, boolean subprojects) { |
| Collection<FileObject> basefos = new ArrayList<FileObject>(); |
| |
| for (WebModule wm : getWebModules(project, subprojects)) { |
| FileObject d = wm.getDocumentBase(); |
| if (d != null) basefos.add(d); |
| } |
| |
| return basefos; |
| } |
| |
| public static Collection<File> getDocumentBaseFiles(Project project, boolean subprojects) { |
| Collection<File> basefiles = new ArrayList<File>(); |
| |
| for (FileObject basefo : getDocumentBaseFileObjects(project, subprojects)) { |
| basefiles.add(FileUtil.toFile(basefo)); |
| } |
| |
| return basefiles; |
| } |
| |
| public static boolean isWebProject(Lookup.Provider p) { |
| assert p != null; |
| return p.getLookup().lookup(WebModule.class) != null; |
| } |
| |
| public static ArrayList[] getFilterClasses(Document deploymentDescriptorDocument) { |
| ArrayList mappedFilters = new ArrayList(); |
| ArrayList notMappedFilters = new ArrayList(); |
| |
| NodeList filtersList = getFilters(deploymentDescriptorDocument); |
| NodeList filterMappingsList = getFilterMappings(deploymentDescriptorDocument); |
| |
| Collection<String> mappedFilterNames = new HashSet<String>(); |
| |
| for (int i = 0; i < filterMappingsList.getLength(); i++) { |
| String mappedFilterName = getElementContent((Element) filterMappingsList.item(i), "filter-name"); // NOI18N |
| |
| if ((mappedFilterName != null) && !mappedFilterNames.contains(mappedFilterName)) { |
| mappedFilterNames.add(mappedFilterName); |
| } |
| } |
| |
| for (int i = 0; i < filtersList.getLength(); i++) { |
| String filterName = getElementContent((Element) filtersList.item(i), "filter-name"); // NOI18N |
| String filterClassName = getElementContent((Element) filtersList.item(i), "filter-class"); // NOI18N |
| |
| if ((filterName != null) && (filterClassName != null) && mappedFilterNames.contains(filterName)) { |
| if (!mappedFilters.contains(filterClassName)) { |
| mappedFilters.add(filterClassName); |
| } |
| } else { |
| if (!notMappedFilters.contains(filterClassName)) { |
| notMappedFilters.add(filterClassName); |
| } |
| } |
| } |
| |
| return new ArrayList[] { mappedFilters, notMappedFilters }; |
| } |
| |
| public static NodeList getFilterMappings(Document deploymentDescriptorDocument) { |
| return deploymentDescriptorDocument.getElementsByTagName("filter-mapping"); // NOI18N |
| } |
| |
| public static NodeList getFilters(Document deploymentDescriptorDocument) { |
| return deploymentDescriptorDocument.getElementsByTagName("filter"); // NOI18N |
| } |
| |
| public static boolean isHttpServlet(FileObject fo) { |
| // FIXME pass in the JavaProfilerSource instead |
| JavaProfilerSource src = JavaProfilerSource.createFrom(fo); |
| return src != null && src.isInstanceOf("javax.servlet.http.HttpServlet"); // NOI18N |
| } |
| |
| public static boolean isJSP(FileObject fo) { |
| return "jsp".equals(fo.getExt()); // NOI18N |
| } |
| |
| public static String getJSPFileContext(Project project, FileObject jspFile, boolean subprojects) { |
| Collection<FileObject> docBases = getDocumentBaseFileObjects(project, subprojects); |
| String relPathUsed = null; |
| |
| for (FileObject docBase : docBases) { |
| if (docBase == null) { |
| continue; |
| } |
| |
| String relativePath = FileUtil.getRelativePath(docBase, jspFile); |
| |
| if (relativePath == null) { |
| continue; |
| } |
| |
| if ((relPathUsed == null) || (relPathUsed.length() > relativePath.length())) { |
| relPathUsed = relativePath; |
| } |
| } |
| |
| return relPathUsed; |
| } |
| |
| public static ClientUtils.SourceCodeSelection getJSPFileRootMethod(Project project, FileObject jspFile) { |
| return getJSPMethodSignature(project, jspFile); |
| } |
| |
| public static ClientUtils.SourceCodeSelection getJSPMethodSignature(Project project, FileObject jspFile) { |
| String jspPseudoServletClass = getJSPPseudoServletClass(project, jspFile); |
| |
| if (jspPseudoServletClass == null) { |
| LOGGER.log(Level.WARNING, Bundle.WebProjectUtils_CannotFindServletMsg(FileUtil.toFile(jspFile).getPath())); |
| return null; // According to Issue 62519, jsp file is not resolved/found due odd project layout |
| } |
| |
| return getJSPMethodSignature(jspPseudoServletClass); |
| } |
| |
| public static ClientUtils.SourceCodeSelection getJSPMethodSignature(String jspPseudoServletClass) { |
| return new ClientUtils.SourceCodeSelection(jspPseudoServletClass, jspServletMethods[0][0], jspServletMethods[0][1]); |
| } |
| |
| public static Set<ClientUtils.SourceCodeSelection> getJSPMethodSignatures(Project project, boolean subprojects) { |
| Set<ClientUtils.SourceCodeSelection> methodSignatures = new HashSet<ClientUtils.SourceCodeSelection>(); |
| Collection<FileObject> baseFOs = getDocumentBaseFileObjects(project, subprojects); |
| |
| if ((baseFOs == null) || baseFOs.isEmpty()) { |
| return methodSignatures; |
| } |
| |
| for (FileObject baseFO : baseFOs) { |
| int jspStringStartIndex = baseFO.getPath().length(); |
| List<FileObject> jspFileObjects = getJSPs(baseFO); |
| ClientUtils.SourceCodeSelection methodDescription; |
| |
| for (FileObject jsp : jspFileObjects) { |
| methodDescription = getJSPMethodSignature(project, jsp); |
| |
| if (methodDescription != null) { |
| // TODO: Get rid of this ridiculous formatter and enhance FlatProfileContainer to return a SourceCodeSelection of a certain row |
| jspClass2NameMap.put(methodDescription, jsp.getPath().substring(jspStringStartIndex)); |
| // **** |
| methodSignatures.add(methodDescription); |
| } |
| } |
| } |
| |
| return methodSignatures; |
| } |
| |
| public static String getJSPPath(ClientUtils.SourceCodeSelection jspMethod) { |
| return jspClass2NameMap.get(jspMethod); |
| } |
| |
| public static String getJSPPseudoServletClass(Project project, FileObject jspFile) { |
| String jspPseudoServletJavaFile = JSPServletFinder.findJSPServletFinder(jspFile) |
| .getServletResourcePath(getJSPFileContext(project, jspFile, true)); |
| |
| if (jspPseudoServletJavaFile == null) { |
| return null; // According to Issue 62519, jsp file is not resolved/found due odd project layout |
| } |
| |
| String jspPseudoServletJavaClass = jspPseudoServletJavaFile.substring(0, |
| jspPseudoServletJavaFile.length() |
| - ".java".length()).replace('/', '.'); // NOI18N |
| |
| return jspPseudoServletJavaClass; |
| } |
| |
| public static ClientUtils.SourceCodeSelection[] getJSPRootMethods(Project project, boolean subprojects) { |
| Set<ClientUtils.SourceCodeSelection> jspRootMethodDescriptions = getJSPMethodSignatures(project, subprojects); |
| |
| if (jspRootMethodDescriptions == null) { |
| return new ClientUtils.SourceCodeSelection[0]; |
| } |
| |
| return jspRootMethodDescriptions.toArray(new ClientUtils.SourceCodeSelection[0]); |
| } |
| |
| public static ArrayList getJSPs(FileObject documentBase) { |
| ArrayList jspFileObjects = new ArrayList(); |
| |
| if (documentBase.isFolder()) { |
| searchForJSPs(documentBase, jspFileObjects); |
| } |
| |
| return jspFileObjects; |
| } |
| |
| public static ArrayList getListenerClasses(Document deploymentDescriptorDocument) { |
| ArrayList listeners = new ArrayList(); |
| NodeList listenersList = getListeners(deploymentDescriptorDocument); |
| |
| for (int i = 0; i < listenersList.getLength(); i++) { |
| String listenerClass = getElementContent((Element) listenersList.item(i), "listener-class"); // NOI18N |
| |
| if ((listenerClass != null) && !listeners.contains(listenerClass)) { |
| listeners.add(listenerClass); |
| } |
| } |
| |
| return listeners; |
| } |
| |
| public static NodeList getListeners(Document deploymentDescriptorDocument) { |
| return deploymentDescriptorDocument.getElementsByTagName("listener"); // NOI18N |
| } |
| |
| public static boolean isMappedServlet(FileObject servlet, Project project, boolean subprojects) { |
| Collection<Document> dds = getDeploymentDescriptorDocuments(project, subprojects); |
| |
| for (Document dd : dds) { |
| if (getServletMapping(servlet, dd) != null) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| public static ArrayList[] getServletClasses(Document deploymentDescriptorDocument) { |
| ArrayList mappedServlets = new ArrayList(); |
| ArrayList notMappedServlets = new ArrayList(); |
| |
| NodeList servletsList = getServlets(deploymentDescriptorDocument); |
| NodeList servletMappingsList = getServletMappings(deploymentDescriptorDocument); |
| |
| Collection<String> mappedServletNames = new HashSet<String>(); |
| |
| for (int i = 0; i < servletMappingsList.getLength(); i++) { |
| String mappedServletName = getElementContent((Element) servletMappingsList.item(i), "servlet-name"); // NOI18N |
| |
| if ((mappedServletName != null) && !mappedServletNames.contains(mappedServletName)) { |
| mappedServletNames.add(mappedServletName); |
| } |
| } |
| |
| for (int i = 0; i < servletsList.getLength(); i++) { |
| String servletName = getElementContent((Element) servletsList.item(i), "servlet-name"); // NOI18N |
| String servletClassName = getElementContent((Element) servletsList.item(i), "servlet-class"); // NOI18N |
| |
| if ((servletName != null) && (servletClassName != null) && mappedServletNames.contains(servletName)) { |
| if (!mappedServlets.contains(servletClassName)) { |
| mappedServlets.add(servletClassName); |
| } |
| } else { |
| if (!notMappedServlets.contains(servletClassName)) { |
| notMappedServlets.add(servletClassName); |
| } |
| } |
| } |
| |
| return new ArrayList[] { mappedServlets, notMappedServlets }; |
| } |
| |
| public static String getServletMapping(FileObject servletFO, Document deploymentDescriptorDocument) { |
| // FIXME - pass in JavaProfilerSource param |
| JavaProfilerSource src = JavaProfilerSource.createFrom(servletFO); |
| if (src == null) { |
| return null; |
| } |
| String servletClassName = src.getTopLevelClass().getVMName(); |
| |
| if ((servletClassName == null) || (deploymentDescriptorDocument == null)) { |
| return null; |
| } |
| |
| NodeList servletsList = getServlets(deploymentDescriptorDocument); |
| |
| for (int i = 0; i < servletsList.getLength(); i++) { |
| String servletName = getElementContent((Element) servletsList.item(i), "servlet-name"); // NOI18N |
| String className = getElementContent((Element) servletsList.item(i), "servlet-class"); // NOI18N |
| |
| if ((servletName != null) && (className != null) && servletClassName.equals(className)) { |
| NodeList servletMappingsList = getServletMappings(deploymentDescriptorDocument); |
| |
| for (int j = 0; j < servletMappingsList.getLength(); j++) { |
| if (servletName.equals(getElementContent((Element) servletMappingsList.item(j), "servlet-name"))) { |
| // NOI18N |
| return getElementContent((Element) servletMappingsList.item(j), "url-pattern"); // NOI18N |
| } |
| } |
| |
| return null; |
| } |
| } |
| |
| return null; |
| } |
| |
| public static NodeList getServletMappings(Document deploymentDescriptorDocument) { |
| return deploymentDescriptorDocument.getElementsByTagName("servlet-mapping"); // NOI18N |
| } |
| |
| public static NodeList getServlets(Document deploymentDescriptorDocument) { |
| return deploymentDescriptorDocument.getElementsByTagName("servlet"); // NOI18N |
| } |
| |
| // returns true if passed fo lives in /web directory |
| public static boolean isWebDocumentSource(FileObject fo, Project project) { |
| SourceGroup[] sg = ProjectUtils.getSources(project).getSourceGroups(WebProjectConstants.TYPE_DOC_ROOT); |
| |
| for (int i = 0; i < sg.length; i++) { |
| if (FileUtil.isParentOf(sg[i].getRootFolder(), fo)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| // returns true if passed fo lives in /src directory |
| public static boolean isWebJavaSource(FileObject fo, Project project) { |
| SourceGroup[] sg = ProjectUtils.getSources(project).getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); |
| |
| for (int i = 0; i < sg.length; i++) { |
| if (FileUtil.isParentOf(sg[i].getRootFolder(), fo)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| public static Collection<WebModule> getWebModules(Project project, boolean subprojects) { |
| Collection<WebModule> wms = new ArrayList<WebModule>(); |
| WebModule wm = WebModule.getWebModule(project.getProjectDirectory()); |
| |
| if (wm != null) { |
| wms.add(wm); |
| } |
| |
| if (subprojects) { |
| EarProvider earprovider = project.getLookup().lookup(EarProvider.class); |
| |
| if ((wm == null) && (earprovider != null)) { |
| Set<Project> projects = new HashSet<Project>(); |
| ProjectUtilities.fetchSubprojects(project, projects); |
| |
| for (Project subp : projects) { |
| wms.addAll(getWebModules(subp, subprojects)); |
| } |
| } |
| } |
| |
| return wms; |
| } |
| |
| public static void resetJSPNameCache() { |
| jspClass2NameMap.clear(); |
| } |
| |
| private static String getElementContent(Element rootElement, String tagName) { |
| if (rootElement == null) { |
| return null; |
| } |
| |
| NodeList elementsList = rootElement.getElementsByTagName(tagName); |
| |
| if ((elementsList == null) || (elementsList.getLength() == 0)) { |
| return null; |
| } |
| |
| Node element = elementsList.item(0); |
| |
| if (element == null) { |
| return null; |
| } |
| |
| String elementContents = element.getTextContent(); |
| |
| if (elementContents == null) { |
| return null; |
| } |
| |
| return elementContents.trim(); |
| } |
| |
| private static void searchForJSPs(FileObject root, ArrayList jspFileObjects) { |
| FileObject[] childs = root.getChildren(); |
| FileObject child; |
| |
| for (int i = 0; i < childs.length; i++) { |
| child = childs[i]; |
| |
| if (child.isFolder()) { |
| searchForJSPs(child, jspFileObjects); |
| } else if (child.isData() && "jsp".equals(child.getExt())) { |
| jspFileObjects.add(child); // NOI18N |
| } |
| } |
| } |
| } |