android的UriMatcher类

package fkshl.activity.contentProvider;

/* Copyright (C) 2006 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.  

 */

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import android.net.Uri;

public class UriMatcher

{

	public static final int NO_MATCH = -1;

	/***
	 * 
	 * Creates the root node of the URI tree.
	 * 
	 * 
	 * 
	 * @param code
	 *            the code 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 to return when this URI is
	 * 
	 * matched. URI nodes may be exact match string, the token "*"
	 * 
	 * that matches any text, or the token "#" that matches only
	 * 
	 * numbers.
	 * 
	 * 
	 * 
	 * @param authority
	 *            the authority to match
	 * 
	 * @param path
	 *            the path to match. * may be used as a wild card for
	 * 
	 *            any text, and # may be used as a wild card for numbers.
	 * 
	 * @param code
	 *            the code that is returned when a URI is matched
	 * 
	 *            against the given components. Must be positive.
	 */

	public void addURI(String authority, String path, int code){

		if (code < 0) {
			throw new IllegalArgumentException("code " + code
					+ " is invalid: it must be positive");

		}
		//以"/"分隔path
		String[] tokens = path != null ? PATH_SPLIT_PATTERN.split(path) : null;
        //判断分隔后的数组长度.并取其值
		int numTokens = tokens != null ? tokens.length : 0;
		//当前对象
		UriMatcher node = this;
		
		for (int i = -1; i < numTokens; i++) {
			//当前循环变量小于0就取authority,否则就获取分隔后的数组的字符,并赋值给token
			String token = i < 0 ? authority : tokens[i];
			//把当前对象的集合赋值给children
			ArrayList<UriMatcher> children = node.mChildren;
			//获取其长度
			int numChildren = children.size();	
	 	         UriMatcher child;
			int j;	
			for (j = 0; j < numChildren; j++) {
				//获取children对象的孩子
				child = children.get(j);
				//判断当前的token和child对象中的mText是否相等
				if (token.equals(child.mText)) {
					//把child 赋值给 node;
					node = child;
					break;
				}
			}
			//获取循环变量j并判断是否等于children对应的大小.也就是判断是否是最后一个
			if (j == numChildren) {
				// Child not found, create it
				//没有发现孩子,并创建
				child = new UriMatcher();
				///判断当前的token是否等于"#"
				if (token.equals("#")) {
					//mWhich=1
					child.mWhich = NUMBER;
				} else if (token.equals("*")) {
					//mWhich=2
					child.mWhich = TEXT;
				} else {
					//mWhich=0
					child.mWhich = EXACT;
				}
				//mText=当前的token
				child.mText = token;
				//添加到mChildren集合中
				node.mChildren.add(child);
				//node = child;
				node = child;
			}
		}
		//node.mCode = code;
		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 match against.
	 * 
	 * 
	 * 
	 * @return The code for the matched node (added using addURI),
	 * 
	 *         or -1 if there is no matched node.
	 */

	public int match(Uri uri){

		final List<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) {
				case EXACT:
					if (n.mText.equals(u)) {
						node = n;
					}
				        break;
				case NUMBER:
					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;
				case TEXT:
					node = n;
					break;
				}
				if (node != null) {
				     break;
				}
			}
			if (node == null) {
				return NO_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 String mText;
	private final ArrayList<UriMatcher> mChildren;

}
这是android源码.
由于不懂所以就把它粘贴的项目中.所以包自然就改成自己项目的了..
package fkshl.activity.contentProvider;

import java.util.HashMap;
import java.util.Map;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import fkshl.activity.contentProviderMetaData.ContentProviderMetaData;
import fkshl.activity.contentProviderMetaData.ContentProviderMetaData.UserTableMetaData;
import fkshl.activity.dataBase.DBHelper;

public class FkshlContentProvider extends ContentProvider {

	public static final UriMatcher URI_MATCHER;
	public static final int FKSHL_TABLE = 1;
	public static final int FKSHL_TABLE_COLUMN = 2;
	public static final Map<String, String> COLUM_MAPPIGN;

	public DBHelper dbHelper;

	static {
		/**
		 * uri验证
		 */
		URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "users", 1);
		URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "users/#", 2);

		/**
		 * 列的映射
		 */
		COLUM_MAPPIGN = new HashMap<String, String>();
		COLUM_MAPPIGN.put(UserTableMetaData._ID, UserTableMetaData._ID);
		COLUM_MAPPIGN.put(UserTableMetaData.COLUMN_NAME, UserTableMetaData.COLUMN_NAME);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		switch (URI_MATCHER.match(uri)) {
		case FKSHL_TABLE:
			return UserTableMetaData.CONTENT_TYPE;
		case FKSHL_TABLE_COLUMN:
			return UserTableMetaData.CONTENT_TYPE_ITEM;
		default:
			throw new IllegalArgumentException("Unknown URI!!!!!" + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		SQLiteDatabase database = dbHelper.getWritableDatabase();
		Long rowId = database.insert(ContentProviderMetaData.TABLE_NAME, null, values);
		if (rowId > 0) {
			Uri empuri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
			getContext().getContentResolver().notifyChange(empuri, null);
			System.out.println("insert success!!!");
		}
		return null;
	}

	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		dbHelper = new DBHelper(getContext(), ContentProviderMetaData.DATABASE_NAME);
		dbHelper.getReadableDatabase();
		System.out.println("create database success!!");
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
		// TODO Auto-generated method stub
		switch (URI_MATCHER.match(uri)) {
		case FKSHL_TABLE:
			builder.setTables(UserTableMetaData.TABLE_NAME);
			builder.setProjectionMap(COLUM_MAPPIGN);
			break;
		case FKSHL_TABLE_COLUMN:
			builder.setTables(UserTableMetaData.TABLE_NAME);
			builder.setProjectionMap(COLUM_MAPPIGN);
			builder.appendWhere(UserTableMetaData.COLUMN_NAME + "="
					+ uri.getPathSegments().get(1));
			break;

		default:
			throw new IllegalArgumentException("uri error !!!!" + uri);
		}
		String orderBy;
		if (TextUtils.isEmpty(sortOrder)) {
			orderBy = UserTableMetaData.ORDER_BY + " Desc";
		} else {
			orderBy = sortOrder;
		}
		SQLiteDatabase database = dbHelper.getReadableDatabase();
		Cursor c =	builder.query(database, projection, selection, selectionArgs, null, null, orderBy);
		c.setNotificationUri(getContext().getContentResolver(), uri);
		System.out.println("seach end!!!!");
		return c;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}

}
做的时间发现一个问题.
这是之前发现在按官方提示做的.
	URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "/users", 1);
		URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "/users/#", 2);
可是在getType中怎么都走default.都是抛异常.
05-22 09:39:23.449: ERROR/AndroidRuntime(581): java.lang.IllegalArgumentException: uri error !!!!content://fkshl.activity.contentProvider.FkshlContentProvider/users
最后看了源码,改成了.
	URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "users", 1);
		URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "users/#", 2);
这样就好.
原因是在add方法中它会以"/"分隔users/#,然后把分隔后的字符串像树型的一级一级保存在mChildren中.如果在users/#前面加"/",哪么就导致在"/"之前有一个空字符(content://fkshl.activity.contentProvider.FkshlContentProvider//users),而在我的项目中调用getType方法传过来时的uir中没有这样的一个空字符(content://fkshl.activity.contentProvider.FkshlContentProvider/users)
没有.

你可能感兴趣的:(C++,c,android,sqlite,J#)