Skip to content

Commit

Permalink
Merge branch 'release/3.1.0.Final'
Browse files Browse the repository at this point in the history
  • Loading branch information
sbryzak committed Dec 20, 2011
2 parents 08c7604 + 6e5d676 commit 9b0aa8e
Show file tree
Hide file tree
Showing 17 changed files with 289 additions and 80 deletions.
2 changes: 1 addition & 1 deletion api/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>seam-faces-parent</artifactId>
<groupId>org.jboss.seam.faces</groupId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion dist/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.jboss.seam.faces</groupId>
<artifactId>seam-faces-parent</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion docs/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.jboss.seam.faces</groupId>
<artifactId>seam-faces-parent</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
48 changes: 48 additions & 0 deletions docs/src/main/docbook/en-US/faces-conversation.xml
@@ -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>
35 changes: 35 additions & 0 deletions docs/src/main/docbook/en-US/faces-exceptionhandling.xml
@@ -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>
26 changes: 26 additions & 0 deletions docs/src/main/docbook/en-US/faces-locale.xml
@@ -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>
7 changes: 6 additions & 1 deletion docs/src/main/docbook/en-US/faces-viewconfig.xml
Expand Up @@ -25,14 +25,17 @@
framework)
</para>
</listitem>
<!--
<listitem>
<para>
Configuring Transactional behaviour through Seam Persistence
</para>
</listitem>
-->
<listitem>
<para>
A personal favorite: setting <literal>faces-direct=true</literal> when navigating to a view.
A personal favorite of the Seam Faces lead: setting <literal>faces-direct=true</literal> when
navigating to a view.
</para>
</listitem>
</itemizedlist>
Expand Down Expand Up @@ -227,6 +230,7 @@ public @Secures @Owner boolean ownerChecker(Identity identity, @Current Item ite
</para>
</section>

<!-- Leaving this out unless it really is done, in that case it needs more information.
<section id="viewconfig.transaction">
<title>Configuring Transactional Views</title>
Expand All @@ -236,5 +240,6 @@ public @Secures @Owner boolean ownerChecker(Identity identity, @Current Item ite
this feature is fleshed out.
</para>
</section>
-->

</chapter>
3 changes: 3 additions & 0 deletions docs/src/main/docbook/en-US/master.xml
Expand Up @@ -10,12 +10,15 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-preface.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-installation.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-scopes.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-conversation.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-locale.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-messages.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-components.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-artifacts.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-events.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-projectstage.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-viewconfig.xml" />
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="faces-exceptionhandling.xml" />

<!--
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="chapterXX.xml" />
Expand Down
2 changes: 1 addition & 1 deletion examples/short-ly/pom.xml
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.jboss.seam.faces</groupId>
<artifactId>seam-faces-parent</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion examples/viewconfig/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.jboss.seam.faces</groupId>
<artifactId>seam-faces-parent</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion impl/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>seam-faces-parent</artifactId>
<groupId>org.jboss.seam.faces</groupId>
<version>3.1.0-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
153 changes: 153 additions & 0 deletions impl/src/main/java/org/jboss/seam/faces/el/CollectionsELResolver.java
@@ -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);
}

}

0 comments on commit 9b0aa8e

Please sign in to comment.