UriMatcher

原文地址:http://blog.csdn.net/wcs542882916

package android.content;

 

import android.net.Uri;

 

import java.util.ArrayList;

import java.util.List;

import java.util.regex.Pattern;

 

/**

Utility class toaid in matching URIs in content providers.

contentproviders里帮助匹配URIs的实用类

<p>To use this class, build up a tree of<code>UriMatcher</code> objects.

For example:

使用这个类建立UriMatcher对象的一个树,一下是UriMatcher的用法

<pre>

    private static final int PEOPLE = 1;

    private static final int PEOPLE_ID =2;

    private static final intPEOPLE_PHONES = 3;

    private static final intPEOPLE_PHONES_ID = 4;

    private static final intPEOPLE_CONTACTMETHODS = 7;

    private static final intPEOPLE_CONTACTMETHODS_ID = 8;

 

    private static final intDELETED_PEOPLE = 20;

 

    private static final int PHONES = 9;

    private static final int PHONES_ID =10;

    private static final intPHONES_FILTER = 14;

 

    private static final intCONTACTMETHODS = 18;

    private static final intCONTACTMETHODS_ID = 19;

 

    private static final int CALLS = 11;

    private static final int CALLS_ID =12;

    private static final intCALLS_FILTER = 15;

 

    private static final UriMatcher sURIMatcher= new UriMatcher(UriMatcher.NO_MATCH);

    static

    {

       sURIMatcher.addURI("contacts", "people", PEOPLE);

       sURIMatcher.addURI("contacts", "people/#",PEOPLE_ID);

       sURIMatcher.addURI("contacts", "people/#/phones",PEOPLE_PHONES);

       sURIMatcher.addURI("contacts", "people/#/phones/#",PEOPLE_PHONES_ID);

       sURIMatcher.addURI("contacts","people/#/contact_methods", PEOPLE_CONTACTMETHODS);

        sURIMatcher.addURI("contacts","people/#/contact_methods/#", PEOPLE_CONTACTMETHODS_ID);

       sURIMatcher.addURI("contacts", "deleted_people",DELETED_PEOPLE);

       sURIMatcher.addURI("contacts", "phones", PHONES);

       sURIMatcher.addURI("contacts", "phones/filter/*",PHONES_FILTER);

       sURIMatcher.addURI("contacts", "phones/#",PHONES_ID);

       sURIMatcher.addURI("contacts", "contact_methods",CONTACTMETHODS);

       sURIMatcher.addURI("contacts", "contact_methods/#",CONTACTMETHODS_ID);

       sURIMatcher.addURI("call_log", "calls", CALLS);

       sURIMatcher.addURI("call_log", "calls/filter/*",CALLS_FILTER);

       sURIMatcher.addURI("call_log", "calls/#", CALLS_ID);

}

</pre>

<p>Starting from API level{@linkandroid.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, paths can start

 with a leading slash.  For example:

<pre>

       sURIMatcher.addURI("contacts", "/people", PEOPLE);

</pre>

<p>Then when you need to match against a URI,call{@link #match}, providing

the URL that youhave been given.  You can use the resultto build a query,

return a type,insert or delete a row, or whatever you need, without duplicating

all of the if-else logicthat you would otherwise need.  Forexample:

 

<pre>

    public String getType(Uri url)

    {

        int match = sURIMatcher.match(url);

        switch (match)

        {

            case PEOPLE:

                return"vnd.android.cursor.dir/person";

            case PEOPLE_ID:

                return"vnd.android.cursor.item/person";

... snip...

                return"vnd.android.cursor.dir/snail-mail";

            case PEOPLE_ADDRESS_ID:

                return"vnd.android.cursor.item/snail-mail";

            default:

                return null;

        }

    }

</pre>

instead of:

<pre>

    public String getType(Uri url)

    {

        List<String>pathSegments = url.getPathSegments();

        if (pathSegments.size() >= 2) {

            if("people".equals(pathSegments.get(1))) {

                if (pathSegments.size() == 2) {

                    return"vnd.android.cursor.dir/person";

                } else if (pathSegments.size()== 3) {

                    return"vnd.android.cursor.item/person";

... snip...

                    return"vnd.android.cursor.dir/snail-mail";

                } else if (pathSegments.size()== 3) {

                    return"vnd.android.cursor.item/snail-mail";

                }

            }

        }

        return null;

    }

</pre>

*/

public class UriMatcher

{

    public static final int NO_MATCH = -1;

    /**

     * Creates the root node of the URI tree.

     * 创建URI树的根节点

     * @param code thecode to match for the root URI

     */

    public UriMatcher(int code)

    {

        mCode = code;

        mWhich = -1;

        mChildren = new ArrayList<UriMatcher>();

        mText = null;

    }    private UriMatcher()

    {

        mCode = NO_MATCH;

        mWhich = -1;

        mChildren = new ArrayList<UriMatcher>();

        mText = null;

    }

 

    /**

     * Add a URI to match, and the code toreturn when this URI is

     * matched. URI nodes may be exact matchstring, the token "*"

     * that matches any text, or the token"#" that matches only

     * numbers.

     * <p>

     * Starting from API level {@linkandroid.os.Build.VERSION_CODES#JELLY_BEAN_MR2},

     * this method will accept leading slash inthe path.

     *

     * @param authoritythe authority to match

     * @param path thepath to match. * may be used as a wild card for

     * any text, and # may be used as a wildcard for numbers.

     * @param code thecode that is returned when a URI is matched

     * against the given components. Must bepositive.

     *

     * 添加需要匹配的URI,当URI匹配的时候返回code

     * URI节点可能会精确的匹配字符串,标记“*”匹配任何text,标记“#”仅仅匹配数字。

     * API level 18JELLY_BEAN_MR2)开始,这个方法中的path参数接受正向斜线。

     * path路径前的“/”可有可无eg:sURIMatcher.addURI("contacts", "people", PEOPLE);

     * code这个参数必须是正数,大于等于0

     */

    publicvoid addURI(String authority, String path,int code)

    {

        if (code <0) {

            throw new IllegalArgumentException("code " + code +" isinvalid: it must be positive");

        }

 

        String[] tokens = null;

        if (path !=null) {

            String newPath = path;

            // Strip leading slash if present.

            if(path.length() > 0 && path.charAt(0) =='/') {

                newPath = path.substring(1);

            }

            tokens = PATH_SPLIT_PATTERN.split(newPath);

        }

        int numTokens =tokens !=null ? tokens.length : 0;

        UriMatcher node = this;

        for (int i = -1; i < numTokens; i++) {

            String token = i < 0 ? authority: tokens[i];

            ArrayList<UriMatcher>children = node.mChildren;

            int numChildren= children.size();

            UriMatcher child;

            int j;

            for (j = 0; j< numChildren; j++) {

                child = children.get(j);

                if(token.equals(child.mText)) {

                    node = child;

                    break;

                }

            }

            if (j ==numChildren) {

                // Child not found, create it

                child = new UriMatcher();

                if(token.equals("#")) {

                    child.mWhich =NUMBER;

                } elseif (token.equals("*")) {

                    child.mWhich =TEXT;

                } else {

                    child.mWhich =EXACT;

                }

                child.mText = token;

                node.mChildren.add(child);

                node = child;

            }

        }

        node.mCode = code;

    }

 

    /**

     * 还不知道用法,以后去了解

     */

    static final Pattern PATH_SPLIT_PATTERN =Pattern.compile("/");

 

    /**

     * Try to match against the path in a url.

     *

     * @param uri       The url whose path we will matchagainst.

     *

     * @return The code for the matched node (added using addURI),

     * or -1 if there is no matched node.

     *

     * 如果匹配则返回添加时的code,否则返回-1

     */

    publicint match(Uri uri)

    {

        finalList<String> pathSegments = uri.getPathSegments();

        final int li = pathSegments.size();

 

        UriMatcher node = this;

 

        if (li == 0&& uri.getAuthority() ==null) {

            return this.mCode;

        }

 

        for (int i=-1; i<li; i++) {

            String u = i < 0 ?uri.getAuthority() : pathSegments.get(i);

            ArrayList<UriMatcher> list =node.mChildren;

            if (list ==null) {

                break;

            }

            node = null;

            int lj =list.size();

            for (int j=0; j<lj; j++) {

                UriMatcher n = list.get(j);

          which_switch:

                switch (n.mWhich) {

                    caseEXACT:

                        if (n.mText.equals(u)) {

                            node = n;

                        }

                        break;

                    caseNUMBER:

                        int lk = u.length();

                        for (int k=0; k<lk; k++) {

                            char c = u.charAt(k);

                            if (c <'0' || c > '9') {

                                break which_switch;

                            }

                        }

                        node = n;

                        break;

                    caseTEXT:

                        node = n;

                        break;

                }

                if (node !=null) {

                    break;

                }

            }

            if (node ==null) {

                returnNO_MATCH;

            }

        }

 

        return node.mCode;

    }

 

    private static final int EXACT = 0;

    private static final int NUMBER = 1;

    private static final int TEXT = 2;

 

    private int mCode;

    private int mWhich;

    private StringmText;

    privateArrayList<UriMatcher>mChildren;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值