Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4665463c authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Add XmlParseUtils class

Change-Id: Ie288272bc75832db7d743262c4c4fbe73b6dca04
parent e35e13fc
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -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);
        }

+12 −17
Original line number Diff line number Diff line
@@ -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);
                }
            }
        }
+11 −9
Original line number Diff line number Diff line
@@ -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<Integer, Object> mAttributes = new HashMap<Integer, Object>();

        @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);
+30 −66
Original line number Diff line number Diff line
@@ -305,7 +305,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
                    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<KP extends KeyboardParams> {
                } 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<KP extends KeyboardParams> {
                } 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<KP extends KeyboardParams> {
                } 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<KP extends KeyboardParams> {
                } 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<KP extends KeyboardParams> {
    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<KP extends KeyboardParams> {
    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<KP extends KeyboardParams> {
    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);
            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 <include/>", 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<KP extends KeyboardParams> {
                    }
                    break;
                } else {
                    throw new ParseException(
                    throw new XmlParseUtils.ParseException(
                            "Included keyboard layout must have <merge> root element", parser);
                }
            }
@@ -571,7 +575,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
                } 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<KP extends KeyboardParams> {
                    if (DEBUG) Log.d(TAG, String.format("</%s>", TAG_SWITCH));
                    break;
                } else {
                    throw new IllegalEndTag(parser, TAG_KEY);
                    throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEY);
                }
            }
        }
@@ -716,14 +720,15 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
        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<KP extends KeyboardParams> {
        }
    }

    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<KP extends KeyboardParams> {
    }

    private void endKeyboard() {
        // nothing to do here.
    }

    private void addEdgeSpace(float width, Row row) {
@@ -824,41 +823,6 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
        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) : "";
    }
+77 −0
Original line number Diff line number Diff line
/*
 * 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);
    }
}