Android Open Source - ContentProviderProcessor Generic Uri Matcher






From Project

Back to project page ContentProviderProcessor.

License

The source code is released under:

Apache License

If you think the Android project ContentProviderProcessor listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package de.wackernagel.android.contractcontentprovider;
//from  w  w w  .j  ava2s .c  om
/*
 * 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;

/**
 * A generic version of {@link android.content.UriMatcher}. </br> (Source can be
 * found under {@link https
 * ://raw.github.com/android/platform_frameworks_base/master
 * /core/java/android/content/UriMatcher.java})
 * 
 * @author wackernagel
 * 
 * @param <T>
 *           Type of code which is returned by
 *           {@link android.content.UriMatcher#match(Uri)}
 */
public class GenericUriMatcher<T extends Object> {
  public static final Object NO_MATCH = null;

  /**
   * Creates the root node of the URI tree.
   * 
   * @param code
   *           the code to match for the root URI
   */
  public GenericUriMatcher( T code ) {
    mCode = code;
    mWhich = -1;
    mChildren = new ArrayList<GenericUriMatcher<T>>();
    mText = null;
  }

  @SuppressWarnings( "unchecked" )
  private GenericUriMatcher() {
    mCode = ( T ) NO_MATCH;
    mWhich = -1;
    mChildren = new ArrayList<GenericUriMatcher<T>>();
    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.
   * <p>
   * Starting from API level
   * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this method will
   * accept leading slash in the path.
   * 
   * @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, T code ) {
    if( code == null ) {
      throw new IllegalArgumentException( "code " + code + " is invalid: 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;
    GenericUriMatcher<T> node = this;
    for( int i = -1; i < numTokens; i++ ) {
      String token = i < 0 ? authority : tokens[i];
      ArrayList<GenericUriMatcher<T>> children = node.mChildren;
      int numChildren = children.size();
      GenericUriMatcher<T> 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 GenericUriMatcher<T>();
        if( token.equals( "#" ) ) {
          child.mWhich = NUMBER;
        } else if( 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 match against.
   * 
   * @return The code for the matched node (added using addURI), or -1 if there
   *         is no matched node.
   */
  @SuppressWarnings( "unchecked" )
  public T match( Uri uri ) {
    final List<String> pathSegments = uri.getPathSegments();
    final int li = pathSegments.size();

    GenericUriMatcher<T> 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<GenericUriMatcher<T>> list = node.mChildren;
      if( list == null ) {
        break;
      }
      node = null;
      int lj = list.size();
      for( int j = 0; j < lj; j++ ) {
        GenericUriMatcher<T> 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 ( T ) NO_MATCH;
      }
    }

    return node.mCode;
  }

  private static final int EXACT = 0;
  private static final int NUMBER = 1;
  private static final int TEXT = 2;

  private T mCode;
  private int mWhich;
  private String mText;
  private ArrayList<GenericUriMatcher<T>> mChildren;
}




Java Source Code List

de.wackernagel.android.contractcontentprovider.AbstractContentProviderProcessor.java
de.wackernagel.android.contractcontentprovider.ContentProviderProcessor.java
de.wackernagel.android.contractcontentprovider.ContentProviderUtils.java
de.wackernagel.android.contractcontentprovider.ContractContentProvider.java
de.wackernagel.android.contractcontentprovider.ContractSQLiteOpenHelper.java
de.wackernagel.android.contractcontentprovider.Contract.java
de.wackernagel.android.contractcontentprovider.DefaultContentProviderProcessor.java
de.wackernagel.android.contractcontentprovider.GenericUriMatcher.java
de.wackernagel.android.contractcontentprovider.sample.MainActivity.java
de.wackernagel.android.contractcontentprovider.sample.provider.CustomerContract.java
de.wackernagel.android.contractcontentprovider.sample.provider.SampleProvider.java