private File getRepositoryFile(final URI uri, final AbstractProcessor processor) {
   if (uri.isOpaque()) {
     final String path = uri.getSchemeSpecificPart();
     if (path.startsWith("/")) {
       final File repoRoot = processor.getFactory().getRepository().getRoot();
       return new File(repoRoot, path.substring(1));
     } else {
       final File productRepo =
           processor
               .getFactory()
               .getRepository()
               .getProductDirectory(processor.getDescriptor().getProductId());
       return new File(productRepo, path);
     }
   } else {
     final String productId =
         uri.getHost() == null ? processor.getDescriptor().getProductId() : uri.getHost();
     return new File(
         processor.getFactory().getRepository().getProductDirectory(productId),
         uri.getPath().substring(1));
   }
 }
 @Override
 Source getSource(final URI uri, final AbstractProcessor processor) throws ProcessorException {
   final String productId = uri.getHost();
   final String path = uri.getPath();
   final Descriptor descriptor = processor.getFactory().getRepository().getDescriptor(productId);
   try {
     final URI resolvedUri = UriManipulator.resolve(descriptor.getRootUri(), path.substring(1));
     LOGGER.trace("URI {} resolved to {}", uri, resolvedUri);
     return new StreamSource(resolvedUri.toURL().openStream(), uri.toString());
   } catch (final IOException | URISyntaxException e) {
     throw new ProcessorException(e);
   }
 }