/** * */ package org.commcare.android.javarosa; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Date; import org.commcare.android.database.SqlStorage; import org.commcare.android.database.user.models.User; import org.commcare.dalvik.application.CommCareApplication; import org.javarosa.core.log.StreamLogSerializer; import org.javarosa.core.model.utils.DateUtils; import org.kxml2.io.KXmlSerializer; import org.xmlpull.v1.XmlSerializer; import android.content.Context; /** * This class generates and serializes a device report to either a byte array * or to a file as designated by a log record * * @author ctsims * */ public class DeviceReportWriter { public static final String XMLNS = "http://code.javarosa.org/devicereport"; Context mContext; XmlSerializer serializer; ByteArrayOutputStream baos; OutputStream os; StreamLogSerializer logSerializer; ArrayList<DeviceReportElement> elements = new ArrayList<DeviceReportElement>(); public DeviceReportWriter(DeviceReportRecord record) throws IOException { this(record.openOutputStream()); } public DeviceReportWriter(OutputStream outputStream) throws IOException { os = outputStream; serializer = new KXmlSerializer(); serializer.setOutput(os, "UTF-8"); serializer.setPrefix("", XMLNS); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); } public void addReportElement(DeviceReportElement element) { this.elements.add(element); } public void write() throws IllegalArgumentException, IllegalStateException, IOException { try { serializer.startDocument("UTF-8", null); serializer.startTag(XMLNS, "device_report"); try { //All inner elements are supposed to catch their errors and wrap them, so we //can safely catch any of the processing issues try { writeHeader(); } catch(Exception e) { } try { writeUserReport(); } catch(Exception e) { } for(DeviceReportElement element : elements) { try { element.writeToDeviceReport(serializer); } catch(Exception e) { } } } catch(Exception e) { } finally { serializer.endTag(XMLNS, "device_report"); } serializer.endDocument(); } finally { //Close that stream! try { os.close(); } catch (IOException e) { //unclear whether "end" will close it for us on certain platforms, //so don't choke if it's already closed. } } } private void writeHeader() throws IllegalArgumentException, IllegalStateException, IOException { CommCareApplication application = CommCareApplication._(); String did = application.getPhoneId(); writeText("device_id", did); writeText("report_date", DateUtils.formatDateTime(new Date(), DateUtils.FORMAT_ISO8601)); writeText("app_version", application.getCurrentVersionString()); } private void writeUserReport() throws IllegalArgumentException, IllegalStateException, IOException { SqlStorage<User> storage = CommCareApplication._().getUserStorage(User.class); serializer.startTag(XMLNS, "user_subreport"); try{ for(User u : storage) { writeUser(u); } } finally { serializer.endTag(XMLNS, "user_subreport"); } } private void writeUser(User user) throws IllegalArgumentException, IllegalStateException, IOException { serializer.startTag(XMLNS, "user"); try{ writeText("username", user.getUsername()); writeText("user_id", user.getUniqueId()); writeText("sync_token", user.getSyncToken()); } finally { serializer.endTag(XMLNS, "user"); } } private void writeText(String element, String text) throws IllegalArgumentException, IllegalStateException, IOException { serializer.startTag(XMLNS,element); try { serializer.text(text); } catch(Exception e) { e.printStackTrace(); } finally { serializer.endTag(XMLNS,element); } } }