Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
289 additions
and
80 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
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
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
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,48 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | ||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | ||
<chapter id="faces.conversation"> | ||
<title>Conversation Management and Usage</title> | ||
|
||
<section id="faces.conversation_el"> | ||
<title>Conversation Usage in EL</title> | ||
<para> | ||
CDI exposes the conversation to EL via the name <literal>javax.enterprise.context.conversation</literal>. Seam | ||
Faces adds an alias to make this a little more convient for page authors. The alias Seam Faces provides is | ||
simply <literal>conversation</literal>. | ||
</para> | ||
</section> | ||
|
||
<section id="faces.conversation_management"> | ||
<title>Conversation Management</title> | ||
|
||
<para> | ||
CDI Conversations can be started and stopped easily in Seam Faces using annotations, respectifully | ||
<literal>@Begin</literal> and <literal>@End</literal>. Both of these have some extra properties that can be | ||
used to configure the conversation. | ||
</para> | ||
|
||
<para> | ||
Common to both annotations is the <literal>permit</literal> attribute. This is an array of Exception classes | ||
which if encountered during the method execution, will still allow the conversation to begin, or end. By default, | ||
any exception encountered will either prohibit the conversation from beginning or ending. | ||
</para> | ||
|
||
<section id="faces.conversation_management.begin"> | ||
<title><literal>@Begin</literal></title> | ||
<para> | ||
The <literal>@Begin</literal> annotation has the <literal>id</literal> property | ||
which can be used to provide an id for the conversation, instead of the default. The <literal>timeout</literal> | ||
property is used to set the timeout for the conversation in milliseconds. | ||
</para> | ||
</section> | ||
|
||
<section id="faces.conversation_management.end"> | ||
<title><literal>@End</literal></title> | ||
<para> | ||
<literal>@End</literal> has no additional properties. | ||
</para> | ||
</section> | ||
</section> | ||
|
||
</chapter> |
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,35 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | ||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | ||
<chapter id="faces.exceptionhandling"> | ||
<title>Exception Handling</title> | ||
<para> | ||
Seam Faces makes use of Solder Exception Handling, coupled with JSF2 exception handlers to provide a robust and | ||
complete means of handling exceptions that occur in a JSF application. For more information about using Solder | ||
Exception Handling, please see <xref linkend="catch-introduction"/>. | ||
</para> | ||
<para> | ||
All exceptions that occur during the JSF life cycle should be caught by Seam Faces and passed along to Solder | ||
Exception Handling. There may be a few cases where this doesn't happen, fortunately, a Solder servlet filter | ||
acts as a catch all for exceptions and will pass along the uncaught exception. | ||
</para> | ||
<warning> | ||
<para> | ||
Something that must be considered when handling an exception within the JSF life cycle is the phase in which the | ||
exception occurred. Most exceptions can be handled easily and a <literal>FacesMessage</literal> can be added and | ||
displayed to the user, or the user can be redirected to an error page. However, if the exception occurred in the | ||
<literal>RENDER_RESPONSE</literal> phase this is not the case. No redirection, or messages, or other output to | ||
the response can be used if the request is in this part of the life cycle. Please inject the | ||
<literal>FacesContext</literal> and determine the life cycle phase of the request before proceeding with exception | ||
handling. | ||
</para> | ||
</warning> | ||
<section id="faces.exceptionhandling.qualifier"> | ||
<title>Qualifier</title> | ||
<para> | ||
All exceptions that are passed to Solder Exception Handling from within Seam Faces have the <literal>Faces</literal> | ||
qualifier added to them. This can aid in exception handling by limiting the exception handlers (based on qualifier) | ||
which are notified of the exception. | ||
</para> | ||
</section> | ||
</chapter> |
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,26 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | ||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | ||
<chapter id="faces.locale"> | ||
<title>Locale</title> | ||
<para> | ||
In addition to <xref linkend="international.locales" />, Seam Faces provides an additional producer which returns | ||
the supported locale of the <literal>UIViewRoot</literal> or <literal>ViewHandler</literal>. This | ||
<literal>Locale</literal> has the <literal>@Faces</literal> qualifier to help distinguish it from other produced | ||
locales. | ||
</para> | ||
<para> | ||
Seam Faces also provides easy access to the configured list of locales for the application both via injection and | ||
via EL. Using EL thould would be <literal>#{supportedLocales}</literal> and <literal>#{defaultFacesLocale}</literal>. | ||
Via injection one would use | ||
</para> | ||
<programlisting role="JAVA"><![CDATA[@Inject @Faces | ||
List<Locale> supportedLocales;]]> | ||
</programlisting> | ||
<para> | ||
or | ||
</para> | ||
<programlisting role="JAVA"><![CDATA[@Inject @Faces @DefaultLocale | ||
Locale defaultLocale;]]> | ||
</programlisting> | ||
</chapter> |
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
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
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
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
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
153 changes: 153 additions & 0 deletions
153
impl/src/main/java/org/jboss/seam/faces/el/CollectionsELResolver.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,153 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source | ||
* Copyright 2011, Red Hat, Inc., and individual contributors | ||
* by the @authors tag. See the copyright.txt in the distribution for a | ||
* full listing of individual contributors. | ||
* | ||
* Licensed 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.faces.el; | ||
|
||
import java.beans.FeatureDescriptor; | ||
import java.lang.reflect.Method; | ||
import java.util.Collection; | ||
import java.util.Iterator; | ||
import java.util.Map; | ||
|
||
import javax.el.ELContext; | ||
import javax.el.ELResolver; | ||
|
||
import org.jboss.solder.el.Resolver; | ||
import org.jboss.solder.reflection.Reflections; | ||
|
||
/** | ||
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a> | ||
*/ | ||
@Resolver | ||
public class CollectionsELResolver extends ELResolver { | ||
private static Class<?> DATA_MODEL; | ||
private static Class<?>[] EMPTY_CLASS_ARRAY = new Class[0]; | ||
|
||
static { | ||
try { | ||
DATA_MODEL = CollectionsELResolver.class.getClassLoader().loadClass("javax.faces.model.DataModel"); | ||
} catch (ClassNotFoundException e) { | ||
DATA_MODEL = null; | ||
} | ||
} | ||
// private ELResolver getWrapped() { | ||
// return FacesContext.getCurrentInstance().getELContext().getELResolver(); | ||
// } | ||
|
||
@Override | ||
public Object getValue(ELContext context, Object base, Object property) { | ||
if (base instanceof Collection) { | ||
return this.resolveInCollection(context, (Collection) base, property); | ||
} else if (base instanceof Map) { | ||
return this.resolveInMap(context, (Map) base, property); | ||
} else if (DATA_MODEL.isInstance(base)) { | ||
return this.resolveInDataModel(context, base, property); | ||
} else if (base != null) { | ||
return this.resolveNoArgMethod(context, base, property.toString()); | ||
} | ||
return null; | ||
} | ||
|
||
@Override | ||
public Class<?> getType(ELContext context, Object base, Object property) { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void setValue(ELContext context, Object base, Object property, Object value) { | ||
return; | ||
} | ||
|
||
@Override | ||
public boolean isReadOnly(ELContext context, Object base, Object property) { | ||
return base != null && (base.getClass().isInstance(DATA_MODEL) || base instanceof Collection || base instanceof Map); | ||
} | ||
|
||
@Override | ||
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) { | ||
return null; | ||
} | ||
|
||
@Override | ||
public Class<?> getCommonPropertyType(ELContext context, Object base) { | ||
return Object.class; | ||
} | ||
|
||
private boolean containsKey(Map map, String key) { | ||
try { | ||
return map.containsKey(key); | ||
} catch (UnsupportedOperationException e) { | ||
// eat it | ||
return false; | ||
} | ||
} | ||
|
||
private Object resolveInMap(ELContext context, Map map, Object property) { | ||
if ("size".equals(property) && !containsKey(map, "size")) { | ||
context.setPropertyResolved(true); | ||
return map.size(); | ||
} else if ("values".equals(property) && !containsKey(map, "values")) { | ||
context.setPropertyResolved(true); | ||
return map.values(); | ||
} else if ("keySet".equals(property) && !containsKey(map, "keySet")) { | ||
context.setPropertyResolved(true); | ||
return map.keySet(); | ||
} else if ("entrySet".equals(property) && !containsKey(map, "entrySet")) { | ||
context.setPropertyResolved(true); | ||
return map.entrySet(); | ||
} else if ("empty".equals(property) && !containsKey(map, "empty")) { | ||
context.setPropertyResolved(true); | ||
return map.isEmpty(); | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
private Object resolveInDataModel(ELContext context, Object base, Object property) { | ||
if ("size".equals(property)) { | ||
context.setPropertyResolved(true); | ||
return (Integer) Reflections.invokeMethod(Reflections.findDeclaredMethod(DATA_MODEL, "getRowCount", EMPTY_CLASS_ARRAY), base); | ||
} else if ("empty".equals(property)) { | ||
context.setPropertyResolved(true); | ||
return (Integer) Reflections.invokeMethod(Reflections.findDeclaredMethod(DATA_MODEL, "getRowCount", EMPTY_CLASS_ARRAY), base) == 0; | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
private Object resolveInCollection(ELContext context, Collection collection, Object property) { | ||
if ("size".equals(property)) { | ||
context.setPropertyResolved(true); | ||
return collection.size(); | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
private Object resolveNoArgMethod(ELContext context, Object target, String property) { | ||
final Method foundMethod = Reflections.findDeclaredMethod(target.getClass(), property, EMPTY_CLASS_ARRAY); | ||
if (foundMethod != null) { | ||
context.setPropertyResolved(true); | ||
return Reflections.invokeMethod(foundMethod, target); | ||
} | ||
return null; | ||
} | ||
|
||
public static Object invok(Method method, Object target, Object... args) { | ||
return Reflections.invokeMethod(method, target, args); | ||
} | ||
|
||
} |
Oops, something went wrong.