Package org.eclipse.osgi.framework.internal.core

Source Code of org.eclipse.osgi.framework.internal.core.ConditionalPermissionInfoImpl

/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.osgi.framework.internal.core;

import java.io.File;
import java.io.Serializable;
import java.lang.reflect.*;
import java.security.*;
import java.util.ArrayList;
import org.osgi.framework.Bundle;
import org.osgi.service.condpermadmin.*;
import org.osgi.service.permissionadmin.PermissionInfo;

/**
*
* This is a runtime embodiment of the data stored in ConditionalPermissionInfo.
* It has methods to facilitate the management of Conditions and Permissions at
* runtime.
*/
public class ConditionalPermissionInfoImpl implements ConditionalPermissionInfo, Serializable {
  private static final long serialVersionUID = 3258130245704825139L;
  /**
   * The permissions enabled by the associated Conditions.
   */
  PermissionInfo perms[];
  /**
   * The conditions that must be satisfied to enable the corresponding
   * permissions.
   */
  ConditionInfo conds[];

  /**
   * The name of the ConditionalPermissionInfo
   */
  private String name;

  /**
   * When true, this object has been deleted and any information retrieved
   * from it should be discarded.
   */
  private boolean deleted = false;

  /**
   * When true, this object has been deleted and any information retrieved
   * from it should be discarded.
   */
  boolean isDeleted() {
    return deleted;
  }

  public ConditionalPermissionInfoImpl(String encoded) {
    decode(encoded);
  }

  public ConditionalPermissionInfoImpl(String name, ConditionInfo conds[], PermissionInfo perms[]) {
    this.name = name;
    this.conds = conds;
    this.perms = perms;
  }

  private void decode(String encoded) {
    int start = encoded.indexOf('{');
    int end = encoded.lastIndexOf('}');
    if (start < 0 || end < start)
      throw new IllegalArgumentException(encoded);
    if (start != 0)
      name = encoded.substring(0, start);
    char[] chars = encoded.substring(start + 1, end).toCharArray();
    ArrayList condList = new ArrayList();
    ArrayList permList = new ArrayList();
    int pos = 0;
    while (pos < chars.length) {
      while (pos < chars.length && chars[pos] != '[' && chars[pos] != '(')
        pos++;
      if (pos == chars.length)
        break; // no perms or conds left
      int startPos = pos;
      char endChar = chars[startPos] == '[' ? ']' : ')';
      while (chars[pos] != endChar) {
        if (chars[pos] == '"') {
          pos++;
          while (chars[pos] != '"') {
            if (chars[pos] == '\\')
              pos++;
            pos++;
          }
        }
        pos++;
      }
      int endPos = pos;
      String token = new String(chars, startPos, endPos - startPos + 1);
      if (endChar == ']')
        condList.add(new ConditionInfo(token));
      else
        permList.add(new PermissionInfo(token));
      pos++;
    }
    conds = (ConditionInfo[]) condList.toArray(new ConditionInfo[condList.size()]);
    perms = (PermissionInfo[]) permList.toArray(new PermissionInfo[permList.size()]);
  }

  public String getName() {
    return name;
  }

  /**
   * @see org.osgi.service.condpermadmin.ConditionalPermissionInfo#getConditionInfos()
   */
  public ConditionInfo[] getConditionInfos() {
    if (conds == null)
      return null;
    ConditionInfo[] results = new ConditionInfo[conds.length];
    System.arraycopy(conds, 0, results, 0, conds.length);
    return results;
  }

  /* Used to find permission constructors in addPermissions */
  static private final Class twoStringClassArray[] = new Class[] {String.class, String.class};
  static private final Class oneStringClassArray[] = new Class[] {String.class};
  static private final Class noArgClassArray[] = new Class[] {};
  static private final Class[][] permClassArrayArgs = new Class[][] {noArgClassArray, oneStringClassArray, twoStringClassArray};
  /* Used to find condition constructors getConditions */
  static private final Class[] condClassArray = new Class[] {Bundle.class, ConditionInfo.class};

  /**
   * Adds the permissions of the given type (if any) that are part of this
   * ConditionalPermissionInfo to the specified collection. The Permission
   * instances are constructed using the specified permClass.
   *
   * @param collection the collection to add to.
   * @param permClass the class to use to construct Permission instances.
   * @return the number of Permissions added.
   * @throws NoSuchMethodException
   * @throws SecurityException
   * @throws InvocationTargetException
   * @throws IllegalAccessException
   * @throws InstantiationException
   * @throws IllegalArgumentException
   */
  int addPermissions(AbstractBundle bundle, PermissionCollection collection, Class permClass) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
    String permClassName = permClass.getName();
    Constructor constructor = null;
    int numArgs = -1;
    for (int i = permClassArrayArgs.length - 1 ; i >= 0; i--) {
      try {
        constructor = permClass.getConstructor(permClassArrayArgs[i]);
        numArgs = i;
        break;
      } catch (NoSuchMethodException e) {
        // ignore
      }
    }
    if (constructor == null)
      throw new NoSuchMethodException(permClass.getName() + ".<init>()"); //$NON-NLS-1$
    int count = 0;
    /*
     * TODO: We need to cache the permission constructors to enhance performance (see bug 118813).
     */
    for (int i = 0; i < perms.length; i++) {
      if (perms[i].getType().equals(permClassName)) {
        count++;
        String args[] = new String[numArgs];
        if (numArgs > 0)
          args[0] = perms[i].getName();
        if (numArgs > 1)
          args[1] = perms[i].getActions();
        if (perms[i].getType().equals("java.io.FilePermission")) { //$NON-NLS-1$
          // map FilePermissions for relative names to the bundle's data area
          if (!args[0].equals("<<ALL FILES>>")) { //$NON-NLS-1$
            File file = new File(args[0]);
            if (!file.isAbsolute()) { // relative name
              if (bundle == null) // default permissions
                continue; // no relative file permissions
              File target = bundle.framework.getDataFile(bundle, args[0]);
              if (target == null) // no bundle data file area
                continue; // no relative file permissions
              args[0] = target.getPath();
            }
          }
        }
        collection.add((Permission) constructor.newInstance(args));
      }
    }
    return count;
  }

  /**
   * Returns the Condition objects associated with this ConditionalPermissionInfo.
   *
   * @param bundle the bundle to be used to construct the Conditions.
   *
   * @return the array of Conditions that must be satisfied before permissions
   *         in the ConditionPermissionInfoImpl can be used.
   */
  Condition[] getConditions(Bundle bundle) {
    Condition conditions[] = new Condition[conds.length];
    for (int i = 0; i < conds.length; i++) {
      /*
       * TODO: I think we can pre-get the Constructors in our own
       * constructor
       */
      Class clazz;
      try {
        clazz = Class.forName(conds[i].getType());
      } catch (ClassNotFoundException e) {
        /* If the class isn't there, we fail */
        return null;
      }
      Constructor constructor = null;
      Method method = null;
      try {
        method = clazz.getMethod("getCondition", condClassArray); //$NON-NLS-1$
        if ((method.getModifiers() & Modifier.STATIC) == 0)
          method = null;
      } catch (NoSuchMethodException e) {
        // This is a normal case
      }
      if (method == null)
        try {
          constructor = clazz.getConstructor(condClassArray);
        } catch (NoSuchMethodException e) {
          // TODO should post a FrameworkEvent of type error here
          conditions[i] = Condition.FALSE;
          continue;
        }

      Object args[] = {bundle, conds[i]};
      try {
        if (method != null)
          conditions[i] = (Condition) method.invoke(null, args);
        else
          conditions[i] = (Condition) constructor.newInstance(args);
      } catch (Throwable t) {
        // TODO should post a FrameworkEvent of type error here
        conditions[i] = Condition.FALSE;
      }
    }
    return conditions;
  }

  /**
   * @see org.osgi.service.condpermadmin.ConditionalPermissionInfo#getPermissionInfos()
   */
  public PermissionInfo[] getPermissionInfos() {
    if (perms == null)
      return null;
    PermissionInfo[] results = new PermissionInfo[perms.length];
    System.arraycopy(perms, 0, results, 0, perms.length);
    return results;
  }

  /**
   *
   * @see org.osgi.service.condpermadmin.ConditionalPermissionInfo#delete()
   */
  public void delete() {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkPermission(new AllPermission());
    deleted = true;
    condAdmin.deleteConditionalPermissionInfo(this);
  }

  private static ConditionalPermissionAdminImpl condAdmin;

  static void setConditionalPermissionAdminImpl(ConditionalPermissionAdminImpl condAdmin) {
    ConditionalPermissionInfoImpl.condAdmin = condAdmin;
  }

  public String toString() {
    StringBuffer result = new StringBuffer();
    if (name != null)
      result.append(name);
    ConditionInfo[] curConds = getConditionInfos();
    PermissionInfo[] curPerms = getPermissionInfos();
    result.append('{').append(' ');
    if (curConds != null)
      for (int i = 0; i < curConds.length; i++)
        result.append(curConds[i].getEncoded()).append(' ');
    if (curPerms != null)
      for (int i = 0; i < curPerms.length; i++)
        result.append(curPerms[i].getEncoded()).append(' ');
    result.append('}');
    return result.toString();
  }
}
TOP

Related Classes of org.eclipse.osgi.framework.internal.core.ConditionalPermissionInfoImpl

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.