org.richfaces.fragment.calendar.RichFacesCalendar Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.fragment.calendar;
import org.jboss.arquillian.graphene.Graphene;
import org.jboss.arquillian.graphene.findby.ByJQuery;
import org.jboss.arquillian.graphene.fragment.Root;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.openqa.selenium.WebElement;
import org.richfaces.fragment.common.AdvancedInteractions;
import org.richfaces.fragment.common.TextInputComponent;
import org.richfaces.fragment.common.Utils;
import org.richfaces.fragment.configuration.RichFacesPageFragmentsConfiguration;
import org.richfaces.fragment.configuration.RichFacesPageFragmentsConfigurationContext;
import com.google.common.base.Optional;
/**
*
* @author Jiri Stefek
*/
public class RichFacesCalendar implements Calendar, AdvancedInteractions {
@Root
private WebElement root;
private final AdvancedCalendarInteractions interactions = new AdvancedCalendarInteractions();
private final RichFacesPageFragmentsConfiguration configuration = RichFacesPageFragmentsConfigurationContext
.getProxy();
private Calendar strategy = configuration.isUseJSInteractionStrategy() ? new CalendarJavaScriptStrategy() : new CalendarInteractiveStrategy();
@Override
public AdvancedCalendarInteractions advanced() {
return interactions;
}
@Override
public DateTime getDate() {
return strategy.getDate();
}
@Override
public void setDate(DateTime d) {
strategy.setDate(d);
}
/**
* Slower strategy for setting date using fragments advanced API.
*/
private class CalendarInteractiveStrategy implements Calendar {
@Override
public DateTime getDate() {
TextInputComponent input;
if (advanced().isPopup()) {
input = advanced().getPopupCalendar().getInput();
} else {
input = advanced().getInlineCalendar().getInput();
}
return advanced().getDatePattern().parseDateTime(input.getStringValue());
}
@Override
public void setDate(DateTime d) {
if (advanced().isPopup()) {
advanced().getPopupCalendar().setDateTime(d);
} else {
advanced().getInlineCalendar().setDateTime(d);
}
}
}
/**
* Fastest strategy. Sets/gets value by JS API.
*/
private class CalendarJavaScriptStrategy implements Calendar {
@Override
public DateTime getDate() {
return DateTime.parse(Utils.invokeRichFacesJSAPIFunction(advanced().getRootElement(), "getValueAsString()"), advanced().getDatePattern());
}
@Override
public void setDate(DateTime d) {
Utils.invokeRichFacesJSAPIFunction(advanced().getRootElement(), "setValue(new Date(" + d.getMillis() + "))");
}
}
public class AdvancedCalendarInteractions {
private static final String DATE_PATTERN_DEFAULT = "MMM d , yyyy";
private String datePattern;
public WebElement getRootElement() {
return root;
}
private DateTimeFormatter getDatePattern() {
return DateTimeFormat.forPattern(Optional.fromNullable(datePattern).or(DATE_PATTERN_DEFAULT));
}
public RichFacesAdvancedInlineCalendar getInlineCalendar() {
if (!isPopup()) {
return Graphene.createPageFragment(RichFacesAdvancedInlineCalendar.class, advanced().getRootElement());
}
throw new RuntimeException("This is a popup calendar. Cannot get its inline version.");
}
public RichFacesAdvancedPopupCalendar getPopupCalendar() {
if (isPopup()) {
return Graphene.createPageFragment(RichFacesAdvancedPopupCalendar.class, advanced().getRootElement());
}
throw new RuntimeException("This is an inline calendar. Cannot get its popup version.");
}
private boolean isPopup() {
return Utils.isVisible(advanced().getRootElement(), ByJQuery.selector("span[id$='Popup']"));
}
public void setDatePattern(String datePattern) {
this.datePattern = datePattern;
}
/**
* Set the interactive strategy for setting of date. The getting of date uses JS API of component. The strategy uses
* advanced API of this fragment.
*/
public void setInteractiveStrategy() {
strategy = new CalendarInteractiveStrategy();
}
/**
* Sets the much faster strategy for setting and getting of date. Default value. The strategy uses JS API of the
* component.
*/
public void setJavaScriptStrategy() {
strategy = new CalendarJavaScriptStrategy();
}
}
}