Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed the issues with #163 #164

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ public Set<CalendarDisplayEvent> getEvents(
CalendarConfiguration calendar,
Interval interval,
PortletRequest request,
DateTimeZone usersConfiguredDateTimeZone) {
DateTimeZone usersConfiguredDateTimeZone,
int calendarIndex) {

// Get the set of calendar events for the requested period.
// We invoke the adapter before checking cache because we expect the adapter
Expand Down Expand Up @@ -159,7 +160,7 @@ public Set<CalendarDisplayEvent> getEvents(
for (VEvent event : eventSet.getEvents()) {
try {
displayEvents.addAll(
getDisplayEvents(event, interval, request.getLocale(), usersConfiguredDateTimeZone));
getDisplayEvents(event, interval, request.getLocale(), usersConfiguredDateTimeZone, calendarIndex));
} catch (ParseException e) {
log.error("Exception parsing event", e);
} catch (IOException e) {
Expand Down Expand Up @@ -214,7 +215,7 @@ public Set<CalendarDisplayEvent> getEvents(
* @throws ParseException
*/
protected Set<CalendarDisplayEvent> getDisplayEvents(
VEvent e, Interval interval, Locale locale, DateTimeZone usersConfiguredDateTimeZone)
VEvent e, Interval interval, Locale locale, DateTimeZone usersConfiguredDateTimeZone, int calendarIndex)
throws IOException, URISyntaxException, ParseException {

final VEvent event = (VEvent) e.copy();
Expand Down Expand Up @@ -280,7 +281,7 @@ protected Set<CalendarDisplayEvent> getDisplayEvents(
*/
if (theSpecificDay.getStart().isEqual(eventStart) || theSpecificDay.overlaps(eventInterval)) {
final CalendarDisplayEvent json =
new CalendarDisplayEvent(event, eventInterval, theSpecificDay, df, tf);
new CalendarDisplayEvent(event, eventInterval, theSpecificDay, df, tf, calendarIndex);
events.add(json);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.util.Set;
import javax.portlet.PortletRequest;
import net.fortuna.ical4j.model.component.VEvent;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
Expand All @@ -37,6 +39,7 @@
import org.apache.commons.io.input.BOMInputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.params.CoreConnectionPNames;
import org.jasig.portlet.calendar.CalendarConfiguration;
import org.jasig.portlet.calendar.caching.DefaultCacheKeyGeneratorImpl;
import org.jasig.portlet.calendar.caching.ICacheKeyGenerator;
Expand Down Expand Up @@ -260,22 +263,131 @@ protected String getIntervalSpecificCacheKey(String baseKey, Interval interval)
protected InputStream retrieveCalendarHttp(String url, Credentials credentials)
throws CalendarException {

final int TIMEOUT_MS = 3 * 1000;
final HttpClient client = new HttpClient();

//fixing where broken https links never connect. just keeps retrying.
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, TIMEOUT_MS );
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, TIMEOUT_MS);
client.getParams().setParameter("http.connection-manager.timeout", new Long(TIMEOUT_MS));

if (null != credentials) {
client.getState().setCredentials(AuthScope.ANY, credentials);
}
GetMethod get = null;

try {
if(url.contains("webcal://")){
return tryWebcalHttps(get,url,client);
}else{
return tryHttp(get,url,client);
}
}

if (log.isDebugEnabled()) {
log.debug("Retrieving calendar " + url);
protected InputStream tryHttp(GetMethod get, String url, HttpClient client) throws CalendarException{
try {
if (log.isDebugEnabled()) {
log.debug("Retrieving calendar " + url);
}

get = new GetMethod(url);
final int rc = client.executeMethod(get);
if (rc == HttpStatus.SC_OK) {
// return the response body
return getCalendarResponse(get);
} else {
log.warn("HttpStatus for " + url + ": " + rc);
throw new CalendarException(
"Non-successful status code retrieving url '" + url + "'; status code: " + rc);
}
} catch(ConnectTimeoutException e) {
log.warn("Error fetching iCalendar feed for "+ url, e);
throw new CalendarException("Error fetching iCalendar feed for "+ url, e);
} catch(SocketTimeoutException e){
log.warn("Error fetching iCalendar feed for "+ url, e);
throw new CalendarException("Error fetching iCalendar feed for "+ url, e);
} catch (HttpException e) {
log.warn("Error fetching iCalendar feed for "+ url, e);
throw new CalendarException("Error fetching iCalendar feed for "+ url, e);
} catch (IOException e) {
log.warn("Error fetching iCalendar feed for "+ url, e);
throw new CalendarException("Error fetching iCalendar feed for "+ url, e);
} finally {
if (get != null) {
get.releaseConnection();
}
}
}

protected InputStream tryWebcalHttps(GetMethod get, String url, HttpClient client) throws CalendarException{
try {

if (log.isDebugEnabled()) {
log.debug("Retrieving calendar " + url);
}

get = new GetMethod(url);
final int rc = client.executeMethod(get);
if (rc == HttpStatus.SC_OK) {
// return the response body
get = new GetMethod(url.replace("webcal://","https://"));
final int rc = client.executeMethod(get);
if (rc == HttpStatus.SC_OK) {
// return the response body
return getCalendarResponse(get);
} else {
log.warn("HttpStatus for https replacement of " + url + ": " + rc+". Trying http.");
get.releaseConnection();

return tryWebcalHttp(get, url, client);
}
} catch(ConnectTimeoutException e) {
log.warn("Timed out trying to connect to https replacement of "+ url +". Trying http.");
get.releaseConnection();
return tryWebcalHttp(get, url, client);
} catch(SocketTimeoutException e){
log.warn("Timed out between fetches to http replacement of "+ url +". Trying http.");
get.releaseConnection();
return tryWebcalHttp(get, url, client);
}catch (HttpException e) {
log.warn("Error fetching iCalendar feed for "+ url, e);
throw new CalendarException("Error fetching iCalendar feed for "+ url, e);
} catch (IOException e) {
log.warn("Error fetching iCalendar feed", e);
throw new CalendarException("Error fetching iCalendar feed for "+ url, e);
} finally {
if (get != null) {
get.releaseConnection();
}
}
}



protected InputStream tryWebcalHttp(GetMethod get, String url, HttpClient client) throws CalendarException{
try{
get = new GetMethod(url.replace("webcal://","http://"));
final int rc1 = client.executeMethod(get);
if (rc1 == HttpStatus.SC_OK) {
return getCalendarResponse(get);
} else {
log.warn("HttpStatus for http replacement of " + url + ": " + rc1+". Link appears dead, throwing error.");
throw new CalendarException(
"Non-successful status code retrieving url '" + url + "'; status code: " + rc1);
}
}catch(ConnectTimeoutException ee){
log.warn("Timed out trying to connect to http replacement of "+ url +". Link appears dead, throwing error.", ee);
throw new CalendarException("Error fetching iCalendar feed for "+ url, ee);
}catch(SocketTimeoutException ee){
log.warn("Timed out between fetches to http replacement of "+ url +". Link appears dead, throwing error.", ee);
throw new CalendarException("Error fetching iCalendar feed for "+ url, ee);
}catch (HttpException ee) {
log.warn("Error fetching iCalendar feed", ee);
throw new CalendarException("Error fetching iCalendar feed for "+ url, ee);
} catch (IOException ee) {
log.warn("Error fetching iCalendar feed", ee);
throw new CalendarException("Error fetching iCalendar feed for "+ url, ee);
} finally {
get.releaseConnection();
}
}

protected InputStream getCalendarResponse(GetMethod get) throws IOException{
log.debug("request completed successfully");
final InputStream responseBody = get.getResponseBodyAsStream();

Expand All @@ -289,21 +401,5 @@ protected InputStream retrieveCalendarHttp(String url, Credentials credentials)
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
IOUtils.copyLarge(bomIn, buffer);
return new ByteArrayInputStream(buffer.toByteArray());
} else {
log.warn("HttpStatus for " + url + ": " + rc);
throw new CalendarException(
"Non-successful status code retrieving url '" + url + "'; status code: " + rc);
}
} catch (HttpException e) {
log.warn("Error fetching iCalendar feed", e);
throw new CalendarException("Error fetching iCalendar feed", e);
} catch (IOException e) {
log.warn("Error fetching iCalendar feed", e);
throw new CalendarException("Error fetching iCalendar feed", e);
} finally {
if (get != null) {
get.releaseConnection();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public class CalendarDisplayEvent implements Comparable<CalendarDisplayEvent> {
private final String startDate;
private final String endDate;

private final int calendarIndex;

/**
* Constructs an object from specified data.
*
Expand All @@ -66,14 +68,17 @@ public CalendarDisplayEvent(
Interval eventInterval,
Interval theSpecificDay,
DateTimeFormatter df,
DateTimeFormatter tf) {
DateTimeFormatter tf,
int calendarIndex) {
assert theSpecificDay.abuts(eventInterval) || theSpecificDay.overlaps(eventInterval)
: "Event interval is not in the specified day!";

this.summary = event.getSummary() != null ? event.getSummary().getValue() : null;
this.description = event.getDescription() != null ? event.getDescription().getValue() : null;
this.location = event.getLocation() != null ? event.getLocation().getValue() : null;

this.calendarIndex = calendarIndex;

boolean multi = false;
if (eventInterval.getStart().isBefore(theSpecificDay.getStart())) {
dayStart = theSpecificDay.getStart();
Expand Down Expand Up @@ -162,6 +167,8 @@ public DateTime getDayEnd() {
return this.dayEnd;
}

public int getCalendarIndex(){ return this.calendarIndex; }

public int compareTo(CalendarDisplayEvent event) {
// Order events by start date, then end date, then summary.
// If all properties are equal, use the calendar and event ids to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public Set<CalendarDisplayEvent> getEventList(
DateTimeZone tz = DateTimeZone.forID(timezone);
Set<CalendarDisplayEvent> events = new TreeSet<CalendarDisplayEvent>();

int calendarIndex=0; //to keep the color of the calendar consistent with the order in the main controller
for (CalendarConfiguration callisting : calendars) {
// don't bother to fetch hidden calendars
if (hiddenCalendars.get(callisting.getId()) == null) {
Expand All @@ -105,7 +106,7 @@ public Set<CalendarDisplayEvent> getEventList(
ICalendarAdapter adapter =
(ICalendarAdapter)
applicationContext.getBean(callisting.getCalendarDefinition().getClassName());
events.addAll(calendarEventsDao.getEvents(adapter, callisting, interval, request, tz));
events.addAll(calendarEventsDao.getEvents(adapter, callisting, interval, request, tz, calendarIndex));
} catch (NoSuchBeanDefinitionException ex) {
log.error("Calendar class instance could not be found: " + ex.getMessage());
} catch (UserFeedbackCalendarException sce) {
Expand All @@ -123,6 +124,7 @@ public Set<CalendarDisplayEvent> getEventList(
+ "\" is currently unavailable.");
}
}
calendarIndex++;
}
return events;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ public ModelAndView getEventList(ResourceRequest request, ResourceResponse respo

final Set<CalendarDisplayEvent> calendarEvents = helper.getEventList(errors, interval, request);

int index = 0;

final Set<JsonCalendarEventWrapper> events = new TreeSet<JsonCalendarEventWrapper>();
for (CalendarDisplayEvent e : calendarEvents) {
events.add(new JsonCalendarEventWrapper(e, index++));
events.add(new JsonCalendarEventWrapper(e, e.getCalendarIndex()));
}

/*
Expand Down
Loading