001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2007
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.war.webdav;
034:
035: import javax.naming.*;
036: import javax.naming.directory.*;
037: import java.io.Serializable;
038: import java.util.*;
039:
040: /**
041: * Memory impementation ofthe DirContext.
042: */
043: public class MemoryDirContext extends DirContextStringImpl implements
044: DirContext, Serializable {
045: static final long serialVersionUID = 2547463437468465948L;
046: private static NameParser nameParser = DefaultName.getNameParser();
047: private HashMap<String, Object> bindings = new HashMap<String, Object>();
048: private HashMap<String, Attributes> bindingAttrs = new HashMap<String, Attributes>();
049: private MemoryDirContext parent;
050: private String contextName;
051: private Hashtable env;
052:
053: /**
054: * Constructor
055: */
056: public MemoryDirContext() {
057: this .contextName = "";
058: }
059:
060: /**
061: * Constructor.
062: *
063: * @param contextName
064: * @param parent
065: * @param attributes
066: * @throws NamingException
067: */
068: public MemoryDirContext(String contextName,
069: MemoryDirContext parent, Attributes attributes)
070: throws NamingException {
071: this (contextName, parent, attributes, null);
072: }
073:
074: /**
075: * Constructor.
076: *
077: * @param contextName
078: * @param parent
079: * @param attributes
080: * @param env
081: * @throws NamingException
082: */
083: public MemoryDirContext(String contextName,
084: MemoryDirContext parent, Attributes attributes,
085: Hashtable env) throws NamingException {
086: this .contextName = contextName == null ? "" : contextName;
087: this .parent = parent;
088: bindingAttrs.put("", (Attributes) attributes.clone());
089: if (parent != null)
090: parent.bind(contextName, this );
091: this .env = (Hashtable) env.clone();
092: }
093:
094: /**
095: * Returns a String representation of the object.
096: *
097: * @return a String representation of the object.
098: */
099: public String toString() {
100: try {
101: return getFullName().toString();
102: } catch (NamingException e) {
103: return e.getMessage();
104: }
105: }
106:
107: /**
108: * Returns the name.
109: *
110: * @return the name
111: */
112:
113: String getName() {
114: return contextName;
115: }
116:
117: /**
118: * Sets the name.
119: *
120: * @param contextName the new name
121: */
122: void setName(String contextName) {
123: this .contextName = contextName;
124: }
125:
126: /**
127: * Returns the full name.
128: *
129: * @return the full name
130: * @throws NamingException
131: */
132: Name getFullName() throws NamingException {
133: CompositeName name = new CompositeName(getName());
134: MemoryDirContext context = parent;
135: if (context == null)
136: return name;
137:
138: try {
139: while (context.parent != null) {
140: name.add(0, context.getName());
141: context = context.parent;
142: }
143: } catch (NamingException e) {/*ignore*/
144: }
145: return name;
146: }
147:
148: public Object addToEnvironment(String p1, Object p2)
149: throws NamingException {
150: return null;
151: }
152:
153: public Object removeFromEnvironment(String p1)
154: throws NamingException {
155: return null;
156: }
157:
158: public void bind(Name name, Object value) throws NamingException {
159: bind(name, value, null);
160: }
161:
162: public void bind(Name name, Object value, Attributes attributes)
163: throws NamingException {
164: if (name.isEmpty()) {
165: throw new InvalidNameException("Cannot bind empty name");
166: }
167:
168: internalBind(name, value, attributes, true);
169: }
170:
171: public void close() throws NamingException {
172: }
173:
174: public Name composeName(Name p1, Name p2) throws NamingException {
175: return null;
176: }
177:
178: public Context createSubcontext(Name name) throws NamingException {
179: return createSubcontext(name, null);
180: }
181:
182: public DirContext createSubcontext(Name name, Attributes attributes)
183: throws NamingException {
184: if (name.isEmpty()) {
185: throw new InvalidNameException(
186: "Cannot createSubcontext with empty name");
187: }
188:
189: DirContext subctx;
190: String atom = name.get(0);
191: if (name.size() == 1) {
192: subctx = new MemoryDirContext(atom, this , attributes, env);
193: } else {
194: DirContext context = (DirContext) bindings.get(atom);
195: subctx = context.createSubcontext(name.getSuffix(1),
196: attributes);
197: }
198:
199: return subctx;
200: }
201:
202: public void destroySubcontext(Name name) throws NamingException {
203: unbind(name);
204: }
205:
206: public Attributes getAttributes(Name name) throws NamingException {
207: return getAttributes(name, null);
208: }
209:
210: public Attributes getAttributes(Name name, String[] attrIDs)
211: throws NamingException {
212: Attributes nameAttributes;
213: String atom = name.isEmpty() ? "" : name.get(0);
214: if (name.isEmpty()) {
215: nameAttributes = bindingAttrs.get("");
216: } else if (name.size() == 1) {
217: Object binding = bindings.get(atom);
218: if (binding != null) {
219: if (binding instanceof DirContext) {
220: DirContext dirCtx = (DirContext) binding;
221: try {
222: return dirCtx.getAttributes(name.getSuffix(1),
223: attrIDs);
224: } catch (Exception exc) {
225: return new BasicAttributes();
226: }
227: }
228: }
229: nameAttributes = bindingAttrs.get(atom);
230: } else {
231: DirContext context = (DirContext) bindings.get(atom);
232: nameAttributes = context.getAttributes(name.getSuffix(1),
233: attrIDs);
234: }
235:
236: if (nameAttributes != null && attrIDs != null) {
237: BasicAttributes matches = new BasicAttributes(
238: nameAttributes.isCaseIgnored());
239: for (String attrID : attrIDs) {
240: Attribute attr = nameAttributes.get(attrID);
241: if (attr != null)
242: matches.put(attr);
243: }
244: nameAttributes = matches;
245: }
246: return nameAttributes;
247: }
248:
249: public java.util.Hashtable<?, ?> getEnvironment()
250: throws NamingException {
251: return (Hashtable<?, ?>) Collections.unmodifiableMap(env);
252: }
253:
254: public String getNameInNamespace() throws NamingException {
255: return toString();
256: }
257:
258: public NameParser getNameParser(Name p1) throws NamingException {
259: return nameParser;
260: }
261:
262: public DirContext getSchema(Name p1) throws NamingException {
263: throw new OperationNotSupportedException("Not implemented yet");
264: }
265:
266: public DirContext getSchemaClassDefinition(Name p1)
267: throws NamingException {
268: throw new OperationNotSupportedException("Not implemented yet");
269: }
270:
271: public NamingEnumeration<NameClassPair> list(Name p1)
272: throws NamingException {
273: NamingEnumeration<Binding> result = listBindings(p1);
274: // Cast -> NameClassPair
275: ArrayList<NameClassPair> tmp = new ArrayList<NameClassPair>(50);
276: while (result.hasMore()) {
277: tmp.add((NameClassPair) result.next());
278: }
279: return new NameBindingIterator(tmp.iterator(), this );
280: }
281:
282: public NamingEnumeration<Binding> listBindings(Name name)
283: throws NamingException {
284: NamingEnumeration<Binding> iter;
285:
286: if (name.isEmpty()) {
287: Iterator keys = bindings.keySet().iterator();
288: ArrayList<DirBinding> tmp = new ArrayList<DirBinding>();
289: while (keys.hasNext()) {
290: String key = (String) keys.next();
291: Object value = bindings.get(key);
292: Attributes attributes = bindingAttrs.get(key);
293: DirBinding tuple = new DirBinding(key, value,
294: attributes);
295: tmp.add(tuple);
296: }
297: iter = new NameBindingIterator(tmp.iterator(), this );
298: } else {
299: String atom = name.get(0);
300: Context context = (Context) bindings.get(atom);
301: iter = context.listBindings(name.getSuffix(1));
302: }
303:
304: return iter;
305: }
306:
307: public Object lookup(Name name) throws NamingException {
308: if (name.isEmpty())
309: return this ;
310:
311: String atom = name.get(0);
312: Object binding = bindings.get(atom);
313: if (name.size() == 1) { /* Need to check that binding is null and atom is not a key
314: since a null value could have been bound.
315: */
316: if (binding == null && !bindings.containsKey(atom)) {
317: NameNotFoundException e = new NameNotFoundException(
318: "Failed to find: " + atom);
319: e.setRemainingName(name);
320: e.setResolvedObj(this );
321: throw e;
322: }
323: } else if ((binding instanceof Context)) {
324: Context context = (Context) binding;
325: binding = context.lookup(name.getSuffix(1));
326: } else {
327: NotContextException e = new NotContextException(
328: atom
329: + " does not name a directory context that supports attributes");
330: e.setRemainingName(name);
331: e.setResolvedObj(binding);
332: throw e;
333: }
334: return binding;
335: }
336:
337: public Object lookupLink(Name p1) throws NamingException {
338: throw new OperationNotSupportedException("Not implemented yet");
339: }
340:
341: public void modifyAttributes(Name p1, ModificationItem[] p2)
342: throws NamingException {
343: throw new OperationNotSupportedException("Not implemented yet");
344: }
345:
346: public void modifyAttributes(Name p1, int p2, Attributes p3)
347: throws NamingException {
348: throw new OperationNotSupportedException("Not implemented yet");
349: }
350:
351: public void rebind(Name name, Object value) throws NamingException {
352: rebind(name, value, null);
353: }
354:
355: public void rebind(Name name, Object value, Attributes attributes)
356: throws NamingException {
357: if (name.isEmpty()) {
358: throw new InvalidNameException("Cannot bind empty name");
359: }
360:
361: internalBind(name, value, attributes, false);
362: }
363:
364: public void rename(Name p1, Name p2) throws NamingException {
365: throw new OperationNotSupportedException("Not implemented yet");
366: }
367:
368: public NamingEnumeration<javax.naming.directory.SearchResult> search(
369: Name p1, Attributes p2) throws NamingException {
370: throw new OperationNotSupportedException("Not implemented yet");
371: }
372:
373: public NamingEnumeration<javax.naming.directory.SearchResult> search(
374: Name p1, String p2, SearchControls p3)
375: throws NamingException {
376: throw new OperationNotSupportedException("Not implemented yet");
377: }
378:
379: public NamingEnumeration<javax.naming.directory.SearchResult> search(
380: Name p1, Attributes p2, String[] p3) throws NamingException {
381: throw new OperationNotSupportedException("Not implemented yet");
382: }
383:
384: public NamingEnumeration<javax.naming.directory.SearchResult> search(
385: Name p1, String p2, Object[] p3, SearchControls p4)
386: throws NamingException {
387: throw new OperationNotSupportedException("Not implemented yet");
388: }
389:
390: public void unbind(Name name) throws NamingException {
391: if (name.isEmpty()) {
392: throw new InvalidNameException("Cannot unbind empty name");
393: }
394:
395: String atom = name.get(0);
396: Object binding = bindings.get(atom);
397: if (name.size() == 1) { /* Need to check that binding is null and atom is not a key
398: since a null value could have been bound.
399: */
400: if (binding == null && !bindings.containsKey(atom)) {
401: NameNotFoundException e = new NameNotFoundException(
402: "Failed to find: " + atom);
403: e.setRemainingName(name);
404: e.setResolvedObj(this );
405: throw e;
406: }
407: bindings.remove(atom);
408: bindingAttrs.remove(atom);
409: } else if ((binding instanceof Context)) {
410: Context context = (Context) binding;
411: context.unbind(name.getSuffix(1));
412: } else {
413: NotContextException e = new NotContextException(
414: atom
415: + " does not name a directory context that supports attributes");
416: e.setRemainingName(name);
417: e.setResolvedObj(binding);
418: throw e;
419: }
420: }
421:
422: // ---
423:
424: private void internalBind(Name name, Object value,
425: Attributes attributes, boolean isBind)
426: throws NamingException {
427: String atom = name.get(0);
428: Object binding = bindings.get(atom);
429:
430: if (name.size() == 1) {
431: if (binding != null && !isBind) {
432: throw new NameAlreadyBoundException(
433: "Use rebind to override");
434: }
435:
436: // Add object to internal data structure
437: bindings.put(atom, value);
438:
439: // Add attributes
440: if (attributes != null) {
441: bindingAttrs.put(atom, attributes);
442: }
443: } else {
444: // Intermediate name: Consume name in this context and continue
445: if (!(binding instanceof Context)) {
446: NotContextException e = new NotContextException(atom
447: + " does not name a context");
448: e.setRemainingName(name);
449: e.setResolvedObj(binding);
450: throw e;
451: }
452:
453: if (attributes == null) {
454: Context context = (Context) binding;
455: if (isBind)
456: context.bind(name.getSuffix(1), value);
457: else
458: context.rebind(name.getSuffix(1), value);
459: } else if (!(binding instanceof DirContext)) {
460: NotContextException e = new NotContextException(
461: atom
462: + " does not name a directory context that supports attributes");
463: e.setRemainingName(name);
464: e.setResolvedObj(binding);
465: throw e;
466: } else {
467: DirContext context = (DirContext) binding;
468: if (isBind)
469: context.bind(name.getSuffix(1), value, attributes);
470: else
471: context
472: .rebind(name.getSuffix(1), value,
473: attributes);
474: }
475: }
476: }
477: }
|