View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2007 utgenome.org
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *--------------------------------------------------------------------------*/
16  //--------------------------------------
17  // GenomeBrowser Project
18  //
19  // TrackBase.java
20  // Since: Jun 12, 2007
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.gwt.utgb.client.track;
26  
27  import java.util.HashMap;
28  
29  import org.utgenome.gwt.utgb.client.BrowserServiceAsync;
30  import org.utgenome.gwt.utgb.client.RPCServiceManager;
31  import org.utgenome.gwt.utgb.client.UTGBEntryPointBase;
32  import org.utgenome.gwt.utgb.client.bio.Coordinate;
33  import org.utgenome.gwt.utgb.client.util.CanonicalProperties;
34  import org.utgenome.gwt.utgb.client.util.Properties;
35  import org.utgenome.gwt.utgb.client.util.xml.XMLAttribute;
36  import org.utgenome.gwt.utgb.client.util.xml.XMLUtil;
37  import org.utgenome.gwt.utgb.client.util.xml.XMLWriter;
38  import org.utgenome.gwt.utgb.client.view.TrackView;
39  
40  import com.google.gwt.user.client.Command;
41  import com.google.gwt.user.client.DeferredCommand;
42  
43  /**
44   * {@link TrackBase} is a base class that supports to implement your own {@link Track}s.
45   * 
46   * @author leo
47   * 
48   */
49  public abstract class TrackBase implements Track {
50  	protected TrackGroup _trackGroup = null;
51  	protected TrackFrame _frame = null;
52  	protected final TrackInfo _trackInfo;
53  	private boolean _isInitialized = false;
54  	private int defaultTrackHeight = TrackFrameState.DEFAULT_MIN_TRACKFRAME_HEIGHT;
55  
56  	private TrackConfig __config;
57  
58  	public TrackBase(String trackName) {
59  		this(new TrackInfo(trackName));
60  	}
61  
62  	public TrackBase(TrackInfo trackInfo) {
63  		_trackInfo = trackInfo;
64  		__config = new TrackConfig(this);
65  	}
66  
67  	public void setUp(TrackFrame trackFrame, TrackGroup group) {
68  		// do nothing
69  	}
70  
71  	/**
72  	 * Substitute the query parameters in the given string with the actual values.
73  	 * 
74  	 * @param template
75  	 * @return
76  	 */
77  	public String resolvePropertyValues(String template) {
78  		if (template == null)
79  			return null;
80  		// replace track group properties
81  		TrackWindow w = getTrackWindow();
82  		if (template.contains("%start"))
83  			template = template.replaceAll("%start", Integer.toString(w.getStartOnGenome()));
84  		if (template.contains("%end"))
85  			template = template.replaceAll("%end", Integer.toString(w.getEndOnGenome()));
86  		if (template.contains("%len"))
87  			template = template.replaceAll("%len", Integer.toString(w.getSequenceLength()));
88  		if (template.contains("%pixelwidth"))
89  			template = template.replaceAll("%pixelwidth", Integer.toString(w.getPixelWidth()));
90  		String chr = getTrackGroupProperty(UTGBProperty.TARGET);
91  		if (chr != null && template.contains("%chr"))
92  			template = template.replaceAll("%chr", chr);
93  		String ref = getTrackGroupProperty(UTGBProperty.REVISION);
94  		if (ref != null && template.contains("%ref"))
95  			template = template.replaceAll("%ref", ref);
96  		String species = getTrackGroupProperty(UTGBProperty.SPECIES);
97  		if (species != null && template.contains("%species"))
98  			template = template.replaceAll("%species", species);
99  
100 		return template;
101 	}
102 
103 	public TrackGroup getTrackGroup() {
104 		assert (_trackGroup != null);
105 		return _trackGroup;
106 	}
107 
108 	public TrackWindow getTrackWindow() {
109 		return _trackGroup.getTrackWindow();
110 	}
111 
112 	public TrackInfo getTrackInfo() {
113 		return _trackInfo;
114 	}
115 
116 	public void setTrackGroup(TrackGroup trackGroup) {
117 		this._trackGroup = trackGroup;
118 		validateTrackEnvironment();
119 	}
120 
121 	public TrackFrame getFrame() {
122 		return _frame;
123 	}
124 
125 	public void setFrame(TrackFrame frame) {
126 		this._frame = frame;
127 		validateTrackEnvironment();
128 	}
129 
130 	private void validateTrackEnvironment() {
131 		if (_trackGroup != null && _frame != null) {
132 			_trackGroup.setResizeNotification(false);
133 			if (frameConfig != null) {
134 
135 				_frame.setPacked(frameConfig.pack);
136 
137 				// restore trackFrame State
138 				if (frameConfig.height > TrackFrameState.DEFAULT_MIN_TRACKFRAME_HEIGHT) {
139 					defaultTrackHeight = frameConfig.height;
140 					_frame.resize(defaultTrackHeight);
141 				}
142 
143 			}
144 			setUp(_frame, _trackGroup);
145 			_trackGroup.setResizeNotification(true);
146 			_isInitialized = true;
147 		}
148 	}
149 
150 	public int getDefaultWindowHeight() {
151 		return defaultTrackHeight;
152 	}
153 
154 	public int getMinimumWindowHeight() {
155 		return 0;
156 	}
157 
158 	public void onChangeTrackGroupProperty(TrackGroupPropertyChange change) {
159 		// do nothing in default
160 	}
161 
162 	public void beforeChangeTrackWindow(TrackWindow newWindow) {
163 		// do nothing in default 
164 	}
165 
166 	public void onChangeTrackWindow(TrackWindow newWindow) {
167 		// do nothing in default
168 	}
169 
170 	public void onChange(TrackGroupPropertyChange change, TrackWindow newWindow) {
171 
172 		// invoke onChangeTrackGroupProperty for compatibility
173 		if (change != null)
174 			this.onChangeTrackGroupProperty(change);
175 
176 		if (newWindow != null)
177 			this.onChangeTrackWindow(newWindow);
178 
179 	}
180 
181 	public void draw() {
182 		// do nothing on default
183 	}
184 
185 	public void refresh() {
186 		TrackBase.this.draw();
187 		//TrackBase.this.draw();
188 		//getFrame().onUpdateTrackWidget();
189 		DeferredCommand.addCommand(new Command() {
190 			public void execute() {
191 				getFrame().onUpdateTrackWidget();
192 
193 			}
194 		});
195 	}
196 
197 	/**
198 	 * Get the current genome coordinate
199 	 * 
200 	 * @return
201 	 */
202 	public Coordinate getCoordinate() {
203 		TrackGroupProperty prop = getTrackGroup().getPropertyReader();
204 		String species = prop.getProperty(UTGBProperty.SPECIES);
205 		String revision = prop.getProperty(UTGBProperty.REVISION);
206 		String name = prop.getProperty(UTGBProperty.TARGET);
207 		String group = prop.getProperty(UTGBProperty.GROUP, "utgb");
208 
209 		return new Coordinate(group, species, revision, name);
210 
211 	}
212 
213 	public boolean isInitialized() {
214 		return _isInitialized;
215 	}
216 
217 	public void onChangeTrackConfig(TrackConfigChange change) {
218 		// do nothing on default
219 	}
220 
221 	public TrackConfig getConfig() {
222 		return __config;
223 	}
224 
225 	public void setConfig(TrackConfig config) {
226 		this.__config = config;
227 	}
228 
229 	public String getName() {
230 		return getTrackInfo().getTrackName();
231 	}
232 
233 	public boolean isTrack() {
234 		return true;
235 	}
236 
237 	public boolean isTrackGroup() {
238 		return false;
239 	}
240 
241 	public static class TrackFrameConfig {
242 		public int height = TrackFrameState.DEFAULT_MIN_TRACKFRAME_HEIGHT;
243 		public boolean pack = true;
244 	}
245 
246 	public TrackFrameConfig frameConfig = null;
247 
248 	public void loadView(TrackView.Track view) {
249 		if (view.name != null)
250 			getTrackInfo().setTrackName(view.name);
251 
252 		//		Properties p = new Properties();
253 		//		p.putAll(view.property);
254 		//		p.put("height", Integer.toString(view.height));
255 		//		p.put("pack", Boolean.toString(view.pack));
256 
257 		frameConfig = new TrackFrameConfig();
258 		frameConfig.height = view.height;
259 		frameConfig.pack = view.pack;
260 
261 		restoreProperties(view.property);
262 	}
263 
264 	public TrackView.Track toView() {
265 		TrackView.Track t = new TrackView.Track();
266 		t.name = getName();
267 		t.height = getWidget().getOffsetHeight();
268 		t.class_ = getClassName();
269 		t.pack = _frame.isPacked();
270 		saveProperties(t.property);
271 		return t;
272 	}
273 
274 	public String toXML() {
275 		XMLWriter xmlWriter = new XMLWriter();
276 		toXML(xmlWriter);
277 		return xmlWriter.toString();
278 	}
279 
280 	public void toXML(XMLWriter xmlWriter) {
281 		xmlWriter.start(
282 				"track",
283 				new XMLAttribute().add("className", getClassName()).add("name", getName()).add("height", getWidget().getOffsetHeight())
284 						.add("pack", _frame.isPacked()));
285 
286 		CanonicalProperties trackProperties = new CanonicalProperties();
287 		saveProperties(trackProperties);
288 		XMLUtil.toCanonicalXML(trackProperties, xmlWriter);
289 		xmlWriter.end(); // track
290 	}
291 
292 	public String getClassName() {
293 		return this.getClass().getName();
294 	}
295 
296 	/**
297 	 * Override this method to save internal state of the track into a {@link Properties} object
298 	 * 
299 	 * @param xmlWriter
300 	 */
301 	public void saveProperties(CanonicalProperties saveData) {
302 		__config.saveProperties(saveData);
303 	}
304 
305 	/**
306 	 * Override this method to restore internal state of the track
307 	 * 
308 	 * @param properties
309 	 */
310 	public void restoreProperties(CanonicalProperties properties) {
311 		__config.restoreProperties(properties);
312 	}
313 
314 	public String getTrackGroupProperty(String key) {
315 		return getTrackGroup().getProperty(key);
316 	}
317 
318 	public String getTrackGroupProperty(String key, String defaultValue) {
319 		return getTrackGroup().getProperty(key, defaultValue);
320 	}
321 
322 	public void setTrackGroupProperty(String key, String value) {
323 		getTrackGroup().getPropertyWriter().setProperty(key, value);
324 	}
325 
326 	public void setCenterOfTrackWindow(String chr, int start, int end) {
327 
328 		TrackWindow win = getTrackGroup().getTrackWindow();
329 		int width = win.getEndOnGenome() - win.getStartOnGenome();
330 		int left = start;
331 		int right = end;
332 		if (width < 0) {
333 			width = -width;
334 		}
335 
336 		// locate the new window so that the target region will be at 20% from the left side 
337 		int newLeft = left - (int) (width * 0.3);
338 		int newRight = right + (int) (width * 0.3);
339 
340 		TrackGroupPropertyWriter writer = getTrackGroup().getPropertyWriter();
341 		HashMap<String, String> property = new HashMap<String, String>();
342 		property.put(UTGBProperty.TARGET, chr);
343 
344 		try {
345 			writer.setProperyChangeNotifaction(false);
346 			if (!win.isReverseStrand())
347 				writer.setTrackWindow(newLeft, newRight);
348 			else
349 				writer.setTrackWindow(newRight, newLeft);
350 		}
351 		finally {
352 			writer.setProperyChangeNotifaction(true);
353 		}
354 		writer.setProperty(property);
355 	}
356 
357 	/**
358 	 * Get the RPC service for communicating with the server
359 	 * 
360 	 * @return
361 	 */
362 	public BrowserServiceAsync getBrowserService() {
363 		return RPCServiceManager.getRPCService();
364 	}
365 
366 	public void onChangeTrackHeight(int newHeight) {
367 		// do nothing
368 	}
369 
370 	public void error(String message) {
371 		UTGBEntryPointBase.showErrorMessage(message);
372 	}
373 
374 }