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  // OldUTGBTrack.java
20  // Since: 2007/06/19
21  //
22  // $URL$ 
23  // $Author$
24  //--------------------------------------
25  package org.utgenome.gwt.utgb.client.track.lib.old;
26  
27  import java.util.ArrayList;
28  import java.util.HashMap;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Stack;
33  
34  import org.utgenome.gwt.utgb.client.db.datatype.StringType;
35  import org.utgenome.gwt.utgb.client.track.Design;
36  import org.utgenome.gwt.utgb.client.track.Track;
37  import org.utgenome.gwt.utgb.client.track.TrackBase;
38  import org.utgenome.gwt.utgb.client.track.TrackConfig;
39  import org.utgenome.gwt.utgb.client.track.TrackConfigChange;
40  import org.utgenome.gwt.utgb.client.track.TrackFrame;
41  import org.utgenome.gwt.utgb.client.track.TrackGroup;
42  import org.utgenome.gwt.utgb.client.track.TrackGroupProperty;
43  import org.utgenome.gwt.utgb.client.track.TrackGroupPropertyChange;
44  import org.utgenome.gwt.utgb.client.track.TrackWindow;
45  import org.utgenome.gwt.utgb.client.track.operation.OperationParser;
46  import org.utgenome.gwt.utgb.client.util.CanonicalProperties;
47  import org.utgenome.gwt.utgb.client.util.GETMethodURL;
48  import org.utgenome.gwt.utgb.client.util.JSONUtil;
49  import org.utgenome.gwt.widget.client.Style;
50  
51  import com.google.gwt.core.client.GWT;
52  import com.google.gwt.event.dom.client.ErrorEvent;
53  import com.google.gwt.event.dom.client.ErrorHandler;
54  import com.google.gwt.event.dom.client.LoadEvent;
55  import com.google.gwt.event.dom.client.LoadHandler;
56  import com.google.gwt.user.client.Random;
57  import com.google.gwt.user.client.rpc.AsyncCallback;
58  import com.google.gwt.user.client.ui.AbsolutePanel;
59  import com.google.gwt.user.client.ui.FlexTable;
60  import com.google.gwt.user.client.ui.Image;
61  import com.google.gwt.user.client.ui.Label;
62  import com.google.gwt.user.client.ui.Widget;
63  import com.google.gwt.xml.client.Document;
64  import com.google.gwt.xml.client.Node;
65  import com.google.gwt.xml.client.NodeList;
66  import com.google.gwt.xml.client.XMLParser;
67  
68  /**
69   * @author ssksn
70   * 
71   */
72  public class OldUTGBTrack extends TrackBase {
73  	public static TrackFactory factory() {
74  		return new TrackFactory() {
75  			Map<String, List<String>> properties = new HashMap<String, List<String>>();
76  
77  			@Override
78  			public Track newInstance() {
79  				OldUTGBTrack track = new OldUTGBTrack();
80  				if (properties.containsKey("descriptionXMLURL")) {
81  					final List<String> values = properties.get("descriptionXMLURL");
82  					for (int i = 0; i < values.size(); i++) {
83  						final String descriptionXMLURL = (values.get(i));
84  						track.setDescriptionXML(descriptionXMLURL);
85  					}
86  				}
87  				return track;
88  			}
89  
90  			@Override
91  			public void setProperty(String key, String value) {
92  				if (properties.containsKey(key)) {
93  					final List<String> values = properties.get(key);
94  					values.add(value);
95  				}
96  				else {
97  					final List<String> values = new ArrayList<String>();
98  					properties.put(key, values);
99  					values.add(value);
100 				}
101 			}
102 
103 			@Override
104 			public void clear() {
105 				properties.clear();
106 			}
107 		};
108 	}
109 
110 	private class DescriptionURLInfo {
111 		protected String descriptionXMLURL;
112 		protected GETMethodURL graphicLayerURL = null;
113 		protected GETMethodURL indexLayerURL = null;
114 		protected GETMethodURL operationLayerURL = null;
115 		protected GETMethodURL indexOperationLayerURL = null;
116 		protected String scalingStability = null;
117 		protected String scrollingStability = null;
118 
119 		public DescriptionURLInfo(final String descriptionXMLURL) {
120 			setDescriptionXMLURL(descriptionXMLURL);
121 		}
122 
123 		final String getDescriptionXMLURL() {
124 			return descriptionXMLURL;
125 		}
126 
127 		private final void setDescriptionXMLURL(final String descriptionXMLURL) {
128 			this.descriptionXMLURL = descriptionXMLURL;
129 		}
130 
131 		final void setGraphicLayerURL(final String graphicLayerURL) {
132 			this.graphicLayerURL = GETMethodURL.newInstance(graphicLayerURL);
133 		}
134 
135 		final GETMethodURL getGraphicLayerURL() {
136 			return graphicLayerURL;
137 		}
138 
139 		final void setIndexLayerURL(final String indexLayerURL) {
140 			this.indexLayerURL = GETMethodURL.newInstance(indexLayerURL);
141 		}
142 
143 		final GETMethodURL getIndexLayerURL() {
144 			return indexLayerURL;
145 		}
146 
147 		final void setOperationLayerURL(final String operationLayerURL) {
148 			this.operationLayerURL = GETMethodURL.newInstance(operationLayerURL);
149 		}
150 
151 		final GETMethodURL getOperationLayerURL() {
152 			return operationLayerURL;
153 		}
154 
155 		final void setIndexOperationLayerURL(final String indexOperationLayerURL) {
156 			this.indexOperationLayerURL = GETMethodURL.newInstance(indexOperationLayerURL);
157 		}
158 
159 		final GETMethodURL getIndexOperationLayerURL() {
160 			return indexOperationLayerURL;
161 		}
162 
163 		final void setScalingStability(final String scalingStability) {
164 			this.scalingStability = scalingStability;
165 		}
166 
167 		final String getScalingStability() {
168 			return scalingStability;
169 		}
170 
171 		final void setScrollingStability(final String scrollingStability) {
172 			this.scrollingStability = scrollingStability;
173 		}
174 
175 		final String getScrollingStability() {
176 			return scrollingStability;
177 		}
178 	}
179 
180 	final FlexTable _panel = new FlexTable();
181 	final Label _label = new Label();
182 	final AbsolutePanel indexAbsolutePanel = new AbsolutePanel();
183 	final Image indexGraphicPanel = new Image();
184 	final AbsolutePanel mainAbsolutePanel = new AbsolutePanel();
185 	final Image mainGraphicPanel = new Image();
186 	private boolean isUptodate = false;
187 	private boolean isLoading = false;
188 	private int remainingDescriptionXMLCount = 0;
189 	private Stack<String> unparsedDescriptionXML = new Stack<String>();
190 	protected final List<DescriptionURLInfo> descriptionURLList = new ArrayList<DescriptionURLInfo>();
191 	protected DescriptionURLInfo currentDescriptionURLInfo = null;
192 	protected final List<AcceptSpeciesEntry> acceptSpeciesEntries = new ArrayList<AcceptSpeciesEntry>();
193 	private static final int INDEX_WINDOW_WIDTH = 100;
194 	protected final List<OldUTGBOptionAttribute> optionAttributes = new ArrayList<OldUTGBOptionAttribute>();
195 
196 	public OldUTGBTrack() {
197 		super("Operation Track");
198 		_panel.setWidth("100%");
199 		_label.setStyleName("operation-track-label");
200 		_label.setWidth("100%");
201 		_label.setHorizontalAlignment(Label.ALIGN_CENTER);
202 		indexGraphicPanel.setWidth(INDEX_WINDOW_WIDTH + "px");
203 		// indexGraphicPanel.setStyleName("utgbtrack-indeximage");
204 		indexAbsolutePanel.add(indexGraphicPanel, 0, 0);
205 		indexAbsolutePanel.setWidth(INDEX_WINDOW_WIDTH + "px");
206 
207 		_panel.setBorderWidth(0);
208 		_panel.setCellPadding(0);
209 		_panel.setCellSpacing(0);
210 
211 		_panel.getCellFormatter().setWidth(0, 0, INDEX_WINDOW_WIDTH + "px");
212 		_panel.setWidget(0, 0, indexAbsolutePanel);
213 		mainAbsolutePanel.add(mainGraphicPanel);
214 		_panel.setWidget(0, 1, mainAbsolutePanel);
215 		Style.hideHorizontalScrollBar(_panel);
216 	}
217 
218 	@Override
219 	public int getDefaultWindowHeight() {
220 		return 50;
221 	}
222 
223 	public Widget getWidget() {
224 		return _panel;
225 	}
226 
227 	public void setDescriptionXML(final String descriptionXMLURL) {
228 		unparsedDescriptionXML.push(descriptionXMLURL);
229 	}
230 
231 	@Override
232 	public void draw() {
233 
234 		if (!unparsedDescriptionXML.empty()) {
235 			updateDescriptionXML();
236 			return;
237 		}
238 
239 		if (isUptodate)
240 			return;
241 
242 		getFrame().setNowLoading();
243 
244 		{ // remove an old image panel and operationAreas.
245 			{ // main
246 				//mainAbsolutePanel.clear();
247 				//mainAbsolutePanel.add(mainGraphicPanel); // re-add image panel
248 			}
249 			{ // index
250 				//indexAbsolutePanel.clear();
251 			}
252 		}
253 		{
254 			// acceptability check
255 			final TrackGroupProperty propertyReader = _trackGroup.getPropertyReader();
256 			final String species = propertyReader.getProperty(OldUTGBProperty.SPECIES);
257 			final String revision = propertyReader.getProperty(OldUTGBProperty.REVISION);
258 			boolean isAccept = isAccepted(species, revision);
259 			if (!isAccept) {
260 				mainGraphicPanel.setUrl("theme/image/na.png");
261 				GWT.log("This track does not accept this species/revision setting.", null);
262 				isUptodate = true;
263 				return;
264 			}
265 			else {
266 				_frame.setNowLoading();
267 				eraseMessage();
268 				indexAbsolutePanel.add(indexGraphicPanel); // re-add image panel
269 			}
270 		}
271 		{ // update image panel
272 			{ // main
273 				final String mainGraphicURL = getMainGraphicURL();
274 				if (mainGraphicURL != null) {
275 					Image.prefetch(mainGraphicURL);
276 					mainGraphicPanel.setUrl(mainGraphicURL);
277 					getConfig().setParameter("URL", mainGraphicURL);
278 				}
279 			}
280 			{ // index
281 				final String indexGraphicURL = getIndexGraphicURL();
282 				if (indexGraphicURL != null) {
283 					Image.prefetch(indexGraphicURL);
284 					indexGraphicPanel.setUrl(indexGraphicURL);
285 				}
286 				else {
287 					indexGraphicPanel.setUrl(Design.IMAGE_TRANSPARENT);
288 					indexGraphicPanel.setWidth(INDEX_WINDOW_WIDTH + "px");
289 				}
290 			}
291 		}
292 		{ // process operation xml
293 			parseOperationXML();
294 		}
295 		isUptodate = true;
296 	}
297 
298 	@Override
299 	public void onChangeTrackWindow(TrackWindow newWindow) {
300 		isUptodate = false;
301 		refresh();
302 	}
303 
304 	@Override
305 	public void onChangeTrackGroupProperty(TrackGroupPropertyChange change) {
306 		final String[] propertyNameArray = OldUTGBProperty.getPropertyNameArray();
307 		if (change.containsOneOf(propertyNameArray)) {
308 			isUptodate = false;
309 			refresh();
310 		}
311 	}
312 
313 	@Override
314 	public void onChangeTrackConfig(TrackConfigChange change) {
315 		isUptodate = false;
316 		refresh();
317 	}
318 
319 	@Override
320 	public void setUp(TrackFrame trackFrame, TrackGroup group) {
321 		trackFrame.pack();
322 		trackFrame.enableConfig();
323 
324 		mainGraphicPanel.addLoadHandler(new LoadHandler() {
325 			public void onLoad(LoadEvent e) {
326 				getFrame().onUpdateTrackWidget();
327 				_frame.loadingDone();
328 			}
329 		});
330 		mainGraphicPanel.addErrorHandler(new ErrorHandler() {
331 			public void onError(ErrorEvent e) {
332 				GWT.log("failed to load " + mainGraphicPanel.getUrl(), null);
333 				mainGraphicPanel.setUrl("theme/image/na.png");
334 				_frame.loadingDone();
335 			}
336 		});
337 
338 		indexGraphicPanel.addLoadHandler(new LoadHandler() {
339 			public void onLoad(LoadEvent e) {
340 				getFrame().onUpdateTrackWidget();
341 			}
342 		});
343 
344 		indexGraphicPanel.addErrorHandler(new ErrorHandler() {
345 			public void onError(ErrorEvent e) {
346 				GWT.log("failed to load " + indexGraphicPanel.getUrl(), null);
347 				indexGraphicPanel.setUrl(Design.IMAGE_TRANSPARENT);
348 			}
349 		});
350 
351 		// updateDescriptionXML();
352 	}
353 
354 	protected void updateDescriptionXML() {
355 		// parse description XMLs
356 		ArrayList<String> parseList = new ArrayList<String>();
357 		parseList.addAll(unparsedDescriptionXML);
358 		remainingDescriptionXMLCount = unparsedDescriptionXML.size();
359 		getFrame().setNowLoading();
360 		for (String url : parseList) {
361 			parseDescriptionXML(url);
362 		}
363 		unparsedDescriptionXML.clear();
364 	}
365 
366 	protected void parseDescriptionXML(String descriptionXMLURL) {
367 		final String resolvedDescriptionXMLURL = (descriptionXMLURL.startsWith("http:")) ? descriptionXMLURL : GWT.getModuleBaseURL() + descriptionXMLURL;
368 
369 		getBrowserService().getHTTPContent(resolvedDescriptionXMLURL, new AsyncCallback<String>() {
370 			public void onFailure(Throwable caught) {
371 				GWT.log("cannot retrieve: " + resolvedDescriptionXMLURL, caught);
372 				remainingDescriptionXMLCount--;
373 				if (remainingDescriptionXMLCount <= 0)
374 					draw();
375 			}
376 
377 			public void onSuccess(String text) {
378 				try {
379 					final Document dom = XMLParser.parse(text);
380 					final DescriptionURLInfo descriptionURLInfo = new DescriptionURLInfo(resolvedDescriptionXMLURL);
381 					{
382 						// set up the configuration panel
383 						final NodeList topLevelTrackNodeList = dom.getElementsByTagName("track");
384 						if (topLevelTrackNodeList.getLength() != 1) {
385 							throw new AssertionError();
386 						}
387 						final Node topLevelTrackNode = topLevelTrackNodeList.item(0);
388 						final String trackName = Utilities.getAttributeValue(topLevelTrackNode, "name");
389 						_trackInfo.setTrackName(trackName);
390 						final String trackComment = Utilities.getAttributeValue(topLevelTrackNode, "comment");
391 						if (trackComment != null) {
392 							_trackInfo.setDescription(trackComment);
393 						}
394 						final String trackDescriptionURL = Utilities.getAttributeValue(topLevelTrackNode, "description_url");
395 						if (trackDescriptionURL != null) {
396 							_trackInfo.setLinkURL(trackDescriptionURL);
397 						}
398 						final String optAttrStr = Utilities.getAttributeValue(topLevelTrackNode, "optattr");
399 						if (optAttrStr != null) {
400 							final String prefix = Integer.toString(Random.nextInt());
401 							parseOptionAttribute(optAttrStr.trim(), prefix);
402 							setConfig(new TrackConfig(OldUTGBTrack.this));
403 							for (int i = 0; i < optionAttributes.size(); i++) {
404 								final OldUTGBOptionAttribute optionAttribute = (optionAttributes.get(i));
405 								optionAttribute.setConfig(getConfig());
406 							}
407 						}
408 						getConfig().addConfig(new StringType("URL"), "");
409 					}
410 					final NodeList layerNodes = dom.getElementsByTagName("layer");
411 					for (int i = 0; i < layerNodes.getLength(); i++) {
412 						final Node layerNode = layerNodes.item(i);
413 						final String kindValue = Utilities.getAttributeValue(layerNode, "kind");
414 						final String urlValue = Utilities.getAttributeValue(layerNode, "url");
415 						if (kindValue.equals("graphic")) {
416 							descriptionURLInfo.setGraphicLayerURL(urlValue);
417 						}
418 						if (kindValue.equals("index")) {
419 							descriptionURLInfo.setIndexLayerURL(urlValue);
420 						}
421 						if (kindValue.equals("operation")) {
422 							descriptionURLInfo.setOperationLayerURL(urlValue);
423 						}
424 						if (kindValue.equals("indexoperation")) {
425 							descriptionURLInfo.setIndexOperationLayerURL(urlValue);
426 						}
427 					}
428 					{
429 						final NodeList scalingStabilityNodes = dom.getElementsByTagName("scaling_stability");
430 						if (scalingStabilityNodes.getLength() >= 1) {
431 							final Node scalingStabilityNode = scalingStabilityNodes.item(0);
432 							if (scalingStabilityNode != null)
433 								currentDescriptionURLInfo.setScalingStability(Utilities.getAttributeValue(scalingStabilityNode, "kind", null));
434 						}
435 					}
436 					{
437 						final NodeList scrollingStabilityNodes = dom.getElementsByTagName("scrolling_stability");
438 						if (scrollingStabilityNodes.getLength() >= 1) {
439 							final Node scrollingStabilityNode = scrollingStabilityNodes.item(0);
440 							currentDescriptionURLInfo.setScrollingStability(Utilities.getAttributeValue(scrollingStabilityNode, "kind", null));
441 						}
442 					}
443 					{
444 						final NodeList acceptSpeciesNodeList = dom.getElementsByTagName("accept_species");
445 						if (acceptSpeciesNodeList.getLength() >= 1) {
446 							final Node acceptSpeciesNode = acceptSpeciesNodeList.item(0);
447 							final NodeList acceptSpeciesEntries = Utilities.getTagChildNodes(acceptSpeciesNode);
448 							for (int i = 0; i < acceptSpeciesEntries.getLength(); i++) {
449 								final Node acceptSpeciesEntry = acceptSpeciesEntries.item(i);
450 								final String acceptSpecies = Utilities.getAttributeValue(acceptSpeciesEntry, "species", "any");
451 								final String acceptRevision = Utilities.getAttributeValue(acceptSpeciesEntry, "revision", "any");
452 								final AcceptSpeciesEntry entry = new AcceptSpeciesEntry(acceptSpecies, acceptRevision, descriptionURLInfo);
453 								addAcceptSpeciesEntry(entry);
454 							}
455 						}
456 					}
457 					descriptionURLList.add(descriptionURLInfo);
458 					isUptodate = false;
459 				}
460 				finally {
461 					remainingDescriptionXMLCount--;
462 					if (remainingDescriptionXMLCount <= 0)
463 						draw();
464 				}
465 			}
466 		});
467 
468 	}
469 
470 	/*
471 	 * class ParseDescriptionXMLCommand implements IncrementalCommand { private String descriptionXMLURL; private
472 	 * boolean nowLoading = false; private boolean loadingDone = false; public ParseDescriptionXMLCommand(String
473 	 * descrptionXMLURL) { this.descriptionXMLURL = descrptionXMLURL; }
474 	 * 
475 	 * public boolean execute() { if(nowLoading) return !loadingDone; // continue the command until the loading complete
476 	 * else { nowLoading = true; }
477 	 * 
478 	 * 
479 	 * return !loadingDone; } }
480 	 */
481 
482 	public void writeMessage(final String message) {
483 		// _label.setText(message);
484 		// _frame.writeMessage(message);
485 	}
486 
487 	public void eraseMessage() {
488 		// _label.setText("");
489 		// _frame.eraseMessage(true);
490 	}
491 
492 	private final void parseOptionAttribute(final String optAttrStr, final String prefix) {
493 		final int slashIndex = optAttrStr.indexOf('/');
494 		if (slashIndex < 0)
495 			return;
496 		final String parameterName = optAttrStr.substring(0, slashIndex).trim();
497 		final int leftBlockBracketIndex = optAttrStr.indexOf('[', slashIndex + 1);
498 		if (leftBlockBracketIndex < 0)
499 			return;
500 		final String type = optAttrStr.substring(slashIndex + 1, leftBlockBracketIndex).trim();
501 		final int rightBlockBracketIndex = optAttrStr.indexOf(']', leftBlockBracketIndex + 1);
502 		if (rightBlockBracketIndex < 0)
503 			return;
504 		final String valueStr = optAttrStr.substring(leftBlockBracketIndex + 1, rightBlockBracketIndex).trim();
505 		if (valueStr.length() <= 0)
506 			return;
507 		final String[] values = valueStr.split(",");
508 		final int leftBracketIndex = optAttrStr.indexOf('(', rightBlockBracketIndex + 1);
509 		if (leftBracketIndex < 0)
510 			return;
511 		final int rightBracketIndex = optAttrStr.indexOf(')', leftBracketIndex + 1);
512 		if (rightBracketIndex < 0)
513 			return;
514 		final String operationStr = optAttrStr.substring(leftBracketIndex + 1, rightBracketIndex).trim();
515 		if (operationStr.length() <= 0)
516 			return;
517 		final String[] operations = operationStr.split(",");
518 		if (type.equalsIgnoreCase("select")) {
519 			// operation check
520 			for (int i = 0; i < operations.length; i++) {
521 				final String operation = operations[i];
522 				if (!operation.equalsIgnoreCase("disp") && !operation.equalsIgnoreCase("color") && !operation.equalsIgnoreCase("select"))
523 					return;
524 			}
525 			final OldUTGBOptionAttribute optionAttribute = OldUTGBOptionAttribute.getSelectInstance(parameterName, values, operations, prefix);
526 			if (optionAttribute != null)
527 				optionAttributes.add(optionAttribute);
528 		}
529 		else if (type.equalsIgnoreCase("real")) {
530 			// operation check
531 			for (int i = 0; i < operations.length; i++) {
532 				final String operation = operations[i];
533 				if (!operation.equalsIgnoreCase("gradation") && !operation.equalsIgnoreCase("ubound") && !operation.equalsIgnoreCase("lbound"))
534 					return;
535 			}
536 			if (values.length != 2)
537 				return;
538 			final String minValue = values[0];
539 			final String maxValue = values[1];
540 			final OldUTGBOptionAttribute optionAttribute = OldUTGBOptionAttribute.getRealInstance(parameterName, minValue, maxValue, operations, prefix);
541 			if (optionAttribute != null)
542 				optionAttributes.add(optionAttribute);
543 		}
544 		final int nextCommaIndex = optAttrStr.indexOf(',', rightBracketIndex + 1);
545 		if (nextCommaIndex < 0)
546 			return;
547 		final String nextOptAttrStr = optAttrStr.substring(nextCommaIndex + 1).trim();
548 		parseOptionAttribute(nextOptAttrStr, prefix);
549 	}
550 
551 	final int getMainPanelWidth() {
552 		final int windowWidth = getTrackGroup().getPropertyReader().getTrackWindow().getPixelWidth();
553 		return windowWidth - INDEX_WINDOW_WIDTH;
554 	}
555 
556 	private final String getMainGraphicURL() {
557 		if (currentDescriptionURLInfo != null) {
558 			final GETMethodURL graphicLayerURL = currentDescriptionURLInfo.getGraphicLayerURL();
559 			if (graphicLayerURL != null)
560 				return getURL(graphicLayerURL, getMainPanelWidth());
561 		}
562 		return null;
563 	}
564 
565 	private final String getIndexGraphicURL() {
566 		if (currentDescriptionURLInfo != null) {
567 			final GETMethodURL indexLayerURL = currentDescriptionURLInfo.getIndexLayerURL();
568 			if (indexLayerURL != null)
569 				return getURL(indexLayerURL, getMainPanelWidth());
570 		}
571 		return null;
572 	}
573 
574 	private final String getMainOperationURL() {
575 		if (currentDescriptionURLInfo != null) {
576 			final GETMethodURL operationLayerURL = currentDescriptionURLInfo.getOperationLayerURL();
577 			if (operationLayerURL != null)
578 				return getURL(operationLayerURL, getMainPanelWidth());
579 		}
580 		return null;
581 	}
582 
583 	private final String getIndexOperationURL() {
584 		if (currentDescriptionURLInfo != null) {
585 			final GETMethodURL indexOperationLayerURL = currentDescriptionURLInfo.getIndexOperationLayerURL();
586 			if (indexOperationLayerURL != null)
587 				return getURL(indexOperationLayerURL, getMainPanelWidth());
588 		}
589 		return null;
590 	}
591 
592 	private final String getURL(final GETMethodURL url, final int width) {
593 		if (url == null)
594 			return null;
595 		final Map<String, String> parameterMap = new HashMap<String, String>();
596 		final String[] propertyNameArray = OldUTGBProperty.getPropertyNameArray();
597 		final TrackGroupProperty propertyReader = _trackGroup.getPropertyReader();
598 		for (int i = 0; i < propertyNameArray.length; i++) {
599 			final String key = propertyNameArray[i];
600 			final String value = propertyReader.getProperty(key);
601 			parameterMap.put(key, value);
602 		}
603 		parameterMap.put("width", Integer.toString(width));
604 		final TrackWindow trackWindow = _trackGroup.getTrackWindow();
605 		final long startIndex = trackWindow.getStartOnGenome();
606 		final long endIndex = trackWindow.getEndOnGenome();
607 		parameterMap.put("start", Long.toString(startIndex));
608 		parameterMap.put("end", Long.toString(endIndex));
609 		for (int i = 0; i < optionAttributes.size(); i++) {
610 			final OldUTGBOptionAttribute optionAttribute = (optionAttributes.get(i));
611 			optionAttribute.setParameters(parameterMap);
612 		}
613 		final String returnURL = url.getURL(parameterMap);
614 		if (returnURL.startsWith("http"))
615 			return returnURL;
616 		else
617 			return null;
618 	}
619 
620 	private final void parseOperationXML() {
621 		// main
622 		final String mainOperationURL = getMainOperationURL();
623 		parseOperationXML(mainOperationURL, mainAbsolutePanel, "Now Operation XML Parsing ...");
624 		// index
625 		final String indexOperationURL = getIndexOperationURL();
626 		parseOperationXML(indexOperationURL, indexAbsolutePanel, null);
627 	}
628 
629 	private final void parseOperationXML(final String operationURL, final AbsolutePanel _absolutePanel, final String loadingMessage) {
630 		if (operationURL == null)
631 			return;
632 		if (loadingMessage != null)
633 			writeMessage(loadingMessage);
634 		getBrowserService().getHTTPContent(operationURL, new AsyncCallback<String>() {
635 			public void onFailure(Throwable caught) {
636 			}
637 
638 			public void onSuccess(String text) {
639 				if (text.length() <= 0) {
640 					if (loadingMessage != null)
641 						eraseMessage();
642 					return;
643 				}
644 				{
645 					final Document dom = XMLParser.parse(text);
646 					final OperationParser parser = OperationParser.getParser();
647 					parser.parse(dom, _absolutePanel, OldUTGBTrack.this);
648 					if (loadingMessage != null)
649 						eraseMessage();
650 					getFrame().onUpdateTrackWidget();
651 				}
652 			}
653 		});
654 	}
655 
656 	private boolean isAccepted(final String species, final String revision) {
657 		final Iterator<AcceptSpeciesEntry> it = acceptSpeciesEntries.iterator();
658 		while (it.hasNext()) {
659 			final AcceptSpeciesEntry acceptSpeciesEntry = it.next();
660 			final boolean result = acceptSpeciesEntry.isAccepted(species, revision);
661 			if (result) {
662 				currentDescriptionURLInfo = acceptSpeciesEntry.getDescriptionURLInfo();
663 				return true;
664 			}
665 		}
666 		return false;
667 	}
668 
669 	private void addAcceptSpeciesEntry(final AcceptSpeciesEntry entry) {
670 		acceptSpeciesEntries.add(entry);
671 	}
672 
673 	class AcceptSpeciesEntry {
674 		private String species = null;
675 		private String revision = null;
676 		private DescriptionURLInfo descriptionURLInfo = null;
677 
678 		public AcceptSpeciesEntry(final String species, final String revision, final DescriptionURLInfo descriptionURLInfo) {
679 			if (species.equals("any"))
680 				this.species = null;
681 			else
682 				this.species = species;
683 			if (revision.equals("any"))
684 				this.revision = null;
685 			else
686 				this.revision = revision;
687 			this.descriptionURLInfo = descriptionURLInfo;
688 		}
689 
690 		public boolean isAccepted(final String species, final String revision) {
691 			if (this.species == null)
692 				return true;
693 			else {
694 				if (!this.species.equals(species))
695 					return false;
696 				else {
697 					if (this.revision == null)
698 						return true;
699 					else {
700 						if (!this.revision.equals(revision))
701 							return false;
702 						else
703 							return true;
704 					}
705 				}
706 			}
707 		}
708 
709 		public final DescriptionURLInfo getDescriptionURLInfo() {
710 			return descriptionURLInfo;
711 		}
712 	}
713 
714 	@Override
715 	public void saveProperties(CanonicalProperties saveData) {
716 		final ArrayList<String> descriptionURLs = new ArrayList<String>();
717 		for (int i = 0; i < descriptionURLList.size(); i++) {
718 			final DescriptionURLInfo descriptionURLInfo = (descriptionURLList.get(i));
719 			final String descriptionXMLURL = descriptionURLInfo.getDescriptionXMLURL();
720 			descriptionURLs.add(descriptionXMLURL);
721 		}
722 		saveData.add("descriptionXMLURL", JSONUtil.toJSONArray(descriptionURLs));
723 	}
724 
725 	@Override
726 	public void restoreProperties(CanonicalProperties properties) {
727 		ArrayList<String> valueList = JSONUtil.parseJSONArray(properties.get("descriptionXMLURL", "[]"));
728 		for (Iterator<String> it = valueList.iterator(); it.hasNext();) {
729 			String value = it.next();
730 			unparsedDescriptionXML.push(value);
731 		}
732 		isUptodate = false;
733 	}
734 }