Newer
Older
gmantele
committed
* @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);
}
gmantele
committed
/**
* Initialize the list of all allowed coordinate systems.
gmantele
committed
* @param tapConfig The content of the TAP configuration file.
gmantele
committed
* @throws TAPException If the corresponding TAP configuration properties are wrong.
*/
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
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:
else{
// split all the list items:
String[] items = propValue.split(",");
if (items.length > 0){
lstCoordSys = new ArrayList<String>(items.length);
for(String item : items){
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:
else{
try{
STCS.buildCoordSysRegExp(new String[]{item});
lstCoordSys.add(item);
}catch(ParseException pe){
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;
}else
lstCoordSys = null;
}
}
gmantele
committed
/**
* Initialize the list of all allowed ADQL geometrical functions.
gmantele
committed
* @param tapConfig The content of the TAP configuration file.
gmantele
committed
* @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:
else{
// split all the list items:
String[] items = propValue.split(",");
if (items.length > 0){
geometries = new ArrayList<String>(items.length);
for(String item : items){
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;
}else
geometries = null;
}
}
private final String REGEXP_SIGNATURE = "(\\([^()]*\\)|[^,])*";
private final String REGEXP_CLASSPATH = "\\{[^{}]*\\}";
private final String REGEXP_DESCRIPTION = "\"((\\\"|[^\"])*)\"";
private final String REGEXP_UDF = "\\[\\s*(" + REGEXP_SIGNATURE + ")\\s*(,\\s*(" + REGEXP_CLASSPATH + ")?\\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 = 5;
private final int GROUP_DESCRIPTION = 8;
private final int GROUP_NEXT_UDFs = 11;
gmantele
committed
/**
* Initialize the list of all known and allowed User Defined Functions.
gmantele
committed
* @param tapConfig The content of the TAP configuration file.
gmantele
committed
* @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:
else{
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
Pattern patternUDFS = Pattern.compile(REGEXP_UDFS);
String udfList = propValue;
int udfOffset = 1;
while(udfList != null){
Matcher matcher = patternUDFS.matcher(udfList);
if (matcher.matches()){
// Fetch the signature, classpath and description:
String signature = matcher.group(GROUP_SIGNATURE),
classpath = matcher.group(GROUP_CLASSPATH),
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;
}
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
if (!ignoreUdf){
// Add the new UDF in the list:
try{
// resolve the function signature:
FunctionDef def = FunctionDef.parse(signature);
// resolve the class name:
if (classpath != null){
if (isClassName(classpath)){
Class<? extends UserDefinedFunction> fctClass = null;
try{
// fetch the class:
fctClass = fetchClass(classpath, KEY_UDFS, UserDefinedFunction.class);
// set the class inside the UDF definition:
def.setUDFClass(fctClass);
}catch(TAPException te){
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)) + ")");
}
}else
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)) + ")");
// set the description if any:
if (description != null)
def.description = description;
// add the UDF:
udfs.add(def);
}catch(ParseException pe){
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);
}else
throw new TAPException("Wrong UDF declaration syntax: \"" + udfList + "\"! (position in the property " + KEY_UDFS + ": " + udfOffset + "-" + (propValue.length() + 1) + ")");
}
@Override
public String getProviderName(){
return providerName;
}
@Override
public String getProviderDescription(){
return serviceDescription;
}
@Override
public boolean isAvailable(){
return isAvailable;
}
@Override
public String getAvailability(){
return availability;
}
@Override
public void setAvailable(boolean isAvailable, String message){
this.isAvailable = isAvailable;
availability = message;
}
@Override
public int[] getRetentionPeriod(){
return retentionPeriod;
}
gmantele
committed
/**
* <p>Set the default retention period.</p>
gmantele
committed
* <p>This period is set by default if the user did not specify one before the execution of his query.</p>
gmantele
committed
* <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).
gmantele
committed
* @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;
}else
return false;
}
gmantele
committed
/**
* <p>Set the maximum retention period.</p>
gmantele
committed
* <p>This period limits the default retention period and the retention period specified by a user.</p>
gmantele
committed
* <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>
gmantele
committed
* @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;
}
@Override
public int[] getExecutionDuration(){
return executionDuration;
}
gmantele
committed
/**
* <p>Set the default execution duration.</p>
gmantele
committed
* <p>This duration is set by default if the user did not specify one before the execution of his query.</p>
gmantele
committed
* <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).
gmantele
committed
* @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])){
executionDuration[0] = duration;
return true;
}else
return false;
}
gmantele
committed
/**
* <p>Set the maximum execution duration.</p>
gmantele
committed
* <p>This duration limits the default execution duration and the execution duration specified by a user.</p>
gmantele
committed
* <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>
gmantele
committed
* @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;
}
@Override
gmantele
committed
public Iterator<OutputFormat> getOutputFormats(){
return outputFormats.iterator();
}
@Override
gmantele
committed
public OutputFormat getOutputFormat(final String mimeOrAlias){
if (mimeOrAlias == null || mimeOrAlias.trim().isEmpty())
return null;
gmantele
committed
for(OutputFormat f : outputFormats){
if ((f.getMimeType() != null && f.getMimeType().equalsIgnoreCase(mimeOrAlias)) || (f.getShortMimeType() != null && f.getShortMimeType().equalsIgnoreCase(mimeOrAlias)))
return f;
}
return null;
}
gmantele
committed
/**
* <p>Add the given {@link OutputFormat} in the list of output formats supported by the TAP service.</p>
gmantele
committed
* <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>
gmantele
committed
* @param newOutputFormat New output format.
*/
gmantele
committed
public void addOutputFormat(final OutputFormat newOutputFormat){
gmantele
committed
if (newOutputFormat != null)
outputFormats.add(newOutputFormat);
}
gmantele
committed
/**
* Remove the specified output format.
gmantele
committed
* @param mimeOrAlias Full or short MIME type of the output format to remove.
gmantele
committed
* @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){
gmantele
committed
OutputFormat of = getOutputFormat(mimeOrAlias);
if (of != null)
return outputFormats.remove(of);
else
return false;
}
@Override
public int[] getOutputLimit(){
return outputLimits;
}
gmantele
committed
/**
* <p>Set the default output limit.</p>
gmantele
committed
* <p>This limit is set by default if the user did not specify one before the execution of his query.</p>
gmantele
committed
* <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).
gmantele
committed
* @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;
}else
return false;
}
gmantele
committed
/**
* <p>Set the maximum output limit.</p>
gmantele
committed
* <p>This output limit limits the default output limit and the output limit specified by a user.</p>
gmantele
committed
* <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>
gmantele
committed
* @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;
}
@Override
public final LimitUnit[] getOutputLimitType(){
return new LimitUnit[]{LimitUnit.rows,LimitUnit.rows};
}
@Override
public Collection<String> getCoordinateSystems(){
return lstCoordSys;
}
@Override
public TAPLog getLogger(){
return logger;
}
@Override
gmantele
committed
public TAPFactory getFactory(){
return tapFactory;
}
@Override
gmantele
committed
public UWSFileManager getFileManager(){
return fileManager;
}
@Override
public boolean uploadEnabled(){
return isUploadEnabled;
public void setUploadEnabled(final boolean enabled){
isUploadEnabled = enabled;
}
@Override
public int[] getUploadLimit(){
return uploadLimits;
}
@Override
public LimitUnit[] getUploadLimitType(){
return uploadLimitTypes;
}
gmantele
committed
/**
* Set the unit of the upload limit.
gmantele
committed
* @param type Unit of upload limit (rows or bytes).
*/
public void setUploadLimitType(final LimitUnit type){
if (type != null)
uploadLimitTypes = new LimitUnit[]{type,type};
}
gmantele
committed
/**
* <p>Set the default upload limit.</p>
gmantele
committed
* <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.
gmantele
committed
* @return <i>true</i> if the given upload limit has been successfully set, <i>false</i> otherwise.
*/
public boolean setDefaultUploadLimit(final int limit){
try{
if ((uploadLimits[1] <= 0) || (limit > 0 && LimitUnit.compare(limit, uploadLimitTypes[0], uploadLimits[1], uploadLimitTypes[1]) <= 0)){
uploadLimits[0] = limit;
return true;
}
}catch(TAPException e){}
return false;
}
gmantele
committed
/**
* <p>Set the maximum upload limit.</p>
gmantele
committed
* <p>This upload limit limits the default upload limit.</p>
gmantele
committed
* <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>
gmantele
committed
* @param limit New maximum upload limit.
*/
public void setMaxUploadLimit(final int limit){
try{
gmantele
committed
// 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;
}catch(TAPException e){}
}
@Override
public int getMaxUploadSize(){
return maxUploadSize;
}
gmantele
committed
/**
* <p>Set the maximum size of a VOTable files set that can be uploaded in once.</p>
gmantele
committed
* <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>
gmantele
committed
* @param maxSize New maximum size (in bytes).
gmantele
committed
* @return <i>true</i> if the size has been successfully set, <i>false</i> otherwise.
*/
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;
}
@Override
public int getNbMaxAsyncJobs(){
return maxAsyncJobs;
}
@Override
public UserIdentifier getUserIdentifier(){
return userIdentifier;
}
@Override
public TAPMetadata getTAPMetadata(){
return metadata;
}
gmantele
committed
@Override
public Collection<String> getGeometries(){
return geometries;
gmantele
committed
}
@Override
public Collection<FunctionDef> getUDFs(){
gmantele
committed
}
@Override
public int[] getFetchSize(){
return fetchSize;
}