/**
   * Creates the AxisConfiguration object using an XML document. Subclasses of this class must
   * provide the XML via an input stream. The concrete implementation can store the XML file
   * wherever it wants as we only need an InputStream
   */
  public AxisConfiguration getAxisConfiguration() throws AxisFault {
    if (axisConfig != null) {
      // we have already initialized
      return axisConfig;
    }
    try {

      // create a new AxisConfiguration
      axisConfig = new AxisConfiguration();

      // get the config XML input stream
      InputStream in = getConfigXml();
      // build the configuration
      AxisConfigBuilder builder = new AxisConfigBuilder(in, axisConfig, null);
      builder.populateConfig();
    } catch (Exception e) {
      e.printStackTrace();
      throw AxisFault.makeFault(e);
    }
    // set this object as the Axis configurator. Axis will call loadServices().
    axisConfig.setConfigurator(this);
    return axisConfig;
  }
  public AxisConfiguration populateAxisConfiguration(InputStream in) throws DeploymentException {
    axisConfig = TenantAxisConfiguration.createInstance();
    PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getCurrentContext(axisConfig);
    carbonContext.setTenantId(tenantId);
    carbonContext.setTenantDomain(tenantDomain);

    boolean isUrlRepo = CarbonUtils.isURL(repoLocation);
    if (repoLocation != null && repoLocation.trim().length() != 0) {
      try {
        if (isUrlRepo) {
          URL axis2Repository = new URL(repoLocation);
          axisConfig.setRepository(axis2Repository);
        } else {
          axisConfig.setRepository(new URL("file://" + repoLocation));
        }
      } catch (MalformedURLException e) {
        throw new DeploymentException("Invalid URL " + repoLocation, e);
      }
    }

    // Notify all observers
    if (bundleContext != null) {
      ServiceTracker tracker =
          new ServiceTracker(
              bundleContext, PreAxisConfigurationPopulationObserver.class.getName(), null);
      tracker.open();
      Object[] services = tracker.getServices();
      if (services != null) {
        for (Object service : services) {
          ((PreAxisConfigurationPopulationObserver) service).createdAxisConfiguration(axisConfig);
        }
      }
      tracker.close();
    }
    try {
      // Add the relevant AxisObservers to the tenantAxisConfig
      if (bundleContext != null) {
        ServiceTracker tracker =
            new ServiceTracker(bundleContext, AxisObserver.class.getName(), null);
        tracker.open();
        ServiceReference[] serviceRefs = tracker.getServiceReferences();
        if (serviceRefs != null) {
          for (ServiceReference serviceRef : serviceRefs) {
            if (serviceRef.getProperty(MultitenantConstants.TENANT_ID) != null
                && tenantId == (Integer) serviceRef.getProperty(MultitenantConstants.TENANT_ID)) {
              axisConfig.addObservers((AxisObserver) bundleContext.getService(serviceRef));
            }
          }
        }
        tracker.close();
      }

      // Set services dir
      File servicesDir =
          new File(repoLocation + File.separator + CarbonUtils.getAxis2ServicesDir(axisConfig));
      if (!servicesDir.exists() && !servicesDir.mkdirs()) {
        throw new DeploymentException(
            "Could not create services directory " + servicesDir.getAbsolutePath());
      }

      // Set modules dir
      String modulesDirName = "axis2modules";
      File modulesDir = new File(repoLocation + File.separator + modulesDirName);
      if (!modulesDir.exists() && !modulesDir.mkdirs()) {
        throw new DeploymentException(
            "Could not create modules directory " + modulesDir.getAbsolutePath());
      }
      axisConfig.addParameter(new Parameter(DeploymentConstants.MODULE_DRI_PATH, modulesDirName));
    } catch (AxisFault e) {
      String msg =
          "Cannot add DeploymentConstants.SERVICE_DIR_PATH or "
              + "DeploymentConstants.MODULE_DIR_PATH parameters";
      log.error(msg, e);
      throw new DeploymentException(msg, e);
    }

    carbonContext.setRegistry(RegistryType.SYSTEM_CONFIGURATION, registry);
    try {
      // TODO: The governance system registry should be passed into the tenant axis
      // configurator like the config system registry - Senaka.
      carbonContext.setRegistry(
          RegistryType.SYSTEM_GOVERNANCE,
          CarbonCoreDataHolder.getInstance()
              .getRegistryService()
              .getGovernanceSystemRegistry(tenantId));
      carbonContext.setRegistry(
          RegistryType.LOCAL_REPOSITORY,
          CarbonCoreDataHolder.getInstance().getRegistryService().getLocalRepository(tenantId));
    } catch (Exception ignored) {
      // We are not worried about the exception in here.
    }

    // The following two lines of code are kept for backward compatibility. Remove this once we
    // are certain that this is not required. -- Senaka.
    // Please also note that we no longer need to set the user realm to the configuration
    // explicitly.
    setRegistry();
    setUserRealm();

    // Add the DeploymentInterceptor for the tenant AxisConfigurations
    DeploymentInterceptor interceptor = new DeploymentInterceptor();
    interceptor.setRegistry(registry);
    interceptor.init(axisConfig);
    axisConfig.addObservers(interceptor);

    setHostName(axisConfig);

    // TCCL will be based on OSGi
    AxisConfigBuilder builder = new AxisConfigBuilder(in, axisConfig, this);
    builder.populateConfig();
    try {
      if (in != null) {
        in.close();
      }
    } catch (IOException e) {
      String msg = "error in closing input stream";
      log.error(msg, e);
    }
    axisConfig.setConfigurator(this);
    Parameter disableArtifactLoading = axisConfig.getParameter("DisableArtifactLoading");
    if (disableArtifactLoading == null || "false".equals(disableArtifactLoading.getValue())) {
      moduleDeployer = new ModuleDeployer(axisConfig);
      new Axis2ModuleRegistry(axisConfig).register(moduleBundles);
      // Add Ghost deployer registry only if ghost is on
      if (GhostDeployerUtils.isGhostOn()) {
        new GhostDeployerRegistry(axisConfig).register(deployerBundles);
      } else {
        new Axis2DeployerRegistry(axisConfig).register(deployerBundles);
      }
    }
    return axisConfig;
  }