Projects >> wro4j >>7d5856d3c4336c3fe18b9d28b10e32299d0ac28f

Chunk
Conflicting content
/**
    }
  @Deprecated
  /**
<<<<<<< HEAD
/**
 * Copyright Alex Objelean
 */
package ro.isdc.wro.http;

import java.util.Properties;

import javax.servlet.FilterConfig;

import ro.isdc.wro.config.factory.PropertyWroConfigurationFactory;
import ro.isdc.wro.config.jmx.ConfigConstants;
import ro.isdc.wro.config.jmx.WroConfiguration;
import ro.isdc.wro.manager.factory.ConfigurableWroManagerFactory;
import ro.isdc.wro.manager.factory.DefaultWroManagerFactory;
import ro.isdc.wro.manager.factory.WroManagerFactory;
import ro.isdc.wro.util.ObjectFactory;


/**
 * An extension of {@link WroFilter} which allows configuration by injecting some of the properties. This class can be
 * very useful when using DelegatingFilterProxy (spring extension of Filter) and configuring the fields with values from
 * some properties file which may vary depending on environment.
 * 
 * @author Alex Objelean
 */
public class ConfigurableWroFilter
    extends WroFilter {
  /**
   * Properties to be injected with default values set. These values are deprecated. Prefer setting the "properties"
   * field instead.
   */
  @Deprecated
  private boolean debug = true;
  @Deprecated
  private boolean gzipEnabled = true;
  @Deprecated
  private boolean jmxEnabled = true;
  @Deprecated
  private String mbeanName;
  @Deprecated
  private long cacheUpdatePeriod = 0;
  @Deprecated
  private long modelUpdatePeriod = 0;
  @Deprecated
  private boolean disableCache;
  @Deprecated
  private String encoding;
  
  /**
   * This {@link Properties} object will hold the configurations and it will replace all other fields.
   */
  private Properties properties;
  
  /**
   * {@inheritDoc}
   */
  @Override
  protected ObjectFactory newWroConfigurationFactory(final FilterConfig filterConfig) {
    if (properties == null) {
      properties = new Properties();
      properties.setProperty(ConfigConstants.debug.name(), String.valueOf(debug));
      properties.setProperty(ConfigConstants.gzipResources.name(), String.valueOf(gzipEnabled));
      properties.setProperty(ConfigConstants.jmxEnabled.name(), String.valueOf(jmxEnabled));
      properties.setProperty(ConfigConstants.cacheUpdatePeriod.name(), String.valueOf(cacheUpdatePeriod));
      properties.setProperty(ConfigConstants.modelUpdatePeriod.name(), String.valueOf(modelUpdatePeriod));
      properties.setProperty(ConfigConstants.disableCache.name(), String.valueOf(disableCache));
      if (encoding != null) {
import ro.isdc.wro.manager.factory.WroManagerFactory;
    return super.newMBeanName();
  }
  
        properties.setProperty(ConfigConstants.encoding.name(), encoding);
  /**
      }
      if (mbeanName != null) {
        properties.setProperty(ConfigConstants.mbeanName.name(), mbeanName);
      }
    }
import ro.isdc.wro.util.ObjectFactory;

   * The default implementation of ConfigurableWroFilter should allow setting of pre & post processors in configuration
  private long cacheUpdatePeriod = 0;
import ro.isdc.wro.manager.factory.ConfigurableWroManagerFactory;
import ro.isdc.wro.manager.factory.DefaultWroManagerFactory;
    final PropertyWroConfigurationFactory factory = new PropertyWroConfigurationFactory(properties);
    return factory;
  }
  
  /**
   * @param disableCache
   *          the disableCache to set
   */
  public void setDisableCache(final boolean disableCache) {
    this.disableCache = disableCache;
  }
  
  /**
   * {@inheritDoc}
   */
  @Override
  protected String newMBeanName() {
    if (mbeanName != null) {
      return mbeanName;
   * properties. This will work only if no custom {@link WroManagerFactory} is configured.
   */
  @Override
  protected WroManagerFactory newWroManagerFactory() {
    return new DefaultWroManagerFactory(properties) {
      @Override
      protected WroManagerFactory newManagerFactory() {
    return new ConfigurableWroManagerFactory().setConfigProperties(properties);
      }
    };
  }
  
  /**
   * @param mbeanName the mbeanName to set
   */
  public void setMbeanName(final String mbeanName) {
    this.mbeanName = mbeanName;
  }
  
  /**
   * @param jmxEnabled the jmxEnabled to set
   */
  public void setJmxEnabled(final boolean jmxEnabled) {
    this.jmxEnabled = jmxEnabled;
  }
  
  /**
   * @param debug the debug to set
   */
  public final void setDebug(final boolean debug) {
    this.debug = debug;
  }
  
  /**
   * @param gzipEnabled the gzipEnabled to set
   */
  public final void setGzipEnabled(final boolean gzipEnabled) {
    this.gzipEnabled = gzipEnabled;
  }
  
  /**
   * @param cacheUpdatePeriod the cacheUpdatePeriod to set
   */
  public final void setCacheUpdatePeriod(final long cacheUpdatePeriod) {
    this.cacheUpdatePeriod = cacheUpdatePeriod;
  }
  
  /**
   * @param modelUpdatePeriod the modelUpdatePeriod to set
   */
  public final void setModelUpdatePeriod(final long modelUpdatePeriod) {
    this.modelUpdatePeriod = modelUpdatePeriod;
  }
  
  /**
   * @param properties
   *          the properties to set
   */
  public void setProperties(final Properties properties) {
    this.properties = properties;
  }
  
  /**
   * @return the encoding
   */
  public String getEncoding() {
    return this.encoding;
  }
  
  /**
   * @param encoding
   *          the encoding to set
   */
  public void setEncoding(final String encoding) {
    this.encoding = encoding;
  }
}
=======
/**
 * Copyright Alex Objelean
 */
package ro.isdc.wro.http;

import java.util.Properties;

import javax.servlet.FilterConfig;

import ro.isdc.wro.config.factory.PropertyWroConfigurationFactory;
import ro.isdc.wro.config.jmx.ConfigConstants;
import ro.isdc.wro.config.jmx.WroConfiguration;
  @Deprecated
 * An extension of {@link WroFilter} which allows configuration by injecting some of the properties. This class can be
 * very useful when using DelegatingFilterProxy (spring extension of Filter) and configuring the fields with values from
 * some properties file which may vary depending on environment.
 *
 * @author Alex Objelean
 */
public class ConfigurableWroFilter
    extends WroFilter {
  /**
   * Properties to be injected with default values set. These values are deprecated. Prefer setting the "properties"
   * field instead.
   */
  @Deprecated
  private boolean debug = true;
  @Deprecated
  private boolean gzipEnabled = true;
  @Deprecated
  private boolean jmxEnabled = true;
  @Deprecated
  private String mbeanName;
  private long modelUpdatePeriod = 0;
  @Deprecated
  private boolean disableCache;
  @Deprecated
  private String encoding;

  /**
   * This {@link Properties} object will hold the configurations and it will replace all other fields.
   */
  private Properties properties;

  /**
   * {@inheritDoc}
   */
  @Override
  protected ObjectFactory newWroConfigurationFactory(final FilterConfig filterConfig) {
    if (properties == null) {
      // when no
      properties = new Properties();
      properties.setProperty(ConfigConstants.debug.name(), String.valueOf(debug));
      properties.setProperty(ConfigConstants.gzipResources.name(), String.valueOf(gzipEnabled));
      properties.setProperty(ConfigConstants.jmxEnabled.name(), String.valueOf(jmxEnabled));
      properties.setProperty(ConfigConstants.cacheUpdatePeriod.name(), String.valueOf(cacheUpdatePeriod));
      properties.setProperty(ConfigConstants.modelUpdatePeriod.name(), String.valueOf(modelUpdatePeriod));
      properties.setProperty(ConfigConstants.disableCache.name(), String.valueOf(disableCache));
      if (encoding != null) {
        properties.setProperty(ConfigConstants.encoding.name(), encoding);
      }
      if (mbeanName != null) {
        properties.setProperty(ConfigConstants.mbeanName.name(), mbeanName);
      }
    }
    final PropertyWroConfigurationFactory factory = new PropertyWroConfigurationFactory(properties);
    return factory;
  }

  /**
   * @param disableCache
   *          the disableCache to set
   */
  public void setDisableCache(final boolean disableCache) {
    this.disableCache = disableCache;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected String newMBeanName() {
    if (mbeanName != null) {
      return mbeanName;
    }
    return super.newMBeanName();
  }

  /**
   * The default implementation of ConfigurableWroFilter should allow setting of pre & post processors in configuration
   * properties. This will work only if no custom {@link WroManagerFactory} is configured.
   */
  @Override
  protected WroManagerFactory newWroManagerFactory() {
    return new DefaultWroManagerFactory(properties) {
      @Override
      protected WroManagerFactory newManagerFactory() {
        return new ConfigurableWroManagerFactory() {
          @Override
          protected Properties newConfigProperties() {
            return properties;
          }
        };
      }
    };
  }

  /**
   * @param mbeanName
   *          the mbeanName to set
   */
  public void setMbeanName(final String mbeanName) {
    this.mbeanName = mbeanName;
  }

  /**
   * @param jmxEnabled
   *          the jmxEnabled to set
   */
  public void setJmxEnabled(final boolean jmxEnabled) {
    this.jmxEnabled = jmxEnabled;
  }

  /**
   * @param debug
   *          the debug to set
   */
  public final void setDebug(final boolean debug) {
    this.debug = debug;
  }

  /**
   * @param gzipEnabled
   *          the gzipEnabled to set
   */
  public final void setGzipEnabled(final boolean gzipEnabled) {
    this.gzipEnabled = gzipEnabled;
  }

   * @param cacheUpdatePeriod
   *          the cacheUpdatePeriod to set
   */
  public final void setCacheUpdatePeriod(final long cacheUpdatePeriod) {
    this.cacheUpdatePeriod = cacheUpdatePeriod;
  }

  /**
   * @param modelUpdatePeriod
   *          the modelUpdatePeriod to set
   */
  public final void setModelUpdatePeriod(final long modelUpdatePeriod) {
    this.modelUpdatePeriod = modelUpdatePeriod;
  }

  /**
   * @param properties
   *          the properties to set
   */
  public void setProperties(final Properties properties) {
    this.properties = properties;
  }

  /**
   * @return the encoding
   */
  public String getEncoding() {
    return this.encoding;
  }

  /**
   * @param encoding
   *          the encoding to set
   */
  public void setEncoding(final String encoding) {
    this.encoding = encoding;
  }
}
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
Solution content
      }
    }
/**
 * Copyright Alex Objelean
 */
package ro.isdc.wro.http;

import java.util.Properties;

import javax.servlet.FilterConfig;

import ro.isdc.wro.config.factory.PropertyWroConfigurationFactory;
import ro.isdc.wro.config.jmx.ConfigConstants;
import ro.isdc.wro.config.jmx.WroConfiguration;
import ro.isdc.wro.manager.factory.ConfigurableWroManagerFactory;
import ro.isdc.wro.manager.factory.DefaultWroManagerFactory;
import ro.isdc.wro.manager.factory.WroManagerFactory;
import ro.isdc.wro.util.ObjectFactory;


/**
 * An extension of {@link WroFilter} which allows configuration by injecting some of the properties. This class can be
 * very useful when using DelegatingFilterProxy (spring extension of Filter) and configuring the fields with values from
 * some properties file which may vary depending on environment.
 * 
 * @author Alex Objelean
 */
public class ConfigurableWroFilter
    extends WroFilter {
  /**
   * Properties to be injected with default values set. These values are deprecated. Prefer setting the "properties"
   * field instead.
   */
  @Deprecated
  private boolean debug = true;
  @Deprecated
  private boolean gzipEnabled = true;
  @Deprecated
  private boolean jmxEnabled = true;
  @Deprecated
  private String mbeanName;
  @Deprecated
  private long cacheUpdatePeriod = 0;
  @Deprecated
  private long modelUpdatePeriod = 0;
  @Deprecated
  private boolean disableCache;
  @Deprecated
  private String encoding;
  
  /**
   * This {@link Properties} object will hold the configurations and it will replace all other fields.
   */
  private Properties properties;
  
  /**
   * {@inheritDoc}
   */
  @Override
  protected ObjectFactory newWroConfigurationFactory(final FilterConfig filterConfig) {
    if (properties == null) {
      properties = new Properties();
      properties.setProperty(ConfigConstants.debug.name(), String.valueOf(debug));
      properties.setProperty(ConfigConstants.gzipResources.name(), String.valueOf(gzipEnabled));
      properties.setProperty(ConfigConstants.jmxEnabled.name(), String.valueOf(jmxEnabled));
      properties.setProperty(ConfigConstants.cacheUpdatePeriod.name(), String.valueOf(cacheUpdatePeriod));
      properties.setProperty(ConfigConstants.modelUpdatePeriod.name(), String.valueOf(modelUpdatePeriod));
      properties.setProperty(ConfigConstants.disableCache.name(), String.valueOf(disableCache));
      if (encoding != null) {
        properties.setProperty(ConfigConstants.encoding.name(), encoding);
      }
      if (mbeanName != null) {
        properties.setProperty(ConfigConstants.mbeanName.name(), mbeanName);
  public void setEncoding(final String encoding) {
    this.encoding = encoding;
    final PropertyWroConfigurationFactory factory = new PropertyWroConfigurationFactory(properties);
    return factory;
  }
  
  /**
   * @param disableCache
   *          the disableCache to set
   */
  public void setDisableCache(final boolean disableCache) {
    this.disableCache = disableCache;
  }
  
  /**
   * {@inheritDoc}
   */
  @Override
  protected String newMBeanName() {
    if (mbeanName != null) {
      return mbeanName;
    }
    return super.newMBeanName();
  }
  
  /**
   * The default implementation of ConfigurableWroFilter should allow setting of pre & post processors in configuration
   * properties. This will work only if no custom {@link WroManagerFactory} is configured.
   */
  @Override
  protected WroManagerFactory newWroManagerFactory() {
    return new DefaultWroManagerFactory(properties) {
      @Override
      protected WroManagerFactory newManagerFactory() {
        return new ConfigurableWroManagerFactory() {
          @Override
          protected Properties newConfigProperties() {
            return properties;
          }
        };
      }
    };
  }
  
  /**
   * @param mbeanName the mbeanName to set
   */
  public void setMbeanName(final String mbeanName) {
    this.mbeanName = mbeanName;
  }
  
  /**
   * @param jmxEnabled the jmxEnabled to set
   */
  public void setJmxEnabled(final boolean jmxEnabled) {
    this.jmxEnabled = jmxEnabled;
  }
  
  /**
   * @param debug the debug to set
   */
  public final void setDebug(final boolean debug) {
    this.debug = debug;
  }
  
  /**
   * @param gzipEnabled the gzipEnabled to set
   */
  public final void setGzipEnabled(final boolean gzipEnabled) {
    this.gzipEnabled = gzipEnabled;
  }
  
  /**
   * @param cacheUpdatePeriod the cacheUpdatePeriod to set
   */
  public final void setCacheUpdatePeriod(final long cacheUpdatePeriod) {
    this.cacheUpdatePeriod = cacheUpdatePeriod;
  }
  
  /**
   * @param modelUpdatePeriod the modelUpdatePeriod to set
   */
  public final void setModelUpdatePeriod(final long modelUpdatePeriod) {
    this.modelUpdatePeriod = modelUpdatePeriod;
  }
  
  /**
   * @param properties
   *          the properties to set
   */
  public void setProperties(final Properties properties) {
    this.properties = properties;
  }
  
  /**
   * @return the encoding
   */
  public String getEncoding() {
    return this.encoding;
  }
  
  /**
   * @param encoding
   *          the encoding to set
   */
  }
}
File
ConfigurableWroFilter.java
Developer's decision
Combination
Kind of conflict
Class declaration
Comment
Import
Package declaration
Chunk
Conflicting content
   * Servlet output stream of wrapped response.
   */
  private ServletOutputStream servletOutputStream;
<<<<<<< HEAD
  
=======
  /**
   * Used to locate external resources.
   */
  private final UriLocator externalResourceLocator = newExternalResourceLocator();

  /**
   * @return {@link UriLocator} responsible for resolving external resources.
   */
  protected UriLocator newExternalResourceLocator() {
    return new UrlUriLocator().setEnableWildcards(false);
  }

>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
  /**
   * @param outputStream
   *          the stream where the response will be written.
Solution content
   * Servlet output stream of wrapped response.
   */
  private ServletOutputStream servletOutputStream;
  
  /**
   * @param outputStream
   *          the stream where the response will be written.
File
RedirectedStreamServletResponseWrapper.java
Developer's decision
Version 1
Kind of conflict
Attribute
Comment
Method declaration
Method invocation
Chunk
Conflicting content
      throws IOException {
    return servletOutputStream;
  }
<<<<<<< HEAD
  
=======

>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
  @Override
  public PrintWriter getWriter()
      throws IOException {
Solution content
      throws IOException {
    return servletOutputStream;
  }
  
  @Override
  public PrintWriter getWriter()
      throws IOException {
File
RedirectedStreamServletResponseWrapper.java
Developer's decision
Version 1
Kind of conflict
Blank
Chunk
Conflicting content
    map.put(ResourceChangeDetector.class, createResourceChangeDetectorProxy());
    map.put(ResourceWatcher.class, createResourceWatcherProxy());
  }
<<<<<<< HEAD

  private Object createMetaDataFactoryProxy() {
    return new InjectorObjectFactory() {
      public MetaDataFactory create() {
        final MetaDataFactory factory = managerFactory.create().getMetaDataFactory();
        return factory;
      }
    };
=======

  private Object createResourceBundleProcessorProxy() {
    return new InjectorObjectFactory() {
      public ResourceBundleProcessor create() {
        return bundleProcessor;
      }
    };
  }

  private Object createMetaDataFactoryProxy() {
    return new InjectorObjectFactory() {
      public MetaDataFactory create() {
        return managerFactory.create().getMetaDataFactory();
      }
    };
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
  }

  private InjectorObjectFactory createConfigProxy() {
Solution content
    map.put(ResourceChangeDetector.class, createResourceChangeDetectorProxy());
    map.put(ResourceWatcher.class, createResourceWatcherProxy());
  }

  private Object createResourceBundleProcessorProxy() {
    return new InjectorObjectFactory() {
      public ResourceBundleProcessor create() {
        return bundleProcessor;
      }
    };
  }

  private Object createMetaDataFactoryProxy() {
    return new InjectorObjectFactory() {
      public MetaDataFactory create() {
        final MetaDataFactory factory = managerFactory.create().getMetaDataFactory();
        return factory;
      }
    };
  }

  private InjectorObjectFactory createConfigProxy() {
File
InjectorBuilder.java
Developer's decision
Combination
Kind of conflict
Method declaration
Method invocation
Method signature
Return statement
Chunk
Conflicting content
 */
package ro.isdc.wro.model.resource;

<<<<<<< HEAD
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
=======
import org.apache.commons.lang3.Validate;
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b

/**
 * Make a distinction between resource type. Can be CSS or JS.
Solution content
 */
package ro.isdc.wro.model.resource;

import org.apache.commons.lang3.Validate;

/**
 * Make a distinction between resource type. Can be CSS or JS.
File
ResourceType.java
Developer's decision
Version 2
Kind of conflict
Import
Chunk
Conflicting content
      }
    } finally {
<<<<<<< HEAD
/*
 * Copyright (c) 2008. All rights reserved.
 */
package ro.isdc.wro.model.resource.locator.support;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.isdc.wro.config.Context;
import ro.isdc.wro.http.support.RedirectedStreamServletResponseWrapper;
import ro.isdc.wro.model.resource.locator.ResourceLocator;
import ro.isdc.wro.util.WroUtil;


/**
 * Responsible to locate a context relative resource. Attempts to locate the resource using {@link RequestDispatcher} .
 * If the dispatcher fails, it will fallback resource retrieval to a http call using {@link UrlUriLocator}.
 *
 * @author Alex Objelean
 */
public class DispatcherStreamLocator {
  private static final Logger LOG = LoggerFactory.getLogger(DispatcherStreamLocator.class);
  /**
   * Attribute indicating that the request is included from within a wro request cycle. This is required to prevent
   * {@link StackOverflowError}.
   *
   * @VisibleForTesting
   */
  public static final String ATTRIBUTE_INCLUDED_BY_DISPATCHER = DispatcherStreamLocator.class.getName()
      + ".included_with_dispatcher";

  /**
   * When using JBoss Portal and it has some funny quirks...actually a portal application have several small web
   * application behind it. So when it intercepts a requests for portal then it start bombing the the application behind
   * the portal with multiple threads (web requests) that are combined with threads for wro4j.
   *
   * @return a valid stream for required location. This method will never return a null.
   * @throws IOException
   *           if the stream cannot be located at the specified location.
   */
  public InputStream getInputStream(final HttpServletRequest request, final HttpServletResponse response,
      final String location)
      throws IOException {
    if (request == null || response == null || location == null) {
      throw new IOException("Cannot get stream for location: " + location
          + " because either request, response or location is not available");
    }

    // where to write the bytes of the stream
    final ByteArrayOutputStream os = new ByteArrayOutputStream();
    boolean warnOnEmptyStream = false;

    try {
      final RequestDispatcher dispatcher = request.getRequestDispatcher(location);
      if (warnOnEmptyStream && os.size() == 0) {
        // use dispatcher

  /**
import javax.servlet.http.HttpServletRequest;
      LOG.debug("[FAIL] Error while dispatching the request for location {}", location);
      // Not only servletException can be thrown, also dispatch.include can throw NPE when the scheduler runs outside
        dispatcher.include(servletRequest, servletResponse);
        warnOnEmptyStream = true;
        // force flushing - the content will be written to
      // of the request cycle, thus connection is unavailable. This is caused mostly when invalid resources are
      if (dispatcher != null) {
        // Wrap request
      // included.
      return locateExternal(request, location);
    }
    try {
      //fallback to external resource locator if the dispatcher is empty
        final ServletRequest servletRequest = getWrappedServletRequest(request, location);
        // Wrap response
        final ServletResponse servletResponse = new RedirectedStreamServletResponseWrapper(os, response);
        LOG.debug("dispatching request to location: {}", location);
      if (os.size() == 0) {
        // BytArrayOutputStream. Otherwise exactly 32K of data will be
        // written.
        servletResponse.getWriter().flush();
        os.close();
      }
    } catch (final Exception e) {
        return locateExternal(request, location);
        LOG.debug("Wrong or empty resource with location: {}", location);
      }
    }
    return new ByteArrayInputStream(os.toByteArray());
  }

  private InputStream locateExternal(final HttpServletRequest request, final String location)
      throws IOException {
    // Returns the part URL from the protocol name up to the query string and contextPath.
    final String servletContextPath = request.getRequestURL().toString().replace(request.getServletPath(), "");
    final String absolutePath = servletContextPath + location;
    return createExternalResourceLocator(absolutePath).getInputStream();
  }

  /**
   * Used to locate external resources. No wildcard handling is required.
   *
   * @VisibleForTesting
   */
  ResourceLocator createExternalResourceLocator(final String location) {
    final ResourceLocator locator = new UrlResourceLocator(location) {
      /**
       * No wildcard handling is required.
       */
      @Override
      public boolean isEnableWildcards() {
        return false;
      };
    };
    return locator;
  }

  /**
   * Build a wrapped servlet request which will be used for dispatching.
   */
  private ServletRequest getWrappedServletRequest(final HttpServletRequest request, final String location) {
    final HttpServletRequest wrappedRequest = new HttpServletRequestWrapper(request) {
      @Override
      public String getRequestURI() {
        return getContextPath() + location;
      }

      @Override
      public String getPathInfo() {
        return WroUtil.getPathInfoFromLocation(this, location);
      }

      @Override
      public String getServletPath() {
        return WroUtil.getServletPathFromLocation(this, location);
      }
    };
    // add an attribute to mark this request as included from wro
    wrappedRequest.setAttribute(ATTRIBUTE_INCLUDED_BY_DISPATCHER, Boolean.TRUE);
    return wrappedRequest;
  }

  /**
   * @param request
   * @return true if the request is included from within wro request cycle.
   */
  public static boolean isIncludedRequest(final HttpServletRequest request) {
    Validate.notNull(request);
    return request.getAttribute(ATTRIBUTE_INCLUDED_BY_DISPATCHER) != null;
  }
=======
/*
 * Copyright (c) 2008. All rights reserved.
 */
package ro.isdc.wro.model.resource.locator.support;

import static org.apache.commons.lang3.Validate.notNull;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.isdc.wro.http.support.RedirectedStreamServletResponseWrapper;
import ro.isdc.wro.model.resource.locator.UriLocator;
import ro.isdc.wro.model.resource.locator.UrlUriLocator;
import ro.isdc.wro.util.WroUtil;


/**
 * Responsible to locate a context relative resource. Attempts to locate the resource using {@link RequestDispatcher} .
 * If the dispatcher fails, it will fallback resource retrieval to a http call using {@link UrlUriLocator}.
 *
 * @author Alex Objelean
 */
public class DispatcherStreamLocator {
  private static final Logger LOG = LoggerFactory.getLogger(DispatcherStreamLocator.class);
  /**
   * Attribute indicating that the request is included from within a wro request cycle. This is required to prevent
   * {@link StackOverflowError}.
   *
   * @VisibleForTesting
   */
  public static final String ATTRIBUTE_INCLUDED_BY_DISPATCHER = DispatcherStreamLocator.class.getName()
      + ".included_with_dispatcher";

  /**
   * When using JBoss Portal and it has some funny quirks...actually a portal application have several small web
   * application behind it. So when it intercepts a requests for portal then it start bombing the the application behind
   * the portal with multiple threads (web requests) that are combined with threads for wro4j.
   *
   * @param location
   *          a path to a request relative resource to locate.
   * @return a valid stream for required location. This method will never return a null.
   * @throws IOException
   *           if the stream cannot be located at the specified location.
   */
  public InputStream getInputStream(final HttpServletRequest request, final HttpServletResponse response,
      final String location)
      throws IOException {
    if (request == null || response == null || location == null) {
      throw new IOException("Cannot get stream for location: " + location
          + " because either request, response or location is not available");
    }

    // where to write the bytes of the stream
    final ByteArrayOutputStream os = new ByteArrayOutputStream();
    boolean warnOnEmptyStream = false;
    try {
      final RequestDispatcher dispatcher = request.getRequestDispatcher(location);
      if (dispatcher != null) {
        // Wrap request
        final ServletRequest servletRequest = getWrappedServletRequest(request, location);
        // Wrap response
        final ServletResponse servletResponse = new RedirectedStreamServletResponseWrapper(os, response);
        LOG.debug("dispatching request to location: {}", location);
        // use dispatcher
        dispatcher.include(servletRequest, servletResponse);
        warnOnEmptyStream = true;
        // force flushing - the content will be written to BytArrayOutputStream.
        // Otherwise exactly 32K of data will be written.
        servletResponse.getWriter().flush();
        os.close();
      }
    } catch (final Exception e) {
      LOG.debug("[FAIL] Error while dispatching the request for location {}", location);
      // Not only servletException can be thrown, also dispatch.include can throw NPE when the scheduler runs outside
      // of the request cycle, thus connection is unavailable. This is caused mostly when invalid resources are
      // included.
      return locateExternal(request, location);
    }
    try {
      // fallback to external resource locator if the dispatcher is empty
      if (os.size() == 0) {
        return locateExternal(request, location);
      }
    } finally {
      if (warnOnEmptyStream && os.size() == 0) {
        LOG.debug("Wrong or empty resource with location: {}", location);
      }
    }
    return new ByteArrayInputStream(os.toByteArray());
  }

  public void forward(final RequestDispatcher dispatcher, final HttpServletRequest request,
      final HttpServletResponse response, final String location)
      throws IOException {
    try {
      dispatcher.forward(getWrappedServletRequest(request, location), response);
    } catch (final Exception e) {
      throw new IOException("Could not forward to location: " + location, e);
    }
  }

  private InputStream locateExternal(final HttpServletRequest request, final String location)
      throws IOException {
    final String servletContextPath = request.getRequestURL().toString().replace(request.getServletPath(), "");
    final String absolutePath = servletContextPath + location;
    LOG.debug("locateExternalUri: {}", absolutePath);
    return createExternalResourceLocator().locate(absolutePath);
  }
   * @return the {@link UriLocator} responsible for locating resources when dispatcher fails. No wildcard handling is
   *         required.
   * @VisibleForTesting
   */
  UriLocator createExternalResourceLocator() {
    final UriLocator locator = new UrlUriLocator() {
      @Override
      public boolean isEnableWildcards() {
        return false;
      };
    };
    return locator;
  }

  /**
   * Build a wrapped servlet request which will be used for dispatching.
   */
  private ServletRequest getWrappedServletRequest(final HttpServletRequest request, final String location) {
    final HttpServletRequest wrappedRequest = new HttpServletRequestWrapper(request) {
      @Override
      public String getRequestURI() {
        return getContextPath() + location;
      }

      @Override
      public String getPathInfo() {
        return WroUtil.getPathInfoFromLocation(this, location);
      }

      @Override
      public String getServletPath() {
        return WroUtil.getServletPathFromLocation(this, location);
      }
    };
    // add an attribute to mark this request as included from wro
    wrappedRequest.setAttribute(ATTRIBUTE_INCLUDED_BY_DISPATCHER, Boolean.TRUE);
    return wrappedRequest;
  }

  /**
   * @return true if the request is included from within wro request cycle.
   */
  public static boolean isIncludedRequest(final HttpServletRequest request) {
    notNull(request);
    return request.getAttribute(ATTRIBUTE_INCLUDED_BY_DISPATCHER) != null;
  }
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
}
Solution content
   * @throws IOException
   */
   *           if the stream cannot be located at the specified location.
    }
/*
 * Copyright (c) 2008. All rights reserved.
 */
package ro.isdc.wro.model.resource.locator.support;

import static org.apache.commons.lang3.Validate.notNull;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.isdc.wro.config.Context;
import ro.isdc.wro.http.support.RedirectedStreamServletResponseWrapper;
import ro.isdc.wro.model.resource.locator.ResourceLocator;
import ro.isdc.wro.util.WroUtil;


/**
 * Responsible to locate a context relative resource. Attempts to locate the resource using {@link RequestDispatcher} .
 * If the dispatcher fails, it will fallback resource retrieval to a http call using {@link UrlUriLocator}.
 *
 * @author Alex Objelean
 */
public class DispatcherStreamLocator {
  private static final Logger LOG = LoggerFactory.getLogger(DispatcherStreamLocator.class);
  /**
   * Attribute indicating that the request is included from within a wro request cycle. This is required to prevent
   * {@link StackOverflowError}.
   *
   * @VisibleForTesting
   */
  public static final String ATTRIBUTE_INCLUDED_BY_DISPATCHER = DispatcherStreamLocator.class.getName()
      + ".included_with_dispatcher";

  /**
   * When using JBoss Portal and it has some funny quirks...actually a portal application have several small web
   * application behind it. So when it intercepts a requests for portal then it start bombing the the application behind
   * the portal with multiple threads (web requests) that are combined with threads for wro4j.
   *
   * @param location
   *          a path to a request relative resource to locate.
   * @return a valid stream for required location. This method will never return a null.
  public InputStream getInputStream(final HttpServletRequest request, final HttpServletResponse response,
      final String location)
      throws IOException {
    if (request == null || response == null || location == null) {
      throw new IOException("Cannot get stream for location: " + location
    // add an attribute to mark this request as included from wro
          + " because either request, response or location is not available");

    // where to write the bytes of the stream
    final ByteArrayOutputStream os = new ByteArrayOutputStream();
    boolean warnOnEmptyStream = false;
    try {
      final RequestDispatcher dispatcher = request.getRequestDispatcher(location);
      if (dispatcher != null) {
        // Wrap request
        final ServletRequest servletRequest = getWrappedServletRequest(request, location);
        // Wrap response
        final ServletResponse servletResponse = new RedirectedStreamServletResponseWrapper(os, response);
        LOG.debug("dispatching request to location: {}", location);
        // use dispatcher
        dispatcher.include(servletRequest, servletResponse);
        warnOnEmptyStream = true;
        // force flushing - the content will be written to BytArrayOutputStream.
        // Otherwise exactly 32K of data will be written.
        servletResponse.getWriter().flush();
        os.close();
      }
    } catch (final Exception e) {
      LOG.debug("[FAIL] Error while dispatching the request for location {}", location);
      // Not only servletException can be thrown, also dispatch.include can throw NPE when the scheduler runs outside
      // of the request cycle, thus connection is unavailable. This is caused mostly when invalid resources are
      // included.
      return locateExternal(request, location);
    }
    try {
      //fallback to external resource locator if the dispatcher is empty
      if (os.size() == 0) {
        return locateExternal(request, location);
      }
    } finally {
      if (warnOnEmptyStream && os.size() == 0) {
        LOG.debug("Wrong or empty resource with location: {}", location);
      }
    }
    return new ByteArrayInputStream(os.toByteArray());
  }

  private InputStream locateExternal(final HttpServletRequest request, final String location)
      throws IOException {
    final String servletContextPath = request.getRequestURL().toString().replace(request.getServletPath(), "");
    final String absolutePath = servletContextPath + location;
    LOG.debug("locateExternalUri: {}", absolutePath);
    return createExternalResourceLocator(absolutePath).getInputStream();
  }

  /**
   * Used to locate external resources. No wildcard handling is required.
   *
   * @VisibleForTesting
   */
  ResourceLocator createExternalResourceLocator(final String location) {
    final ResourceLocator locator = new UrlResourceLocator(location) {
      /**
       * No wildcard handling is required.
       */
      @Override
      public boolean isEnableWildcards() {
        return false;
      };
    };
    return locator;
  }

  /**
   * Build a wrapped servlet request which will be used for dispatching.
   */
  private ServletRequest getWrappedServletRequest(final HttpServletRequest request, final String location) {
    final HttpServletRequest wrappedRequest = new HttpServletRequestWrapper(request) {
      @Override
      public String getRequestURI() {
        return getContextPath() + location;
      }

      @Override
      public String getPathInfo() {
        return WroUtil.getPathInfoFromLocation(this, location);
      }

      @Override
      public String getServletPath() {
        return WroUtil.getServletPathFromLocation(this, location);
      }
    };
    wrappedRequest.setAttribute(ATTRIBUTE_INCLUDED_BY_DISPATCHER, Boolean.TRUE);
    return wrappedRequest;
  }

  /**
   * @return true if the request is included from within wro request cycle.
   */
  public static boolean isIncludedRequest(final HttpServletRequest request) {
    notNull(request);
    return request.getAttribute(ATTRIBUTE_INCLUDED_BY_DISPATCHER) != null;
  }
}
File
DispatcherStreamLocator.java
Developer's decision
Combination
Kind of conflict
Attribute
Comment
Import
Method declaration
Method invocation
Package declaration
Chunk
Conflicting content
    try {
   * variant.
   */

import java.io.File;
<<<<<<< HEAD:wro4j-core/src/main/java/ro/isdc/wro/model/resource/locator/support/ServletContextResourceLocator.java
/**
 * Copyright Alex Objelean
 */
package ro.isdc.wro.model.resource.locator.support;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;

import javax.servlet.ServletContext;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.isdc.wro.config.Context;
import ro.isdc.wro.model.resource.locator.ResourceLocator;
import ro.isdc.wro.model.transformer.WildcardExpanderModelTransformer.NoMoreAttemptsIOException;
import ro.isdc.wro.util.StringUtils;


/**
 * {@link org.springframework.core.io.Resource} implementation for {@link javax.servlet.ServletContext} resources,
 * interpreting relative paths within the web application root directory.
 *
 * @author Alex Objelean, Ivar Conradi Østhus
 * @created Created on Nov 10, 2008, Updated on March 2, 2012
 */
public class ServletContextResourceLocator
    extends AbstractResourceLocator {
      throws IOException {
    if (inputStream == null) {
      LOG.debug("[FAIL] reading resource from {}", uri);
import java.io.IOException;
import java.io.InputStream;
      throw new IOException("Exception while reading resource from " + uri);
   */
    }
  }

  /**
   * example, a jsp resource will be served in its final state (processed by servlet container), rather than in its raw
   * Same as default Alias (exist for explicit configuration). Uses DISPATCHER_FIRST strategy. Meaning that, for
  private static final Logger LOG = LoggerFactory.getLogger(ServletContextResourceLocator.class);
  /**
   * Alias used to register this locator with {@link LocatorProvider}.
   */
  public static final String ALIAS = "servletContext";
  /**
  public static final String ALIAS_DISPATCHER_FIRST = "servletContext.DISPATCHER_FIRST";
  /**
   * Uses SERVLET_CONTEXT_FIRST strategy, meaning that, for example, a jsp will be served with its raw content, instead
   * of processed by container.
   */
  public static final String ALIAS_SERVLET_CONTEXT_FIRST = "servletContext.SERVLET_CONTEXT_FIRST";
  /**
   * Uses SERVLET_CONTEXT_ONLY strategy, meaning that no dispatching will be performed when there is no servletContext resource available.
   */
  public static final String ALIAS_SERVLET_CONTEXT_ONLY = "servletContext.SERVLET_CONTEXT_ONLY";

  /**
   * Prefix for url resources.
   */
  public static final String PREFIX = "/";
  private final ServletContext servletContext;
  private final String path;
  /**
   * Locates a stream using request dispatcher.
   */
  private DispatcherStreamLocator dispatcherStreamLocator;
  /**
   * Determines the order of dispatcher resource locator and servlet context based resource locator.
   */
  private LocatorStrategy locatorStrategy = LocatorStrategy.DISPATCHER_FIRST;
  /**
   * Available LocatorStrategies. DISPATCHER_FIRST is default option. This means this UriLocator will first try to
   * locate resource via the dispatcher stream locator. This will include dynamic resources produces by servlet's or
   * JSP's. If the specified resource cannot be found with the dispatcherStreamLocator the implementation will try to
   * use the ServletContext to locate the resource. SERVLET_CONTEXT_FIRST is a alternative approach where we will first
   * try to locate the resource VIA the ServletContext first, and then use the dispatcheStreamLocator if not found. In
   * some cases, where you do not rely on dynamic resources this can be a more reliable and a more efficient approach.
   * If requests should never be forwarded to a servlet, use SERVLET_CONTEXT_ONLY.
   */
  public static enum LocatorStrategy {
    DISPATCHER_FIRST, SERVLET_CONTEXT_FIRST, SERVLET_CONTEXT_ONLY
  }

  /**
   * Sets the locator strategy to use.
   */
  public ResourceLocator setLocatorStrategy(final LocatorStrategy locatorStrategy) {
    Validate.notNull(locatorStrategy);
    this.locatorStrategy = locatorStrategy;
    return this;
  }


  public ServletContextResourceLocator(final ServletContext servletContext, final String path) {
    Validate.notNull(path);
    // allow null servletContext and prefer throwing IOException if null value is set.
    this.servletContext = servletContext;
    String pathToUse = StringUtils.cleanPath(path);
    if (!pathToUse.startsWith(PREFIX)) {
      pathToUse = PREFIX + pathToUse;
  }
    this.path = pathToUse;
  }

  /**
   * {@inheritDoc}
   */
  public InputStream getInputStream()
      throws IOException {
    if (servletContext == null) {
      throw new IOException("Cannot get stream for the following path: " + path
          + ", because no servletContext is detected.");
    }
    LOG.debug("locating uri: {}", path);
    try {
      if (getWildcardStreamLocator().hasWildcard(path)) {
        final String fullPath = FilenameUtils.getFullPath(path);
        final String realPath = servletContext.getRealPath(fullPath);
        if (realPath == null) {
          final String message = "[FAIL] Could not determine realPath for resource: " + path;
          LOG.debug(message);
          throw new IOException(message);
        }
  public static enum LocatorStrategy {
   * @return the strategy used by this locator.
        return getWildcardStreamLocator().locateStream(path, new File(URLDecoder.decode(realPath, "UTF-8")));
      }
    } catch (final IOException e) {
      /**
       * This is a special case when no more attempts are required, since the required computation was achieved
       * successfully. This solves the following issue.
       * 

* @VisibleForTesting * The problem was that in some situations, when the dispatcherStreamLocator was used to locate resources * containing wildcard, the following message was printed to the console: * SEVERE: Servlet.service() for servlet default threw exception * java.io.FileNotFoundException. */ if (e instanceof NoMoreAttemptsIOException) { throw e; } LOG.debug("[FAIL] localize the stream containing wildcard. Original error message: '{}'", e.getMessage() + "\".\n Trying to locate the stream without the wildcard."); } InputStream inputStream = null; try { switch (locatorStrategy) { case DISPATCHER_FIRST: inputStream = dispatcherFirstStreamLocator(path); break; case SERVLET_CONTEXT_FIRST: inputStream = servletContextFirstStreamLocator(path); break; case SERVLET_CONTEXT_ONLY: inputStream = servletContextBasedStreamLocator(path); break; } validateInputStreamIsNotNull(inputStream, path); return inputStream; } catch (final IOException e) { LOG.debug("Wrong or empty resource with location: {}", path); throw e; } } /** * {@inheritDoc} */ @Override public ResourceLocator createRelative(final String relativePath) throws IOException { final String folder = FilenameUtils.getFullPath(path); // remove '../' & normalize the path. final String pathToUse = StringUtils.cleanPath(folder + relativePath); return new ServletContextResourceLocator(servletContext, pathToUse); } private InputStream servletContextFirstStreamLocator(final String uri) throws IOException { try { return servletContextBasedStreamLocator(uri); } catch (final IOException e) { LOG.debug("retrieving servletContext stream for uri: {}", uri); return locateWithDispatcher(uri); } } private InputStream dispatcherFirstStreamLocator(final String uri) throws IOException { try { return locateWithDispatcher(uri); } catch (final IOException e) { LOG.debug("retrieving servletContext stream for uri: {}", uri); return servletContextBasedStreamLocator(uri); } } /** * @VisibleForTesting */ InputStream locateWithDispatcher(final String uri) throws IOException { final Context context = Context.get(); // The order of stream retrieval is important. We are trying to get the dispatcherStreamLocator in order to handle // jsp resources (if such exist). Switching the order would cause jsp to not be interpreted by the container. return new DispatcherStreamLocator().getInputStream(context.getRequest(), context.getResponse(), uri); } private InputStream servletContextBasedStreamLocator(final String uri) throws IOException { try { return Context.get().getServletContext().getResourceAsStream(uri); } catch (final Exception e) { throw new IOException("Could not locate uri: " + uri, e); } } private void validateInputStreamIsNotNull(final InputStream inputStream, final String uri) */ public LocatorStrategy getLocatorStrategy() { return locatorStrategy; } } ======= /* * Copyright (c) 2008. All rights reserved. */ package ro.isdc.wro.model.resource.locator; import static org.apache.commons.lang3.Validate.notNull; import java.net.URLDecoder; import javax.servlet.ServletContext; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ro.isdc.wro.config.Context; import ro.isdc.wro.model.resource.locator.support.DispatcherStreamLocator; import ro.isdc.wro.model.resource.locator.support.LocatorProvider; import ro.isdc.wro.model.resource.locator.wildcard.WildcardUriLocatorSupport; import ro.isdc.wro.model.transformer.WildcardExpanderModelTransformer.NoMoreAttemptsIOException; import ro.isdc.wro.util.WroUtil; /** * UriLocator capable to read the resources relative to servlet context. The resource reader will attempt to locate a * physic resource under the servlet context and if the resource does not exist, will try to use requestDispatcher. This * kind of resources will be accepted if their prefix is '/'. * * @author Alex Objelean, Ivar Conradi Østhus * @created Created on Nov 10 2008 */ public class ServletContextUriLocator extends WildcardUriLocatorSupport { private static final Logger LOG = LoggerFactory.getLogger(ServletContextUriLocator.class); /** * Alias used to register this locator with {@link LocatorProvider}. */ public static final String ALIAS = "servletContext"; /** * Same as default Alias (exist for explicit configuration). Uses DISPATCHER_FIRST strategy. Meaning that, for * example, a jsp resource will be served in its final state (processed by servlet container), rather than in its raw * variant. */ public static final String ALIAS_DISPATCHER_FIRST = "servletContext.DISPATCHER_FIRST"; /** * Uses SERVLET_CONTEXT_FIRST strategy, meaning that, for example, a jsp will be served with its raw content, instead * of processed by container. */ public static final String ALIAS_SERVLET_CONTEXT_FIRST = "servletContext.SERVLET_CONTEXT_FIRST"; /** * Uses SERVLET_CONTEXT_ONLY strategy, meaning that no dispatching will be performed when there is no servletContext resource available. */ public static final String ALIAS_SERVLET_CONTEXT_ONLY = "servletContext.SERVLET_CONTEXT_ONLY"; /** * Prefix for url resources. */ public static final String PREFIX = "/"; /** * Constant for WEB-INF folder. */ private static final String PROTECTED_PREFIX = "/WEB-INF/"; /** * Determines the order of dispatcher resource locator and servlet context based resource locator. */ private LocatorStrategy locatorStrategy = LocatorStrategy.DISPATCHER_FIRST; /** * Available LocatorStrategies. DISPATCHER_FIRST is default option. This means this UriLocator will first try to * locate resource via the dispatcher stream locator. This will include dynamic resources produces by servlet's or * JSP's. If the specified resource cannot be found with the dispatcherStreamLocator the implementation will try to * use the ServletContext to locate the resource. SERVLET_CONTEXT_FIRST is a alternative approach where we will first * try to locate the resource VIA the ServletContext first, and then use the dispatcheStreamLocator if not found. In * some cases, where you do not rely on dynamic resources this can be a more reliable and a more efficient approach. * If requests should never be forwarded to a servlet, use SERVLET_CONTEXT_ONLY. DISPATCHER_FIRST, SERVLET_CONTEXT_FIRST, SERVLET_CONTEXT_ONLY } /** * Sets the locator strategy to use. */ public ServletContextUriLocator setLocatorStrategy(final LocatorStrategy locatorStrategy) { notNull(locatorStrategy); this.locatorStrategy = locatorStrategy; return this; } /** * {@inheritDoc} */ public boolean accept(final String uri) { return isValid(uri); } /** * Check if a uri is a servletContext resource. * * @param uri * to check. * @return true if the uri is a servletContext resource. */ */ public static boolean isValid(final String uri) { return uri.trim().startsWith(PREFIX); } /** * Check If the uri of the resource is protected: it cannot be accessed by accessing the url directly (WEB-INF * folder). * * @param uri * the uri to check. * @return true if the uri is a protected resource. */ public static boolean isProtectedResource(final String uri) { return WroUtil.startsWithIgnoreCase(uri, PROTECTED_PREFIX); } /** * {@inheritDoc} */ public InputStream locate(final String uri) throws IOException { Validate.notNull(uri, "URI cannot be NULL!"); LOG.debug("locate resource: {}", uri); try { if (getWildcardStreamLocator().hasWildcard(uri)) { final ServletContext servletContext = Context.get().getServletContext(); final String fullPath = FilenameUtils.getFullPath(uri); final String realPath = servletContext.getRealPath(fullPath); if (realPath == null) { final String message = "[FAIL] determine realPath for resource: " + uri; LOG.debug(message); throw new IOException(message); } return getWildcardStreamLocator().locateStream(uri, new File(URLDecoder.decode(realPath, "UTF-8"))); } } catch (final IOException e) { /** * This is a special case when no more attempts are required, since the required computation was achieved * successfully. This solves the following issue. *

* The problem was that in some situations, when the dispatcherStreamLocator was used to locate resources * containing wildcard, the following message was printed to the console: * SEVERE: Servlet.service() for servlet default threw exception * java.io.FileNotFoundException. */ if (e instanceof NoMoreAttemptsIOException) { throw e; } LOG.debug("[FAIL] localize the stream containing wildcard. Original error message: '{}'", e.getMessage() + "\".\n Trying to locate the stream without the wildcard."); } InputStream inputStream = null; try { switch (locatorStrategy) { case DISPATCHER_FIRST: inputStream = dispatcherFirstStreamLocator(uri); break; case SERVLET_CONTEXT_FIRST: inputStream = servletContextFirstStreamLocator(uri); break; case SERVLET_CONTEXT_ONLY: inputStream = servletContextBasedStreamLocator(uri); break; } validateInputStreamIsNotNull(inputStream, uri); return inputStream; } catch (final IOException e) { LOG.debug("Wrong or empty resource with location: {}", uri); throw e; } } private InputStream servletContextFirstStreamLocator(final String uri) throws IOException { InputStream locateWithDispatcher(final String uri) return servletContextBasedStreamLocator(uri); } catch (final Exception e) { LOG.debug("retrieving servletContext stream for uri: {}", uri); return locateWithDispatcher(uri); } } private InputStream dispatcherFirstStreamLocator(final String uri) throws IOException { try { return locateWithDispatcher(uri); } catch (final Exception e) { LOG.debug("retrieving servletContext stream for uri: {}", uri); return servletContextBasedStreamLocator(uri); } } /** * @VisibleForTesting throws IOException { final Context context = Context.get(); // The order of stream retrieval is important. We are trying to get the dispatcherStreamLocator in order to handle // jsp resources (if such exist). Switching the order would cause jsp to not be interpreted by the container. return new DispatcherStreamLocator().getInputStream(context.getRequest(), context.getResponse(), uri); } private InputStream servletContextBasedStreamLocator(final String uri) throws IOException { try { return Context.get().getServletContext().getResourceAsStream(uri); } catch (final Exception e) { throw new IOException("Could not locate uri: " + uri, e); } } private void validateInputStreamIsNotNull(final InputStream inputStream, final String uri) throws IOException { if (inputStream == null) { LOG.debug("[FAIL] reading resource from {}", uri); throw new IOException("Exception while reading resource from " + uri); } } /** * @return the strategy used by this locator. * @VisibleForTesting */ public LocatorStrategy getLocatorStrategy() { return locatorStrategy; } } >>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b:wro4j-core/src/main/java/ro/isdc/wro/model/resource/locator/ServletContextUriLocator.java

Solution content
  /**
/**
 * Copyright Alex Objelean
 */
package ro.isdc.wro.model.resource.locator.support;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;

import javax.servlet.ServletContext;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.isdc.wro.config.Context;
import ro.isdc.wro.model.resource.locator.ResourceLocator;
import ro.isdc.wro.model.transformer.WildcardExpanderModelTransformer.NoMoreAttemptsIOException;
import ro.isdc.wro.util.StringUtils;


/**
 * {@link org.springframework.core.io.Resource} implementation for {@link javax.servlet.ServletContext} resources,
 * interpreting relative paths within the web application root directory.
 *
 * @author Alex Objelean, Ivar Conradi Østhus
 * @created Created on Nov 10 2008
 */
public class ServletContextResourceLocator
    extends AbstractResourceLocator {
  private static final Logger LOG = LoggerFactory.getLogger(ServletContextResourceLocator.class);
  /**
   * Alias used to register this locator with {@link LocatorProvider}.
   */
  public static final String ALIAS = "servletContext";
  /**
   * Same as default Alias (exist for explicit configuration). Uses DISPATCHER_FIRST strategy. Meaning that, for
   * example, a jsp resource will be served in its final state (processed by servlet container), rather than in its raw
   * variant.
   */
  public static final String ALIAS_DISPATCHER_FIRST = "servletContext.DISPATCHER_FIRST";
  /**
   * Uses SERVLET_CONTEXT_FIRST strategy, meaning that, for example, a jsp will be served with its raw content, instead
   * of processed by container.
   */
  public static final String ALIAS_SERVLET_CONTEXT_FIRST = "servletContext.SERVLET_CONTEXT_FIRST";
  /**
   * Uses SERVLET_CONTEXT_ONLY strategy, meaning that no dispatching will be performed when there is no servletContext resource available.
   */
  public static final String ALIAS_SERVLET_CONTEXT_ONLY = "servletContext.SERVLET_CONTEXT_ONLY";

  /**
   * Prefix for url resources.
   */
  public static final String PREFIX = "/";
  private final ServletContext servletContext;
  private final String path;
  /**
   * Locates a stream using request dispatcher.
   */
  private DispatcherStreamLocator dispatcherStreamLocator;
  /**
   * Determines the order of dispatcher resource locator and servlet context based resource locator.
   */
  private LocatorStrategy locatorStrategy = LocatorStrategy.DISPATCHER_FIRST;
  /**
   * Available LocatorStrategies. DISPATCHER_FIRST is default option. This means this UriLocator will first try to
   * locate resource via the dispatcher stream locator. This will include dynamic resources produces by servlet's or
   * JSP's. If the specified resource cannot be found with the dispatcherStreamLocator the implementation will try to
   * use the ServletContext to locate the resource. SERVLET_CONTEXT_FIRST is a alternative approach where we will first
   * try to locate the resource VIA the ServletContext first, and then use the dispatcheStreamLocator if not found. In
   * some cases, where you do not rely on dynamic resources this can be a more reliable and a more efficient approach.
   * If requests should never be forwarded to a servlet, use SERVLET_CONTEXT_ONLY.
   */
  public static enum LocatorStrategy {
    DISPATCHER_FIRST, SERVLET_CONTEXT_FIRST, SERVLET_CONTEXT_ONLY
  }
   * Sets the locator strategy to use.
   */
  public ResourceLocator setLocatorStrategy(final LocatorStrategy locatorStrategy) {
    Validate.notNull(locatorStrategy);
    this.locatorStrategy = locatorStrategy;
    return this;
  }
  }



  private InputStream servletContextFirstStreamLocator(final String uri)
      throws IOException {
    try {

  public ServletContextResourceLocator(final ServletContext servletContext, final String path) {
    Validate.notNull(path);
    // allow null servletContext and prefer throwing IOException if null value is set.
    this.servletContext = servletContext;
    String pathToUse = StringUtils.cleanPath(path);
    if (!pathToUse.startsWith(PREFIX)) {
      pathToUse = PREFIX + pathToUse;
  }
    this.path = pathToUse;
  }

  /**
   * {@inheritDoc}
   */
  public InputStream getInputStream()
      throws IOException {
    if (servletContext == null) {
      throw new IOException("Cannot get stream for the following path: " + path
          + ", because no servletContext is detected.");
    }
    LOG.debug("locating uri: {}", path);
    try {
      if (getWildcardStreamLocator().hasWildcard(path)) {
        final String fullPath = FilenameUtils.getFullPath(path);
        final String realPath = servletContext.getRealPath(fullPath);
        if (realPath == null) {
          final String message = "[FAIL] Could not determine realPath for resource: " + path;
          LOG.debug(message);
          throw new IOException(message);
        }
        return getWildcardStreamLocator().locateStream(path, new File(URLDecoder.decode(realPath, "UTF-8")));
      }
    } catch (final IOException e) {
      /**
       * This is a special case when no more attempts are required, since the required computation was achieved
       * successfully. This solves the following issue.
       * 

* The problem was that in some situations, when the dispatcherStreamLocator was used to locate resources * containing wildcard, the following message was printed to the console: * SEVERE: Servlet.service() for servlet default threw exception * java.io.FileNotFoundException. */ if (e instanceof NoMoreAttemptsIOException) { throw e; } LOG.debug("[FAIL] localize the stream containing wildcard. Original error message: '{}'", e.getMessage() + "\".\n Trying to locate the stream without the wildcard."); } InputStream inputStream = null; try { switch (locatorStrategy) { case DISPATCHER_FIRST: inputStream = dispatcherFirstStreamLocator(path); break; case SERVLET_CONTEXT_FIRST: inputStream = servletContextFirstStreamLocator(path); break; case SERVLET_CONTEXT_ONLY: inputStream = servletContextBasedStreamLocator(path); break; } validateInputStreamIsNotNull(inputStream, path); return inputStream; } catch (final IOException e) { LOG.debug("Wrong or empty resource with location: {}", path); throw e; } } /** * {@inheritDoc} */ @Override public ResourceLocator createRelative(final String relativePath) throws IOException { final String folder = FilenameUtils.getFullPath(path); // remove '../' & normalize the path. final String pathToUse = StringUtils.cleanPath(folder + relativePath); return new ServletContextResourceLocator(servletContext, pathToUse); return servletContextBasedStreamLocator(uri); } catch (final Exception e) { LOG.debug("retrieving servletContext stream for uri: {}", uri); return locateWithDispatcher(uri); } } private InputStream dispatcherFirstStreamLocator(final String uri) throws IOException { try { return locateWithDispatcher(uri); } catch (final Exception e) { LOG.debug("retrieving servletContext stream for uri: {}", uri); return servletContextBasedStreamLocator(uri); } } /** * @VisibleForTesting */ InputStream locateWithDispatcher(final String uri) throws IOException { final Context context = Context.get(); // The order of stream retrieval is important. We are trying to get the dispatcherStreamLocator in order to handle // jsp resources (if such exist). Switching the order would cause jsp to not be interpreted by the container. return new DispatcherStreamLocator().getInputStream(context.getRequest(), context.getResponse(), uri); } private InputStream servletContextBasedStreamLocator(final String uri) throws IOException { try { return Context.get().getServletContext().getResourceAsStream(uri); } catch (final Exception e) { throw new IOException("Could not locate uri: " + uri, e); } } private void validateInputStreamIsNotNull(final InputStream inputStream, final String uri) throws IOException { if (inputStream == null) { LOG.debug("[FAIL] reading resource from {}", uri); throw new IOException("Exception while reading resource from " + uri); } } /** * @return the strategy used by this locator. * @VisibleForTesting */ public LocatorStrategy getLocatorStrategy() { return locatorStrategy; } }

File
ServletContextResourceLocator.java
Developer's decision
Combination
Kind of conflict
Class declaration
Comment
Import
Package declaration
Chunk
Conflicting content
}
=======
/**
   *
   * @param dataUri
<<<<<<< HEAD
/**
 * Copyright Alex Objelean
 */
package ro.isdc.wro.model.resource.processor.impl.css;

import static ro.isdc.wro.util.WroUtil.cleanImageUrl;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.isdc.wro.WroRuntimeException;
import ro.isdc.wro.model.group.Inject;
import ro.isdc.wro.model.resource.locator.factory.ResourceLocatorFactory;
import ro.isdc.wro.model.resource.processor.support.DataUriGenerator;


/**
 * Rewrites background images by replacing the url with data uri of the image. If the replacement is not successful, it
 * is left unchanged.
 * 

* Attention: This processor should be added before {@link CssUrlRewritingProcessor}, otherwise the url's won't be * replaced. For more details, @see DataUri Scheme on * Wikipedia * * @author Alex Objelean * @created May 9, 2010 */ public class CssDataUriPreProcessor extends AbstractCssUrlRewritingProcessor { private static final Logger LOG = LoggerFactory.getLogger(CssDataUriPreProcessor.class); public static final String ALIAS = "cssDataUri"; /** * The size limit. Images larger than this limit won't be transformed (due to IE8 limitation). */ Validate.notNull(resourceLocatorFactory); * base64 encoded stream. LOG.debug("replace url for image: {} from css: {}", imageUrl, cssUri); final String cleanImageUrl = cleanImageUrl(imageUrl); final String fileName = FilenameUtils.getName(imageUrl); private static final int SIZE_LIMIT = 32 * 1024; String fullPath = cleanImageUrl; /** * Copyright Alex Objelean private ResourceLocatorFactory resourceLocatorFactory; /** /** */ * Replace provided url with the new url if needed. * * @param imageUrl * to replace. * Generates dataUri based on inputStream of the url's found inside the css resource. */ private DataUriGenerator dataUriGenerator; @Inject * @param cssUri * Uri of the parsed css. * @return replaced url. */ @Override protected String replaceImageUrl(final String cssUri, final String imageUrl) { } * Allow dataUri transformation of absolute url's using http(s) protocol. All url's protocol are intentionally not * allowed, because it could be a potential security issue. For instance: * *

     * .class {
     *   background: url(file:/path/to/secure/file.png);
     * }
     * 
* * This should not be allowed. */ if (isImageUrlChangeRequired(cleanImageUrl)) { fullPath = FilenameUtils.getFullPath(cssUri) + cleanImageUrl; } String result = imageUrl; InputStream is = null; try { is = resourceLocatorFactory.locate(fullPath); final String dataUri = getDataUriGenerator().generateDataURI(is, fileName); if (isReplaceAccepted(dataUri)) { result = dataUri; LOG.debug("dataUri replacement: {}", StringUtils.abbreviate(dataUri, 30)); } } catch (final IOException e) { LOG.warn("[FAIL] extract dataUri from: {}, because: {}. " + "A possible cause: using CssUrlRewritingProcessor before CssDataUriPreProcessor.", fullPath, e.getMessage()); } finally { IOUtils.closeQuietly(is); } return result; } /** * @param imageUrl * the original url of the image. * @return true if the image url should be replaced with another (servlet context relative). */ private boolean isImageUrlChangeRequired(final String imageUrl) { return !(imageUrl.startsWith("http") || (isProxyResource(imageUrl))); } /** * Similar to {@link CssDataUriPreProcessor#isReplaceAccepted(String)}, but decides whether the computed dataUri * should replace the image url. It is useful when you want to limit the dataUri size. By default the size of dataUri * is limited to 32KB (because IE8 has a 32KB limitation). * * @param dataUri * base64 encoded stream. * @return true if dataUri should replace original image url. */ protected boolean isReplaceAccepted(final String dataUri) { try { final byte[] bytes = dataUri.getBytes(CharEncoding.UTF_8); final boolean exceedLimit = bytes.length >= SIZE_LIMIT; LOG.debug("dataUri size: {}KB, limit exceeded: {}", bytes.length / 1024, exceedLimit); return !exceedLimit; } catch (final UnsupportedEncodingException e) { throw new WroRuntimeException("Should never happen", e); } } /** * {@inheritDoc} */ @Override protected boolean isReplaceNeeded(final String url) { // the dataUri should replace also absolute url's return !DataUriGenerator.isDataUri(url.trim()); } /** * @return the DataUriGenerator class responsible for transforming streams into base64 encoded strings. * @VisibleForTesting */ protected DataUriGenerator getDataUriGenerator() { if (dataUriGenerator == null) { dataUriGenerator = new DataUriGenerator(); } return dataUriGenerator; import ro.isdc.wro.model.group.Inject; package ro.isdc.wro.model.resource.processor.impl.css; import static ro.isdc.wro.util.WroUtil.cleanImageUrl; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.CharEncoding; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ro.isdc.wro.WroRuntimeException; import ro.isdc.wro.http.handler.ResourceProxyRequestHandler; import ro.isdc.wro.model.resource.locator.factory.UriLocatorFactory; import ro.isdc.wro.model.resource.processor.support.DataUriGenerator; /** * Rewrites background images by replacing the url with data uri of the image. If the replacement is not successful, it * is left unchanged. *

* Attention: This processor should be added before {@link CssUrlRewritingProcessor}, otherwise the url's won't be * replaced. For more details, @see DataUri Scheme on * Wikipedia * * @author Alex Objelean * @created May 9, 2010 */ public class CssDataUriPreProcessor extends AbstractCssUrlRewritingProcessor { private static final Logger LOG = LoggerFactory.getLogger(CssDataUriPreProcessor.class); public static final String ALIAS = "cssDataUri"; /** * The size limit. Images larger than this limit won't be transformed (due to IE8 limitation). */ private static final int SIZE_LIMIT = 32 * 1024; /** * Generates dataUri based on inputStream of the url's found inside the css resource. */ private DataUriGenerator dataUriGenerator; /** * Contains a {@link UriLocatorFactory} reference injected externally. */ @Inject private UriLocatorFactory uriLocatorFactory; /** * Replace provided url with the new url if needed. * * @param imageUrl * to replace. * @param cssUri * Uri of the parsed css. * @return replaced url. */ @Override protected String replaceImageUrl(final String cssUri, final String imageUrl) { Validate.notNull(uriLocatorFactory); LOG.debug("replace url for image: {} from css: {}", imageUrl, cssUri); final String cleanImageUrl = cleanImageUrl(imageUrl); final String fileName = FilenameUtils.getName(imageUrl); String fullPath = cleanImageUrl; /** * Allow dataUri transformation of absolute url's using http(s) protocol. All url's protocol are intentionally not * allowed, because it could be a potential security issue. For instance: * *

     * .class {
     *   background: url(file:/path/to/secure/file.png);
     * }
     * 
* * This should not be allowed. */ if (isImageUrlChangeRequired(cleanImageUrl)) { fullPath = FilenameUtils.getFullPath(cssUri) + cleanImageUrl; } String result = imageUrl; InputStream is = null; try { is = uriLocatorFactory.locate(fullPath); final String dataUri = getDataUriGenerator().generateDataURI(is, fileName); if (isReplaceAccepted(dataUri)) { result = dataUri; LOG.debug("dataUri replacement: {}", StringUtils.abbreviate(dataUri, 30)); } } catch (final IOException e) { LOG.warn("[FAIL] extract dataUri from: {}, because: {}. " + "A possible cause: using CssUrlRewritingProcessor before CssDataUriPreProcessor.", fullPath, e.getMessage()); } finally { * is limited to 32KB (because IE8 has a 32KB limitation). IOUtils.closeQuietly(is); } return result; } /** * @param imageUrl * the original url of the image. * @return true if the image url should be replaced with another (servlet context relative). */ private boolean isImageUrlChangeRequired(final String imageUrl) { return !(imageUrl.startsWith("http") || ResourceProxyRequestHandler.isProxyUri(imageUrl)); } /** * Similar to {@link CssDataUriPreProcessor#isReplaceAccepted(String)}, but decides whether the computed dataUri * should replace the image url. It is useful when you want to limit the dataUri size. By default the size of dataUri * @return true if dataUri should replace original image url. */ protected boolean isReplaceAccepted(final String dataUri) { try { final byte[] bytes = dataUri.getBytes(CharEncoding.UTF_8); final boolean exceedLimit = bytes.length >= SIZE_LIMIT; LOG.debug("dataUri size: {}KB, limit exceeded: {}", bytes.length / 1024, exceedLimit); return !exceedLimit; } catch (final UnsupportedEncodingException e) { throw new WroRuntimeException("Should never happen", e); } } /** * {@inheritDoc} */ @Override protected boolean isReplaceNeeded(final String url) { // the dataUri should replace also absolute url's return !DataUriGenerator.isDataUri(url.trim()); } /** * @return the DataUriGenerator class responsible for transforming streams into base64 encoded strings. * @VisibleForTesting */ protected DataUriGenerator getDataUriGenerator() { if (dataUriGenerator == null) { dataUriGenerator = new DataUriGenerator(); } return dataUriGenerator; } } >>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
Solution content
   * Replace provided url with the new url if needed.
/**
 * Copyright Alex Objelean
 */
package ro.isdc.wro.model.resource.processor.impl.css;

import static ro.isdc.wro.util.WroUtil.cleanImageUrl;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.isdc.wro.WroRuntimeException;
import ro.isdc.wro.http.handler.ResourceProxyRequestHandler;
import ro.isdc.wro.model.group.Inject;
import ro.isdc.wro.model.resource.locator.factory.ResourceLocatorFactory;
import ro.isdc.wro.model.resource.processor.support.DataUriGenerator;


/**
 * Rewrites background images by replacing the url with data uri of the image. If the replacement is not successful, it
 * is left unchanged.
 * 

* Attention: This processor should be added before {@link CssUrlRewritingProcessor}, otherwise the url's won't be * replaced. For more details, @see DataUri Scheme on * Wikipedia * * @author Alex Objelean * @created May 9, 2010 */ public class CssDataUriPreProcessor extends AbstractCssUrlRewritingProcessor { private static final Logger LOG = LoggerFactory.getLogger(CssDataUriPreProcessor.class); public static final String ALIAS = "cssDataUri"; /** * The size limit. Images larger than this limit won't be transformed (due to IE8 limitation). */ private static final int SIZE_LIMIT = 32 * 1024; /** * Generates dataUri based on inputStream of the url's found inside the css resource. */ private DataUriGenerator dataUriGenerator; @Inject private ResourceLocatorFactory resourceLocatorFactory; /** * * @param imageUrl * to replace. * @param cssUri * Uri of the parsed css. * @return replaced url. */ @Override protected String replaceImageUrl(final String cssUri, final String imageUrl) { Validate.notNull(resourceLocatorFactory); LOG.debug("replace url for image: {} from css: {}", imageUrl, cssUri); final String cleanImageUrl = cleanImageUrl(imageUrl); final String fileName = FilenameUtils.getName(imageUrl); String fullPath = cleanImageUrl; /** * Allow dataUri transformation of absolute url's using http(s) protocol. All url's protocol are intentionally not * allowed, because it could be a potential security issue. For instance: * *

     * .class {
     *   background: url(file:/path/to/secure/file.png);
     * }
     * 
* * This should not be allowed. */ if (isImageUrlChangeRequired(cleanImageUrl)) { fullPath = FilenameUtils.getFullPath(cssUri) + cleanImageUrl; } String result = imageUrl; InputStream is = null; try { is = resourceLocatorFactory.locate(fullPath); final String dataUri = getDataUriGenerator().generateDataURI(is, fileName); if (isReplaceAccepted(dataUri)) { result = dataUri; LOG.debug("dataUri replacement: {}", StringUtils.abbreviate(dataUri, 30)); } } catch (final IOException e) { LOG.warn("[FAIL] extract dataUri from: {}, because: {}. " + "A possible cause: using CssUrlRewritingProcessor before CssDataUriPreProcessor.", fullPath, e.getMessage()); } finally { IOUtils.closeQuietly(is); } return result; } /** * @param imageUrl * the original url of the image. * @return true if the image url should be replaced with another (servlet context relative). */ private boolean isImageUrlChangeRequired(final String imageUrl) { return !(imageUrl.startsWith("http") || ResourceProxyRequestHandler.isProxyUri(imageUrl)); } /** * Similar to {@link CssDataUriPreProcessor#isReplaceAccepted(String)}, but decides whether the computed dataUri * should replace the image url. It is useful when you want to limit the dataUri size. By default the size of dataUri * is limited to 32KB (because IE8 has a 32KB limitation). * * @param dataUri * base64 encoded stream. * @return true if dataUri should replace original image url. */ protected boolean isReplaceAccepted(final String dataUri) { try { final byte[] bytes = dataUri.getBytes(CharEncoding.UTF_8); final boolean exceedLimit = bytes.length >= SIZE_LIMIT; LOG.debug("dataUri size: {}KB, limit exceeded: {}", bytes.length / 1024, exceedLimit); return !exceedLimit; } catch (final UnsupportedEncodingException e) { throw new WroRuntimeException("Should never happen", e); } } /** * {@inheritDoc} */ @Override protected boolean isReplaceNeeded(final String url) { // the dataUri should replace also absolute url's return !DataUriGenerator.isDataUri(url.trim()); } /** * @return the DataUriGenerator class responsible for transforming streams into base64 encoded strings. * @VisibleForTesting */ protected DataUriGenerator getDataUriGenerator() { if (dataUriGenerator == null) { dataUriGenerator = new DataUriGenerator(); } return dataUriGenerator; } }
File
CssDataUriPreProcessor.java
Developer's decision
Combination
Kind of conflict
Class declaration
Comment
Import
Package declaration
Chunk
Conflicting content
import ro.isdc.wro.model.group.processor.Injector;
import ro.isdc.wro.model.resource.Resource;
import ro.isdc.wro.model.resource.ResourceType;
<<<<<<< HEAD
import ro.isdc.wro.model.resource.locator.factory.ResourceLocatorFactory;
import ro.isdc.wro.model.resource.processor.ResourceProcessor;
=======
import ro.isdc.wro.model.resource.locator.factory.UriLocatorFactory;
import ro.isdc.wro.model.resource.processor.Destroyable;
import ro.isdc.wro.model.resource.processor.ResourcePreProcessor;
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
import ro.isdc.wro.model.resource.processor.decorator.ExceptionHandlingProcessorDecorator;
import ro.isdc.wro.model.resource.processor.impl.css.AbstractCssImportPreProcessor;
import ro.isdc.wro.model.resource.processor.impl.css.CssImportPreProcessor;
Solution content
import ro.isdc.wro.model.group.processor.Injector;
import ro.isdc.wro.model.resource.Resource;
import ro.isdc.wro.model.resource.ResourceType;
import ro.isdc.wro.model.resource.locator.factory.ResourceLocatorFactory;
import ro.isdc.wro.model.resource.processor.ResourceProcessor;
import ro.isdc.wro.model.resource.processor.decorator.ExceptionHandlingProcessorDecorator;
import ro.isdc.wro.model.resource.processor.impl.css.AbstractCssImportPreProcessor;
import ro.isdc.wro.model.resource.processor.impl.css.CssImportPreProcessor;
File
ResourceWatcher.java
Developer's decision
Version 1
Kind of conflict
Import
Chunk
Conflicting content
   *          the name of the group being processed.
   * @return a processor used to detect changes in imported resources.
   */
<<<<<<< HEAD
  private ResourceProcessor createCssImportProcessor(final AtomicBoolean changeDetected,
      final String groupName) {
    final ResourceProcessor cssImportProcessor = new AbstractCssImportPreProcessor() {
=======
  private ResourcePreProcessor createCssImportProcessor(final AtomicBoolean changeDetected, final String groupName) {
    final ResourcePreProcessor cssImportProcessor = new AbstractCssImportPreProcessor() {
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
      @Override
      protected void onImportDetected(final String importedUri) {
        LOG.debug("Found @import {}", importedUri);
Solution content
   *          the name of the group being processed.
   * @return a processor used to detect changes in imported resources.
   */
  private ResourceProcessor createCssImportProcessor(final AtomicBoolean changeDetected,
      final String groupName) {
    final ResourceProcessor cssImportProcessor = new AbstractCssImportPreProcessor() {
      @Override
      protected void onImportDetected(final String importedUri) {
        LOG.debug("Found @import {}", importedUri);
File
ResourceWatcher.java
Developer's decision
Version 1
Kind of conflict
Method invocation
Method signature
Variable
Chunk
Conflicting content
    sample.processorsFactory.getPostProcessors();
    verify(mockProcessorsFactory).getPostProcessors();
<<<<<<< HEAD
    
    sample.resourceLocatorFactory.getLocator("");
    verify(mockLocatorFactory).getLocator("");
    
    sample.metaDataFactory.create();
    verify(mockMetaDataFactory).create();
    
    assertSame(mockProcessorsFactory, AbstractDecorator.getOriginalDecoratedObject(sample.processorsFactory));
    assertSame(mockLocatorFactory, AbstractDecorator.getOriginalDecoratedObject(sample.resourceLocatorFactory));
=======

    sample.uriLocatorFactory.getInstance("");
    verify(mockLocatorFactory).getInstance("");

    sample.metaDataFactory.create();
    verify(mockMetaDataFactory).create();
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b

    assertNotNull(sample.callbackRegistry);
    assertSame(injector, sample.injector);
Solution content
    sample.processorsFactory.getPostProcessors();
    verify(mockProcessorsFactory).getPostProcessors();

    sample.resourceLocatorFactory.getLocator("");
    verify(mockLocatorFactory).getLocator("");

    sample.metaDataFactory.create();
    verify(mockMetaDataFactory).create();

    assertSame(mockProcessorsFactory, AbstractDecorator.getOriginalDecoratedObject(sample.processorsFactory));
    assertSame(mockLocatorFactory, AbstractDecorator.getOriginalDecoratedObject(sample.resourceLocatorFactory));

    assertNotNull(sample.callbackRegistry);
    assertSame(injector, sample.injector);
File
TestInjectorBuilder.java
Developer's decision
Version 1
Kind of conflict
Method invocation
Chunk
Conflicting content
  @Before
  public void setUp() {
    Context.set(Context.standaloneContext());
<<<<<<< HEAD
    victim = new ResourceChangeDetector();
    final WroManagerFactory managerFactory = new BaseWroManagerFactory().setLocatorFactory(WroTestUtils.createResourceMockingLocatorFactory());
=======
    final WroManagerFactory managerFactory = new BaseWroManagerFactory()
        .setUriLocatorFactory(new SimpleUriLocatorFactory().addLocator(WroTestUtils.createResourceMockingLocator()));
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
    final Injector injector = InjectorBuilder.create(managerFactory).build();
    injector.inject(this);
  }
Solution content
  @Before
  public void setUp() {
    Context.set(Context.standaloneContext());
    final WroManagerFactory managerFactory = new BaseWroManagerFactory().setLocatorFactory(WroTestUtils.createResourceMockingLocatorFactory());
    final Injector injector = InjectorBuilder.create(managerFactory).build();
    injector.inject(this);
  }
File
TestResourceChangeDetector.java
Developer's decision
Combination
Kind of conflict
Attribute
Method invocation
Variable
Chunk
Conflicting content
import ro.isdc.wro.model.group.processor.InjectorBuilder;
import ro.isdc.wro.model.resource.Resource;
import ro.isdc.wro.model.resource.ResourceType;
<<<<<<< HEAD
import ro.isdc.wro.model.resource.locator.ResourceLocator;
import ro.isdc.wro.model.resource.locator.factory.ResourceLocatorFactory;
=======
import ro.isdc.wro.model.resource.locator.UriLocator;
import ro.isdc.wro.model.resource.locator.factory.AbstractUriLocatorFactory;
import ro.isdc.wro.model.resource.locator.factory.UriLocatorFactory;
import ro.isdc.wro.model.resource.support.change.ResourceWatcher.Callback;
import ro.isdc.wro.util.Function;
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
import ro.isdc.wro.util.ObjectFactory;
import ro.isdc.wro.util.WroTestUtils;
import ro.isdc.wro.util.WroUtil;
Solution content
import ro.isdc.wro.model.group.processor.InjectorBuilder;
import ro.isdc.wro.model.resource.Resource;
import ro.isdc.wro.model.resource.ResourceType;
import ro.isdc.wro.model.resource.locator.ResourceLocator;
import ro.isdc.wro.model.resource.locator.factory.ResourceLocatorFactory;
import ro.isdc.wro.model.resource.support.change.ResourceWatcher.Callback;
import ro.isdc.wro.util.Function;
import ro.isdc.wro.util.ObjectFactory;
import ro.isdc.wro.util.WroTestUtils;
import ro.isdc.wro.util.WroUtil;
File
TestResourceWatcher.java
Developer's decision
Combination
Kind of conflict
Import
Chunk
Conflicting content
  private final CacheKey cacheKey = new CacheKey(GROUP_NAME, ResourceType.CSS, true);
  private final CacheKey cacheEntry2 = new CacheKey(GROUP_2, ResourceType.JS, true);
  @Mock
<<<<<<< HEAD
  private ResourceLocator mockLocator;
  @Mock
  private ResourceLocatorFactory mockLocatorFactory;
=======
  private HttpServletRequest request;
  @Mock
  private HttpServletResponse response;
  @Mock
  private FilterConfig filterConfig;
  @Mock
  private UriLocator mockLocator;
  @Mock
  private Callback resourceWatcherCallback;
  @Mock
  private CacheStrategy cacheStrategy;
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b

  private ResourceWatcher victim;
Solution content
  private final CacheKey cacheKey = new CacheKey(GROUP_NAME, ResourceType.CSS, true);
  private final CacheKey cacheEntry2 = new CacheKey(GROUP_2, ResourceType.JS, true);
  @Mock
  private HttpServletRequest request;
  @Mock
  private HttpServletResponse response;
  @Mock
  private FilterConfig filterConfig;
  @Mock
  private ResourceLocatorFactory mockLocatorFactory;
  @Mock
  private Callback resourceWatcherCallback;
  @Mock
  private CacheStrategy cacheStrategy;

  private ResourceWatcher victim;
File
TestResourceWatcher.java
Developer's decision
Combination
Kind of conflict
Annotation
Attribute
Chunk
Conflicting content
  public void setUp()
      throws Exception {
    initMocks(this);
<<<<<<< HEAD
    Context.set(Context.standaloneContext());
    victim = new ResourceWatcher();
    when(mockLocatorFactory.getLocator(Mockito.anyString())).thenReturn(mockLocator);
    when(mockLocatorFactory.locate(Mockito.anyString())).thenReturn(WroUtil.EMPTY_STREAM);
    when(mockLocator.getInputStream()).thenReturn(WroUtil.EMPTY_STREAM);
=======
    Context.set(Context.webContext(request, response, filterConfig));
    // spy the interface instead of WroTestUtils.createResourceMockingLocator() because of mockito bug which was
    // reported on their mailing list.
    mockLocator = Mockito.spy(new UriLocator() {
      public InputStream locate(final String uri)
          throws IOException {
        return new ByteArrayInputStream(uri.getBytes());
      }

      public boolean accept(final String uri) {
        return true;
      }
    });
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b

    victim = new ResourceWatcher();
    createDefaultInjector().inject(victim);
Solution content
  public void setUp()
      throws Exception {
    initMocks(this);
    Context.set(Context.webContext(request, response, filterConfig));
    victim = new ResourceWatcher();
    when(mockLocatorFactory.getLocator(Mockito.anyString())).thenReturn(mockLocator);
    when(mockLocatorFactory.locate(Mockito.anyString())).thenReturn(WroUtil.EMPTY_STREAM);
    when(mockLocator.getInputStream()).thenReturn(WroUtil.EMPTY_STREAM);

    victim = new ResourceWatcher();
    createDefaultInjector().inject(victim);
File
TestResourceWatcher.java
Developer's decision
Combination
Kind of conflict
Attribute
Comment
Method invocation
Chunk
Conflicting content
  public void tearDown()
        Resource.create("/path/2.js")));
    createDefaultInjector().inject(victim);
  }

<<<<<<< HEAD
  public Injector createDefaultInjector() {
=======
  @After
      throws Exception {
    victim.destroy();
    Context.unset();
  }

  public Injector createDefaultInjector() {
    final UriLocatorFactory locatorFactory = new AbstractUriLocatorFactory() {
      public UriLocator getInstance(final String uri) {
        return mockLocator;
      }
    };

>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
    final WroModel model = new WroModel().addGroup(new Group(GROUP_NAME).addResource(Resource.create(RESOURCE_URI)));
    model.addGroup(new Group(GROUP_2).addResource(Resource.create(RESOURCE_FIRST)).addResource(
Solution content
      throws Exception {
    victim.destroy();
    Context.unset();
  }

  public Injector createDefaultInjector() {
    createDefaultInjector().inject(victim);
  }

  @After
  public void tearDown()
    final WroModel model = new WroModel().addGroup(new Group(GROUP_NAME).addResource(Resource.create(RESOURCE_URI)));
    model.addGroup(new Group(GROUP_2).addResource(Resource.create(RESOURCE_FIRST)).addResource(
        Resource.create("/path/2.js")));
File
TestResourceWatcher.java
Developer's decision
Combination
Kind of conflict
Annotation
Method declaration
Method invocation
Method signature
Variable
Chunk
Conflicting content
    model.addGroup(new Group(GROUP_2).addResource(Resource.create(RESOURCE_FIRST)).addResource(
        Resource.create("/path/2.js")));
    final WroModelFactory modelFactory = WroTestUtils.simpleModelFactory(model);
<<<<<<< HEAD
    final WroManagerFactory factory = new BaseWroManagerFactory().setModelFactory(modelFactory).setLocatorFactory(
        mockLocatorFactory);
=======
    final WroManagerFactory factory = new BaseWroManagerFactory().setModelFactory(modelFactory).setUriLocatorFactory(
        locatorFactory).setCacheStrategy(cacheStrategy);
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
    final Injector injector = InjectorBuilder.create(factory).build();
    return injector;
  }
Solution content
    model.addGroup(new Group(GROUP_2).addResource(Resource.create(RESOURCE_FIRST)).addResource(
        Resource.create("/path/2.js")));
    final WroModelFactory modelFactory = WroTestUtils.simpleModelFactory(model);
    final WroManagerFactory factory = new BaseWroManagerFactory().setModelFactory(modelFactory).setLocatorFactory(
        mockLocatorFactory);
    final Injector injector = InjectorBuilder.create(factory).build();
    return injector;
  }
File
TestResourceWatcher.java
Developer's decision
Version 1
Kind of conflict
Method invocation
Variable
Chunk
Conflicting content
    victim.check(cacheKey, resourceWatcherCallback);
    assertFalse(victim.getResourceChangeDetector().checkChangeForGroup(RESOURCE_URI, GROUP_NAME));

<<<<<<< HEAD
    Mockito.when(mockLocatorFactory.locate(Mockito.anyString())).then(answerWithContent("different"));

    victim.check(cacheEntry);
=======
    Mockito.when(mockLocator.locate(Mockito.anyString())).thenReturn(new ByteArrayInputStream("different".getBytes()));
    final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CacheKey.class);

    victim.check(cacheKey);
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
    assertTrue(victim.getResourceChangeDetector().checkChangeForGroup(RESOURCE_URI, GROUP_NAME));
    Mockito.verify(resourceWatcherCallback).onGroupChanged(argumentCaptor.capture());
    assertEquals(GROUP_NAME, argumentCaptor.getValue().getGroupName());
Solution content
    victim.check(cacheKey, resourceWatcherCallback);
    assertFalse(victim.getResourceChangeDetector().checkChangeForGroup(RESOURCE_URI, GROUP_NAME));

    Mockito.when(mockLocatorFactory.locate(Mockito.anyString())).then(answerWithContent("different"));
    final ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(CacheKey.class);

    victim.check(cacheKey);
    assertTrue(victim.getResourceChangeDetector().checkChangeForGroup(RESOURCE_URI, GROUP_NAME));
    Mockito.verify(resourceWatcherCallback).onGroupChanged(argumentCaptor.capture());
    assertEquals(GROUP_NAME, argumentCaptor.getValue().getGroupName());
File
TestResourceWatcher.java
Developer's decision
Combination
Kind of conflict
Method invocation
Variable
Chunk
Conflicting content
    createDefaultInjector().inject(victim);
    final ResourceChangeDetector mockChangeDetector = Mockito.spy(victim.getResourceChangeDetector());

<<<<<<< HEAD
    Mockito.when(mockLocatorFactory.locate(Mockito.anyString())).thenThrow(new IOException("Resource is unavailable"));

    victim.check(cacheEntry);
=======
    Mockito.when(mockLocator.locate(Mockito.anyString())).thenThrow(new IOException("Resource is unavailable"));

    victim.check(cacheKey, resourceWatcherCallback);
    verify(resourceWatcherCallback, never()).onGroupChanged(Mockito.any(CacheKey.class));
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
    verify(mockChangeDetector, never()).checkChangeForGroup(Mockito.anyString(), Mockito.anyString());
  }
Solution content
    createDefaultInjector().inject(victim);
    final ResourceChangeDetector mockChangeDetector = Mockito.spy(victim.getResourceChangeDetector());

    Mockito.when(mockLocatorFactory.locate(Mockito.anyString())).thenThrow(new IOException("Resource is unavailable"));

    victim.check(cacheKey, resourceWatcherCallback);
    verify(resourceWatcherCallback, never()).onGroupChanged(Mockito.any(CacheKey.class));
    verify(mockChangeDetector, never()).checkChangeForGroup(Mockito.anyString(), Mockito.anyString());
  }
File
TestResourceWatcher.java
Developer's decision
Combination
Kind of conflict
Method invocation
Chunk
Conflicting content
    victim.check(cacheEntry);


      throws Exception {
    final String importResourceUri = "imported.css";
    final CacheKey cacheEntry = new CacheKey(GROUP_NAME, ResourceType.CSS, true);
<<<<<<< HEAD
    victim = new ResourceWatcher() {
      @Override
      void onResourceChanged(final Resource resource) {
        importResourceChanged.set(true);
      }

      @Override
      void onGroupChanged(final CacheKey key) {
        groupChanged.set(true);
      }
    };
    createDefaultInjector().inject(victim);
    when(mockLocator.getInputStream()).then(answerWithContent(String.format("@import url(%s)", importResourceUri)));

    final ResourceLocator mockImportedResourceLocator = mock(ResourceLocator.class);
    when(mockImportedResourceLocator.getInputStream()).then(answerWithContent("initial"));

    when(mockLocatorFactory.getLocator(Mockito.eq("/" + RESOURCE_URI))).thenReturn(mockLocator);
    when(mockLocatorFactory.getLocator(Mockito.eq("/" + importResourceUri))).thenReturn(mockImportedResourceLocator);

    victim.check(cacheEntry);

    when(mockImportedResourceLocator.getInputStream()).then(answerWithContent("changed"));
=======
    victim = new ResourceWatcher();
    createDefaultInjector().inject(victim);
    when(mockLocator.locate(Mockito.anyString())).thenAnswer(answerWithContent("initial"));
    when(mockLocator.locate("/" + Mockito.eq(RESOURCE_URI))).thenAnswer(
        answerWithContent(String.format("@import url(%s)", importResourceUri)));

    victim.check(cacheEntry, resourceWatcherCallback);

    when(mockLocator.locate(Mockito.anyString())).thenAnswer(answerWithContent("changed"));
    when(mockLocator.locate("/" + Mockito.eq(RESOURCE_URI))).thenAnswer(
        answerWithContent(String.format("@import url(%s)", importResourceUri)));
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
Solution content
      throws Exception {
    final String importResourceUri = "imported.css";
    final CacheKey cacheEntry = new CacheKey(GROUP_NAME, ResourceType.CSS, true);
    victim = new ResourceWatcher();
    createDefaultInjector().inject(victim);
    when(mockLocator.getInputStream()).then(answerWithContent(String.format("@import url(%s)", importResourceUri)));

    final ResourceLocator mockImportedResourceLocator = mock(ResourceLocator.class);
    when(mockImportedResourceLocator.getInputStream()).then(answerWithContent("initial"));

    when(mockLocatorFactory.getLocator(Mockito.eq("/" + RESOURCE_URI))).thenReturn(mockLocator);
    when(mockLocatorFactory.getLocator(Mockito.eq("/" + importResourceUri))).thenReturn(mockImportedResourceLocator);

    victim.check(cacheEntry);

    when(mockImportedResourceLocator.getInputStream()).then(answerWithContent("changed"));

    victim.check(cacheEntry);
File
TestResourceWatcher.java
Developer's decision
Combination
Kind of conflict
Attribute
Method invocation
Variable
Chunk
Conflicting content
  @Test
  public void shouldNotDetectErroneouslyChange()
      throws Exception {
<<<<<<< HEAD
    final AtomicBoolean groupChanged = new AtomicBoolean(false);
    final AtomicBoolean resourceChanged = new AtomicBoolean(false);
    victim = new ResourceWatcher() {
      @Override
      void onResourceChanged(final Resource resource) {
        resourceChanged.set(true);
      }

      @Override
      void onGroupChanged(final CacheKey key) {
        groupChanged.set(true);
      }
    };

=======
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
    createDefaultInjector().inject(victim);

    // first check will always detect changes.
Solution content
  @Test
  public void shouldNotDetectErroneouslyChange()
      throws Exception {
    createDefaultInjector().inject(victim);

    // first check will always detect changes.
File
TestResourceWatcher.java
Developer's decision
Version 2
Kind of conflict
Attribute
Method invocation
Variable
Chunk
Conflicting content
    createDefaultInjector().inject(victim);

    // first check will always detect changes.
<<<<<<< HEAD
    victim.check(cacheEntry2);

    Mockito.when(mockLocatorFactory.locate(RESOURCE_FIRST)).then(answerWithContent("different"));

    victim.check(cacheEntry2);
    assertTrue(groupChanged.get());
    assertTrue(resourceChanged.get());

    groupChanged.set(false);
    resourceChanged.set(false);
=======
    victim.check(cacheEntry2, resourceWatcherCallback);

    when(mockLocator.locate(RESOURCE_FIRST)).thenAnswer(answerWithContent("changed"));

    victim.check(cacheEntry2, resourceWatcherCallback);
    verify(resourceWatcherCallback, Mockito.atLeastOnce()).onGroupChanged(Mockito.any(CacheKey.class));
    verify(resourceWatcherCallback, Mockito.atLeastOnce()).onResourceChanged(Mockito.any(Resource.class));

    Mockito.reset(resourceWatcherCallback);
>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b

    // next check should find no change
    victim.check(cacheEntry2, resourceWatcherCallback);
Solution content
    createDefaultInjector().inject(victim);

    // first check will always detect changes.
    victim.check(cacheEntry2, resourceWatcherCallback);

    Mockito.when(mockLocatorFactory.locate(RESOURCE_FIRST)).then(answerWithContent("changed"));

    victim.check(cacheEntry2, resourceWatcherCallback);
    verify(resourceWatcherCallback, Mockito.atLeastOnce()).onGroupChanged(Mockito.any(CacheKey.class));
    verify(resourceWatcherCallback, Mockito.atLeastOnce()).onResourceChanged(Mockito.any(Resource.class));

    Mockito.reset(resourceWatcherCallback);

    // next check should find no change
    victim.check(cacheEntry2, resourceWatcherCallback);
File
TestResourceWatcher.java
Developer's decision
Manual
Kind of conflict
Method invocation
Chunk
Conflicting content
  @Test
              }
    assertTrue(flag.get());
  }

<<<<<<< HEAD
=======
  @Test
  public void shouldCheckForChangeAsynchronously()
      throws Exception {
    final String invalidUrl = "http://invalidEndpoint:9999/";
    when(request.getRequestURL()).thenReturn(new StringBuffer(invalidUrl));
    when(request.getServletPath()).thenReturn("");
    final AtomicReference> asyncInvoker = new AtomicReference>();
    final AtomicReference exceptionHolder = new AtomicReference();
    victim = new ResourceWatcher() {
      @Override
      void submit(final Callable callable) {
        try {
          final Callable decorated = new ContextPropagatingCallable(callable) {
            @Override
            public Void call()
                throws Exception {
              try {
                callable.call();
                return null;
              } catch (final Exception e) {
                exceptionHolder.set(e);
                throw e;
              } finally {
                asyncInvoker.set(callable);
            }
          };
          super.submit(decorated);
        } finally {
        }
      }
    };
    createDefaultInjector().inject(victim);

    Context.get().getConfig().setResourceWatcherAsync(true);

    victim.checkAsync(cacheKey);
    WroTestUtils.waitUntil(new Function() {
      public Boolean apply(final Void input)
          throws Exception {
        return asyncInvoker.get() != null;
      }
    }, 500);
    assertNotNull(asyncInvoker.get());
    assertNotNull(exceptionHolder.get());
    //We expect a request to an invalid host, since a call to configured url will be performed.
    assertTrue(exceptionHolder.get() instanceof UnknownHostException);
  }

  public void shouldRemoveKeyFromCacheStrategyWhenChangeDetected() {
    victim.check(cacheKey);
    final CacheValue cacheValue = null;
    verify(cacheStrategy).put(Mockito.eq(cacheKey), Mockito.eq(cacheValue));
  }

>>>>>>> b51b01fcaaaf0cc2a3d7de0ba9af7c756f68813b
  private Answer answerWithContent(final String content) {
    return new Answer() {
      public InputStream answer(final InvocationOnMock invocation)
Solution content
      @Override
                exceptionHolder.set(e);
    victim = new ResourceWatcher() {
    assertTrue(flag.get());
  }

  @Test
  public void shouldCheckForChangeAsynchronously()
      throws Exception {
    final String invalidUrl = "http://invalidEndpoint:9999/";
    when(request.getRequestURL()).thenReturn(new StringBuffer(invalidUrl));
    when(request.getServletPath()).thenReturn("");
    final AtomicReference> asyncInvoker = new AtomicReference>();
    final AtomicReference exceptionHolder = new AtomicReference();
      void submit(final Callable callable) {
        try {
          final Callable decorated = new ContextPropagatingCallable(callable) {
            @Override
            public Void call()
                throws Exception {
              try {
                callable.call();
                return null;
              } catch (final Exception e) {
                throw e;
              } finally {
                asyncInvoker.set(callable);
              }
            }
          };
          super.submit(decorated);
        } finally {
        }
      }
    };
    createDefaultInjector().inject(victim);

    Context.get().getConfig().setResourceWatcherAsync(true);

    victim.checkAsync(cacheKey);
    WroTestUtils.waitUntil(new Function() {
      public Boolean apply(final Void input)
          throws Exception {
        return asyncInvoker.get() != null;
      }
    }, 500);
    assertNotNull(asyncInvoker.get());
    assertNotNull(exceptionHolder.get());
    //We expect a request to an invalid host, since a call to configured url will be performed.
    assertTrue(exceptionHolder.get() instanceof UnknownHostException);
  }

  @Test
  public void shouldRemoveKeyFromCacheStrategyWhenChangeDetected() {
    victim.check(cacheKey);
    final CacheValue cacheValue = null;
    verify(cacheStrategy).put(Mockito.eq(cacheKey), Mockito.eq(cacheValue));
  }

  private Answer answerWithContent(final String content) {
    return new Answer() {
      public InputStream answer(final InvocationOnMock invocation)
File
TestResourceWatcher.java
Developer's decision
Version 2
Kind of conflict
Annotation
Method declaration