Search in sources :

Example 1 with WebJarsResourceReference

use of org.xwiki.webjars.internal.WebJarsResourceReference in project xwiki-platform by xwiki.

the class WebJarsScriptService method url.

/**
 * Creates an URL that can be used to load a resource (JavaScript, CSS, etc.) from a WebJar in the passed namespace.
 *
 * @param webjarId the id of the WebJar that contains the resource; the format of the WebJar id is
 *            {@code groupId:artifactId} (e.g. {@code org.xwiki.platform:xwiki-platform-job-webjar}), where the
 *            {@code groupId} can be omitted if it is {@link #DEFAULT_WEBJAR_GROUP_ID} (i.e. {@code angular}
 *            translates to {@code org.webjars:angular})
 * @param namespace the namespace in which the webjars resources will be loaded from (e.g. for a wiki namespace you
 *                  should use the format {@code wiki:<wikiId>}). If null then defaults to the current wiki
 *                  namespace. And if the passed namespace doesn't exist, falls back to the main wiki namespace
 * @param path the path within the WebJar, starting from the version folder (e.g. you should pass just
 *            {@code angular.js} if the actual path is {@code META-INF/resources/webjars/angular/2.1.11/angular.js})
 * @param params additional query string parameters to add to the returned URL; there are two known (reserved)
 *            parameters: {@code version} (the WebJar version) and {@code evaluate} (a boolean parameter that
 *            specifies if the requested resource has Velocity code that needs to be evaluated); besides these you
 *            can pass whatever parameters you like (they will be taken into account or not depending on the
 *            resource)
 * @return the URL to load the WebJar resource (relative to the context path of the web application)
 * @since 8.1M2
 */
public String url(String webjarId, String namespace, String path, Map<String, ?> params) {
    if (StringUtils.isEmpty(webjarId)) {
        return null;
    }
    String groupId = DEFAULT_WEBJAR_GROUP_ID;
    String artifactId = webjarId;
    int groupSeparatorPosition = webjarId.indexOf(':');
    if (groupSeparatorPosition >= 0) {
        // A different group id.
        groupId = webjarId.substring(0, groupSeparatorPosition);
        artifactId = webjarId.substring(groupSeparatorPosition + 1);
    }
    Map<String, Object> urlParams = new LinkedHashMap<>();
    if (params != null) {
        urlParams.putAll(params);
    }
    // For backward-compatibility reasons we still support passing the target wiki in parameters. However we need
    // to remove it from the params if that's the case since we don't want to output a URL with the wiki id in the
    // query string (since the namespace is now part of the URL).
    urlParams.remove(WIKI);
    Object version = urlParams.remove(VERSION);
    if (version == null) {
        // Try to determine the version based on the extensions that are currently installed or provided by default.
        version = getVersion(String.format("%s:%s", groupId, artifactId), namespace);
    }
    // Construct a WebJarsResourceReference so that we can serialize it!
    WebJarsResourceReference resourceReference = getResourceReference(artifactId, version, namespace, path, urlParams);
    ExtendedURL extendedURL;
    try {
        extendedURL = this.defaultResourceReferenceSerializer.serialize(resourceReference);
    } catch (SerializeResourceReferenceException | UnsupportedResourceReferenceException e) {
        this.logger.warn("Error while serializing WebJar URL for id [{}], path = [{}]. Root cause = [{}]", webjarId, path, ExceptionUtils.getRootCauseMessage(e));
        return null;
    }
    return extendedURL.serialize();
}
Also used : SerializeResourceReferenceException(org.xwiki.resource.SerializeResourceReferenceException) WebJarsResourceReference(org.xwiki.webjars.internal.WebJarsResourceReference) UnsupportedResourceReferenceException(org.xwiki.resource.UnsupportedResourceReferenceException) ExtendedURL(org.xwiki.url.ExtendedURL) LinkedHashMap(java.util.LinkedHashMap)

Example 2 with WebJarsResourceReference

use of org.xwiki.webjars.internal.WebJarsResourceReference in project xwiki-platform by xwiki.

the class WebJarsResourceReferenceHandlerTest method executeWhenResourceExists.

@Test
public void executeWhenResourceExists() throws Exception {
    WebJarsResourceReference reference = new WebJarsResourceReference("wiki:wiki", Arrays.asList("angular", "2.1.11", "angular.js"));
    ByteArrayInputStream resourceStream = new ByteArrayInputStream("content".getBytes());
    when(this.classLoader.getResourceAsStream("META-INF/resources/webjars/angular/2.1.11/angular.js")).thenReturn(resourceStream);
    Long now = new Date().getTime();
    this.handler.handle(reference, this.chain);
    assertEquals(1, this.handler.getSupportedResourceReferences().size());
    assertEquals(WebJarsResourceReference.TYPE, this.handler.getSupportedResourceReferences().get(0));
    // Verify that the resource content has been copied to the Response output stream.
    assertEquals("content", this.response.getOutputStream().toString());
    // Verify that the correct Content Type has been set.
    verify(this.response).setContentType("application/javascript");
    // Verify that the static resource is cached permanently.
    verify(this.response.getHttpServletResponse()).setHeader("Cache-Control", "public");
    ArgumentCaptor<Long> expireDate = ArgumentCaptor.forClass(Long.class);
    verify(this.response.getHttpServletResponse()).setDateHeader(eq("Expires"), expireDate.capture());
    // The expiration date should be in one year from now.
    assertTrue(expireDate.getValue() >= (now + 365 * 24 * 3600 * 1000L));
    // Also verify that the "Last-Modified" header has been set in the response so that the browser will send
    // an If-Modified-Since header for the next request and we can tell it to use its cache.
    verify(this.response.getHttpServletResponse()).setDateHeader(eq("Last-Modified"), anyLong());
    verify(this.chain).handleNext(reference);
}
Also used : WebJarsResourceReference(org.xwiki.webjars.internal.WebJarsResourceReference) ByteArrayInputStream(java.io.ByteArrayInputStream) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) Date(java.util.Date) Test(org.junit.Test)

Example 3 with WebJarsResourceReference

use of org.xwiki.webjars.internal.WebJarsResourceReference in project xwiki-platform by xwiki.

the class WebJarsResourceReferenceHandlerTest method executeWhenResourceDoesntExist.

@Test
public void executeWhenResourceDoesntExist() throws Exception {
    WebJarsResourceReference reference = new WebJarsResourceReference("wiki:wiki", Arrays.asList("angular", "2.1.11", "angular.js"));
    this.handler.handle(reference, this.chain);
    verify(this.classLoader).getResourceAsStream("META-INF/resources/webjars/angular/2.1.11/angular.js");
    verify(this.response.getHttpServletResponse()).sendError(404, "Resource not found [angular/2.1.11/angular.js].");
    verify(this.chain).handleNext(reference);
}
Also used : WebJarsResourceReference(org.xwiki.webjars.internal.WebJarsResourceReference) Test(org.junit.Test)

Example 4 with WebJarsResourceReference

use of org.xwiki.webjars.internal.WebJarsResourceReference in project xwiki-platform by xwiki.

the class WebJarsResourceReferenceHandlerTest method return304WhenIfModifiedSinceHeader.

@Test
public void return304WhenIfModifiedSinceHeader() throws Exception {
    WebJarsResourceReference reference = new WebJarsResourceReference("wiki:wiki", Arrays.asList("angular", "2.1.11", "angular.js"));
    when(this.request.getHttpServletRequest().getHeader("If-Modified-Since")).thenReturn("some value");
    this.handler.handle(reference, this.chain);
    // This the test: we verify that 304 is returned when the "If-Modified-Since" header is found in the request
    verify(this.response.getHttpServletResponse()).setStatus(304);
    verify(this.chain).handleNext(reference);
}
Also used : WebJarsResourceReference(org.xwiki.webjars.internal.WebJarsResourceReference) Test(org.junit.Test)

Example 5 with WebJarsResourceReference

use of org.xwiki.webjars.internal.WebJarsResourceReference in project xwiki-platform by xwiki.

the class WebJarsResourceReferenceHandlerTest method evaluateResource.

@Test
public void evaluateResource() throws Exception {
    WebJarsResourceReference reference = new WebJarsResourceReference("wiki:wiki", Arrays.asList("angular", "2.1.11", "angular.js"));
    reference.addParameter("evaluate", true);
    ByteArrayInputStream resourceStream = new ByteArrayInputStream("content".getBytes());
    when(this.classLoader.getResourceAsStream("META-INF/resources/webjars/angular/2.1.11/angular.js")).thenReturn(resourceStream);
    VelocityManager velocityManager = this.componentManager.getInstance(VelocityManager.class);
    VelocityEngine velocityEngine = mock(VelocityEngine.class);
    when(velocityManager.getVelocityEngine()).thenReturn(velocityEngine);
    doAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) {
            ((StringWriter) invocation.getArguments()[1]).write("evaluated content");
            return null;
        }
    }).when(velocityEngine).evaluate(any(), any(), eq("angular/2.1.11/angular.js"), any(Reader.class));
    this.handler.handle(reference, this.chain);
    // Verify that the resource content has been evaluated and copied to the Response output stream.
    assertEquals("evaluated content", this.response.getOutputStream().toString());
    // Verify that the correct Content Type has been set.
    verify(this.response).setContentType("application/javascript");
    // Verify that the dynamic resource is not cached.
    verify(this.response.getHttpServletResponse(), never()).setHeader(any(), any());
    verify(this.response.getHttpServletResponse(), never()).setDateHeader(any(), anyLong());
}
Also used : VelocityEngine(org.xwiki.velocity.VelocityEngine) WebJarsResourceReference(org.xwiki.webjars.internal.WebJarsResourceReference) ByteArrayInputStream(java.io.ByteArrayInputStream) VelocityManager(org.xwiki.velocity.VelocityManager) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Reader(java.io.Reader) Test(org.junit.Test)

Aggregations

WebJarsResourceReference (org.xwiki.webjars.internal.WebJarsResourceReference)15 Test (org.junit.Test)13 ExtendedURL (org.xwiki.url.ExtendedURL)8 WikiDescriptorManager (org.xwiki.wiki.descriptor.WikiDescriptorManager)5 ByteArrayInputStream (java.io.ByteArrayInputStream)3 LinkedHashMap (java.util.LinkedHashMap)3 ExtensionId (org.xwiki.extension.ExtensionId)3 InstalledExtension (org.xwiki.extension.InstalledExtension)3 InstalledExtensionRepository (org.xwiki.extension.repository.InstalledExtensionRepository)3 Reader (java.io.Reader)2 VelocityEngine (org.xwiki.velocity.VelocityEngine)2 VelocityManager (org.xwiki.velocity.VelocityManager)2 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 Map (java.util.Map)1 VelocityException (org.apache.velocity.exception.VelocityException)1 ArgumentMatchers.anyLong (org.mockito.ArgumentMatchers.anyLong)1 InvocationOnMock (org.mockito.invocation.InvocationOnMock)1 ResourceReferenceHandlerException (org.xwiki.resource.ResourceReferenceHandlerException)1 SerializeResourceReferenceException (org.xwiki.resource.SerializeResourceReferenceException)1