Package org.osgi.service.condpermadmin

Source Code of org.osgi.service.condpermadmin.BundleLocationCondition

/*
* Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
*
* 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 org.osgi.service.condpermadmin;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Hashtable;

import org.osgi.framework.Bundle;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;

/**
* Condition to test if the location of a bundle matches or does not match a
* pattern. Since the bundle's location cannot be changed, this condition is
* immutable.
*
* <p>
* Pattern matching is done according to the filter string matching rules.
*
* @ThreadSafe
* @version $Revision: 5901 $
*/
public class BundleLocationCondition {
  private static final String  CONDITION_TYPE  = "org.osgi.service.condpermadmin.BundleLocationCondition";

  /**
   * Constructs a condition that tries to match the passed Bundle's location
   * to the location pattern.
   *
   * @param bundle The Bundle being evaluated.
   * @param info The ConditionInfo from which to construct the condition. The
   *        ConditionInfo must specify one or two arguments. The first
   *        argument of the ConditionInfo specifies the location pattern
   *        against which to match the bundle location. Matching is done
   *        according to the filter string matching rules. Any '*' characters
   *        in the first argument are used as wildcards when matching bundle
   *        locations unless they are escaped with a '\' character. The
   *        Condition is satisfied if the bundle location matches the pattern.
   *        The second argument of the ConditionInfo is optional. If a second
   *        argument is present and equal to "!", then the satisfaction of the
   *        Condition is negated. That is, the Condition is satisfied if the
   *        bundle location does NOT match the pattern. If the second argument
   *        is present but does not equal "!", then the second argument is
   *        ignored.
   * @return Condition object for the requested condition.
   */
  static public Condition getCondition(final Bundle bundle,
      final ConditionInfo info) {
    if (!CONDITION_TYPE.equals(info.getType()))
      throw new IllegalArgumentException(
          "ConditionInfo must be of type \"" + CONDITION_TYPE + "\"");
    String[] args = info.getArgs();
    if (args.length != 1 && args.length != 2)
      throw new IllegalArgumentException("Illegal number of args: " + args.length);
    String bundleLocation = (String) AccessController.doPrivileged(new PrivilegedAction() {
          public Object run() {
            return bundle.getLocation();
          }
        });
    Filter filter = null;
    try {
      filter = FrameworkUtil.createFilter("(location="
          + escapeLocation(args[0]) + ")");
    }
    catch (InvalidSyntaxException e) {
      // this should never happen, but just in case
      throw new RuntimeException("Invalid filter: " + e.getFilter(), e);
    }
    Hashtable matchProps = new Hashtable(2);
    matchProps.put("location", bundleLocation);
    boolean negate = (args.length == 2) ? "!".equals(args[1]) : false;
    return (negate ^ filter.match(matchProps)) ? Condition.TRUE
        : Condition.FALSE;
  }

  private BundleLocationCondition() {
    // private constructor to prevent objects of this type
  }

  /**
   * Escape the value string such that '(', ')' and '\' are escaped. The '\'
   * char is only escaped if it is not followed by a '*'.
   *
   * @param value unescaped value string.
   * @return escaped value string.
   */
  private static String escapeLocation(final String value) {
    boolean escaped = false;
    int inlen = value.length();
    int outlen = inlen << 1; /* inlen * 2 */

    char[] output = new char[outlen];
    value.getChars(0, inlen, output, inlen);

    int cursor = 0;
    for (int i = inlen; i < outlen; i++) {
      char c = output[i];
      switch (c) {
        case '\\' :
          if (i + 1 < outlen && output[i + 1] == '*')
            break;
        case '(' :
        case ')' :
          output[cursor] = '\\';
          cursor++;
          escaped = true;
          break;
      }

      output[cursor] = c;
      cursor++;
    }

    return escaped ? new String(output, 0, cursor) : value;
  }
}
TOP

Related Classes of org.osgi.service.condpermadmin.BundleLocationCondition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.