0001: /*
0002: * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/naming/resources/ProxyDirContext.java,v 1.12 2002/06/11 00:31:43 remm Exp $
0003: * $Revision: 1.12 $
0004: * $Date: 2002/06/11 00:31:43 $
0005: *
0006: * ====================================================================
0007: *
0008: * The Apache Software License, Version 1.1
0009: *
0010: * Copyright (c) 1999 The Apache Software Foundation. All rights
0011: * reserved.
0012: *
0013: * Redistribution and use in source and binary forms, with or without
0014: * modification, are permitted provided that the following conditions
0015: * are met:
0016: *
0017: * 1. Redistributions of source code must retain the above copyright
0018: * notice, this list of conditions and the following disclaimer.
0019: *
0020: * 2. Redistributions in binary form must reproduce the above copyright
0021: * notice, this list of conditions and the following disclaimer in
0022: * the documentation and/or other materials provided with the
0023: * distribution.
0024: *
0025: * 3. The end-user documentation included with the redistribution, if
0026: * any, must include the following acknowlegement:
0027: * "This product includes software developed by the
0028: * Apache Software Foundation (http://www.apache.org/)."
0029: * Alternately, this acknowlegement may appear in the software itself,
0030: * if and wherever such third-party acknowlegements normally appear.
0031: *
0032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
0033: * Foundation" must not be used to endorse or promote products derived
0034: * from this software without prior written permission. For written
0035: * permission, please contact apache@apache.org.
0036: *
0037: * 5. Products derived from this software may not be called "Apache"
0038: * nor may "Apache" appear in their names without prior written
0039: * permission of the Apache Group.
0040: *
0041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0052: * SUCH DAMAGE.
0053: * ====================================================================
0054: *
0055: * This software consists of voluntary contributions made by many
0056: * individuals on behalf of the Apache Software Foundation. For more
0057: * information on the Apache Software Foundation, please see
0058: * <http://www.apache.org/>.
0059: *
0060: * [Additional notices, if required by prior licensing conditions]
0061: *
0062: */
0063:
0064: package org.apache.naming.resources;
0065:
0066: import java.util.Collections;
0067: import java.util.Date;
0068: import java.util.Hashtable;
0069: import java.util.Map;
0070: import java.io.InputStream;
0071: import java.io.IOException;
0072: import java.io.ByteArrayInputStream;
0073:
0074: import javax.naming.Context;
0075: import javax.naming.Name;
0076: import javax.naming.NameParser;
0077: import javax.naming.NamingEnumeration;
0078: import javax.naming.NamingException;
0079: import javax.naming.directory.DirContext;
0080: import javax.naming.directory.Attributes;
0081: import javax.naming.directory.Attribute;
0082: import javax.naming.directory.ModificationItem;
0083: import javax.naming.directory.SearchControls;
0084:
0085: import org.apache.naming.StringManager;
0086:
0087: import org.apache.commons.collections.LRUMap;
0088:
0089: /**
0090: * Proxy Directory Context implementation.
0091: *
0092: * @author Remy Maucherat
0093: * @version $Revision: 1.12 $ $Date: 2002/06/11 00:31:43 $
0094: */
0095:
0096: public class ProxyDirContext implements DirContext {
0097:
0098: // -------------------------------------------------------------- Constants
0099:
0100: public static final String CONTEXT = "context";
0101: public static final String HOST = "host";
0102:
0103: // ----------------------------------------------------------- Constructors
0104:
0105: /**
0106: * Builds a proxy directory context using the given environment.
0107: */
0108: public ProxyDirContext(Hashtable env, DirContext dirContext) {
0109: this .env = env;
0110: this .dirContext = dirContext;
0111: if (dirContext instanceof BaseDirContext) {
0112: // Initialize parameters based on the associated dir context, like
0113: // the caching policy.
0114: if (((BaseDirContext) dirContext).isCached()) {
0115: cache = Collections.synchronizedMap(new LRUMap(
0116: cacheSize));
0117: cacheTTL = ((BaseDirContext) dirContext).getCacheTTL();
0118: cacheObjectMaxSize = ((BaseDirContext) dirContext)
0119: .getCacheObjectMaxSize();
0120: }
0121: }
0122: hostName = (String) env.get(HOST);
0123: contextName = (String) env.get(CONTEXT);
0124: }
0125:
0126: /**
0127: * Builds a clone of this proxy dir context, wrapping the given directory
0128: * context, and sharing the same cache.
0129: */
0130: protected ProxyDirContext(ProxyDirContext proxyDirContext,
0131: DirContext dirContext, String vPath) {
0132: this .env = proxyDirContext.env;
0133: this .dirContext = dirContext;
0134: this .vPath = vPath;
0135: this .cache = proxyDirContext.cache;
0136: this .cacheSize = proxyDirContext.cacheSize;
0137: this .cacheTTL = proxyDirContext.cacheTTL;
0138: this .cacheObjectMaxSize = proxyDirContext.cacheObjectMaxSize;
0139: this .hostName = proxyDirContext.hostName;
0140: this .contextName = proxyDirContext.contextName;
0141: }
0142:
0143: // ----------------------------------------------------- Instance Variables
0144:
0145: /**
0146: * Environment.
0147: */
0148: protected Hashtable env;
0149:
0150: /**
0151: * The string manager for this package.
0152: */
0153: protected StringManager sm = StringManager
0154: .getManager(Constants.Package);
0155:
0156: /**
0157: * Associated DirContext.
0158: */
0159: protected DirContext dirContext;
0160:
0161: /**
0162: * Virtual path.
0163: */
0164: protected String vPath = null;
0165:
0166: /**
0167: * Host name.
0168: */
0169: protected String hostName;
0170:
0171: /**
0172: * Context name.
0173: */
0174: protected String contextName;
0175:
0176: /**
0177: * Cache.
0178: * Path -> Cache entry.
0179: */
0180: protected Map cache = null;
0181:
0182: /**
0183: * Cache size
0184: */
0185: protected int cacheSize = 1000;
0186:
0187: /**
0188: * Cache TTL.
0189: */
0190: protected int cacheTTL = 5000; // 5s
0191:
0192: /**
0193: * Max size of resources which will have their content cached.
0194: */
0195: protected int cacheObjectMaxSize = 32768; // 32 KB
0196:
0197: // --------------------------------------------------------- Public Methods
0198:
0199: /**
0200: * Return the actual directory context we are wrapping.
0201: */
0202: public DirContext getDirContext() {
0203: return this .dirContext;
0204: }
0205:
0206: /**
0207: * Return the document root for this component.
0208: */
0209: public String getDocBase() {
0210: if (dirContext instanceof BaseDirContext)
0211: return ((BaseDirContext) dirContext).getDocBase();
0212: else
0213: return "";
0214: }
0215:
0216: /**
0217: * Return the host name.
0218: */
0219: public String getHostName() {
0220: return this .hostName;
0221: }
0222:
0223: /**
0224: * Return the context name.
0225: */
0226: public String getContextName() {
0227: return this .contextName;
0228: }
0229:
0230: // -------------------------------------------------------- Context Methods
0231:
0232: /**
0233: * Retrieves the named object. If name is empty, returns a new instance
0234: * of this context (which represents the same naming context as this
0235: * context, but its environment may be modified independently and it may
0236: * be accessed concurrently).
0237: *
0238: * @param name the name of the object to look up
0239: * @return the object bound to name
0240: * @exception NamingException if a naming exception is encountered
0241: */
0242: public Object lookup(Name name) throws NamingException {
0243: CacheEntry entry = cacheLookup(name.toString());
0244: if (entry != null) {
0245: if (entry.resource != null) {
0246: // Check content caching.
0247:
0248: return entry.resource;
0249: } else {
0250: return entry.context;
0251: }
0252: }
0253: Object object = dirContext.lookup(parseName(name));
0254: if (object instanceof InputStream)
0255: return new Resource((InputStream) object);
0256: else
0257: return object;
0258: }
0259:
0260: /**
0261: * Retrieves the named object.
0262: *
0263: * @param name the name of the object to look up
0264: * @return the object bound to name
0265: * @exception NamingException if a naming exception is encountered
0266: */
0267: public Object lookup(String name) throws NamingException {
0268: CacheEntry entry = cacheLookup(name);
0269: if (entry != null) {
0270: if (entry.resource != null) {
0271: return entry.resource;
0272: } else {
0273: return entry.context;
0274: }
0275: }
0276: Object object = dirContext.lookup(parseName(name));
0277: if (object instanceof InputStream) {
0278: return new Resource((InputStream) object);
0279: } else if (object instanceof DirContext) {
0280: return object;
0281: } else if (object instanceof Resource) {
0282: return object;
0283: } else {
0284: return new Resource(new ByteArrayInputStream(object
0285: .toString().getBytes()));
0286: }
0287: }
0288:
0289: /**
0290: * Binds a name to an object. All intermediate contexts and the target
0291: * context (that named by all but terminal atomic component of the name)
0292: * must already exist.
0293: *
0294: * @param name the name to bind; may not be empty
0295: * @param obj the object to bind; possibly null
0296: * @exception NameAlreadyBoundException if name is already bound
0297: * @exception InvalidAttributesException if object did not supply all
0298: * mandatory attributes
0299: * @exception NamingException if a naming exception is encountered
0300: */
0301: public void bind(Name name, Object obj) throws NamingException {
0302: dirContext.bind(parseName(name), obj);
0303: cacheUnload(name.toString());
0304: }
0305:
0306: /**
0307: * Binds a name to an object.
0308: *
0309: * @param name the name to bind; may not be empty
0310: * @param obj the object to bind; possibly null
0311: * @exception NameAlreadyBoundException if name is already bound
0312: * @exception InvalidAttributesException if object did not supply all
0313: * mandatory attributes
0314: * @exception NamingException if a naming exception is encountered
0315: */
0316: public void bind(String name, Object obj) throws NamingException {
0317: dirContext.bind(parseName(name), obj);
0318: cacheUnload(name);
0319: }
0320:
0321: /**
0322: * Binds a name to an object, overwriting any existing binding. All
0323: * intermediate contexts and the target context (that named by all but
0324: * terminal atomic component of the name) must already exist.
0325: * <p>
0326: * If the object is a DirContext, any existing attributes associated with
0327: * the name are replaced with those of the object. Otherwise, any
0328: * existing attributes associated with the name remain unchanged.
0329: *
0330: * @param name the name to bind; may not be empty
0331: * @param obj the object to bind; possibly null
0332: * @exception InvalidAttributesException if object did not supply all
0333: * mandatory attributes
0334: * @exception NamingException if a naming exception is encountered
0335: */
0336: public void rebind(Name name, Object obj) throws NamingException {
0337: dirContext.rebind(parseName(name), obj);
0338: cacheUnload(name.toString());
0339: }
0340:
0341: /**
0342: * Binds a name to an object, overwriting any existing binding.
0343: *
0344: * @param name the name to bind; may not be empty
0345: * @param obj the object to bind; possibly null
0346: * @exception InvalidAttributesException if object did not supply all
0347: * mandatory attributes
0348: * @exception NamingException if a naming exception is encountered
0349: */
0350: public void rebind(String name, Object obj) throws NamingException {
0351: dirContext.rebind(parseName(name), obj);
0352: cacheUnload(name);
0353: }
0354:
0355: /**
0356: * Unbinds the named object. Removes the terminal atomic name in name
0357: * from the target context--that named by all but the terminal atomic
0358: * part of name.
0359: * <p>
0360: * This method is idempotent. It succeeds even if the terminal atomic
0361: * name is not bound in the target context, but throws
0362: * NameNotFoundException if any of the intermediate contexts do not exist.
0363: *
0364: * @param name the name to bind; may not be empty
0365: * @exception NameNotFoundException if an intermediate context does not
0366: * exist
0367: * @exception NamingException if a naming exception is encountered
0368: */
0369: public void unbind(Name name) throws NamingException {
0370: dirContext.unbind(parseName(name));
0371: cacheUnload(name.toString());
0372: }
0373:
0374: /**
0375: * Unbinds the named object.
0376: *
0377: * @param name the name to bind; may not be empty
0378: * @exception NameNotFoundException if an intermediate context does not
0379: * exist
0380: * @exception NamingException if a naming exception is encountered
0381: */
0382: public void unbind(String name) throws NamingException {
0383: dirContext.unbind(parseName(name));
0384: cacheUnload(name);
0385: }
0386:
0387: /**
0388: * Binds a new name to the object bound to an old name, and unbinds the
0389: * old name. Both names are relative to this context. Any attributes
0390: * associated with the old name become associated with the new name.
0391: * Intermediate contexts of the old name are not changed.
0392: *
0393: * @param oldName the name of the existing binding; may not be empty
0394: * @param newName the name of the new binding; may not be empty
0395: * @exception NameAlreadyBoundException if newName is already bound
0396: * @exception NamingException if a naming exception is encountered
0397: */
0398: public void rename(Name oldName, Name newName)
0399: throws NamingException {
0400: dirContext.rename(parseName(oldName), parseName(newName));
0401: cacheUnload(oldName.toString());
0402: }
0403:
0404: /**
0405: * Binds a new name to the object bound to an old name, and unbinds the
0406: * old name.
0407: *
0408: * @param oldName the name of the existing binding; may not be empty
0409: * @param newName the name of the new binding; may not be empty
0410: * @exception NameAlreadyBoundException if newName is already bound
0411: * @exception NamingException if a naming exception is encountered
0412: */
0413: public void rename(String oldName, String newName)
0414: throws NamingException {
0415: dirContext.rename(parseName(oldName), parseName(newName));
0416: cacheUnload(oldName);
0417: }
0418:
0419: /**
0420: * Enumerates the names bound in the named context, along with the class
0421: * names of objects bound to them. The contents of any subcontexts are
0422: * not included.
0423: * <p>
0424: * If a binding is added to or removed from this context, its effect on
0425: * an enumeration previously returned is undefined.
0426: *
0427: * @param name the name of the context to list
0428: * @return an enumeration of the names and class names of the bindings in
0429: * this context. Each element of the enumeration is of type NameClassPair.
0430: * @exception NamingException if a naming exception is encountered
0431: */
0432: public NamingEnumeration list(Name name) throws NamingException {
0433: return dirContext.list(parseName(name));
0434: }
0435:
0436: /**
0437: * Enumerates the names bound in the named context, along with the class
0438: * names of objects bound to them.
0439: *
0440: * @param name the name of the context to list
0441: * @return an enumeration of the names and class names of the bindings in
0442: * this context. Each element of the enumeration is of type NameClassPair.
0443: * @exception NamingException if a naming exception is encountered
0444: */
0445: public NamingEnumeration list(String name) throws NamingException {
0446: return dirContext.list(parseName(name));
0447: }
0448:
0449: /**
0450: * Enumerates the names bound in the named context, along with the
0451: * objects bound to them. The contents of any subcontexts are not
0452: * included.
0453: * <p>
0454: * If a binding is added to or removed from this context, its effect on
0455: * an enumeration previously returned is undefined.
0456: *
0457: * @param name the name of the context to list
0458: * @return an enumeration of the bindings in this context.
0459: * Each element of the enumeration is of type Binding.
0460: * @exception NamingException if a naming exception is encountered
0461: */
0462: public NamingEnumeration listBindings(Name name)
0463: throws NamingException {
0464: return dirContext.listBindings(parseName(name));
0465: }
0466:
0467: /**
0468: * Enumerates the names bound in the named context, along with the
0469: * objects bound to them.
0470: *
0471: * @param name the name of the context to list
0472: * @return an enumeration of the bindings in this context.
0473: * Each element of the enumeration is of type Binding.
0474: * @exception NamingException if a naming exception is encountered
0475: */
0476: public NamingEnumeration listBindings(String name)
0477: throws NamingException {
0478: return dirContext.listBindings(parseName(name));
0479: }
0480:
0481: /**
0482: * Destroys the named context and removes it from the namespace. Any
0483: * attributes associated with the name are also removed. Intermediate
0484: * contexts are not destroyed.
0485: * <p>
0486: * This method is idempotent. It succeeds even if the terminal atomic
0487: * name is not bound in the target context, but throws
0488: * NameNotFoundException if any of the intermediate contexts do not exist.
0489: *
0490: * In a federated naming system, a context from one naming system may be
0491: * bound to a name in another. One can subsequently look up and perform
0492: * operations on the foreign context using a composite name. However, an
0493: * attempt destroy the context using this composite name will fail with
0494: * NotContextException, because the foreign context is not a "subcontext"
0495: * of the context in which it is bound. Instead, use unbind() to remove
0496: * the binding of the foreign context. Destroying the foreign context
0497: * requires that the destroySubcontext() be performed on a context from
0498: * the foreign context's "native" naming system.
0499: *
0500: * @param name the name of the context to be destroyed; may not be empty
0501: * @exception NameNotFoundException if an intermediate context does not
0502: * exist
0503: * @exception NotContextException if the name is bound but does not name
0504: * a context, or does not name a context of the appropriate type
0505: */
0506: public void destroySubcontext(Name name) throws NamingException {
0507: dirContext.destroySubcontext(parseName(name));
0508: cacheUnload(name.toString());
0509: }
0510:
0511: /**
0512: * Destroys the named context and removes it from the namespace.
0513: *
0514: * @param name the name of the context to be destroyed; may not be empty
0515: * @exception NameNotFoundException if an intermediate context does not
0516: * exist
0517: * @exception NotContextException if the name is bound but does not name
0518: * a context, or does not name a context of the appropriate type
0519: */
0520: public void destroySubcontext(String name) throws NamingException {
0521: dirContext.destroySubcontext(parseName(name));
0522: cacheUnload(name);
0523: }
0524:
0525: /**
0526: * Creates and binds a new context. Creates a new context with the given
0527: * name and binds it in the target context (that named by all but
0528: * terminal atomic component of the name). All intermediate contexts and
0529: * the target context must already exist.
0530: *
0531: * @param name the name of the context to create; may not be empty
0532: * @return the newly created context
0533: * @exception NameAlreadyBoundException if name is already bound
0534: * @exception InvalidAttributesException if creation of the subcontext
0535: * requires specification of mandatory attributes
0536: * @exception NamingException if a naming exception is encountered
0537: */
0538: public Context createSubcontext(Name name) throws NamingException {
0539: return dirContext.createSubcontext(parseName(name));
0540: }
0541:
0542: /**
0543: * Creates and binds a new context.
0544: *
0545: * @param name the name of the context to create; may not be empty
0546: * @return the newly created context
0547: * @exception NameAlreadyBoundException if name is already bound
0548: * @exception InvalidAttributesException if creation of the subcontext
0549: * requires specification of mandatory attributes
0550: * @exception NamingException if a naming exception is encountered
0551: */
0552: public Context createSubcontext(String name) throws NamingException {
0553: return dirContext.createSubcontext(parseName(name));
0554: }
0555:
0556: /**
0557: * Retrieves the named object, following links except for the terminal
0558: * atomic component of the name. If the object bound to name is not a
0559: * link, returns the object itself.
0560: *
0561: * @param name the name of the object to look up
0562: * @return the object bound to name, not following the terminal link
0563: * (if any).
0564: * @exception NamingException if a naming exception is encountered
0565: */
0566: public Object lookupLink(Name name) throws NamingException {
0567: return dirContext.lookupLink(parseName(name));
0568: }
0569:
0570: /**
0571: * Retrieves the named object, following links except for the terminal
0572: * atomic component of the name.
0573: *
0574: * @param name the name of the object to look up
0575: * @return the object bound to name, not following the terminal link
0576: * (if any).
0577: * @exception NamingException if a naming exception is encountered
0578: */
0579: public Object lookupLink(String name) throws NamingException {
0580: return dirContext.lookupLink(parseName(name));
0581: }
0582:
0583: /**
0584: * Retrieves the parser associated with the named context. In a
0585: * federation of namespaces, different naming systems will parse names
0586: * differently. This method allows an application to get a parser for
0587: * parsing names into their atomic components using the naming convention
0588: * of a particular naming system. Within any single naming system,
0589: * NameParser objects returned by this method must be equal (using the
0590: * equals() test).
0591: *
0592: * @param name the name of the context from which to get the parser
0593: * @return a name parser that can parse compound names into their atomic
0594: * components
0595: * @exception NamingException if a naming exception is encountered
0596: */
0597: public NameParser getNameParser(Name name) throws NamingException {
0598: return dirContext.getNameParser(parseName(name));
0599: }
0600:
0601: /**
0602: * Retrieves the parser associated with the named context.
0603: *
0604: * @param name the name of the context from which to get the parser
0605: * @return a name parser that can parse compound names into their atomic
0606: * components
0607: * @exception NamingException if a naming exception is encountered
0608: */
0609: public NameParser getNameParser(String name) throws NamingException {
0610: return dirContext.getNameParser(parseName(name));
0611: }
0612:
0613: /**
0614: * Composes the name of this context with a name relative to this context.
0615: * <p>
0616: * Given a name (name) relative to this context, and the name (prefix)
0617: * of this context relative to one of its ancestors, this method returns
0618: * the composition of the two names using the syntax appropriate for the
0619: * naming system(s) involved. That is, if name names an object relative
0620: * to this context, the result is the name of the same object, but
0621: * relative to the ancestor context. None of the names may be null.
0622: *
0623: * @param name a name relative to this context
0624: * @param prefix the name of this context relative to one of its ancestors
0625: * @return the composition of prefix and name
0626: * @exception NamingException if a naming exception is encountered
0627: */
0628: public Name composeName(Name name, Name prefix)
0629: throws NamingException {
0630: prefix = (Name) name.clone();
0631: return prefix.addAll(name);
0632: }
0633:
0634: /**
0635: * Composes the name of this context with a name relative to this context.
0636: *
0637: * @param name a name relative to this context
0638: * @param prefix the name of this context relative to one of its ancestors
0639: * @return the composition of prefix and name
0640: * @exception NamingException if a naming exception is encountered
0641: */
0642: public String composeName(String name, String prefix)
0643: throws NamingException {
0644: return prefix + "/" + name;
0645: }
0646:
0647: /**
0648: * Adds a new environment property to the environment of this context. If
0649: * the property already exists, its value is overwritten.
0650: *
0651: * @param propName the name of the environment property to add; may not
0652: * be null
0653: * @param propVal the value of the property to add; may not be null
0654: * @exception NamingException if a naming exception is encountered
0655: */
0656: public Object addToEnvironment(String propName, Object propVal)
0657: throws NamingException {
0658: return dirContext.addToEnvironment(propName, propVal);
0659: }
0660:
0661: /**
0662: * Removes an environment property from the environment of this context.
0663: *
0664: * @param propName the name of the environment property to remove;
0665: * may not be null
0666: * @exception NamingException if a naming exception is encountered
0667: */
0668: public Object removeFromEnvironment(String propName)
0669: throws NamingException {
0670: return dirContext.removeFromEnvironment(propName);
0671: }
0672:
0673: /**
0674: * Retrieves the environment in effect for this context. See class
0675: * description for more details on environment properties.
0676: * The caller should not make any changes to the object returned: their
0677: * effect on the context is undefined. The environment of this context
0678: * may be changed using addToEnvironment() and removeFromEnvironment().
0679: *
0680: * @return the environment of this context; never null
0681: * @exception NamingException if a naming exception is encountered
0682: */
0683: public Hashtable getEnvironment() throws NamingException {
0684: return dirContext.getEnvironment();
0685: }
0686:
0687: /**
0688: * Closes this context. This method releases this context's resources
0689: * immediately, instead of waiting for them to be released automatically
0690: * by the garbage collector.
0691: * This method is idempotent: invoking it on a context that has already
0692: * been closed has no effect. Invoking any other method on a closed
0693: * context is not allowed, and results in undefined behaviour.
0694: *
0695: * @exception NamingException if a naming exception is encountered
0696: */
0697: public void close() throws NamingException {
0698: dirContext.close();
0699: }
0700:
0701: /**
0702: * Retrieves the full name of this context within its own namespace.
0703: * <p>
0704: * Many naming services have a notion of a "full name" for objects in
0705: * their respective namespaces. For example, an LDAP entry has a
0706: * distinguished name, and a DNS record has a fully qualified name. This
0707: * method allows the client application to retrieve this name. The string
0708: * returned by this method is not a JNDI composite name and should not be
0709: * passed directly to context methods. In naming systems for which the
0710: * notion of full name does not make sense,
0711: * OperationNotSupportedException is thrown.
0712: *
0713: * @return this context's name in its own namespace; never null
0714: * @exception OperationNotSupportedException if the naming system does
0715: * not have the notion of a full name
0716: * @exception NamingException if a naming exception is encountered
0717: */
0718: public String getNameInNamespace() throws NamingException {
0719: return dirContext.getNameInNamespace();
0720: }
0721:
0722: // ----------------------------------------------------- DirContext Methods
0723:
0724: /**
0725: * Retrieves all of the attributes associated with a named object.
0726: *
0727: * @return the set of attributes associated with name.
0728: * Returns an empty attribute set if name has no attributes; never null.
0729: * @param name the name of the object from which to retrieve attributes
0730: * @exception NamingException if a naming exception is encountered
0731: */
0732: public Attributes getAttributes(Name name) throws NamingException {
0733: CacheEntry entry = cacheLookup(name.toString());
0734: if (entry != null) {
0735: return entry.attributes;
0736: }
0737: Attributes attributes = dirContext
0738: .getAttributes(parseName(name));
0739: if (!(attributes instanceof ResourceAttributes)) {
0740: attributes = new ResourceAttributes(attributes);
0741: }
0742: return attributes;
0743: }
0744:
0745: /**
0746: * Retrieves all of the attributes associated with a named object.
0747: *
0748: * @return the set of attributes associated with name
0749: * @param name the name of the object from which to retrieve attributes
0750: * @exception NamingException if a naming exception is encountered
0751: */
0752: public Attributes getAttributes(String name) throws NamingException {
0753: CacheEntry entry = cacheLookup(name);
0754: if (entry != null) {
0755: return entry.attributes;
0756: }
0757: Attributes attributes = dirContext
0758: .getAttributes(parseName(name));
0759: if (!(attributes instanceof ResourceAttributes)) {
0760: attributes = new ResourceAttributes(attributes);
0761: }
0762: return attributes;
0763: }
0764:
0765: /**
0766: * Retrieves selected attributes associated with a named object.
0767: * See the class description regarding attribute models, attribute type
0768: * names, and operational attributes.
0769: *
0770: * @return the requested attributes; never null
0771: * @param name the name of the object from which to retrieve attributes
0772: * @param attrIds the identifiers of the attributes to retrieve. null
0773: * indicates that all attributes should be retrieved; an empty array
0774: * indicates that none should be retrieved
0775: * @exception NamingException if a naming exception is encountered
0776: */
0777: public Attributes getAttributes(Name name, String[] attrIds)
0778: throws NamingException {
0779: Attributes attributes = dirContext.getAttributes(
0780: parseName(name), attrIds);
0781: if (!(attributes instanceof ResourceAttributes)) {
0782: attributes = new ResourceAttributes(attributes);
0783: }
0784: return attributes;
0785: }
0786:
0787: /**
0788: * Retrieves selected attributes associated with a named object.
0789: *
0790: * @return the requested attributes; never null
0791: * @param name the name of the object from which to retrieve attributes
0792: * @param attrIds the identifiers of the attributes to retrieve. null
0793: * indicates that all attributes should be retrieved; an empty array
0794: * indicates that none should be retrieved
0795: * @exception NamingException if a naming exception is encountered
0796: */
0797: public Attributes getAttributes(String name, String[] attrIds)
0798: throws NamingException {
0799: Attributes attributes = dirContext.getAttributes(
0800: parseName(name), attrIds);
0801: if (!(attributes instanceof ResourceAttributes)) {
0802: attributes = new ResourceAttributes(attributes);
0803: }
0804: return attributes;
0805: }
0806:
0807: /**
0808: * Modifies the attributes associated with a named object. The order of
0809: * the modifications is not specified. Where possible, the modifications
0810: * are performed atomically.
0811: *
0812: * @param name the name of the object whose attributes will be updated
0813: * @param mod_op the modification operation, one of: ADD_ATTRIBUTE,
0814: * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
0815: * @param attrs the attributes to be used for the modification; may not
0816: * be null
0817: * @exception AttributeModificationException if the modification cannot be
0818: * completed successfully
0819: * @exception NamingException if a naming exception is encountered
0820: */
0821: public void modifyAttributes(Name name, int mod_op, Attributes attrs)
0822: throws NamingException {
0823: dirContext.modifyAttributes(parseName(name), mod_op, attrs);
0824: }
0825:
0826: /**
0827: * Modifies the attributes associated with a named object.
0828: *
0829: * @param name the name of the object whose attributes will be updated
0830: * @param mod_op the modification operation, one of: ADD_ATTRIBUTE,
0831: * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
0832: * @param attrs the attributes to be used for the modification; may not
0833: * be null
0834: * @exception AttributeModificationException if the modification cannot be
0835: * completed successfully
0836: * @exception NamingException if a naming exception is encountered
0837: */
0838: public void modifyAttributes(String name, int mod_op,
0839: Attributes attrs) throws NamingException {
0840: dirContext.modifyAttributes(parseName(name), mod_op, attrs);
0841: }
0842:
0843: /**
0844: * Modifies the attributes associated with a named object using an an
0845: * ordered list of modifications. The modifications are performed in the
0846: * order specified. Each modification specifies a modification operation
0847: * code and an attribute on which to operate. Where possible, the
0848: * modifications are performed atomically.
0849: *
0850: * @param name the name of the object whose attributes will be updated
0851: * @param mods an ordered sequence of modifications to be performed; may
0852: * not be null
0853: * @exception AttributeModificationException if the modification cannot be
0854: * completed successfully
0855: * @exception NamingException if a naming exception is encountered
0856: */
0857: public void modifyAttributes(Name name, ModificationItem[] mods)
0858: throws NamingException {
0859: dirContext.modifyAttributes(parseName(name), mods);
0860: }
0861:
0862: /**
0863: * Modifies the attributes associated with a named object using an an
0864: * ordered list of modifications.
0865: *
0866: * @param name the name of the object whose attributes will be updated
0867: * @param mods an ordered sequence of modifications to be performed; may
0868: * not be null
0869: * @exception AttributeModificationException if the modification cannot be
0870: * completed successfully
0871: * @exception NamingException if a naming exception is encountered
0872: */
0873: public void modifyAttributes(String name, ModificationItem[] mods)
0874: throws NamingException {
0875: dirContext.modifyAttributes(parseName(name), mods);
0876: }
0877:
0878: /**
0879: * Binds a name to an object, along with associated attributes. If attrs
0880: * is null, the resulting binding will have the attributes associated
0881: * with obj if obj is a DirContext, and no attributes otherwise. If attrs
0882: * is non-null, the resulting binding will have attrs as its attributes;
0883: * any attributes associated with obj are ignored.
0884: *
0885: * @param name the name to bind; may not be empty
0886: * @param obj the object to bind; possibly null
0887: * @param attrs the attributes to associate with the binding
0888: * @exception NameAlreadyBoundException if name is already bound
0889: * @exception InvalidAttributesException if some "mandatory" attributes
0890: * of the binding are not supplied
0891: * @exception NamingException if a naming exception is encountered
0892: */
0893: public void bind(Name name, Object obj, Attributes attrs)
0894: throws NamingException {
0895: dirContext.bind(parseName(name), obj, attrs);
0896: }
0897:
0898: /**
0899: * Binds a name to an object, along with associated attributes.
0900: *
0901: * @param name the name to bind; may not be empty
0902: * @param obj the object to bind; possibly null
0903: * @param attrs the attributes to associate with the binding
0904: * @exception NameAlreadyBoundException if name is already bound
0905: * @exception InvalidAttributesException if some "mandatory" attributes
0906: * of the binding are not supplied
0907: * @exception NamingException if a naming exception is encountered
0908: */
0909: public void bind(String name, Object obj, Attributes attrs)
0910: throws NamingException {
0911: dirContext.bind(parseName(name), obj, attrs);
0912: }
0913:
0914: /**
0915: * Binds a name to an object, along with associated attributes,
0916: * overwriting any existing binding. If attrs is null and obj is a
0917: * DirContext, the attributes from obj are used. If attrs is null and obj
0918: * is not a DirContext, any existing attributes associated with the object
0919: * already bound in the directory remain unchanged. If attrs is non-null,
0920: * any existing attributes associated with the object already bound in
0921: * the directory are removed and attrs is associated with the named
0922: * object. If obj is a DirContext and attrs is non-null, the attributes
0923: * of obj are ignored.
0924: *
0925: * @param name the name to bind; may not be empty
0926: * @param obj the object to bind; possibly null
0927: * @param attrs the attributes to associate with the binding
0928: * @exception InvalidAttributesException if some "mandatory" attributes
0929: * of the binding are not supplied
0930: * @exception NamingException if a naming exception is encountered
0931: */
0932: public void rebind(Name name, Object obj, Attributes attrs)
0933: throws NamingException {
0934: dirContext.rebind(parseName(name), obj, attrs);
0935: }
0936:
0937: /**
0938: * Binds a name to an object, along with associated attributes,
0939: * overwriting any existing binding.
0940: *
0941: * @param name the name to bind; may not be empty
0942: * @param obj the object to bind; possibly null
0943: * @param attrs the attributes to associate with the binding
0944: * @exception InvalidAttributesException if some "mandatory" attributes
0945: * of the binding are not supplied
0946: * @exception NamingException if a naming exception is encountered
0947: */
0948: public void rebind(String name, Object obj, Attributes attrs)
0949: throws NamingException {
0950: dirContext.rebind(parseName(name), obj, attrs);
0951: }
0952:
0953: /**
0954: * Creates and binds a new context, along with associated attributes.
0955: * This method creates a new subcontext with the given name, binds it in
0956: * the target context (that named by all but terminal atomic component of
0957: * the name), and associates the supplied attributes with the newly
0958: * created object. All intermediate and target contexts must already
0959: * exist. If attrs is null, this method is equivalent to
0960: * Context.createSubcontext().
0961: *
0962: * @param name the name of the context to create; may not be empty
0963: * @param attrs the attributes to associate with the newly created context
0964: * @return the newly created context
0965: * @exception NameAlreadyBoundException if the name is already bound
0966: * @exception InvalidAttributesException if attrs does not contain all
0967: * the mandatory attributes required for creation
0968: * @exception NamingException if a naming exception is encountered
0969: */
0970: public DirContext createSubcontext(Name name, Attributes attrs)
0971: throws NamingException {
0972: return dirContext.createSubcontext(parseName(name), attrs);
0973: }
0974:
0975: /**
0976: * Creates and binds a new context, along with associated attributes.
0977: *
0978: * @param name the name of the context to create; may not be empty
0979: * @param attrs the attributes to associate with the newly created context
0980: * @return the newly created context
0981: * @exception NameAlreadyBoundException if the name is already bound
0982: * @exception InvalidAttributesException if attrs does not contain all
0983: * the mandatory attributes required for creation
0984: * @exception NamingException if a naming exception is encountered
0985: */
0986: public DirContext createSubcontext(String name, Attributes attrs)
0987: throws NamingException {
0988: return dirContext.createSubcontext(parseName(name), attrs);
0989: }
0990:
0991: /**
0992: * Retrieves the schema associated with the named object. The schema
0993: * describes rules regarding the structure of the namespace and the
0994: * attributes stored within it. The schema specifies what types of
0995: * objects can be added to the directory and where they can be added;
0996: * what mandatory and optional attributes an object can have. The range
0997: * of support for schemas is directory-specific.
0998: *
0999: * @param name the name of the object whose schema is to be retrieved
1000: * @return the schema associated with the context; never null
1001: * @exception OperationNotSupportedException if schema not supported
1002: * @exception NamingException if a naming exception is encountered
1003: */
1004: public DirContext getSchema(Name name) throws NamingException {
1005: return dirContext.getSchema(parseName(name));
1006: }
1007:
1008: /**
1009: * Retrieves the schema associated with the named object.
1010: *
1011: * @param name the name of the object whose schema is to be retrieved
1012: * @return the schema associated with the context; never null
1013: * @exception OperationNotSupportedException if schema not supported
1014: * @exception NamingException if a naming exception is encountered
1015: */
1016: public DirContext getSchema(String name) throws NamingException {
1017: return dirContext.getSchema(parseName(name));
1018: }
1019:
1020: /**
1021: * Retrieves a context containing the schema objects of the named
1022: * object's class definitions.
1023: *
1024: * @param name the name of the object whose object class definition is to
1025: * be retrieved
1026: * @return the DirContext containing the named object's class
1027: * definitions; never null
1028: * @exception OperationNotSupportedException if schema not supported
1029: * @exception NamingException if a naming exception is encountered
1030: */
1031: public DirContext getSchemaClassDefinition(Name name)
1032: throws NamingException {
1033: return dirContext.getSchemaClassDefinition(parseName(name));
1034: }
1035:
1036: /**
1037: * Retrieves a context containing the schema objects of the named
1038: * object's class definitions.
1039: *
1040: * @param name the name of the object whose object class definition is to
1041: * be retrieved
1042: * @return the DirContext containing the named object's class
1043: * definitions; never null
1044: * @exception OperationNotSupportedException if schema not supported
1045: * @exception NamingException if a naming exception is encountered
1046: */
1047: public DirContext getSchemaClassDefinition(String name)
1048: throws NamingException {
1049: return dirContext.getSchemaClassDefinition(parseName(name));
1050: }
1051:
1052: /**
1053: * Searches in a single context for objects that contain a specified set
1054: * of attributes, and retrieves selected attributes. The search is
1055: * performed using the default SearchControls settings.
1056: *
1057: * @param name the name of the context to search
1058: * @param matchingAttributes the attributes to search for. If empty or
1059: * null, all objects in the target context are returned.
1060: * @param attributesToReturn the attributes to return. null indicates
1061: * that all attributes are to be returned; an empty array indicates that
1062: * none are to be returned.
1063: * @return a non-null enumeration of SearchResult objects. Each
1064: * SearchResult contains the attributes identified by attributesToReturn
1065: * and the name of the corresponding object, named relative to the
1066: * context named by name.
1067: * @exception NamingException if a naming exception is encountered
1068: */
1069: public NamingEnumeration search(Name name,
1070: Attributes matchingAttributes, String[] attributesToReturn)
1071: throws NamingException {
1072: return dirContext.search(parseName(name), matchingAttributes,
1073: attributesToReturn);
1074: }
1075:
1076: /**
1077: * Searches in a single context for objects that contain a specified set
1078: * of attributes, and retrieves selected attributes.
1079: *
1080: * @param name the name of the context to search
1081: * @param matchingAttributes the attributes to search for. If empty or
1082: * null, all objects in the target context are returned.
1083: * @param attributesToReturn the attributes to return. null indicates
1084: * that all attributes are to be returned; an empty array indicates that
1085: * none are to be returned.
1086: * @return a non-null enumeration of SearchResult objects. Each
1087: * SearchResult contains the attributes identified by attributesToReturn
1088: * and the name of the corresponding object, named relative to the
1089: * context named by name.
1090: * @exception NamingException if a naming exception is encountered
1091: */
1092: public NamingEnumeration search(String name,
1093: Attributes matchingAttributes, String[] attributesToReturn)
1094: throws NamingException {
1095: return dirContext.search(parseName(name), matchingAttributes,
1096: attributesToReturn);
1097: }
1098:
1099: /**
1100: * Searches in a single context for objects that contain a specified set
1101: * of attributes. This method returns all the attributes of such objects.
1102: * It is equivalent to supplying null as the atributesToReturn parameter
1103: * to the method search(Name, Attributes, String[]).
1104: *
1105: * @param name the name of the context to search
1106: * @param matchingAttributes the attributes to search for. If empty or
1107: * null, all objects in the target context are returned.
1108: * @return a non-null enumeration of SearchResult objects. Each
1109: * SearchResult contains the attributes identified by attributesToReturn
1110: * and the name of the corresponding object, named relative to the
1111: * context named by name.
1112: * @exception NamingException if a naming exception is encountered
1113: */
1114: public NamingEnumeration search(Name name,
1115: Attributes matchingAttributes) throws NamingException {
1116: return dirContext.search(parseName(name), matchingAttributes);
1117: }
1118:
1119: /**
1120: * Searches in a single context for objects that contain a specified set
1121: * of attributes.
1122: *
1123: * @param name the name of the context to search
1124: * @param matchingAttributes the attributes to search for. If empty or
1125: * null, all objects in the target context are returned.
1126: * @return a non-null enumeration of SearchResult objects. Each
1127: * SearchResult contains the attributes identified by attributesToReturn
1128: * and the name of the corresponding object, named relative to the
1129: * context named by name.
1130: * @exception NamingException if a naming exception is encountered
1131: */
1132: public NamingEnumeration search(String name,
1133: Attributes matchingAttributes) throws NamingException {
1134: return dirContext.search(parseName(name), matchingAttributes);
1135: }
1136:
1137: /**
1138: * Searches in the named context or object for entries that satisfy the
1139: * given search filter. Performs the search as specified by the search
1140: * controls.
1141: *
1142: * @param name the name of the context or object to search
1143: * @param filter the filter expression to use for the search; may not be
1144: * null
1145: * @param cons the search controls that control the search. If null,
1146: * the default search controls are used (equivalent to
1147: * (new SearchControls())).
1148: * @return an enumeration of SearchResults of the objects that satisfy
1149: * the filter; never null
1150: * @exception InvalidSearchFilterException if the search filter specified
1151: * is not supported or understood by the underlying directory
1152: * @exception InvalidSearchControlsException if the search controls
1153: * contain invalid settings
1154: * @exception NamingException if a naming exception is encountered
1155: */
1156: public NamingEnumeration search(Name name, String filter,
1157: SearchControls cons) throws NamingException {
1158: return dirContext.search(parseName(name), filter, cons);
1159: }
1160:
1161: /**
1162: * Searches in the named context or object for entries that satisfy the
1163: * given search filter. Performs the search as specified by the search
1164: * controls.
1165: *
1166: * @param name the name of the context or object to search
1167: * @param filter the filter expression to use for the search; may not be
1168: * null
1169: * @param cons the search controls that control the search. If null,
1170: * the default search controls are used (equivalent to
1171: * (new SearchControls())).
1172: * @return an enumeration of SearchResults of the objects that satisfy
1173: * the filter; never null
1174: * @exception InvalidSearchFilterException if the search filter
1175: * specified is not supported or understood by the underlying directory
1176: * @exception InvalidSearchControlsException if the search controls
1177: * contain invalid settings
1178: * @exception NamingException if a naming exception is encountered
1179: */
1180: public NamingEnumeration search(String name, String filter,
1181: SearchControls cons) throws NamingException {
1182: return dirContext.search(parseName(name), filter, cons);
1183: }
1184:
1185: /**
1186: * Searches in the named context or object for entries that satisfy the
1187: * given search filter. Performs the search as specified by the search
1188: * controls.
1189: *
1190: * @param name the name of the context or object to search
1191: * @param filterExpr the filter expression to use for the search.
1192: * The expression may contain variables of the form "{i}" where i is a
1193: * nonnegative integer. May not be null.
1194: * @param filterArgs the array of arguments to substitute for the
1195: * variables in filterExpr. The value of filterArgs[i] will replace each
1196: * occurrence of "{i}". If null, equivalent to an empty array.
1197: * @param cons the search controls that control the search. If null, the
1198: * default search controls are used (equivalent to (new SearchControls())).
1199: * @return an enumeration of SearchResults of the objects that satisy the
1200: * filter; never null
1201: * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i}
1202: * expressions where i is outside the bounds of the array filterArgs
1203: * @exception InvalidSearchControlsException if cons contains invalid
1204: * settings
1205: * @exception InvalidSearchFilterException if filterExpr with filterArgs
1206: * represents an invalid search filter
1207: * @exception NamingException if a naming exception is encountered
1208: */
1209: public NamingEnumeration search(Name name, String filterExpr,
1210: Object[] filterArgs, SearchControls cons)
1211: throws NamingException {
1212: return dirContext.search(parseName(name), filterExpr,
1213: filterArgs, cons);
1214: }
1215:
1216: /**
1217: * Searches in the named context or object for entries that satisfy the
1218: * given search filter. Performs the search as specified by the search
1219: * controls.
1220: *
1221: * @param name the name of the context or object to search
1222: * @param filterExpr the filter expression to use for the search.
1223: * The expression may contain variables of the form "{i}" where i is a
1224: * nonnegative integer. May not be null.
1225: * @param filterArgs the array of arguments to substitute for the
1226: * variables in filterExpr. The value of filterArgs[i] will replace each
1227: * occurrence of "{i}". If null, equivalent to an empty array.
1228: * @param cons the search controls that control the search. If null, the
1229: * default search controls are used (equivalent to (new SearchControls())).
1230: * @return an enumeration of SearchResults of the objects that satisy the
1231: * filter; never null
1232: * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i}
1233: * expressions where i is outside the bounds of the array filterArgs
1234: * @exception InvalidSearchControlsException if cons contains invalid
1235: * settings
1236: * @exception InvalidSearchFilterException if filterExpr with filterArgs
1237: * represents an invalid search filter
1238: * @exception NamingException if a naming exception is encountered
1239: */
1240: public NamingEnumeration search(String name, String filterExpr,
1241: Object[] filterArgs, SearchControls cons)
1242: throws NamingException {
1243: return dirContext.search(parseName(name), filterExpr,
1244: filterArgs, cons);
1245: }
1246:
1247: // ------------------------------------------------------ Protected Methods
1248:
1249: /**
1250: * Parses a name.
1251: *
1252: * @return the parsed name
1253: */
1254: protected String parseName(String name) throws NamingException {
1255: return name;
1256: }
1257:
1258: /**
1259: * Parses a name.
1260: *
1261: * @return the parsed name
1262: */
1263: protected Name parseName(Name name) throws NamingException {
1264: return name;
1265: }
1266:
1267: /**
1268: * Lookup in cache.
1269: */
1270: protected CacheEntry cacheLookup(String name) {
1271: if (cache == null)
1272: return (null);
1273: CacheEntry cacheEntry = (CacheEntry) cache.get(name);
1274: if (cacheEntry == null) {
1275: cacheEntry = new CacheEntry();
1276: cacheEntry.name = name;
1277: // Load entry
1278: if (!cacheLoad(cacheEntry))
1279: return null;
1280: return (cacheEntry);
1281: } else {
1282: if (!validate(cacheEntry)) {
1283: if (!revalidate(cacheEntry)) {
1284: cacheUnload(cacheEntry.name);
1285: return (null);
1286: } else {
1287: cacheEntry.timestamp = System.currentTimeMillis()
1288: + cacheTTL;
1289: }
1290: }
1291: return (cacheEntry);
1292: }
1293: }
1294:
1295: /**
1296: * Validate entry.
1297: */
1298: protected boolean validate(CacheEntry entry) {
1299: if ((entry.resource != null)
1300: && (entry.resource.getContent() != null)
1301: && (System.currentTimeMillis() < entry.timestamp)) {
1302: return true;
1303: }
1304: return false;
1305: }
1306:
1307: /**
1308: * Revalidate entry.
1309: */
1310: protected boolean revalidate(CacheEntry entry) {
1311: // Get the attributes at the given path, and check the last
1312: // modification date
1313: if (entry.attributes == null)
1314: return false;
1315: long lastModified = entry.attributes.getLastModified();
1316: long contentLength = entry.attributes.getContentLength();
1317: if (lastModified <= 0)
1318: return false;
1319: try {
1320: Attributes tempAttributes = dirContext
1321: .getAttributes(entry.name);
1322: ResourceAttributes attributes = null;
1323: if (!(tempAttributes instanceof ResourceAttributes)) {
1324: attributes = new ResourceAttributes(tempAttributes);
1325: } else {
1326: attributes = (ResourceAttributes) tempAttributes;
1327: }
1328: long lastModified2 = attributes.getLastModified();
1329: long contentLength2 = attributes.getContentLength();
1330: return (lastModified == lastModified2)
1331: && (contentLength == contentLength2);
1332: } catch (NamingException e) {
1333: return false;
1334: }
1335: }
1336:
1337: /**
1338: * Load entry into cache.
1339: */
1340: protected boolean cacheLoad(CacheEntry entry) {
1341:
1342: if (cache == null)
1343: return false;
1344:
1345: String name = entry.name;
1346:
1347: // Retrieve missing info
1348:
1349: // Retrieving attributes
1350: if (entry.attributes == null) {
1351: try {
1352: Attributes attributes = dirContext
1353: .getAttributes(entry.name);
1354: if (!(attributes instanceof ResourceAttributes)) {
1355: entry.attributes = new ResourceAttributes(
1356: attributes);
1357: } else {
1358: entry.attributes = (ResourceAttributes) attributes;
1359: }
1360: } catch (NamingException e) {
1361: return false;
1362: }
1363: }
1364:
1365: // Retriving object
1366: if ((entry.resource == null) && (entry.context == null)) {
1367: try {
1368: Object object = dirContext.lookup(name);
1369: if (object instanceof InputStream) {
1370: entry.resource = new Resource((InputStream) object);
1371: } else if (object instanceof DirContext) {
1372: entry.context = (DirContext) object;
1373: } else if (object instanceof Resource) {
1374: entry.resource = (Resource) object;
1375: } else {
1376: entry.resource = new Resource(
1377: new ByteArrayInputStream(object.toString()
1378: .getBytes()));
1379: }
1380: } catch (NamingException e) {
1381: return false;
1382: }
1383: }
1384:
1385: // Load object content
1386: if ((entry.resource != null)
1387: && (entry.resource.getContent() == null)
1388: && (entry.attributes.getContentLength() >= 0)
1389: && (entry.attributes.getContentLength() < cacheObjectMaxSize)) {
1390: int length = (int) entry.attributes.getContentLength();
1391: InputStream is = null;
1392: try {
1393: is = entry.resource.streamContent();
1394: int pos = 0;
1395: byte[] b = new byte[length];
1396: while (pos < length) {
1397: int n = is.read(b, pos, length - pos);
1398: if (n < 0)
1399: break;
1400: pos = pos + n;
1401: }
1402: entry.resource.setContent(b);
1403: } catch (IOException e) {
1404: ; // Ignore
1405: } finally {
1406: try {
1407: if (is != null)
1408: is.close();
1409: } catch (IOException e) {
1410: ; // Ignore
1411: }
1412: }
1413: }
1414:
1415: // Set timestamp
1416: entry.timestamp = System.currentTimeMillis() + cacheTTL;
1417:
1418: // Add new entry to cache
1419: cache.put(name, entry);
1420:
1421: return true;
1422:
1423: }
1424:
1425: /**
1426: * Remove entry from cache.
1427: */
1428: protected boolean cacheUnload(String name) {
1429: if (cache == null)
1430: return false;
1431: return (cache.remove(name) != null);
1432: }
1433:
1434: // ------------------------------------------------- CacheEntry Inner Class
1435:
1436: protected class CacheEntry {
1437:
1438: // ------------------------------------------------- Instance Variables
1439:
1440: long timestamp = -1;
1441: String name = null;
1442: ResourceAttributes attributes = null;
1443: Resource resource = null;
1444: DirContext context = null;
1445:
1446: // ----------------------------------------------------- Public Methods
1447:
1448: public void recycle() {
1449: timestamp = -1;
1450: name = null;
1451: attributes = null;
1452: resource = null;
1453: context = null;
1454: }
1455:
1456: public String toString() {
1457: return ("Cache entry: " + name + "\n" + "Attributes: "
1458: + attributes + "\n" + "Resource: " + resource
1459: + "\n" + "Context: " + context);
1460: }
1461:
1462: }
1463:
1464: }
|