private Map<String, GlobalIdDesc> createGlobalIdMap(
      Collection<GlobalIdEntry> registryEntries, ServiceConfigHolder config) {

    Map<String, GlobalIdDesc> result = new HashMap<String, GlobalIdDesc>();
    Set<String> supportedGlobalId = null;
    Set<String> supportedLocales = null;
    if (config != null) {
      supportedGlobalId = config.getSupportedGlobalId();
      supportedLocales = config.getSupportedLocales();
    }
    for (GlobalIdEntry entry : registryEntries) {
      String id = entry.getId();
      boolean isDefaultRegistryEntry = entry.isDefaultGlobalId();
      boolean supported;
      if (supportedGlobalId == null || supportedGlobalId.isEmpty()) {
        // No configured list implies all IDs are supported.
        supported = true;
      } else if (isDefaultRegistryEntry) {
        supported = true;
      } else {
        supported = (supportedGlobalId.contains(id));
      }
      GlobalIdDesc idDesc = new GlobalIdDesc(entry, supported, supportedLocales);
      if (isDefaultRegistryEntry) {
        result.put(SOAConstants.DEFAULT_GLOBAL_ID, idDesc);
      } else {
        result.put(id, idDesc);
      }
    }
    return result;
  }
 private String getDispatcherClassName(ServiceConfigHolder config)
     throws ServiceCreationException {
   String implClass = config.getServiceImplClassName();
   String dispatcher = null;
   if (implClass != null) {
     dispatcher = ServiceNameUtils.getServiceDispatcherClassName(config.getAdminName(), implClass);
   }
   String implFactory = null;
   if (implClass == null) {
     implFactory = config.getServiceImplFactoryClassName();
     if (implFactory == null) {
       // Same error message for backward compatibility
       throw new ServiceCreationException(
           ErrorDataFactory.createErrorData(
               ErrorConstants.SVC_FACTORY_UNDEFINED_IMPL_CLASS_NAME, ErrorConstants.ERRORDOMAIN));
     }
     String interfaceName = config.getServiceInterfaceClassName();
     dispatcher =
         ServiceNameUtils.getServiceDispatcherClassName(config.getAdminName(), interfaceName);
   }
   return dispatcher;
 }
  private VersionCheckHandler createVersionCheckHandler(
      ServerServiceId serverSvcId, ServiceConfigHolder config, ClassLoader cl)
      throws ServiceException {
    String currentVersion = config.getMetaData().getVersion();
    if (currentVersion == null || currentVersion.length() == 0) {
      throw new ServiceCreationException(
          ErrorDataFactory.createErrorData(
              ErrorConstants.SVC_FACTORY_MISSING_SERVICE_VERSION,
              ErrorConstants.ERRORDOMAIN,
              new Object[] {serverSvcId.getAdminName()}));
    }

    Collection<String> supportedVersions = config.getSupportedVersions();
    if (supportedVersions != null) {
      supportedVersions = new ArrayList<String>(supportedVersions);
    } else {
      supportedVersions = new ArrayList<String>();
    }
    if (!supportedVersions.contains(currentVersion)) {
      supportedVersions.add(currentVersion);
    }
    supportedVersions = Collections.unmodifiableCollection(supportedVersions);

    String versionCheckClassName = config.getVersionCheckHandlerClassName();
    if (versionCheckClassName == null) {
      versionCheckClassName = SimpleVersionCheckHandler.class.getName();
    }

    VersionCheckHandler versionCheckHandler =
        ReflectionUtils.createInstance(versionCheckClassName, VersionCheckHandler.class, cl);

    VersionCheckHandlerInitContextImpl initCtx =
        new VersionCheckHandlerInitContextImpl(serverSvcId, currentVersion, supportedVersions);
    versionCheckHandler.init(initCtx);
    initCtx.kill();

    return versionCheckHandler;
  }
  private DataBindingDesc getDefaultRequestDataBinding(
      ServiceConfigHolder config,
      Collection<String> supportedDataBindings,
      Map<String, DataBindingDesc> bindings,
      String adminName)
      throws ServiceCreationException {
    String defaultBinding = config.getDefaultRequestDataBinding();
    if (defaultBinding == null) {
      defaultBinding = BindingConstants.PAYLOAD_XML;
    }
    if (supportedDataBindings != null && !supportedDataBindings.isEmpty()) {
      if (!supportedDataBindings.contains(defaultBinding)) {
        throw new ServiceCreationException(
            ErrorDataFactory.createErrorData(
                ErrorConstants.SVC_FACTORY_INVALID_DEFAULT_DATA_BINDING,
                ErrorConstants.ERRORDOMAIN,
                new Object[] {adminName, defaultBinding, supportedDataBindings.toString()}));
      }
    }

    return bindings.get(defaultBinding);
  }
  private UrlMappingsDesc loadUrlMappings(String adminName, ServiceConfigHolder config)
      throws ServiceCreationException {
    OptionList options = config.getHeaderMappingOptions();
    if (options == null) {
      return UrlMappingsDesc.EMPTY_MAPPINGS;
    }
    List<NameValue> nameValueList = options.getOption();
    Map<Integer, String> pathMap = new HashMap<Integer, String>();
    Map<String, String> queryMap = new HashMap<String, String>();
    Set<String> rejectSet = new HashSet<String>();
    Set<String> nameSet = new HashSet<String>();

    String queryOpMapping = null;
    for (NameValue nv : nameValueList) {
      String rawname = nv.getName();
      String name = SOAHeaders.normalizeName(rawname, true);
      if (!SOAHeaders.isSOAHeader(name)) {
        throw new ServiceCreationException(
            ErrorDataFactory.createErrorData(
                ErrorConstants.SVC_FACTORY_INVALID_HEADER_NAME,
                ErrorConstants.ERRORDOMAIN,
                new Object[] {adminName, name}));
      }

      if (nameSet.contains(name)) {
        throw new ServiceCreationException(
            ErrorDataFactory.createErrorData(
                ErrorConstants.SVC_FACTORY_DUPLICATE_HEADER_KEY,
                ErrorConstants.ERRORDOMAIN,
                new Object[] {adminName, name}));
      }
      nameSet.add(name);

      String value = nv.getValue();
      if (value.startsWith("query[")) {
        if (!value.endsWith("]")) {
          throw new ServiceCreationException(
              ErrorDataFactory.createErrorData(
                  ErrorConstants.SVC_FACTORY_INVALID_MAPPING_VALUE,
                  ErrorConstants.ERRORDOMAIN,
                  new Object[] {adminName, value}));
        }
        String indexval = value.substring(6, value.length() - 1);
        queryMap.put(indexval, name);
      } else if (value.equals("queryop")) {
        queryOpMapping = name;
      } else if (value.startsWith("path[")) {
        if (!value.endsWith("]")) {
          throw new ServiceCreationException(
              ErrorDataFactory.createErrorData(
                  ErrorConstants.SVC_FACTORY_INVALID_MAPPING_VALUE,
                  ErrorConstants.ERRORDOMAIN,
                  new Object[] {adminName, value}));
        }
        String indexval = value.substring(5, value.length() - 1);
        Integer indexnum = null;
        try {
          if (indexval.startsWith("+")) {
            indexval = indexval.replace("+", "-");
          }
          indexnum = Integer.valueOf(indexval);
        } catch (NumberFormatException e) {
          throw new ServiceCreationException(
              ErrorDataFactory.createErrorData(
                  ErrorConstants.SVC_FACTORY_INVALID_MAPPING_VALUE,
                  ErrorConstants.ERRORDOMAIN,
                  new Object[] {adminName, value}),
              e);
        }
        pathMap.put(indexnum, name);
      } else if (value.trim().equalsIgnoreCase("reject")) {
        rejectSet.add(name);
      } else {
        throw new ServiceCreationException(
            ErrorDataFactory.createErrorData(
                ErrorConstants.SVC_FACTORY_INVALID_MAPPING_VALUE,
                ErrorConstants.ERRORDOMAIN,
                new Object[] {adminName, value}));
      }
    }
    UrlMappingsDesc result = new UrlMappingsDesc(pathMap, queryMap, queryOpMapping, rejectSet);
    return result;
  }
  @Override
  protected ServerServiceDesc createServiceDesc(ServiceId id) throws ServiceException {
    ServerServiceId serverSvcId = (ServerServiceId) id;
    String adminName = id.getAdminName();
    ServiceConfigHolder config = ServiceConfigManager.getInstance().getConfig(adminName);
    QName serviceQName = config.getServiceQName();

    ClassLoader cl = Thread.currentThread().getContextClassLoader();

    MessageProcessorConfigHolder processorConfig = config.getMessageProcessorConfig();
    TypeMappingConfigHolder typeMappingsCfg = config.getTypeMappings();

    Pipeline requestPipeline = createPipeline(id, PipelineMode.REQUEST, processorConfig, cl);
    Pipeline responsePipeline = createPipeline(id, PipelineMode.RESPONSE, processorConfig, cl);

    Class serviceInterfaceClass = loadServiceInterfaceClass(config, true, cl);

    ServiceTypeMappings typeMappings =
        createTypeMappings(id, typeMappingsCfg, serviceInterfaceClass, cl);

    Collection<String> unsupportedOperations = config.getUnsupportedOperation();
    Map<String, ServiceOperationDesc> operations =
        createOperations(
            id,
            typeMappingsCfg,
            unsupportedOperations,
            typeMappings,
            serviceQName,
            cl,
            config.getOperationProperties());
    RequestPatternMatcher<ServiceOperationDesc> operationMatcher =
        createOperationsMatcher(operations.values());

    Map<String, ProtocolProcessorDesc> protocols =
        createProtocolProcessors(serverSvcId, processorConfig.getProtocolProcessors(), cl);
    RequestPatternMatcher<ProtocolProcessorDesc> protocolMatcher =
        createProtocolProcessorsMatcher(processorConfig.getProtocolProcessors(), protocols);

    Collection<String> supportedDataBindings = config.getSupportedDataBindings();
    Set<Class> rootClasses = getRootClassesFromOperations(operations.values());
    for (String className : typeMappingsCfg.getJavaTypes()) {
      Class clazz = ReflectionUtils.loadClass(className, null, true, cl);
      if (clazz == null) {
        if (LOGGER.isLogEnabled(LogLevel.WARN)) {
          LOGGER.log(LogLevel.WARN, "Unable to load type mapping class: " + className);
        }
      } else {
        rootClasses.add(clazz);
      }
    }
    Map<String, DataBindingDesc> bindings =
        createDataBindings(
            serverSvcId, processorConfig, supportedDataBindings, rootClasses, true, cl, true);

    DataBindingDesc defaultRequestBinding =
        getDefaultRequestDataBinding(config, supportedDataBindings, bindings, adminName);
    DataBindingDesc defaultResponseBinding =
        getDefaultResponseDataBinding(config, supportedDataBindings, bindings, adminName);

    RequestPatternMatcher<DataBindingDesc> bindingMatcherForRequest =
        new RequestPatternMatcher<DataBindingDesc>(true);
    RequestPatternMatcher<DataBindingDesc> bindingMatcherForResponse =
        new RequestPatternMatcher<DataBindingDesc>(true);
    createDataBindingsMatchers(
        bindings.values(), bindingMatcherForRequest, bindingMatcherForResponse);

    ErrorMapper errorMapper = createErrorMapper(processorConfig, serverSvcId, cl);
    ErrorDataProvider errorDataProviderClass = getErrorDataProviderClass(processorConfig, cl);
    List<LoggingHandler> loggingHandlers = createLoggingHandlers(id, processorConfig, cl);

    String serviceDispatcherClassName = getDispatcherClassName(config);

    String serviceImplClassName = config.getServiceImplClassName();
    String implFactory = config.getServiceImplFactoryClassName();

    BaseServiceRequestDispatcher<?> serviceDispatcher = null;
    try {
      serviceDispatcher =
          ReflectionUtils.createInstance(
              serviceDispatcherClassName, BaseServiceRequestDispatcher.class, cl);
    } catch (ServiceException se) {
      String mode = "Service Impl";
      if (implFactory != null) {
        mode += " factory";
      }
      throw new ServiceCreationException(
          ErrorDataFactory.createErrorData(
              ErrorConstants.SVC_FACTORY_MISSING_DISPATCHER_IMPL,
              ErrorConstants.ERRORDOMAIN,
              new Object[] {serviceDispatcherClassName}),
          se.getCause());
    }

    VersionCheckHandler versionCheckHandler = createVersionCheckHandler(serverSvcId, config, cl);

    serviceDispatcher.init(
        serverSvcId,
        serviceInterfaceClass,
        serviceImplClassName,
        cl,
        operations.values(),
        versionCheckHandler,
        implFactory,
        config.isImplCached());

    Dispatcher requestDispatcher = new SimpleInvokerDispatcher(serviceDispatcher);
    Dispatcher responseDispatcher = new SimpleServerResponseDispatcher(true);

    Collection<GlobalIdEntry> registryEntries =
        GlobalRegistryConfigManager.getInstance().getAllEntries();
    Map<String, GlobalIdDesc> globalIdMap = createGlobalIdMap(registryEntries, config);

    Charset serviceCharset = null; // default is to use request charset
    String serviceCharsetName = config.getDefaultEncoding();
    if (serviceCharsetName != null) {
      try {
        serviceCharset = Charset.forName(serviceCharsetName);
      } catch (Exception e) {
        throw new ServiceException(
            ErrorDataFactory.createErrorData(
                ErrorConstants.SVC_FACTORY_UNSUPPORTED_CHARSET,
                ErrorConstants.ERRORDOMAIN,
                new Object[] {serviceCharsetName, adminName}),
            e);
      }
    }

    UrlMappingsDesc urlMappings = loadUrlMappings(adminName, config);
    OperationMappings operationMappings = config.getOperationMappings();
    if (operationMappings == null) {
      operationMappings = new OperationMappings();
    }
    HeaderMappingsDesc requestHeaderMappings =
        loadHeaderMappings(adminName, config.getRequestHeaderMappingOptions(), true);
    HeaderMappingsDesc responseHeaderMappings =
        loadHeaderMappings(adminName, config.getResponseHeaderMappingOptions(), false);

    SecurityPolicyConfigHolder securityPolicy = config.getSecurityPolicy();
    Map<String, Map<String, String>> authentOperationsMap =
        new HashMap<String, Map<String, String>>();
    loadSecurityPolicy(adminName, securityPolicy, operations, authentOperationsMap);

    CachePolicyDesc cachePolicyDesc = null;
    if (config.getCachePolicy() != null) {
      cachePolicyDesc =
          CachePolicyDesc.create(config.getCachePolicy(), createOpRequestTypeDesc(operations));
    }

    List<String> serviceLayers =
        ServiceConfigManager.getInstance().getGlobalConfig().getServiceLayerNames();

    String httpErrorMapperClassName = config.getHttpErrorMapper();
    HttpErrorMapper httpErrorMapper = null;
    if (httpErrorMapperClassName != null) {
      httpErrorMapper =
          ReflectionUtils.createInstance(httpErrorMapperClassName, HttpErrorMapper.class, cl);
    }

    ServerServiceDesc result =
        new ServerServiceDesc(
            serverSvcId,
            serviceQName,
            config,
            requestPipeline,
            responsePipeline,
            requestDispatcher,
            responseDispatcher,
            operations,
            protocols,
            bindings,
            typeMappings,
            cl,
            loggingHandlers,
            serviceInterfaceClass,
            operationMatcher,
            protocolMatcher,
            bindingMatcherForRequest,
            bindingMatcherForResponse,
            serviceImplClassName,
            errorMapper,
            errorDataProviderClass,
            globalIdMap,
            versionCheckHandler,
            serviceCharset,
            urlMappings,
            operationMappings,
            requestHeaderMappings,
            responseHeaderMappings,
            authentOperationsMap,
            defaultRequestBinding,
            defaultResponseBinding,
            serviceLayers,
            cachePolicyDesc,
            config.getRequestParamsDescriptor(),
            implFactory,
            httpErrorMapper);

    return result;
  }