• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
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  
17  package android.content;
18  
19  import android.net.Uri;
20  import android.util.Xml;
21  
22  import org.xml.sax.Attributes;
23  import org.xml.sax.Locator;
24  import org.xml.sax.SAXException;
25  
26  import java.io.IOException;
27  import java.io.InputStream;
28  import 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   */
74  public 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  
insert(ContentResolver contentResolver, InputStream in)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  
insert(ContentResolver contentResolver, String in)93      public void insert(ContentResolver contentResolver, String in)
94          throws SAXException {
95          mContentResolver = contentResolver;
96          Xml.parse(in, this);
97      }
98  
parseRow(Attributes atts)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  
insertRow()127      private Uri insertRow() {
128          Uri u = mContentResolver.insert(mUris.lastElement(), mValues);
129          mValues = null;
130          return u;
131      }
132  
startElement(String uri, String localName, String name, Attributes atts)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  
endElement(String uri, String localName, String name)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  
characters(char[] ch, int start, int length)213      public void characters(char[] ch, int start, int length)
214              throws SAXException {
215          // TODO Auto-generated method stub
216  
217      }
218  
endDocument()219      public void endDocument() throws SAXException {
220          // TODO Auto-generated method stub
221  
222      }
223  
endPrefixMapping(String prefix)224      public void endPrefixMapping(String prefix) throws SAXException {
225          // TODO Auto-generated method stub
226  
227      }
228  
ignorableWhitespace(char[] ch, int start, int length)229      public void ignorableWhitespace(char[] ch, int start, int length)
230              throws SAXException {
231          // TODO Auto-generated method stub
232  
233      }
234  
processingInstruction(String target, String data)235      public void processingInstruction(String target, String data)
236              throws SAXException {
237          // TODO Auto-generated method stub
238  
239      }
240  
setDocumentLocator(Locator locator)241      public void setDocumentLocator(Locator locator) {
242          // TODO Auto-generated method stub
243  
244      }
245  
skippedEntity(String name)246      public void skippedEntity(String name) throws SAXException {
247          // TODO Auto-generated method stub
248  
249      }
250  
startDocument()251      public void startDocument() throws SAXException {
252          // TODO Auto-generated method stub
253  
254      }
255  
startPrefixMapping(String prefix, String uri)256      public void startPrefixMapping(String prefix, String uri)
257              throws SAXException {
258          // TODO Auto-generated method stub
259  
260      }
261  
262  }
263