/* * Copyright (C) 2008 The Android Open Source Project * * 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 android.content; import android.net.Uri; import android.util.Xml; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; import java.io.IOException; import java.io.InputStream; import java.util.Stack; /** * Inserts default data from InputStream, should be in XML format. * If the provider syncs data to the server, the imported data will be synced to the server. *

Samples:

*
* Insert one row: *
 * <row uri="content://contacts/people">
 *  <Col column = "name" value = "foo feebe "/>
 *  <Col column = "addr" value = "Tx"/>
 * </row>
*
* Delete, it must be in order of uri, select, and arg: *
 * <del uri="content://contacts/people" select="name=? and addr=?" 
 *  arg1 = "foo feebe" arg2 ="Tx"/>
*
* Use first row's uri to insert into another table, * content://contacts/people/1/phones: *
 * <row uri="content://contacts/people">
 *  <col column = "name" value = "foo feebe"/>
 *  <col column = "addr" value = "Tx"/>
 *  <row postfix="phones">
 *    <col column="number" value="512-514-6535"/>
 *  </row>
 *  <row postfix="phones">
 *    <col column="cell" value="512-514-6535"/>
 *  </row>  
 * </row>
*
* Insert multiple rows in to same table and same attributes: *
 * <row uri="content://contacts/people" >
 *  <row>
 *   <col column= "name" value = "foo feebe"/>
 *   <col column= "addr" value = "Tx"/>
 *  </row>
 *  <row>
 *  </row>
 * </row>
* * @hide */ public class DefaultDataHandler implements ContentInsertHandler { private final static String ROW = "row"; private final static String COL = "col"; private final static String URI_STR = "uri"; private final static String POSTFIX = "postfix"; private final static String DEL = "del"; private final static String SELECT = "select"; private final static String ARG = "arg"; private Stack mUris = new Stack(); private ContentValues mValues; private ContentResolver mContentResolver; public void insert(ContentResolver contentResolver, InputStream in) throws IOException, SAXException { mContentResolver = contentResolver; Xml.parse(in, Xml.Encoding.UTF_8, this); } public void insert(ContentResolver contentResolver, String in) throws SAXException { mContentResolver = contentResolver; Xml.parse(in, this); } private void parseRow(Attributes atts) throws SAXException { String uriStr = atts.getValue(URI_STR); Uri uri; if (uriStr != null) { // case 1 uri = Uri.parse(uriStr); if (uri == null) { throw new SAXException("attribute " + atts.getValue(URI_STR) + " parsing failure"); } } else if (mUris.size() > 0){ // case 2 String postfix = atts.getValue(POSTFIX); if (postfix != null) { uri = Uri.withAppendedPath(mUris.lastElement(), postfix); } else { uri = mUris.lastElement(); } } else { throw new SAXException("attribute parsing failure"); } mUris.push(uri); } private Uri insertRow() { Uri u = mContentResolver.insert(mUris.lastElement(), mValues); mValues = null; return u; } public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException { if (ROW.equals(localName)) { if (mValues != null) { // case 2, before insert last uri if (mUris.empty()) { throw new SAXException("uri is empty"); } Uri nextUri = insertRow(); if (nextUri == null) { throw new SAXException("insert to uri " + mUris.lastElement().toString() + " failure"); } else { // make sure the stack lastElement save uri for more than one row mUris.pop(); mUris.push(nextUri); parseRow(atts); } } else { int attrLen = atts.getLength(); if (attrLen == 0) { // case 3, share same uri as last level mUris.push(mUris.lastElement()); } else { parseRow(atts); } } } else if (COL.equals(localName)) { int attrLen = atts.getLength(); if (attrLen != 2) { throw new SAXException("illegal attributes number " + attrLen); } String key = atts.getValue(0); String value = atts.getValue(1); if (key != null && key.length() > 0 && value != null && value.length() > 0) { if (mValues == null) { mValues = new ContentValues(); } mValues.put(key, value); } else { throw new SAXException("illegal attributes value"); } } else if (DEL.equals(localName)){ Uri u = Uri.parse(atts.getValue(URI_STR)); if (u == null) { throw new SAXException("attribute " + atts.getValue(URI_STR) + " parsing failure"); } int attrLen = atts.getLength() - 2; if (attrLen > 0) { String[] selectionArgs = new String[attrLen]; for (int i = 0; i < attrLen; i++) { selectionArgs[i] = atts.getValue(i+2); } mContentResolver.delete(u, atts.getValue(1), selectionArgs); } else if (attrLen == 0){ mContentResolver.delete(u, atts.getValue(1), null); } else { mContentResolver.delete(u, null, null); } } else { throw new SAXException("unknown element: " + localName); } } public void endElement(String uri, String localName, String name) throws SAXException { if (ROW.equals(localName)) { if (mUris.empty()) { throw new SAXException("uri mismatch"); } if (mValues != null) { insertRow(); } mUris.pop(); } } public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub } public void endDocument() throws SAXException { // TODO Auto-generated method stub } public void endPrefixMapping(String prefix) throws SAXException { // TODO Auto-generated method stub } public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub } public void processingInstruction(String target, String data) throws SAXException { // TODO Auto-generated method stub } public void setDocumentLocator(Locator locator) { // TODO Auto-generated method stub } public void skippedEntity(String name) throws SAXException { // TODO Auto-generated method stub } public void startDocument() throws SAXException { // TODO Auto-generated method stub } public void startPrefixMapping(String prefix, String uri) throws SAXException { // TODO Auto-generated method stub } }