1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.configuration;
18
19 import java.util.Hashtable;
20
21 import javax.naming.Context;
22 import javax.naming.NameClassPair;
23 import javax.naming.NameNotFoundException;
24 import javax.naming.NamingEnumeration;
25 import javax.naming.NamingException;
26 import javax.naming.spi.InitialContextFactory;
27
28 import com.mockobjects.dynamic.C;
29 import com.mockobjects.dynamic.Mock;
30
31 /***
32 * A mock implementation of the <code>InitialContextFactory</code> interface.
33 * This implementation will return a mock context that contains some test data.
34 *
35 * @author <a
36 * href="http://jakarta.apache.org/commons/configuration/team-list.html">Commons
37 * Configuration team</a>
38 * @version $Id: MockInitialContextFactory.java 506128 2007-02-11 20:43:08Z oheger $
39 */
40 public class MockInitialContextFactory implements InitialContextFactory
41 {
42 /*** Constant for the lookup method. */
43 private static final String METHOD_LOOKUP = "lookup";
44
45 /*** Constant for the list method. */
46 private static final String METHOD_LIST = "list";
47
48 /*** Constant for the name of the missing property. */
49 private static final String MISSING_PROP = "/missing";
50
51 /*** Constant for the name of the prefix. */
52 private static final String PREFIX = "test/";
53
54 /*** An array with the names of the supported properties. */
55 private static final String[] PROP_NAMES =
56 { "key", "key2", "short", "boolean", "byte", "double", "float", "integer",
57 "long", "onlyinjndi" };
58
59 /*** An array with the values of the supported properties. */
60 private static final String[] PROP_VALUES =
61 { "jndivalue", "jndivalue2", "1", "true", "10", "10.25", "20.25", "10",
62 "1000000", "true" };
63
64 /*** An array with properties that are requested, but are not in the context. */
65 private static final String[] MISSING_NAMES =
66 { "missing/list", "test/imaginarykey", "foo/bar" };
67
68 /***
69 * Creates a <code>Context</code> object that is backed by a mock object.
70 * The mock context can be queried for the values of certain test
71 * properties. It also supports listing the contained (sub) properties.
72 *
73 * @param env the environment
74 * @return the context mock
75 */
76 public Context getInitialContext(Hashtable env) throws NamingException
77 {
78 Mock mockTopCtx = createCtxMock(PREFIX);
79 Mock mockPrfxCtx = createCtxMock("");
80 Mock mockBaseCtx = new Mock(Context.class);
81 mockBaseCtx.matchAndReturn(METHOD_LOOKUP, C.eq(""), mockTopCtx.proxy());
82 mockBaseCtx.matchAndReturn(METHOD_LOOKUP, C.eq("test"), mockPrfxCtx
83 .proxy());
84 mockTopCtx.matchAndReturn(METHOD_LOOKUP, C.eq("test"), mockPrfxCtx
85 .proxy());
86 mockTopCtx.matchAndReturn(METHOD_LIST, C.eq(""), createEnumMock(
87 mockTopCtx, new String[]
88 { "test" }, new Object[]
89 { mockPrfxCtx.proxy() }).proxy());
90 mockPrfxCtx.matchAndReturn(METHOD_LIST, C.eq(""), createEnumMock(
91 mockPrfxCtx, PROP_NAMES, PROP_VALUES).proxy());
92 return (Context) mockBaseCtx.proxy();
93 }
94
95 /***
96 * Creates a mock for a Context with the specified prefix.
97 *
98 * @param prefix the prefix
99 * @return the mock for the context
100 */
101 private Mock createCtxMock(String prefix)
102 {
103 Mock mockCtx = new Mock(Context.class);
104 for (int i = 0; i < PROP_NAMES.length; i++)
105 {
106 bind(mockCtx, prefix + PROP_NAMES[i], PROP_VALUES[i]);
107 String errProp = (prefix.length() > 0) ? PROP_NAMES[i] : PREFIX
108 + PROP_NAMES[i];
109 bindError(mockCtx, errProp);
110 }
111 for (int i = 0; i < MISSING_NAMES.length; i++)
112 {
113 bindError(mockCtx, MISSING_NAMES[i]);
114 }
115 return mockCtx;
116 }
117
118 /***
119 * Binds a property value to the mock context.
120 *
121 * @param mockCtx the context
122 * @param name the name of the property
123 * @param value the value of the property
124 */
125 private void bind(Mock mockCtx, String name, String value)
126 {
127 mockCtx.matchAndReturn(METHOD_LOOKUP, C.eq(name), value);
128 bindError(mockCtx, name + MISSING_PROP);
129 }
130
131 /***
132 * Configures the mock to expect a call for a non existing property.
133 *
134 * @param mockCtx the mock
135 * @param name the name of the property
136 */
137 private void bindError(Mock mockCtx, String name)
138 {
139 mockCtx.matchAndThrow(METHOD_LOOKUP, C.eq(name),
140 new NameNotFoundException("unknown property"));
141 }
142
143 /***
144 * Creates and initializes a mock for a naming enumeration.
145 *
146 * @param mockCtx the mock representing the context
147 * @param names the names contained in the iteration
148 * @param values the corresponding values
149 * @return the mock for the enumeration
150 */
151 private Mock createEnumMock(Mock mockCtx, String[] names, Object[] values)
152 {
153 Mock mockEnum = new Mock(NamingEnumeration.class);
154 for (int i = 0; i < names.length; i++)
155 {
156 NameClassPair ncp = new NameClassPair(names[i], values[i]
157 .getClass().getName());
158 mockEnum.expectAndReturn("hasMore", true);
159 mockEnum.expectAndReturn("next", ncp);
160 }
161 mockEnum.expectAndReturn("hasMore", false);
162 mockEnum.expect("close");
163 return mockEnum;
164 }
165 }