}
public Sequence eval( Sequence[] args, Sequence contextSequence ) throws XPathException
{
if(!context.getEffectiveUser().hasDbaRole()) {
throw new XPathException("You must be a DBA to retrieve a backup");
}
final String exportDir = args[0].getStringValue();
File dir = new File( exportDir );
if( !dir.isAbsolute() ) {
dir = new File( (String)context.getBroker().getConfiguration().getProperty( BrokerPool.PROPERTY_DATA_DIR ), exportDir );
}
final String name = args[1].getStringValue();
final File backupFile = new File( dir, name );
if( !backupFile.canRead() ) {
return( Sequence.EMPTY_SEQUENCE );
}
if( !name.endsWith( ".zip" ) ) {
throw( new XPathException( this, "for security reasons, the function only allows " + "reading zipped backup archives" ) );
}
try {
final ZipArchiveBackupDescriptor descriptor = new ZipArchiveBackupDescriptor( backupFile );
final Properties properties = descriptor.getProperties();
if( ( properties == null ) || ( properties.size() == 0 ) ) {
throw( new XPathException( this, "the file does not see to be a valid backup archive" ) );
}
}
catch( final IOException e ) {
throw( new XPathException( this, "the file does not see to be a valid backup archive" ) );
}
// directly stream the backup contents to the HTTP response
final ResponseModule myModule = (ResponseModule)context.getModule( ResponseModule.NAMESPACE_URI );
// response object is read from global variable $response
final Variable respVar = myModule.resolveVariable( ResponseModule.RESPONSE_VAR );
if( respVar == null ) {
throw( new XPathException( this, "No response object found in the current XQuery context." ) );
}
if( respVar.getValue().getItemType() != Type.JAVA_OBJECT ) {
throw( new XPathException( this, "Variable $response is not bound to an Java object." ) );
}
final JavaObjectValue respValue = (JavaObjectValue)respVar.getValue().itemAt( 0 );
if( !"org.exist.http.servlets.HttpResponseWrapper".equals( respValue.getObject().getClass().getName() ) ) {
throw( new XPathException( this, signature.toString() + " can only be used within the EXistServlet or XQueryServlet" ) );
}
final ResponseWrapper response = (ResponseWrapper)respValue.getObject();
response.setContentType( "application/zip" );
response.setHeader("Content-Length", String.valueOf(backupFile.length()));
try {
final InputStream is = new FileInputStream( backupFile );
final OutputStream os = response.getOutputStream();
final byte[] buf = new byte[4096];
int c;
while( ( c = is.read( buf ) ) > -1 ) {
os.write( buf, 0, c );
}
is.close();
os.close();
response.flushBuffer();
}
catch( final IOException e ) {
throw( new XPathException( this, "An IO error occurred while reading the backup archive" ) );
}
return( Sequence.EMPTY_SEQUENCE );
}