1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.inputmethod.dictionarypack; 18 19 import android.text.TextUtils; 20 import android.util.JsonReader; 21 22 import java.io.IOException; 23 import java.io.InputStreamReader; 24 import java.util.ArrayList; 25 import java.util.Collections; 26 import java.util.List; 27 import java.util.TreeMap; 28 29 /** 30 * Helper class containing functions to parse the dictionary metadata. 31 */ 32 public class MetadataParser { 33 34 // Name of the fields in the JSON-formatted file. 35 private static final String ID_FIELD_NAME = MetadataDbHelper.WORDLISTID_COLUMN; 36 private static final String LOCALE_FIELD_NAME = "locale"; 37 private static final String DESCRIPTION_FIELD_NAME = MetadataDbHelper.DESCRIPTION_COLUMN; 38 private static final String UPDATE_FIELD_NAME = "update"; 39 private static final String FILESIZE_FIELD_NAME = MetadataDbHelper.FILESIZE_COLUMN; 40 private static final String RAW_CHECKSUM_FIELD_NAME = MetadataDbHelper.RAW_CHECKSUM_COLUMN; 41 private static final String CHECKSUM_FIELD_NAME = MetadataDbHelper.CHECKSUM_COLUMN; 42 private static final String REMOTE_FILENAME_FIELD_NAME = 43 MetadataDbHelper.REMOTE_FILENAME_COLUMN; 44 private static final String VERSION_FIELD_NAME = MetadataDbHelper.VERSION_COLUMN; 45 private static final String FORMATVERSION_FIELD_NAME = MetadataDbHelper.FORMATVERSION_COLUMN; 46 47 /** 48 * Parse one JSON-formatted word list metadata. 49 * @param reader the reader containing the data. 50 * @return a WordListMetadata object from the parsed data. 51 * @throws IOException if the underlying reader throws IOException during reading. 52 */ parseOneWordList(final JsonReader reader)53 private static WordListMetadata parseOneWordList(final JsonReader reader) 54 throws IOException, BadFormatException { 55 final TreeMap<String, String> arguments = new TreeMap<>(); 56 reader.beginObject(); 57 while (reader.hasNext()) { 58 final String name = reader.nextName(); 59 if (!TextUtils.isEmpty(name)) { 60 arguments.put(name, reader.nextString()); 61 } 62 } 63 reader.endObject(); 64 if (TextUtils.isEmpty(arguments.get(ID_FIELD_NAME)) 65 || TextUtils.isEmpty(arguments.get(LOCALE_FIELD_NAME)) 66 || TextUtils.isEmpty(arguments.get(DESCRIPTION_FIELD_NAME)) 67 || TextUtils.isEmpty(arguments.get(UPDATE_FIELD_NAME)) 68 || TextUtils.isEmpty(arguments.get(FILESIZE_FIELD_NAME)) 69 || TextUtils.isEmpty(arguments.get(CHECKSUM_FIELD_NAME)) 70 || TextUtils.isEmpty(arguments.get(REMOTE_FILENAME_FIELD_NAME)) 71 || TextUtils.isEmpty(arguments.get(VERSION_FIELD_NAME)) 72 || TextUtils.isEmpty(arguments.get(FORMATVERSION_FIELD_NAME))) { 73 throw new BadFormatException(arguments.toString()); 74 } 75 // TODO: need to find out whether it's bulk or update 76 // The null argument is the local file name, which is not known at this time and will 77 // be decided later. 78 return new WordListMetadata( 79 arguments.get(ID_FIELD_NAME), 80 MetadataDbHelper.TYPE_BULK, 81 arguments.get(DESCRIPTION_FIELD_NAME), 82 Long.parseLong(arguments.get(UPDATE_FIELD_NAME)), 83 Long.parseLong(arguments.get(FILESIZE_FIELD_NAME)), 84 arguments.get(RAW_CHECKSUM_FIELD_NAME), 85 arguments.get(CHECKSUM_FIELD_NAME), 86 MetadataDbHelper.DICTIONARY_RETRY_THRESHOLD /* retryCount */, 87 null, 88 arguments.get(REMOTE_FILENAME_FIELD_NAME), 89 Integer.parseInt(arguments.get(VERSION_FIELD_NAME)), 90 Integer.parseInt(arguments.get(FORMATVERSION_FIELD_NAME)), 91 0, arguments.get(LOCALE_FIELD_NAME)); 92 } 93 94 /** 95 * Parses metadata in the JSON format. 96 * @param input a stream reader expected to contain JSON formatted metadata. 97 * @return dictionary metadata, as an array of WordListMetadata objects. 98 * @throws IOException if the underlying reader throws IOException during reading. 99 * @throws BadFormatException if the data was not in the expected format. 100 */ parseMetadata(final InputStreamReader input)101 public static List<WordListMetadata> parseMetadata(final InputStreamReader input) 102 throws IOException, BadFormatException { 103 JsonReader reader = new JsonReader(input); 104 final ArrayList<WordListMetadata> readInfo = new ArrayList<>(); 105 reader.beginArray(); 106 while (reader.hasNext()) { 107 final WordListMetadata thisMetadata = parseOneWordList(reader); 108 if (!TextUtils.isEmpty(thisMetadata.mLocale)) 109 readInfo.add(thisMetadata); 110 } 111 return Collections.unmodifiableList(readInfo); 112 } 113 114 } 115