Annotation of java/classes/org/w3c/tools/resources/ContainerResource.java, revision 1.2
1.1 bmahe 1: // ContainerResource.java
1.2 ! bmahe 2: // $Id: ContainerResource.java,v 1.1 1998/01/22 12:54:53 bmahe Exp $
1.1 bmahe 3: // (c) COPYRIGHT MIT and INRIA, 1996.
4: // Please first read the full copyright statement in file COPYRIGHT.html
5:
6: package org.w3c.tools.resources ;
7:
8: import java.util.*;
9:
10: import org.w3c.tools.resources.event.*;
11:
12: /**
13: * This resource manage children resources.
14: */
15: public abstract class ContainerResource extends AbstractContainer {
16:
17: /**
18: * Attribute index - The index of the resource key.
19: */
20: protected static int ATTR_KEY = -1;
21:
22: static {
23: Attribute a = null ;
24: Class cls = null ;
25: // Get a pointer to our own class:
26: try {
27: cls = Class.forName("org.w3c.tools.resources.ContainerResource") ;
28: } catch (Exception ex) {
29: ex.printStackTrace() ;
30: System.exit(1) ;
31: }
32: // The identifier attribute:
33: a = new IntegerAttribute("key",
34: null,
35: Attribute.COMPUTED);
36: ATTR_KEY = AttributeRegistry.registerAttribute(cls, a);
37: }
38:
39: public Object getClone(Object values[]) {
40: values[ATTR_KEY] = null;
41: return super.getClone(values);
42: }
43:
44: /**
45: * Get the container Key. This key must be unique and unchanged
46: * during the container life.
47: * @return a String instance.
48: */
49: public Integer getKey() {
50: Integer key = (Integer) getValue(ATTR_KEY, null);
51: if (key == null) {
52: key = new Integer(getIdentifier().hashCode() ^ (new Date().hashCode()));
53: setValue(ATTR_KEY, key);
54: }
55: return key;
56: }
57:
58: protected SpaceEntry getSpaceEntry() {
59: ResourceReference rr = getParent();
60: if (rr == null) //I'm root or external!!
61: return new SpaceEntryImpl(this);
62: try {
63: //FIXME sure that is a containerResource?
64: ContainerResource cont = (ContainerResource) rr.lock();
65: return new SpaceEntryImpl(cont);
66: } catch (InvalidResourceException ex) {
67: System.out.println(ex.getMessage());
68: ex.printStackTrace();
69: return null;
70: } finally {
71: rr.unlock();
72: }
73: }
74:
1.2 ! bmahe 75: /**
! 76: * Get the SpaceEntry of our children resources.
! 77: * @return A SpaceEntry instance.
! 78: */
1.1 bmahe 79: protected SpaceEntry getChildrenSpaceEntry() {
80: return new SpaceEntryImpl( this );
81: }
82:
83: /**
84: * This handles the <code>RESOURCE_MODIFIED</code> kind of events.
85: * @param evt The StructureChangeEvent.
86: */
87:
88: //FIXME EVENT, we don't know if this resource is valid.
89: public void resourceModified(StructureChangedEvent evt) {
90: super.resourceModified(evt);
91: }
92:
93: /**
94: * A new resource has been created in some space.
95: * This handles the <code>RESOURCE_CREATED</code> kind of events.
96: * @param evt The event describing the change.
97: */
98:
99: public void resourceCreated(StructureChangedEvent evt) {
100: super.resourceCreated(evt);
101: }
102:
103: /**
104: * A resource is about to be removed
105: * This handles the <code>RESOURCE_REMOVED</code> kind of events.
106: * @param evt The event describing the change.
107: */
108:
109: public void resourceRemoved(StructureChangedEvent evt) {
110: super.resourceRemoved(evt);
111: }
112:
113: /**
114: * Update default child attributes.
115: * A parent can often pass default attribute values to its children,
116: * such as a pointer to itself (the <em>parent</em> attribute).
117: * <p>This is the method to overide when you want your container
118: * to provide these kinds of attributes. By default this method will set
119: * the following attributes:
120: * <dl><dt>name<dd>The name of the child (it's identifier) -
121: * String instance.
122: * <dt>parent<dd>The parent of the child (ie ourself here) -
123: * a ContainerResource instance.
124: * <dt>url<dd>If a <em>identifier</em> attribute is defined, that
125: * attribute is set to the full URL path of the children.
126: * </dl>
127: */
128:
129: protected ResourceContext updateDefaultChildAttributes(Hashtable attrs) {
130: ResourceContext context = super.updateDefaultChildAttributes(attrs);
131: if (context == null) {
132: context = new ResourceContext(getContext());
133: attrs.put("context", context) ;
134: }
135: String name = (String) attrs.get("identifier");
136: if ( name != null )
137: attrs.put("url", getURLPath()+name);
138: return context;
139: }
140:
141: /**
142: * Enumerate children resource identifiers.
143: * @param all Should all resources be enumerated ? Resources are often
144: * created on demand only, this flag allows the caller to tell the
145: * container about wether it is interested only in already created
146: * resources, or in all resources (even the one that have not yet been
147: * created).
148: * @return An String enumeration, one element per child.
149: */
150:
151: public synchronized Enumeration enumerateResourceIdentifiers(boolean all) {
152: ResourceSpace space = getSpace();
153: acquireChildren();
154: return space.enumerateResourceIdentifiers( getChildrenSpaceEntry() );
155: }
156:
157: /**
158: * Lookup a children in the container.
159: * @param name The name of the children to lookup.
160: */
161:
162: public ResourceReference lookup(String name)
163: {
164: acquireChildren();
165: SpaceEntry sp = getChildrenSpaceEntry();
166: ResourceSpace space = getSpace();
167: ResourceReference rr = space.lookupResource(sp, name);
168: if (rr != null)
169: return rr;
170: Hashtable defs = new Hashtable(5) ;
171: defs.put("identifier", name);
172: ResourceContext context = updateDefaultChildAttributes(defs);
173:
174: rr = space.loadResource(sp, name, defs);
175: if (rr != null) {
176: context.setResourceReference(rr);
177: try {
178: Resource resource = rr.lock();
179: if (resource instanceof FramedResource) {
180: FramedResource fres = (FramedResource) resource;
181: fres.addStructureChangedListener(this);
182: // send event
183: }
184: } catch (InvalidResourceException ex) {
185: // nothing here
186: } finally {
187: rr.unlock();
188: }
189: }
190: return rr;
191: }
192:
193: /**
194: * Lookup the next component of this lookup state in here.
195: * @param ls The current lookup state.
196: * @param lr The lookup result under construction.
197: * @exception HTTPException If an error occurs.
198: * @return A boolean, <strong>true</strong> if lookup has completed,
199: * <strong>false</strong> if it should be continued by the caller.
200: */
201: public boolean lookup(LookupState ls, LookupResult lr)
202: throws ProtocolException
203: {
204: // Give a chance to our super-class to run its own lookup scheme:
205: if ( super.lookup(ls, lr) )
206: return true;
207: // Perform our own lookup on the next component:
208: String name = ls.getNextComponent() ;
209: ResourceReference rr = null;
210: rr = lookup(name);
211: if (rr == null) {
212: lr.setTarget(null);
213: return false;
214: }
215: try {
216: lr.setTarget(rr);
217: FramedResource resource = (FramedResource) rr.lock();
218: return (resource != null ) ? resource.lookup(ls, lr) : false;
219: } catch (InvalidResourceException ex) {
220: return false;
221: } finally {
222: rr.unlock();
223: }
224: }
225:
226:
227: /**
228: * Remove a child resource from that container.
229: * @param name The name of the child to remove.
230: */
231:
232: public void delete(String name)
233: throws MultipleLockException
234: {
235: ResourceReference rr = null;
236: rr = lookup(name);
237:
238: if (rr != null) {
239: try {
240: synchronized (rr) {
241: Resource resource = rr.lock();
242: if (resource instanceof FramedResource)
243: ((FramedResource)resource).removeStructureChangedListener(this);
244: resource.delete();
245: }
246: } catch (InvalidResourceException ex) {
247: // FIXME ??
248: } finally {
249: rr.unlock();
250: }
251: }
252: }
253:
254:
255:
256: /**
257: * Delete that container and its children if children is true
258: */
259: public synchronized void replace(DirectoryResource newdir)
260: throws MultipleLockException
261: {
262: Enumeration e = enumerateResourceIdentifiers();
263: ResourceReference rr = null;
264: Resource resource = null;
265: while (e.hasMoreElements()) {
266: rr = lookup((String) e.nextElement());
267: if (rr != null) {
268: try {
269: resource = rr.lock();
270: ResourceContext ctxt = new ResourceContext(newdir.getContext());
271: resource.setContext(ctxt, true);
272: if (resource instanceof FramedResource) {
273: ((FramedResource)resource).removeStructureChangedListener(this);
274: ((FramedResource)resource).addStructureChangedListener(newdir);
275: }
276: } catch (InvalidResourceException ex) {
277: // do nothing , continue
278: } finally {
279: rr.unlock();
280: }
281: }
282: }
283: super.delete();
284: }
285:
286: /**
287: * Delete that resource container.
288: */
289: public synchronized void delete()
290: throws MultipleLockException
291: {
292: disableEvent();
293: ResourceSpace space = getSpace();
294: //delete our children
295: acquireChildren();
296: // check for lock on children
297: Enumeration e = enumerateResourceIdentifiers();
298: ResourceReference rr = null;
299: Resource resource = null;
300:
301: while (e.hasMoreElements())
302: delete((String)e.nextElement());
303:
304: SpaceEntry sentry = getChildrenSpaceEntry();
305: //delete myself
306: super.delete();
307: space.deleteChildren(sentry);
308:
309: }
310:
311: /**
312: * This resource is being unloaded.
313: * The resource is being unloaded from memory, perform any additional
314: * cleanup required.
315: */
316: public void notifyUnload() {
317: super.notifyUnload();
318: // anything else?
319: }
320:
321: protected boolean acquired = false;
322:
323: /**
324: * Acquire our children. Must be called before all child manipulation.
325: */
326: protected synchronized void acquireChildren() {
327: if (!acquired) {
328: ResourceSpace space = getSpace();
329: space.acquireChildren( getChildrenSpaceEntry() );
330: acquired = true;
331: }
332: }
333:
334: /**
335: * Add an initialized resource into this store container instance.
336: * @param resource The resource to be added to the store.
337: */
338:
339: protected synchronized ResourceReference addResource(Resource resource,
340: Hashtable defs)
341: {
342: acquireChildren();
343: ResourceReference rr = getSpace().addResource(getChildrenSpaceEntry() ,
344: resource,
345: defs);
346: resource.getContext().setResourceReference(rr);
347: if (resource instanceof FramedResource) {
348: FramedResource fres = (FramedResource) resource;
349: fres.addStructureChangedListener(this);
350: }
351: markModified() ;
352: postStructureChangedEvent(rr, Events.RESOURCE_CREATED);
353: return rr;
354: }
355:
356: /**
357: * Initialize and register the given resource within that container.
358: * @param name The identifier for the resource.
359: * @param resource An unitialized resource instance.
360: * @param defs A default set of init attribute values (may be
361: * <strong>null</strong>).
362: */
363:
364: public void registerResource(String name,
365: Resource resource,
366: Hashtable defs)
367: throws InvalidResourceException
368: {
369: acquireChildren();
370: // Create a default set of attributes:
371: if ( defs == null )
372: defs = new Hashtable(11) ;
373: defs.put("identifier", name);
374: ResourceContext context = updateDefaultChildAttributes(defs);
375: if (context != null) {
376: resource.initialize(defs);
377: ResourceReference rr = getSpace().addResource( getChildrenSpaceEntry(),
378: resource,
379: defs);
380: context.setResourceReference(rr);
381: if (resource instanceof FramedResource) {
382: FramedResource fres = (FramedResource) resource;
383: fres.addStructureChangedListener(this);
384: // send event
385: }
386: markModified();
387: postStructureChangedEvent(rr, Events.RESOURCE_CREATED);
388: } else {
389: throw new InvalidResourceException(getIdentifier(),
390: name,
391: "unable to get context");
392: }
393: }
394:
395: /**
396: * Initialize ourself.
397: * As we are a container resource that really contains something, we make
398: * sure our URL ends properly with a slash.
399: * @param values Our default attribute values.
400: */
401: public void initialize(Object values[]) {
402: super.initialize(values);
403: disableEvent();
404: // If my URL doesn't end with a slah, correct it:
405: String url = getURLPath() ;
406: if ((url != null) && ! url.endsWith("/") )
407: setValue(ATTR_URL, url+"/") ;
408: acquired = false;
409: enableEvent();
410: }
411:
412: }
413:
414:
Webmaster