1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.utgenome.gwt.utgb.client.track;
26
27 import java.util.ArrayList;
28 import java.util.Iterator;
29 import java.util.List;
30
31 import org.utgenome.gwt.utgb.client.BrowserServiceAsync;
32 import org.utgenome.gwt.utgb.client.RPCServiceManager;
33 import org.utgenome.gwt.utgb.client.UTGBClientErrorCode;
34 import org.utgenome.gwt.utgb.client.UTGBClientException;
35 import org.utgenome.gwt.utgb.client.UTGBEntryPointBase;
36 import org.utgenome.gwt.utgb.client.track.Track.TrackFactory;
37 import org.utgenome.gwt.utgb.client.track.impl.TrackGroupPropertyImpl;
38 import org.utgenome.gwt.utgb.client.track.lib.NavigatorTrack;
39 import org.utgenome.gwt.utgb.client.util.Properties;
40 import org.utgenome.gwt.utgb.client.util.xml.XMLAttribute;
41 import org.utgenome.gwt.utgb.client.util.xml.XMLUtil;
42 import org.utgenome.gwt.utgb.client.util.xml.XMLWriter;
43 import org.utgenome.gwt.utgb.client.view.TrackView;
44 import org.utgenome.gwt.utgb.client.view.TrackView.Coordinate;
45
46
47
48
49
50
51
52 interface HasFactory {
53 public static abstract class TrackGroupFactory {
54
55
56
57
58
59 public abstract TrackGroup newInstance();
60
61
62
63
64
65
66
67
68
69 public void setProperty(final String key, final String value) {
70 }
71
72
73
74
75
76
77
78
79 public String getProperty(final String key) {
80 return null;
81 }
82
83 public void clear() {
84 }
85 }
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 public class TrackGroup implements TrackEntry, Comparable<TrackGroup>, HasFactory {
141 public static TrackGroupFactory factory() {
142 return new TrackGroupFactory() {
143 String name = "";
144
145 @Override
146 public TrackGroup newInstance() {
147 return new TrackGroup(name);
148 }
149
150 @Override
151 public void setProperty(String key, String value) {
152 if (key.equals("name"))
153 name = value;
154 }
155 };
156 }
157
158 protected ArrayList<Track> _trackList = new ArrayList<Track>();
159 protected ArrayList<TrackGroup> _trackGroupList = new ArrayList<TrackGroup>();
160 protected TrackGroupPropertyImpl _trackGroupProperty = new TrackGroupPropertyImpl(this);
161 protected ArrayList<TrackUpdateListener> _trackEventListenerList = new ArrayList<TrackUpdateListener>();
162 protected TrackLayoutManager _layoutManager;
163 protected TrackGroup _parentTrackGroup = null;
164 protected String _trackGroupName = "";
165 protected boolean _notifyResize = true;
166
167 public void clear() {
168
169 ArrayList<Track> trackList = new ArrayList<Track>();
170 trackList.addAll(_trackList);
171 for (Iterator<Track> it = trackList.iterator(); it.hasNext();)
172 removeTrack(it.next());
173
174 ArrayList<TrackGroup> trackGroupList = new ArrayList<TrackGroup>();
175 trackGroupList.addAll(_trackGroupList);
176 for (Iterator<TrackGroup> it = trackGroupList.iterator(); it.hasNext();)
177 removeTrackGroup(it.next());
178 }
179
180 public TrackGroup(String trackGroupName) {
181 _trackGroupName = trackGroupName;
182 }
183
184
185
186
187
188
189
190 public void addTrack(Track track) {
191 addTrackInternal(track);
192 for (Iterator<TrackUpdateListener> it = _trackEventListenerList.iterator(); it.hasNext();) {
193 TrackUpdateListener listener = it.next();
194 listener.onInsertTrack(track);
195 }
196
197 }
198
199 private void addTrackInternal(Track track) {
200 _trackList.add(track);
201 track.setTrackGroup(this);
202 }
203
204
205
206
207
208
209
210 public void insertTrack(Track track, int beforeIndex) {
211 addTrackInternal(track);
212 for (Iterator<TrackUpdateListener> it = _trackEventListenerList.iterator(); it.hasNext();) {
213 TrackUpdateListener listener = it.next();
214 listener.onInsertTrack(track, beforeIndex);
215 }
216
217 }
218
219
220
221
222
223
224
225
226
227 public void addTrackGroup(TrackGroup trackGroup) {
228 _trackGroupList.add(trackGroup);
229 trackGroup.setParentTrackGroup(this);
230 this.setResizeNotification(false);
231
232 for (Iterator<TrackUpdateListener> it = _trackEventListenerList.iterator(); it.hasNext();) {
233 TrackUpdateListener listener = it.next();
234 listener.onAddTrackGroup(trackGroup);
235
236
237 }
238 this.setResizeNotification(true);
239 notifyResize();
240 }
241
242
243
244
245
246
247
248 public void broadcastChange(TrackGroupPropertyChange change, TrackWindow newWindow) {
249
250
251 for (Iterator<Track> it = _trackList.iterator(); it.hasNext();) {
252 Track track = it.next();
253 if (track.isInitialized()) {
254 track.beforeChangeTrackWindow(newWindow);
255 }
256 }
257
258
259 for (Iterator<Track> it = _trackList.iterator(); it.hasNext();) {
260 Track track = it.next();
261 if (track.isInitialized()) {
262 track.onChange(change, newWindow);
263 }
264 }
265
266 for (Iterator<TrackGroup> it = _trackGroupList.iterator(); it.hasNext();) {
267 TrackGroup group = it.next();
268 group.onParentChange(change, newWindow);
269 }
270
271 }
272
273 public void broadCastScrollTrackWindow(double scrollPercentage) {
274
275 for (Iterator<TrackGroup> it = _trackGroupList.iterator(); it.hasNext();) {
276 TrackGroup group = it.next();
277 NavigatorTrack.scroll(group, scrollPercentage);
278 }
279 }
280
281 public void broadCastWindowSizeChange(int scaleDiff) {
282
283 for (Iterator<TrackGroup> it = _trackGroupList.iterator(); it.hasNext();) {
284 TrackGroup group = it.next();
285 NavigatorTrack.zoom(group, scaleDiff);
286 }
287 }
288
289
290
291
292
293
294 public TrackGroupProperty getPropertyReader() {
295 return _trackGroupProperty;
296 }
297
298 public String getProperty(String key, String defaultValue) {
299 return getPropertyReader().getProperty(key, defaultValue);
300 }
301
302 public String getProperty(String key) {
303 return getPropertyReader().getProperty(key);
304 }
305
306
307
308
309
310
311
312
313 public TrackGroupPropertyWriter getPropertyWriter() {
314 return _trackGroupProperty;
315 }
316
317
318
319
320
321
322
323 public List<TrackGroup> getTrackGroupList() {
324 return _trackGroupList;
325 }
326
327
328
329
330
331
332 public List<Track> getTrackList() {
333 return _trackList;
334 }
335
336
337
338
339
340
341 public List<Track> getAllTrackList() {
342 ArrayList<Track> trackList = new ArrayList<Track>();
343 trackList.addAll(_trackList);
344 for (Iterator<TrackGroup> it = _trackGroupList.iterator(); it.hasNext();) {
345 TrackGroup group = it.next();
346 trackList.addAll(group.getTrackList());
347 }
348 return trackList;
349 }
350
351
352
353
354
355
356 public TrackWindow getTrackWindow() {
357 return _trackGroupProperty.getTrackWindow();
358 }
359
360 public void onParentChange(TrackGroupPropertyChange change, TrackWindow newWindow) {
361
362 }
363
364
365
366
367
368
369
370 public void onParentTrackWindowChange(TrackWindow newWindow) {
371
372 }
373
374
375
376
377
378
379
380 public void onParentTrackGroupPropertyChange(TrackGroupPropertyChange change) {
381
382 }
383
384
385
386
387 public void redrawAll() {
388
389 for (Iterator<Track> it = _trackList.iterator(); it.hasNext();) {
390 Track track = it.next();
391 track.refresh();
392 }
393
394 for (Iterator<TrackGroup> it = _trackGroupList.iterator(); it.hasNext();) {
395 TrackGroup group = it.next();
396 group.redrawAll();
397 }
398 }
399
400
401
402
403
404
405 public void removeTrack(Track track) {
406 _trackList.remove(track);
407 for (Iterator<TrackUpdateListener> it = _trackEventListenerList.iterator(); it.hasNext();) {
408 TrackUpdateListener listener = it.next();
409 listener.onRemoveTrack(track);
410 }
411
412 }
413
414
415
416
417
418
419
420
421 public void removeTrackGroup(TrackGroup trackGroup) {
422 _trackGroupList.remove(trackGroup);
423 trackGroup.removeParentTrackGroup();
424 this.setResizeNotification(false);
425 for (Iterator<TrackUpdateListener> it = _trackEventListenerList.iterator(); it.hasNext();) {
426 TrackUpdateListener listener = it.next();
427 listener.onRemoveTrackGroup(trackGroup);
428
429
430 }
431 this.setResizeNotification(true);
432 notifyResize();
433 }
434
435
436
437
438
439
440
441
442 public void setTrackWindowLocation(int startOnGenome, int endOnGenome) {
443 _trackGroupProperty.setTrackWindow(startOnGenome, endOnGenome);
444 }
445
446
447
448
449
450
451
452 public void setTrackWindowWidth(int windowWidth) {
453 _trackGroupProperty.setTrackWindowSize(windowWidth);
454 }
455
456
457
458
459
460
461 public void addTrackUpdateListener(TrackUpdateListener listener) {
462 _trackEventListenerList.add(listener);
463 for (Iterator<TrackGroup> it = _trackGroupList.iterator(); it.hasNext();) {
464 TrackGroup group = it.next();
465 group.addTrackUpdateListener(listener);
466 }
467 }
468
469
470
471
472
473
474 public void removeTrackUpdateListener(TrackUpdateListener listener) {
475 _trackEventListenerList.remove(listener);
476 for (Iterator<TrackGroup> it = _trackGroupList.iterator(); it.hasNext();) {
477 TrackGroup group = it.next();
478 group.removeTrackUpdateListener(listener);
479 }
480 }
481
482
483
484
485
486
487
488 public int getTrackIndex(Track track) {
489 return _layoutManager.getTrackIndex(track);
490 }
491
492
493
494
495
496
497 public void setTrackWindow(TrackWindow newWindow) {
498 _trackGroupProperty.setTrackWindow(newWindow);
499 }
500
501
502
503
504
505
506 public TrackGroup getParentTrackGroup() {
507 return _parentTrackGroup;
508 }
509
510 protected void setParentTrackGroup(TrackGroup parentTrackGroup) {
511 this._parentTrackGroup = parentTrackGroup;
512 }
513
514
515
516
517 public void notifyResize() {
518 if (!_notifyResize)
519 return;
520 for (Iterator<TrackUpdateListener> it = _trackEventListenerList.iterator(); it.hasNext();) {
521 TrackUpdateListener listener = it.next();
522 listener.onResizeTrack();
523 listener.onResizeTrackWindow(_trackGroupProperty.getTrackWindow().getPixelWidth());
524 }
525 }
526
527
528
529
530
531
532
533 public void setResizeNotification(boolean enable) {
534 _notifyResize = enable;
535
536 for (Iterator<TrackGroup> it = _trackGroupList.iterator(); it.hasNext();) {
537 TrackGroup g = it.next();
538 g.setResizeNotification(enable);
539 }
540 }
541
542
543
544
545 public int getHeight() {
546 int height = 0;
547 for (Iterator<Track> it = _trackList.iterator(); it.hasNext();) {
548 Track track = it.next();
549 if (track.isInitialized()) {
550 TrackFrame frame = track.getFrame();
551 int frameHeight = frame.getOffsetHeight();
552 if (frameHeight < TrackFrameState.DEFAULT_MIN_TRACKFRAME_HEIGHT)
553 frameHeight = TrackFrameState.DEFAULT_MIN_TRACKFRAME_HEIGHT;
554 height += frameHeight;
555 }
556 }
557 for (Iterator<TrackGroup> it = _trackGroupList.iterator(); it.hasNext();) {
558 TrackGroup group = it.next();
559 height += group.getHeight();
560 }
561 return height;
562 }
563
564 public void setTrackLayoutManager(TrackLayoutManager layout) {
565 _layoutManager = layout;
566 }
567
568 public String getTrackGroupName() {
569 return _trackGroupName;
570 }
571
572 public void setTrackGroupName(String newTrackGroupName) {
573 this._trackGroupName = newTrackGroupName;
574 }
575
576 protected void setTrackGroupProperty(final TrackGroupPropertyImpl trackGroupProperty) {
577 if (trackGroupProperty != null)
578 _trackGroupProperty = trackGroupProperty;
579 }
580
581 public String getName() {
582 return _trackGroupName;
583 }
584
585 public boolean isTrack() {
586 return false;
587 }
588
589 public boolean isTrackGroup() {
590 return true;
591 }
592
593
594
595
596
597
598 public List<TrackEntry> getTrackEntryList() {
599 ArrayList<TrackEntry> list = new ArrayList<TrackEntry>();
600 list.addAll(_trackList);
601 list.addAll(_trackGroupList);
602 return list;
603 }
604
605
606
607
608
609
610 public void addTrackGroupPropertyChangeListener(TrackGroupPropertyChangeListener listener) {
611 _trackGroupProperty.addTrackGroupPropertyChangeListener(listener);
612 }
613
614
615
616
617
618
619 public void removeTrackGroupPropertyChangeListener(TrackGroupPropertyChangeListener listener) {
620 _trackGroupProperty.removeTrackGroupPropertyChangeListener(listener);
621 }
622
623
624
625
626
627
628 public TrackGroup getRootTrackGroup() {
629 TrackGroup rootGroup = null;
630 TrackGroup groupCursor = this;
631 while (groupCursor != null) {
632 rootGroup = groupCursor;
633 groupCursor = groupCursor.getParentTrackGroup();
634 }
635 return rootGroup;
636 }
637
638 protected String getClassName() {
639 return this.getClass().getName();
640 }
641
642 protected void removeParentTrackGroup() {
643 setParentTrackGroup(null);
644 }
645
646
647
648
649
650
651 public int compareTo(TrackGroup o) {
652 if (o instanceof TrackGroup) {
653 final TrackGroup _o = o;
654 return getTrackGroupName().compareTo(_o.getTrackGroupName());
655 }
656 else if (o instanceof Track) {
657 return 1;
658 }
659 else {
660 throw new ClassCastException("The specified object is neither TrackGroup nor Track");
661 }
662 }
663
664 protected void setTrackGroupProperty(final TrackGroupProperty trackGroupProperty) {
665 }
666
667
668
669
670
671
672 public void toXML(XMLWriter xmlWriter) {
673 xmlWriter.start("trackGroup", new XMLAttribute("className", getClassName()).add("name", _trackGroupName));
674 Properties trackGroupInternalProperties = new Properties();
675 storeInternalProperties(trackGroupInternalProperties);
676 XMLUtil.toXML(trackGroupInternalProperties, xmlWriter);
677 getPropertyReader().toXML(xmlWriter);
678 final List<TrackGroup> trackGroupList = getTrackGroupList();
679 for (int i = 0; i < trackGroupList.size(); i++) {
680 final TrackGroup trackGroup = (trackGroupList.get(i));
681 trackGroup.toXML(xmlWriter);
682 }
683 final List<Track> trackList = getTrackList();
684 for (int i = 0; i < trackList.size(); i++) {
685 final Track track = (trackList.get(i));
686 track.toXML(xmlWriter);
687 }
688 xmlWriter.end();
689 }
690
691
692
693
694
695
696 protected void storeInternalProperties(Properties saveData) {
697 saveData.add("name", _trackGroupName);
698 }
699
700
701
702
703
704
705
706
707 public static TrackGroup createTrackGroup(TrackView view) throws UTGBClientException {
708
709 TrackView.TrackGroup g = view.trackGroup;
710 if (g == null)
711 g = new TrackView.TrackGroup();
712 String groupClass = view.trackGroup.class_;
713 if (groupClass == null)
714 groupClass = "org.utgenome.gwt.utgb.client.track.TrackGroup";
715
716
717 TrackGroupFactory trackGroupFactory = TrackFactoryHolder.getTrackGroupFactory(groupClass);
718 final TrackGroup group = trackGroupFactory.newInstance();
719
720
721
722 Properties p = new Properties();
723 p.putAll(g.property);
724 p.put(UTGBProperty.SPECIES, g.coordinate.species);
725 p.put(UTGBProperty.REVISION, g.coordinate.ref);
726 p.put(UTGBProperty.TARGET, g.coordinate.chr);
727
728 group.getPropertyWriter().setProperty(p);
729
730
731 Coordinate c = g.coordinate;
732 if (c.pixelWidth < 0)
733 c.pixelWidth = UTGBEntryPointBase.computeTrackWidth();
734 group.setTrackWindow(new TrackWindow(c.pixelWidth, c.start, c.end));
735
736
737 for (TrackView.Track t : view.track) {
738 String className = t.class_;
739 TrackFactory trackFactory = TrackFactoryHolder.getTrackFactory(className);
740 if (trackFactory == null) {
741
742 String defaultClass = "org.utgenome.gwt.utgb.client.track.lib." + className;
743 trackFactory = TrackFactoryHolder.getTrackFactory(defaultClass);
744 if (trackFactory == null)
745 throw new UTGBClientException(UTGBClientErrorCode.UNKNOWN_TRACK, "unknown track class: " + defaultClass);
746 }
747
748 Track track = trackFactory.newInstance();
749 track.loadView(t);
750 group.addTrack(track);
751 }
752
753 return group;
754
755 }
756
757 public BrowserServiceAsync getBrowserService() {
758 return RPCServiceManager.getRPCService();
759 }
760
761 }