/*
* Copyright (C) 2010 Prasanta Paul, http://prasanta-paul.blogspot.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pras;
import java.util.ArrayList;
import java.util.HashMap;
import com.pras.conn.HttpConHandler;
import com.pras.conn.Response;
import com.pras.sp.Entry;
import com.pras.sp.Feed;
import com.pras.sp.ParseFeed;
import com.pras.table.Table;
/**
* This class represents a given Spreadsheet. You can add multiple WorkSheets into a Spreadsheet.
* It provides methods to Add/Retrieve/Delete WorkSheet and Share SpreadSheet.
*
* API Ref:
* http://code.google.com/apis/spreadsheets/data/3.0/developers_guide.html
*
* Feed Ref:
*
* http://code.google.com/apis/documents/docs/3.0/reference.html
*
*
* NOTE:
* Resource ID is required to delete a SpreadSheet
*
* @author Prasanta Paul
*/
public class SpreadSheet {
/*
* How to get Resource_ID ?
* From SpreadSheet Feed (SpreadSheet List) read the "key" of the following field
*
*/
private String TAG = "SpreadSheet";
/**
* This will contain info specific to SpreadSheet and not about its
* WorkSheets
*/
Entry entry;
ArrayList wks = new ArrayList();
/**
* List of People with whom this SpreadSheet is shared and their
* access rights (ACL)
*/
ArrayList collaborators = new ArrayList();
@Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(obj instanceof SpreadSheet){
SpreadSheet s = (SpreadSheet) obj;
if(this.hashCode() == s.hashCode())
return true;
}
return false;
//return super.equals(obj);
}
@Override
public int hashCode() {
/*
* ResID will be unique for each SpreadSheet
* e.g.
* spreadsheet:0Asn_4k-vXoTXdHhVcUIyeDZwV3VWREdMZll5RTJTMmc
*/
if(entry != null){
return entry.getResID().hashCode();
}
return super.hashCode();
}
public SpreadSheet(Entry entry){
this.entry = entry;
}
/**
* Get Entry Object of SpreadSheet Feed. Entry holds all SpreadSheet Feed details
*
* @return
*/
public Entry getEntry() {
return entry;
}
/**
* Set Entry Object of SpreadSheet Feed.
* @param entry
*/
public void setEntry(Entry entry) {
this.entry = entry;
}
/**
* Get SpreadSheet Title
* @return
*/
public String getTitle(){
if(entry != null)
return entry.getTitle();
return null;
}
/**
* Get SpreadSheet Resource ID. Each SpreadSheet has an unique Resource ID.
* This ID is required to Delete this SpreadSheet.
*
* @return
*/
public String getResourceID(){
if(entry != null)
return entry.getResID();
return null;
}
/**
* Get SpreadSheet Feed Key
* @return
*/
public String getKey(){
if(entry != null)
return entry.getKey();
return null;
}
/**
* Get the list of all Collaborator details (users/groups and their access rights) for a given SpreadSheet
*
* @return
*/
public ArrayList getCollaborators() {
return collaborators;
}
/**
* Add a Collaborator
* @param c
*/
public void addCollaborator(Collaborator c){
collaborators.add(c);
}
/**
* Clear existing list of Collaborators
*/
public void clearCollaboratorList(){
collaborators.clear();
}
/**
* Set a list of Collaborators
* @param collaborators
*/
public void setCollaborators(ArrayList collaborators) {
this.collaborators = collaborators;
}
/**
* This will create an WorkSheet without Table. It will create WorkSheet with 1 Column and 1 Row. It can
* be accessed/modified by Web Interface.
*
* IMPORTANT:
* This Library supports Record Handling only through Table. If you use this method, it will not
* create Table internally and thus unable to add/edit/delete record from this WorkSheet. Instead,
* use addWorkSheet(String name, String[] cols)
*
* @param name WorkSheet name
*/
public void addWorkSheet(String name){
if(name == null){
throw new IllegalAccessError("Please provide WorkSheet Name");
}
addWorkSheet(name, 1, 1);
}
/**
* Create WorkSheet.
*
* @param name name of WorkSheet
* @param col number of columns
* @param row number of rows
*/
private WorkSheet addWorkSheet(String name, int col, int row){
// Sample URL: https://spreadsheets.google.com/feeds/worksheets/key/private/full
String workSheetURL = "https://spreadsheets.google.com/feeds/worksheets/"+ entry.getKey() +"/private/full";
// Add headers
HashMap httpHeaders = new HashMap();
httpHeaders.put(HttpConHandler.AUTHORIZATION_HTTP_HEADER, "GoogleLogin auth="+ SpreadSheetFactory.authToken);
httpHeaders.put(HttpConHandler.GDATA_VERSION_HTTP_HEADER, "3.0");
httpHeaders.put(HttpConHandler.CONTENT_TYPE_HTTP_HEADER, "application/atom+xml");
String postData = ""+
""+ name +""+
""+ row +""+
""+ col +""+
"";
Log.p(TAG, "POST Data- "+ postData);
HttpConHandler http = new HttpConHandler();
Response resp = http.doConnect(workSheetURL, HttpConHandler.HTTP_POST, httpHeaders, postData);
if(resp == null)
return null;
// Create WorkSheet instance from the response
return parseWorkSheet(resp.getOutput());
}
private WorkSheet parseWorkSheet(String xmlFeed)
{
if(xmlFeed == null)
return null;
// XML Parsing
ParseFeed pf = new ParseFeed();
Feed f = pf.parse(xmlFeed.getBytes());
ArrayList entries = f.getEntries();
if(entries == null || entries.size() == 0){
return null;
}
WorkSheet ws = new WorkSheet();
for(int i=0; i
* It will create a Table for this WorkSheet. WorkSheet and Table Name will be the same
* The Table will be used for Add/Edit/Delete Records
*
*
* @param name Name of the WorkSheet
* @param description Description of the WorkSheet
* @param row Number of Rows
* @param cols Name of Columns
*/
public void addWorkSheet(String name, String description, int row, String[] cols){
if(name == null || description == null || cols == null){
throw new IllegalAccessError("Please provide correct input parameters");
}
int col = cols.length;
addWorkSheet(name, col, row);
// Create a Table for this WorkSheet
String tableCreateXML = ""+
""+ name +""+ // Table name will be same as WorkSheet Name
""+ description +""+
""+
""+
"";
for(int i=0; i");
}
tableCreateXML = tableCreateXML.concat("");
// Add headers
HashMap httpHeaders = new HashMap();
httpHeaders.put(HttpConHandler.AUTHORIZATION_HTTP_HEADER, "GoogleLogin auth="+ SpreadSheetFactory.authToken);
httpHeaders.put(HttpConHandler.GDATA_VERSION_HTTP_HEADER, "3.0");
httpHeaders.put(HttpConHandler.CONTENT_TYPE_HTTP_HEADER, "application/atom+xml");
// HTTP Connection
String tableURL = "https://spreadsheets.google.com/feeds/"+ entry.getKey() +"/tables";
HttpConHandler http = new HttpConHandler();
http.doConnect(tableURL, HttpConHandler.HTTP_POST, httpHeaders, tableCreateXML);
}
/**
* Create List feed based WorkSheet
*
* @param name Name of the WorkSheet
* @param rowCount Number of row. This doesn't limit future row addition.
* @param cols Array of column name. First row of the WorkSheet is header row.
*
* @return
*/
public WorkSheet addListWorkSheet(String name, int rowCount, String[] cols){
if(name == null || cols == null){
throw new IllegalAccessError("Please provide correct input parameters");
}
/*
* Steps-
* 1. Create an empty Worksheet with specified number of Rows and Columns
* 2. Create the Header Row
*/
// Create the
Log.p(TAG, "## Create WorkSheet...");
WorkSheet workSheet = addWorkSheet(name, cols.length, rowCount);
if(workSheet == null)
return null;
workSheet.setColumns(cols);
// 2. Create Header Row
// Add headers
HashMap httpHeaders = new HashMap();
httpHeaders.put(HttpConHandler.AUTHORIZATION_HTTP_HEADER, "GoogleLogin auth="+ SpreadSheetFactory.authToken);
httpHeaders.put(HttpConHandler.GDATA_VERSION_HTTP_HEADER, "3.0");
httpHeaders.put(HttpConHandler.CONTENT_TYPE_HTTP_HEADER, "application/atom+xml");
// Ignore updates done by other on the Header Row
httpHeaders.put("If-Match", "*");
// XML to Add HEADER ROW
StringBuffer cellUpdateXML = new StringBuffer();
// Batch Cell Update
// XML- Batch query for multiple Cell Update
cellUpdateXML.append("");
cellUpdateXML.append("https://spreadsheets.google.com/feeds/cells/"+ entry.getKey() +"/"+ workSheet.getWorkSheetID() +"/private/full");
for(int i=0; i");
cellUpdateXML.append("B"+ i +"");
cellUpdateXML.append("");
cellUpdateXML.append("https://spreadsheets.google.com/feeds/cells/"+ entry.getKey() + "/"+ workSheet.getWorkSheetID() +"/private/full/R1C"+ (i+1) +"");
cellUpdateXML.append("");
cellUpdateXML.append("");
cellUpdateXML.append("");
}
cellUpdateXML.append("");
// Do Server transaction
String headerRowUpdateUrl = "https://spreadsheets.google.com/feeds/cells/"+ entry.getKey() + "/"+ workSheet.getWorkSheetID() +"/private/full/batch";
new HttpConHandler().doConnect(headerRowUpdateUrl, HttpConHandler.HTTP_POST, httpHeaders, cellUpdateXML.toString());
return workSheet;
}
/**
* It will retrieve all WorkSheets of this SpreadSheet from Server
*
* @return
*/
public ArrayList getAllWorkSheets(){
return getAllWorkSheets(true);
}
/**
* It will retrieve all WorkSheets of this SpreadSheet either from Server or from Local Cache
*
* @param doRefresh Do you want to Synch with Server ?
* @return list of available WorkSheets
*/
public ArrayList getAllWorkSheets(boolean doRefresh){
return getAllWorkSheets(doRefresh, null, false);
}
/**
* It will retrieve WorkSheets with matching title from Server
*
* @param title SpreadSheet title. null means all SpreadSheets. No need to do URL encode.
* @param isTitleExact whether title string should be an exact match
* @return
*/
public ArrayList getWorkSheet(String title, boolean isTitleExact){
return getAllWorkSheets(true, title, isTitleExact);
}
/**
* It will retrieve WorkSheets with matching title either from Server or from Local Cache
*
* @param doRefresh Do you want to Synch with Server ?
* @param title SpreadSheet title. null means all SpreadSheets. No need to do URL encode.
* @param isTitleExact Whether title string should be an exact match
* @return list of available WorkSheets
*/
public ArrayList getAllWorkSheets(boolean doRefresh, String title, boolean isTitleExact){
// Sample URL: https://spreadsheets.google.com/feeds/worksheets/key/private/full
/*
* TODO:
* Check with other projection values instead of "private" and "full"
* private - unpublished work sheets
* public- published work sheets
*/
if(!doRefresh){
// Don't synch with Server
return wks;
}
String workSheetListURL = "https://spreadsheets.google.com/feeds/worksheets/"+ entry.getKey() +"/private/full";
if(title != null){
// WorkSheet Query Parameters
workSheetListURL = workSheetListURL.concat("?title="+ HttpConHandler.encode(title));
workSheetListURL = workSheetListURL.concat("&title-exact="+ isTitleExact);
}
// Add Headers
HashMap httpHeaders = new HashMap();
httpHeaders.put(HttpConHandler.AUTHORIZATION_HTTP_HEADER, "GoogleLogin auth="+ SpreadSheetFactory.authToken);
httpHeaders.put(HttpConHandler.GDATA_VERSION_HTTP_HEADER, "3.0");
HttpConHandler http = new HttpConHandler();
Response res = http.doConnect(workSheetListURL, HttpConHandler.HTTP_GET, httpHeaders, null);
if(res.isError()){
return null;
}
String xmlOut = res.getOutput();
// XML Parsing
ParseFeed pf = new ParseFeed();
Feed f = pf.parse(xmlOut.getBytes());
ArrayList entries = f.getEntries();
HashMap tables = null;
if(entries != null && entries.size() > 0){
// Fetch Table details of each Work Sheet
Log.p(TAG, "Get Table Feed");
tables = getTables(title, isTitleExact);
}else{
//No WorkSheet exists
return null;
}
// clear existing entries
wks.clear();
for(int i=0; i httpHeaders = new HashMap();
httpHeaders.put(HttpConHandler.AUTHORIZATION_HTTP_HEADER, "GoogleLogin auth="+ SpreadSheetFactory.authToken);
httpHeaders.put(HttpConHandler.GDATA_VERSION_HTTP_HEADER, "3.0");
HttpConHandler http = new HttpConHandler();
Response res = http.doConnect(headerRowURL, HttpConHandler.HTTP_GET, httpHeaders, null);
if(res.isError()){
return null;
}
String xmlOut = res.getOutput();
// XML Parsing
ParseFeed pf = new ParseFeed();
Feed f = pf.parse(xmlOut.getBytes());
ArrayList entries = f.getEntries();
if(entries == null)
return null;
String[] cols = new String[entries.size()];
for(int i=0; inull means all SpreadSheets. No need to do URL encode.
* @param isTitleExact whether title string should be an exact match
*
* @return
*/
private HashMap getTables(String title, boolean isTitleExact){
//Get list of all Tables- one per WorkSheet
HashMap tables = new HashMap();
// Table URL- Get list of all Tables- one per WorkSheet
String tableURL = "https://spreadsheets.google.com/feeds/"+ entry.getKey() +"/tables";
if(title != null){
tableURL = tableURL.concat("?title="+ HttpConHandler.encode(title));
tableURL = tableURL.concat("&title-exact="+ isTitleExact);
}
// Add Headers
HashMap httpHeaders = new HashMap();
httpHeaders.put(HttpConHandler.AUTHORIZATION_HTTP_HEADER, "GoogleLogin auth="+ SpreadSheetFactory.authToken);
httpHeaders.put(HttpConHandler.GDATA_VERSION_HTTP_HEADER, "3.0");
HttpConHandler http = new HttpConHandler();
Response res = http.doConnect(tableURL, HttpConHandler.HTTP_GET, httpHeaders, null);
if(res.isError()){
return null;
}
String xmlOut = res.getOutput();
// XML Parsing
ParseFeed pf = new ParseFeed();
Feed f = pf.parse(xmlOut.getBytes());
ArrayList entries = f.getEntries();
if(entries == null) // No Table exists for this WorkSheet/SpreadSheet
return null;
for(int i=0; i