/**
  * Read last completed process/task instance end time from carbon registry
  *
  * @param resourcePath resource path in the carbon registry
  * @param propertyPath property path in the resource
  * @return the end time of last completed process/task instance
  */
 private String readPublishTimeFromRegistry(String resourcePath, String propertyPath) {
   String time = null;
   try {
     PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
     Registry registry = carbonContext.getRegistry(RegistryType.SYSTEM_GOVERNANCE);
     if (registry != null) {
       if (registry.resourceExists(resourcePath)) {
         if (log.isDebugEnabled()) {
           log.debug("Process instance resource path exists..." + resourcePath);
         }
         Resource resource = registry.get(resourcePath);
         time = resource.getProperty(propertyPath);
       }
     } else {
       if (log.isDebugEnabled()) {
         log.debug("Registry is null...");
       }
       throw new RegistryException("Registry is null");
     }
   } catch (RegistryException e) {
     String errMsg = "Registry error while reading the process instance publish time.";
     log.error(errMsg, e);
   }
   return time;
 }
 /**
  * Write last completed task instance end time to carbon registry
  *
  * @param historicTaskInstanceList List of historic task instances
  */
 private void writeTaskEndTimeToRegistry(List<HistoricTaskInstance> historicTaskInstanceList) {
   if (log.isDebugEnabled()) {
     log.debug("Start writing last completed task instance end time...");
   }
   Date lastTaskInstanceDate =
       historicTaskInstanceList.get(historicTaskInstanceList.size() - 1).getEndTime();
   try {
     PrivilegedCarbonContext privilegedContext =
         PrivilegedCarbonContext.getThreadLocalCarbonContext();
     Registry registry = privilegedContext.getRegistry(RegistryType.SYSTEM_GOVERNANCE);
     Resource resource;
     if (!registry.resourceExists(AnalyticsPublisherConstants.TASK_RESOURCE_PATH)) {
       resource = registry.newResource();
       resource.addProperty(
           AnalyticsPublisherConstants.LAST_TASK_INSTANCE_END_TIME,
           String.valueOf(lastTaskInstanceDate));
       registry.put(AnalyticsPublisherConstants.TASK_RESOURCE_PATH, resource);
     } else {
       resource = registry.get(AnalyticsPublisherConstants.TASK_RESOURCE_PATH);
       resource.setProperty(
           AnalyticsPublisherConstants.LAST_TASK_INSTANCE_END_TIME,
           String.valueOf(lastTaskInstanceDate));
       registry.put(AnalyticsPublisherConstants.TASK_RESOURCE_PATH, resource);
     }
     if (log.isDebugEnabled()) {
       log.debug("End of writing last completed task instance end time...");
     }
   } catch (RegistryException e) {
     String errMsg = "Registry error while writing the task instance end time.";
     log.error(errMsg, e);
   }
 }
 private void loadBAMProfileFromRegistry(
     BAMServerProfile bamServerProfile, Registry registry, String location) {
   try {
     if (registry.resourceExists(location)) {
       Resource resource = registry.get(location);
       String resourceContent = new String((byte[]) resource.getContent());
       OMElement resourceElement =
           new StAXOMBuilder(new ByteArrayInputStream(resourceContent.getBytes()))
               .getDocumentElement();
       processBAMServerProfileName(resourceElement, bamServerProfile);
       processCredentialElement(resourceElement, bamServerProfile);
       processConnectionElement(resourceElement, bamServerProfile);
       processKeyStoreElement(resourceElement, bamServerProfile);
       processStreamsElement(resourceElement, bamServerProfile);
     } else {
       String errMsg = "The resource: " + location + " does not exist.";
       handleError(errMsg);
     }
   } catch (RegistryException e) {
     String errMsg =
         "Error occurred while reading the resource from registry: "
             + location
             + " to build the BAM server profile: "
             + profileLocation;
     handleError(errMsg, e);
   } catch (XMLStreamException e) {
     String errMsg =
         "Error occurred while creating the OMElement out of BAM server "
             + "profile: "
             + profileLocation;
     handleError(errMsg, e);
   } catch (CryptoException e) {
     String errMsg =
         "Error occurred while decrypting password in BAM server profile: " + profileLocation;
     handleError(errMsg, e);
   }
 }
 private void setupEmailTemplates() throws EmailSenderConfigurationFailedException {
   File templateDir =
       new File(
           CarbonUtils.getCarbonHome()
               + File.separator
               + "repository"
               + File.separator
               + "resources"
               + File.separator
               + "email-templates");
   if (!templateDir.exists()) {
     if (log.isDebugEnabled()) {
       log.debug(
           "The directory that is expected to use as the container for all email templates is not "
               + "available. Therefore, no template is uploaded to the registry");
     }
   }
   if (templateDir.canRead()) {
     File[] templates =
         templateDir.listFiles(
             new FilenameFilter() {
               @Override
               public boolean accept(File dir, String name) {
                 name = name.toLowerCase();
                 return name.endsWith(".vm");
               }
             });
     try {
       Registry registry =
           EmailSenderDataHolder.getInstance().getRegistryService().getConfigSystemRegistry();
       if (!registry.resourceExists(EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH)) {
         Collection collection = registry.newCollection();
         registry.put(EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH, collection);
         for (File template : templates) {
           Resource resource = registry.newResource();
           String contents = FileUtils.readFileToString(template);
           resource.setContent(contents.getBytes());
           registry.put(
               EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH + "/" + template.getName(), resource);
         }
       } else {
         /* Existence of a given resource is not checked consciously, before performing registry.put() below.
          *  The rationale is that, the only less expensive way that one can check if a resource exists is
          *  that through registry.resourceExists(), which only checks if 'some' resource exists at the given
          *  registry path. However, this does not capture scenarios where there can be updated contents to
          *  the same resource of which the path hasn't changed after it has been initialized for the first
          *  time. Therefore, whenever the server starts-up, all email templates are updated just to avoid
          *  the aforementioned problem */
         for (File template : templates) {
           Resource resource = registry.newResource();
           String contents = FileUtils.readFileToString(template);
           resource.setContent(contents.getBytes());
           registry.put(
               EMAIL_TEMPLATE_DIR_RELATIVE_REGISTRY_PATH + "/" + template.getName(), resource);
         }
       }
     } catch (RegistryException e) {
       throw new EmailSenderConfigurationFailedException(
           "Error occurred while setting up email templates", e);
     } catch (FileNotFoundException e) {
       throw new EmailSenderConfigurationFailedException(
           "Error occurred while writing template file "
               + "contents as an input stream of a resource",
           e);
     } catch (IOException e) {
       throw new EmailSenderConfigurationFailedException(
           "Error occurred while serializing file " + "contents to a string", e);
     }
   }
 }
  @Override
  public void updateApplication(
      ServiceProvider serviceProvider, String tenantDomain, String userName)
      throws IdentityApplicationManagementException {
    try {

      try {
        startTenantFlow(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);

        IdentityServiceProviderCacheKey cacheKey =
            new IdentityServiceProviderCacheKey(tenantDomain, serviceProvider.getApplicationName());

        IdentityServiceProviderCache.getInstance().clearCacheEntry(cacheKey);

      } finally {
        endTenantFlow();
        startTenantFlow(tenantDomain, userName);
      }

      // invoking the listeners
      List<ApplicationMgtListener> listeners = ApplicationMgtListenerServiceComponent.getListners();
      for (ApplicationMgtListener listener : listeners) {
        listener.updateApplication(serviceProvider);
      }

      // check whether use is authorized to update the application.
      if (!ApplicationConstants.LOCAL_SP.equals(serviceProvider.getApplicationName())
          && !ApplicationMgtUtil.isUserAuthorized(
              serviceProvider.getApplicationName(), serviceProvider.getApplicationID())) {
        log.warn(
            "Illegal Access! User "
                + CarbonContext.getThreadLocalCarbonContext().getUsername()
                + " does not have access to the application "
                + serviceProvider.getApplicationName());
        throw new IdentityApplicationManagementException("User not authorized");
      }

      ApplicationDAO appDAO = ApplicationMgtSystemConfig.getInstance().getApplicationDAO();
      String storedAppName = appDAO.getApplicationName(serviceProvider.getApplicationID());
      appDAO.updateApplication(serviceProvider);

      ApplicationPermission[] permissions =
          serviceProvider.getPermissionAndRoleConfig().getPermissions();
      String applicationNode =
          ApplicationMgtUtil.getApplicationPermissionPath()
              + RegistryConstants.PATH_SEPARATOR
              + storedAppName;
      org.wso2.carbon.registry.api.Registry tenantGovReg =
          CarbonContext.getThreadLocalCarbonContext().getRegistry(RegistryType.USER_GOVERNANCE);

      boolean exist = tenantGovReg.resourceExists(applicationNode);
      if (exist && !storedAppName.equals(serviceProvider.getApplicationName())) {
        ApplicationMgtUtil.renameAppPermissionPathNode(
            storedAppName, serviceProvider.getApplicationName());
      }

      if (ArrayUtils.isNotEmpty(permissions)) {
        ApplicationMgtUtil.updatePermissions(serviceProvider.getApplicationName(), permissions);
      }
    } catch (Exception e) {
      String error = "Error occurred while updating the application";
      log.error(error, e);
      throw new IdentityApplicationManagementException(error, e);
    } finally {
      endTenantFlow();
    }
  }