Package wt.access

Interface CustomSecurityLabelValueTranslator

All Superinterfaces:
Serializable

public interface CustomSecurityLabelValueTranslator extends Serializable
Interface that identifies methods for translating custom security label values into internal and external formats. A custom security label value has an internal form that is used when the access control service evaluates access for an object and is used for specifying the security label value in the database when it is set on a SecurityLabeled object. A custom security label value also has an external representation that is used outside of the two areas mentioned above. The external representation is therefore used in all of the supported access control service security label APIs, and it is used as the attribute value for security labels within a TypeInstance.

Translating must be lossless. In other words, given an internal custom label value for a given custom security label, getExternalValue must always provide the same answer, and when that answer is provided to the getInternalValue method, getInternalValue comes up with the initial internal value. The same must be true when starting with an external value.

An internal custom security label value must not contain the "=" or "," characters. All other characters are allowed. There are no restrictions on the external value.

When a TranslatorClass is specified for a security label value, a single instance of that class, which must implement this interface, will be instantiated and held in memory for that security label value. This occurs when the access control service is starting, and before many other services have been started. Static initializers, the default constructor, and any methods they call, cannot call other Windchill services. If you need to initialize something like a cache or local variable that requires a service, then the initialization needs to wait until the services are started to do so. There are two options to handle this.

The first option is that lazy initialization could be done the first time a method on this class is called (Windchill tries to make sure that methods of this class are not called before all services have been started, but will not absolutely guarantee it). To do the lazy initialization, use a static inner class that stores the information needed. The inner class would have static variable(s) storing the necessary information. An example might be if the custom class wanted to store a principal reference to a group for later comparisons. It should not get that principal reference during initialization, because it would require a call to organization services, which starts after access control. The inner class, during its static initialization, could populate that method variable. The only use of the inner class will be in the overridden methods. The inner class would not get loaded and the static field will not be set until the first time it is referenced during run-time (the first call to the method). For example:

 public class MyCustomTranslator implements CustomSecurityLabelValueTranslator {
    private static class LazyHolder {
       public static final Object SOME_RESOURCE = // Some call to get the resource you want;
    }

    public String getExternalValue(String label_name, String internal_value) throws WTException {
       // Use LazyHolder.SOME_RESOURCE in some way to return result.
    }

    ...

 }
 
The other benefit of the above approach is that it is guaranteed to be thread-safe, since the lazy initialization is done while the inner class is being loaded by the class loader, which can only happen in one thread. The second option is if it is necessary to know for sure when the services are started, the custom class will need to register for the ALL_SERVICES_STARTED event and do the initialization then. For example:
 static {
    ManagerServiceFactory.getDefault()
          .addEventListener(new ServiceEventListenerAdapter(MyCustomTranslator.class.getName()) {
             public void notifyVetoableEvent(Object event) throws WTException {
                // Do your initialization here.
             }
          }, StandardManagerServiceEvent.generateEventKey(StandardManagerServiceEvent.ALL_SERVICES_STARTED));
 }
 
This way will guarantee that the initialization won't occur until all services are available, but will require the class to handle the case where the methods are called before initialization occurs. It is up to the class itself to decide how to return from the methods if they are called before everything is initialized.

Supported API: true

Extendable: true
  • Method Summary

    Modifier and Type
    Method
    Description
    getExternalValue(String label_name, String internal_value)
    Translates an internal custom security label value into an external representation.
    getInternalValue(String label_name, String external_value)
    Translates an external custom security label value into an internal representation.
  • Method Details

    • getExternalValue

      String getExternalValue(String label_name, String internal_value) throws WTException
      Translates an internal custom security label value into an external representation.

      Supported API: true
      Parameters:
      label_name - The security label name associated with the value
      internal_value - Internal custom security label value to translate
      Returns:
      String External representation of the internal value
      Throws:
      WTException - Thrown when the internal value cannot be mapped to an external value
    • getInternalValue

      String getInternalValue(String label_name, String external_value) throws WTException
      Translates an external custom security label value into an internal representation.

      Supported API: true
      Parameters:
      label_name - The security label name associated with the value
      external_value - External custom security label value to translate
      Returns:
      String Internal representation of the external value
      Throws:
      WTException - Thrown when the external value cannot be mapped to an internal value