This patch fixes #3529 and #3235, and was provided by Peter Roßbach ([EMAIL PROTECTED]). I verified the fix with samll test cases. Note that -webapp option has to be used. misto% runsocks cvs diff -u JspC.java Index: JspC.java =================================================================== RCS file: /home/cvspublic/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/JspC.java, v retrieving revision 1.10 diff -u -r1.10 JspC.java --- JspC.java 2001/09/07 18:52:14 1.10 +++ JspC.java 2001/09/13 17:08:56 @@ -73,6 +73,7 @@ import org.apache.jasper.compiler.TldLocationsCache; import org.apache.jasper.servlet.JasperLoader; +import org.apache.jasper.servlet.JspCServletContext; import org.apache.jasper.logging.Logger; import org.apache.jasper.logging.JasperLogger; @@ -167,12 +168,12 @@ * Are we supporting HTML mapped servlets? */ public boolean getMappedFile() { - return mappedFile; - } + return mappedFile; + } // Off-line compiler, no need for security manager public Object getProtectionDomain() { - return null; + return null; } public boolean getSendErrorToClient() { @@ -203,11 +204,11 @@ } public TldLocationsCache getTldLocationsCache() { - return tldLocationsCache; + return tldLocationsCache; } public String getJavaEncoding() { - return "UTF-8"; + return "UTF-8"; } public String getClassPath() { @@ -345,13 +346,13 @@ if (dirset) { clctxt.setOutputInDirs(true); } - ArrayList urls = new ArrayList(); + ArrayList urls = new ArrayList(); if (new File(clctxt.getRealPath("/")).exists()) { File classes = new File(clctxt.getRealPath("/WEB-INF/classes")); try { if (classes.exists()) { - urls.add(classes.toURL()); + urls.add(classes.getCanonicalFile().toURL()); } } catch (IOException ioe) { // failing a toCanonicalPath on a file that @@ -364,10 +365,12 @@ String[] libs = lib.list(); for (int i = 0; i < libs.length; i++) { try { - File libFile = new File(lib.toString() + File libFile = new File(lib.toString() + File.separator + libs[i]); - urls.add(libFile.toURL()); + //System.out.println("WEB-INF/lib element : " + libFile ) ; + + urls.add(libFile.getCanonicalFile().toURL()); } catch (IOException ioe) { // failing a toCanonicalPath on a file that // exists() should be a JVM regression test, @@ -377,9 +380,27 @@ } } } - URLClassLoader loader = new URLClassLoader( - (URL[])(urls.toArray(new URL[urls.size()])),null); - clctxt.setClassLoader(loader); + StringTokenizer tokenizer= new StringTokenizer( + clctxt.getClassPath(), File.pathSeparator) ; + while( tokenizer.hasMoreTokens()) { + String path = tokenizer.nextToken() ; + try { + File libFile = new File(path); + //System.out.println("Classpath element : " + libFile ) ; + urls.add(libFile.toURL()); + } catch (IOException ioe) { + // failing a toCanonicalPath on a file that + // exists() should be a JVM regression test, + // therefore we have permission to freak out + throw new RuntimeException(ioe.toString()); + } + } + urls.add(new File(clctxt.getRealPath("/")).getCanonicalFile().toURL()) ; + //for(Iterator iter=urls.iterator();iter.hasNext();) + // System.out.println("Classpath element : " + iter.next() ) ; + URLClassLoader loader = new URLClassLoader( + (URL[])(urls.toArray(new URL[urls.size()]))); + clctxt.setClassLoader(loader); CommandLineCompiler clc = new CommandLineCompiler(clctxt); clc.compile(); @@ -421,7 +442,7 @@ } catch (Exception e) { Constants.message("jspc.error.generalException", new Object[] {file, e}, Logger.ERROR); - e.printStackTrace(); + e.printStackTrace(); if (dieLevel != NO_DIE_LEVEL) { dieOnExit = true; } @@ -629,6 +650,23 @@ } Enumeration e = pages.elements(); + try { + JspCServletContext context = new JspCServletContext( + new PrintWriter(System.out), + new URL( "file:" + ubase.replace('\\','/') + "/")); + /** + System.out.println("web.xml location: " + + context.getRealPath("/WEB-INF/web.xml") ); + Set thelibs = context.getResourcePaths("WEB-INF/lib/") ; + for(Iterator iter=thelibs.iterator();iter.hasNext();){ + System.out.println("Lib :" + iter.next()) ; + } + **/ + tldLocationsCache = new TldLocationsCache(context) ; + } catch ( MalformedURLException me) { + System.out.println("**" +me ) ; + } + while (e.hasMoreElements()) { String nextjsp = e.nextElement().toString(); @@ -688,6 +726,7 @@ } if (dieOnExit) { System.exit(die); + } } %runsocks cvs diff -u TagLibraryInfoImpl.java Index: TagLibraryInfoImpl.java =================================================================== RCS file: /home/cvspublic/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/T agLibraryInfoImpl.java,v retrieving revision 1.23 diff -u -r1.23 TagLibraryInfoImpl.java --- TagLibraryInfoImpl.java 2001/07/10 23:50:24 1.23 +++ TagLibraryInfoImpl.java 2001/09/13 17:54:08 @@ -100,6 +100,7 @@ import org.apache.jasper.parser.ParserUtils; import org.apache.jasper.parser.TreeNode; +import java.net.URLClassLoader ; /** * Implementation of the TagLibraryInfo class from the JSP spec. @@ -168,94 +169,107 @@ } public TagLibraryInfoImpl(JspCompilationContext ctxt, String prefix, - String uriIn) + String uriIn) throws JasperException { - this(ctxt, prefix, uriIn, null); + this(ctxt, prefix, uriIn, null); } public TagLibraryInfoImpl(JspCompilationContext ctxt, String prefix, - String uriIn, String[] location) + String uriIn, String[] location) throws JasperException { super(prefix, uriIn); - this.ctxt = ctxt; + this.ctxt = ctxt; ZipInputStream zin; InputStream in = null; URL url = null; boolean relativeURL = false; - if (location == null) { - // The URI points to the TLD itself or to a jar - // file where the TLD is located - int uriType = TldLocationsCache.uriType(uri); - if (uriType == TldLocationsCache.ABS_URI) { - throw new JasperException( + if (location == null) { + // The URI points to the TLD itself or to a jar + // file where the TLD is located + int uriType = TldLocationsCache.uriType(uri); + if (uriType == TldLocationsCache.ABS_URI) { + throw new JasperException( Constants.getString("jsp.error.taglibDirective.absUriCannotBeResolved", - new Object[] {uri})); - } else if (uriType == - TldLocationsCache.NOROOT_REL_URI) { - uri = ctxt.resolveRelativeUri(uri); - } - location = new String[2]; - location[0] = uri; - if (uri.endsWith("jar")) { - location[1] = "META-INF/taglib.tld"; - } - } + new Object[] {uri})); + } else if (uriType == + TldLocationsCache.NOROOT_REL_URI) { + uri = ctxt.resolveRelativeUri(uri); + } + location = new String[2]; + location[0] = uri; + if (uri.endsWith("jar")) { + location[1] = "META-INF/taglib.tld"; + } + } if (!location[0].endsWith("jar")) { - // Location points to TLD file - try { - in = getResourceAsStream(location[0]); - if (in == null) throw new FileNotFoundException(location[0]); - } catch (FileNotFoundException ex) { - throw new JasperException( + // Location points to TLD file + try { + in = getResourceAsStream(location[0]); + if (in == null) throw new FileNotFoundException(location[0]); + } catch (FileNotFoundException ex) { + throw new JasperException( Constants.getString("jsp.error.file.not.found", - new Object[] {location[0]})); - } - // Now parse the tld. - parseTLD(ctxt, location[0], in); - } else { - // Location points to a jar file - // tag library in jar file - JarFile jarFile = null; - ZipEntry jarEntry = null; - InputStream stream = null; - try { - url = ctxt.getResource(location[0]); - if (url == null) return; - url = new URL("jar:" + url.toString() + "!/"); - JarURLConnection conn = - (JarURLConnection) url.openConnection(); - conn.connect(); //@@@ necessary??? - jarFile = conn.getJarFile(); - jarEntry = jarFile.getEntry(location[1]); - stream = jarFile.getInputStream(jarEntry); - parseTLD(ctxt, location[0], stream); - // FIXME @@@ - // -- it seems that the JarURLConnection class caches JarFile - // objects for particular URLs, and there is no way to get - // it to release the cached entry, so - // there's no way to redeploy from the same JAR file. Wierd. - } catch (Exception ex) { - Constants.message( + new Object[] {location[0]})); + } + // Now parse the tld. + parseTLD(ctxt, location[0], in); + } else { + // Location points to a jar file + // tag library in jar file + JarFile jarFile = null; + ZipEntry jarEntry = null; + InputStream stream = null; + // p("before tld extraction from jar " + location[0]) ; + try { + String path = location[0] ; + if(ctxt.getClassLoader() != null && + java.net.URLClassLoader.class.equals(ctxt.getClassLoader().getClass()) + && path.startsWith("/")) + path = path.substring(1,path.length()) ; + url = ctxt.getResource(path); + //url = ctxt.getResource(location[0]); + if (url == null) { + // p("can't find jar url resource " + location[0]) ; + return; + } + // p("before jar url connection " + location[0]) ; + url = new URL("jar:" + url.toString() + "!/"); + JarURLConnection conn = + (JarURLConnection) url.openConnection(); + conn.connect(); //@@@ necessary??? + jarFile = conn.getJarFile(); + jarEntry = jarFile.getEntry(location[1]); + stream = jarFile.getInputStream(jarEntry); + parseTLD(ctxt, location[0], stream); + // FIXME @@@ + // -- it seems that the JarURLConnection class caches JarFile + // objects for particular URLs, and there is no way to get + // it to release the cached entry, so + // there's no way to redeploy from the same JAR file. Wierd. + } catch (Exception ex) { + //p("Error jar url connection " + location[0] + " -- " + ex) ; + + Constants.message( "jsp.error.taglib.jarFileException", - new Object[] {url.toString(), ex.getMessage()}, - Logger.ERROR); - if (stream != null) { - try { - stream.close(); - } catch (Throwable t) {} - } - if (jarFile != null) { - try { - jarFile.close(); - } catch (Throwable t) {} - } - } - } + new Object[] {url.toString(), ex.getMessage()}, + Logger.ERROR); + if (stream != null) { + try { + stream.close(); + } catch (Throwable t) {} + } + if (jarFile != null) { + try { + jarFile.close(); + } catch (Throwable t) {} + } + } + } } /** Returns true if the given URI is relative in this web application, false if it is an internet URI. @@ -272,12 +286,16 @@ Vector tagVector = new Vector(); + // p("before tld parsing") ; // Create an iterator over the child elements of our <taglib> element - ClassLoader cl = ctxt.getClassLoader(); - ParserUtils pu = ParserUtils.createParserUtils(cl); +// ClassLoader cl = ctxt.getClassLoader(); +// ParserUtils pu = ParserUtils.createParserUtils(cl); + ParserUtils pu = new ParserUtils(); TreeNode tld = pu.parseXMLDocument(uri, in); Iterator list = tld.findChildren(); - + + TreeNode uriTEST = tld.findChild("uri"); + // p("find treenode uri:" + uriTEST.getBody()) ; // Process each child element of our <taglib> element while (list.hasNext()) { @@ -323,13 +341,13 @@ private TagInfo createTagInfo(TreeNode elem) throws JasperException { String name = null; - String tagclass = null; - String teiclass = null; + String tagclass = null; + String teiclass = null; String bodycontent = "JSP"; // Default body content is JSP - String info = null; - String displayName = null; - String smallIcon = null; - String largeIcon = null; + String info = null; + String displayName = null; + String smallIcon = null; + String largeIcon = null; Vector attributeVector = new Vector(); Vector variableVector = new Vector(); @@ -366,22 +384,22 @@ } else if ("attribute".equals(tname)) attributeVector.addElement(createAttribute(element)); else if ("example".equals(tname) || // Ignored elements - false) + false) ; else { Constants.message("jsp.warning.unknown.element.in.tag", new Object[] {tname}, Logger.WARNING ); - } - } - TagAttributeInfo[] tagAttributeInfo + } + } + TagAttributeInfo[] tagAttributeInfo = new TagAttributeInfo[attributeVector.size()]; - attributeVector.copyInto (tagAttributeInfo); + attributeVector.copyInto (tagAttributeInfo); - TagVariableInfo[] tagVariableInfos + TagVariableInfo[] tagVariableInfos = new TagVariableInfo[variableVector.size()]; - variableVector.copyInto(tagVariableInfos); + variableVector.copyInto(tagVariableInfos); TagExtraInfo tei = null; @@ -390,7 +408,7 @@ try { Class teiClass = ctxt.getClassLoader().loadClass(teiclass); tei = (TagExtraInfo) teiClass.newInstance(); - } catch (ClassNotFoundException cex) { + } catch (ClassNotFoundException cex) { Constants.message("jsp.warning.teiclass.is.null", new Object[] { teiclass, cex.getMessage() @@ -417,10 +435,10 @@ info, this, tei, tagAttributeInfo, - displayName, - smallIcon, - largeIcon, - tagVariableInfos); + displayName, + smallIcon, + largeIcon, + tagVariableInfos); return taginfo; } @@ -448,8 +466,8 @@ } else if ("type".equals(tname)) type = element.getBody(); else if ("description".equals(tname) || // Ignored elements - false ) - ; + false ) + ; else { Constants.message("jsp.warning.unknown.element.in.attribute", new Object[] {tname}, @@ -466,9 +484,9 @@ TagVariableInfo createVariable(TreeNode elem) { String nameGiven = null; String nameFromAttribute = null; - String className = null; - boolean declare = true; - int scope = VariableInfo.NESTED; + String className = null; + boolean declare = true; + int scope = VariableInfo.NESTED; Iterator list = elem.findChildren(); while (list.hasNext()) { @@ -487,30 +505,30 @@ } else if ("scope".equals(tname)) { String s = element.getBody(); if (s != null) { - if ("NESTED".equals(s)) { - scope = VariableInfo.NESTED; - } else if ("AT_BEGIN".equals(s)) { - scope = VariableInfo.AT_BEGIN; - } else if ("AT_END".equals(s)) { - scope = VariableInfo.AT_END; - } - } - } + if ("NESTED".equals(s)) { + scope = VariableInfo.NESTED; + } else if ("AT_BEGIN".equals(s)) { + scope = VariableInfo.AT_BEGIN; + } else if ("AT_END".equals(s)) { + scope = VariableInfo.AT_END; + } + } + } else if ("description".equals(tname) || // Ignored elements - false ) { + false ) { } else { Constants.message("jsp.warning.unknown.element.in.variable", new Object[] {tname}, Logger.WARNING); - } + } } return new TagVariableInfo(nameGiven, nameFromAttribute, - className, declare, scope); + className, declare, scope); } private TagLibraryValidator createValidator(TreeNode elem) { String validatorClass = null; - Map initParams = new Hashtable(); + Map initParams = new Hashtable(); Iterator list = elem.findChildren(); while (list.hasNext()) { @@ -519,37 +537,37 @@ if ("validator-class".equals(tname)) validatorClass = element.getBody(); else if ("init-param".equals(tname)) { - String[] initParam = createInitParam(element); - initParams.put(initParam[0], initParam[1]); + String[] initParam = createInitParam(element); + initParams.put(initParam[0], initParam[1]); } else if ("description".equals(tname) || // Ignored elements - false ) { + false ) { } else { Constants.message("jsp.warning.unknown.element.in.validator", //@@@ add in properties new Object[] {tname}, Logger.WARNING); - } + } } TagLibraryValidator tlv = null; if (validatorClass != null && !validatorClass.equals("")) { try { Class tlvClass = - ctxt.getClassLoader().loadClass(validatorClass); + ctxt.getClassLoader().loadClass(validatorClass); tlv = (TagLibraryValidator)tlvClass.newInstance(); - //p("got validator class: " + tlv); + //p("got validator class: " + tlv); } catch (Exception ex) { Constants.message("jsp.warning.tlvclass.is.null", - new Object[] { - validatorClass, - "EXCEPTION: " + ex.getMessage() - }, - Logger.ERROR); + new Object[] { + validatorClass, + "EXCEPTION: " + ex.getMessage() + }, + Logger.ERROR); } + } + if (tlv != null) { + tlv.setInitParameters(initParams); } - if (tlv != null) { - tlv.setInitParameters(initParams); - } - return tlv; + return tlv; } String[] createInitParam(TreeNode elem) { @@ -569,9 +587,9 @@ Constants.message("jsp.warning.unknown.element.in.initParam", //@@@ properties new Object[] {tname}, Logger.WARNING); - } + } } - return initParam; + return initParam; } static void copy(InputStream in, String fileName) @@ -594,7 +612,7 @@ * @return The TagLibraryValidator instance, if any. */ public TagLibraryValidator getTagLibraryValidator() { - return tagLibraryValidator; + return tagLibraryValidator; } /** @@ -607,14 +625,15 @@ * @return A string indicating whether the page is valid or not. */ public ValidationMessage[] validate(PageData thePage) { - TagLibraryValidator tlv = getTagLibraryValidator(); - if (tlv == null) return null; - return tlv.validate(getPrefixString(), getURI(), thePage); + TagLibraryValidator tlv = getTagLibraryValidator(); + if (tlv == null) return null; + return tlv.validate(getPrefixString(), getURI(), thePage); } protected TagLibraryValidator tagLibraryValidator; private void p(String s) { - System.out.println("[TagLibraryInfoImpl] " + s); + System.out.println("[TagLibraryInfoImpl] " + s); } } =========================================================== misto% cat jasper/src/share/org/apache/jasper/servlet/JspCServletContext.java package org.apache.jasper.servlet; import java.net.*; import java.io.*; import java.util.*; import javax.servlet.*; /** * Simple <code>ServletContext</code> without HTTP-specific methods. * * @author Peter Roßbach ([EMAIL PROTECTED]) * @version $Id:$ */ public class JspCServletContext implements ServletContext { /** * Source-Version */ public static String vcid = "$Id:$"; /** Base URL (doc-root) */ protected URL myResourceBaseURL; /** LogWriter */ protected PrintWriter myLogWriter; /** Context attributes */ protected Hashtable myAttributes; /** * Constructor with which the most important fields are set. * * @param aLogWriter Writer which is used for <code>log()</code>-ouput * @param aResourceBaseURL Ressource base URL */ public JspCServletContext(PrintWriter aLogWriter, URL aResourceBaseURL) { myAttributes = new Hashtable(); if (aLogWriter instanceof PrintWriter) { myLogWriter = (PrintWriter)aLogWriter; } else { myLogWriter = new PrintWriter(aLogWriter); } myResourceBaseURL = aResourceBaseURL; } /** * Always returns <code>this</code>. * * @param uripath */ public ServletContext getContext(String uripath) { return this; } /** * Returns the major version of the servlet API that this * servlet engine supports. All 2.1 compliant implementations * must return the integer 2 from this method. * * @return 2 */ public int getMajorVersion() { return 2; } /** * Always returns <code>null</code>. * * @param file name of the file whose mime type is required */ public String getMimeType(String file) { return null; } /** * Returns the minor version of the servlet API that this * servlet engine supports. All 2.3 compliant implementations * must return the integer 3 from this method. * * @return 3 */ public int getMinorVersion() { return 3; } /** * Returns a URL object of a resource that is mapped to a * corresponding URL path. The URL path must be of the form * <tt>/dir/dir/file.ext</tt>. This method allows a servlet * to access content to be served from the servlet engines * document space in a system independent manner. Resources * could be located on the local file system, a remote * file system, a database, or a remote network site. * * <p>This method may return null if there is no resource * mapped to the given URL path. * * <p>The servlet engine must implement whatever URL handlers * and <tt>URLConnection</tt> objects are necessary to access * the given content. * * <p>This method does not fill the same purpose as the * <tt>getResource</tt> method of <tt>java.lang.Class</tt>. * The method in <tt>java.lang.Class</tt> looks up resources * based on class loader. This method allows servlet engines * to make resources avaialble to a servlet from any source * without regards to class loaders, location, etc. * * @param path Path of the content resource * @exception MalformedURLException if the resource path is * not properly formed. */ public URL getResource(String path) throws MalformedURLException { if (path.startsWith("/")) path = path.substring(1); return new URL(myResourceBaseURL, path); } /** * Enables you to reset the base URL. * * @param aBaseURL new base URL */ public void setResourceBaseURL(String aBaseURL) throws MalformedURLException { myResourceBaseURL = new URL(aBaseURL); } /** * Returns an <tt>InputStream</tt> object allowing access to * a resource that is mapped to a corresponding URL path. The * URL path must be of the form <tt>/dir/dir/file.ext</tt>. * * <p>Note that meta-information such as content length and * content type that are available when using the * <tt>getResource</tt> method of this class are lost when * using this method. * * <p>This method may return null if there is no resource * mapped to the given URL path. * <p>The servlet engine must implement whatever URL handlers * and <tt>URLConnection</tt> objects are necessary to access * the given content. * * <p>This method does not fill the same purpose as the * <tt>getResourceAsStream</tt> method of <tt>java.lang.Class</tt>. * The method in <tt>java.lang.Class</tt> looks up resources * based on class loader. This method allows servlet engines * to make resources avaialble to a servlet from any source * without regards to class loaders, location, etc. * * @param name */ public InputStream getResourceAsStream(String path) { InputStream in = null; try { in = getResource(path).openStream(); } catch (IOException ioe) {} return in; } /** * Always returns <code>null</code>. * * @param urlpath Path to use to look up the target server resource * @see RequestDispatcher * @return <code>null</code> */ public RequestDispatcher getRequestDispatcher(String urlpath) { return null; } /** * Originally defined to return a servlet from the context * with the specified name. This method has been deprecated and * only remains to preserve binary compatibility. * This method will always return null. * * @deprecated This method has been deprecated for * servlet lifecycle reasons. This method will be permanently * removed in a future version of the Servlet API. */ public Servlet getServlet(String name) throws ServletException { return null; } /** * Originally defined to return an <tt>Enumeration</tt> of * <tt>Servlet</tt> objects containing all the servlets * known to this context. * This method has been deprecated and only remains to preserve * binary compatibility. This method must always return an empty * enumeration. * * @deprecated This method has been deprecated for * servlet lifecycle reasons. This method will be permanently * removed in a future version of the Servlet API. */ public Enumeration getServlets() { return new Vector().elements(); } /** * Originally defined to return an <tt>Enumeration</tt> of * <tt>String</tt> objects containing all the servlet names * known to this context. * This method has been deprecated and only remains to preserve * binary compatibility. This methd must always return an * empty enumeration. * * @deprecated This method has been deprecated for * servlet lifecycle reasons. This method will be permanently * removed in a future version of the Servlet API. */ public Enumeration getServletNames() { return new Vector().elements(); } /** * Logs the specified message to the context's log. The * log is set in the constructor. * * @param msg the message to be written */ public void log(String msg) { myLogWriter.println(msg); } /** * Logs the specified message and a stack trace of the given * exception to the context's log. The * log is set in the constructor. * * @param exception the exception to be written * @param msg the message to be written * * @deprecated Use log(String message, Throwable t) instead */ public void log(Exception exception, String msg) { log(msg, exception); } /** * Logs the specified message and a stack trace of the given * <tt>Throwable</tt> object to the context's log. The * log is set in the constructor. * * @param msg the message to be written * @param throwable the exception to be written */ public void log(String message, Throwable aThrowable) { ByteArrayOutputStream theStream = new ByteArrayOutputStream(); aThrowable.printStackTrace(new PrintWriter(theStream,true)); log(message + "\n" + theStream.toString()); } /** * Applies alias rules to the specified virtual path in URL path * format, that is, <tt>/dir/dir/file.ext</tt>. Returns a * String representing the corresponding real path in the * format that is appropriate for the operating system the * servlet engine is running under (including the proper path * separators). * * <p>This method returns null if the translation could not * be performed for any reason. * * @param path the virtual path to be translated into a real path */ public String getRealPath(String path) { if (myResourceBaseURL == null) { return null; } if (!myResourceBaseURL.getProtocol().startsWith("file")) { return null; } try { String theRealPath = getResource(path).getFile().replace('/', File.separatorChar); log(getServerInfo() + "-- resource path :" + theRealPath) ; return theRealPath; } catch (MalformedURLException mue) {} return null; } /** * Returns the name and version of the network service under which * the servlet is running. The form of this string must begin with * <tt><servername>/<versionnumber></tt>. For example * the Java Web Server could return a string of the form * <tt>Java Web Server/1.1.3</tt>. Other optional information * can be returned in parenthesis after the primary string. For * example, <tt>Java Web Server/1.1.3 (JDK 1.1.6; Windows NT 4.0 x86) * </tt>. * * @return JSPC ServletContext Information} */ public String getServerInfo() { return "JSPC_ServletContext for TLD'S"; } /** * Returns an object that is known to the context by a given name, * or null if there is no such object associated with the name. * This method allwos access to additional information about the * servlet engine not already provided by other methods in this * interface. * * Attribute names should follow the same convention as package names. * Names matching java.*, javax.*, and sun.* are reserved for * definition by this specification or by the reference implementation. * * @param name the name of the attribute whose value is required * @return the value of the attribute, or null if the attribute * does not exist. */ public Object getAttribute(String name) { return myAttributes.get(name); } /** * Returns an enumeration of the attribute names present in this * context. */ public Enumeration getAttributeNames() { return myAttributes.keys(); } /** * Binds an object to a given name in this context. If an object * is allready bound into the context with the given name, * it will be replaced. * * Attribute names should follow the same convention as package names. * Names matching java.*, javax.*, and sun.* are reserved for * definition by this specification or by the reference implementation. * * @param name the name of the attribute to store * @param value the value of the attribute */ public void setAttribute(String name, Object object) { myAttributes.put(name, object); } /** * Removes the attribute from the context that is bound to a particular * name. * * @param name the name of the attribute to remove from the context */ public void removeAttribute(String name) { myAttributes.remove(name); } public RequestDispatcher getNamedDispatcher(String aDispatcher) { return null ; } public String getInitParameter(String aName) { return null ; } public Enumeration getInitParameterNames() { return new Vector().elements() ; } public String getServletContextName() { return null ; } public Set getResourcePaths(String path) { Set thePaths = new HashSet() ; if(!path.endsWith("/")) path = path + "/" ; String basePath = getRealPath(path) ; if(basePath!= null) { File theBaseDir = new File(basePath) ; if(theBaseDir.exists() && theBaseDir.isDirectory()) { String[] theFiles = theBaseDir.list() ; for(int i=0;i<theFiles.length;i++) { File testFile = new File(basePath + File.separator + theFiles[i]) ; if(testFile.isFile()) thePaths.add(path + theFiles[i]) ; else thePaths.add(path + theFiles[i] + "/" ); } } } return thePaths; } }