diff options
Diffstat (limited to 'src/com/google/wireless/gdata/spreadsheets/parser/xml')
6 files changed, 505 insertions, 0 deletions
diff --git a/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlCellsGDataParser.java b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlCellsGDataParser.java new file mode 100755 index 0000000..b64f76a --- /dev/null +++ b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlCellsGDataParser.java @@ -0,0 +1,126 @@ +// Copyright 2007 The Android Open Source Project +package com.google.wireless.gdata.spreadsheets.parser.xml; + +import com.google.wireless.gdata.data.Entry; +import com.google.wireless.gdata.data.Feed; +import com.google.wireless.gdata.data.StringUtils; +import com.google.wireless.gdata.data.XmlUtils; +import com.google.wireless.gdata.parser.ParseException; +import com.google.wireless.gdata.parser.xml.XmlGDataParser; +import com.google.wireless.gdata.spreadsheets.data.CellEntry; +import com.google.wireless.gdata.spreadsheets.data.CellFeed; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Parser for non-Atom data in a GData Spreadsheets Cell-based feed. + */ +public class XmlCellsGDataParser extends XmlGDataParser { + /** + * The rel ID used by the server to identify the URLs for Cell POSTs + * (updates) + */ + private static final String CELL_FEED_POST_REL = + "http://schemas.google.com/g/2005#post"; + + /** + * Creates a new XmlCellsGDataParser. + * + * @param is the stream from which to read the data + * @param xmlParser the XMLPullParser to use for parsing the raw XML + * @throws ParseException if the super-class throws one + */ + public XmlCellsGDataParser(InputStream is, XmlPullParser xmlParser) + throws ParseException { + super(is, xmlParser); + } + + /* (non-JavaDoc) + * Creates a new Entry that can handle the data parsed by this class. + */ + protected Entry createEntry() { + return new CellEntry(); + } + + /* (non-JavaDoc) + * Creates a new Feed that can handle the data parsed by this class. + */ + protected Feed createFeed() { + return new CellFeed(); + } + + /* (non-JavaDoc) + * Callback to handle non-Atom data present in an Atom entry tag. + */ + protected void handleExtraElementInEntry(Entry entry) + throws XmlPullParserException, IOException { + XmlPullParser parser = getParser(); + if (!(entry instanceof CellEntry)) { + throw new IllegalArgumentException("Expected CellEntry!"); + } + CellEntry row = (CellEntry) entry; + + String name = parser.getName(); + // cells can only have row, col, inputValue, & numericValue attrs + if ("cell".equals(name)) { + int count = parser.getAttributeCount(); + String attrName = null; + for (int i = 0; i < count; ++i) { + attrName = parser.getAttributeName(i); + if ("row".equals(attrName)) { + row.setRow(StringUtils.parseInt(parser + .getAttributeValue(i), 0)); + } else if ("col".equals(attrName)) { + row.setCol(StringUtils.parseInt(parser + .getAttributeValue(i), 0)); + } else if ("numericValue".equals(attrName)) { + row.setNumericValue(parser.getAttributeValue(i)); + } else if ("inputValue".equals(attrName)) { + row.setInputValue(parser.getAttributeValue(i)); + } + } + + // also need the data stored in the child text node + row.setValue(XmlUtils.extractChildText(parser)); + } + } + + /* (non-JavaDoc) + * Callback to handle non-Atom data in the feed. + */ + protected void handleExtraElementInFeed(Feed feed) + throws XmlPullParserException, IOException { + XmlPullParser parser = getParser(); + if (!(feed instanceof CellFeed)) { + throw new IllegalArgumentException("Expected CellFeed!"); + } + CellFeed cellFeed = (CellFeed) feed; + + String name = parser.getName(); + if (!"link".equals(name)) { + return; + } + + int numAttrs = parser.getAttributeCount(); + String rel = null; + String href = null; + String attrName = null; + for (int i = 0; i < numAttrs; ++i) { + attrName = parser.getAttributeName(i); + if ("rel".equals(attrName)) { + rel = parser.getAttributeValue(i); + } else if ("href".equals(attrName)) { + href = parser.getAttributeValue(i); + } + } + if (!(StringUtils.isEmpty(rel) || StringUtils.isEmpty(href))) { + if (CELL_FEED_POST_REL.equals(rel)) { + cellFeed.setEditUri(href); + } + } + } +} diff --git a/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlListGDataParser.java b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlListGDataParser.java new file mode 100755 index 0000000..b582ad9 --- /dev/null +++ b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlListGDataParser.java @@ -0,0 +1,109 @@ +// Copyright 2007 The Android Open Source Project +package com.google.wireless.gdata.spreadsheets.parser.xml; + +import com.google.wireless.gdata.data.Entry; +import com.google.wireless.gdata.data.Feed; +import com.google.wireless.gdata.data.StringUtils; +import com.google.wireless.gdata.data.XmlUtils; +import com.google.wireless.gdata.parser.ParseException; +import com.google.wireless.gdata.parser.xml.XmlGDataParser; +import com.google.wireless.gdata.spreadsheets.data.ListEntry; +import com.google.wireless.gdata.spreadsheets.data.ListFeed; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Parser for non-Atom data in a GData Spreadsheets List-based feed. + */ +public class XmlListGDataParser extends XmlGDataParser { + /** + * The rel ID used by the server to identify the URLs for List POSTs + * (updates) + */ + private static final String LIST_FEED_POST_REL = + "http://schemas.google.com/g/2005#post"; + + /** + * Creates a new XmlListGDataParser. + * + * @param is the stream from which to read the data + * @param xmlParser the XmlPullParser to use to parse the raw XML + * @throws ParseException if the super-class throws one + */ + public XmlListGDataParser(InputStream is, XmlPullParser xmlParser) + throws ParseException { + super(is, xmlParser); + } + + /* (non-JavaDoc) + * Creates a new Entry that can handle the data parsed by this class. + */ + protected Entry createEntry() { + return new ListEntry(); + } + + /* (non-JavaDoc) + * Creates a new Feed that can handle the data parsed by this class. + */ + protected Feed createFeed() { + return new ListFeed(); + } + + /* (non-JavaDoc) + * Callback to handle non-Atom data present in an Atom entry tag. + */ + protected void handleExtraElementInEntry(Entry entry) + throws XmlPullParserException, IOException { + XmlPullParser parser = getParser(); + if (!(entry instanceof ListEntry)) { + throw new IllegalArgumentException("Expected ListEntry!"); + } + ListEntry row = (ListEntry) entry; + + String name = parser.getName(); + row.setValue(name, XmlUtils.extractChildText(parser)); + } + + /* (non-JavaDoc) + * Callback to handle non-Atom data in the feed. + */ + protected void handleExtraElementInFeed(Feed feed) + throws XmlPullParserException, IOException { + XmlPullParser parser = getParser(); + if (!(feed instanceof ListFeed)) { + throw new IllegalArgumentException("Expected ListFeed!"); + } + ListFeed listFeed = (ListFeed) feed; + + String name = parser.getName(); + if (!"link".equals(name)) { + return; + } + + // lists store column data in the gsx namespace: + // <gsx:columnheader>data</gsx:columnheader> + // The columnheader tag names are the scrubbed values of the first row. + // We extract them all and store them as keys in a Map. + int numAttrs = parser.getAttributeCount(); + String rel = null; + String href = null; + String attrName = null; + for (int i = 0; i < numAttrs; ++i) { + attrName = parser.getAttributeName(i); + if ("rel".equals(attrName)) { + rel = parser.getAttributeValue(i); + } else if ("href".equals(attrName)) { + href = parser.getAttributeValue(i); + } + } + if (!(StringUtils.isEmpty(rel) || StringUtils.isEmpty(href))) { + if (LIST_FEED_POST_REL.equals(rel)) { + listFeed.setEditUri(href); + } + } + } +} diff --git a/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlSpreadsheetsGDataParser.java b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlSpreadsheetsGDataParser.java new file mode 100755 index 0000000..cb1094d --- /dev/null +++ b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlSpreadsheetsGDataParser.java @@ -0,0 +1,68 @@ +// Copyright 2007 The Android Open Source Project +package com.google.wireless.gdata.spreadsheets.parser.xml; + +import com.google.wireless.gdata.data.Entry; +import com.google.wireless.gdata.data.Feed; +import com.google.wireless.gdata.parser.ParseException; +import com.google.wireless.gdata.parser.xml.XmlGDataParser; +import com.google.wireless.gdata.spreadsheets.data.SpreadsheetEntry; +import com.google.wireless.gdata.spreadsheets.data.SpreadsheetFeed; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Parser helper for non-Atom data in a GData Spreadsheets meta-feed. + */ +public class XmlSpreadsheetsGDataParser extends XmlGDataParser { + /** + * The rel ID used by the server to identify the URLs for the worksheets + * feed + */ + protected static final String WORKSHEET_FEED_REL = + "http://schemas.google.com/spreadsheets/2006#worksheetsfeed"; + + /** + * Creates a new XmlSpreadsheetsGDataParser. + * + * @param is the stream from which to read the data + * @param xmlParser the XmlPullParser to use to parse the raw XML + * @throws ParseException if the super-class throws one + */ + public XmlSpreadsheetsGDataParser(InputStream is, XmlPullParser xmlParser) + throws ParseException { + super(is, xmlParser); + } + + /* (non-JavaDoc) + * Creates a new Entry that can handle the data parsed by this class. + */ + protected Entry createEntry() { + return new SpreadsheetEntry(); + } + + /* (non-JavaDoc) + * Creates a new Feed that can handle the data parsed by this class. + */ + protected Feed createFeed() { + return new SpreadsheetFeed(); + } + + /* (non-JavaDoc) + * Callback to handle link elements that are not recognized as Atom links. + * Used to pick out the link tag in a Spreadsheet's entry that corresponds + * to that spreadsheet's worksheets meta-feed. + */ + protected void handleExtraLinkInEntry(String rel, String type, String href, + Entry entry) throws XmlPullParserException, IOException { + super.handleExtraLinkInEntry(rel, type, href, entry); + if (WORKSHEET_FEED_REL.equals(rel) + && "application/atom+xml".equals(type)) { + SpreadsheetEntry sheet = (SpreadsheetEntry) entry; + sheet.setWorksheetFeedUri(href); + } + } +} diff --git a/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlSpreadsheetsGDataParserFactory.java b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlSpreadsheetsGDataParserFactory.java new file mode 100644 index 0000000..4feed62 --- /dev/null +++ b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlSpreadsheetsGDataParserFactory.java @@ -0,0 +1,99 @@ +// Copyright 2007 The Android Open Source Project +package com.google.wireless.gdata.spreadsheets.parser.xml; + +import com.google.wireless.gdata.client.GDataParserFactory; +import com.google.wireless.gdata.data.Entry; +import com.google.wireless.gdata.parser.GDataParser; +import com.google.wireless.gdata.parser.ParseException; +import com.google.wireless.gdata.parser.xml.XmlParserFactory; +import com.google.wireless.gdata.serializer.GDataSerializer; +import com.google.wireless.gdata.spreadsheets.data.CellEntry; +import com.google.wireless.gdata.spreadsheets.data.ListEntry; +import com.google.wireless.gdata.spreadsheets.data.SpreadsheetEntry; +import com.google.wireless.gdata.spreadsheets.data.WorksheetEntry; +import com.google.wireless.gdata.spreadsheets.serializer.xml.XmlCellEntryGDataSerializer; +import com.google.wireless.gdata.spreadsheets.serializer.xml.XmlListEntryGDataSerializer; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.InputStream; + +/** + * A GDataParserFactory capable of handling Spreadsheets. + */ +public class XmlSpreadsheetsGDataParserFactory implements GDataParserFactory { + /* + * @see GDataParserFactory + */ + public XmlSpreadsheetsGDataParserFactory(XmlParserFactory xmlFactory) { + this.xmlFactory = xmlFactory; + } + + /** Intentionally private. */ + private XmlSpreadsheetsGDataParserFactory() { + } + + /* + * Creates a parser for the indicated feed, assuming the default feed type. + * The default type is specified on {@link SpreadsheetsClient#DEFAULT_FEED}. + * + * @param is The stream containing the feed to be parsed. + * @return A GDataParser capable of parsing the feed as the default type. + * @throws ParseException if the feed could not be parsed for any reason + */ + public GDataParser createParser(InputStream is) throws ParseException { + // attempt a default + return createParser(SpreadsheetEntry.class, is); + } + + /* + * Creates a parser of the indicated type for the indicated feed. + * + * @param feedType The type of the feed; must be one of the constants on + * {@link SpreadsheetsClient}. + * @return A parser capable of parsing the feed as the indicated type. + * @throws ParseException if the feed could not be parsed for any reason + */ + public GDataParser createParser(Class entryClass, InputStream is) + throws ParseException { + try { + XmlPullParser xmlParser = xmlFactory.createParser(); + if (entryClass == SpreadsheetEntry.class) { + return new XmlSpreadsheetsGDataParser(is, xmlParser); + } else if (entryClass == WorksheetEntry.class) { + return new XmlWorksheetsGDataParser(is, xmlParser); + } else if (entryClass == CellEntry.class) { + return new XmlCellsGDataParser(is, xmlParser); + } else if (entryClass == ListEntry.class) { + return new XmlListGDataParser(is, xmlParser); + } else { + throw new ParseException("Unrecognized feed requested."); + } + } catch (XmlPullParserException e) { + throw new ParseException("Failed to create parser", e); + } + } + + /* + * Creates a serializer capable of handling the indicated entry. + * + * @param The Entry to be serialized to an XML string. + * @return A GDataSerializer capable of handling the indicated entry. + * @throws IllegalArgumentException if Entry is not a supported type (which + * currently includes only {@link ListEntry} and {@link CellEntry}.) + */ + public GDataSerializer createSerializer(Entry entry) { + if (entry instanceof ListEntry) { + return new XmlListEntryGDataSerializer(xmlFactory, entry); + } else if (entry instanceof CellEntry) { + return new XmlCellEntryGDataSerializer(xmlFactory, entry); + } else { + throw new IllegalArgumentException( + "Expected a ListEntry or CellEntry"); + } + } + + /** The XmlParserFactory to use to actually process XML streams. */ + private XmlParserFactory xmlFactory; +} diff --git a/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlWorksheetsGDataParser.java b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlWorksheetsGDataParser.java new file mode 100755 index 0000000..e9ceee5 --- /dev/null +++ b/src/com/google/wireless/gdata/spreadsheets/parser/xml/XmlWorksheetsGDataParser.java @@ -0,0 +1,98 @@ +// Copyright 2007 The Android Open Source Project +package com.google.wireless.gdata.spreadsheets.parser.xml; + +import com.google.wireless.gdata.data.Entry; +import com.google.wireless.gdata.data.Feed; +import com.google.wireless.gdata.data.StringUtils; +import com.google.wireless.gdata.data.XmlUtils; +import com.google.wireless.gdata.parser.ParseException; +import com.google.wireless.gdata.parser.xml.XmlGDataParser; +import com.google.wireless.gdata.spreadsheets.data.WorksheetEntry; +import com.google.wireless.gdata.spreadsheets.data.WorksheetFeed; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Parser helper for non-Atom data in a GData Spreadsheets Worksheets meta-feed. + */ +public class XmlWorksheetsGDataParser extends XmlGDataParser { + /** + * The rel ID used by the server to identify the cells feed for a worksheet + */ + protected static final String CELLS_FEED_REL = + "http://schemas.google.com/spreadsheets/2006#cellsfeed"; + + /** + * The rel ID used by the server to identify the list feed for a worksheet + */ + protected static final String LIST_FEED_REL = + "http://schemas.google.com/spreadsheets/2006#listfeed"; + + /** + * Creates a new XmlWorksheetsGDataParser. + * + * @param is the stream from which to read the data + * @param xmlParser the XmlPullParser to use to parse the raw XML + * @throws ParseException if the super-class throws one + */ + public XmlWorksheetsGDataParser(InputStream is, XmlPullParser xmlParser) + throws ParseException { + super(is, xmlParser); + } + + /* (non-JavaDoc) + * Creates a new Entry that can handle the data parsed by this class. + */ + protected Entry createEntry() { + return new WorksheetEntry(); + } + + /* (non-JavaDoc) + * Creates a new Feed that can handle the data parsed by this class. + */ + protected Feed createFeed() { + return new WorksheetFeed(); + } + + /* (non-JavaDoc) + * Callback to handle non-Atom data present in an Atom entry tag. + */ + protected void handleExtraElementInEntry(Entry entry) + throws XmlPullParserException, IOException { + XmlPullParser parser = getParser(); + if (!(entry instanceof WorksheetEntry)) { + throw new IllegalArgumentException("Expected WorksheetEntry!"); + } + WorksheetEntry worksheet = (WorksheetEntry) entry; + + // the only custom elements are rowCount and colCount + String name = parser.getName(); + if ("rowCount".equals(name)) { + worksheet.setRowCount(StringUtils.parseInt(XmlUtils + .extractChildText(parser), 0)); + } else if ("colCount".equals(name)) { + worksheet.setColCount(StringUtils.parseInt(XmlUtils + .extractChildText(parser), 0)); + } + } + + /* (non-JavaDoc) + * Callback to handle non-Atom links present in an Atom entry tag. Used to + * pick out a worksheet's cells and list feeds. + */ + protected void handleExtraLinkInEntry(String rel, String type, String href, + Entry entry) throws XmlPullParserException, IOException { + if (LIST_FEED_REL.equals(rel) && "application/atom+xml".equals(type)) { + WorksheetEntry sheet = (WorksheetEntry) entry; + sheet.setListFeedUri(href); + } else if (CELLS_FEED_REL.equals(rel) + && "application/atom+xml".equals(type)) { + WorksheetEntry sheet = (WorksheetEntry) entry; + sheet.setCellFeedUri(href); + } + } +} diff --git a/src/com/google/wireless/gdata/spreadsheets/parser/xml/package.html b/src/com/google/wireless/gdata/spreadsheets/parser/xml/package.html new file mode 100644 index 0000000..1c9bf9d --- /dev/null +++ b/src/com/google/wireless/gdata/spreadsheets/parser/xml/package.html @@ -0,0 +1,5 @@ +<html> +<body> + {@hide} +</body> +</html> |