Sorry for the late answer, last weeks I was on vacations. Here is the code, you are looking for (it is mostly in german, if you have any problems with it, please let me know):
OnDemandFileDownloader (inner class in DateiKnopf): [code]
private final class OnDemandFileDownloader
extends FileDownloader
{
private final OnDemandStreamResource vRessource;
public OnDemandFileDownloader (
final OnDemandStreamResource pRessource )
{
super( new StreamResource( pRessource, "" ) );
vRessource = pRessource;
}
@Override
public boolean handleConnectorRequest(
final VaadinRequest pRequest,
final VaadinResponse pResponse,
final String pPath )
throws IOException
{
if ( !getKnopfStatus().isNormal() )
{
// Richtigerweise 'false', dies bewirkt allerdings auch nur einen Eintrag
// im Logger und ein anschließendes 'return true;'
// siehe ConnectorResourceHandler.error()
return true;
}
final String dateiname = vRessource.getDateiname();
if ( dateiname == null )
{
ressourceAusgewertet( vRessource );
// Richtigerweise 'false', dies bewirkt allerdings auch nur einen Eintrag
// im Logger und ein anschließendes 'return true;'
// siehe ConnectorResourceHandler.error()
return true;
}
getResource().setFilename( dateiname );
final boolean ergebnis = super.handleConnectorRequest( pRequest, pResponse, pPath );
ressourceAusgewertet( vRessource );
return ergebnis;
}
private StreamResource getResource()
{
return (StreamResource) this.getResource( "dl" );
}
}
[/code]
OnDemandStreamResource (inner class in DateiKnopf): [code]
private static interface OnDemandStreamResource
extends StreamSource
{
String getKomplettenPfad();
String getDateiname();
void zuruecksetzen();
}
[/code]BasisOnDemandStreamResource (inner class in DateiKnopf):[code]
private class BasisOnDemandStreamResource
implements OnDemandStreamResource
{
boolean vPfadGelesen;
String vPfad;
@Override
public InputStream getStream()
{
try
{
return new URL( getKomplettenPfad() ).openStream();
}
catch ( final IOException ioe )
{
throw new RuntimeException( ioe );
}
}
@Override
public String getKomplettenPfad()
{
if ( !vPfadGelesen )
{
vPfadGelesen = true;
vPfad = getNaechstenKomplettPfad( this );
}
return vPfad;
}
@Override
public String getDateiname()
{
final String pfad = getKomplettenPfad();
if ( pfad == null ) {
return null;
}
final String[] teile = pfad.split( "/" );
return teile[ teile.length - 1 ]
;
}
@Override
public void zuruecksetzen()
{
vPfadGelesen = false;
vPfad = null;
}
}
[/code]DateiAktion:
[code]
public interface DateiAktion
extends Serializable
{
/**
* Liefert eine Liste von Dateinamen inklusive Pfad
* relativ zu {@link #getWebServiceAdresse()}.
*
* @return Liste von Dateinamen inkl. relativem Pfad
*/
public List getDateienMitPfad();
/**
* Liefert die Basis-Adresse, unter der die Dateien aus
* {@link DateiAktion#getDateienMitPfad()} zu finden sind.
* In der Regel ist dies die Adresse des WebService ohne
* {@code services/CscRPC2}, z.B. {@code http://localhost:1978/}
*
* @return Die Basis-Adresse
*/
public URL getWebServiceAdresse();
}
[/code]DateiKnopf:
class DateiKnopf
{
private final Button vKnopf;
private DateiAktion vAktion;
private String [] vKomplettenPfade;
private List<OnDemandStreamResource> vAusgefuehrteRessourcenLeser;
private List<OnDemandStreamResource> vBeendeteRessourcenLeser;
private static final int C_MAX_DATEIEN = 30;
public DateiKnopf(
final String pLabel,
final DateiAktion pAktion )
{
vKnopf = new Button( pLabel );
vAktion = pAktion;
erzeugeExtensions();
}
private void erzeugeExtensions()
{
for ( int i = 0; i < C_MAX_DATEIEN; i++ )
{
final OnDemandFileDownloader lader =
new OnDemandFileDownloader( new BasisOnDemandStreamResource() );
lader.extend( vKnopf );
}
}
private synchronized String getNaechstenKomplettPfad(
final OnDemandStreamResource pAnfrageRessource )
{
if ( vAktion == null ) {
return null;
}
// Es wurde ein Reset durchgeführt (Dateien sind neu zu lesen)
if ( vKomplettenPfade == null && vAusgefuehrteRessourcenLeser == null )
{
vKomplettenPfade = new String[ C_MAX_DATEIEN ]
;
vAusgefuehrteRessourcenLeser = new ArrayList<>( C_MAX_DATEIEN );
vBeendeteRessourcenLeser = new ArrayList<>( C_MAX_DATEIEN );
final List<String> pfade = vAktion.getDateienMitPfad();
final URL webServiceAdresse = vAktion.getWebServiceAdresse();
if ( pfade.size() > C_MAX_DATEIEN ) {
loggeWarnung( "Es wurden mehr Dateien ermittelt, als dem Nutzer zur Verfügung gestellt werden können!");
}
int i = 0;
for ( final String pfad : pfade )
{
if ( i == C_MAX_DATEIEN ) {
break;
}
vKomplettenPfade[i]
= (webServiceAdresse + pfad).replace( "\\", "/" );
i++;
}
}
if(vAusgefuehrteRessourcenLeser == null)
return null;
// aktuellen Pfad auslesen und anfragende Ressource merken
final String pfad = vKomplettenPfade[vAusgefuehrteRessourcenLeser.size()]
;
vAusgefuehrteRessourcenLeser.add( pAnfrageRessource );
return pfad;
}
private synchronized void ressourceAusgewertet(
final OnDemandStreamResource pAugewerteteRessource )
{
vBeendeteRessourcenLeser.add( pAugewerteteRessource );
// War dies die letzte anfragende Ressource?
if ( vBeendeteRessourcenLeser.size() == C_MAX_DATEIEN )
{
for ( final OnDemandStreamResource ressource : vBeendeteRessourcenLeser )
{
ressource.zuruecksetzen();
}
vAusgefuehrteRessourcenLeser.clear();
vAusgefuehrteRessourcenLeser = null;
vBeendeteRessourcenLeser.clear();
vBeendeteRessourcenLeser = null;
vKomplettenPfade = null;
}
}
public AbstractComponent getView()
{
return vKnopf;
}
}