/**
  * Registers PIP attribute handlers with the PDP against their supported attributes. This PIP
  * attribute handlers are picked from pip-config.xml file - which should be inside
  * [CARBON_HOME]\repository\conf.
  */
 public void init() {
   Map<PIPAttributeFinder, Properties> designators =
       EntitlementServiceComponent.getEntitlementConfig().getDesignators();
   Properties properties =
       EntitlementServiceComponent.getEntitlementConfig().getEngineProperties();
   if ("true".equals(properties.getProperty(PDPConstants.ATTRIBUTE_CACHING))) {
     attributeFinderCache = PIPAttributeCache.getInstance();
     attributeFinderCache.clearCache(tenantId);
   }
   // clear decision cache
   if (designators != null && !designators.isEmpty()) {
     Set<PIPAttributeFinder> pipAttributeFinders = designators.keySet();
     for (Iterator iterator = pipAttributeFinders.iterator(); iterator.hasNext(); ) {
       PIPAttributeFinder pipAttributeFinder = (PIPAttributeFinder) iterator.next();
       Set<String> attrs = pipAttributeFinder.getSupportedAttributes();
       if (attrs != null) {
         for (Iterator attrsIter = attrs.iterator(); attrsIter.hasNext(); ) {
           String attr = (String) attrsIter.next();
           if (attrFinders.containsKey(attr)) {
             List<PIPAttributeFinder> finders = attrFinders.get(attr);
             if (!finders.contains(pipAttributeFinder)) {
               finders.add(pipAttributeFinder);
               if (log.isDebugEnabled()) {
                 log.debug(
                     String.format(
                         "PIP attribute handler %1$s registered for the supported attribute %2$s",
                         pipAttributeFinder.getClass(), attr));
               }
             }
           } else {
             List<PIPAttributeFinder> finders = new ArrayList<PIPAttributeFinder>();
             finders.add(pipAttributeFinder);
             attrFinders.put(attr, finders);
             if (log.isDebugEnabled()) {
               log.debug(
                   String.format(
                       "PIP attribute handler %1$s registered for the supported attribute %2$s",
                       pipAttributeFinder.getClass(), attr));
             }
           }
         }
       }
     }
   }
 }
 /** Clears attribute cache */
 public void clearAttributeCache() {
   if (attributeFinderCache != null) {
     attributeFinderCache.clearCache(tenantId);
     if (log.isDebugEnabled()) {
       log.debug("Attribute value cache is cleared for tenant " + tenantId);
     }
     // clear decision cache
     EntitlementEngine.getInstance().clearDecisionCache(false);
   }
 }
 /** Enables attribute cache */
 public void enableAttributeCache() {
   attributeFinderCache = PIPAttributeCache.getInstance();
 }
  /*
   * (non-Javadoc)
   *
   * @see org.wso2.balana.finder.AttributeFinderModule#findAttribute(java.net.URI, java.net.URI,
   * java.net.URI, java.net.URI, org.wso2.balana.EvaluationCtx, int)
   */
  public EvaluationResult findAttribute(
      URI attributeType, URI attributeId, String issuer, URI category, EvaluationCtx context) {

    List<AttributeValue> attrBag = new ArrayList<AttributeValue>();
    // Get the list of attribute finders who are registered with this particular attribute.
    List<PIPAttributeFinder> finders = attrFinders.get(attributeId.toString());

    if (finders == null || finders.size() == 0) {
      //          there is a API for refresh attribute finder so remove this
      //			try {
      //				refreshAttributeFindersForNewAttributeId();
      //			} catch (Exception e) {
      //				log.warn("Error while refreshing attribute finders");
      //			}
      finders = attrFinders.get(attributeId.toString());
      if (finders == null || finders.size() == 0) {
        log.info("No attribute designators defined for the attribute " + attributeId.toString());
        return new EvaluationResult(BagAttribute.createEmptyBag(attributeType));
      }
    }

    try {

      for (Iterator iterator = finders.iterator(); iterator.hasNext(); ) {
        PIPAttributeFinder pipAttributeFinder = (PIPAttributeFinder) iterator.next();
        if (log.isDebugEnabled()) {
          log.debug(
              String.format(
                  "Finding attributes with the PIP attribute handler %1$s",
                  pipAttributeFinder.getClass()));
        }

        Set<String> attrs = null;
        String key = null;

        if (attributeFinderCache != null && !pipAttributeFinder.overrideDefaultCache()) {

          key =
              attributeType.toString()
                  + attributeId.toString()
                  + category.toString()
                  + encodeContext(context);

          if (issuer != null) {
            key += issuer;
          }

          if (key != null) {
            attrs = attributeFinderCache.getFromCache(tenantId, key);
          }
        }

        if (attrs == null) {
          if (log.isDebugEnabled()) {
            log.debug("Carbon Attribute Cache Miss");
          }
          attrs =
              pipAttributeFinder.getAttributeValues(
                  attributeType, attributeId, category, issuer, context);
          if (attributeFinderCache != null
              && key != null
              && !pipAttributeFinder.overrideDefaultCache()) {
            attributeFinderCache.addToCache(tenantId, key, attrs);
          }
        } else {
          if (log.isDebugEnabled()) {
            log.debug("Carbon Attribute Cache Hit");
          }
        }

        if (attrs != null) {
          for (Iterator iterAttr = attrs.iterator(); iterAttr.hasNext(); ) {
            final String attr = (String) iterAttr.next();
            AttributeValue attribute =
                EntitlementUtil.getAttributeValue(attr, attributeType.toString());
            attrBag.add(attribute);
          }
        }
      }
    } catch (ParsingException e) {
      log.error("Error while parsing attribute values from EvaluationCtx : " + e);
      ArrayList<String> code = new ArrayList<String>();
      code.add(Status.STATUS_MISSING_ATTRIBUTE);
      Status status =
          new Status(
              code, "Error while parsing attribute values from EvaluationCtx : " + e.getMessage());
      return new EvaluationResult(status);
    } catch (ParseException e) {
      e.printStackTrace();
      log.error("Error while parsing attribute values from EvaluationCtx : " + e);
      ArrayList<String> code = new ArrayList<String>();
      code.add(Status.STATUS_MISSING_ATTRIBUTE);
      Status status =
          new Status(
              code, "Error while parsing attribute values from EvaluationCtx : " + e.getMessage());
      return new EvaluationResult(status);
    } catch (URISyntaxException e) {
      log.error("Error while parsing attribute values from EvaluationCtx : " + e);
      ArrayList<String> code = new ArrayList<String>();
      code.add(Status.STATUS_MISSING_ATTRIBUTE);
      Status status =
          new Status(
              code, "Error while parsing attribute values from EvaluationCtx :" + e.getMessage());
      return new EvaluationResult(status);
    } catch (Exception e) {
      log.error("Error while retrieving attribute values from PIP  attribute finder : " + e);
      ArrayList<String> code = new ArrayList<String>();
      code.add(Status.STATUS_MISSING_ATTRIBUTE);
      Status status =
          new Status(
              code,
              "Error while retrieving attribute values from PIP"
                  + " attribute finder : "
                  + e.getMessage());
      return new EvaluationResult(status);
    }
    return new EvaluationResult(new BagAttribute(attributeType, attrBag));
  }