/**
   * Creates a list of {@link NetworkLink}s, one for each {@link ddf.catalog.source.Source}
   * including the local catalog.
   *
   * @param uriInfo - injected resource provding the URI.
   * @return - {@link Kml} containing a folder of {@link NetworkLink}s.
   */
  @GET
  @Path(FORWARD_SLASH + "sources")
  @Produces(KML_MIME_TYPE)
  public Kml getAvailableSources(@Context UriInfo uriInfo) {
    try {
      SourceInfoResponse response = framework.getSourceInfo(new SourceInfoRequestEnterprise(false));

      Kml kml = KmlFactory.createKml();
      Folder folder = kml.createAndSetFolder();
      folder.setOpen(true);
      for (SourceDescriptor descriptor : response.getSourceInfo()) {
        UriBuilder builder = UriBuilder.fromUri(uriInfo.getBaseUri());
        builder =
            generateEndpointUrl(
                servicesContextRoot
                    + FORWARD_SLASH
                    + CATALOG_URL_PATH
                    + FORWARD_SLASH
                    + OPENSEARCH_URL_PATH,
                builder);
        builder = builder.queryParam(SOURCE_PARAM, descriptor.getSourceId());
        builder = builder.queryParam(OPENSEARCH_SORT_KEY, OPENSEARCH_DEFAULT_SORT);
        builder = builder.queryParam(OPENSEARCH_FORMAT_KEY, KML_TRANSFORM_PARAM);
        NetworkLink networkLink =
            generateViewBasedNetworkLink(builder.build().toURL(), descriptor.getSourceId());
        folder.getFeature().add(networkLink);
      }

      return kml;
    } catch (SourceUnavailableException e) {
      throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
    } catch (UnknownHostException e) {
      throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
    } catch (MalformedURLException e) {
      throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
    } catch (IllegalArgumentException e) {
      throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
    } catch (UriBuilderException e) {
      throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
    }
  }