/* * 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