001: // ResourceFrame.java
002: // $Id: ResourceFrame.java,v 1.18 2002/06/26 17:27:43 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.tools.resources;
007:
008: import java.util.Hashtable;
009:
010: import org.w3c.tools.resources.event.AttributeChangedEvent;
011: import org.w3c.tools.resources.event.AttributeChangedListener;
012: import org.w3c.tools.resources.event.Events;
013: import org.w3c.tools.resources.event.FrameEvent;
014: import org.w3c.tools.resources.event.FrameEventListener;
015: import org.w3c.tools.resources.event.ResourceEvent;
016: import org.w3c.tools.resources.event.ResourceEventMulticaster;
017:
018: /**
019: * The resource frame class. A ResourceFrame can be attached to a
020: * resource.
021: */
022: public class ResourceFrame extends FramedResource implements
023: AttributeChangedListener {
024: /**
025: * The special class of filter.
026: */
027: protected static Class filterClass = null;
028:
029: /**
030: * Our FrameEventListener.
031: */
032: protected transient FrameEventListener frameListener = null;
033:
034: /**
035: * Our target resource.
036: */
037: protected FramedResource resource = null;
038:
039: static {
040: try {
041: filterClass = Class
042: .forName("org.w3c.tools.resources.ResourceFilter");
043: } catch (Exception ex) {
044: throw new RuntimeException("No ResourceFilter class found.");
045: }
046: }
047:
048: protected boolean eventDisabled() {
049: if (resource != null)
050: return (event_disabled || resource.eventDisabled());
051: return event_disabled;
052: }
053:
054: /**
055: * Get the file part of the URL this resource is attached to.
056: * @return An URL object specifying the location in the information
057: * space of this resource.
058: */
059: public String getURLPath() {
060: return getString(ATTR_URL, getResource().getURLPath());
061: }
062:
063: /**
064: * Get the space entry for that resource. This Object is use to
065: * retrieve the resource in the resource space.
066: * A ResourceFrame has no SpaceEntry.
067: * @return always null.
068: */
069: protected SpaceEntry getSpaceEntry() {
070: return null;
071: }
072:
073: private ResourceReference self = null;
074:
075: /**
076: * Get The FrameReference of this frame, or <strong>null</strong>
077: * if this frame is not registered.
078: * @return A ResourceReference instance.
079: */
080: public ResourceReference getFrameReference() {
081: if ((self == null) && (resource != null)) {
082: self = resource.getFrameReference(this );
083: }
084: return self;
085: }
086:
087: public ResourceReference getResourceReference() {
088: return getFrameReference();
089: }
090:
091: /**
092: * If our target resource has some children, we could have
093: * some attribute to give to them.
094: * @param attrs A Hashtable.
095: */
096: protected void updateDefaultChildAttributes(Hashtable attrs) {
097: //nothing here
098: }
099:
100: /**
101: * Check if this kind of request can be perform by this resource.
102: * @param request A RequestInterface instance
103: * @return a boolean.
104: */
105: public boolean checkRequest(RequestInterface request) {
106: return true;
107: }
108:
109: /**
110: * Perform the request
111: * @param request the incomming request
112: * @exception ProtocolException If an error relative to the protocol occurs
113: * @exception ResourceException If an error not relative to the
114: * protocol occurs
115: */
116: public ReplyInterface perform(RequestInterface request)
117: throws ProtocolException, ResourceException {
118: return super .perform(request);
119: }
120:
121: /**
122: * lookup only filters.
123: * @exception ProtocolException If an error relative to the protocol occurs
124: */
125: protected boolean lookupFilters(LookupState ls, LookupResult lr)
126: throws ProtocolException {
127: ResourceFilter filters[] = getFilters();
128: if (filters != null) {
129: // Mark filters, for them to be called at outgoing time:
130: lr.addFilters(filters);
131: // Some clever filter around ?
132: for (int i = 0; i < filters.length; i++) {
133: if (filters[i] == null)
134: continue;
135: if (filters[i].lookup(ls, lr))
136: return true;
137: }
138: }
139: return false;
140: }
141:
142: /**
143: * lookup frames excluding filters.
144: * @exception ProtocolException If an error relative to the protocol occurs
145: */
146: protected boolean lookupFrames(LookupState ls, LookupResult lr)
147: throws ProtocolException {
148: ResourceFrame frames[] = getFrames();
149: if (frames != null) {
150: for (int i = 0; i < frames.length; i++) {
151: if ((frames[i] == null)
152: || (frames[i] instanceof ResourceFilter))
153: continue;
154: if (frames[i].lookup(ls, lr))
155: return true;
156: }
157: }
158: return false;
159: }
160:
161: /**
162: * Lookup the target resource.
163: * @param ls The current lookup state
164: * @param lr The result
165: * @exception ProtocolException If an error relative to the protocol occurs
166: */
167: public boolean lookup(LookupState ls, LookupResult lr)
168: throws ProtocolException {
169: if (lookupFrames(ls, lr))
170: return true;
171:
172: if (ls.hasMoreComponents()) {
173: // We are not a container resource, and we don't have children:
174: lr.setTarget(null);
175: return false;
176: } else {
177: // We are done !
178: lr.setTarget(resource.getResourceReference());
179: return true;
180: }
181: }
182:
183: public void processEvent(ResourceEvent evt) {
184: if (evt instanceof FrameEvent) {
185: fireFrameEvent((FrameEvent) evt);
186: } else if (evt instanceof AttributeChangedEvent) {
187: fireAttributeChangeEvent((AttributeChangedEvent) evt);
188: }
189: }
190:
191: /**
192: * Add a frame event listener.
193: * @param l The new frame event listener.
194: */
195:
196: public void addFrameEventListener(FrameEventListener l) {
197: frameListener = ResourceEventMulticaster.add(frameListener, l);
198: }
199:
200: /**
201: * Remove a frame event listener.
202: * @param l The listener to remove.
203: */
204:
205: public void removeFrameEventListener(FrameEventListener l) {
206: frameListener = ResourceEventMulticaster.remove(frameListener,
207: l);
208: }
209:
210: /**
211: * Post a frameEvent.
212: * @param the frame event type.
213: */
214: protected void postFrameEvent(int type) {
215: if (frameListener != null) {
216: FrameEvent evt = new FrameEvent(this , type);
217: postEvent(evt);
218: }
219: }
220:
221: /**
222: * Fire a frameEvent.
223: * @param the frame event type.
224: */
225: protected void fireFrameEvent(FrameEvent evt) {
226: if (frameListener != null) {
227: int type = evt.getID();
228: switch (type) {
229: case Events.FRAME_ADDED:
230: frameListener.frameAdded(evt);
231: break;
232: case Events.FRAME_MODIFIED:
233: frameListener.frameModified(evt);
234: break;
235: case Events.FRAME_REMOVED:
236: frameListener.frameRemoved(evt);
237: break;
238: }
239: }
240: }
241:
242: /**
243: * Listen its resource.
244: */
245: public void attributeChanged(AttributeChangedEvent evt) {
246: if (debugEvent)
247: displayEvent(this , evt);
248: if (!isUnloaded())
249: setValue(ATTR_LAST_MODIFIED, new Long(System
250: .currentTimeMillis()));
251: }
252:
253: /**
254: * This handles the <code>FRAME_MODIFIED</code> kind of events.
255: * @param evt The event describing the change.
256: */
257:
258: public void frameModified(FrameEvent evt) {
259: if (debugEvent)
260: displayEvent(this , evt);
261: if (!isUnloaded()) {
262: markModified();
263: postFrameEvent(evt.getID());
264: }
265: }
266:
267: /**
268: * We overide setValue, to fire event.
269: * @param idx The index of the attribute to modify.
270: * @param value The new attribute value.
271: */
272: public synchronized void setValue(int idx, Object value) {
273: super .setValue(idx, value);
274: if (idx != ATTR_LAST_MODIFIED)
275: postFrameEvent(Events.FRAME_MODIFIED);
276: }
277:
278: /**
279: * Get the target resource.
280: * @return a resource instance.
281: */
282: public FramedResource getResource() {
283: return resource;
284: }
285:
286: /**
287: * Register a target resource. Called after initialize,
288: * set the context. getServer() can be call only after
289: * this method call.
290: * @parame resource The resource to register.
291: */
292: public void registerResource(FramedResource resource) {
293: this .resource = resource;
294: postFrameEvent(Events.FRAME_ADDED);
295: setValue(ATTR_CONTEXT, resource.getContext());
296: }
297:
298: /**
299: * Register a target resource.
300: * @parame resource The resource to register.
301: */
302: public void unregisterResource(Resource resource) {
303: //FIXME (can we have more than one resource? )
304: this .resource = null;
305: postFrameEvent(Events.FRAME_REMOVED);
306: }
307:
308: //
309: // Filtered part
310: //
311:
312: /**
313: * Get our whole list of filters.
314: */
315:
316: public synchronized ResourceFilter[] getFilters() {
317: ResourceFrame frames[] = collectFrames(filterClass);
318: if (frames != null) {
319: // FIXME Normally a simple cast should suffice (?)
320: ResourceFilter f[] = new ResourceFilter[frames.length];
321: for (int i = 0; i < frames.length; i++)
322: f[i] = (ResourceFilter) frames[i];
323: return f;
324: }
325: return null;
326: }
327:
328: /**
329: * Get the list of filters of this class.
330: * @param cls The class of filters requested.
331: * @return An array of filters, which are instances of the given class.
332: */
333:
334: public synchronized ResourceFilter[] getFilters(Class cls) {
335: ResourceFrame frames[] = collectFrames(cls);
336: if (frames != null) {
337: // FIXME Normally a simple cast should suffice (?)
338: ResourceFilter f[] = new ResourceFilter[frames.length];
339: for (int i = 0; i < frames.length; i++)
340: f[i] = (ResourceFilter) frames[i];
341: return f;
342: }
343: return null;
344: }
345:
346: }
|