Seam SVN: r7751 - branches/Seam_2_0/ui/src/main/java/org/jboss/seam/ui/facelet.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-03-31 08:22:33 -0400 (Mon, 31 Mar 2008)
New Revision: 7751
Modified:
branches/Seam_2_0/ui/src/main/java/org/jboss/seam/ui/facelet/FaceletsRenderer.java
Log:
fix warnings
Modified: branches/Seam_2_0/ui/src/main/java/org/jboss/seam/ui/facelet/FaceletsRenderer.java
===================================================================
--- branches/Seam_2_0/ui/src/main/java/org/jboss/seam/ui/facelet/FaceletsRenderer.java 2008-03-31 12:17:16 UTC (rev 7750)
+++ branches/Seam_2_0/ui/src/main/java/org/jboss/seam/ui/facelet/FaceletsRenderer.java 2008-03-31 12:22:33 UTC (rev 7751)
@@ -1,5 +1,8 @@
package org.jboss.seam.ui.facelet;
+import static org.jboss.seam.ScopeType.STATELESS;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
import java.io.IOException;
import java.io.StringWriter;
import java.net.URL;
@@ -8,7 +11,6 @@
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
-import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
@@ -21,7 +23,6 @@
import org.jboss.seam.ui.util.JSF;
import com.sun.facelets.Facelet;
-import com.sun.facelets.compiler.SAXCompiler;
import com.sun.facelets.impl.DefaultFaceletFactory;
import com.sun.facelets.impl.DefaultResourceResolver;
@@ -36,11 +37,11 @@
*
*/
-(a)Scope(ScopeType.STATELESS)
+@Scope(STATELESS)
@BypassInterceptors
@Name("org.jboss.seam.faces.renderer")
@AutoCreate
-@Install(value = true, precedence = Install.BUILT_IN, classDependencies="com.sun.facelets.Facelet")
+@Install(value = true, precedence = BUILT_IN, classDependencies="com.sun.facelets.Facelet")
public class FaceletsRenderer extends Renderer
{
/**
16 years, 8 months
Seam SVN: r7750 - trunk/src/main/org/jboss/seam/security/management.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2008-03-31 08:17:16 -0400 (Mon, 31 Mar 2008)
New Revision: 7750
Modified:
trunk/src/main/org/jboss/seam/security/management/JpaIdentityStore.java
trunk/src/main/org/jboss/seam/security/management/LdapIdentityStore.java
Log:
components should be BUILT_IN
Modified: trunk/src/main/org/jboss/seam/security/management/JpaIdentityStore.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/management/JpaIdentityStore.java 2008-03-31 09:13:02 UTC (rev 7749)
+++ trunk/src/main/org/jboss/seam/security/management/JpaIdentityStore.java 2008-03-31 12:17:16 UTC (rev 7750)
@@ -1,6 +1,7 @@
package org.jboss.seam.security.management;
import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.io.Serializable;
import java.lang.reflect.Field;
@@ -33,7 +34,7 @@
* @author Shane Bryzak
*/
@Name("org.jboss.seam.security.management.jpaIdentityStore")
-@Install(value=false)
+@Install(precedence = BUILT_IN, value=false)
@Scope(APPLICATION)
@BypassInterceptors
public class JpaIdentityStore implements IdentityStore, Serializable
@@ -190,7 +191,7 @@
}
else
{
- account.setPasswordHash(PasswordHash.generateHash(password, username));
+ account.setPasswordHash(PasswordHash.generateHash(password, getAccountSalt(account)));
account.setEnabled(true);
}
@@ -213,6 +214,11 @@
}
}
+ protected String getAccountSalt(UserAccount account)
+ {
+ return account.getUsername();
+ }
+
public boolean createUser(String username, String password)
{
return createUser(username, password, null, null);
@@ -373,7 +379,7 @@
throw new NoSuchUserException("Could not change password, user '" + name + "' does not exist");
}
- account.setPasswordHash(PasswordHash.generateHash(password, name));
+ account.setPasswordHash(PasswordHash.generateHash(password, getAccountSalt(account)));
mergeAccount(account);
return true;
}
@@ -457,7 +463,7 @@
return false;
}
- String passwordHash = PasswordHash.generateHash(password, username);
+ String passwordHash = PasswordHash.generateHash(password, getAccountSalt(account));
boolean success = passwordHash.equals(account.getPasswordHash());
if (success && Events.exists())
Modified: trunk/src/main/org/jboss/seam/security/management/LdapIdentityStore.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/management/LdapIdentityStore.java 2008-03-31 09:13:02 UTC (rev 7749)
+++ trunk/src/main/org/jboss/seam/security/management/LdapIdentityStore.java 2008-03-31 12:17:16 UTC (rev 7750)
@@ -1,6 +1,7 @@
package org.jboss.seam.security.management;
import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.io.Serializable;
import java.util.ArrayList;
@@ -35,7 +36,7 @@
* @author Shane Bryzak
*/
@Name("org.jboss.seam.security.management.ldapIdentityStore")
-@Install(value=false)
+@Install(precedence = BUILT_IN, value=false)
@Scope(APPLICATION)
@BypassInterceptors
public class LdapIdentityStore implements IdentityStore, Serializable
16 years, 8 months
Seam SVN: r7749 - trunk/examples/seamspace/view.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2008-03-31 05:13:02 -0400 (Mon, 31 Mar 2008)
New Revision: 7749
Modified:
trunk/examples/seamspace/view/register.xhtml
Log:
typo
Modified: trunk/examples/seamspace/view/register.xhtml
===================================================================
--- trunk/examples/seamspace/view/register.xhtml 2008-03-31 08:39:08 UTC (rev 7748)
+++ trunk/examples/seamspace/view/register.xhtml 2008-03-31 09:13:02 UTC (rev 7749)
@@ -77,7 +77,7 @@
<h:outputLabel for="dob">Date of birth<em>*</em></h:outputLabel>
<!-- TODO Add in start and end of range -->
<!-- TODO Change image -->
- <rich:calendar id="dob" value="#{newMember.dob}" required="true" datePattern="MM/dd/yyyy" buttonIcon="images/ellipses.png" />
+ <rich:calendar id="dob" value="#{newMember.dob}" required="true" datePattern="MM/dd/yyyy" buttonIcon="images/ellipsis.png" />
<div class="validationError"><h:message for="dob"/></div>
</div>
16 years, 8 months
Seam SVN: r7748 - tags.
by seam-commits@lists.jboss.org
Author: manaRH
Date: 2008-03-31 04:39:08 -0400 (Mon, 31 Mar 2008)
New Revision: 7748
Added:
tags/JBPAPP_4_3_CP01/
Removed:
tags/JBPAPP_4_2_CP_0803/
Log:
renamed tag for EAP 4.3/4.2 CP01/CP03
Copied: tags/JBPAPP_4_3_CP01 (from rev 7747, tags/JBPAPP_4_2_CP_0803)
16 years, 8 months
Seam SVN: r7747 - trunk/src/main/org/jboss/seam/security/management.
by seam-commits@lists.jboss.org
Author: shane.bryzak(a)jboss.com
Date: 2008-03-30 22:57:42 -0400 (Sun, 30 Mar 2008)
New Revision: 7747
Modified:
trunk/src/main/org/jboss/seam/security/management/LdapIdentityStore.java
Log:
JBSEAM-2559, LdapIdentityStore completed
Modified: trunk/src/main/org/jboss/seam/security/management/LdapIdentityStore.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/management/LdapIdentityStore.java 2008-03-30 23:52:26 UTC (rev 7746)
+++ trunk/src/main/org/jboss/seam/security/management/LdapIdentityStore.java 2008-03-31 02:57:42 UTC (rev 7747)
@@ -26,6 +26,8 @@
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
/**
* An IdentityStore implementation that integrates with a directory service.
@@ -42,6 +44,8 @@
private static final String LDAP_BOOLEAN_TRUE = "TRUE";
private static final String LDAP_BOOLEAN_FALSE = "FALSE";
+ private static final LogProvider log = Logging.getLogProvider(LdapIdentityStore.class);
+
protected FeatureSet featureSet = new FeatureSet(FeatureSet.FEATURE_ALL);
private String serverAddress = "localhost";
@@ -49,13 +53,17 @@
private int serverPort = 389;
private String userContextDN = "ou=Person,dc=acme,dc=com";
+
+ private String userDNPrefix = "uid=";
- private String roleContextDN = "ou=Role,dc=acme,dc=com";
+ private String userDNSuffix = ",ou=Person,dc=acme,dc=com";
- private String principalDNPrefix = "uid=";
+ private String roleContextDN = "ou=Role,dc=acme,dc=com";
- private String principalDNSuffix = ",ou=Person,dc=acme,dc=com";
+ private String roleDNPrefix = "cn=";
+ private String roleDNSuffix = ",ou=Roles,dc=acme,dc=com";
+
private String bindDN = "cn=Manager,dc=acme,dc=com";
private String bindCredentials = "secret";
@@ -84,6 +92,8 @@
private String[] userObjectClasses = { "person", "uidObject" };
+ private int searchScope = SearchControls.SUBTREE_SCOPE;
+
/**
* Time limit for LDAP searches, in milliseconds
*/
@@ -129,26 +139,46 @@
this.roleContextDN = roleContextDN;
}
- public String getPrincipalDNPrefix()
+ public String getUserDNPrefix()
{
- return principalDNPrefix;
+ return userDNPrefix;
}
- public void setPrincipalDNPrefix(String value)
+ public void setUserDNPrefix(String value)
{
- this.principalDNPrefix = value;
+ this.userDNPrefix = value;
}
- public String getPrincipalDNSuffix()
+ public String getUserDNSuffix()
{
- return principalDNSuffix;
+ return userDNSuffix;
}
- public void setPrincipalDNSuffix(String value)
+ public void setUserDNSuffix(String value)
{
- this.principalDNSuffix = value;
+ this.userDNSuffix = value;
}
+
+ public String getRoleDNPrefix()
+ {
+ return roleDNPrefix;
+ }
+ public void setRoleDNPrefix(String value)
+ {
+ this.roleDNPrefix = value;
+ }
+
+ public String getRoleDNSuffix()
+ {
+ return roleDNSuffix;
+ }
+
+ public void setRoleDNSuffix(String value)
+ {
+ this.roleDNSuffix = value;
+ }
+
public String getBindDN()
{
return bindDN;
@@ -299,6 +329,37 @@
this.searchTimeLimit = searchTimeLimit;
}
+ public String getSearchScope()
+ {
+ switch (searchScope)
+ {
+ case SearchControls.OBJECT_SCOPE: return "OBJECT_SCOPE";
+ case SearchControls.ONELEVEL_SCOPE : return "ONELEVEL_SCOPE";
+ case SearchControls.SUBTREE_SCOPE : return "SUBTREE_SCOPE";
+ default: return "UNKNOWN";
+ }
+ }
+
+ public void setSearchScope(String value)
+ {
+ if ("OBJECT_SCOPE".equals(value))
+ {
+ searchScope = SearchControls.OBJECT_SCOPE;
+ }
+ else if ("ONELEVEL_SCOPE".equals(value))
+ {
+ searchScope = SearchControls.ONELEVEL_SCOPE;
+ }
+ else
+ {
+ searchScope = SearchControls.SUBTREE_SCOPE;
+ if (!"SUBTREE_SCOPE".equals(value))
+ {
+ log.warn("Invalid search scope specified (" + value + ") - search scope set to SUBTREE_SCOPE");
+ }
+ }
+ }
+
public int getFeatures()
{
return featureSet.getFeatures();
@@ -336,16 +397,21 @@
InitialLdapContext ctx = new InitialLdapContext(env, null);
return ctx;
- }
+ }
protected String getUserDN(String username)
{
- return String.format("%s%s%s", getPrincipalDNPrefix(), username, getPrincipalDNSuffix());
+ return String.format("%s%s%s", getUserDNPrefix(), username, getUserDNSuffix());
}
+
+ protected String getRoleDN(String role)
+ {
+ return String.format("%s%s%s", getRoleDNPrefix(), role, getRoleDNSuffix());
+ }
public boolean authenticate(String username, String password)
{
- String securityPrincipal = getUserDN(username);
+ final String securityPrincipal = getUserDN(username);
InitialLdapContext ctx = null;
try
@@ -388,8 +454,32 @@
public boolean changePassword(String name, String password)
{
- // TODO Auto-generated method stub
- return false;
+ InitialLdapContext ctx = null;
+ try
+ {
+ ctx = initialiseContext();
+
+ BasicAttribute passwordAttrib = new BasicAttribute(getUserPasswordAttribute(), password);
+ ModificationItem mod = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, passwordAttrib);
+ ctx.modifyAttributes(getUserDN(name), new ModificationItem[] { mod });
+
+ return true;
+ }
+ catch (NamingException ex)
+ {
+ throw new IdentityManagementException("Failed to change password", ex);
+ }
+ finally
+ {
+ if (ctx != null)
+ {
+ try
+ {
+ ctx.close();
+ }
+ catch (NamingException ex) {}
+ }
+ }
}
public boolean createRole(String role)
@@ -410,7 +500,7 @@
roleAttribs.put(roleClass);
roleAttribs.put(new BasicAttribute(getRoleNameAttribute(), role));
- String roleDN = String.format("%s=%s,%s", getRoleNameAttribute(), role, getRoleContextDN() );
+ String roleDN = getRoleDN(role);
ctx.createSubcontext(roleDN, roleAttribs);
return true;
@@ -723,11 +813,7 @@
{
ctx = initialiseContext();
- String userFilter = "(" + getUserNameAttribute() + "={0})";
-
- // TODO make configurable
- int searchScope = SearchControls.SUBTREE_SCOPE;
-
+ String userFilter = "(" + getUserNameAttribute() + "={0})";
String[] roleAttr = { getUserRoleAttribute() };
SearchControls controls = new SearchControls();
@@ -806,14 +892,97 @@
}
public boolean grantRole(String name, String role)
- {
- // TODO Auto-generated method stub
- return false;
+ {
+ InitialLdapContext ctx = null;
+ try
+ {
+ ctx = initialiseContext();
+
+ String userDN = getUserDN(name);
+
+ BasicAttribute roleAttrib = new BasicAttribute(getUserRoleAttribute(),
+ getRoleAttributeIsDN() ? getRoleDN(role) : role);
+ ModificationItem mod = new ModificationItem(DirContext.ADD_ATTRIBUTE, roleAttrib);
+
+ ctx.modifyAttributes(userDN, new ModificationItem[] { mod });
+ return true;
+ }
+ catch (NamingException ex)
+ {
+ throw new IdentityManagementException("Failed to grant role", ex);
+ }
+ finally
+ {
+ if (ctx != null)
+ {
+ try
+ {
+ ctx.close();
+ }
+ catch (NamingException ex) {}
+ }
+ }
}
public boolean revokeRole(String name, String role)
- {
- // TODO Auto-generated method stub
+ {
+ InitialLdapContext ctx = null;
+ try
+ {
+ ctx = initialiseContext();
+ String userDN = getUserDN(name);
+
+ Attributes roleAttribs = ctx.getAttributes(userDN, new String[] { getUserRoleAttribute() });
+ Attribute roleAttrib = roleAttribs.get( getUserRoleAttribute() );
+ if (roleAttrib != null)
+ {
+ boolean modified = false;
+ for (int i = roleAttrib.size() - 1; i >= 0; i--)
+ {
+ if (getRoleAttributeIsDN())
+ {
+ Attributes attribs = ctx.getAttributes((String) roleAttrib.get(i),
+ new String[] { getRoleNameAttribute() });
+ Attribute roleNameAttrib = attribs.get( getRoleNameAttribute() );
+ for (int j = 0; j < roleNameAttrib.size(); j++)
+ {
+ if (role.equals(roleNameAttrib.get(j)))
+ {
+ modified = true;
+ roleAttrib.remove(i);
+ }
+ }
+ }
+ else if (role.equals(roleAttrib.get(i)))
+ {
+ modified = true;
+ roleAttrib.remove(i);
+ }
+ }
+
+ if (modified)
+ {
+ ModificationItem mod = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, roleAttrib);
+ ctx.modifyAttributes(userDN, new ModificationItem[] { mod });
+ }
+ }
+ }
+ catch (NamingException ex)
+ {
+ throw new IdentityManagementException("Failed to grant role", ex);
+ }
+ finally
+ {
+ if (ctx != null)
+ {
+ try
+ {
+ ctx.close();
+ }
+ catch (NamingException ex) {}
+ }
+ }
+
return false;
}
@@ -824,11 +993,8 @@
InitialLdapContext ctx = null;
try
{
- ctx = initialiseContext();
+ ctx = initialiseContext();
- // TODO make configurable
- int searchScope = SearchControls.SUBTREE_SCOPE;
-
String[] roleAttr = { getRoleNameAttribute() };
SearchControls controls = new SearchControls();
@@ -885,16 +1051,18 @@
public List<String> listUsers()
{
+ return listUsers(null);
+ }
+
+ public List<String> listUsers(String filter)
+ {
List<String> users = new ArrayList<String>();
InitialLdapContext ctx = null;
try
{
ctx = initialiseContext();
-
- // TODO make configurable
- int searchScope = SearchControls.SUBTREE_SCOPE;
-
+
String[] userAttr = {getUserNameAttribute()};
SearchControls controls = new SearchControls();
@@ -925,7 +1093,18 @@
for (int i = 0; i < user.size(); i++)
{
Object value = user.get(i);
- users.add(value.toString());
+
+ if (filter != null)
+ {
+ if (value.toString().toLowerCase().contains(filter.toLowerCase()))
+ {
+ users.add(value.toString());
+ }
+ }
+ else
+ {
+ users.add(value.toString());
+ }
}
}
answer.close();
@@ -948,16 +1127,67 @@
}
}
- public List<String> listUsers(String filter)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
public boolean userExists(String name)
{
- // TODO Auto-generated method stub
- return false;
+ InitialLdapContext ctx = null;
+ try
+ {
+ ctx = initialiseContext();
+
+ String[] userAttr = {getUserNameAttribute()};
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope(searchScope);
+ controls.setReturningAttributes(userAttr);
+ controls.setTimeLimit(getSearchTimeLimit());
+
+ StringBuilder userFilter = new StringBuilder();
+
+ Object[] filterArgs = new Object[getUserObjectClasses().length];
+ for (int i = 0; i < getUserObjectClasses().length; i++)
+ {
+ userFilter.append("(");
+ userFilter.append(getObjectClassAttribute());
+ userFilter.append("={");
+ userFilter.append(i);
+ userFilter.append("})");
+ filterArgs[i] = getUserObjectClasses()[i];
+ }
+
+ NamingEnumeration answer = ctx.search(getUserContextDN(), userFilter.toString(), filterArgs, controls);
+ while (answer.hasMore())
+ {
+ SearchResult sr = (SearchResult) answer.next();
+ Attributes attrs = sr.getAttributes();
+ Attribute user = attrs.get(getUserNameAttribute());
+
+ for (int i = 0; i < user.size(); i++)
+ {
+ Object value = user.get(i);
+ if (name.equals(value))
+ {
+ answer.close();
+ return true;
+ }
+ }
+ }
+ answer.close();
+ return false;
+ }
+ catch (NamingException ex)
+ {
+ throw new IdentityManagementException("Error getting users", ex);
+ }
+ finally
+ {
+ if (ctx != null)
+ {
+ try
+ {
+ ctx.close();
+ }
+ catch (NamingException ex) {}
+ }
+ }
}
-
}
16 years, 8 months
Seam SVN: r7746 - branches/Seam_2_0/src/main/org/jboss/seam.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-03-30 19:52:26 -0400 (Sun, 30 Mar 2008)
New Revision: 7746
Modified:
branches/Seam_2_0/src/main/org/jboss/seam/Entity.java
Log:
ws
Modified: branches/Seam_2_0/src/main/org/jboss/seam/Entity.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/Entity.java 2008-03-30 23:37:16 UTC (rev 7745)
+++ branches/Seam_2_0/src/main/org/jboss/seam/Entity.java 2008-03-30 23:52:26 UTC (rev 7746)
@@ -21,10 +21,8 @@
/**
* Metamodel class for entity classes.
*
- * A class will be identified as an entity class if it has an
+ * A class will be identified as an entity class if it has an @Entity annotation.
*
- * @Entity annotation.
- *
* @author Gavin King
*
*/
16 years, 8 months
Seam SVN: r7745 - in branches/Seam_2_0: src/main/org/jboss/seam and 5 other directories.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-03-30 19:37:16 -0400 (Sun, 30 Mar 2008)
New Revision: 7745
Added:
branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java
branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java
Modified:
branches/Seam_2_0/doc/Seam_Reference_Guide/en/Security.xml
branches/Seam_2_0/src/main/org/jboss/seam/Entity.java
branches/Seam_2_0/src/main/org/jboss/seam/Seam.java
branches/Seam_2_0/src/main/org/jboss/seam/contexts/PassivatedEntity.java
branches/Seam_2_0/src/main/org/jboss/seam/contexts/ServerConversationContext.java
branches/Seam_2_0/src/main/org/jboss/seam/contexts/SessionContext.java
branches/Seam_2_0/src/main/org/jboss/seam/init/DeploymentDescriptor.java
branches/Seam_2_0/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java
branches/Seam_2_0/src/main/org/jboss/seam/persistence/ManagedEntityIdentityInterceptor.java
branches/Seam_2_0/src/main/org/jboss/seam/persistence/PersistenceProvider.java
branches/Seam_2_0/src/main/org/jboss/seam/security/EntityPermissionChecker.java
branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java
branches/Seam_2_0/src/main/org/jboss/seam/security/Identity.java
branches/Seam_2_0/src/main/org/jboss/seam/util/Reflections.java
Log:
JBSEAM-2029, reworked Entity meta model
Modified: branches/Seam_2_0/doc/Seam_Reference_Guide/en/Security.xml
===================================================================
--- branches/Seam_2_0/doc/Seam_Reference_Guide/en/Security.xml 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/doc/Seam_Reference_Guide/en/Security.xml 2008-03-30 23:37:16 UTC (rev 7745)
@@ -1,3 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
<chapter id="security">
<title>Security</title>
@@ -931,6 +933,32 @@
public void prePersist() {}
]]></programlisting>
+ <note>
+ <title>Using <literal>/META-INF/orm.xml</literal></title>
+
+
+ <para>
+ You can also specify the call back method in <literal>/META-INF/orm.xml</literal>:
+ </para>
+
+ <programlisting role="XML"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
+ version="1.0">
+
+ <entity class="Customer">
+ <pre-persist method-name="prePersist" />
+ </entity>
+
+</entity-mappings>]]></programlisting>
+
+ <para>
+ Of course, you still need to annotate the <literal>prePersist()</literal>
+ method on <literal>Customer</literal> with <literal>@Restrict</literal>
+ </para>
+ </note>
+
<para>
And here's an example of an entity permission rule that checks if the authenticated user is allowed to insert
a new <literal>MemberBlog</literal> record (from the seamspace example). The entity for which the security
@@ -990,10 +1018,11 @@
</sect3>
<sect3>
- <title>Entity security with Hibernate</title>
+ <title>Entity security with a Managed Hibernate Session</title>
<para>
- If you are using a Hibernate <literal>SessionFactory</literal> configured via Seam, you don't
+ If you are using a Hibernate <literal>SessionFactory</literal> configured via Seam,
+ and are using annotations, or <literal>orm.xml</literal>, then you don't
need to do anything special to use entity security.
</para>
Modified: branches/Seam_2_0/src/main/org/jboss/seam/Entity.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/Entity.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/Entity.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -1,5 +1,6 @@
package org.jboss.seam;
+import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -12,20 +13,24 @@
import javax.persistence.Version;
import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.init.EjbDescriptor;
+import org.jboss.seam.init.EjbEntityDescriptor;
+import org.jboss.seam.persistence.PersistenceProvider;
import org.jboss.seam.util.Reflections;
/**
* Metamodel class for entity classes.
*
- * A class will be identified as an entity class
- * if it has an @Entity annotation.
+ * A class will be identified as an entity class if it has an
*
+ * @Entity annotation.
+ *
* @author Gavin King
- *
+ *
*/
public class Entity extends Model
{
-
+
private Method preRemoveMethod;
private Method prePersistMethod;
private Method preUpdateMethod;
@@ -36,85 +41,22 @@
private Field versionField;
private String name;
+ /**
+ *
+ * @param beanClass
+ */
public Entity(Class<?> beanClass)
{
super(beanClass);
-
- if (beanClass.isAnnotationPresent(javax.persistence.Entity.class))
+ EjbDescriptor descriptor = Seam.getEjbDescriptor(beanClass);
+ if (descriptor instanceof EjbEntityDescriptor)
{
- if (!"".equals(beanClass.getAnnotation(javax.persistence.Entity.class).name()))
- {
- name = beanClass.getAnnotation(javax.persistence.Entity.class).name();
- }
- else
- {
- name = beanClass.getName();
- }
+ mergeAnnotationAndOrmXml((EjbEntityDescriptor) descriptor);
}
-
- for ( Class<?> clazz=beanClass; clazz!=Object.class; clazz = clazz.getSuperclass() )
+ else
{
-
- for ( Method method: clazz.getDeclaredMethods() )
- {
- //TODO: does the spec allow multiple lifecycle method
- // in the entity class heirarchy?
- if ( method.isAnnotationPresent(PreRemove.class) )
- {
- preRemoveMethod = method;
- }
- if ( method.isAnnotationPresent(PrePersist.class) )
- {
- prePersistMethod = method;
- }
- if ( method.isAnnotationPresent(PreUpdate.class) )
- {
- preUpdateMethod = method;
- }
- if ( method.isAnnotationPresent(PostLoad.class) )
- {
- postLoadMethod = method;
- }
- if ( method.isAnnotationPresent(Id.class) || method.isAnnotationPresent(EmbeddedId.class))
- {
- identifierGetter = method;
- }
- if ( method.isAnnotationPresent(Version.class) )
- {
- versionGetter = method;
- }
-
- if ( !method.isAccessible() )
- {
- method.setAccessible(true);
- }
- }
-
- if (identifierGetter==null)
- {
- for ( Field field: clazz.getDeclaredFields() )
- {
- if ( field.isAnnotationPresent(Id.class) || field.isAnnotationPresent(EmbeddedId.class))
- {
- identifierField = field;
- if ( !field.isAccessible() )
- {
- field.setAccessible(true);
- }
- }
- if ( field.isAnnotationPresent(Version.class) )
- {
- versionField = field;
- if ( !field.isAccessible() )
- {
- field.setAccessible(true);
- }
- }
- }
- }
-
+ mergeAnnotationAndOrmXml(null);
}
-
}
public Method getPostLoadMethod()
@@ -137,33 +79,37 @@
return preUpdateMethod;
}
+ @Deprecated
public Field getIdentifierField()
{
return identifierField;
}
+ @Deprecated
public Method getIdentifierGetter()
{
return identifierGetter;
}
-
+
+ @Deprecated
public Field getVersionField()
{
return versionField;
}
+ @Deprecated
public Method getVersionGetter()
{
return versionGetter;
}
-
+
public Object getIdentifier(Object entity)
{
- if (identifierGetter!=null)
+ if (identifierGetter != null)
{
return Reflections.invokeAndWrap(identifierGetter, entity);
}
- else if (identifierField!=null)
+ else if (identifierField != null)
{
return Reflections.getAndWrap(identifierField, entity);
}
@@ -175,11 +121,11 @@
public Object getVersion(Object entity)
{
- if (versionGetter!=null)
+ if (versionGetter != null)
{
return Reflections.invokeAndWrap(versionGetter, entity);
}
- else if (versionField!=null)
+ else if (versionField != null)
{
return Reflections.getAndWrap(versionField, entity);
}
@@ -188,31 +134,35 @@
return null;
}
}
-
+
public String getName()
{
return name;
}
- public static Entity forClass(Class clazz)
+ public static Entity forBean(Object bean)
{
- if ( !Contexts.isApplicationContextActive() )
+ if (!Contexts.isApplicationContextActive())
{
throw new IllegalStateException("No application context active");
}
- Class entityClass = Seam.getEntityClass(clazz);
+ Class beanClass = PersistenceProvider.instance().getBeanClass(bean);
- if (entityClass==null)
+ if (beanClass == null)
{
- throw new IllegalArgumentException("Not an entity class: " + clazz.getName());
+ throw new NotEntityException("Not an entity class: " + bean.getClass().getName());
}
-
- String name = getModelName(entityClass);
+ return forBeanClass(beanClass);
+ }
+
+ private static Entity forBeanClass(Class beanClass)
+ {
+ String name = getModelName(beanClass);
Model model = (Model) Contexts.getApplicationContext().get(name);
- if ( model==null || !(model instanceof Entity) )
+ if (model == null || !(model instanceof Entity))
{
- Entity entity = new Entity(entityClass);
+ Entity entity = new Entity(beanClass);
Contexts.getApplicationContext().set(name, entity);
return entity;
}
@@ -221,5 +171,171 @@
return (Entity) model;
}
}
+
+ @Deprecated
+ public static Entity forClass(Class clazz)
+ {
+ if (!Contexts.isApplicationContextActive())
+ {
+ throw new IllegalStateException("No application context active");
+ }
+ Class entityClass = PersistenceProvider.getEntityClass(clazz);
+
+ if (entityClass == null)
+ {
+ throw new NotEntityException("Not an entity class: " + clazz.getName());
+ }
+ return forBeanClass(entityClass);
+ }
+
+ private void mergeAnnotationAndOrmXml(EjbEntityDescriptor descriptor)
+ {
+ // Lookup the name of the Entity from XML, annotation or default
+ this.name = lookupName(getBeanClass(), descriptor);
+ if (this.name == null)
+ {
+ throw new NotEntityException("Unable to establish name of entity " + getBeanClass());
+ }
+
+ if (descriptor != null)
+ {
+ // Set any methods and fields we need metadata for from the XML
+ // descriptor. These take priority over annotations
+
+ this.preRemoveMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPreRemoveMethodName());
+ this.prePersistMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPrePersistMethodName());
+ this.preUpdateMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPreUpdateMethodName());
+ this.postLoadMethod = getEntityCallbackMethod(getBeanClass(), descriptor.getPostLoadMethodName());
+
+ this.identifierField = descriptor.getIdentifierFieldName() != null ? Reflections.getField(getBeanClass(), descriptor.getIdentifierFieldName()) : null;
+ this.identifierGetter = descriptor.getIdentifierPropertyName() != null ? Reflections.getGetterMethod(getBeanClass(), descriptor.getIdentifierPropertyName()) : null;
+
+ this.versionField = descriptor.getVersionFieldName() != null ? Reflections.getField(getBeanClass(), descriptor.getVersionFieldName()) : null;
+ this.versionGetter = descriptor.getVersionPropertyName() != null ? Reflections.getGetterMethod(getBeanClass(), descriptor.getVersionPropertyName()) : null;
+ }
+
+ if (descriptor == null || !descriptor.isMetaDataComplete())
+ {
+ for ( Class<?> clazz=getBeanClass(); clazz!=Object.class; clazz = clazz.getSuperclass() )
+ {
+
+ for ( Method method: clazz.getDeclaredMethods() )
+ {
+ //TODO: does the spec allow multiple lifecycle method
+ // in the entity class heirarchy?
+ if (this.preRemoveMethod == null && method.isAnnotationPresent(PreRemove.class))
+ {
+ this.preRemoveMethod = method;
+ }
+ if (this.prePersistMethod == null && method.isAnnotationPresent(PrePersist.class) )
+ {
+ this.prePersistMethod = method;
+ }
+ if (preUpdateMethod == null && method.isAnnotationPresent(PreUpdate.class) )
+ {
+ preUpdateMethod = method;
+ }
+ if (postLoadMethod == null && method.isAnnotationPresent(PostLoad.class) )
+ {
+ postLoadMethod = method;
+ }
+ if (identifierField == null && identifierGetter == null && method.isAnnotationPresent(Id.class) || method.isAnnotationPresent(EmbeddedId.class))
+ {
+ identifierGetter = method;
+ }
+ if (versionField == null && versionGetter == null && method.isAnnotationPresent(Version.class) )
+ {
+ versionGetter = method;
+ }
+ }
+
+ if ( ( identifierGetter == null && identifierField == null ) || ( versionField == null && versionGetter == null ) )
+ {
+ for ( Field field: clazz.getDeclaredFields() )
+ {
+ if ( identifierGetter == null && identifierField == null && (field.isAnnotationPresent(Id.class) || field.isAnnotationPresent(EmbeddedId.class)))
+ {
+ identifierField = field;
+ }
+ if ( versionGetter == null && versionField == null && field.isAnnotationPresent(Version.class) )
+ {
+ versionField = field;
+ }
+ }
+ }
+ }
+ }
+
+ setAccessible(this.preRemoveMethod);
+ setAccessible(this.prePersistMethod);
+ setAccessible(this.preUpdateMethod);
+ setAccessible(this.postLoadMethod);
+ setAccessible(this.identifierField);
+ setAccessible(this.identifierGetter);
+ setAccessible(this.versionField);
+ setAccessible(this.versionGetter);
+ }
+
+ private void setAccessible(AccessibleObject accessibleObject)
+ {
+ if (accessibleObject != null)
+ {
+ accessibleObject.setAccessible(true);
+ }
+ }
+
+ private static String lookupName(Class<?> beanClass, EjbEntityDescriptor descriptor)
+ {
+ if (descriptor != null && descriptor.getEjbName() != null)
+ {
+ // XML overrides annotations
+ return descriptor.getEjbName();
+ }
+ else if ( (descriptor == null || !descriptor.isMetaDataComplete()) && beanClass.isAnnotationPresent(javax.persistence.Entity.class) && !"".equals(beanClass.getAnnotation(javax.persistence.Entity.class).name()))
+ {
+ // Is a name specified?
+ return beanClass.getAnnotation(javax.persistence.Entity.class).name();
+ }
+ else if (descriptor != null || beanClass.isAnnotationPresent(javax.persistence.Entity.class))
+ {
+ // Use the default name if either a descriptor is specified or the
+ // annotation is present
+ return beanClass.getName();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private static Method getEntityCallbackMethod(Class beanClass, String callbackMethodName)
+ {
+ try
+ {
+ if (callbackMethodName != null)
+ {
+ return Reflections.getMethod(beanClass, callbackMethodName);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IllegalArgumentException("Unable to find Entity callback method specified in orm.xml", e);
+ }
+ }
+
+ public static class NotEntityException extends IllegalArgumentException
+ {
+
+ public NotEntityException(String string)
+ {
+ super(string);
+ }
+
+ }
+
}
Modified: branches/Seam_2_0/src/main/org/jboss/seam/Seam.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/Seam.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/Seam.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -24,6 +24,7 @@
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.init.EjbDescriptor;
import org.jboss.seam.init.DeploymentDescriptor;
+import org.jboss.seam.persistence.PersistenceProvider;
import org.jboss.seam.util.Strings;
import org.jboss.seam.web.Session;
@@ -37,22 +38,28 @@
{
private static final Map<Class, String> COMPONENT_NAME_CACHE = new ConcurrentHashMap<Class, String>();
- private static final Map<Class, EjbDescriptor> EJB_DESCRIPTOR_CACHE = new ConcurrentHashMap<Class, EjbDescriptor>();
+ private static final Map<String, EjbDescriptor> EJB_DESCRIPTOR_CACHE = new ConcurrentHashMap<String, EjbDescriptor>();
- private static EjbDescriptor getEjbDescriptor(Class clazz)
+ public static EjbDescriptor getEjbDescriptor(String className)
{
- EjbDescriptor info = EJB_DESCRIPTOR_CACHE.get(clazz);
+ EjbDescriptor info = EJB_DESCRIPTOR_CACHE.get(className);
if (info != null)
{
return info;
}
else
{
- Map<Class, EjbDescriptor> ejbDescriptors = new DeploymentDescriptor(clazz).getEjbDescriptors();
+ Map<String, EjbDescriptor> ejbDescriptors = new DeploymentDescriptor().getEjbDescriptors();
EJB_DESCRIPTOR_CACHE.putAll(ejbDescriptors);
- return ejbDescriptors.get(clazz);
+ return ejbDescriptors.get(className);
}
}
+
+ // TODO Better impl
+ static EjbDescriptor getEjbDescriptor(Class clazz)
+ {
+ return getEjbDescriptor(clazz.getName());
+ }
/**
* Get the default scope
@@ -143,36 +150,20 @@
/**
* Get the bean class from a container-generated proxy
* class
+ *
+ * Use PersistenceProvider.instance().getBeanClass(bean) instead
*/
+ @Deprecated
public static Class getEntityClass(Class<?> clazz)
{
- while ( clazz!=null && !Object.class.equals(clazz) )
- {
- if ( clazz.isAnnotationPresent(Entity.class) )
- {
- return clazz;
- }
- else
- {
- EjbDescriptor ejbDescriptor = EJB_DESCRIPTOR_CACHE.get(clazz);
- if ( ejbDescriptor!=null )
- {
- return ejbDescriptor.getBeanType()==ComponentType.ENTITY_BEAN ?
- clazz : null;
- }
- else
- {
- clazz = clazz.getSuperclass();
- }
- }
- }
- return null;
- }
+ return PersistenceProvider.getEntityClass(clazz);
+ }
/**
* Is the class a container-generated proxy class for an
* entity bean?
*/
+ @Deprecated
public static boolean isEntityClass(Class<?> clazz)
{
return getEntityClass(clazz)!=null;
Modified: branches/Seam_2_0/src/main/org/jboss/seam/contexts/PassivatedEntity.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/contexts/PassivatedEntity.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/contexts/PassivatedEntity.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -6,7 +6,6 @@
import org.hibernate.Session;
import org.jboss.seam.Component;
-import org.jboss.seam.Seam;
import org.jboss.seam.persistence.HibernatePersistenceProvider;
import org.jboss.seam.persistence.PersistenceContexts;
import org.jboss.seam.persistence.PersistenceProvider;
@@ -152,7 +151,7 @@
public static PassivatedEntity passivateEntity(Object value)
{
- Class entityClass = Seam.getEntityClass( value.getClass() );
+ Class entityClass = PersistenceProvider.getEntityClass(value.getClass());
if (entityClass!=null)
{
for ( String persistenceContextName: PersistenceContexts.instance().getTouchedContexts() )
Modified: branches/Seam_2_0/src/main/org/jboss/seam/contexts/ServerConversationContext.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/contexts/ServerConversationContext.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/contexts/ServerConversationContext.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -15,9 +15,9 @@
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.Seam;
import org.jboss.seam.core.Events;
import org.jboss.seam.core.Manager;
+import org.jboss.seam.persistence.PersistenceProvider;
/**
* A conversation context is a logical context that lasts longer than
@@ -155,7 +155,7 @@
else
{
removals.remove(name);
- if ( Seam.isEntityClass( value.getClass() ) )
+ if ( PersistenceProvider.getEntityClass(value.getClass()) != null )
{
value = new EntityBean(value);
}
Modified: branches/Seam_2_0/src/main/org/jboss/seam/contexts/SessionContext.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/contexts/SessionContext.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/contexts/SessionContext.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -10,7 +10,7 @@
import java.util.Map;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.Seam;
+import org.jboss.seam.persistence.PersistenceProvider;
/**
* Session context - state associated with a user session.
@@ -48,7 +48,7 @@
{
Object attribute = get(name);
boolean dirty = attribute!=null &&
- ( Contexts.isAttributeDirty(attribute) || Seam.isEntityClass( attribute.getClass() ) );
+ ( Contexts.isAttributeDirty(attribute) || PersistenceProvider.getEntityClass(attribute.getClass()) != null );
if ( dirty )
{
set(name, attribute);
Modified: branches/Seam_2_0/src/main/org/jboss/seam/init/DeploymentDescriptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/init/DeploymentDescriptor.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/init/DeploymentDescriptor.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -10,6 +10,7 @@
import org.jboss.seam.ComponentType;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
+import org.jboss.seam.util.Resources;
import org.jboss.seam.util.XML;
/**
@@ -22,19 +23,13 @@
{
private static final LogProvider log = Logging.getLogProvider(Initialization.class);
- private Map<Class, EjbDescriptor> ejbDescriptors = new HashMap<Class, EjbDescriptor>();
- private Class componentClass;
+ private Map<String, EjbDescriptor> ejbDescriptors = new HashMap<String, EjbDescriptor>();
- public DeploymentDescriptor(Class clazz)
+ public DeploymentDescriptor()
{
- componentClass = clazz;
- if (clazz.getClassLoader() == null) {
- return;
- }
-
try
{
- InputStream ejbJarXml = clazz.getClassLoader().getResourceAsStream("META-INF/ejb-jar.xml");
+ InputStream ejbJarXml = Resources.getResourceAsStream("META-INF/ejb-jar.xml", null);
if (ejbJarXml!=null)
{
parseEjbJarXml( XML.getRootElementSafely(ejbJarXml) );
@@ -47,7 +42,7 @@
try
{
- InputStream ormXml = clazz.getClassLoader().getResourceAsStream("META-INF/orm.xml");
+ InputStream ormXml = Resources.getResourceAsStream("META-INF/orm.xml", null);
if (ormXml!=null)
{
parseOrmXml( XML.getRootElementSafely(ormXml) );
@@ -59,7 +54,7 @@
}
}
- public Map<Class, EjbDescriptor> getEjbDescriptors()
+ public Map<String, EjbDescriptor> getEjbDescriptors()
{
return ejbDescriptors;
}
@@ -113,27 +108,95 @@
{
packagePrefix = pkg.getTextTrim() + ".";
}
+
+ String defaultAccessType = getDefaultAccessType(root);
+
+ boolean defaultMetadataComplete = isDefaultMetadataComplete(root);
for (Element entity: (List<Element>) root.elements("entity"))
{
String className = packagePrefix + entity.attribute("class").getText();
- EjbDescriptor info = new EjbDescriptor();
+ EjbEntityDescriptor info = new EjbEntityDescriptor();
info.setBeanType(ComponentType.ENTITY_BEAN);
info.setEjbClassName(className);
+ info.setEjbName(entity.attribute("name") != null ? entity.attribute("name").getText() : null);
+ if (defaultMetadataComplete || entity.attribute("metadata-complete") != null)
+ {
+ info.setMetaDataComplete(defaultMetadataComplete || "true".equals(entity.attribute("metadata-complete").getText()));
+ }
+ info.setPreRemoveMethodName(getEntityCallback(entity, "pre-remove"));
+ info.setPrePersistMethodName(getEntityCallback(entity, "pre-persist"));
+ info.setPreUpdateMethodName(getEntityCallback(entity, "pre-update"));
+ info.setPostLoadMethodName(getEntityCallback(entity, "post-load"));
+ info.setIdentifierAttribute(getEntityAttributeName(entity, "id"), getAccessType(getEntityAttributeAccessType(entity, "id"), defaultAccessType));
+ info.setVersionAttribute(getEntityAttributeName(entity, "version"), getAccessType(getEntityAttributeAccessType(entity, "version"), defaultAccessType));
add(info);
}
}
-
- protected void add(EjbDescriptor descriptor)
+
+ private static String getEntityCallback(Element parent, String callbackName)
{
- try
+ Element callbackElement = parent.element(callbackName);
+ if (callbackElement != null)
{
- Class ejbClass = componentClass.getClassLoader().loadClass( descriptor.getEjbClassName() );
- ejbDescriptors.put(ejbClass, descriptor);
+ return callbackElement.attribute("method-name").getText();
}
- catch (ClassNotFoundException cnfe)
+ return null;
+ }
+
+ private static String getEntityAttributeName(Element entity, String attributeName)
+ {
+ if (entity.element("attributes") != null && entity.element("attributes").element(attributeName) != null)
{
- log.warn("Could not load EJB class: " + descriptor.getEjbClassName());
+ return entity.element("attributes").element(attributeName).attribute("name").getText();
}
+
+ return null;
+
}
+
+ private static String getEntityAttributeAccessType(Element entity, String attributeName)
+ {
+ if (entity.element("attributes") != null && entity.element("attributes").element(attributeName) != null)
+ {
+ if (entity.element("attributes").element(attributeName).attribute("access") != null)
+ {
+ return entity.element("attributes").element(attributeName).attribute("access").getText();
+ }
+ }
+
+ return null;
+ }
+
+ private static String getDefaultAccessType(Element root)
+ {
+ if (root.element("access") != null)
+ {
+ return root.element("access").getText();
+ }
+ else
+ {
+ if (root.element("persistence-unit-metadata") != null && root.element("persistence-unit-metadata").element("persistence-unit-defaults") != null && root.element("persistence-unit-metadata").element("persistence-unit-defaults").element("access") != null )
+ {
+ return root.element("persistence-unit-metadata").element("persistence-unit-defaults").element("access").getText();
+ }
+ }
+ return null;
+ }
+
+ private static boolean isDefaultMetadataComplete(Element root)
+ {
+ return root.element("persistence-unit-metadata") != null && root.element("persistence-unit-metadata").element("xml-mapping-metadata-complete") != null;
+ }
+
+
+ private static String getAccessType(String accessType, String defaultAccessType)
+ {
+ return accessType != null ? accessType : (defaultAccessType != null ? defaultAccessType : "FIELD");
+ }
+
+ protected void add(EjbDescriptor descriptor)
+ {
+ ejbDescriptors.put(descriptor.getEjbClassName(), descriptor);
+ }
}
Added: branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java (rev 0)
+++ branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -0,0 +1,138 @@
+package org.jboss.seam.init;
+
+public class EjbEntityDescriptor extends EjbDescriptor
+{
+
+ private boolean metaDataComplete;
+
+ private String preRemoveMethodName;
+ private String prePersistMethodName;
+ private String preUpdateMethodName;
+ private String postLoadMethodName;
+ private String identifierPropertyName;
+ private String identifierFieldName;
+ private String versionPropertyName;
+ private String versionFieldName;
+
+
+ public String getPreRemoveMethodName()
+ {
+ return preRemoveMethodName;
+ }
+
+ public void setPreRemoveMethodName(String preRemoveMethodName)
+ {
+ this.preRemoveMethodName = preRemoveMethodName;
+ }
+
+ public String getPrePersistMethodName()
+ {
+ return prePersistMethodName;
+ }
+
+ public void setPrePersistMethodName(String prePersistMethodName)
+ {
+ this.prePersistMethodName = prePersistMethodName;
+ }
+
+ public String getPreUpdateMethodName()
+ {
+ return preUpdateMethodName;
+ }
+
+ public void setPreUpdateMethodName(String preUpdateMethodName)
+ {
+ this.preUpdateMethodName = preUpdateMethodName;
+ }
+
+ public String getPostLoadMethodName()
+ {
+ return postLoadMethodName;
+ }
+
+ public void setPostLoadMethodName(String postLoadMethodName)
+ {
+ this.postLoadMethodName = postLoadMethodName;
+ }
+
+ public String getIdentifierPropertyName()
+ {
+ return identifierPropertyName;
+ }
+
+ public void setIdentifierPropertyName(String identifierProperty)
+ {
+ this.identifierPropertyName = identifierProperty;
+ }
+
+ public String getVersionPropertyName()
+ {
+ return versionPropertyName;
+ }
+
+ public void setVersionPropertyName(String versionProperty)
+ {
+ this.versionPropertyName = versionProperty;
+ }
+
+ public String getIdentifierFieldName()
+ {
+ return identifierFieldName;
+ }
+
+ public void setIdentifierFieldName(String identifierField)
+ {
+ this.identifierFieldName = identifierField;
+ }
+
+ public String getVersionFieldName()
+ {
+ return versionFieldName;
+ }
+
+ public void setVersionFieldName(String versionField)
+ {
+ this.versionFieldName = versionField;
+ }
+
+ public void setVersionAttribute(String versionAttributeName, String accessType)
+ {
+ if (accessType != null)
+ {
+ if (accessType == "PROPERTY")
+ {
+ this.versionPropertyName = versionAttributeName;
+ }
+ else if (accessType == "FIELD")
+ {
+ this.versionFieldName = versionAttributeName;
+ }
+ }
+ }
+
+ public void setIdentifierAttribute(String identifierAttributeName, String accessType)
+ {
+ if (accessType != null)
+ {
+ if (accessType == "PROPERTY")
+ {
+ this.identifierPropertyName = identifierAttributeName;
+ }
+ else if (accessType == "FIELD")
+ {
+ this.identifierFieldName = identifierAttributeName;
+ }
+ }
+ }
+
+ public boolean isMetaDataComplete()
+ {
+ return metaDataComplete;
+ }
+
+ public void setMetaDataComplete(boolean metaDataComplete)
+ {
+ this.metaDataComplete = metaDataComplete;
+ }
+
+}
Property changes on: branches/Seam_2_0/src/main/org/jboss/seam/init/EjbEntityDescriptor.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: branches/Seam_2_0/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/persistence/HibernatePersistenceProvider.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -4,7 +4,6 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
@@ -16,15 +15,10 @@
import org.hibernate.Session;
import org.hibernate.StaleStateException;
import org.hibernate.TransientObjectException;
-import org.hibernate.ejb.event.Callback;
-import org.hibernate.ejb.event.EJB3PostLoadEventListener;
-import org.hibernate.ejb.event.EntityCallbackHandler;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.PostLoadEventListener;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.type.VersionType;
+import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.Seam;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
@@ -296,7 +290,7 @@
private static ClassMetadata getClassMetadata(Object value, Session session)
{
- Class entityClass = Seam.getEntityClass( value.getClass() );
+ Class entityClass = getEntityClass(value);
ClassMetadata classMetadata = null;
if (entityClass!=null)
{
@@ -318,135 +312,19 @@
@Override
public Class getBeanClass(Object bean)
{
- try
- {
- return super.getBeanClass(bean);
- }
- catch (IllegalArgumentException iae)
- {
- return Hibernate.getClass(bean);
- }
+ return getEntityClass(bean);
}
- /**
- * A nasty hack until we get a nicer method in Hibernate to use instead
- *
- * TODO fix this once Hibernate exposes an API method to return the callback method/s for a
- * given bean class
- *
- * @param entityManager
- * @return
- */
- private EntityCallbackHandler getCallbackHandler(Session session)
+ public static Class getEntityClass(Object bean)
{
- PostLoadEventListener[] listeners = ((SessionImplementor) session)
- .getListeners().getPostLoadEventListeners();
-
- for (PostLoadEventListener listener : listeners)
+ Class clazz = PersistenceProvider.getEntityClass(bean.getClass());
+ if (clazz == null)
{
- if (listener instanceof EJB3PostLoadEventListener)
- {
- try
- {
- Field callbackHandlerField = EJB3PostLoadEventListener.class.getField("callbackHandler");
- return (EntityCallbackHandler) callbackHandlerField.get(listener);
- }
- catch (Exception ex)
- {
- throw new RuntimeException(ex);
- }
- }
- }
- return null;
- }
-
- /**
- * More nastiness
- *
- * @param handler
- * @param fieldName
- * @return
- */
- private Callback[] getCallbacks(EntityCallbackHandler handler, String fieldName, Class beanClass)
- {
- try
- {
- Field f = EntityCallbackHandler.class.getDeclaredField(fieldName);
- boolean isAccessible = f.isAccessible();
- try
- {
- f.setAccessible(true);
- HashMap<Class,Callback[]> callbacks = (HashMap<Class,Callback[]>) f.get(handler);
- return callbacks.get(beanClass);
- }
- finally
- {
- f.setAccessible(isAccessible);
- }
+ clazz = Hibernate.getClass(bean);
}
- catch (Exception ex)
- {
- throw new RuntimeException(ex);
- }
+ return clazz;
}
- private Method getCallbackMethod(Object persistenceContext, Class beanClass, String callbackFieldName)
- {
- EntityCallbackHandler callbackHandler = null;
-
- if (persistenceContext instanceof EntityManager)
- {
- callbackHandler = getCallbackHandler(getSession((EntityManager) persistenceContext));
- }
- else if (persistenceContext instanceof Session)
- {
- callbackHandler = getCallbackHandler((Session) persistenceContext);
- }
-
- if (callbackHandler == null)
- {
- throw new RuntimeException("Could not determine callback handler for persistence context " +
- persistenceContext);
- }
-
- Callback[] callbacks = getCallbacks(callbackHandler, callbackFieldName, beanClass);
-
- if (callbacks != null)
- {
- for (Callback cb : callbacks)
- {
- return cb.getCallbackMethod();
- }
- }
-
- return null;
- }
-
- /*@Override
- public Method getPostLoadMethod(Class beanClass, Object persistenceContext)
- {
- return getCallbackMethod(persistenceContext, beanClass, "postLoads");
- }
-
-
- @Override
- public Method getPrePersistMethod(Class beanClass, Object persistenceContext)
- {
- return getCallbackMethod(persistenceContext, beanClass, "preCreates");
- }
-
- @Override
- public Method getPreUpdateMethod(Class beanClass, Object persistenceContext)
- {
- return getCallbackMethod(persistenceContext, beanClass, "preUpdates");
- }
-
- @Override
- public Method getPreRemoveMethod(Class beanClass, Object persistenceContext)
- {
- return getCallbackMethod(persistenceContext, beanClass, "preRemoves");
- }*/
-
private Session getSession(EntityManager entityManager)
{
Object delegate = entityManager.getDelegate();
@@ -468,4 +346,9 @@
*
*/
static class NotHibernateException extends IllegalArgumentException {}
+
+ public static HibernatePersistenceProvider instance()
+ {
+ return (HibernatePersistenceProvider) Component.getInstance(HibernatePersistenceProvider.class, ScopeType.STATELESS);
+ }
}
Modified: branches/Seam_2_0/src/main/org/jboss/seam/persistence/ManagedEntityIdentityInterceptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/persistence/ManagedEntityIdentityInterceptor.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/persistence/ManagedEntityIdentityInterceptor.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -10,7 +10,6 @@
import java.util.Map;
import java.util.Set;
-import org.jboss.seam.Seam;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.intercept.AroundInvoke;
import org.jboss.seam.annotations.intercept.Interceptor;
@@ -140,7 +139,7 @@
return value instanceof List ||
value instanceof Map ||
value instanceof Set ||
- Seam.isEntityClass( value.getClass() );
+ PersistenceProvider.getEntityClass(value.getClass()) != null;
}
private Object getFieldValue(Object bean, Field field) throws Exception
Modified: branches/Seam_2_0/src/main/org/jboss/seam/persistence/PersistenceProvider.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/persistence/PersistenceProvider.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/persistence/PersistenceProvider.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -9,12 +9,15 @@
import javax.transaction.Synchronization;
import org.jboss.seam.Component;
+import org.jboss.seam.ComponentType;
import org.jboss.seam.Entity;
import org.jboss.seam.ScopeType;
+import org.jboss.seam.Seam;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.init.EjbDescriptor;
/**
* Abstraction layer for persistence providers (JPA implementations).
* This class provides a working base implementation that can be
@@ -61,7 +64,7 @@
*/
public Object getId(Object bean, EntityManager entityManager)
{
- return Entity.forClass( bean.getClass() ).getIdentifier(bean);
+ return Entity.forBean( bean ).getIdentifier(bean);
}
/**
@@ -74,7 +77,7 @@
*/
public String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException
{
- return Entity.forClass(bean.getClass()).getName();
+ return Entity.forBean( bean ).getName();
}
/**
@@ -84,7 +87,7 @@
*/
public Object getVersion(Object bean, EntityManager entityManager)
{
- return Entity.forClass( bean.getClass() ).getVersion(bean);
+ return Entity.forBean( bean ).getVersion(bean);
}
public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
@@ -148,29 +151,53 @@
*/
public Class getBeanClass(Object bean)
{
- return Entity.forClass(bean.getClass()).getBeanClass();
+ return getEntityClass(bean.getClass());
}
- public Method getPostLoadMethod(Class beanClass, EntityManager entityManager)
+ public static Class getEntityClass(Class clazz)
{
- return Entity.forClass(beanClass).getPostLoadMethod();
+ while (clazz != null && !Object.class.equals(clazz))
+ {
+ if (clazz.isAnnotationPresent(Entity.class))
+ {
+ return clazz;
+ }
+ else
+ {
+ EjbDescriptor ejbDescriptor = Seam.getEjbDescriptor(clazz.getName());
+ if (ejbDescriptor != null)
+ {
+ return ejbDescriptor.getBeanType() == ComponentType.ENTITY_BEAN ? clazz : null;
+ }
+ else
+ {
+ clazz = clazz.getSuperclass();
+ }
+ }
+ }
+ return null;
}
- public Method getPrePersistMethod(Class beanClass, EntityManager entityManager)
+ public Method getPostLoadMethod(Object bean, EntityManager entityManager)
{
- return Entity.forClass(beanClass).getPrePersistMethod();
+ return Entity.forBean(bean).getPostLoadMethod();
}
- public Method getPreUpdateMethod(Class beanClass, EntityManager entityManager)
+ public Method getPrePersistMethod(Object bean, EntityManager entityManager)
{
- return Entity.forClass(beanClass).getPreUpdateMethod();
+ return Entity.forBean(bean).getPrePersistMethod();
}
- public Method getPreRemoveMethod(Class beanClass, EntityManager entityManager)
+ public Method getPreUpdateMethod(Object bean, EntityManager entityManager)
{
- return Entity.forClass(beanClass).getPreRemoveMethod();
+ return Entity.forBean(bean).getPreUpdateMethod();
}
+ public Method getPreRemoveMethod(Object bean, EntityManager entityManager)
+ {
+ return Entity.forBean(bean).getPreRemoveMethod();
+ }
+
@Deprecated
public Method getPreRemoveMethod(Class beanClass)
{
Modified: branches/Seam_2_0/src/main/org/jboss/seam/security/EntityPermissionChecker.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/security/EntityPermissionChecker.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/security/EntityPermissionChecker.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -1,6 +1,6 @@
package org.jboss.seam.security;
-import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.ScopeType.STATELESS;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.lang.reflect.Method;
@@ -8,15 +8,12 @@
import javax.persistence.EntityManager;
import org.jboss.seam.Component;
-import org.jboss.seam.ScopeType;
import org.jboss.seam.Seam;
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.security.Restrict;
-import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.persistence.PersistenceProvider;
import org.jboss.seam.util.Strings;
@@ -24,83 +21,68 @@
* Entity permission checks
*
* @author Shane Bryzak
+ * @author Pete Muir
*/
@Name("org.jboss.seam.security.entityPermissionChecker")
-@Scope(APPLICATION)
-@Install(precedence = BUILT_IN)
+@Scope(STATELESS)
+@Install(precedence = BUILT_IN, classDependencies={"javax.persistence.EntityManager"})
@BypassInterceptors
-@Startup
public class EntityPermissionChecker
{
- private String entityManagerName = "entityManager";
-
- private EntityManager getEntityManager()
+
+ public static EntityPermissionChecker instance()
{
- return (EntityManager) Component.getInstance(entityManagerName);
+ return (EntityPermissionChecker) Component.getInstance(EntityPermissionChecker.class, STATELESS);
}
- public String getEntityManagerName()
+ protected Method getProtectedMethod(EntityAction action, Object bean, EntityManager entityManager)
{
- return entityManagerName;
+ if (bean != null)
+ {
+ switch (action)
+ {
+ case READ:
+ return PersistenceProvider.instance().getPostLoadMethod(bean, entityManager);
+
+ case INSERT:
+ return PersistenceProvider.instance().getPrePersistMethod(bean, entityManager);
+
+ case UPDATE:
+ return PersistenceProvider.instance().getPreUpdateMethod(bean, entityManager);
+
+ case DELETE:
+ return PersistenceProvider.instance().getPreRemoveMethod(bean, entityManager);
+ }
+
+ }
+ return null;
}
- public void setEntityManagerName(String name)
+ public void checkEntityPermission(Object entity, EntityAction action)
{
- this.entityManagerName = name;
- }
+ checkEntityPermission(entity, action, getProtectedMethod(action, entity, null));
+ }
- public static EntityPermissionChecker instance()
+ public void checkEntityPermission(Object entity, EntityAction action, EntityManager entityManager)
{
- if ( !Contexts.isApplicationContextActive() )
- {
- throw new IllegalStateException("No active application context");
- }
-
- EntityPermissionChecker instance = (EntityPermissionChecker) Component.getInstance(
- EntityPermissionChecker.class, ScopeType.APPLICATION);
-
- if (instance == null)
- {
- throw new IllegalStateException("No EntityPermissionChecker could be created");
- }
-
- return instance;
+ checkEntityPermission(entity, action, getProtectedMethod(action, entity, entityManager));
}
- public void checkEntityPermission(Object entity, EntityAction action)
- {
- if (!Identity.isSecurityEnabled()) return;
-
- Identity identity = Identity.instance();
-
- identity.isLoggedIn(true);
-
- PersistenceProvider provider = PersistenceProvider.instance();
- Class beanClass = provider.getBeanClass(entity);
-
- if (beanClass != null)
+ protected void checkEntityPermission(Object entity, EntityAction action, Method m)
+ {
+ if (entity != null)
{
- String name = Seam.getComponentName(entity.getClass());
- if (name == null) name = beanClass.getName();
+ if (!Identity.isSecurityEnabled())
+ return;
+
+ Identity identity = Identity.instance();
+
+ identity.isLoggedIn(true);
- Method m = null;
- switch (action)
- {
- case READ:
- m = provider.getPostLoadMethod(beanClass, getEntityManager());
- break;
- case INSERT:
- m = provider.getPrePersistMethod(beanClass, getEntityManager());
- break;
- case UPDATE:
- m = provider.getPreUpdateMethod(beanClass, getEntityManager());
- break;
- case DELETE:
- m = provider.getPreRemoveMethod(beanClass, getEntityManager());
- }
+ Class beanClass = PersistenceProvider.instance().getBeanClass(entity);
Restrict restrict = null;
-
+
if (m != null && m.isAnnotationPresent(Restrict.class))
{
restrict = m.getAnnotation(Restrict.class);
@@ -109,18 +91,24 @@
{
restrict = entity.getClass().getAnnotation(Restrict.class);
}
-
+
if (restrict != null)
{
if (Strings.isEmpty(restrict.value()))
{
- identity.checkPermission(name, action.toString(), entity);
+ String name = Seam.getComponentName(beanClass);
+ if (name == null)
+ {
+ name = beanClass.getName();
+ }
+ Identity.instance().checkPermission(name, action.toString(), entity);
}
else
{
- identity.checkRestriction(restrict.value());
+ Identity.instance().checkRestriction(restrict.value());
}
}
}
- }
-}
\ No newline at end of file
+ }
+
+}
Added: branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java (rev 0)
+++ branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -0,0 +1,23 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.STATELESS;
+import static org.jboss.seam.annotations.Install.FRAMEWORK;
+
+import java.lang.reflect.Method;
+
+import javax.persistence.EntityManager;
+
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+
+
+@Name("org.jboss.seam.security.entityPermissionChecker")
+@Scope(STATELESS)
+@Install(precedence = FRAMEWORK, classDependencies={"org.hibernate.Session", "javax.persistence.EntityManager"})
+@BypassInterceptors
+public class HibernateEntityPermissionChecker extends EntityPermissionChecker
+{
+
+}
Property changes on: branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateEntityPermissionChecker.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -10,6 +10,7 @@
import org.hibernate.EmptyInterceptor;
import org.hibernate.Interceptor;
import org.hibernate.type.Type;
+import org.jboss.seam.Entity.NotEntityException;
/**
* Facilitates security checks for Hibernate entities
@@ -30,7 +31,14 @@
public boolean onLoad(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types)
{
- EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
+ try
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
+ }
+ catch (NotEntityException e)
+ {
+ // Not a JPA entity
+ }
return wrappedInterceptor != null ?
wrappedInterceptor.onLoad(entity, id, state, propertyNames, types) :
@@ -41,7 +49,14 @@
public void onDelete(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types)
{
- EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
+ try
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
+ }
+ catch (NotEntityException e)
+ {
+ // Not a JPA entity
+ }
if (wrappedInterceptor != null)
wrappedInterceptor.onDelete(entity, id, state, propertyNames, types);
@@ -51,7 +66,14 @@
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState,
Object[] previousState, String[] propertyNames, Type[] types)
{
- EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
+ try
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
+ }
+ catch (NotEntityException e)
+ {
+ // Not a JPA entity
+ }
return wrappedInterceptor != null ?
wrappedInterceptor.onFlushDirty(entity, id, currentState,
@@ -62,7 +84,14 @@
public boolean onSave(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types)
{
- EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
+ try
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
+ }
+ catch (NotEntityException e)
+ {
+ // Not a JPA entity
+ }
return wrappedInterceptor != null ?
wrappedInterceptor.onSave(entity, id, state, propertyNames, types) :
Modified: branches/Seam_2_0/src/main/org/jboss/seam/security/Identity.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/security/Identity.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/security/Identity.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -622,4 +622,9 @@
subject = savedSubject;
}
}
+
+ public void checkEntityPermission(Object entity, EntityAction action)
+ {
+ EntityPermissionChecker.instance().checkEntityPermission(entity, action);
+ }
}
Modified: branches/Seam_2_0/src/main/org/jboss/seam/util/Reflections.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/util/Reflections.java 2008-03-30 22:28:22 UTC (rev 7744)
+++ branches/Seam_2_0/src/main/org/jboss/seam/util/Reflections.java 2008-03-30 23:37:16 UTC (rev 7745)
@@ -283,9 +283,24 @@
throw new IllegalArgumentException("no such field: " + clazz.getName() + '.' + name);
}
+ public static Method getMethod(Class clazz, String name)
+ {
+ for ( Class superClass = clazz; superClass!=Object.class; superClass=superClass.getSuperclass() )
+ {
+ try
+ {
+ return superClass.getDeclaredMethod(name);
+ }
+ catch (NoSuchMethodException nsme) {}
+ }
+ throw new IllegalArgumentException("no such method: " + clazz.getName() + '.' + name);
+ }
+
/**
* Get all the fields which are annotated with the given annotation. Returns an empty list
* if none are found
+ *
+ * This method is slow
*/
public static List<Field> getFields(Class clazz, Class annotation)
{
@@ -302,7 +317,7 @@
}
return fields;
}
-
+
public static Method getMethod(Annotation annotation, String name)
{
try
16 years, 8 months
Seam SVN: r7744 - branches/Seam_2_0/.settings.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-03-30 18:28:22 -0400 (Sun, 30 Mar 2008)
New Revision: 7744
Modified:
branches/Seam_2_0/.settings/org.eclipse.jdt.core.prefs
branches/Seam_2_0/.settings/org.eclipse.jdt.ui.prefs
Log:
Eclipse templates
Modified: branches/Seam_2_0/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- branches/Seam_2_0/.settings/org.eclipse.jdt.core.prefs 2008-03-30 22:28:00 UTC (rev 7743)
+++ branches/Seam_2_0/.settings/org.eclipse.jdt.core.prefs 2008-03-30 22:28:22 UTC (rev 7744)
@@ -1,4 +1,4 @@
-#Fri Aug 31 15:15:15 CDT 2007
+#Sun Mar 30 00:57:33 GMT 2008
eclipse.preferences.version=1
org.eclipse.jdt.core.codeComplete.argumentPrefixes=
org.eclipse.jdt.core.codeComplete.argumentSuffixes=
@@ -80,7 +80,7 @@
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.5
-org.eclipse.jdt.core.formatter.align_type_members_on_columns=true
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
@@ -96,7 +96,7 @@
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
@@ -112,17 +112,17 @@
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
-org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
-org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
@@ -136,7 +136,7 @@
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
-org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
@@ -152,15 +152,15 @@
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
-org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.indentation.size=3
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
-org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
@@ -326,13 +326,13 @@
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
-org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.lineSplit=800
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=space
-org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.tabulation.size=3
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
Modified: branches/Seam_2_0/.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- branches/Seam_2_0/.settings/org.eclipse.jdt.ui.prefs 2008-03-30 22:28:00 UTC (rev 7743)
+++ branches/Seam_2_0/.settings/org.eclipse.jdt.ui.prefs 2008-03-30 22:28:22 UTC (rev 7744)
@@ -1,6 +1,6 @@
-#Fri Aug 31 15:15:15 CDT 2007
+#Sun Mar 30 00:57:34 GMT 2008
eclipse.preferences.version=1
-formatter_profile=_my settings
+formatter_profile=_Seam
formatter_settings_version=11
internal.default.compliance=default
org.eclipse.jdt.ui.exception.name=e
@@ -8,4 +8,4 @@
org.eclipse.jdt.ui.javadoc=false
org.eclipse.jdt.ui.keywordthis=false
org.eclipse.jdt.ui.overrideannotation=true
-org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_cont!
ext" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n *\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="false" con!
text\="overridecomment_context" deleted\="false" description\="Comment
for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment"></template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_contex!
t" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_con!
text" deleted\="false" description\="Code in created method stubs" ena
bled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted!
\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" !
deleted\="false" description\="Comment for overriding methods" enabled
\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment"></template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new in!
terface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created met!
hod stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.
methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
16 years, 8 months
Seam SVN: r7743 - branches/Seam_2_0/examples/dvdstore.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-03-30 18:28:00 -0400 (Sun, 30 Mar 2008)
New Revision: 7743
Modified:
branches/Seam_2_0/examples/dvdstore/
Log:
ignores
Property changes on: branches/Seam_2_0/examples/dvdstore
___________________________________________________________________
Name: svn:ignore
- build
dist
test-build
exploded-archives
+ build
dist
test-build
exploded-archives
dvdindexes
16 years, 8 months
Seam SVN: r7742 - trunk/src/main/org/jboss/seam/pageflow and 1 other directory.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-03-29 19:10:28 -0400 (Sat, 29 Mar 2008)
New Revision: 7742
Modified:
branches/Seam_2_0/src/main/org/jboss/seam/pageflow/Pageflow.java
trunk/src/main/org/jboss/seam/pageflow/Pageflow.java
Log:
JBSEAM-2456
Modified: branches/Seam_2_0/src/main/org/jboss/seam/pageflow/Pageflow.java
===================================================================
--- branches/Seam_2_0/src/main/org/jboss/seam/pageflow/Pageflow.java 2008-03-29 08:52:22 UTC (rev 7741)
+++ branches/Seam_2_0/src/main/org/jboss/seam/pageflow/Pageflow.java 2008-03-29 23:10:28 UTC (rev 7742)
@@ -61,6 +61,11 @@
{
return processInstance!=null;
}
+
+ public boolean isStarted()
+ {
+ return getSubProcessInstance().getRootToken().getNode() != null;
+ }
public ProcessInstance getProcessInstance()
{
Modified: trunk/src/main/org/jboss/seam/pageflow/Pageflow.java
===================================================================
--- trunk/src/main/org/jboss/seam/pageflow/Pageflow.java 2008-03-29 08:52:22 UTC (rev 7741)
+++ trunk/src/main/org/jboss/seam/pageflow/Pageflow.java 2008-03-29 23:10:28 UTC (rev 7742)
@@ -61,6 +61,11 @@
{
return processInstance!=null;
}
+
+ public boolean isStarted()
+ {
+ return getSubProcessInstance().getRootToken().getNode() != null;
+ }
public ProcessInstance getProcessInstance()
{
16 years, 8 months