001: /***
002: * jwma Java WebMail
003: * Copyright (c) 2000-2003 jwma team
004: *
005: * jwma is free software; you can distribute and use this source
006: * under the terms of the BSD-style license received along with
007: * the distribution.
008: ***/package dtw.webmail.directory;
009:
010: import java.util.*;
011: import java.io.*;
012: import javax.naming.*;
013: import javax.naming.directory.*;
014:
015: /**
016: * Class that implements a pool for <tt>DirContext</tt>
017: * instances.
018: * Note that each context has a distinct connection, thus
019: * allows to be used concurrently with the other contexts in the pool.
020: * However, a context itself cannot be used concurrently.
021: *
022: * @author Dieter Wimberger
023: * @version 0.9.7 07/02/2003
024: *
025: * @see javax.naming.directory.DirContext
026: */
027: public class ContextPool {
028:
029: //Instance attributes
030: private List m_Pool;
031: private int m_Size;
032: private String m_ContextURL;
033: private boolean m_Serving = false;
034: private Properties m_Environment;
035: private String m_SearchName;
036: private String[] m_ResultAttributes;
037: private String m_BaseFilter;
038:
039: /**
040: * Constructs a <tt>DirContextPool</tt> instance.
041: *
042: * @param size the size of the pool as <tt>int</tt>.
043: * @param url the URL specifying the directory context as <tt>String</tt>.
044: */
045: public ContextPool(int size, String url) {
046: m_Size = size;
047: m_ContextURL = url;
048: prepareEnvironment();
049: initPool();
050: }//ContextPool
051:
052: /**
053: * Constructs a <tt>DirContextPool</tt> instance.
054: * This instance enables authenticated connections to the directory,
055: * using the given username and password.
056: *
057: * @param size the size of the pool as <tt>int</tt>.
058: * @param url the URL specifying the directory context as <tt>String</tt>.
059: * @param username the username to be used for authentication as <tt>String</tt>.
060: * @param password the password to be used for authentication as <tt>String</tt>.
061: */
062: public ContextPool(int size, String url, String username,
063: String password) {
064: m_Size = size;
065: m_ContextURL = url;
066: prepareEnvironment();
067: //add credentials to use
068: m_Environment.put(Context.SECURITY_PRINCIPAL, username);
069: m_Environment.put(Context.SECURITY_CREDENTIALS, password);
070: initPool();
071: }//ContextPool
072:
073: /**
074: * Returns a leased <tt>DirContext</tt> instance from this
075: * pool.
076: *
077: * @return the leased <tt>DirContext</tt> from this pool.
078: */
079: public synchronized DirContext leaseContext() {
080: if (!m_Serving) {
081: return null;
082: }
083: boolean served = false;
084: DirContext ctx = null;
085: while (!served) {
086: if (m_Pool.size() == 0) {
087: try {
088: wait();
089: } catch (Exception ex) {
090: //do nothing but wait again :)
091: }
092: } else {
093: ctx = (DirContext) m_Pool.get(0);
094: m_Pool.remove(0);
095: served = true;
096: }
097: }
098: return ctx;
099: }//leaseContext
100:
101: /**
102: * Releases a formerly leased <tt>DirContext</tt>, returning
103: * it into this pool.
104: *
105: * @param ctx the formerly leased <tt>DirContext</tt>
106: * to be released.
107: */
108: public synchronized void releaseContext(DirContext ctx) {
109: m_Pool.add(ctx);
110: notifyAll();
111: }//releaseContext
112:
113: /**
114: * Returns the ceiling (in terms of size) of this pool.
115: *
116: * @return the ceiling size of this pool as <tt>int</tt>.
117: */
118: public int getCeiling() {
119: return m_Size;
120: }//getCeiling
121:
122: /**
123: * Returns the size of this pool.
124: *
125: * @return the actual size of this pool as <tt>int</tt>.
126: */
127: public int size() {
128: return m_Pool.size();
129: }//size
130:
131: /**
132: * Resizes the pool.
133: *
134: * @param size the new size as <tt>int</tt>.
135: */
136: public void resize(int size) {
137: //FIXME: not very efficient
138: synchronized (m_Pool) {
139: clear();
140: m_Size = size;
141: initPool();
142: }
143: }//resize
144:
145: /**
146: * Removes all <tt>DirContext</tt> references from
147: * this pool.
148: * Note that it will do so gracefully, waiting for
149: * leased <tt>ProcessingResources</tt>.
150: */
151: public void clear() {
152: m_Serving = false;
153: //wait until pool complete
154: while (m_Pool.size() != m_Size) {
155: try {
156: wait();
157: } catch (Exception ex) {
158: //do nothing but wait again :)
159: }
160: }
161: //close all contexts
162: for (Iterator iter = m_Pool.iterator(); iter.hasNext();) {
163: try {
164: ((DirContext) iter.next()).close();
165: } catch (NamingException nex) {
166: }
167: }
168: //remove all elements
169: m_Pool.clear();
170: }//clear
171:
172: public String getSearchName() {
173: return m_SearchName;
174: }//getSearchName
175:
176: public void setSearchName(String sname) {
177: m_SearchName = sname;
178: }//setSearchName
179:
180: public String getBaseFilter() {
181: return m_BaseFilter;
182: }//getBaseFilter
183:
184: public void setBaseFilter(String filter) {
185: m_BaseFilter = filter;
186: }//setBaseFilter
187:
188: public String[] getResultAttributes() {
189: return m_ResultAttributes;
190: }//getResultAttributes
191:
192: public void setResultAttributes(String[] atts) {
193: m_ResultAttributes = atts;
194: }//setResultAttributes
195:
196: /**
197: * Initializes a pool of <tt>DirContext</tt> instances.
198: */
199: protected void initPool() {
200: m_Pool = new ArrayList(m_Size);
201: for (int i = 0; i < m_Size; i++) {
202: try {
203: m_Pool.add(new InitialDirContext(m_Environment));
204: } catch (NamingException ex) {
205: //handle
206: }
207: }
208: m_Serving = true;
209: }//initPool
210:
211: /**
212: * Prepares the environment that is used for the build
213: * context instances.
214: */
215: private void prepareEnvironment() {
216: m_Environment = new Properties();
217: //prepare the environment
218: m_Environment.put(Context.INITIAL_CONTEXT_FACTORY,
219: "com.sun.jndi.ldap.LdapCtxFactory");
220: m_Environment.put(Context.PROVIDER_URL, m_ContextURL);
221: }//prepareEnvironment
222:
223: }//ContextPool
|