diff --git a/rules-reviewed/eap6/java-ee/seam/seam-java.windup.xml b/rules-reviewed/eap6/java-ee/seam/seam-java.windup.xml new file mode 100644 index 000000000..7800a1eb9 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/seam-java.windup.xml @@ -0,0 +1,615 @@ + + + + + + This ruleset provides generic migration knowledge from the Seam 2 API to pure Java EE/CDI API. + + + + + + + + + + + + + + + + + + + Seam 2.2 and earlier is not supported on JBoss EAP 6 and above. + Consider migration to Context Dependency Injection (CDI) standard which covers most of Seam 2 core functionalities in + a standardized, type safe and extensible way. + + Seam 2.3 still could work on EAP 6.x, but is not maintained and officially supported on new EAP 6.x patched releases or EAP 7.x. + + There are two options available: + + 1. Continue using Seam 2.x on EAP 6 but expect there are bugs or glitches and you need to fix it yourself. + This approach is sometimes lower effort but the application will not use a tested and supported library and some Seam framework features doesn't have to work as expected. + 2. The similar approach as for point 1 but for Seam 2.3 runtime on EAP7 is not verified and therefore not recommended. Some Seam 2.3 features could work on EAP7, + but the expected behavior can differ based on what your application uses and how. + 2. Switch to standard CDI beans and migrate to JSF 2.2 if your server platform is EAP 7+. This will require significant migration effort. + + + + + + + + + cdi + seam + jsf + + + + + + + + + + + You can use Java EE `javax.enterprise.context.Conversation` interface like: + + ```java + @Inject Conversation conversation; + ``` + + + seam + cdi + + + + + + + + + + + + + + + + + + + + + + + + + + METHOD_CALL + + + + + There is no direct replacement for this Seam API. The `org.jboss.seam.Seam` contains methods for accessing annotated information + about Seam component classes. For majority cases you can replace this Seam API with standard CDI's `javax.enterprise.inject.spi.BeanManager`. + + + seam + cdi + + + + + + + ANNOTATION + + + + + CDI supports static injection in comparison to Seam 2 dynamic injection. So you don't need to have `@Named` annotation on every Seam component you would like to migrate. + Remove that annotation or change to `@javax.inject.Named` only if you need to access managed bean in Expression Language (EL). + + + seam + cdi + + + + + + + ANNOTATION + + + + + Convert to a valid CDI scope. CDI scopes has its own annotation. + See linked documentation link for CDI alternatives. For example, `@Scope(ScopeType.SESSION)` should be `@javax.enterprise.context.SessionScoped`. + + + + seam + cdi + + + + + + + ANNOTATION + + + + + Convert Seam annotation `@In` to CDI `@javax.inject.Inject`. + + seam + cdi + + + + + + + ANNOTATION + + + + + Remove this Seam annotation `@AutoCreate` as in CDI it is no longer needed since a bean will always be created when needed. + + seam + cdi + + + + + + + ANNOTATION + + + + + + CDI does not support bijection and does a static injection in comparison to Seam 2, where it is performed dynamically + via interceptor every time a component is invoked. + CDI performs the static injection only once per component life cycle. + + Refactor such Seam API usage with `@javax.enterprise.inject.Produces`. + + + + + + seam + cdi + + + + + + + ANNOTATION + + + + + + Seam Factory annotation was used for binding non Seam component methods into Seam context life cycle. + + Replace it with `@javax.enterprise.inject.Produces` and add additional annotation for context scope if you used `scope = ScopeType.*` enum like for instance + `@Factory(scope = ScopeType.APPLICATION)` use: + + ```java + @Produces @ApplicationScoped ... + ``` + + + + + + seam + cdi + + + + + + + ANNOTATION + + + + + Java EE uses for such use case `@javax.ejb.Singleton` and `@javax.ejb.Startup` annotations. + + + + seam + + + + + + + ANNOTATION + + + + + Seam 2 provided along to standard Java EE `javax.annotation.PostConstruct` also Seam specific annotation `@Create`. + You can use `@javax.annotation.PostConstruct` as one to one replacement. + + seam + javaee + + + + + + + ANNOTATION + + + + + Seam 2 provided along to standard Java EE `javax.annotation.PreDestroy` also Seam specific annotation `@Destroy`. + You can use `@javax.annotation.PreDestroy` as one to one replacement. + + seam + javaee + + + + + + + + + + There is no direct replacement, but it can be implemented with CDI Conversation support. + + seam + cdi + conversation + + + + + + + METHOD_CALL + + + + + paymentProcessor; + ``` + + The second approach is to use `javax.enterprise.inject.spi.BeanManager` like + + ```java + @Inject BeanManager manager; + ``` + ]]> + + + + seam + cdi + + + + + + + ANNOTATION + + + + + Refactor to have annotated error handler which redirect to a viewID page for displaying error page. + seam + + + + + + + ANNOTATION + + + + + Seam 2 offers the `@Install` annotation for controlling whether a given bean should be installed or not together with configurable functionality. + Explicit prevention from installation is in CDI done by `@Vetoed` annotation. + If you need to use Bean specialization there are `@javax.enterprise.inject.Alternative` or `@javax.enterprise.inject.Specializes` instead of precedence. + + + + + seam + cdi + + + + + + + + + + Rework code with a default Java Servlet `javax.servlet.Filter` or different filter interface. + + seam + javaee + + + + + + + ANNOTATION + + + + + Replace this Seam annotation with default Java Servlet `javax.servlet.Filter` or different filter interface. + + seam + javaee + servlet + + + + + + + METHOD_CALL + + + + + Rework using CDI's injected concrete context. + + seam + + + + + + + ANNOTATION + + + + + Seam integration with jBPM should be migrated with help of CDI integration presented directly in Drools - jBPM + + cdi + seam + jbpm + + + + + + + + + + Rework with CDI conversation context `javax.enterprise.context.Conversation`. + + seam + cdi + + + + + + + ANNOTATION + + + + + Rework with `javax.enterprise.context.Conversation.begin()`. + + cdi + seam + + + + + + + ANNOTATION + + + + + Rework with `javax.enterprise.context.Conversation.end()`. + + cdi + seam + + + + + + + ANNOTATION + + + + + + The `@RequestParameter` annotation triggers injection of an HTTP request parameter. + The parameter name can be set explicitly as a value of the annotation or can be implied from the name of an injection point. + + Java EE 6 does not have an annotation for this, however, the JSF 2 spec now has `<f:viewParam />` which can be used instead. + + + seam + jsf + + + + + + + ANNOTATION + + + + + + Seam 2 provides a built-in logger implementation. It is a thin wrapper that delegates to an available logging framework (log4j or JDK logging). + Additionally, it provides extra features such as EL expression evaluation. + + Java SE or EE does not have anything that correlates to this, but you can your own Logger with simple producer for this case like: + + ```java + import javax.enterprise.inject.Produces; + import javax.enterprise.inject.spi.InjectionPoint; + + @Singleton + public class LoggerProducer { + + @Produces Logger createLogger(final InjectionPoint ip){ + return LoggerFactory.getLogger(ip.getMember().getDeclaringClass()); + } + + } + ``` + + and use it in your code like: + + ```java + @Inject private transient Logger logger; + ``` + + + + seam + cdi + + + + + + + ANNOTATION + + + + + In Java EE, the Expression Language Specification has evolved and allows parameters to be passed to EL method expressions. + This approach should be used as a replacement for the `@DataModel*` functionality. + + + + seam + jsf + + + + + + + + ANNOTATION + + + METHOD_CALL + + + + + + + Both Seam 2 and CDI beans may produce and consume events in order to communicate with other beans. Unlike method invocation, events allow for decoupled architecture with no compile-time dependency. + + In Seam 2, the type of an event is represented by a string value. Observer methods may observe one or more event types. + + Unlike Seam 2, the process of observer method resolution is type-safe in CDI. A CDI event is represented by a payload (any Java object) and a set of qualifiers. The Java types of the event payload together with qualifiers determine which observer methods are notified of the event + + + + seam + cdi + + + + + + + ANNOTATION + + + + + + In the Java EE, the concept of interceptors was extracted into a separate specification. As a result, not only EJBs but any CDI managed beans can benefit from this facility. + + If you used interceptors in Seam 2, migration is straightforward. The names and semantics of most of the annotations remain unchanged. If you used meta-annotations to bind interceptors to your beans in Seam 2, this idea (slightly modified) made it into the specification and is now know as an Interceptor binding. + + + + seam + javaee + + + + + + + ANNOTATION + + + + + Replace with Java EE annotation `@javax.ejb.Asynchronous`. + + seam + javaee + + + + + + + ANNOTATION + + + + + Replace with Java EE annotation `@javax.transaction.Transactional`. The usage and transaction types are the same like in Seam API. + + seam + javaee + + + + + diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/ConversationTest.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/ConversationTest.java new file mode 100644 index 000000000..cbd6c99d8 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/ConversationTest.java @@ -0,0 +1,441 @@ +package org.jboss.seam.test.integration; + +import java.util.ArrayList; +import java.util.List; + +import javax.faces.model.SelectItem; + +import org.jboss.seam.core.ConversationEntries; +import org.jboss.seam.core.ConversationEntry; +import org.jboss.seam.core.Manager; +import org.jboss.seam.faces.Switcher; +import org.jboss.seam.mock.SeamTest; +import org.testng.annotations.Test; + +public class ConversationTest + extends SeamTest +{ + + @Test + public void conversationStack() + throws Exception + { + // no conversation, no stack + new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationStack}"); + assert entries.size() == 0; + } + }.run(); + + // no conversation, no stack + new FacesRequest("/pageWithoutDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationStack}"); + assert entries.size() == 0; + } + }.run(); + + // new conversation, stack = 1 + String rootId = new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationStack}"); + assert entries.size() == 1; + } + }.run(); + + // nested conversation, stack =2 + String nested1 = new FacesRequest("/pageWithDescription.xhtml", rootId) { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginNestedConversation(); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationStack}"); + assert entries.size() == 2; + } + + }.run(); + + // nested conversation without description, not added to stack + String nested2 = new FacesRequest("/pageWithoutDescription.xhtml", nested1) { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginNestedConversation(); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationStack}"); + assert entries.size() == 2; + } + }.run(); + + // access a page, now it's on the stack + new FacesRequest("/pageWithDescription.xhtml", nested2) { + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationStack}"); + assert entries.size() == 3; + } + }.run(); + + // end conversation, stack goes down + new FacesRequest("/pageWithDescription.xhtml", nested2) { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().endConversation(false); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationStack}"); + assert entries.size() == 2; + } + }.run(); + + // end another one, size is 1 + new FacesRequest("/pageWithDescription.xhtml", nested1) { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().endConversation(false); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationStack}"); + assert entries.size() == 1; + } + }.run(); + } + + @Test + public void conversationList() + throws Exception + { + new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationList}"); + assert entries.size() == 0; + } + }.run(); + + new FacesRequest("/pageWithoutDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationList}"); + assert entries.size() == 0; + } + }.run(); + + String conv1 = new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationList}"); + assert entries.size() == 1; + } + }.run(); + + String conv2 = new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationList}"); + assert entries.size() == 2; + } + }.run(); + + String conv3 = new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationList}"); + assert entries.size() == 3; + } + }.run(); + + + new FacesRequest("/pageWithDescription", conv2) { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().endConversation(true); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationList}"); + assert entries.size() == 2; + } + }.run(); + + new FacesRequest("/pageWithDescription", conv1) { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().endConversation(true); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationList}"); + assert entries.size() == 1; + } + }.run(); + + + new FacesRequest("/pageWithDescription", conv3) { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().endConversation(true); + } + + @Override + protected void renderResponse() throws Exception { + List entries = (List) getValue("#{conversationList}"); + assert entries.size() == 0; + } + }.run(); + } + + + @Test + public void switcher() + throws Exception + { + new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void renderResponse() throws Exception { + Switcher switcher = (Switcher) getValue("#{switcher}"); + assert switcher.getSelectItems().size() == 0; + assert switcher.getConversationIdOrOutcome() == null; + } + }.run(); + + + final String conv1 = new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception { + Switcher switcher = (Switcher) getValue("#{switcher}"); + assert switcher.getSelectItems().size() == 1; + } + }.run(); + + final String conv2 = new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception { + Switcher switcher = (Switcher) getValue("#{switcher}"); + assert switcher.getSelectItems().size() == 2; + } + }.run(); + + final String conv3 = new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception { + Switcher switcher = (Switcher) getValue("#{switcher}"); + assert switcher.getSelectItems().size() == 3; + } + }.run(); + + new FacesRequest() { + @Override + protected void renderResponse() throws Exception { + Switcher switcher = (Switcher) getValue("#{switcher}"); + assert switcher.getSelectItems().size() == 3; + + List items = switcher.getSelectItems(); + List values = new ArrayList(); + for (SelectItem item: items) { + assert item.getLabel().equals("page description"); + values.add((String) item.getValue()); + } + + assert values.contains(conv1); + assert values.contains(conv2); + assert values.contains(conv3); + } + }.run(); + + new FacesRequest("/pageWithDescription.xhtml", conv1) { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().endConversation(true); + } + }.run(); + + new FacesRequest("/pageWithDescription.xhtml", conv2) { + @Override + protected void invokeApplication() throws Exception { + Manager.instance().endConversation(true); + } + + @Override + protected void renderResponse() throws Exception { + Switcher switcher = (Switcher) getValue("#{switcher}"); + assert switcher.getSelectItems().size() == 1; + assert switcher.getSelectItems().get(0).getLabel().equals("page description"); + assert switcher.getSelectItems().get(0).getValue().equals(conv3); + } + }.run(); + + new FacesRequest("/pageWithAnotherDescription.xhtml", conv3) { + @Override + protected void renderResponse() throws Exception { + Switcher switcher = (Switcher) getValue("#{switcher}"); + assert switcher.getSelectItems().size() == 1; + + assert switcher.getSelectItems().get(0).getLabel().equals("another page description"); + assert switcher.getSelectItems().get(0).getValue().equals(conv3); + } + }.run(); + } + + @Test + public void killAllOthers() throws Exception + { + new FacesRequest("/pageWithAnotherDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception + { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception + { + assert ConversationEntries.instance().size() == 1; + } + }.run(); + + new FacesRequest("/pageWithoutDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception + { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception + { + assert ConversationEntries.instance().size() == 2; + } + }.run(); + + new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception + { + Manager.instance().beginConversation(); + Manager.instance().killAllOtherConversations(); + } + + @Override + protected void renderResponse() throws Exception + { + assert ConversationEntries.instance().size() == 1; + } + }.run(); + + } + + @Test + public void nestedKillAllOthers() throws Exception + { + + final String unrelated = new FacesRequest("/pageWithoutDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception + { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception + { + assert ConversationEntries.instance().size() == 1; + } + }.run(); + + String root = new FacesRequest("/pageWithDescription.xhtml") { + @Override + protected void invokeApplication() throws Exception + { + Manager.instance().beginConversation(); + } + + @Override + protected void renderResponse() throws Exception + { + assert ConversationEntries.instance().size() == 2; + } + }.run(); + + // nested conversation + new FacesRequest("/pageWithDescription.xhtml", root) { + @Override + protected void invokeApplication() throws Exception + { + Manager.instance().beginNestedConversation(); + } + + @Override + protected void renderResponse() throws Exception + { + assert ConversationEntries.instance().size() == 3; + + Manager.instance().killAllOtherConversations(); + assert ConversationEntries.instance().size() == 2; + assert ConversationEntries.instance().getConversationIds() + .contains(unrelated) == false; + } + + }.run(); + } +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/EntityKeyManager.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/EntityKeyManager.java new file mode 100644 index 000000000..44f8b00a7 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/EntityKeyManager.java @@ -0,0 +1,61 @@ +package org.jboss.seam.trinidad; + +import static org.jboss.seam.ScopeType.PAGE; +import static org.jboss.seam.annotations.Install.BUILT_IN; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; + +import org.jboss.seam.Component; +import org.jboss.seam.annotations.Install; +import org.jboss.seam.annotations.intercept.BypassInterceptors; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.Transactional; +import org.jboss.seam.core.AbstractMutable; +import org.jboss.seam.framework.EntityIdentifier; + +/** + * EntityIdentifier manager for EntityCollectionModel + * @author pmuir + * + */ + +@Name("org.jboss.seam.trinidad.entityKeyManager") +@Scope(PAGE) +@BypassInterceptors +@Install(precedence=BUILT_IN) +public class EntityKeyManager extends AbstractMutable +{ + + private List rows = new ArrayList(); + + public static EntityKeyManager instance() + { + return (EntityKeyManager) Component.getInstance(EntityKeyManager.class); + } + + @Transactional + public int getIndex(Integer key, List wrappedList, EntityManager entityManager) + { + Object entity = rows.get(key).find(entityManager); + int index = wrappedList.indexOf(entity); + return index; + } + + + @Transactional + public Object getKey(int rowIndex, List wrappedList, EntityManager entityManager) + { + EntityIdentifier key = new EntityIdentifier(wrappedList.get(rowIndex), entityManager); + if (!rows.contains(key)) + { + rows.add(key); + setDirty(); + } + return rows.indexOf(key); + } + +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/Game.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/Game.java new file mode 100644 index 000000000..8346ff40c --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/Game.java @@ -0,0 +1,42 @@ +package org.jboss.seam.example.poker; + +import java.util.ArrayList; +import java.util.List; + +import static org.jboss.seam.ScopeType.APPLICATION; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.Startup; +import org.jboss.seam.annotations.Create; + +/** + * The game. This is where everything happens. + * + * @author Shane Bryzak + */ +@Name("game") +@Scope(APPLICATION) +@Startup +public class Game +{ + private List players = new ArrayList(); + + @Create + public void createGame() + { + players.clear(); + } + + public synchronized boolean login(String playerName) + { + if (!players.contains(playerName)) + { + players.add(playerName); + return true; + } + else + return false; + } + + +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/HotelBookingAction.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/HotelBookingAction.java new file mode 100644 index 000000000..4e2b4e5a9 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/HotelBookingAction.java @@ -0,0 +1,110 @@ +//$Id: HotelBookingAction.java 5579 2007-06-27 00:06:49Z gavin $ +package org.jboss.seam.example.booking; + +import static javax.persistence.PersistenceContextType.EXTENDED; + +import java.util.Calendar; + +import javax.ejb.Remove; +import javax.ejb.Stateful; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.jboss.seam.annotations.Begin; +import org.jboss.seam.annotations.End; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Logger; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Out; +import org.jboss.seam.annotations.exception.Redirect; +import org.jboss.seam.annotations.security.Restrict; +import org.jboss.seam.core.Events; +import org.jboss.seam.faces.FacesMessages; +import org.jboss.seam.log.Log; + +@Stateful +@Name("hotelBooking") +@Restrict("#{identity.loggedIn}") +public class HotelBookingAction implements HotelBooking +{ + + @PersistenceContext(type=EXTENDED) + private EntityManager em; + + @In + private User user; + + @In(required=false) @Out + private Hotel hotel; + + @In(required=false) + @Out(required=false) + private Booking booking; + + @In + private FacesMessages facesMessages; + + @In + private Events events; + + @Logger + private Log log; + + private boolean bookingValid; + + @Begin + public void selectHotel(Hotel selectedHotel) + { + hotel = em.merge(selectedHotel); + } + + @Redirect(//error.xhtml") + public void bookHotel() + { + booking = new Booking(hotel, user); + Calendar calendar = Calendar.getInstance(); + booking.setCheckinDate( calendar.getTime() ); + calendar.add(Calendar.DAY_OF_MONTH, 1); + booking.setCheckoutDate( calendar.getTime() ); + } + + public void setBookingDetails() + { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DAY_OF_MONTH, -1); + if ( booking.getCheckinDate().before( calendar.getTime() ) ) + { + facesMessages.addToControl("checkinDate", "Check in date must be a future date"); + bookingValid=false; + } + else if ( !booking.getCheckinDate().before( booking.getCheckoutDate() ) ) + { + facesMessages.addToControl("checkoutDate", "Check out date must be later than check in date"); + bookingValid=false; + } + else + { + bookingValid=true; + } + } + + public boolean isBookingValid() + { + return bookingValid; + } + + @End + public void confirm() + { + em.persist(booking); + facesMessages.add("Thank you, #{user.name}, your confimation number for #{hotel.name} is #{booking.id}"); + log.info("New booking: #{booking.id} for #{user.username}"); + events.raiseTransactionSuccessEvent("bookingConfirmed"); + } + + @End + public void cancel() {} + + @Remove + public void destroy() {} +} \ No newline at end of file diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/LoginTest.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/LoginTest.java new file mode 100644 index 000000000..dd704b747 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/LoginTest.java @@ -0,0 +1,88 @@ +//$Id$ +package org.jboss.seam.example.booking.test; + +import org.jboss.seam.Seam; +import org.jboss.seam.core.Manager; +import org.jboss.seam.mock.SeamTest; +import org.testng.annotations.Test; + +public class LoginTest extends SeamTest +{ + + @Test + public void testLogin() throws Exception + { + + new FacesRequest() { + + @Override + protected void invokeApplication() + { + assert !isSessionInvalid(); + assert getValue("#{identity.loggedIn}").equals(false); + } + + }.run(); + + new FacesRequest() { + + @Override + protected void updateModelValues() throws Exception + { + assert !isSessionInvalid(); + setValue("#{identity.username}", "gavin"); + setValue("#{identity.password}", "foobar"); + } + + @Override + protected void invokeApplication() + { + invokeMethod("#{identity.login}"); + } + + @Override + protected void renderResponse() + { + assert getValue("#{user.name}").equals("Gavin King"); + assert getValue("#{user.username}").equals("gavin"); + assert getValue("#{user.password}").equals("foobar"); + assert !Manager.instance().isLongRunningConversation(); + assert getValue("#{identity.loggedIn}").equals(true); + } + + }.run(); + + new FacesRequest() { + + @Override + protected void invokeApplication() + { + assert !isSessionInvalid(); + assert getValue("#{identity.loggedIn}").equals(true); + } + + }.run(); + + new FacesRequest() { + + @Override + protected void invokeApplication() + { + assert !Manager.instance().isLongRunningConversation(); + assert !isSessionInvalid(); + invokeMethod("#{identity.logout}"); + assert Seam.isSessionInvalid(); + } + + @Override + protected void renderResponse() + { + assert getValue("#{identity.loggedIn}").equals(false); + assert Seam.isSessionInvalid(); + } + + }.run(); + + } + +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/Main.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/Main.java new file mode 100644 index 000000000..5e0baf030 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/Main.java @@ -0,0 +1,291 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jboss.seam.example.wicket; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.apache.wicket.Component; +import org.apache.wicket.PageParameters; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; +import org.apache.wicket.feedback.ContainerFeedbackMessageFilter; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.DropDownChoice; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.form.TextField; +import org.apache.wicket.markup.html.link.Link; +import org.apache.wicket.markup.html.panel.FeedbackPanel; +import org.apache.wicket.markup.repeater.Item; +import org.apache.wicket.markup.repeater.data.DataView; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.PageParameters; +import org.jboss.seam.wicket.annotations.Begin; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.security.Restrict; +import org.jboss.seam.core.Conversation; +import org.jboss.seam.core.Manager; +import org.jboss.seam.example.wicket.action.Booking; +import org.jboss.seam.example.wicket.action.BookingList; +import org.jboss.seam.example.wicket.action.Hotel; +import org.jboss.seam.example.wicket.action.HotelBooking; +import org.jboss.seam.example.wicket.action.HotelSearching; +import org.jboss.seam.security.Identity; +import org.jboss.seam.wicket.SeamPropertyModel; + +@Restrict("#{identity.loggedIn}") +public class Main extends WebPage +{ + + @In(create = true) + private HotelSearching hotelSearch; + + @In(create=true) + private List bookings; + + @In(create=true) + private BookingList bookingList; + + @In(create=true) + private HotelBooking hotelBooking; + + private DataView hotelDataView; + private DataView bookedHotelDataView; + private HotelSearchForm hotelSearchForm; + private WebMarkupContainer hotels; + private Component noHotelsFound; + private Component messages; + + + public Main(final PageParameters parameters) + { + Template body = new Template("body"); + add(body); + hotelSearchForm = new HotelSearchForm("searchCriteria"); + body.add(hotelSearchForm); + + messages = new FeedbackPanel("messages", new ContainerFeedbackMessageFilter(this)).setOutputMarkupId(true); + body.add(messages); + + /* + * Hotel Search results + */ + noHotelsFound = new Label("noResults", "No Hotels Found") + { + /** + * Only display the message if no hotels are found + * + */ + @Override + public boolean isVisible() + { + return Identity.instance().isLoggedIn() && hotelSearch.getHotels().size() == 0; + } + }; + body.add(noHotelsFound.setOutputMarkupId(true)); + hotelDataView = new DataView("hotel", new SimpleDataProvider() // A DataProvider adapts between your data and Wicket's internal representation + { + public Iterator iterator(int from, int count) + { + return hotelSearch.getHotels().subList(from, from + count).iterator(); + } + + public int size() + { + return hotelSearch.getHotels().size(); + } + + }) + { + /** + * You specify the tr in the html, and populate each one here + */ + @Override + protected void populateItem(Item item) + { + final Hotel hotel = (Hotel) item.getModelObject(); + item.add(new Label("hotelName", hotel.getName())); + item.add(new Label("hotelAddress", hotel.getAddress())); + item.add(new Label("hotelCityStateCountry", hotel.getCity() + ", " + hotel.getState() + ", " + hotel.getCountry())); + item.add(new Label("hotelZip", hotel.getZip())); + //item.add(new BookmarkablePageLink("viewHotel", org.jboss.seam.example.wicket.Hotel.class).setParameter("hotelId", hotel.getId())); + item.add(new Link("viewHotel") + { + + @Begin + @Override + public void onClick() + { + hotelBooking.selectHotel(hotel); + setResponsePage(new org.jboss.seam.example.wicket.Hotel(new PageParameters())); + } + + }); + } + + }; + + // Set the maximum items per page + hotelDataView.setItemsPerPage(hotelSearchForm.getPageSize()); + hotelDataView.setOutputMarkupId(true); + hotels = new WebMarkupContainer("hotels"); + hotels.add(hotelDataView).setOutputMarkupId(true); + + + // Add a pager + hotels.add(new AjaxPagingNavigator("hotelPager", hotelDataView) + { + @Override + public boolean isVisible() + { + return hotelDataView.isVisible(); + } + + }); + + body.add(hotels); + + /* + * Existing hotel booking + */ + bookedHotelDataView = new DataView("bookedHotel", new SimpleDataProvider() + { + public Iterator iterator(int from, int count) + { + return bookings.subList(from, from + count).iterator(); + } + + public int size() + { + return bookings.size(); + } + + + + }) + { + + @Override + protected void populateItem(Item item) + { + final Booking booking = (Booking) item.getModelObject(); + item.add(new Label("hotelName", booking.getHotel().getName())); + item.add(new Label("hotelAddress", booking.getHotel().getAddress())); + item.add(new Label("hotelCityStateCountry", booking.getHotel().getCity() + ", " + booking.getHotel().getState() + ", " + booking.getHotel().getState())); + item.add(new Label("hotelCheckInDate", booking.getCheckinDate().toString())); + item.add(new Label("hotelCheckOutDate", booking.getCheckoutDate().toString())); + item.add(new Label("hotelConfirmationNumber", booking.getId().toString())); + item.add(new Link("cancel") + { + + @Override + public void onClick() + { + bookingList.cancel(booking); + } + + }); + } + + @Override + public boolean isVisible() + { + return Identity.instance().isLoggedIn() && bookings.size() > 0; + } + + }; + body.add(bookedHotelDataView); + body.add(new Label("noHotelsBooked", "No Bookings Found") + { + @Override + public boolean isVisible() + { + return Identity.instance().isLoggedIn() && bookings.size() == 0; + } + }); + } + + public class HotelSearchForm extends Form + { + + private Integer pageSize = 10; + + public Integer getPageSize() + { + return pageSize; + } + + public void setPageSize(Integer pageSize) + { + this.pageSize = pageSize; + } + + public HotelSearchForm(String id) + { + super(id); + add(new TextField("searchString", new SeamPropertyModel("searchString") + { + + @Override + public Object getTarget() + { + return hotelSearch; + } + + })); + List pageSizes = Arrays.asList(new Integer[] { 5, 10, 20 }); + add(new DropDownChoice("pageSize", new PropertyModel(this, "pageSize"), pageSizes)); + add(new IndicatingAjaxButton("submit", this) + { + + @Override + protected void onSubmit(AjaxRequestTarget target, Form form) + { + target.addComponent(messages); + hotelSearch.find(); + hotelDataView.setCurrentPage(0); + hotelDataView.setItemsPerPage(getPageSize()); + hotelDataView.modelChanged(); + hotels.modelChanged(); + target.addComponent(hotels); + target.addComponent(noHotelsFound); + } + + @Override + protected void onError(AjaxRequestTarget target, Form form) + { + target.addComponent(messages); + } + + }); + } + + @Override + protected void onSubmit() + { + hotelDataView.setCurrentPage(0); + hotelDataView.setItemsPerPage(getPageSize()); + hotelSearch.find(); + } + + } +} + diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/MessageManagerBean.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/MessageManagerBean.java new file mode 100644 index 000000000..632f75dfa --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/MessageManagerBean.java @@ -0,0 +1,63 @@ +//$Id$ +package org.jboss.seam.example.messages; + +import static javax.persistence.PersistenceContextType.EXTENDED; +import static org.jboss.seam.ScopeType.SESSION; + +import java.io.Serializable; +import java.util.List; + +import javax.ejb.Remove; +import javax.ejb.Stateful; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import org.jboss.seam.annotations.Destroy; +import org.jboss.seam.annotations.Factory; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Out; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.datamodel.DataModel; +import org.jboss.seam.annotations.datamodel.DataModelSelection; + +@Stateful +@Scope(SESSION) +@Name("messageManager") +public class MessageManagerBean implements Serializable, MessageManager +{ + + @DataModel + private List messageList; + + @DataModelSelection + @Out(required=false) + private Message message; + + @PersistenceContext(type=EXTENDED) + private EntityManager em; + + @Factory("messageList") + public void findMessages() + { + messageList = em.createQuery("select msg from Message msg order by msg.datetime desc").getResultList(); + } + + public void select() + { + if (message!=null) message.setRead(true); + } + + public void delete() + { + if (message!=null) + { + messageList.remove(message); + em.remove(message); + message=null; + } + } + + @Remove @Destroy + public void destroy() {} + +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/PaymentHome.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/PaymentHome.java new file mode 100644 index 000000000..ece0bc8e9 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/PaymentHome.java @@ -0,0 +1,81 @@ +package org.jboss.seam.example.quartz; + +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Logger; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Transactional; +import org.jboss.seam.annotations.web.RequestParameter; +import org.jboss.seam.async.QuartzTriggerHandle; +import org.jboss.seam.example.quartz.Payment; +import org.jboss.seam.example.quartz.PaymentProcessor; +import org.jboss.seam.faces.FacesMessages; +import org.jboss.seam.framework.EntityHome; +import org.jboss.seam.log.Log; + +@Name("paymentHome") +public class PaymentHome + extends EntityHome +{ + @RequestParameter Long paymentId; + @In PaymentProcessor processor; + + @Logger Log log; + + public String saveAndSchedule() + { + String result = persist(); + + Payment payment = getInstance(); + + log.info("scheduling instance #0", payment); + QuartzTriggerHandle handle = processor.schedulePayment(payment.getPaymentDate(), + payment.getPaymentFrequency().getInterval(), + payment.getPaymentEndDate(), + payment); + + payment.setQuartzTriggerHandle( handle ); + + return result; + } + + public String saveAndScheduleCron() + { + String result = persist(); + + Payment payment = getInstance(); + log.info("scheduling instance #0", payment); + + QuartzTriggerHandle handle = processor.schedulePayment(payment.getPaymentDate(), + payment.getPaymentCron(), + payment.getPaymentEndDate(), + payment); + + payment.setQuartzTriggerHandle( handle ); + + return result; + } + + @Override + public Object getId() { + return paymentId; + } + + @Transactional + public void cancel() { + Payment payment = getInstance(); + + QuartzTriggerHandle handle = payment.getQuartzTriggerHandle(); + payment.setQuartzTriggerHandle(null); + payment.setActive(false); + + try + { + handle.cancel(); + } + catch (Exception nsole) + { + FacesMessages.instance().add("Payment already processed"); + } + } + +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/ShipAction.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/ShipAction.java new file mode 100644 index 000000000..67f58b458 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/ShipAction.java @@ -0,0 +1,57 @@ +/* + * JBoss, Home of Professional Open Source + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package com.jboss.dvd.seam; + +import java.io.Serializable; + +import javax.ejb.Remove; +import javax.ejb.Stateful; + +import org.hibernate.validator.Length; +import org.hibernate.validator.NotNull; +import org.jboss.seam.annotations.bpm.BeginTask; +import org.jboss.seam.annotations.bpm.EndTask; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Name; + +@Stateful +@Name("ship") +public class ShipAction + implements Ship, + Serializable +{ + private static final long serialVersionUID = -5284603520443473953L; + + @In + Order order; + + String track; + + @NotNull + @Length(min=4,max=10) + public String getTrack() { + return track; + } + + public void setTrack(String track) { + this.track=track; + } + + @BeginTask + public String viewTask() { + return "ship"; + } + + @EndTask + public String ship() { + order.ship(track); + return "admin"; + } + + @Remove + public void destroy() { } +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/TestAuthenticator.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/TestAuthenticator.java new file mode 100644 index 000000000..97fcce014 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/TestAuthenticator.java @@ -0,0 +1,51 @@ +package org.jboss.seam.example.restbay.resteasy; + + +import org.jboss.seam.Component; +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Logger; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.Transactional; +import org.jboss.seam.log.Log; +import org.jboss.seam.security.Credentials; +import org.jboss.seam.security.Identity; + +@Name("testAuthenticator") +@Scope(ScopeType.EVENT) +public class TestAuthenticator +{ + + @In + private Identity identity; + + @In + private Credentials credentials; + + @Logger + private Log log; + + @Transactional + public boolean authenticate() + { + // Tests that the SFSB can be obtained in both ContextualHttpRequests (authentication and web service invocation) + TestEjbLocal ejb = (TestEjbLocal) Component.getInstance("securedEjb", ScopeType.EVENT); + ejb.foo(); + + log.debug("Authenticating username/password: " + credentials.getUsername() + "/" + credentials.getPassword()); + if (credentials.getUsername().equals(credentials.getPassword())) { + log.info("Authenticated {0}", credentials.getUsername()); + + if (credentials.getUsername().equals("admin")) { + identity.addRole("admin"); + log.info("Admin rights granted for {0}", credentials.getUsername()); + } + log.debug("Authentication valid"); + return true; + } else { + log.debug("Authentication invalid"); + return false; + } + } +} \ No newline at end of file diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/TestPaymentProcessor.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/TestPaymentProcessor.java new file mode 100644 index 000000000..e2289f643 --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/TestPaymentProcessor.java @@ -0,0 +1,89 @@ +package org.jboss.seam.example.quartz.test; + +import static org.jboss.seam.annotations.Install.MOCK; + +import java.math.BigDecimal; +import java.util.Date; + +import javax.persistence.EntityManager; + +import org.jboss.seam.annotations.AutoCreate; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Install; +import org.jboss.seam.annotations.Logger; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Observer; +import org.jboss.seam.annotations.Transactional; +import org.jboss.seam.annotations.async.Asynchronous; +import org.jboss.seam.async.QuartzTriggerHandle; +import org.jboss.seam.example.quartz.Payment; +import org.jboss.seam.example.quartz.PaymentProcessor; +import org.jboss.seam.log.Log; + +/** + * @author Pete Muir + * + */ +@Name("processor") +@Install(precedence=MOCK) +@AutoCreate +public class TestPaymentProcessor extends PaymentProcessor +{ + + @In + EntityManager entityManager; + + @Logger Log log; + + @Asynchronous + @Transactional + public QuartzTriggerHandle schedulePaymentAsynchronously(Payment payment) + { + payment = entityManager.merge(payment); + + log.info("[#0] Processing cron payment #1", System.currentTimeMillis(), payment.getId()); + + if (payment.getActive()) { + BigDecimal balance = payment.getAccount().adjustBalance(payment.getAmount().negate()); + log.info(":: balance is now #0", balance); + payment.setLastPaid(new Date()); + + } + + return null; + } + + @Observer("org.jboss.seam.example.quartz.test.scheduleAndSave") + @Transactional + public QuartzTriggerHandle schedulePayment(Payment payment) + { + payment = entityManager.merge(payment); + + log.error("[#0] Processing cron payment #1", System.currentTimeMillis(), payment.getId()); + if (payment.getActive()) { + BigDecimal balance = payment.getAccount().adjustBalance(payment.getAmount().negate()); + log.error(":: balance is now #0", balance); + payment.setLastPaid(new Date()); + + } + + return null; + } + + @Observer("org.jboss.seam.example.quartz.test.transactionSuccess") + @Transactional + public void observeTransactionSuccess(Payment payment) + { + TransactionStatus.instance().setTransactionSucceded(true); + TransactionStatus.instance().setId(payment.getId()); + } + + @Observer("org.jboss.seam.example.quartz.test.transactionCompletion") + @Transactional + public void observeTransactionCompletion(Payment payment) + { + TransactionStatus.instance().setTransactionCompleted(true); + TransactionStatus.instance().setId(payment.getId()); + } + +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/TransactionStatus.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/TransactionStatus.java new file mode 100644 index 000000000..dec97a4be --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/TransactionStatus.java @@ -0,0 +1,75 @@ +package org.jboss.seam.example.quartz.test; + +import org.jboss.seam.Component; +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.AutoCreate; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.contexts.Contexts; + +/** + * @author Pete Muir + * + */ +@Name("transactionStatus") +@Scope(ScopeType.APPLICATION) +@AutoCreate +public class TransactionStatus +{ + private Object id; + private boolean transactionSucceded; + private boolean transactionCompleted; + /** + * @return the transactionSuccess + */ + public boolean getTransactionSucceded() + { + return this.transactionSucceded; + } + /** + * @param transactionSuccess the transactionSuccess to set + */ + public void setTransactionSucceded(boolean transactionSuccess) + { + this.transactionSucceded = transactionSuccess; + } + /** + * @return the transactionCompleted + */ + public boolean getTransactionCompleted() + { + return this.transactionCompleted; + } + /** + * @param transactionCompleted the transactionCompleted to set + */ + public void setTransactionCompleted(boolean transactionCompleted) + { + this.transactionCompleted = transactionCompleted; + } + + public static void clear() + { + Contexts.getApplicationContext().remove("transactionStatus"); + } + + public static TransactionStatus instance() + { + return (TransactionStatus) Component.getInstance("transactionStatus"); + } + /** + * @return the id + */ + public Object getId() + { + return this.id; + } + /** + * @param id the id to set + */ + public void setId(Object id) + { + this.id = id; + } + +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/data/src/WikiUrlRewriteFilter.java b/rules-reviewed/eap6/java-ee/seam/tests/data/src/WikiUrlRewriteFilter.java new file mode 100644 index 000000000..4b22500be --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/data/src/WikiUrlRewriteFilter.java @@ -0,0 +1,92 @@ +/* + * JBoss, Home of Professional Open Source + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package org.jboss.seam.wiki.core.ui; + +import org.jboss.seam.ScopeType; +import org.jboss.seam.util.EnumerationEnumeration; +import org.jboss.seam.annotations.Install; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.annotations.Startup; +import org.jboss.seam.annotations.intercept.BypassInterceptors; +import org.jboss.seam.annotations.web.Filter; +import org.jboss.seam.web.AbstractFilter; +import org.tuckey.web.filters.urlrewrite.UrlRewriteFilter; + +import javax.servlet.*; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Collections; +import java.util.Map; + +/** + * Adapts the Tuckey URLRewrite filter to the Seam filter chain. + * + * @author Christian Bauer + */ +@Startup +@Scope(ScopeType.APPLICATION) +@Name("wikiUrlRewriteFilter") +@BypassInterceptors +@Filter(within = "org.jboss.seam.web.exceptionFilter") +@Install(classDependencies = "org.tuckey.web.filters.urlrewrite.UrlRewriteFilter", precedence = Install.APPLICATION) +public class WikiUrlRewriteFilter extends AbstractFilter { + + private UrlRewriteFilter urlRewriteFilter; + + public void init(FilterConfig filterConfig) throws ServletException { + urlRewriteFilter = new UrlRewriteFilter(); + urlRewriteFilter.init(new FilterConfigWrapper(filterConfig, getInitParameters())); + } + + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + urlRewriteFilter.doFilter(servletRequest, servletResponse, filterChain); + } + + private Map initParameters; + + public Map getInitParameters() { + return initParameters; + } + public void setInitParameters(Map initParameters) { + this.initParameters = initParameters; + } + + private class FilterConfigWrapper implements FilterConfig { + + private FilterConfig delegate; + private Map parameters; + + public FilterConfigWrapper(FilterConfig filterConfig, Map initParameters) { + delegate = filterConfig; + parameters = initParameters; + } + + public String getFilterName() { + return delegate.getFilterName(); + } + + public String getInitParameter(String name) { + if (parameters.containsKey(name)) { + return parameters.get(name); + } else { + return delegate.getInitParameter(name); + } + } + + public Enumeration getInitParameterNames() { + Enumeration[] enumerations = {delegate.getInitParameterNames(), Collections.enumeration(parameters.keySet())}; + return new EnumerationEnumeration(enumerations); + } + + public ServletContext getServletContext() { + return delegate.getServletContext(); + } + } + +} diff --git a/rules-reviewed/eap6/java-ee/seam/tests/seam-java.windup.test.xml b/rules-reviewed/eap6/java-ee/seam/tests/seam-java.windup.test.xml new file mode 100644 index 000000000..9b780539f --- /dev/null +++ b/rules-reviewed/eap6/java-ee/seam/tests/seam-java.windup.test.xml @@ -0,0 +1,323 @@ + + + data/src/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +