1 /******************************************************************************* 2 * This file is part of BOINC. 3 * http://boinc.berkeley.edu 4 * Copyright (C) 2012 University of California 5 * 6 * BOINC is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU Lesser General Public License 8 * as published by the Free Software Foundation, 9 * either version 3 of the License, or (at your option) any later version. 10 * 11 * BOINC is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 * See the GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with BOINC. If not, see <http://www.gnu.org/licenses/>. 18 ******************************************************************************/ 19 20 package edu.berkeley.boinc.rpc; 21 22 import java.util.ArrayList; 23 24 import org.xml.sax.Attributes; 25 import org.xml.sax.SAXException; 26 import org.xml.sax.helpers.DefaultHandler; 27 import android.util.Xml; 28 29 30 public class AppVersionsParser extends DefaultHandler { 31 32 private ArrayList<AppVersion> mAppVersions = new ArrayList<AppVersion>(); 33 private AppVersion mAppVersion = null; 34 private StringBuilder mCurrentElement = new StringBuilder(); 35 36 getAppVersions()37 public final ArrayList<AppVersion> getAppVersions() { 38 return mAppVersions; 39 } 40 41 /** 42 * Parse the RPC result (app_version) and generate corresponding vector 43 * @param rpcResult String returned by RPC call of core client 44 * @return vector of application version 45 */ parse(String rpcResult)46 public static ArrayList<AppVersion> parse(String rpcResult) { 47 try { 48 AppVersionsParser parser = new AppVersionsParser(); 49 Xml.parse(rpcResult, parser); 50 return parser.getAppVersions(); 51 } 52 catch (SAXException e) { 53 return null; 54 } 55 } 56 57 @Override startElement(String uri, String localName, String qName, Attributes attributes)58 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 59 super.startElement(uri, localName, qName, attributes); 60 if (localName.equalsIgnoreCase("app_version")) { 61 mAppVersion = new AppVersion(); 62 } 63 } 64 65 @Override characters(char[] ch, int start, int length)66 public void characters(char[] ch, int start, int length) throws SAXException { 67 super.characters(ch, start, length); 68 // put it into StringBuilder 69 int myStart = start; 70 int myLength = length; 71 if (mCurrentElement.length() == 0) { 72 // still empty - trim leading white-spaces 73 for ( ; myStart < length; ++myStart, --myLength) { 74 if (!Character.isWhitespace(ch[myStart])) { 75 // First non-white-space character 76 break; 77 } 78 } 79 } 80 mCurrentElement.append(ch, myStart, myLength); 81 } 82 83 @Override endElement(String uri, String localName, String qName)84 public void endElement(String uri, String localName, String qName) throws SAXException { 85 super.endElement(uri, localName, qName); 86 try { 87 trimEnd(); 88 if (mAppVersion != null) { 89 // We are inside <app_version> 90 if (localName.equalsIgnoreCase("app_version")) { 91 // Closing tag of <app_version> - add to vector and be ready for next one 92 if (!mAppVersion.app_name.equals("")) { 93 // app_name is a must 94 mAppVersions.add(mAppVersion); 95 } 96 mAppVersion = null; 97 } 98 else { 99 // Not the closing tag - we decode possible inner tags 100 if (localName.equalsIgnoreCase("app_name")) { 101 mAppVersion.app_name = mCurrentElement.toString(); 102 } 103 else if (localName.equalsIgnoreCase("version_num")) { 104 mAppVersion.version_num = Integer.parseInt(mCurrentElement.toString()); 105 } 106 } 107 } 108 } 109 catch (NumberFormatException e) { 110 } 111 mCurrentElement.setLength(0); // to be clean for next one 112 } 113 trimEnd()114 private void trimEnd() { 115 int length = mCurrentElement.length(); 116 int i; 117 // Trim trailing spaces 118 for (i = length - 1; i >= 0; --i) { 119 if (!Character.isWhitespace(mCurrentElement.charAt(i))) { 120 // All trailing white-spaces are skipped, i is position of last character 121 break; 122 } 123 } 124 // i is position of last character 125 mCurrentElement.setLength(i+1); 126 } 127 } 128