001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.naming.resources;
018:
019: import java.util.Date;
020:
021: import javax.naming.Binding;
022: import javax.naming.NameClassPair;
023: import javax.naming.NamingEnumeration;
024: import javax.naming.NamingException;
025:
026: import javax.naming.directory.Attribute;
027: import javax.naming.directory.Attributes;
028: import javax.naming.directory.DirContext;
029:
030: import junit.framework.Test;
031: import junit.framework.TestCase;
032: import junit.framework.TestSuite;
033:
034: /**
035: * <p>Basic unit tests for the <code>javax.naming.directory.DirContext</code>
036: * implementations. This class must be subclassed for each individual
037: * <code>DirContext</code> implementation.</p>
038: *
039: * <p><strong>WARNING</strong>: These tests make certain assumptions that
040: * can generate "false negative" results if they are violated:</p>
041: * <ul>
042: * <li>The pathname of a directory (or WAR file) containing the static
043: * resources of the <code>/examples</code> web application shipped
044: * with Tomcat is passed to our test class as a system property
045: * named <code>doc.base</code>.</li>
046: * <li>The entry names that can be found in the top-level DirContext of
047: * the static resources are enumerated in the <code>topLevelNames</code>
048: * variable.</li>
049: * <li>The entry names that can be found in the WEB-INF DirContext of
050: * the static resources are enumerated in the <code>webInfNames</code>
051: * variable.</li>
052: * <li>The entry names in either the top-level or WEB-INF DirContext contexts
053: * that should themselves be <code>DirContext</code> implementations (i.e.
054: * "subdirectories" in the static resources for this web application)
055: * are enumerated in the <code>dirContextNames</code> variable.</li>
056: * </ul>
057: *
058: * @author Craig R. McClanahan
059: * @version $Revision: 1.3 $ $Date: 2004/02/27 14:58:55 $
060: */
061:
062: public abstract class BaseDirContextTestCase extends TestCase {
063:
064: // ----------------------------------------------------- Instance Variables
065:
066: /**
067: * A directory context implementation to be tested.
068: */
069: protected DirContext context = null;
070:
071: /**
072: * The pathname of the document base directory for this directory context.
073: */
074: protected String docBase = System.getProperty("doc.base");
075:
076: /**
077: * Entry names that must be DirContexts. Names not on this list are
078: * assumed to be Resources.
079: */
080: protected static final String dirContextNames[] = { "classes",
081: "images", "jsp", "lib", "META-INF", "WEB-INF" };
082:
083: /**
084: * The set of names that should be present in the top-level
085: * directory context.
086: */
087: protected static final String topLevelNames[] = { "index.jsp",
088: "jakarta-banner.gif", "tomcat.gif", "tomcat-power.gif",
089: "META-INF", "WEB-INF" };
090:
091: /**
092: * The set of names that should be present in the WEB-INF
093: * directory context.
094: */
095: protected static final String webInfNames[] = { "classes", "jsp",
096: "lib", "web.xml" };
097:
098: /**
099: * The set of names that should be attributes of WEB-INF.
100: */
101: protected static final String webInfAttrs[] = { "creationdate",
102: "displayname", "getcontentlength", "getlastmodified",
103: "resourcetype" };
104:
105: /**
106: * The set of names that should be attributes of WEB-INF/web.xml.
107: */
108: protected static final String webXmlAttrs[] = { "creationdate",
109: "displayname", "getcontentlength", "getlastmodified",
110: "resourcetype" };
111:
112: // ----------------------------------------------------------- Constructors
113:
114: /**
115: * Construct a new instance of this test case.
116: *
117: * @param name Name of the test case
118: */
119: public BaseDirContextTestCase(String name) {
120:
121: super (name);
122:
123: }
124:
125: // --------------------------------------------------- Overall Test Methods
126:
127: /**
128: * Set up instance variables required by this test case. This method
129: * <strong>MUST</strong> be implemented by a subclass.
130: */
131: public abstract void setUp();
132:
133: /**
134: * Return the tests included in this test suite. This method
135: * <strong>MUST</strong> be implemented by a subclass.
136: */
137: // public abstract static Test suite();
138:
139: /**
140: * Tear down instance variables required by this test case. This method
141: * <strong>MUST</strong> be implemented by a subclass.
142: */
143: public abstract void tearDown();
144:
145: // ------------------------------------------------ Individual Test Methods
146:
147: /**
148: * Test the attributes returned for the <code>WEB-INF</code> entry.
149: */
150: public abstract void testGetAttributesWebInf();
151:
152: /**
153: * Test the attributes returned for the <code>WEB-INF/web.xml</code>
154: * entry.
155: */
156: public abstract void testGetAttributesWebXml();
157:
158: /**
159: * We should be able to list the contents of the top-level context itself,
160: * and locate some entries we know are there.
161: */
162: public void testListTopLevel() {
163:
164: try {
165: checkList(context.list(""), topLevelNames);
166: } catch (NamingException e) {
167: fail("NamingException: " + e);
168: }
169:
170: }
171:
172: /**
173: * We should be able to list the contents of the WEB-INF entry,
174: * and locate some entries we know are there.
175: */
176: public void testListWebInfDirect() {
177:
178: try {
179:
180: // Look up the WEB-INF entry
181: Object webInfEntry = context.lookup("WEB-INF");
182: assertNotNull("Found WEB-INF entry", webInfEntry);
183: assertTrue("WEB-INF entry is a DirContext",
184: webInfEntry instanceof DirContext);
185: DirContext webInfContext = (DirContext) webInfEntry;
186:
187: // Check the contents of the WEB-INF context directly
188: checkList(webInfContext.list(""), webInfNames);
189:
190: } catch (NamingException e) {
191: fail("NamingException: " + e);
192: }
193:
194: }
195:
196: /**
197: * We should be able to list the contents of the WEB-INF entry,
198: * and locate some entries we know are there.
199: */
200: public void testListWebInfIndirect() {
201:
202: try {
203: checkList(context.list("WEB-INF"), webInfNames);
204: } catch (NamingException e) {
205: fail("NamingException: " + e);
206: }
207:
208: }
209:
210: /**
211: * We should be able to list the bindings of the top-level context itself,
212: * and locate some entries we know are there.
213: */
214: public void testListBindingsTopLevel() {
215:
216: try {
217: checkListBindings(context.listBindings(""), topLevelNames);
218: } catch (NamingException e) {
219: fail("NamingException: " + e);
220: }
221:
222: }
223:
224: /**
225: * We should be able to list the bindings of the WEB-INF entry,
226: * and locate some entries we know are there.
227: */
228: public void testListBindingsWebInfDirect() {
229:
230: try {
231:
232: // Look up the WEB-INF entry
233: Object webInfEntry = context.lookup("WEB-INF");
234: assertNotNull("Found WEB-INF entry", webInfEntry);
235: assertTrue("WEB-INF entry is a DirContext",
236: webInfEntry instanceof DirContext);
237: DirContext webInfContext = (DirContext) webInfEntry;
238:
239: // Check the bindings of the WEB-INF context directly
240: checkListBindings(webInfContext.listBindings(""),
241: webInfNames);
242:
243: } catch (NamingException e) {
244: fail("NamingException: " + e);
245: }
246:
247: }
248:
249: /**
250: * We should be able to list the bindings of the WEB-INF entry,
251: * and locate some entries we know are there.
252: */
253: public void testListBindingsWebInfIndirect() {
254:
255: try {
256: checkListBindings(context.listBindings("WEB-INF"),
257: webInfNames);
258: } catch (NamingException e) {
259: fail("NamingException: " + e);
260: }
261:
262: }
263:
264: // -------------------------------------------------------- Support Methods
265:
266: /**
267: * Check the results of a list() call against the specified entry list.
268: *
269: * @param enum The naming enumeration we are checking
270: * @param list The list of entry names we are expecting
271: *
272: * @exception NamingException if a naming exception occurs
273: */
274: protected void checkList(NamingEnumeration ne, String list[])
275: throws NamingException {
276:
277: String contextClassName = context.getClass().getName();
278:
279: assertNotNull("NamingEnumeration is not null", ne);
280: while (ne.hasMore()) {
281:
282: Object next = ne.next();
283: assertTrue("list() returns NameClassPair instances",
284: next instanceof NameClassPair);
285: NameClassPair ncp = (NameClassPair) next;
286:
287: assertTrue("Name '" + ncp.getName() + "' is expected",
288: isListed(ncp.getName(), list));
289:
290: if (isDirContext(ncp.getName())) {
291: assertTrue("Class '" + ncp.getClassName() + "' is '"
292: + contextClassName + "'", contextClassName
293: .equals(ncp.getClassName()));
294: }
295:
296: assertTrue("Relative is 'true'", ncp.isRelative());
297:
298: }
299:
300: }
301:
302: /**
303: * Check the results of a listBindings() call against the
304: * specified entry list.
305: *
306: * @param enum The naming enumeration we are checking
307: * @param list The list of entry names we are expecting
308: *
309: * @exception NamingException if a naming exception occurs
310: */
311: protected void checkListBindings(NamingEnumeration ne,
312: String list[]) throws NamingException {
313:
314: String contextClassName = context.getClass().getName();
315:
316: assertNotNull("NamingEnumeration is not null", ne);
317: while (ne.hasMore()) {
318:
319: Object next = ne.next();
320: assertTrue("listBindings() returns Binding instances",
321: next instanceof Binding);
322: Binding b = (Binding) next;
323:
324: assertTrue("Name '" + b.getName() + "' is expected",
325: isListed(b.getName(), list));
326:
327: if (isDirContext(b.getName())) {
328: assertTrue("Class '" + b.getClassName() + "' is '"
329: + contextClassName + "'", contextClassName
330: .equals(b.getClassName()));
331: }
332:
333: assertTrue("Relative is 'true'", b.isRelative());
334:
335: Object object = b.getObject();
336: assertNotNull("Name '" + b.getName()
337: + "' has a non-null object", object);
338: if (isDirContext(b.getName())) {
339: assertTrue("Entry '" + b.getName()
340: + "' is a DirContext",
341: object instanceof DirContext);
342: } else {
343: assertTrue("Entry '" + b.getName() + "' is a Resource",
344: object instanceof Resource);
345: }
346:
347: }
348:
349: }
350:
351: /**
352: * Check the attributes associated with a WEB-INF entry.
353: *
354: * @param attrs The attributes for this entry
355: * @param creationDate The creation date for this entry
356: * @param contentLength The content length for this entry
357: * @param displayName The display name for this entry
358: * @param lastModifiedDate The last modified date for this entry
359: */
360: protected void checkWebInfAttributes(Attributes attrs,
361: Date creationDate, long contentLength, String displayName,
362: Date lastModifiedDate) throws NamingException {
363:
364: assertNotNull("getAttributes() returned non-null", attrs);
365:
366: NamingEnumeration ne = attrs.getAll();
367: assertNotNull("getAll() returned non-null", ne);
368: while (ne.hasMore()) {
369:
370: Object next = ne.next();
371: assertTrue("getAll() returns Attribute instances",
372: next instanceof Attribute);
373: Attribute attr = (Attribute) next;
374: String name = attr.getID();
375: int index = getIndex(name, webInfAttrs);
376: assertTrue("WEB-INF attribute '" + name + "' is expected",
377: index >= 0);
378: Object value = attr.get();
379: assertNotNull("get() returned non-null", value);
380:
381: if (name.equals("creationdate")) {
382: assertTrue("Creation date is a date",
383: value instanceof Date);
384: assertTrue("Creation date equals " + creationDate,
385: creationDate.equals((Date) value));
386: } else if (name.equals("displayname")) {
387: assertTrue("Display name is a string",
388: value instanceof String);
389: assertTrue("Display name equals " + displayName,
390: displayName.equals((String) value));
391: } else if (name.equals("getcontentlength")) {
392: assertTrue("Content length is a long",
393: value instanceof Long);
394: assertTrue("Content length equals " + contentLength,
395: contentLength == ((Long) value).longValue());
396: } else if (name.equals("getlastmodified")) {
397: assertTrue("Last modified date is a date",
398: value instanceof Date);
399: assertTrue("Last modified date is " + lastModifiedDate,
400: lastModifiedDate.equals((Date) value));
401: }
402:
403: }
404:
405: }
406:
407: /**
408: * Check the attributes associated with a WEB-INF/web.xml entry.
409: *
410: * @param attrs The attributes for this entry
411: * @param creationDate The creation date for this entry
412: * @param contentLength The content length for this entry
413: * @param displayName The display name for this entry
414: * @param lastModifiedDate The last modified date for this entry
415: */
416: protected void checkWebXmlAttributes(Attributes attrs,
417: Date creationDate, long contentLength, String displayName,
418: Date lastModifiedDate) throws NamingException {
419:
420: assertNotNull("getAttributes() returned non-null", attrs);
421:
422: NamingEnumeration ne = attrs.getAll();
423: assertNotNull("getAll() returned non-null", ne);
424: while (ne.hasMore()) {
425:
426: Object next = ne.next();
427: assertTrue("getAll() returns Attribute instances",
428: next instanceof Attribute);
429: Attribute attr = (Attribute) next;
430: String name = attr.getID();
431: int index = getIndex(name, webXmlAttrs);
432: assertTrue("WEB-INF/web.xml attribute '" + name
433: + "' is expected", index >= 0);
434: Object value = attr.get();
435: assertNotNull("get() returned non-null", value);
436:
437: if (name.equals("creationdate")) {
438: assertTrue("Creation date is a date",
439: value instanceof Date);
440: assertTrue("Creation date equals " + creationDate,
441: creationDate.equals((Date) value));
442: } else if (name.equals("displayname")) {
443: assertTrue("Display name is a string",
444: value instanceof String);
445: assertTrue("Display name equals " + displayName,
446: displayName.equals((String) value));
447: } else if (name.equals("getcontentlength")) {
448: assertTrue("Content length is a long",
449: value instanceof Long);
450: assertTrue("Content length equals " + contentLength,
451: contentLength == ((Long) value).longValue());
452: } else if (name.equals("getlastmodified")) {
453: assertTrue("Last modified date is a date",
454: value instanceof Date);
455: assertTrue("Last modified date is " + lastModifiedDate,
456: lastModifiedDate.equals((Date) value));
457: }
458:
459: }
460:
461: }
462:
463: /**
464: * Return the index of the specified name in the specified list, or
465: * -1 if the name is not present.
466: *
467: * @param name Name to be looked up
468: * @param list List of names to be checked
469: */
470: protected int getIndex(String name, String list[]) {
471:
472: for (int i = 0; i < list.length; i++) {
473: if (name.equals(list[i]))
474: return (i);
475: }
476: return (-1);
477:
478: }
479:
480: /**
481: * Is an entry of the specified name supposed to be a DirContext?
482: *
483: * @param name Name to be checked
484: */
485: protected boolean isDirContext(String name) {
486:
487: return (isListed(name, dirContextNames));
488:
489: }
490:
491: /**
492: * Returns <code>true</code> if the specified name is found in the
493: * specified list.
494: *
495: * @param name Name to be looked up
496: * @param list List to be looked up into
497: */
498: protected boolean isListed(String name, String list[]) {
499:
500: return (getIndex(name, list) >= 0);
501:
502: }
503:
504: }
|