package org.eclipse.packagedrone.repo.adapter.p2.internal.aspect;
import static com.google.common.xml.XmlEscapers.xmlAttributeEscaper;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public abstract class AbstractWriter
{
protected static final char NL = '\n';
protected static final String IN = " ";
protected static final String IN2 = IN + IN;
private final String basename;
private final String title;
private final String type;
private final boolean compressed;
private final Map<String, String> properties;
public AbstractWriter ( final String basename, final String title, final String type, final Instant timestamp, final boolean compressed, final Map<String, String> additionalProperties )
{
this.basename = basename;
this.title = title;
this.type = type;
this.compressed = compressed;
this.properties = new LinkedHashMap<> ();
if ( compressed )
{
this.properties.put ( "p2.compressed", "true" );
}
this.properties.put ( "p2.timestamp", "" + timestamp.toEpochMilli () );
if ( additionalProperties != null )
{
this.properties.putAll ( additionalProperties );
}
}
public String getId ()
{
return this.basename + ( this.compressed ? ".jar" : ".xml" );
}
public String getMimeType ()
{
return this.compressed ? "application/zip" : "application/xml";
}
public void write ( final OutputStream stream ) throws IOException
{
if ( this.compressed )
{
final ZipOutputStream zos = new ZipOutputStream ( stream );
zos.putNextEntry ( new ZipEntry ( this.basename + ".xml" ) );
writeAll ( zos );
zos.closeEntry ();
zos.finish ();
}
else
{
writeAll ( stream );
}
}
private void writeAll ( final OutputStream stream ) throws IOException
{
final PrintWriter out = new PrintWriter ( new OutputStreamWriter ( stream, StandardCharsets.UTF_8 ) );
writeHeader ( out );
writeContent ( out );
writeFooter ( out );
out.flush ();
}
protected void writeHeader ( final PrintWriter out ) throws IOException
{
out.append ( "<?xml version='1.0' encoding='UTF-8'?>" ).append ( NL );
out.append ( "<?metadataRepository version='1.1.0'?>" ).append ( NL );
out.format ( "<repository name='%s' type='%s' version='1'>", xmlAttributeEscaper ().escape ( this.title ), xmlAttributeEscaper ().escape ( this.type ) ).append ( NL );
if ( !this.properties.isEmpty () )
{
out.append ( IN ).format ( "<properties size='%s'>", this.properties.size () ).append ( NL );
for ( final Map.Entry<String, String> entry : this.properties.entrySet () )
{
out.append ( IN2 ).format ( "<property name='%s' value='%s'/>", xmlAttributeEscaper ().escape ( entry.getKey () ), xmlAttributeEscaper ().escape ( entry.getValue () ) ).append ( NL );
}
out.append ( IN ).append ( "</properties>" ).append ( NL );
}
}
protected abstract void writeContent ( PrintWriter out ) throws IOException;
protected void writeFooter ( final PrintWriter out ) throws IOException
{
out.append ( "</repository>" ).append ( NL );
}
}