From 4665463ccd4880c2392d26baa784c5d28de986cc Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Wed, 14 Dec 2011 18:11:27 +0900 Subject: [PATCH] Add XmlParseUtils class Change-Id: Ie288272bc75832db7d743262c4c4fbe73b6dca04 --- .../com/android/inputmethod/keyboard/Key.java | 17 ++-- .../inputmethod/keyboard/KeyboardSet.java | 29 +++--- .../keyboard/internal/KeyStyles.java | 20 ++-- .../keyboard/internal/KeyboardBuilder.java | 96 ++++++------------- .../keyboard/internal/XmlParseUtils.java | 77 +++++++++++++++ 5 files changed, 140 insertions(+), 99 deletions(-) create mode 100644 java/src/com/android/inputmethod/keyboard/internal/XmlParseUtils.java diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index ced763841..4e4ccef18 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -28,13 +28,14 @@ import android.util.Xml; import com.android.inputmethod.keyboard.internal.KeyStyles; import com.android.inputmethod.keyboard.internal.KeyStyles.KeyStyle; import com.android.inputmethod.keyboard.internal.KeyboardBuilder; -import com.android.inputmethod.keyboard.internal.KeyboardBuilder.ParseException; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.keyboard.internal.KeyboardParams; import com.android.inputmethod.keyboard.internal.MoreKeySpecParser; +import com.android.inputmethod.keyboard.internal.XmlParseUtils; import com.android.inputmethod.latin.R; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.util.HashMap; import java.util.Map; @@ -212,9 +213,10 @@ public class Key { * this key. * @param parser the XML parser containing the attributes for this key * @param keyStyles active key styles set + * @throws XmlPullParserException */ public Key(Resources res, KeyboardParams params, KeyboardBuilder.Row row, - XmlPullParser parser, KeyStyles keyStyles) { + XmlPullParser parser, KeyStyles keyStyles) throws XmlPullParserException { final float horizontalGap = isSpacer() ? 0 : params.mHorizontalGap; final int keyHeight = row.mRowHeight; mVerticalGap = params.mVerticalGap; @@ -228,7 +230,8 @@ public class Key { String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle); style = keyStyles.getKeyStyle(styleName); if (style == null) - throw new ParseException("Unknown key style: " + styleName, parser); + throw new XmlParseUtils.ParseException( + "Unknown key style: " + styleName, parser); } else { style = KeyStyles.getEmptyKeyStyle(); } @@ -468,9 +471,9 @@ public class Key { * Detects if a point falls on this key. * @param x the x-coordinate of the point * @param y the y-coordinate of the point - * @return whether or not the point falls on the key. If the key is attached to an edge, it will - * assume that all points between the key and the edge are considered to be on the key. - * @see {@link #markAsLeftEdge(KeyboardParams)} etc. + * @return whether or not the point falls on the key. If the key is attached to an edge, it + * will assume that all points between the key and the edge are considered to be on the key. + * @see #markAsLeftEdge(KeyboardParams) etc. */ public boolean isOnKey(int x, int y) { return mHitBox.contains(x, y); @@ -569,7 +572,7 @@ public class Key { public static class Spacer extends Key { public Spacer(Resources res, KeyboardParams params, KeyboardBuilder.Row row, - XmlPullParser parser, KeyStyles keyStyles) { + XmlPullParser parser, KeyStyles keyStyles) throws XmlPullParserException { super(res, params, row, parser, keyStyles); } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java index 0697c187e..9f182aff4 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java @@ -25,10 +25,7 @@ import android.util.DisplayMetrics; import android.util.Xml; import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.keyboard.internal.KeyboardBuilder; -import com.android.inputmethod.keyboard.internal.KeyboardBuilder.IllegalEndTag; -import com.android.inputmethod.keyboard.internal.KeyboardBuilder.IllegalStartTag; -import com.android.inputmethod.keyboard.internal.KeyboardBuilder.ParseException; +import com.android.inputmethod.keyboard.internal.XmlParseUtils; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.R; @@ -172,7 +169,7 @@ public class KeyboardSet { if (TAG_KEYBOARD_SET.equals(tag)) { parseKeyboardSetContent(parser); } else { - throw new IllegalStartTag(parser, TAG_KEYBOARD_SET); + throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET); } } } @@ -190,14 +187,14 @@ public class KeyboardSet { if (TAG_ELEMENT.equals(tag)) { parseKeyboardSetElement(parser); } else { - throw new IllegalStartTag(parser, TAG_KEYBOARD_SET); + throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET); } } else if (event == XmlPullParser.END_TAG) { final String tag = parser.getName(); if (TAG_KEYBOARD_SET.equals(tag)) { break; } else { - throw new IllegalEndTag(parser, TAG_KEYBOARD_SET); + throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEYBOARD_SET); } } } @@ -208,15 +205,13 @@ public class KeyboardSet { final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.KeyboardSet_Element); try { - if (!a.hasValue(R.styleable.KeyboardSet_Element_elementName)) { - throw new ParseException( - "No elementName attribute in <" + TAG_ELEMENT + "/>", parser); - } - if (!a.hasValue(R.styleable.KeyboardSet_Element_elementKeyboard)) { - throw new ParseException( - "No elementKeyboard attribute in <" + TAG_ELEMENT + "/>", parser); - } - KeyboardBuilder.checkEndTag(TAG_ELEMENT, parser); + XmlParseUtils.checkAttributeExists(a, + R.styleable.KeyboardSet_Element_elementName, "elementName", + TAG_ELEMENT, parser); + XmlParseUtils.checkAttributeExists(a, + R.styleable.KeyboardSet_Element_elementKeyboard, "elementKeyboard", + TAG_ELEMENT, parser); + XmlParseUtils.checkEndTag(TAG_ELEMENT, parser); final int elementName = a.getInt( R.styleable.KeyboardSet_Element_elementName, 0); @@ -245,7 +240,7 @@ public class KeyboardSet { keyboardSetAttr.recycle(); return locale; } else { - throw new IllegalStartTag(parser, TAG_KEYBOARD_SET); + throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD_SET); } } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java index 218793500..3324fa6af 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java @@ -19,10 +19,10 @@ package com.android.inputmethod.keyboard.internal; import android.content.res.TypedArray; import android.util.Log; -import com.android.inputmethod.keyboard.internal.KeyboardBuilder.ParseException; import com.android.inputmethod.latin.R; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.util.ArrayList; import java.util.HashMap; @@ -43,7 +43,7 @@ public class KeyStyles { } /* package */ static class EmptyKeyStyle implements KeyStyle { - private EmptyKeyStyle() { + EmptyKeyStyle() { // Nothing to do. } @@ -118,7 +118,7 @@ public class KeyStyles { } } - private static class DeclaredKeyStyle extends EmptyKeyStyle { + /* package */ static class DeclaredKeyStyle extends EmptyKeyStyle { private final HashMap mAttributes = new HashMap(); @Override @@ -145,11 +145,11 @@ public class KeyStyles { return super.getFlag(a, index, defaultValue) | (value != null ? value : 0); } - private DeclaredKeyStyle() { + DeclaredKeyStyle() { super(); } - private void parseKeyStyleAttributes(TypedArray keyAttr) { + void parseKeyStyleAttributes(TypedArray keyAttr) { // TODO: Currently not all Key attributes can be declared as style. readInt(keyAttr, R.styleable.Keyboard_Key_code); readInt(keyAttr, R.styleable.Keyboard_Key_altCode); @@ -188,18 +188,19 @@ public class KeyStyles { mAttributes.put(index, value); } - private void addParent(DeclaredKeyStyle parentStyle) { + void addParent(DeclaredKeyStyle parentStyle) { mAttributes.putAll(parentStyle.mAttributes); } } public void parseKeyStyleAttributes(TypedArray keyStyleAttr, TypedArray keyAttrs, - XmlPullParser parser) { + XmlPullParser parser) throws XmlPullParserException { final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName); if (DEBUG) Log.d(TAG, String.format("<%s styleName=%s />", KeyboardBuilder.TAG_KEY_STYLE, styleName)); if (mStyles.containsKey(styleName)) - throw new ParseException("duplicate key style declared: " + styleName, parser); + throw new XmlParseUtils.ParseException( + "duplicate key style declared: " + styleName, parser); final DeclaredKeyStyle style = new DeclaredKeyStyle(); if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) { @@ -207,7 +208,8 @@ public class KeyStyles { R.styleable.Keyboard_KeyStyle_parentStyle); final DeclaredKeyStyle parent = mStyles.get(parentStyle); if (parent == null) - throw new ParseException("Unknown parentStyle " + parentStyle, parser); + throw new XmlParseUtils.ParseException( + "Unknown parentStyle " + parentStyle, parser); style.addParent(parent); } style.parseKeyStyleAttributes(keyAttrs); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java index d9d9c2f83..a88a1638c 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java @@ -305,7 +305,7 @@ public class KeyboardBuilder { parseKeyboardContent(parser, false); break; } else { - throw new IllegalStartTag(parser, TAG_KEYBOARD); + throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD); } } } @@ -393,7 +393,7 @@ public class KeyboardBuilder { } else if (TAG_KEY_STYLE.equals(tag)) { parseKeyStyle(parser, skip); } else { - throw new IllegalStartTag(parser, TAG_ROW); + throw new XmlParseUtils.IllegalStartTag(parser, TAG_ROW); } } else if (event == XmlPullParser.END_TAG) { final String tag = parser.getName(); @@ -407,20 +407,20 @@ public class KeyboardBuilder { } else if (TAG_KEY_STYLE.equals(tag)) { continue; } else { - throw new IllegalEndTag(parser, TAG_ROW); + throw new XmlParseUtils.IllegalEndTag(parser, TAG_ROW); } } } } - private Row parseRowAttributes(XmlPullParser parser) { + private Row parseRowAttributes(XmlPullParser parser) throws XmlPullParserException { final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard); try { if (a.hasValue(R.styleable.Keyboard_horizontalGap)) - throw new IllegalAttribute(parser, "horizontalGap"); + throw new XmlParseUtils.IllegalAttribute(parser, "horizontalGap"); if (a.hasValue(R.styleable.Keyboard_verticalGap)) - throw new IllegalAttribute(parser, "verticalGap"); + throw new XmlParseUtils.IllegalAttribute(parser, "verticalGap"); return new Row(mResources, mParams, parser, mCurrentY); } finally { a.recycle(); @@ -444,7 +444,7 @@ public class KeyboardBuilder { } else if (TAG_KEY_STYLE.equals(tag)) { parseKeyStyle(parser, skip); } else { - throw new IllegalStartTag(parser, TAG_KEY); + throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEY); } } else if (event == XmlPullParser.END_TAG) { final String tag = parser.getName(); @@ -460,7 +460,7 @@ public class KeyboardBuilder { } else if (TAG_KEY_STYLE.equals(tag)) { continue; } else { - throw new IllegalEndTag(parser, TAG_KEY); + throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEY); } } } @@ -469,13 +469,13 @@ public class KeyboardBuilder { private void parseKey(XmlPullParser parser, Row row, boolean skip) throws XmlPullParserException, IOException { if (skip) { - checkEndTag(TAG_KEY, parser); + XmlParseUtils.checkEndTag(TAG_KEY, parser); } else { final Key key = new Key(mResources, mParams, row, parser, mKeyStyles); if (DEBUG) Log.d(TAG, String.format("<%s%s keyLabel=%s code=%d moreKeys=%s />", TAG_KEY, (key.isEnabled() ? "" : " disabled"), key.mLabel, key.mCode, Arrays.toString(key.mMoreKeys))); - checkEndTag(TAG_KEY, parser); + XmlParseUtils.checkEndTag(TAG_KEY, parser); endKey(key); } } @@ -483,11 +483,11 @@ public class KeyboardBuilder { private void parseSpacer(XmlPullParser parser, Row row, boolean skip) throws XmlPullParserException, IOException { if (skip) { - checkEndTag(TAG_SPACER, parser); + XmlParseUtils.checkEndTag(TAG_SPACER, parser); } else { final Key.Spacer spacer = new Key.Spacer(mResources, mParams, row, parser, mKeyStyles); if (DEBUG) Log.d(TAG, String.format("<%s />", TAG_SPACER)); - checkEndTag(TAG_SPACER, parser); + XmlParseUtils.checkEndTag(TAG_SPACER, parser); endKey(spacer); } } @@ -505,17 +505,21 @@ public class KeyboardBuilder { private void parseIncludeInternal(XmlPullParser parser, Row row, boolean skip) throws XmlPullParserException, IOException { if (skip) { - checkEndTag(TAG_INCLUDE, parser); + XmlParseUtils.checkEndTag(TAG_INCLUDE, parser); } else { final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Include); - final int keyboardLayout = a.getResourceId( - R.styleable.Keyboard_Include_keyboardLayout, 0); - a.recycle(); + int keyboardLayout = 0; + try { + XmlParseUtils.checkAttributeExists(a, + R.styleable.Keyboard_Include_keyboardLayout, "keyboardLayout", + TAG_INCLUDE, parser); + keyboardLayout = a.getResourceId(R.styleable.Keyboard_Include_keyboardLayout, 0); + } finally { + a.recycle(); + } - checkEndTag(TAG_INCLUDE, parser); - if (keyboardLayout == 0) - throw new ParseException("No keyboardLayout attribute in ", parser); + XmlParseUtils.checkEndTag(TAG_INCLUDE, parser); if (DEBUG) Log.d(TAG, String.format("<%s keyboardLayout=%s />", TAG_INCLUDE, mResources.getResourceEntryName(keyboardLayout))); final XmlResourceParser parserForInclude = mResources.getXml(keyboardLayout); @@ -541,7 +545,7 @@ public class KeyboardBuilder { } break; } else { - throw new ParseException( + throw new XmlParseUtils.ParseException( "Included keyboard layout must have root element", parser); } } @@ -571,7 +575,7 @@ public class KeyboardBuilder { } else if (TAG_DEFAULT.equals(tag)) { selected |= parseDefault(parser, row, selected ? true : skip); } else { - throw new IllegalStartTag(parser, TAG_KEY); + throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEY); } } else if (event == XmlPullParser.END_TAG) { final String tag = parser.getName(); @@ -579,7 +583,7 @@ public class KeyboardBuilder { if (DEBUG) Log.d(TAG, String.format("", TAG_SWITCH)); break; } else { - throw new IllegalEndTag(parser, TAG_KEY); + throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEY); } } } @@ -716,14 +720,15 @@ public class KeyboardBuilder { return true; } - private void parseKeyStyle(XmlPullParser parser, boolean skip) { + private void parseKeyStyle(XmlPullParser parser, boolean skip) + throws XmlPullParserException { TypedArray keyStyleAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_KeyStyle); TypedArray keyAttrs = mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Key); try { if (!keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_styleName)) - throw new ParseException("<" + TAG_KEY_STYLE + throw new XmlParseUtils.ParseException("<" + TAG_KEY_STYLE + "/> needs styleName attribute", parser); if (!skip) mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser); @@ -733,13 +738,6 @@ public class KeyboardBuilder { } } - public static void checkEndTag(String tag, XmlPullParser parser) - throws XmlPullParserException, IOException { - if (parser.next() == XmlPullParser.END_TAG && tag.equals(parser.getName())) - return; - throw new NonEmptyTag(tag, parser); - } - private void startKeyboard() { mCurrentY += mParams.mTopPadding; mTopEdge = true; @@ -778,6 +776,7 @@ public class KeyboardBuilder { } private void endKeyboard() { + // nothing to do here. } private void addEdgeSpace(float width, Row row) { @@ -824,41 +823,6 @@ public class KeyboardBuilder { return v.type == TypedValue.TYPE_STRING; } - @SuppressWarnings("serial") - public static class ParseException extends InflateException { - public ParseException(String msg, XmlPullParser parser) { - super(msg + " at line " + parser.getLineNumber()); - } - } - - @SuppressWarnings("serial") - public static class IllegalStartTag extends ParseException { - public IllegalStartTag(XmlPullParser parser, String parent) { - super("Illegal start tag " + parser.getName() + " in " + parent, parser); - } - } - - @SuppressWarnings("serial") - public static class IllegalEndTag extends ParseException { - public IllegalEndTag(XmlPullParser parser, String parent) { - super("Illegal end tag " + parser.getName() + " in " + parent, parser); - } - } - - @SuppressWarnings("serial") - private static class IllegalAttribute extends ParseException { - public IllegalAttribute(XmlPullParser parser, String attribute) { - super("Tag " + parser.getName() + " has illegal attribute " + attribute, parser); - } - } - - @SuppressWarnings("serial") - private static class NonEmptyTag extends ParseException { - public NonEmptyTag(String tag, XmlPullParser parser) { - super(tag + " must be empty tag", parser); - } - } - private static String textAttr(String value, String name) { return value != null ? String.format(" %s=%s", name, value) : ""; } diff --git a/java/src/com/android/inputmethod/keyboard/internal/XmlParseUtils.java b/java/src/com/android/inputmethod/keyboard/internal/XmlParseUtils.java new file mode 100644 index 000000000..170be347b --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/internal/XmlParseUtils.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2011 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 com.android.inputmethod.keyboard.internal; + +import android.content.res.TypedArray; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + +public class XmlParseUtils { + @SuppressWarnings("serial") + public static class ParseException extends XmlPullParserException { + public ParseException(String msg, XmlPullParser parser) { + super(msg + " at line " + parser.getLineNumber() + + ", column " + parser.getColumnNumber()); + } + } + + @SuppressWarnings("serial") + public static class IllegalStartTag extends ParseException { + public IllegalStartTag(XmlPullParser parser, String parent) { + super("Illegal start tag " + parser.getName() + " in " + parent, parser); + } + } + + @SuppressWarnings("serial") + public static class IllegalEndTag extends ParseException { + public IllegalEndTag(XmlPullParser parser, String parent) { + super("Illegal end tag " + parser.getName() + " in " + parent, parser); + } + } + + @SuppressWarnings("serial") + static class IllegalAttribute extends ParseException { + public IllegalAttribute(XmlPullParser parser, String attribute) { + super("Tag " + parser.getName() + " has illegal attribute " + attribute, parser); + } + } + + @SuppressWarnings("serial") + static class NonEmptyTag extends ParseException{ + public NonEmptyTag(String tag, XmlPullParser parser) { + super(tag + " must be empty tag", parser); + } + } + + public static void checkEndTag(String tag, XmlPullParser parser) + throws XmlPullParserException, IOException { + if (parser.next() == XmlPullParser.END_TAG && tag.equals(parser.getName())) + return; + throw new NonEmptyTag(tag, parser); + } + + public static void checkAttributeExists(TypedArray attr, int attrId, String attrName, + String tag, XmlPullParser parser) throws XmlPullParserException { + if (attr.hasValue(attrId)) + return; + throw new ParseException( + "No " + attrName + " attribute found in <" + tag + "/>", parser); + } +}