package edu.colostate.vchill.bookmark; import edu.colostate.vchill.ScaleManager; import edu.colostate.vchill.chill.ChillMomentFieldScale; import edu.colostate.vchill.file.FileFunctions.Moment; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * ContentHandler for VCHILL's XML bookmark file. * Unlike the old-style text parser, this parser adds all bookmarks it finds to the controller. * * @author Jochen Deyke * @author jpont * @version 2010-07-07 */ public class XMLBookmarkHandler extends DefaultHandler { private static final ScaleManager sm = ScaleManager.getInstance(); private Bookmark bookmark; private boolean inCat; private boolean inName; private boolean inUrl; private boolean inDir; private boolean inFile; private boolean inSweep; private boolean inScan_type; private boolean inColor; private boolean inAutoscale; private boolean inMinval; private boolean inMaxval; private boolean inZoom; private boolean inPan; private boolean inX; private boolean inY; private boolean inRange; private boolean inRing; private boolean inRhi_height; private boolean inComment; private StringBuilder tmpCat; private StringBuilder tmpName; private StringBuilder tmpUrl; private StringBuilder tmpDir; private StringBuilder tmpFile; private StringBuilder tmpSweep; private StringBuilder tmpScan_type; private StringBuilder tmpAutoscale; private StringBuilder tmpMinval; private StringBuilder tmpMaxval; private StringBuilder tmpZoom; private StringBuilder tmpX; private StringBuilder tmpY; private StringBuilder tmpRange; private StringBuilder tmpRing; private StringBuilder tmpRhi_height; private StringBuilder tmpComment; private double zoom = 1; private final String prefix; public XMLBookmarkHandler(final String prefix) { this.prefix = prefix; } @Override public void startDocument() { this.bookmark = new Bookmark(); this.zoom = 1.0; this.inCat = false; this.inName = false; this.inUrl = false; this.inDir = false; this.inFile = false; this.inSweep = false; this.inScan_type = false; this.inColor = false; this.inAutoscale = false; this.inMinval = false; this.inMaxval = false; this.inZoom = false; this.inPan = false; this.inX = false; this.inY = false; this.inRange = false; this.inRing = false; this.inRhi_height = false; this.inComment = false; this.tmpCat = new StringBuilder(); this.tmpName = new StringBuilder(); this.tmpUrl = new StringBuilder(); this.tmpDir = new StringBuilder(); this.tmpFile = new StringBuilder(); this.tmpSweep = new StringBuilder(); this.tmpScan_type = new StringBuilder(); this.tmpAutoscale = new StringBuilder(); this.tmpMinval = new StringBuilder(); this.tmpMaxval = new StringBuilder(); this.tmpZoom = new StringBuilder(); this.tmpX = new StringBuilder(); this.tmpY = new StringBuilder(); this.tmpRange = new StringBuilder(); this.tmpRing = new StringBuilder(); this.tmpRhi_height = new StringBuilder(); this.tmpComment = new StringBuilder(); } @Override public void startElement(final String namespaceURI, final String localName, final String qualifiedName, final Attributes attribs) throws SAXException { String lowname = qualifiedName.toLowerCase(); if (lowname.equals("category")) { this.inCat = true; } else if (lowname.equals("name")) { this.inName = true; } else if (lowname.equals("url")) { this.inUrl = true; } else if (lowname.equals("directory")) { this.inDir = true; } else if (lowname.equals("file")) { this.inFile = true; } else if (lowname.equals("sweep")) { this.inSweep = true; } else if (lowname.equals("scantype")) { this.inScan_type = true; } else if (lowname.equals("color")) { this.inColor = true; } else if (lowname.equals("autoscale")) { this.inAutoscale = true; } else if (lowname.equals("minval")) { this.inMinval = true; } else if (lowname.equals("maxval")) { this.inMaxval = true; } else if (lowname.equals("zoomfactor")) { this.inZoom = true; } else if (lowname.equals("pan")) { this.inPan = true; } else if (lowname.equals("x")) { this.inX = true; } else if (lowname.equals("y")) { this.inY = true; } else if (lowname.equals("range")) { this.inRange = true; } else if (lowname.equals("ring")) { this.inRing = true; } else if (lowname.equals("rhiheight")) { this.inRhi_height = true; } else if (lowname.equals("comment")) { this.inComment = true; } else if (this.inComment) { //allow arbitrary tags within comments this.tmpComment.append("<").append(lowname); for (int i = 0; i < attribs.getLength(); ++i) { this.tmpComment.append(" ").append(attribs.getQName(i)).append("=\"").append(attribs.getValue(i)).append("\""); } this.tmpComment.append(">"); } } @Override public void characters(final char[] text, final int start, final int length) throws SAXException { String chars = new String(text, start, length); if (this.inCat) { this.tmpCat.append(chars); } else if (this.inName) { this.tmpName.append(chars); } else if (this.inUrl) { this.tmpUrl.append(chars); } else if (this.inDir) { this.tmpDir.append(chars); } else if (this.inFile) { this.tmpFile.append(chars); } else if (this.inSweep) { this.tmpSweep.append(chars); } else if (this.inScan_type) { this.tmpScan_type.append(chars); } else if (this.inColor) { if (this.inAutoscale) { this.tmpAutoscale.append(chars); } else if (this.inMinval) { this.tmpMinval.append(chars); } else if (this.inMaxval) { this.tmpMaxval.append(chars); } } else if (this.inZoom) { this.tmpZoom.append(chars); } else if (this.inPan) { if (this.inX) { this.tmpX.append(chars); } else if (this.inY) { this.tmpY.append(chars); } } else if (this.inRange) { this.tmpRange.append(chars); } else if (this.inRing) { this.tmpRing.append(chars); } else if (this.inRhi_height) { this.tmpRhi_height.append(chars); } else if (this.inComment) { this.tmpComment.append(chars); } } @Override public void endElement(final String namespaceURI, final String localName, final String qualifiedName) throws SAXException { String lowname = (qualifiedName.toLowerCase()); if (lowname.equals("bookmarks")) { //main element } else if (lowname.equals("bookmark")) { BookmarkControl bmc = BookmarkControl.getInstance(); bmc.addBookmark(this.prefix + this.tmpCat.toString(), this.tmpName.toString(), this.bookmark); this.tmpCat = new StringBuilder(); this.tmpName = new StringBuilder(); this.bookmark = new Bookmark(); this.zoom = 1.0; } else if (lowname.equals("category")) { this.inCat = false; } else if (lowname.equals("name")) { this.inName = false; } else if (lowname.equals("url")) { this.inUrl = false; this.bookmark.url = this.tmpUrl.toString(); this.tmpUrl = new StringBuilder(); } else if (lowname.equals("directory")) { this.inDir = false; this.bookmark.dir = this.tmpDir.toString(); this.tmpDir = new StringBuilder(); } else if (lowname.equals("file")) { this.inFile = false; this.bookmark.file = this.tmpFile.toString(); this.tmpFile = new StringBuilder(); } else if (lowname.equals("sweep")) { this.inSweep = false; String[] parts = this.tmpSweep.toString().split(" "); if (parts.length > 1 && parts[1].length() == 1) parts[1] = "0" + parts[1]; this.bookmark.sweep = parts.length > 2 ? this.tmpSweep.toString() : parts[0] + " " + parts[1]; this.tmpSweep = new StringBuilder(); } else if (lowname.equals("scantype")) { this.inScan_type = false; this.bookmark.scan_type = this.tmpScan_type.toString(); this.tmpScan_type = new StringBuilder(); } else if (lowname.equals("color")) { this.inColor = false; } else if (lowname.equals("autoscale")) { this.inAutoscale = false; } else if (lowname.equals("minval")) { this.inMinval = false; } else if (lowname.equals("maxval")) { this.inMaxval = false; } else if (lowname.equals("zoomfactor")) { this.inZoom = false; this.zoom = Double.parseDouble(this.tmpZoom.toString()); this.tmpZoom = new StringBuilder(); } else if (lowname.equals("x")) { this.inX = false; } else if (lowname.equals("y")) { this.inY = false; } else if (lowname.equals("pan")) { this.inPan = false; this.bookmark.x = Double.parseDouble(this.tmpX.toString()); this.tmpX = new StringBuilder(); this.bookmark.y = Double.parseDouble(this.tmpY.toString()); this.tmpY = new StringBuilder(); } else if (lowname.equals("range")) { this.inRange = false; this.bookmark.range = Double.parseDouble(this.tmpRange.toString()) / this.zoom; this.tmpRange = new StringBuilder(); } else if (lowname.equals("ring")) { this.inRing = false; this.bookmark.ring = this.tmpRing.toString(); this.tmpRing = new StringBuilder(); } else if (lowname.equals("rhiheight")) { this.inRhi_height = false; this.bookmark.rhi_height = this.tmpRhi_height.toString(); this.tmpRhi_height = new StringBuilder(); } else if (lowname.equals("comment")) { this.inComment = false; this.bookmark.comment = this.tmpComment.toString().trim(); this.tmpComment = new StringBuilder(); } else if (this.inComment) { //allow arbitrary tags within comments this.tmpComment.append("</").append(lowname).append(">"); } else { //scaling info this.setScale(qualifiedName); } } private void setScale(String type) //argument not final { if (sm.getScale(type) == null) { //not a (currently) known data type Moment tmp = Moment.translate(type); if (tmp != null) { //known old data type ChillMomentFieldScale scale = sm.getScale(tmp.ordinal()); if (scale != null) { type = scale.fieldName; //maps to this new type } } } Bookmark.Scale bmScale = new Bookmark.Scale(); bmScale.autoscale = Boolean.valueOf(this.tmpAutoscale.toString()).booleanValue(); this.tmpAutoscale = new StringBuilder(); String min = this.tmpMinval.toString(); try { Double.parseDouble(min); bmScale.minval = min; } catch (Exception e) { bmScale.minval = String.valueOf(Double.MIN_VALUE); } this.tmpMinval = new StringBuilder(); String max = this.tmpMaxval.toString(); try { Double.parseDouble(max); bmScale.maxval = max; } catch (Exception e) { bmScale.maxval = String.valueOf(Double.MAX_VALUE); } this.tmpMaxval = new StringBuilder(); this.bookmark.scale.put(type, bmScale); } //do nothing: @Override public void endDocument() { } @Override public void startPrefixMapping(final String prefix, final String uri) { } @Override public void endPrefixMapping(final String prefix) { } @Override public void ignorableWhitespace(final char[] text, final int start, final int length) throws SAXException { } @Override public void processingInstruction(final String target, final String data) { } @Override public void skippedEntity(final String name) { } @Override public void setDocumentLocator(final Locator locator) { } }