public void process(Exchange exchange) throws Exception {
    // store any existing file header which we want to keep and propagate
    final String existing = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class);

    // create the target file name
    String target = createFileName(exchange);

    // use lock for same file name to avoid concurrent writes to the same file
    // for example when you concurrently append to the same file
    Lock lock;
    synchronized (locks) {
      lock = locks.get(target);
      if (lock == null) {
        lock = new ReentrantLock();
        locks.put(target, lock);
      }
    }

    lock.lock();
    try {
      processExchange(exchange, target);
    } finally {
      // do not remove as the locks cache has an upper bound
      // this ensure the locks is appropriate reused
      lock.unlock();
      // and remove the write file name header as we only want to use it once (by design)
      exchange.getIn().removeHeader(Exchange.OVERRULE_FILE_NAME);
      // and restore existing file name
      exchange.getIn().setHeader(Exchange.FILE_NAME, existing);
    }
  }
  @Override
  public Transformer put(TransformerKey key, Transformer transformer) {
    // at first we must see if the key already exists and then replace it back, so it stays the same
    // spot
    Transformer answer = staticMap.remove(key);
    if (answer != null) {
      // replace existing
      staticMap.put(key, transformer);
      return answer;
    }

    answer = super.remove(key);
    if (answer != null) {
      // replace existing
      super.put(key, transformer);
      return answer;
    }

    // we want endpoints to be static if they are part of setting up or starting routes
    if (context.isSetupRoutes() || context.isStartingRoutes()) {
      answer = staticMap.put(key, transformer);
    } else {
      answer = super.put(key, transformer);
    }

    return answer;
  }
 /** Purges the cache */
 @Override
 public void purge() {
   // only purge the dynamic part
   super.clear();
 }
 @Override
 public void clear() {
   staticMap.clear();
   super.clear();
 }