📄 abstractcomponent.java
字号:
public int previousIndex() { return _j - 1; } public void add(Object o) { final Component newChild = (Component)o; if (newChild.getParent() == AbstractComponent.this) throw new UnsupportedOperationException("Unable to add component with the same parent: "+o); //1. it is confusing to allow adding (with replace) //2. the code is sophisticated checkComodification(); insertBefore(newChild, _p); ++_j; _lastRet = null; //spec: cause remove to throw ex if no next/previous ++_modCntSnap; //don't assign _modCntChd directly since deriving class //might manipulate others in insertBefore } public void remove() { if (_lastRet == null) throw new IllegalStateException(); checkComodification(); removeChild(_lastRet); if (_p == _lastRet) _p = _lastRet._next; //previous was called else --_j; //next was called _lastRet = null; ++_modCntSnap; } public void set(Object o) { throw new UnsupportedOperationException(); //Possible to implement this but confusing to developers //if o has the same parent (since we have to move) } } //Cloneable// public Object clone() { final AbstractComponent clone; try { clone = (AbstractComponent)super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } //1. make it not belonging to any page clone._page = null; clone._parent = null; //1a. clone attributes clone._attrs = new HashMap(4); for (Iterator it = _attrs.entrySet().iterator(); it.hasNext();) { final Map.Entry me = (Map.Entry)it.next(); Object val = me.getValue(); if (val instanceof ComponentCloneListener) { val = ((ComponentCloneListener)val).clone(clone); if (val == null) continue; //don't use it in clone } clone._attrs.put(me.getKey(), val); } //1b. clone listeners if (_listeners != null) { clone._listeners = new HashMap(4); for (Iterator it = _listeners.entrySet().iterator(); it.hasNext();) { final Map.Entry me = (Map.Entry)it.next(); final List list = new LinkedList(); for (Iterator it2 = ((List)me.getValue()).iterator(); it2.hasNext();) { Object val = it2.next(); if (val instanceof ComponentCloneListener) { val = ((ComponentCloneListener)val).clone(clone); if (val == null) continue; //don't use it in clone } list.add(val); } if (!list.isEmpty()) clone._listeners.put(me.getKey(), list); } } if (!_annotsShared && _annots != null) clone._annots = (AnnotationMap)_annots.clone(); if (!_evthdsShared && _evthds != null) clone._evthds = (EventHandlerMap)_evthds.clone(); //2. clone children (deep cloning) cloneChildren(clone); clone.init(true); //3. spaceinfo if (clone._spaceInfo != null) { clone._spaceInfo = new SpaceInfo(clone, _spaceInfo.ns); cloneSpaceInfo(clone, this._spaceInfo); } //4. clone _forwards if (clone._forwards != null) { clone._forwards = null; for (Iterator it = _forwards.entrySet().iterator(); it.hasNext();) { final Map.Entry me = (Map.Entry)it.next(); final String orgEvent = (String)me.getKey(); final Object[] info = (Object[])me.getValue(); final List fwds = (List)info[1]; for (Iterator e = fwds.iterator(); e.hasNext();) { final Object[] fwd = (Object[])e.next(); clone.addForward0(orgEvent, fwd[0], (String)fwd[1]); } } } return clone; } private static final void cloneSpaceInfo(AbstractComponent clone, SpaceInfo from) { final SpaceInfo to = clone._spaceInfo; to.attrs = new HashMap(8); for (Iterator it = from.attrs.entrySet().iterator(); it.hasNext();) { final Map.Entry me = (Map.Entry)it.next(); Object val = me.getValue(); if (val instanceof ComponentCloneListener) { val = ((ComponentCloneListener)val).clone(clone); if (val == null) continue; //don't use it in clone } to.attrs.put(me.getKey(), val); } //rebuild ID space by binding itself and all children clone.bindToIdSpace(clone); for (AbstractComponent p = clone._first; p != null; p = p._next) addToIdSpacesDown(p, clone); } private static final void cloneChildren(final AbstractComponent comp) { AbstractComponent q = null; for (AbstractComponent p = comp._first; p != null; p = p._next) { AbstractComponent child = (AbstractComponent)p.clone(); if (q != null) q._next = child; else comp._first = child; child._prev = q; q = child; child._parent = comp; //correct it if (child._spaceInfo != null) child._spaceInfo.ns.setParent(comp.getNamespace()); } comp._last = q; } //Serializable// //NOTE: they must be declared as private private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { //No need to unshare since they are stored as an independent copy //unshareAnnotationMap(false); //unshareEventHandlerMap(false); s.defaultWriteObject(); //write definition if (_def == ComponentsCtrl.DUMMY) { s.writeObject(null); } else { LanguageDefinition langdef = _def.getLanguageDefinition(); if (langdef != null) { s.writeObject(langdef.getName()); s.writeObject(_def.getName()); } else { s.writeObject(_def); } } //write children for (AbstractComponent p = _first; p != null; p = p._next) s.writeObject(p); s.writeObject(null); //write attrs willSerialize(_attrs.values()); Serializables.smartWrite(s, _attrs); if (_listeners != null) for (Iterator it = _listeners.entrySet().iterator(); it.hasNext();) { final Map.Entry me = (Map.Entry)it.next(); s.writeObject(me.getKey()); final Collection ls = (Collection)me.getValue(); willSerialize(ls); Serializables.smartWrite(s, ls); } s.writeObject(null); //store _spaceInfo if (this instanceof IdSpace) { //write _spaceInfo.attrs willSerialize(_spaceInfo.attrs.values()); Serializables.smartWrite(s, _spaceInfo.attrs); //write _spaceInfo.ns (only variables that are not fellows) for (Iterator it = _spaceInfo.ns.getVariableNames().iterator(); it.hasNext();) { final String nm = (String)it.next(); final Object val = _spaceInfo.ns.getVariable(nm, true); willSerialize(val); //always called even if not serializable if (isVariableSerializable(nm, val) && (val instanceof java.io.Serializable || val instanceof java.io.Externalizable)) { s.writeObject(nm); s.writeObject(val); } } s.writeObject(null); //denote end-of-namespace } //write _forwards if (_forwards != null) { for (Iterator it = _forwards.entrySet().iterator(); it.hasNext();) { final Map.Entry me = (Map.Entry)it.next(); s.writeObject(me.getKey()); //original event final Object[] info = (Object[])me.getValue(); final List fwds = (List)info[1]; s.writeInt(fwds.size()); for (Iterator e = fwds.iterator(); e.hasNext();) { final Object[] fwd = (Object[])e.next(); s.writeObject( //store target as string fwd[0] instanceof Component ? Components.componentToPath((Component)fwd[0], this): fwd[0]); s.writeObject(fwd[1]); //target event } } } s.writeObject(null); } private void willSerialize(Collection c) { if (c != null) for (Iterator it = c.iterator(); it.hasNext();) willSerialize(it.next()); } private void willSerialize(Object o) { if (o instanceof ComponentSerializationListener) ((ComponentSerializationListener)o).willSerialize(this); } private synchronized void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); init(false); //read definition Object def = s.readObject(); if (def == null) { _def = ComponentsCtrl.DUMMY; } else if (def instanceof String) { LanguageDefinition langdef = LanguageDefinition.lookup((String)def); _def = langdef.getComponentDefinition((String)s.readObject()); } else { _def = (ComponentDefinition)def; } //read children for (AbstractComponent q = null;;) { final AbstractComponent child = (AbstractComponent)s.readObject(); if (child == null) { _last = q; break; //no more } if (q != null) q._next = child; else _first = child; child._prev = q; child._parent = this; q = child; } //read attrs Serializables.smartRead(s, _attrs); didDeserialize(_attrs.values()); for (;;) { final String evtnm = (String)s.readObject(); if (evtnm == null) break; //no more if (_listeners == null) _listeners = new HashMap(4); final Collection ls = Serializables.smartRead(s, (Collection)null); _listeners.put(evtnm, ls); didDeserialize(ls); } //restore _spaceInfo if (this instanceof IdSpace) { _spaceInfo = new SpaceInfo(this); //fix child's _spaceInfo's parent fixSpaceParentOneLevelDown(this, _spaceInfo.ns); //read _spaceInfo.attrs Serializables.smartRead(s, _spaceInfo.attrs); didDeserialize(_spaceInfo.attrs.values()); //_spaceInfo.ns for (;;) { final String nm = (String)s.readObject(); if (nm == null) break; //no more Object val = s.readObject(); _spaceInfo.ns.setVariable(nm, val, true); didDeserialize(val); } //restore ID space by binding itself and all children bindToIdSpace(this); for (Iterator it = getChildren().iterator(); it.hasNext();) addToIdSpacesDown((Component)it.next(), this); } //restore _forwards for (;;) { final String orgEvent = (String)s.readObject(); if (orgEvent == null) break; int sz = s.readInt(); while (--sz >= 0) addForward0(orgEvent, s.readObject(), (String)s.readObject()); //Note: we don't call Components.pathToComponent here //since the parent doesn't deserialized completely //Rather, we handle it until the event is received } } private void didDeserialize(Collection c) { if (c != null) for (Iterator it = c.iterator(); it.hasNext();) didDeserialize(it.next()); } private void didDeserialize(Object o) { if (o instanceof ComponentSerializationListener) ((ComponentSerializationListener)o).didDeserialize(this); } private static boolean isVariableSerializable(String name, Object value) { return !"spaceScope".equals(name) && !"spaceOwner".equals(name) && !(value instanceof Component); } /** Fixed Namespace's parent of children only one level. */ private static final void fixSpaceParentOneLevelDown(Component comp, Namespace nsparent) { for (Iterator it = comp.getChildren().iterator(); it.hasNext();) { final AbstractComponent child = (AbstractComponent)it.next(); //Others are handled by readObject if (child._spaceInfo != null) child._spaceInfo.ns.setParent(nsparent); else fixSpaceParentOneLevelDown(child, nsparent); //recursive } } /** Used to forward events (for the forward conditions). */ private class ForwardListener implements EventListener, ComponentCloneListener { //Note: it is not serializable since it is handled by //AbstractComponent.writeObject private final String _orgEvent; private ForwardListener(String orgEvent) { _orgEvent = orgEvent; } public void onEvent(Event event) { final Object[] info = (Object[])_forwards.get(_orgEvent); if (info != null) for (Iterator it = ((List)info[1]).iterator(); it.hasNext();) { final Object[] fwd = (Object[])it.next(); Component target = fwd[0] instanceof String ? Components.pathToComponent( (String)fwd[0], AbstractComponent.this): (Component)fwd[0]; if (target == null) { final IdSpace owner = getSpaceOwner(); if (owner instanceof Component) { target = (Component)owner; } else { //Use the root component instead for (target = AbstractComponent.this;;) { final Component p = target.getParent(); if (p == null) break; target = p; } } } Events.postEvent( new ForwardEvent((String)fwd[1], target, event)); } } //ComponentCloneListener// public Object clone(Component comp) { return null; //handle by AbstractComponent.clone } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -