/**
* Copyright 2005-2014 Restlet
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can
* select the license that you prefer but you may not use this file except in
* compliance with one of these Licenses.
*
* You can obtain a copy of the Apache 2.0 license at
* http://www.opensource.org/licenses/apache-2.0
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://restlet.com/products/restlet-framework
*
* Restlet is a registered trademark of Restlet S.A.S.
*/
package org.restlet.data;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.restlet.Context;
import org.restlet.engine.Engine;
import org.restlet.engine.io.IoUtils;
/**
* Client specific data related to a call. When extracted from a request, most
* of these data are directly taken from the underlying headers. There are some
* exceptions: agentAttributes and mainAgentProduct which are taken from the
* agent name (for example the "user-agent" header for HTTP requests).<br>
* <br>
* As described by the HTTP specification, the "user-agent" can be seen as a
* ordered list of products name (ie a name and a version) and/or comments.<br>
* <br>
* Each HTTP client (mainly browsers and web crawlers) defines its own
* "user-agent" header which can be seen as the "signature" of the client.
* Unfortunately, there is no rule to identify clearly a kind a client and its
* version (let's say Firefox 2.x, Internet Explorer IE 7.0, Opera, etc)
* according to its signature. Each signature follow its own rules which may
* vary according to the version of the client.<br>
* <br>
* In order to help retrieving interesting data such as product name (Firefox,
* IE, etc), version, operating system, Restlet users has the ability to define
* their own way to extract data from the "user-agent" header. It is based on a
* list of templates declared in a file called "agent.properties" and located in
* the classpath in the sub directory "org/restlet/data". Each template
* describes a typical user-agent string and allows to use predefined variables
* that help to retrieve the content of the agent name, version, operating
* system.<br>
* <br>
* The "user-agent" string is confronted to the each template from the beginning
* of the property file to the end. The loop stops at the first matched
* template.<br>
* <br>
* Here is a sample of such template:<br>
*
* <pre>
* #Firefox for Windows
* Mozilla/{mozillaVersion} (Windows; U; {agentOs}; {osData}; rv:{releaseVersion}) Gecko/{geckoReleaseDate} {agentName}/{agentVersion}
* </pre>
*
* This template matches the "user-agent" string of the Firefox client for
* windows:
*
* <pre>
* Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20060918 Firefox/2.0
* </pre>
*
* At this time, six predefined variables are used:<br>
* <table>
* <tr>
* <th>Name</th>
* <th>Description</th>
* </tr>
* <tr>
* <td>agentName</td>
* <td>Name of the user agent (i.e.: Firefox)</td>
* </tr>
* <tr>
* <td>agentVersion</td>
* <td>Version of the user agent</td>
* </tr>
* <tr>
* <td>agentOs</td>
* <td>Operating system of the user agent</td>
* </tr>
* <tr>
* <td>agentComment</td>
* <td>Comment string, that is to say a sequence of characters enclosed "(", or
* ")"</td>
* </tr>
* <tr>
* <td>commentAttribute</td>
* <td>A sequence of characters enclosed by ";", "(", or ")"</td>
* </tr>
* <tr>
* <td>facultativeData</td>
* <td>A sequence of characters that can be empty</td>
* </tr>
* </table>
* <br>
* <br>
* These variables are used to generate a {@link Product} instance with the main
* data (name, version, comment). This instance is accessible via the
* {@link ClientInfo#getMainAgentProduct()} method. All other variables used in
* the template aims at catching a sequence of characters and are accessible via
* the {@link ClientInfo#getAgentAttributes()} method.
*
* @author Jerome Louvel
*/
public final class ClientInfo {
// [ifndef gwt] member
/**
* List of user-agent templates defined in "agent.properties" file.<br>
*
* @see The {@link ClientInfo#getAgentAttributes()} method.
*/
private static volatile List<String> userAgentTemplates = null;
// [ifndef gwt] method
/**
* Returns the preferred metadata taking into account both metadata
* supported by the server and client preferences.
*
* @param supported
* The metadata supported by the server.
* @param preferences
* The client preferences.
* @return The preferred metadata.
*/
public static <T extends Metadata> T getPreferredMetadata(
List<T> supported, List<Preference<T>> preferences) {
T result = null;
float maxQuality = 0;
if (supported != null) {
for (Preference<T> pref : preferences) {
for (T metadata : supported) {
if (pref.getMetadata().isCompatible(metadata)
&& (pref.getQuality() > maxQuality)) {
result = metadata;
maxQuality = pref.getQuality();
}
}
}
}
return result;
}
// [ifndef gwt] method
/**
* Returns the list of user-agent templates defined in "agent.properties"
* file.
*
* @return The list of user-agent templates defined in "agent.properties"
* file.
* @see The {@link ClientInfo#getAgentAttributes()} method.
*/
private static List<String> getUserAgentTemplates() {
// Lazy initialization with double-check.
List<String> u = ClientInfo.userAgentTemplates;
if (u == null) {
synchronized (ClientInfo.class) {
u = ClientInfo.userAgentTemplates;
if (u == null) {
// Load from the "agent.properties" file
java.net.URL userAgentPropertiesUrl = Engine
.getResource("org/restlet/data/agent.properties");
if (userAgentPropertiesUrl != null) {
BufferedReader reader;
try {
reader = new BufferedReader(new InputStreamReader(
userAgentPropertiesUrl.openStream(),
CharacterSet.UTF_8.getName()),
IoUtils.BUFFER_SIZE);
String line = reader.readLine();
for (; line != null; line = reader.readLine()) {
if ((line.trim().length() > 0)
&& !line.trim().startsWith("#")) {
if (u == null) {
u = new CopyOnWriteArrayList<String>();
}
u.add(line);
}
}
reader.close();
} catch (IOException e) {
if (Context.getCurrent() != null) {
Context.getCurrent()
.getLogger()
.warning(
"Cannot read '"
+ userAgentPropertiesUrl
.toString()
+ "' due to: "
+ e.getMessage());
}
}
}
ClientInfo.userAgentTemplates = u;
}
}
}
return u;
}
/** The character set preferences. */
private volatile List<Preference<CharacterSet>> acceptedCharacterSets;
/** The encoding preferences. */
private volatile List<Preference<Encoding>> acceptedEncodings;
/** The language preferences. */
private volatile List<Preference<Language>> acceptedLanguages;
/** The media preferences. */
private volatile List<Preference<MediaType>> acceptedMediaTypes;
/** The patch preferences. */
private volatile List<Preference<MediaType>> acceptedPatches;
/** The immediate IP addresses. */
private volatile String address;
/** The agent name. */
private volatile String agent;
// [ifndef gwt] member
/** The attributes data taken from the agent name. */
private volatile Map<String, String> agentAttributes;
// [ifndef gwt] member
/** The main product data taken from the agent name. */
private volatile Product agentMainProduct;
// [ifndef gwt] member
/** The list of product tokens taken from the agent name. */
private volatile List<Product> agentProducts;
// [ifndef gwt] member
/**
* Indicates if the subject has been authenticated. The application is
* responsible for updating this property, relying on
* {@link org.restlet.security.Authenticator} or manually.
*/
private volatile boolean authenticated;
// [ifndef gwt] member
/** List of client certificates. */
private volatile List<java.security.cert.Certificate> certificates;
// [ifndef gwt] member
/** The SSL Cipher Suite, if available and accessible. */
private volatile String cipherSuite;
// [ifndef gwt] member
/** List of expectations. */
private volatile List<org.restlet.data.Expectation> expectations;
/** The forwarded IP addresses. */
private volatile List<String> forwardedAddresses;
/** The email address of the human user controlling the user agent. */
private volatile String from;
/** The port number. */
private volatile int port;
// [ifndef gwt] member
/** List of additional client principals. */
private volatile List<java.security.Principal> principals;
// [ifndef gwt] member
/** List of user roles. */
private volatile List<org.restlet.security.Role> roles;
// [ifndef gwt] member
/** Authenticated user. */
private volatile org.restlet.security.User user;
/**
* Constructor.
*/
public ClientInfo() {
this.address = null;
this.agent = null;
this.port = -1;
this.acceptedCharacterSets = null;
this.acceptedEncodings = null;
this.acceptedLanguages = null;
this.acceptedMediaTypes = null;
this.acceptedPatches = null;
this.forwardedAddresses = null;
this.from = null;
// [ifndef gwt]
this.agentProducts = null;
this.principals = null;
this.user = null;
this.roles = null;
this.expectations = null;
// [enddef]
}
// [ifndef gwt] method
/**
* Constructor from a list of variants. Note that only media types are taken
* into account.
*
* @param variants
* The variants corresponding to the accepted media types.
*/
public ClientInfo(
List<? extends org.restlet.representation.Variant> variants) {
if (variants != null) {
for (org.restlet.representation.Variant variant : variants) {
getAcceptedMediaTypes().add(
new Preference<MediaType>(variant.getMediaType()));
}
}
}
/**
* Constructor from a media type.
*
* @param mediaType
* The preferred media type.
*/
public ClientInfo(MediaType mediaType) {
getAcceptedMediaTypes().add(new Preference<MediaType>(mediaType));
}
/**
* Updates the client preferences to accept the given metadata (media types,
* character sets, etc.) with a 1.0 quality in addition to existing ones.
*
* @param metadata
* The metadata to accept.
*/
public void accept(Metadata... metadata) {
if (metadata != null) {
for (Metadata md : metadata) {
accept(md, 1.0F);
}
}
}
/**
* Updates the client preferences to accept the given metadata (media types,
* character sets, etc.) with a given quality in addition to existing ones.
*
* @param metadata
* The metadata to accept.
* @param quality
* The quality to set.
*/
public void accept(Metadata metadata, float quality) {
if (metadata instanceof MediaType) {
getAcceptedMediaTypes().add(
new Preference<MediaType>((MediaType) metadata, quality));
} else if (metadata instanceof Language) {
getAcceptedLanguages().add(
new Preference<Language>((Language) metadata, quality));
} else if (metadata instanceof Encoding) {
getAcceptedEncodings().add(
new Preference<Encoding>((Encoding) metadata, quality));
} else {
getAcceptedCharacterSets().add(
new Preference<CharacterSet>((CharacterSet) metadata,
quality));
}
}
/**
* Returns the modifiable list of character set preferences. Creates a new
* instance if no one has been set.<br>
* <br>
* Note that when used with HTTP connectors, this property maps to the
* "Accept-Charset" header.
*
* @return The character set preferences.
*/
public List<Preference<CharacterSet>> getAcceptedCharacterSets() {
// Lazy initialization with double-check.
List<Preference<CharacterSet>> a = this.acceptedCharacterSets;
if (a == null) {
synchronized (this) {
a = this.acceptedCharacterSets;
if (a == null) {
this.acceptedCharacterSets = a = new CopyOnWriteArrayList<Preference<CharacterSet>>();
}
}
}
return a;
}
/**
* Returns the modifiable list of encoding preferences. Creates a new
* instance if no one has been set.<br>
* <br>
* Note that when used with HTTP connectors, this property maps to the
* "Accept-Encoding" header.
*
* @return The encoding preferences.
*/
public List<Preference<Encoding>> getAcceptedEncodings() {
// Lazy initialization with double-check.
List<Preference<Encoding>> a = this.acceptedEncodings;
if (a == null) {
synchronized (this) {
a = this.acceptedEncodings;
if (a == null) {
this.acceptedEncodings = a = new CopyOnWriteArrayList<Preference<Encoding>>();
}
}
}
return a;
}
/**
* Returns the modifiable list of language preferences. Creates a new
* instance if no one has been set.<br>
* <br>
* Note that when used with HTTP connectors, this property maps to the
* "Accept-Language" header.
*
* @return The language preferences.
*/
public List<Preference<Language>> getAcceptedLanguages() {
// Lazy initialization with double-check.
List<Preference<Language>> a = this.acceptedLanguages;
if (a == null) {
synchronized (this) {
a = this.acceptedLanguages;
if (a == null) {
this.acceptedLanguages = a = new CopyOnWriteArrayList<Preference<Language>>();
}
}
}
return a;
}
/**
* Returns the modifiable list of media type preferences. Creates a new
* instance if no one has been set.<br>
* <br>
* Note that when used with HTTP connectors, this property maps to the
* "Accept" header.
*
* @return The media type preferences.
*/
public List<Preference<MediaType>> getAcceptedMediaTypes() {
// Lazy initialization with double-check.
List<Preference<MediaType>> a = this.acceptedMediaTypes;
if (a == null) {
synchronized (this) {
a = this.acceptedMediaTypes;
if (a == null) {
this.acceptedMediaTypes = a = new CopyOnWriteArrayList<Preference<MediaType>>();
}
}
}
return a;
}
/**
* Returns the modifiable list of patch preferences. Creates a new instance
* if no one has been set.<br>
* <br>
* Note that when used with HTTP connectors, this property maps to the
* "Accept-Patch" header.
*
* @return The patch preferences.
*/
public List<Preference<MediaType>> getAcceptedPatches() {
// Lazy initialization with double-check.
List<Preference<MediaType>> a = this.acceptedPatches;
if (a == null) {
synchronized (this) {
a = this.acceptedPatches;
if (a == null) {
this.acceptedPatches = a = new CopyOnWriteArrayList<Preference<MediaType>>();
}
}
}
return a;
}
/**
* Returns the immediate client's IP address. If the real client is
* separated from the server by a proxy server, this will return the IP
* address of the proxy.
*
* @return The immediate client's IP address.
* @see #getUpstreamAddress()
* @see #getForwardedAddresses()
*/
public String getAddress() {
return this.address;
}
/**
* Returns the agent name (ex: "Restlet-Framework/2.0"). Note that when used
* with HTTP connectors, this property maps to the "User-Agent" header.
*
* @return The agent name.
*/
public String getAgent() {
return this.agent;
}
// [ifndef gwt] method
/**
* Returns a list of attributes taken from the name of the user agent.
*
* @return A list of attributes taken from the name of the user agent.
* @see #getAgent()
*/
public Map<String, String> getAgentAttributes() {
if (this.agentAttributes == null) {
this.agentAttributes = new ConcurrentHashMap<String, String>();
Map<String, Object> map = new ConcurrentHashMap<String, Object>();
// Loop on a list of user-agent templates until a template match
// the current user-agent string. The list of templates is
// located in a file named "agent.properties" available on
// the classpath.
// Some defined variables are used in order to catch the name,
// version and optional comment. Respectively, these
// variables are called "agentName", "agentVersion" and
// "agentComment".
org.restlet.routing.Template template = null;
// Predefined variables.
org.restlet.routing.Variable agentName = new org.restlet.routing.Variable(
org.restlet.routing.Variable.TYPE_TOKEN);
org.restlet.routing.Variable agentVersion = new org.restlet.routing.Variable(
org.restlet.routing.Variable.TYPE_TOKEN);
org.restlet.routing.Variable agentComment = new org.restlet.routing.Variable(
org.restlet.routing.Variable.TYPE_COMMENT);
org.restlet.routing.Variable agentCommentAttribute = new org.restlet.routing.Variable(
org.restlet.routing.Variable.TYPE_COMMENT_ATTRIBUTE);
org.restlet.routing.Variable facultativeData = new org.restlet.routing.Variable(
org.restlet.routing.Variable.TYPE_ALL, null, false, false);
if (ClientInfo.getUserAgentTemplates() != null) {
for (String string : ClientInfo.getUserAgentTemplates()) {
template = new org.restlet.routing.Template(string,
org.restlet.routing.Template.MODE_EQUALS);
// Update the predefined variables.
template.getVariables().put("agentName", agentName);
template.getVariables().put("agentVersion", agentVersion);
template.getVariables().put("agentComment", agentComment);
template.getVariables().put("agentOs",
agentCommentAttribute);
template.getVariables().put("commentAttribute",
agentCommentAttribute);
template.getVariables().put("facultativeData",
facultativeData);
// Parse the template
if (template.parse(getAgent(), map) > -1) {
for (String key : map.keySet()) {
this.agentAttributes
.put(key, (String) map.get(key));
}
break;
}
}
}
}
return this.agentAttributes;
}
// [ifndef gwt] method
/**
* Returns the name of the user agent.
*
* @return The name of the user agent.
* @see #getAgent()
*/
public String getAgentName() {
final Product product = getMainAgentProduct();
if (product != null) {
return product.getName();
}
return null;
}
// [ifndef gwt] method
/**
* Returns the list of product tokens from the user agent name.
*
* @return The list of product tokens from the user agent name.
* @see #getAgent()
*/
public List<Product> getAgentProducts() {
if (this.agentProducts == null) {
this.agentProducts = org.restlet.engine.header.ProductReader
.read(getAgent());
}
return this.agentProducts;
}
// [ifndef gwt] method
/**
* Returns the version of the user agent.
*
* @return The version of the user agent.
* @see #getAgent()
*/
public String getAgentVersion() {
final Product product = getMainAgentProduct();
if (product != null) {
return product.getVersion();
}
return null;
}
// [ifndef gwt] method
/**
* Returns the client certificates. Those certificates are available when a
* request is received via an HTTPS connection, corresponding to the SSL/TLS
* certificates.
*
* @return The client certificates.
* @see javax.net.ssl.SSLSession#getPeerCertificates()
*/
public List<java.security.cert.Certificate> getCertificates() {
// Lazy initialization with double-check.
List<java.security.cert.Certificate> a = this.certificates;
if (a == null) {
synchronized (this) {
a = this.certificates;
if (a == null) {
this.certificates = a = new CopyOnWriteArrayList<java.security.cert.Certificate>();
}
}
}
return a;
}
// [ifndef gwt] method
/**
* Returns the SSL Cipher Suite, if available and accessible.
*
* @return The SSL Cipher Suite, if available and accessible.
* @see javax.net.ssl.SSLSession#getCipherSuite()
*/
public String getCipherSuite() {
return this.cipherSuite;
}
// [ifndef gwt] method
/**
* Returns the client expectations.
*
* @return The client expectations.
*/
public List<org.restlet.data.Expectation> getExpectations() {
// Lazy initialization with double-check.
List<org.restlet.data.Expectation> a = this.expectations;
if (a == null) {
synchronized (this) {
a = this.expectations;
if (a == null) {
this.expectations = a = new CopyOnWriteArrayList<org.restlet.data.Expectation>();
}
}
}
return a;
}
/**
* Returns the list of forwarded IP addresses. This is useful when the user
* agent is separated from the origin server by a chain of intermediary
* components. Creates a new instance if no one has been set. <br>
* <br>
* The first address is the one of the immediate client component and the
* last address should correspond to the origin client (frequently a user
* agent).<br>
* <br>
* This information is only safe for intermediary components within your
* local network. Other addresses could easily be changed by setting a fake
* header and should not be trusted for serious security checks.<br>
* <br>
* Note that your HTTP server connectors need to have a special
* "useForwardedForHeader" parameter explicitly set to "true" in order to
* activate this feature, due to potential security issues.
*
* @return The list of forwarded IP addresses.
* @see #getUpstreamAddress()
* @see <a href="http://en.wikipedia.org/wiki/X-Forwarded-For">Wikipedia
* page for the "X-Forwarded-For" HTTP header</a>
*/
public List<String> getForwardedAddresses() {
// Lazy initialization with double-check.
List<String> a = this.forwardedAddresses;
if (a == null) {
synchronized (this) {
a = this.forwardedAddresses;
if (a == null) {
this.forwardedAddresses = a = new CopyOnWriteArrayList<String>();
}
}
}
return a;
}
/**
* Returns the email address of the human user controlling the user agent.
* Default value is null.
*
* @return The email address of the human user controlling the user agent.
*/
public String getFrom() {
return from;
}
// [ifndef gwt] method
/**
* Returns a Product object based on the name of the user agent.
*
* @return A Product object based on name of the user agent.
*/
public Product getMainAgentProduct() {
if (this.agentMainProduct == null) {
if (getAgentAttributes() != null) {
this.agentMainProduct = new Product(getAgentAttributes().get(
"agentName"), getAgentAttributes().get("agentVersion"),
getAgentAttributes().get("agentComment"));
}
}
return this.agentMainProduct;
}
/**
* Returns the port number which sent the call. If no port is specified, -1
* is returned.
*
* @return The port number which sent the call.
*/
public int getPort() {
return this.port;
}
// [ifndef gwt] method
/**
* Returns the preferred character set among a list of supported ones, based
* on the client preferences.
*
* @param supported
* The supported character sets.
* @return The preferred character set.
*/
public CharacterSet getPreferredCharacterSet(List<CharacterSet> supported) {
return getPreferredMetadata(supported, getAcceptedCharacterSets());
}
// [ifndef gwt] method
/**
* Returns the preferred encoding among a list of supported ones, based on
* the client preferences.
*
* @param supported
* The supported encodings.
* @return The preferred encoding.
*/
public Encoding getPreferredEncoding(List<Encoding> supported) {
return getPreferredMetadata(supported, getAcceptedEncodings());
}
// [ifndef gwt] method
/**
* Returns the preferred language among a list of supported ones, based on
* the client preferences.
*
* @param supported
* The supported languages.
* @return The preferred language.
*/
public Language getPreferredLanguage(List<Language> supported) {
return getPreferredMetadata(supported, getAcceptedLanguages());
}
// [ifndef gwt] method
/**
* Returns the preferred media type among a list of supported ones, based on
* the client preferences.
*
* @param supported
* The supported media types.
* @return The preferred media type.
*/
public MediaType getPreferredMediaType(List<MediaType> supported) {
return getPreferredMetadata(supported, getAcceptedMediaTypes());
}
// [ifndef gwt] method
/**
* Returns the preferred patch among a list of supported ones, based on the
* client preferences.
*
* @param supported
* The supported patches.
* @return The preferred patch.
*/
public MediaType getPreferredPatch(List<MediaType> supported) {
return getPreferredMetadata(supported, getAcceptedPatches());
}
// [ifndef gwt] method
/**
* Returns the additional client principals. Note that {@link #getUser()}
* and {@link #getRoles()} methods already return user and role principals.
*
* @return The additional client principals.
*/
public List<java.security.Principal> getPrincipals() {
// Lazy initialization with double-check.
List<java.security.Principal> a = this.principals;
if (a == null) {
synchronized (this) {
a = this.principals;
if (a == null) {
this.principals = a = new CopyOnWriteArrayList<java.security.Principal>();
}
}
}
return a;
}
// [ifndef gwt] method
/**
* Returns the authenticated user roles.
*
* @return The authenticated user roles.
*/
public List<org.restlet.security.Role> getRoles() {
// Lazy initialization with double-check.
List<org.restlet.security.Role> a = this.roles;
if (a == null) {
synchronized (this) {
a = this.roles;
if (a == null) {
this.roles = a = new CopyOnWriteArrayList<org.restlet.security.Role>();
}
}
}
return a;
}
// [ifndef gwt] method
/**
* Returns the IP address of the upstream client component. In general this
* will correspond the the user agent IP address. This is useful if there
* are intermediary components like proxies and load balancers.
*
* If the supporting {@link #getForwardedAddresses()} method returns a non
* empty list, the IP address will be the first element. Otherwise, the
* value of {@link #getAddress()} will be returned.<br>
* <br>
* Note that your HTTP server connectors need to have a special
* "useForwardedForHeader" parameter explicitly set to "true" in order to
* activate this feature, due to potential security issues.
*
* @return The most upstream IP address.
* @see #getAddress()
* @see #getForwardedAddresses()
*/
public String getUpstreamAddress() {
if (this.forwardedAddresses == null
|| this.forwardedAddresses.isEmpty()) {
return getAddress();
}
return this.forwardedAddresses.get(0);
}
// [ifndef gwt] method
/**
* Returns the authenticated user.
*
* @return The authenticated user.
*/
public org.restlet.security.User getUser() {
return user;
}
// [ifndef gwt] method
/**
* Indicates if the identifier or principal has been authenticated. The
* application is responsible for updating this property, relying on a
* {@link org.restlet.security.Authenticator} or manually.
*
* @return True if the identifier or principal has been authenticated.
*/
public boolean isAuthenticated() {
return this.authenticated;
}
/**
* Sets the character set preferences. Note that when used with HTTP
* connectors, this property maps to the "Accept-Charset" header.
*
* @param acceptedCharacterSets
* The character set preferences.
*/
public void setAcceptedCharacterSets(
List<Preference<CharacterSet>> acceptedCharacterSets) {
synchronized (this) {
List<Preference<CharacterSet>> ac = getAcceptedCharacterSets();
ac.clear();
ac.addAll(acceptedCharacterSets);
}
}
/**
* Sets the encoding preferences. Note that when used with HTTP connectors,
* this property maps to the "Accept-Encoding" header.
*
* @param acceptedEncodings
* The encoding preferences.
*/
public void setAcceptedEncodings(
List<Preference<Encoding>> acceptedEncodings) {
synchronized (this) {
List<Preference<Encoding>> ac = getAcceptedEncodings();
ac.clear();
ac.addAll(acceptedEncodings);
}
}
/**
* Sets the language preferences. Note that when used with HTTP connectors,
* this property maps to the "Accept-Language" header.
*
* @param acceptedLanguages
* The language preferences.
*/
public void setAcceptedLanguages(
List<Preference<Language>> acceptedLanguages) {
synchronized (this) {
List<Preference<Language>> ac = getAcceptedLanguages();
ac.clear();
ac.addAll(acceptedLanguages);
}
}
/**
* Sets the media type preferences. Note that when used with HTTP
* connectors, this property maps to the "Accept" header.
*
* @param acceptedMediaTypes
* The media type preferences.
*/
public void setAcceptedMediaTypes(
List<Preference<MediaType>> acceptedMediaTypes) {
synchronized (this) {
List<Preference<MediaType>> ac = getAcceptedMediaTypes();
ac.clear();
ac.addAll(acceptedMediaTypes);
}
}
/**
* Sets the patch preferences. Note that when used with HTTP connectors,
* this property maps to the "Accept-Patch" header.
*
* @param acceptedPatches
* The media type preferences.
*/
public void setAcceptedPatches(List<Preference<MediaType>> acceptedPatches) {
synchronized (this) {
List<Preference<MediaType>> ac = getAcceptedPatches();
ac.clear();
ac.addAll(acceptedPatches);
}
}
/**
* Sets the client's IP address.
*
* @param address
* The client's IP address.
*/
public void setAddress(String address) {
this.address = address;
}
/**
* Sets the agent name (ex: "Restlet-Framework/2.0"). Note that when used
* with HTTP connectors, this property maps to the "User-Agent" header.
*
* @param agent
* The agent name.
*/
public void setAgent(String agent) {
this.agent = agent;
}
// [ifndef gwt] method
/**
* Sets a list of attributes taken from the name of the user agent.
*
* @param agentAttributes
* A list of attributes taken from the name of the user agent.
*/
public void setAgentAttributes(Map<String, String> agentAttributes) {
synchronized (this) {
Map<String, String> aa = getAgentAttributes();
aa.clear();
aa.putAll(agentAttributes);
}
}
// [ifndef gwt] method
/**
* Sets the list of product tokens from the user agent name.
*
* @param agentProducts
* The list of product tokens from the user agent name.
*/
public void setAgentProducts(List<Product> agentProducts) {
synchronized (this) {
List<Product> ap = getAgentProducts();
ap.clear();
ap.addAll(agentProducts);
}
}
// [ifndef gwt] method
/**
* Indicates if the identifier or principal has been authenticated. The
* application is responsible for updating this property, relying on a
* {@link org.restlet.security.Authenticator} or manually.
*
* @param authenticated
* True if the identifier or principal has been authenticated.
*/
public void setAuthenticated(boolean authenticated) {
this.authenticated = authenticated;
}
// [ifndef gwt] method
/**
* Sets the new client certificates.
*
* @param certificates
* The client certificates.
* @see #getCertificates()
*/
public void setCertificates(
List<java.security.cert.Certificate> certificates) {
synchronized (this) {
List<java.security.cert.Certificate> fa = getCertificates();
fa.clear();
fa.addAll(certificates);
}
}
// [ifndef gwt] method
/**
* Sets the SSL Cipher Suite, if available and accessible.
*
* @param cipherSuite
* The SSL Cipher Suite, if available and accessible.
*/
public void setCipherSuite(String cipherSuite) {
this.cipherSuite = cipherSuite;
}
// [ifndef gwt] method
/**
* Sets the client expectations.
*
* @param expectations
* The client expectations.
*/
public void setExpectations(List<org.restlet.data.Expectation> expectations) {
synchronized (this) {
List<org.restlet.data.Expectation> e = getExpectations();
e.clear();
e.addAll(expectations);
}
}
/**
* Sets the list of forwarded IP addresses.
*
* @param forwardedAddresses
* The list of forwarded IP addresses.
* @see #getForwardedAddresses()
*/
public void setForwardedAddresses(List<String> forwardedAddresses) {
synchronized (this) {
List<String> fa = getForwardedAddresses();
fa.clear();
fa.addAll(forwardedAddresses);
}
}
/**
* Sets the email address of the human user controlling the user agent.
*
* @param from
* The email address of the human user controlling the user
* agent.
*/
public void setFrom(String from) {
this.from = from;
}
/**
* Sets the port number which sent the call.
*
* @param port
* The port number which sent the call.
*/
public void setPort(int port) {
this.port = port;
}
// [ifndef gwt] method
/**
* Sets the additional client principals.
*
* @param principals
* The additional client principals.
* @see #getPrincipals()
*/
public void setPrincipals(List<java.security.Principal> principals) {
synchronized (this) {
List<java.security.Principal> fa = getPrincipals();
fa.clear();
fa.addAll(principals);
}
}
// [ifndef gwt] method
/**
* Sets the authenticated user roles.
*
* @param roles
* The authenticated user roles.
*/
public void setRoles(List<org.restlet.security.Role> roles) {
synchronized (this) {
List<org.restlet.security.Role> r = getRoles();
r.clear();
r.addAll(roles);
}
}
// [ifndef gwt] method
/**
* Sets the authenticated user.
*
* @param user
* The authenticated user.
*/
public void setUser(org.restlet.security.User user) {
this.user = user;
}
}