@ -6,8 +6,51 @@ import static de.srsoftware.tools.Error.error;
@@ -6,8 +6,51 @@ import static de.srsoftware.tools.Error.error;
import de.srsoftware.cal.api.Coords ;
import de.srsoftware.tools.Payload ;
import de.srsoftware.tools.Result ;
import java.time.format.DateTimeFormatter ;
import java.util.ArrayList ;
public class Util {
public static final String BEGIN = "BEGIN" ;
public static final String END = "END" ;
public static final String DESCRIPTION = "DESCRIPTION" ;
public static final String DTEND = "DTEND" ;
public static final String DTSTAMP = "DTSTAMP" ;
public static final String DTSTART = "DTSTART" ;
public static final String GEO = "GEO" ;
public static final DateTimeFormatter ICAL_DATE_FORMAT = DateTimeFormatter . ofPattern ( "yyyyMMdd HHmmss" ) ;
public static final String LOCATION = "LOCATION" ;
public static final String PRODID = "PRODID" ;
public static final String SUMMARY = "SUMMARY" ;
public static final String UID = "UID" ;
public static final String VERSION = "VERSION" ;
public static final String VEVENT = "VEVENT" ;
public static final String VCALENDAR = "VCALENDAR" ;
private Util ( ) { }
/ * *
* formats a content line as defined in < a href = "https://datatracker.ietf.org/doc/html/rfc5545#section-3.1" > iCalendar spec < / a >
* @param key the content line key
* @param value the content line value
* @return content line formatted as described in the spec
* /
public static String contentLine ( String key , String value ) {
var contentLine = "%s:%s" . formatted ( key , value ) . trim ( ) ;
// escape line breaks
contentLine = contentLine . replace ( "\\n" , "\\\\n" ) . replace ( "\r\n" , "\\n" ) . replace ( "\r" , "\\n" ) . replace ( "\n" , "\\n" ) ;
var lines = new ArrayList < String > ( ) ;
while ( contentLine . length ( ) > 70 ) {
var pos = contentLine . lastIndexOf ( " " , 70 ) ;
if ( pos < 10 ) pos = 70 ;
var dummy = contentLine . substring ( 0 , pos ) ;
lines . add ( dummy ) ;
contentLine = '\t' + contentLine . substring ( pos ) ;
}
lines . add ( contentLine ) ;
lines . add ( "" ) ;
return String . join ( "\r\n" , lines ) ;
}
public static Result < Coords > extractCoords ( String coords ) {
if ( coords = = null ) return error ( "Argument is null" ) ;
if ( coords . isBlank ( ) ) return error ( "Argument is blank" ) ;
@ -21,4 +64,35 @@ public class Util {
@@ -21,4 +64,35 @@ public class Util {
return error ( nfe , "Failed to parse coords from %s" , coords ) ;
}
}
public static String paramText ( String param ) {
return param
. replace ( "\n" , "\\n" )
. replace ( "\"" , "''" )
. replace ( ";" , "/" )
. replace ( "," , "/" )
. replace ( ":" , "/" ) ;
}
/ * *
* wraps a text ( list of vevents in a vcalendar , as described in th < a href = "https://datatracker.ietf.org/doc/html/rfc5545#section-3.4" > iCalendar spec < / a >
* @param ical the vevents list
* @param prodId the producer id of this icalendar
* @return the completed ical string
* /
public static Result < String > wrapIcal ( Result < String > ical , String prodId ) {
if ( ical instanceof Payload < String > payload ) {
var calendar = new StringBuilder ( ) ;
calendar . append ( contentLine ( BEGIN , VCALENDAR ) ) ;
calendar . append ( contentLine ( VERSION , "2.0" ) ) ;
calendar . append ( contentLine ( PRODID , prodId ) ) ;
calendar . append ( payload . get ( ) ) ;
calendar . append ( contentLine ( END , VCALENDAR ) ) ;
return Payload . of ( calendar . toString ( ) ) ;
}
return ical ;
}
}