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