Skip to content
Snippets Groups Projects
Commit 021054e4 authored by gmantele's avatar gmantele
Browse files

[UWS,TAP] Fix UPLOAD bug (the last line of the table to upload was ignored)....

[UWS,TAP] Fix UPLOAD bug (the last line of the table to upload was ignored). Fix an improbable NullPointerException in the MultipartParser.
parent e10cca67
No related branches found
No related tags found
No related merge requests found
...@@ -51,17 +51,17 @@ public class VOTableIterator implements TableIterator { ...@@ -51,17 +51,17 @@ public class VOTableIterator implements TableIterator {
* <p><i>Note: this may be NULL after the metadata has been read if an error occurred while performing the conversion. * <p><i>Note: this may be NULL after the metadata has been read if an error occurred while performing the conversion.
* In this case, metaError contains this error.</> */ * In this case, metaError contains this error.</> */
private TAPColumn[] meta = null; private TAPColumn[] meta = null;
/** The error which happened while converting the StarTable metadata into TAP metadata. */ /** The error which happened while converting the StarTable metadata into TAP metadata. */
private DataReadException metaError = null; private DataReadException metaError = null;
/** The last accepted row. */ /** The last accepted row. */
private Object[] pendingRow = null; private Object[] pendingRow = null;
/** Flag meaning that the end of the stream has been reached /** Flag meaning that the end of the stream has been reached
* OR if the VOTable reading should be stopped before reading more rows. */ * OR if the VOTable reading should be stopped before reading more rows. */
private boolean endReached = false; private boolean endReached = false;
/** /**
* <p>Stop nicely reading the VOTable.</p> * <p>Stop nicely reading the VOTable.</p>
* *
...@@ -74,17 +74,17 @@ public class VOTableIterator implements TableIterator { ...@@ -74,17 +74,17 @@ public class VOTableIterator implements TableIterator {
endReached = true; endReached = true;
notifyAll(); notifyAll();
} }
@Override @Override
public synchronized void acceptMetadata(final StarTable metaTable) throws TableFormatException { public synchronized void acceptMetadata(final StarTable metaTable) throws TableFormatException{
try{ try{
// Convert the StartTable metadata into TAP metadata: // Convert the StartTable metadata into TAP metadata:
meta = extractColMeta(metaTable); meta = extractColMeta(metaTable);
}catch(DataReadException dre){ }catch(DataReadException dre){
// Save the error ; this error will be throw when a call to getMetadata() will be done: // Save the error ; this error will be throw when a call to getMetadata() will be done:
metaError = dre; metaError = dre;
}finally{ }finally{
// Free all waiting threads: // Free all waiting threads:
notifyAll(); notifyAll();
...@@ -92,18 +92,18 @@ public class VOTableIterator implements TableIterator { ...@@ -92,18 +92,18 @@ public class VOTableIterator implements TableIterator {
} }
@Override @Override
public synchronized void acceptRow(final Object[] row) throws IOException { public synchronized void acceptRow(final Object[] row) throws IOException{
try{ try{
// Wait until the last accepted row has been consumed: // Wait until the last accepted row has been consumed:
while(!endReached && pendingRow != null) while(!endReached && pendingRow != null)
wait(); wait();
/* If the end has been reached, this is not normal /* If the end has been reached, this is not normal
* (because endRows() is always called after acceptRow()...so, it means the iteration has been aborted before the end) * (because endRows() is always called after acceptRow()...so, it means the iteration has been aborted before the end)
* and so the stream reading should be interrupted: */ * and so the stream reading should be interrupted: */
if (endReached) if (endReached)
throw new IOException("Streaming aborted!"); throw new IOException("Streaming aborted!");
// Otherwise, keep the given row: // Otherwise, keep the given row:
pendingRow = row; pendingRow = row;
...@@ -113,13 +113,13 @@ public class VOTableIterator implements TableIterator { ...@@ -113,13 +113,13 @@ public class VOTableIterator implements TableIterator {
* ...which should then mean that the end of the stream has been reached. */ * ...which should then mean that the end of the stream has been reached. */
if (pendingRow == null) if (pendingRow == null)
endReached = true; endReached = true;
}catch(InterruptedException ie){ }catch(InterruptedException ie){
/* If the thread has been interrupted, set this TableSink in a state similar to /* If the thread has been interrupted, set this TableSink in a state similar to
* when the end of the stream has been reached: */ * when the end of the stream has been reached: */
pendingRow = null; pendingRow = null;
endReached = true; endReached = true;
}finally{ }finally{
// In all cases, all waiting threads must be freed: // In all cases, all waiting threads must be freed:
notifyAll(); notifyAll();
...@@ -127,15 +127,23 @@ public class VOTableIterator implements TableIterator { ...@@ -127,15 +127,23 @@ public class VOTableIterator implements TableIterator {
} }
@Override @Override
public synchronized void endRows() throws IOException { public synchronized void endRows() throws IOException{
// No more rows are available: try{
pendingRow = null; // Wait until the last accepted row has been consumed:
// Set the END flag: while(!endReached && pendingRow != null)
endReached = true; wait();
// Notify all waiting threads that the end has been reached: }catch(InterruptedException ie){
notifyAll(); /* Nothing to do in particular ; the end of the stream will be set anyway. */
}finally{
// No more rows are available:
pendingRow = null;
// Set the END flag:
endReached = true;
// Notify all waiting threads that the end has been reached:
notifyAll();
}
} }
/** /**
* <p>Get the metadata found in the VOTable.</p> * <p>Get the metadata found in the VOTable.</p>
* *
...@@ -154,14 +162,14 @@ public class VOTableIterator implements TableIterator { ...@@ -154,14 +162,14 @@ public class VOTableIterator implements TableIterator {
// Wait until metadata are available, or if an error has occurred while accepting them: // Wait until metadata are available, or if an error has occurred while accepting them:
while(metaError == null && meta == null) while(metaError == null && meta == null)
wait(); wait();
// If there was an error while interpreting the accepted metadata, throw it: // If there was an error while interpreting the accepted metadata, throw it:
if (metaError != null) if (metaError != null)
throw metaError; throw metaError;
// Otherwise, just return the metadata: // Otherwise, just return the metadata:
return meta; return meta;
}catch(InterruptedException ie){ }catch(InterruptedException ie){
/* If the thread has been interrupted, set this TableSink in a state similar to /* If the thread has been interrupted, set this TableSink in a state similar to
* when the end of the stream has been reached: */ * when the end of the stream has been reached: */
...@@ -169,13 +177,13 @@ public class VOTableIterator implements TableIterator { ...@@ -169,13 +177,13 @@ public class VOTableIterator implements TableIterator {
/* Return the metadata ; /* Return the metadata ;
* NULL will be returned if the interruption has occurred before the real reading of the VOTable metadata: */ * NULL will be returned if the interruption has occurred before the real reading of the VOTable metadata: */
return meta; return meta;
}finally{ }finally{
// In all cases, the waiting threads must be freed: // In all cases, the waiting threads must be freed:
notifyAll(); notifyAll();
} }
} }
/** /**
* <p>Get the last accepted row.</p> * <p>Get the last accepted row.</p>
* *
...@@ -186,35 +194,35 @@ public class VOTableIterator implements TableIterator { ...@@ -186,35 +194,35 @@ public class VOTableIterator implements TableIterator {
* *
* @return * @return
*/ */
public synchronized Object[] getRow() { public synchronized Object[] getRow(){
try{ try{
// Wait until a row has been accepted or the end has been reached: // Wait until a row has been accepted or the end has been reached:
while(!endReached && pendingRow == null) while(!endReached && pendingRow == null)
wait(); wait();
// If there is no more rows, just return NULL (meaning for the called "end of stream"): // If there is no more rows, just return NULL (meaning for the called "end of stream"):
if (endReached) if (endReached && pendingRow == null)
return null; return null;
/* Otherwise, reset pendingRow to NULL in order to enable the reading of the next row, /* Otherwise, reset pendingRow to NULL in order to enable the reading of the next row,
* and finally return the last accepted row: */ * and finally return the last accepted row: */
Object[] row = pendingRow; Object[] row = pendingRow;
pendingRow = null; pendingRow = null;
return row; return row;
}catch(InterruptedException ie){ }catch(InterruptedException ie){
/* If the thread has been interrupted, set this TableSink in a state similar to /* If the thread has been interrupted, set this TableSink in a state similar to
* when the end of the stream has been reached: */ * when the end of the stream has been reached: */
endReached = true; endReached = true;
// Return NULL, meaning the end of the stream has been reached: // Return NULL, meaning the end of the stream has been reached:
return null; return null;
}finally { }finally{
// In all cases, the waiting threads must be freed: // In all cases, the waiting threads must be freed:
notifyAll(); notifyAll();
} }
} }
/** /**
* Extract an array of {@link TAPColumn} objects. Each corresponds to one of the columns listed in the given table, * Extract an array of {@link TAPColumn} objects. Each corresponds to one of the columns listed in the given table,
* and so corresponds to the metadata of a column. * and so corresponds to the metadata of a column.
...@@ -307,9 +315,9 @@ public class VOTableIterator implements TableIterator { ...@@ -307,9 +315,9 @@ public class VOTableIterator implements TableIterator {
// Build the VOTable type: // Build the VOTable type:
return new VotType(votdatatype, arraysize, xtype); return new VotType(votdatatype, arraysize, xtype);
} }
} }
/** Stream containing the VOTable on which this {@link TableIterator} is iterating. */ /** Stream containing the VOTable on which this {@link TableIterator} is iterating. */
protected final InputStream input; protected final InputStream input;
/** The StarTable consumer which is used to iterate on each row. */ /** The StarTable consumer which is used to iterate on each row. */
...@@ -319,14 +327,14 @@ public class VOTableIterator implements TableIterator { ...@@ -319,14 +327,14 @@ public class VOTableIterator implements TableIterator {
protected boolean iterationStarted = false; protected boolean iterationStarted = false;
/** Indicate whether the last row has already been reached. */ /** Indicate whether the last row has already been reached. */
protected boolean endReached = false; protected boolean endReached = false;
/** The last read row. Column iteration is done on this array. */ /** The last read row. Column iteration is done on this array. */
protected Object[] row; protected Object[] row;
/** Index of the last read column (=0 just after {@link #nextRow()} and before {@link #nextCol()}, ={@link #nbColumns} after the last column has been read). */ /** Index of the last read column (=0 just after {@link #nextRow()} and before {@link #nextCol()}, ={@link #nbColumns} after the last column has been read). */
protected int indCol = -1; protected int indCol = -1;
/** Number of columns available according to the metadata. */ /** Number of columns available according to the metadata. */
protected int nbCol = 0; protected int nbCol = 0;
/** /**
* Build a TableIterator able to read rows and columns inside the given VOTable input stream. * Build a TableIterator able to read rows and columns inside the given VOTable input stream.
* *
...@@ -340,7 +348,7 @@ public class VOTableIterator implements TableIterator { ...@@ -340,7 +348,7 @@ public class VOTableIterator implements TableIterator {
if (input == null) if (input == null)
throw new NullPointerException("Missing VOTable document input stream over which to iterate!"); throw new NullPointerException("Missing VOTable document input stream over which to iterate!");
this.input = input; this.input = input;
try{ try{
// Set the VOTable builder/interpreter: // Set the VOTable builder/interpreter:
...@@ -348,19 +356,20 @@ public class VOTableIterator implements TableIterator { ...@@ -348,19 +356,20 @@ public class VOTableIterator implements TableIterator {
// Build the TableSink to use: // Build the TableSink to use:
sink = new StreamVOTableSink(); sink = new StreamVOTableSink();
// Initiate the stream process: // Initiate the stream process:
Thread streamThread = new Thread() { Thread streamThread = new Thread(){
public void run() { @Override
try{ public void run(){
tb.streamStarTable(input, sink, null); try{
}catch(IOException e) { tb.streamStarTable(input, sink, null);
if (e.getMessage() != null && !e.getMessage().equals("Reading interrupted!")) }catch(IOException e){
e.printStackTrace(); if (e.getMessage() != null && !e.getMessage().equals("Reading interrupted!"))
} e.printStackTrace();
} }
}; }
streamThread.start(); };
streamThread.start();
}catch(Exception ex){ }catch(Exception ex){
throw new DataReadException("Unable to parse/read the given VOTable input stream!", ex); throw new DataReadException("Unable to parse/read the given VOTable input stream!", ex);
...@@ -368,33 +377,33 @@ public class VOTableIterator implements TableIterator { ...@@ -368,33 +377,33 @@ public class VOTableIterator implements TableIterator {
} }
@Override @Override
public TAPColumn[] getMetadata() throws DataReadException { public TAPColumn[] getMetadata() throws DataReadException{
return sink.getMeta(); return sink.getMeta();
} }
@Override @Override
public boolean nextRow() throws DataReadException { public boolean nextRow() throws DataReadException{
// If no more rows, return false directly: // If no more rows, return false directly:
if (endReached) if (endReached)
return false; return false;
// Fetch the row: // Fetch the row:
row = sink.getRow(); row = sink.getRow();
// Reset the column iteration: // Reset the column iteration:
if (!iterationStarted){ if (!iterationStarted){
iterationStarted = true; iterationStarted = true;
nbCol = sink.getMeta().length; nbCol = sink.getMeta().length;
} }
indCol = 0; indCol = 0;
// Tells whether there is more rows or not: // Tells whether there is more rows or not:
endReached = (row == null); endReached = (row == null);
return !endReached; return !endReached;
} }
@Override @Override
public boolean hasNextCol() throws IllegalStateException, DataReadException { public boolean hasNextCol() throws IllegalStateException, DataReadException{
// Check the read state: // Check the read state:
checkReadState(); checkReadState();
...@@ -403,7 +412,7 @@ public class VOTableIterator implements TableIterator { ...@@ -403,7 +412,7 @@ public class VOTableIterator implements TableIterator {
} }
@Override @Override
public Object nextCol() throws NoSuchElementException, IllegalStateException, DataReadException { public Object nextCol() throws NoSuchElementException, IllegalStateException, DataReadException{
// Check the read state and ensure there is still at least one column to read: // Check the read state and ensure there is still at least one column to read:
if (!hasNextCol()) if (!hasNextCol())
throw new NoSuchElementException("No more field to read!"); throw new NoSuchElementException("No more field to read!");
...@@ -413,7 +422,7 @@ public class VOTableIterator implements TableIterator { ...@@ -413,7 +422,7 @@ public class VOTableIterator implements TableIterator {
} }
@Override @Override
public DBType getColType() throws IllegalStateException, DataReadException { public DBType getColType() throws IllegalStateException, DataReadException{
// Basically check the read state (for rows iteration): // Basically check the read state (for rows iteration):
checkReadState(); checkReadState();
...@@ -428,7 +437,7 @@ public class VOTableIterator implements TableIterator { ...@@ -428,7 +437,7 @@ public class VOTableIterator implements TableIterator {
} }
@Override @Override
public void close() throws DataReadException { public void close() throws DataReadException{
endReached = true; endReached = true;
sink.stop(); sink.stop();
// input.close(); // in case sink.stop() is not enough to stop the VOTable reading! // input.close(); // in case sink.stop() is not enough to stop the VOTable reading!
......
...@@ -512,7 +512,7 @@ public class DALIUpload { ...@@ -512,7 +512,7 @@ public class DALIUpload {
// Check the label: // Check the label:
if (!parts[0].matches("[a-zA-Z][a-zA-Z0-9_]*")) if (!parts[0].matches("[a-zA-Z][a-zA-Z0-9_]*"))
throw new TAPException("Wrong uploaded item name syntax: \"" + parts[0] + "\"! An uploaded item must have a label with the syntax: [a-zA-Z][a-zA-Z0-9_]*.", UWSException.BAD_REQUEST); throw new TAPException("Wrong uploaded item name syntax: \"" + parts[0] + "\"! An uploaded item must have a label respecting the 'regular_identifier' production of ADQL 2.0 (regular expression: [a-zA-Z][a-zA-Z0-9_]*).", UWSException.BAD_REQUEST);
// Check the URI: // Check the URI:
else if (!parts[1].matches("[a-zA-Z][a-zA-Z0-9\\+\\.\\-]*:.+")) else if (!parts[1].matches("[a-zA-Z][a-zA-Z0-9\\+\\.\\-]*:.+"))
throw new TAPException("Bad URI syntax: \"" + parts[1] + "\"! A URI must start with: \"<scheme>:\", where <scheme>=\"[a-zA-Z][a-zA-Z0-9+.-]*\".", UWSException.BAD_REQUEST); throw new TAPException("Bad URI syntax: \"" + parts[1] + "\"! A URI must start with: \"<scheme>:\", where <scheme>=\"[a-zA-Z][a-zA-Z0-9+.-]*\".", UWSException.BAD_REQUEST);
......
...@@ -166,6 +166,8 @@ public class MultipartParser implements RequestParser { ...@@ -166,6 +166,8 @@ public class MultipartParser implements RequestParser {
throw new UWSException(UWSException.BAD_REQUEST, "Uploads are not allowed by this service!"); throw new UWSException(UWSException.BAD_REQUEST, "Uploads are not allowed by this service!");
while(e.hasMoreElements()){ while(e.hasMoreElements()){
param = e.nextElement(); param = e.nextElement();
if (multipart.getFile(param) == null)
continue;
/* /*
* TODO !!!POSSIBLE ISSUE!!! * TODO !!!POSSIBLE ISSUE!!!
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment