All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xmlresolver.ResourceResponse Maven / Gradle / Ivy

There is a newer version: 6.0.11
Show newest version
package org.xmlresolver;

import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A {@code ResourceResponse} is the return type for either an attempt to lookup a resource
 * in the catalog or to resolve a resource. It encapsulates the results of the attempt.
 */
public class ResourceResponse {
    /** The request for which this is the response. */
    public final ResourceRequest request;
    private URI uri;
    private URI resolvedURI;
    private boolean rejected = false;
    private boolean resolved = false;
    private final Map> headers = new HashMap<>();
    private InputStream stream = null;
    private String contentType = null;
    private String encoding = null;
    private int statusCode = -1;
    private ResourceConnection connection = null;

    /**
     * The simplest constructor for an unsuccessful request.
     * @param request The request.
     */
    public ResourceResponse(ResourceRequest request) {
        this(request, false);
    }

    /**
     * This constructor is also for an unsuccessful request.
     * 

This constructor can explicitly indicate that the request was rejected. For example, * if the {@link ResolverFeature#ACCESS_EXTERNAL_ENTITY} or {@link ResolverFeature#ACCESS_EXTERNAL_DOCUMENT} * settings did not allow requests for a particular URI scheme.

* @param request The request. * @param rejected Was this request rejected? */ public ResourceResponse(ResourceRequest request, boolean rejected) { this.request = request; this.rejected = rejected; this.uri = null; this.resolvedURI = null; this.resolved = false; } /** * The constructor for a successful request (usually). *

The {@code request} was satisfied with the {@code uri}. If the {@code uri} is * null, the response will indicate that the request was unsuccessful.

* @param request The request. * @param uri The successfully resolved URI, or null. */ public ResourceResponse(ResourceRequest request, URI uri) { // If the URI is null, make the result the same as a constructor that didn't pass a URI. this.request = request; this.rejected = false; this.uri = uri; this.resolvedURI = uri; this.resolved = false; if (uri != null) { if (("jar".equals(uri.getScheme()) || "classpath".equals(uri.getScheme())) && request.config.getFeature(ResolverFeature.MASK_JAR_URIS)) { try { this.uri = request.getAbsoluteURI(); } catch (URISyntaxException ex) { // nop } } this.resolved = true; } } /** * Set the resource connection. *

If an attempt is made to open a connection to the resource, that connection can be saved in the * response.

* @param conn The resource connection. */ /* package */ void setConnection(ResourceConnection conn) { connection = conn; } /** * Get the resource connection. *

If this response was accessed with a resource connection, it will be saved in the response.

* @return The connection. */ public ResourceConnection getConnection() { return connection; } /* package */ void setContentType(String contentType) { this.contentType = contentType; } /** * Get the content type. * @return The content type, or null if it's unknown. */ public String getContentType() { return contentType; } /* package */ void setInputStream(InputStream stream) { this.stream = stream; } /** * Get the input stream. *

If this resource is opened for reading by the resolution attempt, this is its readable stream.

*

Attempts to resolve a resource will provide a stream if one is available. Requests that simply * inspect the catalog (with the lookup* methods) will not.

* @return The stream, or null if the resource wasn't opened. */ public InputStream getInputStream() { return stream; } /* package */ void setRejected(boolean rejected) { this.rejected = rejected; } /** * Was this request rejected? * @return True if the request was rejected, false otherwise. */ public boolean isRejected() { return rejected; } /* package */ void setResolved(boolean resolved) { this.resolved = resolved; } /** * Was this request successfully resolved? * @return True if the request was resolved, false otherwise. */ public boolean isResolved() { return resolved; } /* package */ void setUri(URI uri) { this.uri = uri; } /** * Get the URI. *

This is the initially resolved URI. The distinction between initial and final resolution arises * when redirects come into play. Suppose you request {@code http://example.com/some.dtd} and that resolves * in the catalog to {@code http://example.com/version2/some.dtd}. The URI returned by {@code getURI()} will * be {@code http://example.com/version2/some.dtd}. However, if an attempt to obtain that resource encounters * redirection at, for example, the HTTP layer, then the actual URI returned may differ, see {@link #getResolvedURI()}.

* @return The URI. */ public URI getURI() { return uri; } /* package */ void setResolvedURI(URI uri) { resolvedURI = uri; } /** * Get the resolved URI. *

This is the finally resolved URI. The distinction between initial and final resolution arises * when redirects come into play. Suppose you request {@code http://example.com/some.dtd} and that resolves * in the catalog to {@code http://example.com/version2/some.dtd}. If an attempt to obtain that resource encounters * redirection at, for example, the HTTP layer, to {@code http://cdn.example.com/version2/some.dtd}, the * URI returned by {@link #getResolvedURI()} will be {@code http://cdn.example.com/version2/some.dtd}. * See {@link #getURI()}.

*

If {@link ResolverFeature#MASK_JAR_URIS} is true and the resolved URI is a jar: URI, the * {@link #getURI()} is returned instead.

* @return The resolved URI. */ public URI getResolvedURI() { if (resolvedURI != null) { if ((resolvedURI.getScheme().equals("jar") || resolvedURI.getScheme().equals("classpath")) && request.config.getFeature(ResolverFeature.MASK_JAR_URIS)) { return uri; } } return resolvedURI; } /** * Get the resolved URI, irrespective of masking. *

Where {@link #getResolvedURI()} will not return a {@code jar:} URI if the * {@link ResolverFeature#MASK_JAR_URIS} is true, this method always returns the actual, unmasked URI. *

* @return The resolved URI, unmasked. */ public URI getUnmaskedURI() { return resolvedURI; } /* package */ void setEncoding(String encoding) { this.encoding = encoding; } /** * Get the encoding. * @return The resource encoding, or null if the encoding is unknown. */ public String getEncoding() { return encoding; } /* package */ void setHeaders(Map> headers) { this.headers.clear(); this.headers.putAll(headers); } /** * Get the headers. *

This method never returns null, it returns an empty map if no headers are available.

* @return The headers, if headers are available. */ public Map> getHeaders() { return headers; } /** * Get the value of a specific header. *

This is a convenience method. Headers can be repeated, and consequently have multiple values. * This method only returns the first value; that is, the value associated with the first header named {@code name} * encountered during resolution.

* @param name The header name. * @return The (first) value of that header, or null if no such header exists * @throws NullPointerException if name is null. */ public String getHeader(String name) { // URLConnection stores the "HTTP/1.0 200 OK" status return line in the headers // with a null key value. ¯\_(ツ)_/¯ if (name != null) { name = name.toLowerCase(); } for (String key : headers.keySet()) { if ((name == null && key == null) || (name != null && name.equals(key.toLowerCase()))) { List value = headers.get(key); if (value == null || value.isEmpty()) { return null; } return value.get(0); } } return null; } /* package */ void setStatusCode(int code) { statusCode = code; } /** * Get the status code of the request. *

Successful requests return 200 irrespective of the URI scheme.

* @return the status code. */ public int getStatusCode() { return statusCode; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy