Skip to content
ConfigurableServiceConnection.java 71.6 KiB
Newer Older
				fetchSize[1] = Integer.parseInt(propVal);
				if (fetchSize[1] < 0)
					fetchSize[1] = 0;
				throw new TAPException("Integer expected for the property " + KEY_SYNC_FETCH_SIZE + ": \"" + propVal + "\"!");
			}
		}
	}

	 * Initialise the maximum upload limit.
	 *
	 * <p><em><b>Note:</b>
	 * 	The default upload limit is still fetched in this function, but only
	 * 	in case no maximum limit is provided, just for backward compatibility
	 * 	with versions 2.2 or less.
	 * </em></p>
	 * @param tapConfig	The content of the TAP configuration file.
	 * @throws TAPException	If the corresponding TAP configuration properties
	 *                     	are wrong.
	private void initUploadLimits(final Properties tapConfig) throws TAPException {
		// Fetch the given default and maximum limits:
		String defaultDBLimit = getProperty(tapConfig, KEY_DEFAULT_UPLOAD_LIMIT);
		String maxDBLimit = getProperty(tapConfig, KEY_MAX_UPLOAD_LIMIT);
		Object[] limit = null;

		/* Parse the given maximum limit. */
		if (maxDBLimit != null)
			limit = parseLimit(maxDBLimit, KEY_MAX_UPLOAD_LIMIT, true, true);
		/* If none is provided, try to use the deprecated default limit
		 * (just for backward compatibility). */
			logger.warning("The property `" + KEY_DEFAULT_UPLOAD_LIMIT + "` has been deprecated! This value is currently used anyway, but not forever. You should now use only `" + KEY_MAX_UPLOAD_LIMIT + "` instead. (comment or delete the property `" + KEY_DEFAULT_UPLOAD_LIMIT + "` from your configuration file to remove this WARNING)");
			limit = parseLimit(defaultDBLimit, KEY_DEFAULT_UPLOAD_LIMIT, true, true);

		/* If still no value is provided, set the default value. */
			limit = parseLimit(DEFAULT_MAX_UPLOAD_LIMIT, KEY_DEFAULT_UPLOAD_LIMIT, true, true);

		// Finally, set the new limits:
		uploadLimitTypes[0] = uploadLimitTypes[1] = (LimitUnit)limit[1];
		setDefaultUploadLimit((Long)limit[0]);
		setMaxUploadLimit((Long)limit[0]);

	 * Initialise the maximum size (in bytes) of a whole HTTP Multipart request.
	 * 	This maximum size includes the HTTP header (normal parameters included)
	 * 	and the sum of the size of all uploaded files.
	 * </em></p>
	 * <p><em><b>Note 2:</b>
	 * 	The former property name
	 * 	({@link TAPConfiguration#KEY_UPLOAD_MAX_FILE_SIZE KEY_UPLOAD_MAX_FILE_SIZE})
	 * 	for this limit is still supported yet for some time....but ONLY IF the
	 * 	new one ({@link TAPConfiguration#KEY_UPLOAD_MAX_REQUEST_SIZE KEY_UPLOAD_MAX_REQUEST_SIZE})
	 * 	is not defined.
	 * </em></p>
	 *
	 * @param tapConfig	The content of the TAP configuration file.
	 * @throws TAPException	If the corresponding TAP configuration property is
	 *                     	wrong.
	private void initMaxUploadSize(final Properties tapConfig) throws TAPException {
		String propName = KEY_UPLOAD_MAX_REQUEST_SIZE;
		String propValue = getProperty(tapConfig, propName);

		// temporary backward compatibility with the deprecated property name:
			propName = KEY_UPLOAD_MAX_FILE_SIZE;
			propValue = getProperty(tapConfig, propName);
			if (propValue != null)
				logger.warning("The property `" + KEY_UPLOAD_MAX_FILE_SIZE + "` has been replaced by `" + KEY_UPLOAD_MAX_REQUEST_SIZE + "`! This value is currently used anyway, but not forever. You should rename it into `" + KEY_UPLOAD_MAX_REQUEST_SIZE + "`.");
		}

			Object[] limit = parseLimit(propValue, propName, true, true);
			// ...check that the unit is correct (bytes):
			if (!LimitUnit.bytes.isCompatibleWith((LimitUnit)limit[1]))
				throw new TAPException("The maximum upload request size " + propName + " (here: " + propValue + ") can not be expressed in a unit different from bytes (B, kB, MB, GB)!");
			// ...set the max request size:
			long value = (Long)limit[0] * ((LimitUnit)limit[1]).bytesFactor();
	/**
	 * Initialize the TAP user identification method.
	 * @param tapConfig	The content of the TAP configuration file.
	 * @throws TAPException	If the corresponding TAP configuration property is wrong.
	 */
	private void initUserIdentifier(final Properties tapConfig) throws TAPException {
		// Get the property value:
		String propValue = getProperty(tapConfig, KEY_USER_IDENTIFIER);
		if (propValue != null)
			userIdentifier = newInstance(propValue, KEY_USER_IDENTIFIER, UserIdentifier.class);
        
        private void initQueryExecutor(final Properties tapConfig) throws TAPException {
		// Get the property value:
		String propValue = getProperty(tapConfig, KEY_QUERY_EXECUTOR);
		if (propValue != null)
			queryExecutor = newInstance(propValue, KEY_QUERY_EXECUTOR, QueryExecutor.class);
                else
			queryExecutor = new QueryExecutor();
	}
	/**
	 * Initialize the list of all allowed coordinate systems.
	 * @param tapConfig	The content of the TAP configuration file.
	 * @throws TAPException	If the corresponding TAP configuration properties are wrong.
	 */
	private void initCoordSys(final Properties tapConfig) throws TAPException {
		// Get the property value:
		String propValue = getProperty(tapConfig, KEY_COORD_SYS);

		// NO VALUE => ALL COORD SYS ALLOWED!
		if (propValue == null)
			lstCoordSys = null;

		// "NONE" => ALL COORD SYS FORBIDDEN (= no coordinate system expression is allowed)!
		else if (propValue.equalsIgnoreCase(VALUE_NONE))
			lstCoordSys = new ArrayList<String>(0);

		// "ANY" => ALL COORD SYS ALLOWED (= any coordinate system is allowed)!
		else if (propValue.equalsIgnoreCase(VALUE_ANY))
			lstCoordSys = null;

		// OTHERWISE, JUST THE ALLOWED ONE ARE LISTED:
			// split all the list items:
			String[] items = propValue.split(",");
				lstCoordSys = new ArrayList<String>(items.length);
					item = item.trim();
					// empty item => ignored
					if (item.length() <= 0)
						continue;
					// "NONE" is not allowed inside a list => error!
					else if (item.toUpperCase().equals(VALUE_NONE))
						throw new TAPException("The special value \"" + VALUE_NONE + "\" can not be used inside a list! It MUST be used in replacement of a whole list to specify that no value is allowed.");
					// "ANY" is not allowed inside a list => error!
					else if (item.toUpperCase().equals(VALUE_ANY))
						throw new TAPException("The special value \"" + VALUE_ANY + "\" can not be used inside a list! It MUST be used in replacement of a whole list to specify that any value is allowed.");
					// parse the coordinate system regular expression in order to check it:
							STCS.buildCoordSysRegExp(new String[]{ item });
							throw new TAPException("Incorrect coordinate system regular expression (\"" + item + "\"): " + pe.getMessage(), pe);
						}
					}
				}
				// if finally no item has been specified, consider it as "any coordinate system allowed":
				if (lstCoordSys.size() == 0)
					lstCoordSys = null;
	/**
	 * Initialize the list of all allowed ADQL geometrical functions.
	 * @param tapConfig	The content of the TAP configuration file.
	 * @throws TAPException	If the corresponding TAP configuration properties are wrong.
	 */
	private void initADQLGeometries(final Properties tapConfig) throws TAPException {
		// Get the property value:
		String propValue = getProperty(tapConfig, KEY_GEOMETRIES);

		// NO VALUE => ALL FCT ALLOWED!
		if (propValue == null)
			geometries = null;

		// "NONE" => ALL FCT FORBIDDEN (= none of these functions are allowed)!
		else if (propValue.equalsIgnoreCase(VALUE_NONE))
			geometries = new ArrayList<String>(0);

		// "ANY" => ALL FCT ALLOWED (= all of these functions are allowed)!
		else if (propValue.equalsIgnoreCase(VALUE_ANY))
			geometries = null;

		// OTHERWISE, JUST THE ALLOWED ONE ARE LISTED:
			// split all the list items:
			String[] items = propValue.split(",");
				geometries = new ArrayList<String>(items.length);
					item = item.trim();
					// empty item => ignored
					if (item.length() <= 0)
						continue;
					// if it is a name of known ADQL geometrical function, add it to the list:
					else if (item.toUpperCase().matches(GEOMETRY_REGEXP))
						geometries.add(item.toUpperCase());
					// "NONE" is not allowed inside a list => error!
					else if (item.toUpperCase().equals(VALUE_NONE))
						throw new TAPException("The special value \"" + VALUE_NONE + "\" can not be used inside a list! It MUST be used in replacement of a whole list to specify that no value is allowed.");
					// "ANY" is not allowed inside a list => error!
					else if (item.toUpperCase().equals(VALUE_ANY))
						throw new TAPException("The special value \"" + VALUE_ANY + "\" can not be used inside a list! It MUST be used in replacement of a whole list to specify that any value is allowed.");
					// unknown value => error!
					else
						throw new TAPException("Unknown ADQL geometrical function: \"" + item + "\"!");
				}
				// if finally no item has been specified, consider it as "all functions allowed":
				if (geometries.size() == 0)
					geometries = null;
	private final String REGEXP_SIGNATURE = "(\\([^()]*\\)|[^,])*";

	private final String REGEXP_CLASSPATH = "(\\{[^{}]*\\})";

	private final String REGEXP_TRANSLATION = "\"((\\\\\"|[^\"])*)\"";
	private final String REGEXP_DESCRIPTION = "\"((\\\\\"|[^\"])*)\"";
	private final String REGEXP_UDF = "\\[\\s*(" + REGEXP_SIGNATURE + ")\\s*(,\\s*(" + REGEXP_CLASSPATH + "|" + REGEXP_TRANSLATION + ")?\\s*(,\\s*(" + REGEXP_DESCRIPTION + ")?\\s*)?)?\\]";

	private final String REGEXP_UDFS = "\\s*(" + REGEXP_UDF + ")\\s*(,(.*))?";
	private final int GROUP_SIGNATURE = 2;
	private final int GROUP_CLASSPATH = 6;
	private final int GROUP_TRANSLATION = 7;
	private final int GROUP_DESCRIPTION = 11;
	private final int GROUP_NEXT_UDFs = 14;
	/**
	 * Initialize the list of all known and allowed User Defined Functions.
	 * @param tapConfig	The content of the TAP configuration file.
	 * @throws TAPException	If the corresponding TAP configuration properties are wrong.
	 */
	private void initUDFs(final Properties tapConfig) throws TAPException {
		// Get the property value:
		String propValue = getProperty(tapConfig, KEY_UDFS);

		// NO VALUE => NO UNKNOWN FCT ALLOWED!
		if (propValue == null || propValue.trim().length() == 0)
			udfs = new ArrayList<FunctionDef>(0);

		// "NONE" => NO UNKNOWN FCT ALLOWED (= none of the unknown functions are allowed)!
		else if (propValue.equalsIgnoreCase(VALUE_NONE))
			udfs = new ArrayList<FunctionDef>(0);

		// "ANY" => ALL UNKNOWN FCT ALLOWED (= all of the unknown functions are allowed)!
		else if (propValue.equalsIgnoreCase(VALUE_ANY))
			udfs = null;

		// OTHERWISE, JUST THE ALLOWED ONE ARE LISTED:
			Pattern patternUDFS = Pattern.compile(REGEXP_UDFS);
			String udfList = propValue;
			int udfOffset = 1;
				Matcher matcher = patternUDFS.matcher(udfList);

					// Fetch the signature, classpath and description:
					String signature = matcher.group(GROUP_SIGNATURE),
							classpath = matcher.group(GROUP_CLASSPATH),
							translation = matcher.group(GROUP_TRANSLATION),
							description = matcher.group(GROUP_DESCRIPTION);

					// If no signature...
					boolean ignoreUdf = false;
					if (signature == null || signature.length() == 0) {
						// ...BUT a class name => error
						if (classpath != null)
							throw new TAPException("Missing UDF declaration! (position in the property " + KEY_UDFS + ": " + (udfOffset + matcher.start(GROUP_SIGNATURE)) + "-" + (udfOffset + matcher.end(GROUP_SIGNATURE)) + ")");
						// ... => ignore this item
						else
							ignoreUdf = true;
					}
						// Add the new UDF in the list:
							// resolve the function signature:
							FunctionDef def = FunctionDef.parse(signature);
							// resolve the class name...
							if (classpath != null) {
								if (isClassName(classpath)) {
									Class<? extends UserDefinedFunction> fctClass = null;
										// fetch the class:
										fctClass = fetchClass(classpath, KEY_UDFS, UserDefinedFunction.class);
										// set the class inside the UDF definition:
										def.setUDFClass(fctClass);
										throw new TAPException("Invalid class name for the UDF definition \"" + def + "\": " + te.getMessage() + " (position in the property " + KEY_UDFS + ": " + (udfOffset + matcher.start(GROUP_CLASSPATH)) + "-" + (udfOffset + matcher.end(GROUP_CLASSPATH)) + ")", te);
									} catch(IllegalArgumentException iae) {
										throw new TAPException("Invalid class name for the UDF definition \"" + def + "\": missing a constructor with a single parameter of type ADQLOperand[] " + (fctClass != null ? "in the class \"" + fctClass.getName() + "\"" : "") + "! (position in the property " + KEY_UDFS + ": " + (udfOffset + matcher.start(GROUP_CLASSPATH)) + "-" + (udfOffset + matcher.end(GROUP_CLASSPATH)) + ")");
									}
									throw new TAPException("Invalid class name for the UDF definition \"" + def + "\": \"" + classpath + "\" is not a class name (or is not surrounding by {} as expected in this property file)! (position in the property " + KEY_UDFS + ": " + (udfOffset + matcher.start(GROUP_CLASSPATH)) + "-" + (udfOffset + matcher.end(GROUP_CLASSPATH)) + ")");
							// ...or the given translation:
							else if (translation != null) {
								try {
									def.setTranslationPattern(translation);
								} catch(IllegalArgumentException iae) {
									throw new TAPException("Invalid argument reference in the translation pattern for the UDF \"" + def + "\"! Cause: " + iae.getMessage());
								}
							}
							// set the description if any:
							if (description != null)
								def.description = description;
							// add the UDF:
							udfs.add(def);
							throw new TAPException("Wrong UDF declaration syntax: " + pe.getMessage() + " (position in the property " + KEY_UDFS + ": " + (udfOffset + matcher.start(GROUP_SIGNATURE)) + "-" + (udfOffset + matcher.end(GROUP_SIGNATURE)) + ")", pe);
						}
					// Prepare the next iteration (i.e. the other UDFs):
					udfList = matcher.group(GROUP_NEXT_UDFs);
					if (udfList != null && udfList.trim().length() == 0)
						udfList = null;
					udfOffset += matcher.start(GROUP_NEXT_UDFs);
					throw new TAPException("Wrong UDF declaration syntax: \"" + udfList + "\"! (position in the property " + KEY_UDFS + ": " + udfOffset + "-" + (propValue.length() + 1) + ")");
			}
	public String getProviderDescription() {
	public void setAvailable(boolean isAvailable, String message) {
		this.isAvailable = isAvailable;
		availability = message;
	/**
	 * <p>Set the default retention period.</p>
	 * <p>This period is set by default if the user did not specify one before the execution of his query.</p>
	 * <p><em><b>Important note:</b>
	 * 	This function will apply the given retention period only if legal compared to the currently set maximum value.
	 * 	In other words, if the given value is less or equals to the current maximum retention period.
	 * </em></p>
	 * @param period	New default retention period (in seconds).
	 * @return	<i>true</i> if the given retention period has been successfully set, <i>false</i> otherwise.
	 */
	public boolean setDefaultRetentionPeriod(final int period) {
		if ((retentionPeriod[1] <= 0) || (period > 0 && period <= retentionPeriod[1])) {
			retentionPeriod[0] = period;
			return true;
	/**
	 * <p>Set the maximum retention period.</p>
	 * <p>This period limits the default retention period and the retention period specified by a user.</p>
	 * <p><em><b>Important note:</b>
	 * 	This function may reduce the default retention period if the current default retention period is bigger
	 * 	to the new maximum retention period. In a such case, the default retention period is set to the
	 * 	new maximum retention period.
	 * </em></p>
	 * @param period	New maximum retention period (in seconds).
	 */
	public void setMaxRetentionPeriod(final int period) {
		// Decrease the default retention period if it will be bigger than the new maximum retention period:
		if (period > 0 && (retentionPeriod[0] <= 0 || period < retentionPeriod[0]))
			retentionPeriod[0] = period;
		// Set the new maximum retention period:
		retentionPeriod[1] = period;
	/**
	 * <p>Set the default execution duration.</p>
	 * <p>This duration is set by default if the user did not specify one before the execution of his query.</p>
	 * <p><em><b>Important note:</b>
	 * 	This function will apply the given execution duration only if legal compared to the currently set maximum value.
	 * 	In other words, if the given value is less or equals to the current maximum execution duration.
	 * </em></p>
	 * @param duration	New default execution duration (in milliseconds).
	 * @return	<i>true</i> if the given execution duration has been successfully set, <i>false</i> otherwise.
	 */
	public boolean setDefaultExecutionDuration(final int duration) {
		if ((executionDuration[1] <= 0) || (duration > 0 && duration <= executionDuration[1])) {
	/**
	 * <p>Set the maximum execution duration.</p>
	 * <p>This duration limits the default execution duration and the execution duration specified by a user.</p>
	 * <p><em><b>Important note:</b>
	 * 	This function may reduce the default execution duration if the current default execution duration is bigger
	 * 	to the new maximum execution duration. In a such case, the default execution duration is set to the
	 * 	new maximum execution duration.
	 * </em></p>
	 * @param duration	New maximum execution duration (in milliseconds).
	 */
	public void setMaxExecutionDuration(final int duration) {
		// Decrease the default execution duration if it will be bigger than the new maximum execution duration:
		if (duration > 0 && (executionDuration[0] <= 0 || duration < executionDuration[0]))
			executionDuration[0] = duration;
		// Set the new maximum execution duration:
		executionDuration[1] = duration;
	public Iterator<OutputFormat> getOutputFormats() {
		return outputFormats.iterator();
	public OutputFormat getOutputFormat(final String mimeOrAlias) {
		if (mimeOrAlias == null || mimeOrAlias.trim().isEmpty())
			return null;

			if ((f.getMimeType() != null && f.getMimeType().equalsIgnoreCase(mimeOrAlias)) || (f.getShortMimeType() != null && f.getShortMimeType().equalsIgnoreCase(mimeOrAlias)))
				return f;
		}
	/**
	 * <p>Add the given {@link OutputFormat} in the list of output formats supported by the TAP service.</p>
	 * <p><b>Warning:
	 * 	No verification is done in order to avoid duplicated output formats in the list.
	 * 	NULL objects are merely ignored silently.
	 * </b></p>
	 * @param newOutputFormat	New output format.
	 */
	public void addOutputFormat(final OutputFormat newOutputFormat) {
		if (newOutputFormat != null)
			outputFormats.add(newOutputFormat);
	 * @param mimeOrAlias	Full or short MIME type of the output format to remove.
	 * @return	<i>true</i> if the specified format has been found and successfully removed from the list,
	 *        	<i>false</i> otherwise.
	 */
	public boolean removeOutputFormat(final String mimeOrAlias) {
		if (of != null)
			return outputFormats.remove(of);
		else
			return false;
	 * <p>This limit is set by default if the user did not specify one before the execution of his query.</p>
	 * <p><em><b>Important note:</b>
	 * 	This function will apply the given output limit only if legal compared to the currently set maximum value.
	 * 	In other words, if the given value is less or equals to the current maximum output limit.
	 * </em></p>
	 * @param limit	New default output limit (in number of rows).
	 * @return	<i>true</i> if the given output limit has been successfully set, <i>false</i> otherwise.
	 */
	public boolean setDefaultOutputLimit(final int limit) {
		if ((outputLimits[1] <= 0) || (limit > 0 && limit <= outputLimits[1])) {
			outputLimits[0] = limit;
			return true;
	 * <p>This output limit limits the default output limit and the output limit specified by a user.</p>
	 * <p><em><b>Important note:</b>
	 * 	This function may reduce the default output limit if the current default output limit is bigger
	 * 	to the new maximum output limit. In a such case, the default output limit is set to the
	 * 	new maximum output limit.
	 * </em></p>
	 * @param limit	New maximum output limit (in number of rows).
	 */
	public void setMaxOutputLimit(final int limit) {
		// Decrease the default output limit if it will be bigger than the new maximum output limit:
		if (limit > 0 && (outputLimits[0] <= 0 || limit < outputLimits[0]))
			outputLimits[0] = limit;
		// Set the new maximum output limit:
		outputLimits[1] = limit;
	public final LimitUnit[] getOutputLimitType() {
		return new LimitUnit[]{ LimitUnit.rows, LimitUnit.rows };
	public Collection<String> getCoordinateSystems() {
	public UWSFileManager getFileManager() {
	public void setUploadEnabled(final boolean enabled) {
	public LimitUnit[] getUploadLimitType() {
	 * @param type	Unit of upload limit (rows or bytes).
	 */
	public void setUploadLimitType(final LimitUnit type) {
			uploadLimitTypes = new LimitUnit[]{ type, type };
	 * Set the default upload limit.
	 * 	This function will apply the given upload limit only if legal compared
	 * 	to the currently set maximum value. In other words, if the given value
	 * 	is less or equals to the current maximum upload limit.
	 * @param limit	New default upload limit.
	 * @return	<i>true</i> if the given upload limit has been successfully set,
	 *        	<i>false</i> otherwise.
	 *
	 * @deprecated	Since 2.3, use {@link #setDefaultUploadLimit(long)} instead.
	public boolean setDefaultUploadLimit(final int limit) {
		return setDefaultUploadLimit((long)limit);
	}

	/**
	 * Set the default upload limit.
	 *
	 * <p><em><b>Important note:</b>
	 * 	This function will apply the given upload limit only if legal compared
	 * 	to the currently set maximum value. In other words, if the given value
	 * 	is less or equals to the current maximum upload limit.
	 * </em></p>
	 *
	 * @param limit	New default upload limit.
	 *
	 * @return	<i>true</i> if the given upload limit has been successfully set,
	 *        	<i>false</i> otherwise.
	 *
	 * @since 2.3
	 */
	public boolean setDefaultUploadLimit(final long limit) {
		try {
			if ((uploadLimits[1] <= 0) || (limit > 0 && LimitUnit.compare(limit, uploadLimitTypes[0], uploadLimits[1], uploadLimitTypes[1]) <= 0)) {
	 * Set the maximum upload limit.
	 * <p>This upload limit limits the default upload limit.</p>
	 * 	This function may reduce the default upload limit if the current default
	 * 	upload limit is bigger to the new maximum upload limit. In a such case,
	 * 	the default upload limit is set to the new maximum upload limit.
	 * @param limit	New maximum upload limit.
	 *
	 * @deprecated	Since 2.3, use {@link #setMaxUploadLimit(long)} instead.
	public void setMaxUploadLimit(final int limit) {
		setMaxUploadLimit((long)limit);
	}

	/**
	 * Set the maximum upload limit.
	 *
	 * <p>This upload limit limits the default upload limit.</p>
	 *
	 * <p><em><b>Important note:</b>
	 * 	This function may reduce the default upload limit if the current default
	 * 	upload limit is bigger to the new maximum upload limit. In a such case,
	 * 	the default upload limit is set to the new maximum upload limit.
	 * </em></p>
	 *
	 * @param limit	New maximum upload limit.
	 *
	 * @since 2.3
	 */
	public void setMaxUploadLimit(final long limit) {
		try {
			// Decrease the default output limit if it will be bigger than the new maximum output limit:
			if (limit > 0 && (uploadLimits[0] <= 0 || LimitUnit.compare(limit, uploadLimitTypes[1], uploadLimits[0], uploadLimitTypes[0]) < 0))
				uploadLimits[0] = limit;
			// Set the new maximum output limit:
			uploadLimits[1] = limit;
	 * Set the maximum size of a VOTable files set that can be uploaded in once.
	 * 	This size can not be negative or 0. If the given value is in this case,
	 * 	nothing will be done and <i>false</i> will be returned. On the contrary
	 * 	to the other limits, no "unlimited" limit is possible here ; only the
	 * 	maximum value can be set (i.e. maximum positive integer value).
	 * </b></p>
	 * @param maxSize	New maximum size (in bytes).
	 * @return	<i>true</i> if the size has been successfully set,
	 *        	<i>false</i> otherwise.
	 *
	 * @deprecated	Since 2.3, use {@link #setMaxUploadSize(long)} instead.
	public boolean setMaxUploadSize(final int maxSize) {
		// No "unlimited" value possible there:
		if (maxSize <= 0)
			return false;

		// Otherwise, set the maximum upload file size:
		maxUploadSize = maxSize;
		return true;
	}

	/**
	 * Set the maximum size of a VOTable files set that can be uploaded in once.
	 *
	 * <p><b>Warning:
	 * 	This size can not be negative or 0. If the given value is in this case,
	 * 	nothing will be done and <i>false</i> will be returned. On the contrary
	 * 	to the other limits, no "unlimited" limit is possible here ; only the
	 * 	maximum value can be set (i.e. maximum positive integer value).
	 * </b></p>
	 *
	 * @param maxSize	New maximum size (in bytes).
	 *
	 * @return	<i>true</i> if the size has been successfully set,
	 *        	<i>false</i> otherwise.
	 *
	 * @since 2.3
	 */
	public boolean setMaxUploadSize(final long maxSize) {
		// No "unlimited" value possible there:
		if (maxSize <= 0)
			return false;

		// Otherwise, set the maximum upload file size:
		maxUploadSize = maxSize;
		return true;
	}

	public UserIdentifier getUserIdentifier() {
        
	@Override
        public QueryExecutor getQueryExecutor() {
		return queryExecutor;
        }
	public Collection<String> getGeometries() {
	public Collection<FunctionDef> getUDFs() {