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