View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2009 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  // utgb-core Project
18  //
19  // GenomeTrack.java
20  // Since: Feb 17, 2009
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.gwt.utgb.client.track.lib;
26  
27  import java.util.HashSet;
28  import java.util.Set;
29  
30  import org.utgenome.gwt.utgb.client.bio.Coordinate;
31  import org.utgenome.gwt.utgb.client.db.datatype.StringType;
32  import org.utgenome.gwt.utgb.client.track.Design;
33  import org.utgenome.gwt.utgb.client.track.Track;
34  import org.utgenome.gwt.utgb.client.track.TrackBase;
35  import org.utgenome.gwt.utgb.client.track.TrackConfig;
36  import org.utgenome.gwt.utgb.client.track.TrackConfigChange;
37  import org.utgenome.gwt.utgb.client.track.TrackFrame;
38  import org.utgenome.gwt.utgb.client.track.TrackGroup;
39  import org.utgenome.gwt.utgb.client.track.TrackGroupPropertyChange;
40  import org.utgenome.gwt.utgb.client.track.TrackWindow;
41  import org.utgenome.gwt.utgb.client.track.UTGBProperty;
42  import org.utgenome.gwt.utgb.client.util.CanonicalProperties;
43  import org.utgenome.gwt.utgb.client.util.Properties;
44  import org.utgenome.gwt.utgb.client.util.StringUtil;
45  import org.utgenome.gwt.widget.client.Style;
46  
47  import com.google.gwt.event.dom.client.ErrorEvent;
48  import com.google.gwt.event.dom.client.ErrorHandler;
49  import com.google.gwt.event.dom.client.LoadEvent;
50  import com.google.gwt.event.dom.client.LoadHandler;
51  import com.google.gwt.user.client.DOM;
52  import com.google.gwt.user.client.ui.FlexTable;
53  import com.google.gwt.user.client.ui.Frame;
54  import com.google.gwt.user.client.ui.Image;
55  import com.google.gwt.user.client.ui.Widget;
56  
57  /**
58   * GenomeTrack for visualizing data on genome sequences using an image URL or an HTML page embedded in IFRAME tag.
59   * 
60   * <pre>
61   * -track
62   *  -class: genome track
63   *  -property:
64   *   -type: image (or frame)
65   *   -track base URL: http://somewhere/cgi/drawGenes?ref=%ref&chr=%chr&start=%start&end=%end&pixelwidth=%pixelwidth
66   * </pre>
67   * 
68   * In the track base URL parameter, you can use several keyword parameters starting with %. For the details of available
69   * parameters, see also {@link ReadTrack} page.
70   * 
71   * @author leo
72   * 
73   */
74  public class GenomeTrack extends TrackBase {
75  
76  	protected String type = "image";
77  	private String trackURL;
78  	protected int leftMargin = 0;
79  
80  	protected FlexTable layoutPanel = new FlexTable();
81  	protected Image trackImage = new Image();
82  	protected Frame frame = new Frame();
83  	protected boolean isWidgetReady = false;
84  
85  	protected Set<String> queryParams = new HashSet<String>();
86  
87  	public static TrackFactory factory() {
88  		return new TrackFactory() {
89  			@Override
90  			public Track newInstance() {
91  				return new GenomeTrack();
92  			}
93  		};
94  	}
95  
96  	public GenomeTrack() {
97  		this("Genome Track");
98  	}
99  
100 	public GenomeTrack(String string) {
101 		super(string);
102 
103 		Style.fullWidth(layoutPanel);
104 		layoutPanel.setCellPadding(0);
105 		layoutPanel.setCellSpacing(0);
106 		Style.fontSize(layoutPanel, 0);
107 
108 		Style.fullWidth(frame);
109 		Style.margin(frame, 0);
110 		Style.padding(frame, 0);
111 		DOM.setElementProperty(frame.getElement(), "align", "left");
112 		DOM.setElementPropertyInt(frame.getElement(), "marginHight", 0);
113 		DOM.setElementPropertyInt(frame.getElement(), "marginWidth", 0);
114 		DOM.setElementPropertyInt(frame.getElement(), "frameBorder", 0);
115 	}
116 
117 	public Widget getWidget() {
118 		return layoutPanel;
119 	}
120 
121 	@Override
122 	public void draw() {
123 
124 		if (leftMargin > 0)
125 			layoutPanel.getCellFormatter().setWidth(0, 0, leftMargin + "px");
126 
127 		String newURL = getTrackURL();
128 		if (trackURL != null && trackURL.equals(newURL)) {
129 			getFrame().loadingDone();
130 			return; // do nothing when generated URL has no change
131 		}
132 		else
133 			trackURL = newURL;
134 
135 		getConfig().setParameter("trackURL", trackURL);
136 
137 		if (type.equals("frame")) {
138 			if (!isWidgetReady) {
139 				layoutPanel.setWidget(0, 1, frame);
140 				isWidgetReady = true;
141 			}
142 			frame.setUrl(trackURL);
143 		}
144 		else if (type.equals("image")) {
145 			// use image 
146 			if (!isWidgetReady) {
147 				layoutPanel.setWidget(0, 1, trackImage);
148 				isWidgetReady = true;
149 			}
150 
151 			trackImage.setUrl(trackURL);
152 			getFrame().setNowLoading();
153 		}
154 	}
155 
156 	protected String getTrackURL() {
157 		Coordinate c = getCoordinate();
158 
159 		Properties p = new Properties();
160 		TrackWindow w = getTrackGroup().getTrackWindow();
161 
162 		for (String key : queryParams) {
163 			// override the group property using the corresponding config parameter 
164 			String v = getConfig().getParameter(key);
165 			if (v == null) {
166 				v = getTrackGroup().getProperty(key);
167 			}
168 			if (v != null)
169 				p.add(key, v);
170 		}
171 
172 		String trackBaseURL = getConfig().getString(CONFIG_TRACK_BASE_URL, "utgb-core/roundcircle");
173 		return resolvePropertyValues(c.getTrackURL(trackBaseURL, p));
174 	}
175 
176 	@Override
177 	public void setUp(TrackFrame trackFrame, TrackGroup group) {
178 
179 		trackImage.addLoadHandler(new LoadHandler() {
180 			public void onLoad(LoadEvent arg0) {
181 				getFrame().onUpdateTrackWidget();
182 				getFrame().loadingDone();
183 			}
184 		});
185 		trackImage.addErrorHandler(new ErrorHandler() {
186 			public void onError(ErrorEvent arg0) {
187 				trackImage.setUrl(Design.IMAGE_NOT_AVAILABLE);
188 				getFrame().loadingDone();
189 			}
190 		});
191 
192 		int height = this.getDefaultWindowHeight();
193 		if (height > 0) {
194 			frame.setHeight(height + "px");
195 			layoutPanel.setHeight(height + "px");
196 		}
197 
198 		// set up the configuration panel
199 		TrackConfig config = getConfig();
200 		config.addConfig("Track Base URL", new StringType(CONFIG_TRACK_BASE_URL), "");
201 		config.addConfig("Track URL", new StringType("trackURL"), trackURL);
202 	}
203 
204 	public static final String CONFIG_TRACK_BASE_URL = "trackBaseURL";
205 	public static final String CONFIG_TRACK_TYPE = "type";
206 
207 	@Override
208 	public void onChange(TrackGroupPropertyChange change, TrackWindow newWindow) {
209 
210 		if (monitorWindowChange && newWindow != null) {
211 			draw();
212 			return;
213 		}
214 
215 		if (change == null)
216 			return;
217 
218 		if (monitorCoordinateChange) {
219 			if (change.containsOneOf(UTGBProperty.coordinateParameters))
220 				draw();
221 		}
222 		else if (change.containsOneOf(queryParams))
223 			draw();
224 
225 	}
226 
227 	@Override
228 	public void onChangeTrackConfig(TrackConfigChange change) {
229 		if (change.contains(CONFIG_TRACK_BASE_URL)) {
230 			draw();
231 		}
232 	}
233 
234 	private boolean monitorCoordinateChange = true;
235 	private boolean monitorWindowChange = true;
236 
237 	@Override
238 	public void saveProperties(CanonicalProperties saveData) {
239 		super.saveProperties(saveData);
240 		String q = StringUtil.joinIterable(queryParams, ",");
241 		saveData.add("queryParams", q);
242 	}
243 
244 	@Override
245 	public void restoreProperties(CanonicalProperties properties) {
246 		super.restoreProperties(properties);
247 
248 		leftMargin = properties.getInt("leftMargin", leftMargin);
249 		type = properties.get(CONFIG_TRACK_TYPE, type);
250 		monitorCoordinateChange = properties.getBoolean("monitorCoordinateChange", monitorCoordinateChange);
251 		monitorWindowChange = properties.getBoolean("monitorWindowChange", monitorWindowChange);
252 
253 		queryParams.clear();
254 		String q = properties.get("queryParams");
255 		if (q != null) {
256 			String[] params = q.split(",");
257 			if (params != null) {
258 				for (String each : params)
259 					queryParams.add(each);
260 			}
261 		}
262 
263 	}
264 }