1
2
3
25
26
47
48 import org.omus.util.EventDispatcher;
49 import org.omus.util.iObservable;
50 import org.omus.util._Error;
51 import org.omus.util._Class;
52
53 import org.omus.data.MarshalledProperties;
54 import org.omus.data.TableProperty;
55 import org.omus.data.ObjectProperty;
56 import org.omus.data.Property;
57
58 import org.omus.msg.Message;
59 import org.omus.msg.Envelope;
60 import org.omus.msg.EnvelopeFactory;
61 import org.omus.msg.MessageRouter;
62
63 import org.omus.core.User;
64 import org.omus.core.Group;
65
66
96 class org.omus.data.PropertySet implements iObservable
97 {
98
99
100
101
104 private var props:Object;
105
106
109 private var _size:Number;
110
111
117 private var parent:PropertySet;
118
119
122 public var marsh:MarshalledProperties;
123
124
127 private var type:String;
128
129
132 private var owner:Object;
133
134
137 private var pKey:Number;
138
139
142 private var cache:Object;
143
144
147 private var _eventSource:EventDispatcher;
148
149
150
151
152
153
163 public function PropertySet (type:String, owner:Object, pKey:Number, par:PropertySet)
164 {
165
166 _eventSource = new EventDispatcher();
167
168
169 props = new Object();
170 _size = 0;
171 parent = par;
172 marsh = (par == null) ? new MarshalledProperties() : par.marsh;
173
174 this.type = type;
175 this.owner = owner;
176 this.pKey = pKey;
177 cache = new Object();
178
179
180 }
181
182
183
184
185
189 public function toString ():String
190 {
191 return format(0);
192 }
193
194
201 public function getParent ():PropertySet
202 {
203 return parent;
204 }
205
206
212 public function getOwner ():Object
213 {
214 return owner;
215 }
216
217
222 public function getPrimaryKey ():Number
223 {
224 return pKey;
225 }
226
227
232 public function size ():Number
233 {
234 return _size;
235 }
236
237
242 public function getMarshalledProperties():MarshalledProperties
243 {
244 return marsh;
245 }
246
247
252 public function isSynchronized ():Boolean
253 {
254 var ps = props;
255 for (var each:String in ps)
256 {
257 if (ps[each].isModified()) return false;
258 }
259 return true;
260 }
261
262
268 public function isValid ():Boolean
269 {
270
271 var group = Group.getInstance();
272 if (type == "user")
273 {
274
275
276 return group.containsUser (String (owner));
277 } else
278 {
279 return (group == owner);
280 }
281 }
282
283
289 public function getValue (propName:String):Object
290 {
291
292 var p = this.getPropertyByName (propName);
293 return (typeof(p) == "object") ? p.value : null ;
294 }
295
296
302 public function getType (propName:String):String
303 {
304
305 var p = this.getPropertyByName (propName);
306 return (typeof(p) == "object") ? p.type : null ;
307 }
308
309
315 public function contains (propName:String):Boolean
316 {
317 return (props[propName] != undefined);
318 }
319
320
326 public function isModified (propName:String):Boolean
327 {
328
329 var p = this.getPropertyByName (propName);
330 return (typeof(p) == "object") ? p.modified : false ;
331 }
332
333
339 public function isLoaded (propName:String):Boolean
340 {
341
342 var p = this.getPropertyByName (propName);
343 return (typeof(p) == "object") ? (p.value != null) : false ;
344 }
345
346
355 public function setValue (propName:String, newVal:Object):Void
356 {
357
358 var p = this.getPropertyByName (propName);
359 if (typeof(p) == "object") p.setValue(newVal);
360 }
361
362
368 public function synchronize ():Void
369 {
370 if (! isValid())
371 {
372
373 _global.oregano.iLog.error("clj-020","owner = " + owner);
374 return;
375 }
376
377 var msg = new Message(type);
378 var attach = msg.getAttachment();
379 var extr = marsh.extract(this.props);
380 if (extr.size() == 0)
381 {
382
383 _global.oregano.iLog.warn("clj-021","owner = " + owner);
384 return;
385 }
386 attach.props = extr;
387 if (type == "user") attach.username = owner;
388
389 var envFactory = EnvelopeFactory.getInstance();
390 var env = envFactory.getOutgoing(msg, "syncProps");
391
392 var msgRouter = MessageRouter.getInstance();
393 msgRouter.handleOutgoing(env, this, "synchronize", arguments, {props:extr});
394 }
395
396
401 public function load (propNames:Array):Void
402 {
403
404 var clazz = _Class.getInstance();
405 if (! clazz.checkArguments("org.omus.data.PropertySet.load", [[propNames, Array, true]])) return;
406 if (! isValid())
407 {
408
409 _global.oregano.iLog.error("clj-022","owner = " + this.owner);
410 return;
411 }
412
413 var pa = new Array();
414 var ps:Object = this.props;
415 var long = propNames.length;
416 for (var i = 0; i < long ; i++)
417 {
418 var p = ps[propNames[i]];
419 if (p == undefined)
420 {
421
422 _global.oregano.iLog.error("clj-023", "property name = " + propNames[i] + " - owner = " + owner);
423 return;
424 }
425 if (p.isLoaded())
426 {
427
428 _global.oregano.iLog.warn("clj-024", "property name = " + propNames[i] + " - owner = " + this.owner);
429 } else
430 {
431 pa.push(p.name);
432 }
433 }
434 loadInternal(pa, "load");
435 }
436
437
441 public function loadAll ():Void
442 {
443 if (! isValid())
444 {
445
446 _global.oregano.iLog.error("clj-025", "owner = " + owner);
447 return;
448 }
449 var pa = new Array();
450 var ps:Object = this.props;
451 for (var each:String in ps)
452 {
453
454
455 var p = ps[each];
456 if (! p.isLoaded()) pa.push(p.name);
457 }
458 loadInternal(pa, "loadAll");
459 }
460
461
466 public function getChanged ():MarshalledProperties
467 {
468 return marsh.extract(props);
469 }
470
471
477 public function valueChanged (propName:String, marshVal:Object):Void
478 {
479 marsh.addProp(propName, marshVal);
480 }
481
482
491 public function fill (propConfig:Object, props:Object):Void
492 {
493 for (var each:String in propConfig)
494 {
495 var typ = propConfig[each].type;
496 var cach = propConfig[each].cache;
497 var value = props[each];
498
499 var clazzInstance = _Class.getInstance();
500 var clazz = clazzInstance.propTypeToClass(typ);
501 var p:Property;
502
503 if (value != undefined)
504 {
505 if (clazz.toString() == "[Object Table]")
506 {
507 p = new TableProperty(each, typ, clazz, cach, value);
508 } else if (typeof(clazz) != "string")
509 {
510 p = new ObjectProperty(each, typ, clazz, cach, value);
511 }else
512 {
513 p = new Property(each, typ, clazz, cach, value);
514 }
515 } else
516 {
517 p = new Property(each, typ, clazz, cach, null);
518 }
519 addProperty(p);
520 }
521 }
522
523
524
531 private function fireEvent (logLevel:String, eventName:String):Void
532 {
533 _eventSource.fireEvent.apply (_eventSource, arguments);
534 }
535
536
542 public function addListener (listener:Object):Boolean
543 {
544 return _eventSource.addListener(listener);
545 }
546
547
553 public function removeListener (listener:Object):Boolean
554 {
555 return _eventSource.removeListener(listener);
556 }
557
558
561 public function removeAllListeners ():Void
562 {
563 _eventSource.removeAllListeners();
564 }
565
566
571 public function countListeners ():Number
572 {
573 return _eventSource.countListeners();
574 }
575
576
577
578
583 public function handleMessage (env:Envelope):Void
584 {
585 var type = env.getType();
586 if (type == "syncProps")
587 {
588 handleSynchronize(env);
589 }else
590 {
591 handleLoad(env);
592 }
593 }
594
595
600 private function handleSynchronize (env:Envelope):Void
601 {
602 var attach = env.getMessage().getAttachment();
603 var errCode = attach.error;
604 var clientRequest = attach.clientRequest;
605
606 var msgRouter = MessageRouter.getInstance();
607
608 var extr = (errCode != "ok" || clientRequest) ? msgRouter.getCache(env.getID(), "info") ["props"].props : null;
609 if (errCode == "ok") {
610 synchronizeOK(attach.props, clientRequest, extr);
611 } else {
612 synchronizeFailed(extr, errCode, "synchronize", new Array());
613 }
614 }
615
616
624 public function synchronizeOK (props:Object, cr:Boolean, cache:Object):Void
625 {
626 var par = (this.parent == null) ? this : this.parent;
627
628 var ps = new PropertySet(type, owner, pKey, par);
629 for (var each:String in props)
630 {
631
632
633 var p = this.props[each];
634 if (p == undefined)
635 {
636
637 _global.oregano.iLog.error("clj-026", "property name = " + each + " - owner = " + owner);
638 continue;
639 }
640
641 p.update(props[each], cr);
642 ps.addProperty(p);
643 }
644
645 if (cache != null)
646 {
647
648 var user = User.getInstance();
649 var group = Group.getInstance();
650 for (var each:String in cache)
651 {
652 var p = this.props[each];
653 var minCache:Number;
654 if (owner == group || owner != user.getName())
655 {
656 minCache = org.omus.data.Property.SYNCHRONIZE_GROUP;
657 } else
658 {
659 minCache = org.omus.data.Property.SYNCHRONIZE_CLIENT;
660 }
661 if (p.cache < minCache)
662 {
663 p.update(null, cr);
664 ps.addProperty(p);
665 }
666 }
667 }
668
669 fireEvent("info", "onSynchronize", ps, cr);
670 }
671
672
681 public function synchronizeFailed (cache:Object, errCode:String, method:String, args:Array) {
682 var par = (parent == null) ? this : parent;
683
684 var ps = new PropertySet(type, owner, pKey, par);
685 for (var each:String in cache)
686 {
687 var p:Property = props[each];
688 p.reset();
689 ps.addProperty(p);
690 }
691 fireEvent("error", "onError", ps, new _Error(errCode, method, args));
692 }
693
694
700 private function handleLoad (env:Envelope)
701 {
702 var attach = env.getMessage().getAttachment();
703 var errCode = attach.error;
704 if (errCode == "ok")
705 {
706 var par = (parent == null) ? this : parent;
707 var ps = new PropertySet(type, owner, pKey, par);
708
709 var props:Property = attach.props;
710 for (var each:String in props)
711 {
712
713 var p = this.props[each];
714 if (p == undefined)
715 {
716
717 _global.oregano.iLog.error("clj-027", "property name = " + each + " - owner = " + owner);
718 continue;
719 }
720 p.loadTemp(props[each]);
721 ps.addProperty(p);
722 }
723
724 fireEvent("info", "onLoad", ps);
725
726
727 for (var each:String in props)
728 {
729 var p:Property = this.props[each];
730 if (p == undefined) continue;
731
732 p.unload();
733 }
734 } else
735 {
736
737 var msgRouter = MessageRouter.getInstance();
738 var cache = msgRouter.getCacheObject(env.getID());
739 var method = cache.method;
740 var ps:PropertySet;
741 if (method == "load")
742 {
743
744
745
746 var propNames = cache.args[0];
747 ps = filterByName(propNames);
748 } else
749 {
750
751 var par = (parent == null) ? this : parent;
752 ps = new PropertySet(type, owner, pKey, par);
753 var all = this.props;
754 for (var each:String in all)
755 {
756
757
758
759 var p = all[each];
760 if (! p.isLoaded()) ps.addProperty(p);
761 }
762 }
763
764 fireEvent("error", "onError", ps, new _Error(errCode, method, cache.args));
765 }
766 }
767
768
769
770
771
777 private function loadInternal (propNames:Array, methodName:String):Void
778 {
779 if (propNames.length == 0)
780 {
781
782 _global.oregano.iLog.warn("clj-064", "owner = " + owner);
783 return;
784 }
785
786 var msg = new Message(type);
787 var attach = msg.getAttachment();
788 attach.propNames = propNames;
789 if (type == "user") attach.username = owner;
790
791 var envFactory = EnvelopeFactory.getInstance();
792 var env = envFactory.getOutgoing(msg, "loadProps");
793
794 var args = (methodName == "loadAll") ? [] : [propNames] ;
795
796 var msgRouter = MessageRouter.getInstance();
797 msgRouter.handleOutgoing(env, this, methodName, args, null);
798 }
799
800
806 private function getPropertyByName (propName:String):Object
807 {
808 var p:Property = props[propName];
809
810 if (typeof(p) != "object") _global.oregano.iLog.warn("clj-067", "property name = " + propName + " - owner = " + owner);
811 return p;
812 }
813
814
821 private function filter (filterFunc:Function):PropertySet
822 {
823
824 var clazz = _Class.getInstance();
825
826 if (clazz.checkArguments("org.omus.data.PropertySet.filter", [[filterFunc, "function", true]]))
827 {
828 var par = (parent == null) ? this : parent;
829
830 var ps = new PropertySet(type, owner, pKey, par);
831 var p = props;
832 var long = p.length;
833 for (var i = 0; i < long ; i++)
834 {
835 if (filterFunc(p[i])) ps.addProperty(p[i]);
836 }
837 return ps;
838 }
839 }
840
841
847 private function filterByName (propNames:Array):PropertySet
848 {
849
850 var clazz = _Class.getInstance();
851
852 if (clazz.checkArguments("org.omus.data.PropertySet.filterByName", [[propNames, Array, true]]))
853 {
854 var par = (parent == null) ? this : parent;
855
856 var ps = new PropertySet(type, owner, pKey, par);
857 var long = propNames.length;
858 for (var i = 0; i < long ; i++)
859 {
860 var p:Property = this.props[propNames[i]];
861 if (p == undefined)
862 {
863 _global.oregano.iLog.error("clj-019", "property name = " + propNames[i] + " - owner = " + owner);
864 } else {
865 ps.addProperty(p[i]);
866 }
867 }
868 return ps;
869 }
870 }
871
872
878 private function filterInternal (filterFunc:Function):Object
879 {
880 var props = new Object();
881 var p = this.props;
882 var long = p.length;
883 for (var i = 0; i < long ; i++)
884 {
885 if (filterFunc(p[i])) props[p[i].name] = p[i].value;
886 }
887 return props;
888 }
889
890
895 private function addProperty (p:Property):Void
896 {
897
898 if (parent == null) p.setPropertySet(this);
899 _size++;
900
901 props[p.getName()] = p;
902 }
903
904
909 private function format (indent:Number):String
910 {
911 var s= "org.omus.data.PropertySet:";
912 s += "\n";
913 for (var idx = 0; idx < indent; idx++) s += " ";
914 s += "type = " + type;
915 if (type == "user")
916 {
917 s += "\n";
918 for (var idx = 0; idx < indent; idx++) s += " ";
919 s += "owner = " + owner;
920 }
921 s += "\n";
922 for (var idx = 0; idx < indent; idx++) s += " ";
923 s += "primary key = " + pKey;
924 s += "\n";
925 for (var idx = 0; idx < indent; idx++) s += " ";
926 s += "number of properties = " + _size;
927
928 var pr = props;
929 for (var each:String in pr)
930 {
931 s += "\n";
932 for (var idx = 0; idx < indent; idx++) s += " ";
933 s += "===========================";
934 s += "\n";
935 for (var idx = 0; idx < indent; idx++) s += " ";
936 s += pr[each].format(indent + 1);
937 }
938 return s;
939 }
940
941
942
943
944
948 public static function toLog():String
949 {
950 return "[Object PropertySet]";
951 }
952
953
961 public static function handleIncomingMessage (env:Envelope):Void
962 {
963 var type = env.getType();
964 if (type == "syncProps")
965 {
966 var username = env.getMessage().getAttachment().username;
967 var target:PropertySet;
968
969 var group = Group.getInstance();
970 if (username == undefined){
971 target = group.getProperties();
972 } else {
973 target = group.getUserProperties(username);
974 }
975 target.handleMessage(env);
976 return;
977 }
978
979 var msgRouter = MessageRouter.getInstance();
980 msgRouter.unknownMsgType(env);
981 }
982 }
983