jfxtras.icalendarfx.VCalendar Maven / Gradle / Ivy
package jfxtras.icalendarfx;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import jfxtras.icalendarfx.VCalendar;
import jfxtras.icalendarfx.VParentBase;
import jfxtras.icalendarfx.components.VComponent;
import jfxtras.icalendarfx.components.VEvent;
import jfxtras.icalendarfx.components.VFreeBusy;
import jfxtras.icalendarfx.components.VJournal;
import jfxtras.icalendarfx.components.VPersonal;
import jfxtras.icalendarfx.components.VTimeZone;
import jfxtras.icalendarfx.components.VTodo;
import jfxtras.icalendarfx.content.MultiLineContent;
import jfxtras.icalendarfx.content.OrdererBase;
import jfxtras.icalendarfx.content.UnfoldingStringIterator;
import jfxtras.icalendarfx.itip.AbstractITIPFactory;
import jfxtras.icalendarfx.itip.DefaultITIPFactory;
import jfxtras.icalendarfx.itip.Processable;
import jfxtras.icalendarfx.properties.calendar.CalendarScale;
import jfxtras.icalendarfx.properties.calendar.Method;
import jfxtras.icalendarfx.properties.calendar.ProductIdentifier;
import jfxtras.icalendarfx.properties.calendar.Version;
import jfxtras.icalendarfx.properties.calendar.Method.MethodType;
import jfxtras.icalendarfx.properties.component.misc.NonStandardProperty;
import jfxtras.icalendarfx.properties.component.misc.RequestStatus;
import jfxtras.icalendarfx.utilities.DateTimeUtilities;
/**
* iCalendar Object
* RFC 5545, 3.4, page 50
*
* Parent calendar object represents a collection of calendaring and scheduling information
*
* @author David Bal
*
*/
public class VCalendar extends VParentBase
{
// version of this project, not associated with the iCalendar specification version
// public static String myVersion = "1.0";
private static final String NAME = "VCALENDAR";
@Override public String name() { return NAME; }
private static final String FIRST_CONTENT_LINE = BEGIN + NAME;
private static final String LAST_CONTENT_LINE = END + NAME;
/*
* Calendar properties
*/
/**
* CALSCALE: RFC 5545 iCalendar 3.7.1. page 76
* This property defines the calendar scale used for the
* calendar information specified in the iCalendar object.
*
* This project is based on the Gregorian calendar scale.
* The Gregorian calendar scale is assumed if this property is not
* specified in the iCalendar object. It is expected that other
* calendar scales will be defined in other specifications or by
* future versions of iCalendar.
*
* The default value is "GREGORIAN"
*
* Example:
* CALSCALE:GREGORIAN
* */
public CalendarScale getCalendarScale() { return calendarScale; }
private CalendarScale calendarScale;
public void setCalendarScale(String calendarScale) { setCalendarScale(CalendarScale.parse(calendarScale)); }
public void setCalendarScale(CalendarScale calendarScale)
{
this.calendarScale = calendarScale;
orderChild(calendarScale);
}
public VCalendar withCalendarScale(CalendarScale calendarScale)
{
setCalendarScale(calendarScale);
return this;
}
public VCalendar withCalendarScale(String calendarScale)
{
setCalendarScale(calendarScale);
return this;
}
/**
* METHOD: RFC 5545 iCalendar 3.7.2. page 77
* This property defines the iCalendar object method
* associated with the calendar object
*
* Example:
* METHOD:REQUEST
* */
public Method getMethod() { return method; }
private Method method;
public void setMethod(String method) { setMethod(Method.parse(method)); }
public void setMethod(Method method)
{
this.method = method;
orderChild(method);
}
public void setMethod(MethodType method) { setMethod(new Method(method)); }
public VCalendar withMethod(Method method)
{
setMethod(method);
return this;
}
public VCalendar withMethod(MethodType method)
{
setMethod(method);
return this;
}
public VCalendar withMethod(String method)
{
setMethod(method);
return this;
}
/**
* PRODID: RFC 5545 iCalendar 3.7.3. page 78
* This property specifies the identifier for the product that
* created the iCalendar object
*
* This project is named JFxtras iCalendar
*
* Example:
* PRODID:-//JFxtras//JFXtras iCalendar 1.0//EN
* */
public ProductIdentifier getProductIdentifier() { return productIdentifier; }
private ProductIdentifier productIdentifier;
public void setProductIdentifier(String productIdentifier) { setProductIdentifier(ProductIdentifier.parse(productIdentifier)); }
public void setProductIdentifier(ProductIdentifier productIdentifier)
{
this.productIdentifier = productIdentifier;
orderChild(productIdentifier);
}
public VCalendar withProductIdentifier(ProductIdentifier productIdentifier)
{
setProductIdentifier(productIdentifier);
return this;
}
public VCalendar withProductIdentifier(String productIdentifier)
{
setProductIdentifier(productIdentifier);
return this;
}
/**
* VERSION: RFC 5545 iCalendar 3.7.4. page 79
* This property specifies the identifier corresponding to the
* highest version number or the minimum and maximum range of the
* iCalendar specification that is required in order to interpret the
* iCalendar object.
*
* This project complies with version 2.0
*
* Example:
* VERSION:2.0
* */
public Version getVersion() { return version; }
private Version version;
public void setVersion(String version) { setVersion(Version.parse(version)); }
public void setVersion(Version version)
{
this.version = version;
orderChild(version);
}
public VCalendar withVersion(Version version)
{
setVersion(version);
return this;
}
public VCalendar withVersion(String version)
{
setVersion(version);
return this;
}
public VCalendar withVersion()
{
setVersion(new Version());
return this;
}
/**
* Provides a framework for defining non-standard properties.
*/
private List nonStandardProps;
public List getNonStandard() { return nonStandardProps; }
public void setNonStandard(List nonStandardProps)
{
if (this.nonStandardProps != null)
{
this.nonStandardProps.forEach(e -> orderChild(e, null)); // remove old elements
}
this.nonStandardProps = nonStandardProps;
if (nonStandardProps != null)
{
nonStandardProps.forEach(c -> orderChild(c)); // order new elements
}
}
/**
* Sets the value of the {@link #nonStandardProperty()}
*
* @return - this class for chaining
*/
public VCalendar withNonStandard(List nonStandardProps)
{
if (getNonStandard() == null)
{
setNonStandard(new ArrayList<>());
}
getNonStandard().addAll(nonStandardProps);
if (nonStandardProps != null)
{
nonStandardProps.forEach(c -> orderChild(c));
}
return this;
}
/**
* Sets the value of the {@link #nonStandardProperty()} by parsing a vararg of
* iCalendar content text representing individual {@link NonStandardProperty} objects.
*
* @return - this class for chaining
*/
public VCalendar withNonStandard(String...nonStandardProps)
{
List newElements = Arrays.stream(nonStandardProps)
.map(c -> NonStandardProperty.parse(c))
.collect(Collectors.toList());
return withNonStandard(newElements);
}
/**
* Sets the value of the {@link #nonStandardProperty()} from a vararg of {@link NonStandardProperty} objects.
*
* @return - this class for chaining
*/
public VCalendar withNonStandard(NonStandardProperty...nonStandardProps)
{
return withNonStandard(Arrays.asList(nonStandardProps));
}
/*
* Calendar Components
*/
/**
* VEVENT: RFC 5545 iCalendar 3.6.1. page 52
*
* A grouping of component properties that describe an event.
*
*/
public List getVEvents() { return vEvents; }
private List vEvents;
public void setVEvents(List vEvents)
{
if (this.vEvents != null)
{
this.vEvents.forEach(e -> orderChild(e, null)); // remove old elements
}
this.vEvents = vEvents;
if (vEvents != null)
{
vEvents.forEach(c -> orderChild(c)); // order new elements
}
}
public VCalendar withVEvents(List vEvents)
{
if (getVEvents() == null)
{
setVEvents(new ArrayList<>());
}
getVEvents().addAll(vEvents);
if (vEvents != null)
{
vEvents.forEach(c -> orderChild(c));
}
return this;
}
public VCalendar withVEvents(String...vEvents)
{
List list = Arrays.stream(vEvents)
.map(c -> VEvent.parse(c))
.collect(Collectors.toList());
return withVEvents(list);
}
public VCalendar withVEvents(VEvent...vEvents)
{
return withVEvents(Arrays.asList(vEvents));
}
/**
* VTODO: RFC 5545 iCalendar 3.6.2. page 55
*
* A grouping of component properties that describe a task that needs to be completed.
*
*/
public List getVTodos() { return vTodos; }
private List vTodos;
public void setVTodos(List vTodos)
{
if (this.vTodos != null)
{
this.vTodos.forEach(e -> orderChild(e, null)); // remove old elements
}
this.vTodos = vTodos;
if (vTodos != null)
{
vTodos.forEach(c -> orderChild(c)); // order new elements
}
}
public VCalendar withVTodos(List vTodos)
{
if (getVTodos() == null)
{
setVTodos(new ArrayList<>());
}
getVTodos().addAll(vTodos);
if (vTodos != null)
{
vTodos.forEach(c -> orderChild(c));
}
return this;
}
public VCalendar withVTodos(String...vTodos)
{
List list = Arrays.stream(vTodos)
.map(c -> VTodo.parse(c))
.collect(Collectors.toList());
return withVTodos(list);
}
public VCalendar withVTodos(VTodo...vTodos)
{
return withVTodos(Arrays.asList(vTodos));
}
/**
* VJOURNAL: RFC 5545 iCalendar 3.6.3. page 57
*
* A grouping of component properties that describe a task that needs to be completed.
*
* @see VComponent
* @see VJournal
*/
public List getVJournals() { return vJournals; }
private List vJournals;
public void setVJournals(List vJournals)
{
if (this.vJournals != null)
{
this.vJournals.forEach(e -> orderChild(e, null)); // remove old elements
}
this.vJournals = vJournals;
if (vJournals != null)
{
vJournals.forEach(c -> orderChild(c)); // order new elements
}
}
public VCalendar withVJournals(List vJournals)
{
if (getVJournals() == null)
{
setVJournals(new ArrayList<>());
}
getVJournals().addAll(vJournals);
if (vJournals != null)
{
vJournals.forEach(c -> orderChild(c));
}
return this;
}
public VCalendar withVJournals(String...vJournals)
{
List list = Arrays.stream(vJournals)
.map(c -> VJournal.parse(c))
.collect(Collectors.toList());
return withVJournals(list);
}
public VCalendar withVJournals(VJournal...vJournals)
{
return withVJournals(Arrays.asList(vJournals));
}
/**
* VFREEBUSY: RFC 5545 iCalendar 3.6.4. page 59
*
* @see VFreeBusy
*/
public List getVFreeBusies() { return vFreeBusys; }
private List vFreeBusys;
public void setVFreeBusys(List vFreeBusys)
{
if (this.vFreeBusys != null)
{
this.vFreeBusys.forEach(e -> orderChild(e, null)); // remove old elements
}
this.vFreeBusys = vFreeBusys;
if (vFreeBusys != null)
{
vFreeBusys.forEach(c -> orderChild(c)); // order new elements
}
}
public VCalendar withVFreeBusies(List vFreeBusys)
{
if (getVFreeBusies() == null)
{
setVFreeBusys(new ArrayList<>());
}
getVFreeBusies().addAll(vFreeBusys);
if (vFreeBusys != null)
{
vFreeBusys.forEach(c -> orderChild(c));
}
return this;
}
public VCalendar withVFreeBusies(String...vFreeBusys)
{
List list = Arrays.stream(vFreeBusys)
.map(c -> VFreeBusy.parse(c))
.collect(Collectors.toList());
return withVFreeBusies(list);
}
public VCalendar withVFreeBusies(VFreeBusy...vFreeBusys)
{
return withVFreeBusies(Arrays.asList(vFreeBusys));
}
/**
* VTIMEZONE: RFC 5545 iCalendar 3.6.5. page 62
*
* @see VTimeZone
*/
public List getVTimeZones() { return vTimeZones; }
private List vTimeZones;
public void setVTimeZones(List vTimeZones)
{
if (this.vTimeZones != null)
{
this.vTimeZones.forEach(e -> orderChild(e, null)); // remove old elements
}
this.vTimeZones = vTimeZones;
if (vTimeZones != null)
{
vTimeZones.forEach(c -> orderChild(c)); // order new elements
}
}
public VCalendar withVTimeZones(List vTimeZones)
{
if (getVTimeZones() == null)
{
setVTimeZones(new ArrayList<>());
}
getVTimeZones().addAll(vTimeZones);
if (vTimeZones != null)
{
vTimeZones.forEach(c -> orderChild(c));
}
return this;
}
public VCalendar withVTimeZones(String...vTimeZones)
{
List list = Arrays.stream(vTimeZones)
.map(c -> VTimeZone.parse(c))
.collect(Collectors.toList());
return withVTimeZones(list);
}
public VCalendar withVTimeZones(VTimeZone...vTimeZones)
{
return withVTimeZones(Arrays.asList(vTimeZones));
}
// /**
// * A convenience method that adds a VComponent to one of the Lists based on
// * its type such as VEVENT, VTODO, etc.
// *
// * @param newVComponent - VComponent to add
// * @return true if add was successful, false otherwise
// */
// @Deprecated
// public boolean addVComponent(VComponent newVComponent)
// {
// if (newVComponent instanceof VEvent)
// {
// System.out.println("getVEvents():" + getVEvents());
// getVEvents().add((VEvent) newVComponent);
// } else if (newVComponent instanceof VTodo)
// {
// getVTodos().add((VTodo) newVComponent);
// } else if (newVComponent instanceof VJournal)
// {
// getVJournals().add((VJournal) newVComponent);
// } else if (newVComponent instanceof VFreeBusy)
// {
// getVFreeBusies().add((VFreeBusy) newVComponent);
// } else if (newVComponent instanceof VTimeZone)
// {
// getVTimeZones().add((VTimeZone) newVComponent);
// } else
// {
// throw new RuntimeException("Unsuppored VComponent type:" + newVComponent.getClass());
// }
// orderChild(newVComponent);
// return true;
// }
//
// public boolean removeVComponent(VComponent vComponent)
// {
// if (vComponent instanceof VEvent)
// {
// return getVEvents().remove(vComponent);
// } else if (vComponent instanceof VTodo)
// {
// return getVTodos().remove(vComponent);
// } else if (vComponent instanceof VJournal)
// {
// return getVJournals().remove(vComponent);
// } else if (vComponent instanceof VFreeBusy)
// {
// return getVFreeBusies().remove(vComponent);
// } else if (vComponent instanceof VTimeZone)
// {
// return getVTimeZones().remove(vComponent);
// } else
// {
// throw new RuntimeException("Unsuppored VComponent type:" + vComponent.getClass());
// }
// }
/**
* A convenience method that returns parent list of the {@link VComponent} parameter.
* Returns null if component is not in any {@link VComponent} list.
*
* @param vComponent - VComponent to look up
*/
public List extends VComponent> getVComponents(VComponent vComponent)
{
if (vComponent instanceof VEvent)
{
return getVEvents();
} else if (vComponent instanceof VTodo)
{
return getVTodos();
} else if (vComponent instanceof VJournal)
{
return getVJournals();
} else if (vComponent instanceof VFreeBusy)
{
return getVFreeBusies();
} else if (vComponent instanceof VTimeZone)
{
return getVTimeZones();
} else
{
throw new RuntimeException("Unsuppored VComponent type:" + vComponent.getClass());
}
}
/** set AbstractITIPFactory to handle processing input VCalendar based on {@link Method} */
public void setMethodProcessFactory(AbstractITIPFactory iTIPFactory)
{
this.iTIPFactory = iTIPFactory;
}
/** get AbstractITIPFactory to handle processing input VCalendar based on {@link Method} */
public AbstractITIPFactory getITIPFactory()
{
return iTIPFactory;
}
private AbstractITIPFactory iTIPFactory;
/**
* Process the exchange of iCalendar object according to the iTIP methods identifies in RFC 5546
* based on the methods in {@link #getITIPFactory()}
*
* @param iTIPMessages iTIP VCalendars to process with {@link Method} populated
* @return - log of process operation
*/
public List processITIPMessage(VCalendar... iTIPMessages)
{
return processITIPMessage(Arrays.asList(iTIPMessages));
}
/**
* Process the exchange of iCalendar object according to the iTIP methods identifies in RFC 5546
* based on the methods in {@link #getITIPFactory()}
*
* @param iTIPMessages iTIP VCalendars to process with {@link Method} populated
* @return - log of process operation
*/
public List processITIPMessage(Collection iTIPMessages)
{
List log = new ArrayList<>();
iTIPMessages.forEach(message ->
{
final Processable methodProcess;
if (message.getMethod() == null)
{ // default to PUBLISH method if not present
methodProcess = getITIPFactory().getITIPMessageProcess(MethodType.PUBLISH);
// throw new IllegalArgumentException("VCalendar to be processed MUST have the METHOD property populated");
} else
{
MethodType method = message.getMethod().getValue();
methodProcess = getITIPFactory().getITIPMessageProcess(method);
}
List methodLog = methodProcess.process(this, message);
log.addAll(methodLog);
});
return log;
}
/**
* Process the exchange of iCalendar object according to the iTIP methods identifies in RFC 5546.
* Input string can contain multiple iTIP VCALENDAR messages.
*
* @param iTIPMessages iTIP VCalendar Message strings
* @return - log of process operation
*/
public List processITIPMessage(String iTIPMessages)
{
List log = new ArrayList<>();
List iTIPMessageList = new ArrayList<>();
StringBuilder builder = new StringBuilder(1000);
for(String line : iTIPMessages.split(System.lineSeparator()))
{
if (line.equals("BEGIN:VCALENDAR") && builder.length() > 0)
{
iTIPMessageList.add(builder.toString());
builder = new StringBuilder(1000);
}
builder.append(line + System.lineSeparator());
}
// handle last VCalendar message
if (builder.length() > 0)
{
iTIPMessageList.add(builder.toString());
}
iTIPMessageList.forEach(message ->
{
List methodLog = processITIPMessage(VCalendar.parse(message));
log.addAll(methodLog);
});
return log;
}
/**
* Parse component text to new VComponent with {@link RequestStatus REQUEST-STATUS} properties containing
* the result of the process, such as success message or error report.
*
* @param contentText iCalendar content lines
* @return the created VComponent with {@link RequestStatus REQUEST-STATUS} populated to indicate success or failuer.
*/
@Deprecated // replace with addVCalendar
public VComponent importVComponent(String contentText)
{
// VPersonal> vComponent = (VPersonal>) SimpleVComponentFactory.emptyVComponent(contentText);
VPersonal> vComponent = null; //TODO - FIX THIS
List contentLines = Arrays.asList(contentText.split(System.lineSeparator()));
UnfoldingStringIterator unfoldedLines = new UnfoldingStringIterator(contentLines.iterator());
// Iterator unfoldedLines = ICalendarUtilities.unfoldLines(contentLines).iterator();
boolean useRequestStatus = true;
// vComponent.parseContent(unfoldedLines, useRequestStatus);
vComponent.parseContent(unfoldedLines);
// requestStatusErrors.stream().forEach(System.out::println);
// TODO - only check conflict if opaque
String conflict = (vComponent instanceof VEvent) ? DateTimeUtilities.checkScheduleConflict((VEvent) vComponent, getVEvents()) : null;
if (conflict != null)
{
final List requestStatus;
if (vComponent.getRequestStatus() == null)
{
requestStatus = new ArrayList<>();
vComponent.setRequestStatus(requestStatus);
} else
{
requestStatus = vComponent.getRequestStatus();
}
// remove success REQUEST-STATUS message, if present
Iterator rsIterator = requestStatus.iterator();
while (rsIterator.hasNext())
{
RequestStatus rs = rsIterator.next();
if (rs.getValue().substring(0, 3).equals("2.0"))
{
rsIterator.remove();
}
}
requestStatus.add(RequestStatus.parse("4.1;Event conflict with " + conflict));
}
final boolean isVComponentValidToAdd;
if (vComponent.getRequestStatus() == null)
{
isVComponentValidToAdd = true;
} else
{
isVComponentValidToAdd = ! vComponent.getRequestStatus().stream()
.map(s -> s.getValue())
.anyMatch(s -> (s.charAt(0) == '3') || (s.charAt(0) == '4')); // error codes start with 3 or 4
}
if (isVComponentValidToAdd)
{
addChild(vComponent);
}
return vComponent;
}
/**
* Import new VComponent with {@link RequestStatus REQUEST-STATUS} properties containing
* the result of the process, such as success message or error report.
*
* @param contentText iCalendar content lines
* @return list of error messages if import failed, null if successful
*/
@Deprecated
public List importVComponent(VComponent newVComponent)
{
throw new RuntimeException("not implemented");
}
@Override
public List errors()
{
List errors = super.errors();
if (getProductIdentifier() == null)
{
errors.add("PRODID is not present. PRODID is REQUIRED and MUST NOT occur more than once");
}
if (getVersion() == null)
{
errors.add("VERSION is not present. VERSION is REQUIRED and MUST NOT occur more than once");
}
return errors;
}
/*
* CONSTRUCTORS
*/
/** Creates an empty VCalendar */
public VCalendar()
{
setMethodProcessFactory(new DefaultITIPFactory());
// List getters = ICalendarUtilities.collectGetters(getClass());
orderer = new OrdererBase(this, getGetters());
contentLineGenerator = new MultiLineContent(
orderer,
FIRST_CONTENT_LINE,
LAST_CONTENT_LINE,
1000);
}
/** Copy constructor */
public VCalendar(VCalendar source)
{
this();
source.copyChildrenInto(this);
}
/*
* OTHER METHODS
*/
// @Override
// public List parseContent(String content)
// {
// Iterator lineIterator = Arrays.asList(content.split(System.lineSeparator())).iterator();
// return parseContent(lineIterator)
// .entrySet()
// .stream()
// .flatMap(e -> e.getValue().stream().map(v -> e.getKey().name() + ":" + v))
// .collect(Collectors.toList());
// }
/** Parse unfolded content line iterator into calendar object */
//// @Override
// public Map> parseContent(Iterator unfoldedLineIterator)
// {
// boolean useResourceStatus = false;
// return parseContent(unfoldedLineIterator, useResourceStatus);
// }
// /** Parse unfolded content lines into calendar object */
// public List parseContent(Iterator lineIterator, boolean collectErrorMessages)
// {
// List vCalendarMessages = new ArrayList<>();
// List messages = new ArrayList<>();
// String firstLine = lineIterator.next();
// if (! firstLine.equals("BEGIN:VCALENDAR"))
// {
// throw new IllegalArgumentException("Content lines must begin with BEGIN:VCALENDAR");
// }
// // wrap lineIterator in UnfoldingStringIterator decorator
//// int line = 0;
// UnfoldingStringIterator unfoldedLineIterator = new UnfoldingStringIterator(lineIterator);
// while (unfoldedLineIterator.hasNext())
// {
// String unfoldedLine = unfoldedLineIterator.next();
//// System.out.println("unfoldedLine:" + unfoldedLine);
//// if (line++ > 20000) System.exit(0);
// int nameEndIndex = ICalendarUtilities.getPropertyNameIndex(unfoldedLine);
// String propertyName = (nameEndIndex > 0) ? unfoldedLine.substring(0, nameEndIndex) : "";
//
// // Parse component
// if (propertyName.equals("BEGIN"))
// {
// String componentName = unfoldedLine.substring(nameEndIndex+1);
//// System.out.println(componentName);
// VComponentBase newComponent = (VComponentBase) SimpleVComponentFactory.emptyVComponent(componentName);
//// Map> newComponentMessages = newComponent.parseContent(unfoldedLineIterator, collectErrorMessages);
// List newComponentMessages = newComponent.parseContent(unfoldedLineIterator);
// // TODO - USE ELEMENTS STATICS
// addChild(newComponent);
//// addVComponent(newComponent);
//// System.out.println(childrenUnmodifiable().size());
// messages.addAll(newComponentMessages);
//
//
//// String componentName = unfoldedLine.substring(nameEndIndex+1);
//// VComponent newComponent = SimpleVComponentFactory.emptyVComponent(componentName);
//// // TODO - USE ADD CHILD
//// System.out.println("new component");
//// Map> newComponentMessages = newComponent.parseContent(unfoldedLineIterator, collectErrorMessages);
////// addChild(newComponent);
//// addVComponent(newComponent);
//// messageMap.putAll(newComponentMessages);
// } else if (propertyName.equals("END"))
// {
// break;
// } else
// { // parse calendar property
// VChild child = null;
// CalendarProperty elementType = CalendarProperty.enumFromName(propertyName);
// if (elementType != null)
// {
// child = elementType.parse(this, unfoldedLine);
// } else if (unfoldedLine.contains(":"))
// {
// //non-standard - check for X- prefix
// boolean isNonStandard = propertyName.substring(0, PropertyType.NON_STANDARD.toString().length()).equals(PropertyType.NON_STANDARD.toString());
// if (isNonStandard)
// {
// child = NonStandardProperty.parse(unfoldedLine);
// addChild(child);
// } else
// {
// // ignore unknown properties
// vCalendarMessages.add("Unknown property is ignored:" + unfoldedLine);
// }
// } else
// {
// vCalendarMessages.add("Unknown line is ignored:" + unfoldedLine);
// }
// if (child != null)
// {
// vCalendarMessages.addAll(child.errors());
//// addChild(child); // TODO - USE WHEN NO USING ENUM PARSE ANYMORE.
// }
// }
// }
// // TODO - Log status messages if not using RequestStatus
//// messageMap.put(this, vCalendarMessages);
// return messages;
// }
// // multi threaded
// /** Parse content lines into calendar object */
// // TODO - TEST THIS - MAY NOT MAINTAIN ORDER
// // TODO - FIX THIS - DOESN'T WORK, DOESN'T GET CALENDARY PROPERTIES
// public void parseContentMulti(Iterator lineIterator)
// {
// // Callables to generate components
// ExecutorService service = Executors.newWorkStealingPool();
//// Map> taskMap = new LinkedHashMap<>();
// Integer order = 0;
// List> tasks = new ArrayList<>();
//
// String firstLine = lineIterator.next();
// if (! firstLine.equals("BEGIN:VCALENDAR"))
// {
// throw new IllegalArgumentException("Content lines must begin with BEGIN:VCALENDAR");
// }
// while (lineIterator.hasNext())
// {
// String line = lineIterator.next();
// int nameEndIndex = ICalendarUtilities.getPropertyNameIndex(line);
// String propertyName = line.substring(0, nameEndIndex);
//
// // Parse component
// if (propertyName.equals("BEGIN"))
// {
// String componentName = line.substring(nameEndIndex+1);
// List myLines = new ArrayList<>(20);
// myLines.add(line);
// final String endLine = "END:" + componentName;
// while (lineIterator.hasNext())
// {
// String myLine = lineIterator.next();
// myLines.add(myLine);
// if (myLine.equals(endLine))
// {
// Integer myOrder = order;
// order += 100;
// Runnable vComponentRunnable = () ->
// {
// CalendarComponent elementType = CalendarComponent.valueOf(componentName);
// VElement component = elementType.parse(this, myLines);
//// orderer().elementSortOrderMap().put((VChild) component, myOrder);
// };
//// taskMap.put(order, Executors.callable(vComponentRunnable));
// tasks.add(Executors.callable(vComponentRunnable));
// break;
// }
// }
//
// // parse calendar properties (ignores unknown properties)
// } else
// {
// CalendarComponent elementType = CalendarComponent.enumFromName(propertyName);
// if (elementType != null)
// {
// VElement property = elementType.parse(this, Arrays.asList(line));
//// orderer().elementSortOrderMap().put((VChild) property, order);
//// order += 100;
// }
// }
// }
//
// try
// {
//// List> tasks = taskMap.entrySet().stream().map(e -> e.getValue()).collect(Collectors.toList());
// service.invokeAll(tasks);
// } catch (InterruptedException e)
// {
// e.printStackTrace();
// }
// }
public static VCalendar parse(Reader reader) throws IOException
{
BufferedReader br = new BufferedReader(reader);
Iterator unfoldedLineIterator = new UnfoldingStringIterator(br.lines().iterator());
// Iterator unfoldedLineIterator = br.lines().iterator();
// UnfoldingBufferedReader unfoldingReader = new UnfoldingBufferedReader(reader);
// Iterator unfoldedLineIterator = unfoldingReader.lines().iterator();
VCalendar vCalendar = new VCalendar();
vCalendar.parseContent(unfoldedLineIterator);
// unfoldingReader.close();
return vCalendar;
}
/**
* Creates a new VCalendar from an ics file
*
* @param icsFilePath path of ics file to parse
* @return Created VCalendar
* @throws IOException
*/
public static VCalendar parse(Path icsFilePath) throws IOException
{
return parse(Files.newBufferedReader(icsFilePath));
}
/**
* Creates a new VCalendar from an ics file
*
* @param icsFilePath path of ics file to parse
* @return Created VCalendar
* @throws IOException
*/
// TODO - REMOVE useResourceStatus
public static VCalendar parseICalendarFile(Path icsFilePath, boolean useResourceStatus) throws IOException
{
BufferedReader br = Files.newBufferedReader(icsFilePath);
List lines = br.lines().collect(Collectors.toList());
// Iterator unfoldedLines = ICalendarUtilities.unfoldLines(lines).iterator();
VCalendar vCalendar = new VCalendar();
// vCalendar.parseContent(lines.iterator(), useResourceStatus);
vCalendar.parseContent(lines.iterator());
return vCalendar;
}
/**
* Creates a new VCalendar from an ics file
*
* @param icsFilePath path of ics file to parse
* @return Created VCalendar
* @throws IOException
*/
// TODO - REMOVE useResourceStatus
public static VCalendar parseICalendarFile(Path icsFilePath) throws IOException
{
BufferedReader br = Files.newBufferedReader(icsFilePath);
List lines = br.lines().collect(Collectors.toList());
// Iterator unfoldedLines = ICalendarUtilities.unfoldLines(lines).iterator();
VCalendar vCalendar = new VCalendar();
vCalendar.parseContent(lines.iterator());
return vCalendar;
}
@Override
protected boolean isContentValid(String valueContent)
{
boolean isElementValid = super.isContentValid(valueContent);
if (! isElementValid) return false;
boolean isBeginPresent = valueContent.startsWith(FIRST_CONTENT_LINE);
if (! isBeginPresent) return false;
int lastLineIndex = valueContent.lastIndexOf(System.lineSeparator());
if (lastLineIndex == -1) return false;
boolean isEndPresent = valueContent
.substring(lastLineIndex)
.equals(LAST_CONTENT_LINE);
return ! isEndPresent;
}
/**
* Creates a new VCalendar calendar component by parsing a String of iCalendar content lines
*
* @param content the text to parse, not null
* @return the parsed VCalendar
*/
public static VCalendar parse(String content)
{
return VCalendar.parse(new VCalendar(), content);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy