-
-
Notifications
You must be signed in to change notification settings - Fork 200
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #296 from ical4j/feature/refactor-transforms
Feature/refactor transforms
- Loading branch information
Showing
16 changed files
with
175 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
src/main/java/net/fortuna/ical4j/transform/Rfc5545Transformer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package net.fortuna.ical4j.transform; | ||
|
||
import net.fortuna.ical4j.model.*; | ||
import net.fortuna.ical4j.transform.rfc5545.RuleManager; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.util.List; | ||
|
||
public class Rfc5545Transformer implements Transformer<Calendar> { | ||
|
||
@Override | ||
public Calendar transform(Calendar object) { | ||
|
||
conformPropertiesToRfc5545(object.getProperties()); | ||
|
||
for(Component component : object.getComponents()){ | ||
CountableProperties.removeExceededPropertiesForComponent(component); | ||
|
||
//each component | ||
conformComponentToRfc5545(component); | ||
|
||
//each component property | ||
conformPropertiesToRfc5545(component.getProperties()); | ||
|
||
for(java.lang.reflect.Method m : component.getClass().getDeclaredMethods()){ | ||
if(ComponentList.class.isAssignableFrom(m.getReturnType()) && | ||
m.getName().startsWith("get")){ | ||
|
||
try { | ||
List<Component> components = (List<Component>) m.invoke(component); | ||
for(Component c : components){ | ||
//each inner component | ||
conformComponentToRfc5545(c); | ||
|
||
//each inner component properties | ||
conformPropertiesToRfc5545(c.getProperties()); | ||
} | ||
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} | ||
} | ||
return object; | ||
} | ||
|
||
private static void conformPropertiesToRfc5545(List<Property> properties) { | ||
for (Property property : properties) { | ||
RuleManager.applyTo(property); | ||
} | ||
} | ||
|
||
private static void conformComponentToRfc5545(Component component){ | ||
RuleManager.applyTo(component); | ||
} | ||
|
||
private enum CountableProperties{ | ||
STATUS(Property.STATUS, 1); | ||
private int maxApparitionNumber; | ||
private String name; | ||
|
||
CountableProperties(String name, int maxApparitionNumber){ | ||
this.maxApparitionNumber = maxApparitionNumber; | ||
this.name = name; | ||
} | ||
|
||
protected void limitApparitionsNumberIn(Component component){ | ||
PropertyList<? extends Property> propertyList = component.getProperties(name); | ||
|
||
if(propertyList.size() <= maxApparitionNumber){ | ||
return; | ||
} | ||
int toRemove = propertyList.size() - maxApparitionNumber; | ||
for(int i = 0; i < toRemove; i++){ | ||
component.getProperties().remove(propertyList.get(i)); } | ||
} | ||
|
||
private static void removeExceededPropertiesForComponent(Component component){ | ||
for(CountableProperties cp: values()){ | ||
cp.limitApparitionsNumberIn(component); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
src/test/java/net/fortuna/ical4j/transform/Rfc5545TransformerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package net.fortuna.ical4j.transform; | ||
|
||
import net.fortuna.ical4j.data.CalendarBuilder; | ||
import net.fortuna.ical4j.data.ParserException; | ||
import net.fortuna.ical4j.model.Calendar; | ||
import net.fortuna.ical4j.validate.ValidationException; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.lang.reflect.InvocationTargetException; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.fail; | ||
|
||
public class Rfc5545TransformerTest { | ||
|
||
private Rfc5545Transformer transformer; | ||
|
||
@Before | ||
public void setUp() { | ||
transformer = new Rfc5545Transformer(); | ||
} | ||
|
||
@Test | ||
public void shouldCorrectCalendarBody() throws IOException, ParserException, IllegalAccessException, | ||
IllegalArgumentException, InvocationTargetException { | ||
|
||
String[] calendarNames = { "yahoo1.txt", "yahoo2.txt", "outlook1.txt", "outlook2.txt", "apple.txt" }; | ||
for (String calendarName : calendarNames) { | ||
Calendar calendar = buildCalendar(calendarName); | ||
calendar = transformer.transform(calendar); | ||
try { | ||
calendar.validate(); | ||
} catch (ValidationException e) { | ||
e.printStackTrace(); | ||
fail("Validation failed for " + calendarName); | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldCorrectMsSpecificTimeZones() throws IOException, ParserException, IllegalAccessException, | ||
IllegalArgumentException, InvocationTargetException { | ||
String actuals[] = { "timezones/outlook1.txt", "timezones/outlook2.txt" }; | ||
String expecteds[] = { "timezones/outlook1_expected.txt", "timezones/outlook2_expected.txt" }; | ||
|
||
for (int i = 0; i < actuals.length; i++) { | ||
Calendar actual = buildCalendar(actuals[i]); | ||
actual = transformer.transform(actual); | ||
Calendar expected = buildCalendar(expecteds[i]); | ||
assertEquals("on from " + expecteds[i] + " and " + actuals[i] + " failed.", expected, actual); | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldCorrectDTStampByAddingUTCTimezone() { | ||
String calendarName = "dtstamp/invalid.txt"; | ||
try { | ||
Calendar actual = buildCalendar(calendarName); | ||
actual = transformer.transform(actual); | ||
} catch (RuntimeException | IOException | ParserException e) { | ||
e.printStackTrace(); | ||
fail("RFC transformation failed for " + calendarName); | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldSetTimezoneToUtcForNoTZdescription() { | ||
String actualCalendar = "outlook/TZ-no-description.txt"; | ||
try { | ||
Calendar actual = buildCalendar(actualCalendar); | ||
actual = transformer.transform(actual); | ||
Calendar expected = buildCalendar("outlook/TZ-set-to-utc.txt"); | ||
assertEquals(expected.toString(), actual.toString()); | ||
assertEquals(expected, actual); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
fail("RFC transformation failed for " + actualCalendar); | ||
} | ||
} | ||
|
||
private Calendar buildCalendar(String file) throws IOException, ParserException { | ||
InputStream is = getClass().getResourceAsStream(file); | ||
CalendarBuilder cb = new CalendarBuilder(); | ||
Calendar calendar = cb.build(is); | ||
is.close(); | ||
return calendar; | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.