Package org.osgi.service.application

Source Code of org.osgi.service.application.ApplicationAdminPermission$SignerWrapper

/*
* Copyright (c) OSGi Alliance (2004, 2010). 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.application;

import java.security.Permission;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;

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

/**
* This class implements permissions for manipulating applications and their
* instances.
* <P>
* ApplicationAdminPermission can be targeted to applications that matches the
* specified filter.
* <P>
* ApplicationAdminPermission may be granted for different actions:
* {@code lifecycle}, {@code schedule} and {@code lock}. The
* permission {@code schedule} implies the permission
* {@code lifecycle}.
*
* @version $Id: 8c7941578972d6f61ed9aeffac374a0b8c294056 $
*/
public class ApplicationAdminPermission extends Permission {
  private static final long serialVersionUID = 1L;
 
  /**
   * Allows the lifecycle management of the target applications.
   */
  public static final String LIFECYCLE_ACTION = "lifecycle";

  /**
   * Allows scheduling of the target applications. The permission to
   * schedule an application implies that the scheduler can also
   * manage the lifecycle of that application i.e. {@code schedule}
   * implies {@code lifecycle}
   */
  public static final String SCHEDULE_ACTION = "schedule";

  /**
   * Allows setting/unsetting the locking state of the target applications.
   */
  public static final String LOCK_ACTION = "lock";

  private ApplicationDescriptor  applicationDescriptor;

  /**
   * Constructs an ApplicationAdminPermission. The {@code filter}
   * specifies the target application. The {@code filter} is an
   * LDAP-style filter, the recognized properties are {@code signer}
   * and {@code pid}. The pattern specified in the {@code signer}
   * is matched with the Distinguished Name chain used to sign the application.
   * Wildcards in a DN are not matched according to the filter string rules,
   * but according to the rules defined for a DN chain. The attribute
   * {@code pid} is matched with the PID of the application according to
   * the filter string rules.
   * <p>
   * If the {@code filter} is {@code null} then it matches
   * {@code "*"}. If
   * {@code actions} is {@code "*"} then it identifies all the
   * possible actions.
   *
   * @param filter
   *            filter to identify application. The value {@code null}
   *            is equivalent to {@code "*"} and it indicates "all application".
   * @param actions
   *            comma-separated list of the desired actions granted on the
   *            applications or "*" means all the actions. It must not be
   *            {@code null}. The order of the actions in the list is
   *            not significant.
   * @throws InvalidSyntaxException
   *            is thrown if the specified {@code filter} is not syntactically
   *            correct.
   *
   * @exception NullPointerException
   *                is thrown if the actions parameter is {@code null}
   *
   * @see ApplicationDescriptor
   * @see org.osgi.framework.AdminPermission
   */
  public ApplicationAdminPermission(String filter, String actions) throws InvalidSyntaxException {
    super(filter == null ? "*" : filter);
   
    if( filter == null )
      filter = "*";
   
    if( actions == null )
      throw new NullPointerException( "Action string cannot be null!" );
   
    this.applicationDescriptor = null;
    this.filter = (filter == null ? "*" : filter);
    this.actions = actions;

    if( !filter.equals( "*" ) && !filter.equals( "<<SELF>>" ) )
      FrameworkUtil.createFilter( this.filter ); // check if the filter is valid
    init();
  }
 
  /**
   * This contructor should be used when creating {@code ApplicationAdminPermission}
   * instance for {@code checkPermission} call.
   * @param application the tareget of the operation, it must not be {@code null}
   * @param actions the required operation. it must not be {@code null}
   * @throws NullPointerException if any of the arguments is null.
   */
  public ApplicationAdminPermission(ApplicationDescriptor application, String actions) {
    super(application.getApplicationId());
       
    if( application == null || actions == null )
      throw new NullPointerException( "ApplicationDescriptor and action string cannot be null!" );
   
    this.filter = application.getApplicationId();
    this.applicationDescriptor = application;
    this.actions = actions;
   
    init();
  }
 
  /**
   * This method can be used in the {@link java.security.ProtectionDomain}
   * implementation in the {@code implies} method to insert the
   * application ID of the current application into the permission being
   * checked. This enables the evaluation of the
   * {@code &lt;&lt;SELF&gt;&gt;} pseudo targets.
   * @param applicationId the ID of the current application.
   * @return the permission updated with the ID of the current application
   */
  public ApplicationAdminPermission setCurrentApplicationId(String applicationId) {
    ApplicationAdminPermission newPerm = null;
   
    if( this.applicationDescriptor == null ) {
      try {
        newPerm = new ApplicationAdminPermission( this.filter, this.actions );
      }catch( InvalidSyntaxException e ) {
        throw new RuntimeException(e); /* this can never happen */
      }
    }
    else 
        newPerm = new ApplicationAdminPermission( this.applicationDescriptor, this.actions );
   
    newPerm.applicationID = applicationId;
   
    return newPerm;
  }

  /**
   * Checks if the specified {@code permission} is implied by this permission.
   * The method returns true under the following conditions:
   * <UL>
   * <LI> This permission was created by specifying a filter (see {@link #ApplicationAdminPermission(String, String)})
   * <LI> The implied {@code otherPermission} was created for a particular {@link ApplicationDescriptor}
   *      (see {@link #ApplicationAdminPermission(ApplicationDescriptor, String)})
   * <LI> The {@code filter} of this permission mathes the {@code ApplicationDescriptor} specified
   *      in the {@code otherPermission}. If the filter in this permission is the
   *      {@code &lt;&lt;SELF&gt;&gt;} pseudo target, then the currentApplicationId set in the
   *      {@code otherPermission} is compared to the application Id of the target
   *      {@code ApplicationDescriptor}.
   * <LI> The list of permitted actions in this permission contains all actions required in the
   *      {@code otherPermission} 
   * </UL>
   * Otherwise the method returns false.
   * @param otherPermission the implied permission
   * @return true if this permission implies the {@code otherPermission}, false otherwise.
   */
  public boolean implies(Permission otherPermission) {
      if( otherPermission == null )
        return false;
       
      if(!(otherPermission instanceof ApplicationAdminPermission))
          return false;

      ApplicationAdminPermission other = (ApplicationAdminPermission) otherPermission;

      if( !filter.equals("*") ) {
         if( other.applicationDescriptor == null )
           return false;
        
        if( filter.equals( "<<SELF>>") ) {
            if( other.applicationID == null )
              return false; /* it cannot be, this might be a bug */
           
          if( !other.applicationID.equals( other.applicationDescriptor.getApplicationId() ) )
            return false;
        }
        else {
          Hashtable props = new Hashtable();
          props.put( "pid", other.applicationDescriptor.getApplicationId() );
          props.put( "signer", new SignerWrapper( other.applicationDescriptor ) );
                   
          Filter flt = getFilter();
          if( flt == null )
            return false;
         
          if( !flt.match( props ) )
            return false;
        }
      }
     
      if( !actionsVector.containsAll( other.actionsVector ) )
        return false;
     
      return true;
  }

  public boolean equals(Object with) {
    if( with == null || !(with instanceof ApplicationAdminPermission) )
      return false;
   
    ApplicationAdminPermission other = (ApplicationAdminPermission)with;   
   
    // Compare actions:
    if( other.actionsVector.size() != actionsVector.size() )
      return false;
   
    for( int i=0; i != actionsVector.size(); i++ )
      if( !other.actionsVector.contains( actionsVector.get( i ) ) )
        return false;
   
   
    return equal(this.filter, other.filter ) && equal(this.applicationDescriptor, other.applicationDescriptor)
        && equal(this.applicationID, other.applicationID);
  }
 
  /**
   * Compares parameters for equality. If both object are null, they are considered
   * equal.
   * @param a object to compare
   * @param b other object to compare
   * @return true if both objects are equal or both are null
   */
  private static boolean equal(Object a, Object b) {
    // This equation is true if both references are null or both point
    // to the same object. In both cases they are considered as equal.
    if( a == b ) {
      return true;
    }
   
    return a.equals(b);
  }

  public int hashCode() {
    int hc = 0;
    for( int i=0; i != actionsVector.size(); i++ )
      hc ^= ((String)actionsVector.get( i )).hashCode();
    hc ^= (null == this.filter )? 0 : this.filter.hashCode();
    hc ^= (null == this.applicationDescriptor) ? 0 : this.applicationDescriptor.hashCode();
    hc ^= (null == this.applicationID) ? 0 : this.applicationID.hashCode();
    return hc;
  }

  /**
   * Returns the actions of this permission.
   * @return the actions specified when this permission was created
   */
  public String getActions() {
    return actions;
  }

  private String applicationID;

  private static final Vector ACTIONS = new Vector();
  private              Vector actionsVector;
  private final        String filter;
  private final        String actions;
  private              Filter appliedFilter = null;
 
  static {
      ACTIONS.add(LIFECYCLE_ACTION);
      ACTIONS.add(SCHEDULE_ACTION);
      ACTIONS.add(LOCK_ACTION);
  }

  private static Vector actionsVector(String actions) {
      Vector v = new Vector();
      StringTokenizer t = new StringTokenizer(actions.toUpperCase(), ",");
      while (t.hasMoreTokens()) {
          String action = t.nextToken().trim();
          v.add(action.toLowerCase());
      }
     
      if( v.contains( SCHEDULE_ACTION ) && !v.contains( LIFECYCLE_ACTION ) )
        v.add( LIFECYCLE_ACTION );
     
      return v;
  }
 

  private static class SignerWrapper extends Object {
    private String pattern;
    private ApplicationDescriptor appDesc;
   
    /**
     * @param pattern
     */
    public SignerWrapper(String pattern) {
      this.pattern = pattern;         
    }
   
    SignerWrapper(ApplicationDescriptor appDesc) {
      this.appDesc = appDesc;
    }
   
    public boolean equals(Object o) {
      if (!(o instanceof SignerWrapper))
        return false;
      SignerWrapper other = (SignerWrapper) o;
      ApplicationDescriptor matchAppDesc = (ApplicationDescriptor) (appDesc != null ? appDesc : other.appDesc);
      String matchPattern = appDesc != null ? other.pattern : pattern;
      return matchAppDesc.matchDNChain(matchPattern);
    }
  }
 
  private void init() {
    actionsVector = actionsVector( actions );

    if ( actions.equals("*") )
      actionsVector = actionsVector( LIFECYCLE_ACTION + "," + SCHEDULE_ACTION + "," + LOCK_ACTION );
    else if (!ACTIONS.containsAll(actionsVector))
      throw new IllegalArgumentException("Illegal action!");
   
    applicationID = null;
  }
 
  private Filter getFilter() {
    if (appliedFilter == null) {
      try {
        appliedFilter = FrameworkUtil.createFilter(filter);
    } catch (InvalidSyntaxException e) {
      //we will return null
    }
    }        
    return appliedFilter;
  }
}
TOP

Related Classes of org.osgi.service.application.ApplicationAdminPermission$SignerWrapper

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.