blob: 863c9f6f144dfcf1b7f3e5d31d0fd07ba952a659 [file] [log] [blame]
Alan Viverette3da604b2020-06-10 18:34:39 +00001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content;
18
19import android.net.Uri;
20import android.util.Xml;
21
22import org.xml.sax.Attributes;
23import org.xml.sax.Locator;
24import org.xml.sax.SAXException;
25
26import java.io.IOException;
27import java.io.InputStream;
28import java.util.Stack;
29
30/**
31 * Inserts default data from InputStream, should be in XML format.
32 * If the provider syncs data to the server, the imported data will be synced to the server.
33 * <p>Samples:</p>
34 * <br/>
35 * Insert one row:
36 * <pre>
37 * &lt;row uri="content://contacts/people">
38 * &lt;Col column = "name" value = "foo feebe "/>
39 * &lt;Col column = "addr" value = "Tx"/>
40 * &lt;/row></pre>
41 * <br/>
42 * Delete, it must be in order of uri, select, and arg:
43 * <pre>
44 * &lt;del uri="content://contacts/people" select="name=? and addr=?"
45 * arg1 = "foo feebe" arg2 ="Tx"/></pre>
46 * <br/>
47 * Use first row's uri to insert into another table,
48 * content://contacts/people/1/phones:
49 * <pre>
50 * &lt;row uri="content://contacts/people">
51 * &lt;col column = "name" value = "foo feebe"/>
52 * &lt;col column = "addr" value = "Tx"/>
53 * &lt;row postfix="phones">
54 * &lt;col column="number" value="512-514-6535"/>
55 * &lt;/row>
56 * &lt;row postfix="phones">
57 * &lt;col column="cell" value="512-514-6535"/>
58 * &lt;/row>
59 * &lt;/row></pre>
60 * <br/>
61 * Insert multiple rows in to same table and same attributes:
62 * <pre>
63 * &lt;row uri="content://contacts/people" >
64 * &lt;row>
65 * &lt;col column= "name" value = "foo feebe"/>
66 * &lt;col column= "addr" value = "Tx"/>
67 * &lt;/row>
68 * &lt;row>
69 * &lt;/row>
70 * &lt;/row></pre>
71 *
72 * @hide
73 */
74public class DefaultDataHandler implements ContentInsertHandler {
75 private final static String ROW = "row";
76 private final static String COL = "col";
77 private final static String URI_STR = "uri";
78 private final static String POSTFIX = "postfix";
79 private final static String DEL = "del";
80 private final static String SELECT = "select";
81 private final static String ARG = "arg";
82
83 private Stack<Uri> mUris = new Stack<Uri>();
84 private ContentValues mValues;
85 private ContentResolver mContentResolver;
86
87 public void insert(ContentResolver contentResolver, InputStream in)
88 throws IOException, SAXException {
89 mContentResolver = contentResolver;
90 Xml.parse(in, Xml.Encoding.UTF_8, this);
91 }
92
93 public void insert(ContentResolver contentResolver, String in)
94 throws SAXException {
95 mContentResolver = contentResolver;
96 Xml.parse(in, this);
97 }
98
99 private void parseRow(Attributes atts) throws SAXException {
100 String uriStr = atts.getValue(URI_STR);
101 Uri uri;
102 if (uriStr != null) {
103 // case 1
104 uri = Uri.parse(uriStr);
105 if (uri == null) {
106 throw new SAXException("attribute " +
107 atts.getValue(URI_STR) + " parsing failure");
108 }
109
110 } else if (mUris.size() > 0){
111 // case 2
112 String postfix = atts.getValue(POSTFIX);
113 if (postfix != null) {
114 uri = Uri.withAppendedPath(mUris.lastElement(),
115 postfix);
116 } else {
117 uri = mUris.lastElement();
118 }
119 } else {
120 throw new SAXException("attribute parsing failure");
121 }
122
123 mUris.push(uri);
124
125 }
126
127 private Uri insertRow() {
128 Uri u = mContentResolver.insert(mUris.lastElement(), mValues);
129 mValues = null;
130 return u;
131 }
132
133 public void startElement(String uri, String localName, String name,
134 Attributes atts) throws SAXException {
135 if (ROW.equals(localName)) {
136 if (mValues != null) {
137 // case 2, <Col> before <Row> insert last uri
138 if (mUris.empty()) {
139 throw new SAXException("uri is empty");
140 }
141 Uri nextUri = insertRow();
142 if (nextUri == null) {
143 throw new SAXException("insert to uri " +
144 mUris.lastElement().toString() + " failure");
145 } else {
146 // make sure the stack lastElement save uri for more than one row
147 mUris.pop();
148 mUris.push(nextUri);
149 parseRow(atts);
150 }
151 } else {
152 int attrLen = atts.getLength();
153 if (attrLen == 0) {
154 // case 3, share same uri as last level
155 mUris.push(mUris.lastElement());
156 } else {
157 parseRow(atts);
158 }
159 }
160 } else if (COL.equals(localName)) {
161 int attrLen = atts.getLength();
162 if (attrLen != 2) {
163 throw new SAXException("illegal attributes number " + attrLen);
164 }
165 String key = atts.getValue(0);
166 String value = atts.getValue(1);
167 if (key != null && key.length() > 0 && value != null && value.length() > 0) {
168 if (mValues == null) {
169 mValues = new ContentValues();
170 }
171 mValues.put(key, value);
172 } else {
173 throw new SAXException("illegal attributes value");
174 }
175 } else if (DEL.equals(localName)){
176 Uri u = Uri.parse(atts.getValue(URI_STR));
177 if (u == null) {
178 throw new SAXException("attribute " +
179 atts.getValue(URI_STR) + " parsing failure");
180 }
181 int attrLen = atts.getLength() - 2;
182 if (attrLen > 0) {
183 String[] selectionArgs = new String[attrLen];
184 for (int i = 0; i < attrLen; i++) {
185 selectionArgs[i] = atts.getValue(i+2);
186 }
187 mContentResolver.delete(u, atts.getValue(1), selectionArgs);
188 } else if (attrLen == 0){
189 mContentResolver.delete(u, atts.getValue(1), null);
190 } else {
191 mContentResolver.delete(u, null, null);
192 }
193
194 } else {
195 throw new SAXException("unknown element: " + localName);
196 }
197 }
198
199 public void endElement(String uri, String localName, String name)
200 throws SAXException {
201 if (ROW.equals(localName)) {
202 if (mUris.empty()) {
203 throw new SAXException("uri mismatch");
204 }
205 if (mValues != null) {
206 insertRow();
207 }
208 mUris.pop();
209 }
210 }
211
212
213 public void characters(char[] ch, int start, int length)
214 throws SAXException {
215 // TODO Auto-generated method stub
216
217 }
218
219 public void endDocument() throws SAXException {
220 // TODO Auto-generated method stub
221
222 }
223
224 public void endPrefixMapping(String prefix) throws SAXException {
225 // TODO Auto-generated method stub
226
227 }
228
229 public void ignorableWhitespace(char[] ch, int start, int length)
230 throws SAXException {
231 // TODO Auto-generated method stub
232
233 }
234
235 public void processingInstruction(String target, String data)
236 throws SAXException {
237 // TODO Auto-generated method stub
238
239 }
240
241 public void setDocumentLocator(Locator locator) {
242 // TODO Auto-generated method stub
243
244 }
245
246 public void skippedEntity(String name) throws SAXException {
247 // TODO Auto-generated method stub
248
249 }
250
251 public void startDocument() throws SAXException {
252 // TODO Auto-generated method stub
253
254 }
255
256 public void startPrefixMapping(String prefix, String uri)
257 throws SAXException {
258 // TODO Auto-generated method stub
259
260 }
261
262}