[jboss-cvs] jboss-seam/src/main/org/jboss/seam/init ...
Norman Richards
norman.richards at jboss.com
Sat Mar 10 00:50:41 EST 2007
User: nrichards
Date: 07/03/10 00:50:41
Modified: src/main/org/jboss/seam/init Initialization.java
Added: src/main/org/jboss/seam/init ComponentDescriptor.java
DependencyManager.java FactoryDescriptor.java
NamespaceDescriptor.java
Log:
fix the broken component dependency logic
Revision Changes Path
1.162 +34 -340 jboss-seam/src/main/org/jboss/seam/init/Initialization.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: Initialization.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/init/Initialization.java,v
retrieving revision 1.161
retrieving revision 1.162
diff -u -b -r1.161 -r1.162
--- Initialization.java 9 Mar 2007 02:29:21 -0000 1.161
+++ Initialization.java 10 Mar 2007 05:50:40 -0000 1.162
@@ -24,7 +24,6 @@
import java.util.TreeMap;
import java.util.TreeSet;
-import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
@@ -34,7 +33,6 @@
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.Seam;
-import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Namespace;
@@ -51,7 +49,6 @@
import org.jboss.seam.deployment.NamespaceScanner;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
-import org.jboss.seam.servlet.AbstractResource;
import org.jboss.seam.util.Conversions;
import org.jboss.seam.util.Naming;
import org.jboss.seam.util.Reflections;
@@ -62,7 +59,7 @@
/**
* @author Gavin King
* @author <a href="mailto:theute at jboss.org">Thomas Heute</a>
- * @version $Revision: 1.161 $
+ * @version $Revision: 1.162 $
*/
public class Initialization
{
@@ -71,7 +68,7 @@
private ServletContext servletContext;
private Map<String, Conversions.PropertyValue> properties = new HashMap<String, Conversions.PropertyValue>();
- private Map<String, SortedSet<ComponentDescriptor>> componentDescriptors = new TreeMap<String, SortedSet<ComponentDescriptor>>();
+ private Map<String, Set<ComponentDescriptor>> componentDescriptors = new TreeMap<String, Set<ComponentDescriptor>>();
private List<FactoryDescriptor> factoryDescriptors = new ArrayList<FactoryDescriptor>();
private Set<Class> installedComponentClasses = new HashSet<Class>();
private Set<String> importedPackages = new HashSet<String>();
@@ -159,6 +156,7 @@
}
}
+ @SuppressWarnings("unchecked")
private void installComponentsFromXmlElements(Element rootElement, Properties replacements)
throws DocumentException, ClassNotFoundException
{
@@ -248,6 +246,7 @@
}
}
+ @SuppressWarnings("unchecked")
private void installEventListenerFromXmlElement(Element event)
{
String type = event.attributeValue("type");
@@ -305,6 +304,7 @@
return value;
}
+ @SuppressWarnings("unchecked")
private void installComponentFromXmlElement(Element component, String name, String className,
Properties replacements) throws ClassNotFoundException
{
@@ -397,10 +397,10 @@
private void addComponentDescriptor(ComponentDescriptor descriptor)
{
String name = descriptor.getName();
- SortedSet<ComponentDescriptor> set = componentDescriptors.get(name);
+ Set<ComponentDescriptor> set = componentDescriptors.get(name);
if (set==null)
{
- set = new TreeSet<ComponentDescriptor>();
+ set = new TreeSet<ComponentDescriptor>(new ComponentDescriptor.PrecedenceComparator());
componentDescriptors.put(name, set);
}
if ( !set.isEmpty() )
@@ -418,6 +418,7 @@
return new Conversions.FlatPropertyValue( trimmedText(prop, replacements) );
}
+ @SuppressWarnings("unchecked")
private Conversions.PropertyValue getPropertyValue(Element prop, String propName,
Properties replacements)
{
@@ -755,7 +756,7 @@
protected ComponentDescriptor findDescriptor(Class<?> componentClass)
{
- for (SortedSet<ComponentDescriptor> components : componentDescriptors.values())
+ for (Set<ComponentDescriptor> components : componentDescriptors.values())
{
for (ComponentDescriptor component: components)
{
@@ -786,44 +787,31 @@
{
log.info("Installing components...");
Context context = Contexts.getApplicationContext();
- boolean installedSomething = false;
- do
- {
- installedSomething = false;
- for ( SortedSet<ComponentDescriptor> descriptors: componentDescriptors.values() )
- {
- //iterate over them from highest precedence to lowest
- for (ComponentDescriptor componentDescriptor: descriptors)
- {
+
+ DependencyManager manager = new DependencyManager(componentDescriptors);
+
+ Set<ComponentDescriptor> installable = manager.installedSet();
+ System.out.println("** INSTALLABLE: " + installable);
+ for (ComponentDescriptor componentDescriptor: installable) {
String compName = componentDescriptor.getName() + COMPONENT_SUFFIX;
- if ( !context.isSet(compName) && dependenciesMet(componentDescriptor) )
- {
- addComponent(componentDescriptor, context);
- installedSomething = true;
+ if (!context.isSet(compName)) {
+ addComponent(componentDescriptor, context);
- if ( componentDescriptor.isAutoCreate() )
- {
+ if (componentDescriptor.isAutoCreate()) {
init.addAutocreateVariable( componentDescriptor.getName() );
}
- if ( componentDescriptor.isFilter() )
- {
+ if (componentDescriptor.isFilter()) {
init.addInstalledFilter( componentDescriptor.getName() );
}
- if ( componentDescriptor.isResourceProvider() )
- {
+ if (componentDescriptor.isResourceProvider()) {
init.addResourceProvider( componentDescriptor.getName() );
}
-
- break;
- }
}
}
- }
- while (installedSomething);
for (FactoryDescriptor factoryDescriptor : factoryDescriptors)
{
@@ -852,49 +840,6 @@
}
}
- protected boolean dependenciesMet(ComponentDescriptor descriptor)
- {
- if ( !descriptor.isInstalled() ) return false;
-
- String[] dependencies = descriptor.getDependencies();
- if (dependencies!=null)
- {
- for (String dependency: dependencies)
- {
- if ( !componentDescriptors.containsKey(dependency) ) //TODO: call && descriptor.isInstalled() recursively
- {
- return false;
- }
- }
- }
- Class[] genericDependencies = descriptor.getGenericDependencies();
- if (genericDependencies!=null)
- {
- for (Class genericDependency: genericDependencies)
- {
- if ( !installedComponentClasses.contains(genericDependency) )
- {
- return false;
- }
- }
- }
- String[] classDependencies = descriptor.getClassDependencies();
- if (classDependencies != null)
- {
- for (String className: classDependencies)
- {
- try
- {
- descriptor.getComponentClass().getClassLoader().loadClass(className);
- }
- catch (Exception e)
- {
- return false;
- }
- }
- }
- return true;
- }
/**
* This actually creates a real Component and should only be called when
@@ -947,89 +892,7 @@
return result.toString();
}
- private static class FactoryDescriptor
- {
- private String name;
- private ScopeType scope;
- private String method;
- private String value;
- private boolean autoCreate;
- FactoryDescriptor(String name, ScopeType scope, String method, String value,
- boolean autoCreate)
- {
- super();
- this.name = name;
- this.scope = scope;
- this.method = method;
- this.value = value;
- this.autoCreate = autoCreate;
- }
-
- public String getMethod()
- {
- return method;
- }
-
- public String getValue()
- {
- return value;
- }
-
- public String getName()
- {
- return name;
- }
-
- public ScopeType getScope()
- {
- return scope;
- }
-
- public boolean isValueBinding()
- {
- return method == null;
- }
-
- public boolean isAutoCreate()
- {
- return autoCreate;
- }
-
- @Override
- public String toString()
- {
- return "FactoryDescriptor(" + name + ')';
- }
- }
-
- private static class NamespaceDescriptor
- {
- private Namespace namespace;
- private Package pkg;
-
- NamespaceDescriptor(Namespace namespace, Package pkg)
- {
- this.namespace = namespace;
- this.pkg = pkg;
- }
-
- public Namespace getNamespace()
- {
- return namespace;
- }
-
- public Package getPackage()
- {
- return pkg;
- }
-
- @Override
- public String toString()
- {
- return "EventListenerDescriptor(" + namespace + ')';
- }
- }
private static class EventListenerDescriptor
{
@@ -1058,174 +921,5 @@
}
}
- private static class ComponentDescriptor implements Comparable<ComponentDescriptor>
- {
- private String name;
- private Class<?> componentClass;
- private ScopeType scope;
- private String jndiName;
- private Boolean installed;
- private boolean autoCreate;
- private Integer precedence;
-
- /**
- * For components.xml
- */
- ComponentDescriptor(String name, Class<?> componentClass, ScopeType scope,
- boolean autoCreate, String jndiName, Boolean installed, Integer precedence)
- {
- this.name = name;
- this.componentClass = componentClass;
- this.scope = scope;
- this.jndiName = jndiName;
- this.installed = installed;
- this.autoCreate = autoCreate;
- this.precedence = precedence;
- }
-
- /**
- * For a scanned role
- */
- public ComponentDescriptor(String name, Class<?> componentClass, ScopeType scope)
- {
- this.name = name;
- this.componentClass = componentClass;
- this.scope = scope;
- }
-
- /**
- * For a scanned default role
- */
- public ComponentDescriptor(Class componentClass)
- {
- this.componentClass = componentClass;
- }
-
- /**
- * For built-ins with special rules
- */
- public ComponentDescriptor(Class componentClass, Boolean installed)
- {
- this.componentClass = componentClass;
- this.installed = installed;
-
- }
-
- public String getName()
- {
- return name == null ? Seam.getComponentName(componentClass) : name;
- }
-
- public ScopeType getScope()
- {
- return scope == null ? Seam.getComponentScope(componentClass) : scope;
- }
-
- public Class getComponentClass()
- {
- return componentClass;
- }
-
- public String getJndiName()
- {
- return jndiName;
- }
-
- public boolean isAutoCreate()
- {
- return autoCreate || componentClass.isAnnotationPresent(AutoCreate.class);
- }
-
- public String[] getDependencies()
- {
- Install install = componentClass.getAnnotation(Install.class);
- if (install == null)
- {
- return null;
- }
- return install.dependencies();
- }
-
- public Class[] getGenericDependencies()
- {
- Install install = componentClass.getAnnotation(Install.class);
- if (install == null)
- {
- return null;
- }
- return install.genericDependencies();
- }
-
- public String[] getClassDependencies()
- {
- Install install = componentClass.getAnnotation(Install.class);
- if (install == null)
- {
- return null;
- }
- return install.classDependencies();
- }
-
- public boolean isInstalled()
- {
- if (installed != null)
- {
- return installed;
- }
- Install install = componentClass.getAnnotation(Install.class);
- if (install == null)
- {
- return true;
- }
- return install.debug() ? Init.instance().isDebug() : install.value();
- }
-
- public int getPrecedence()
- {
- if (precedence != null)
- {
- return precedence;
- }
- Install install = componentClass.getAnnotation(Install.class);
- if (install == null)
- {
- return Install.APPLICATION;
- }
- return install.precedence();
- }
-
- public int compareTo(ComponentDescriptor other)
- {
- return other.getPrecedence() - getPrecedence();
- }
-
- @Override
- public boolean equals(Object other)
- {
- return getPrecedence() == ( (ComponentDescriptor) other ).getPrecedence();
- }
-
- @Override
- public int hashCode()
- {
- return getPrecedence();
- }
-
- public boolean isFilter()
- {
- return Filter.class.isAssignableFrom(componentClass);
- }
-
- public boolean isResourceProvider()
- {
- return AbstractResource.class.isAssignableFrom(componentClass);
- }
-
- @Override
- public String toString()
- {
- return "ComponentDescriptor(" + getName() + ')';
- }
- }
}
1.1 date: 2007/03/10 05:50:40; author: nrichards; state: Exp;jboss-seam/src/main/org/jboss/seam/init/ComponentDescriptor.java
Index: ComponentDescriptor.java
===================================================================
package org.jboss.seam.init;
import java.util.Comparator;
import javax.servlet.Filter;
import org.jboss.seam.ScopeType;
import org.jboss.seam.Seam;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.core.Init;
import org.jboss.seam.servlet.AbstractResource;
public class ComponentDescriptor
implements Comparable<ComponentDescriptor>
{
protected String name;
protected Class<?> componentClass;
protected ScopeType scope;
protected String jndiName;
protected Boolean installed;
protected boolean autoCreate;
protected Integer precedence;
/**
* For components.xml
*/
public ComponentDescriptor(String name, Class<?> componentClass, ScopeType scope,
boolean autoCreate, String jndiName, Boolean installed, Integer precedence)
{
this.name = name;
this.componentClass = componentClass;
this.scope = scope;
this.jndiName = jndiName;
this.installed = installed;
this.autoCreate = autoCreate;
this.precedence = precedence;
}
/**
* For a scanned role
*/
public ComponentDescriptor(String name, Class<?> componentClass, ScopeType scope)
{
this.name = name;
this.componentClass = componentClass;
this.scope = scope;
}
/**
* For a scanned default role
*/
public ComponentDescriptor(Class componentClass)
{
this.componentClass = componentClass;
}
/**
* For built-ins with special rules
*/
public ComponentDescriptor(Class componentClass, Boolean installed)
{
this.componentClass = componentClass;
this.installed = installed;
}
public String getName()
{
return name == null ? Seam.getComponentName(componentClass) : name;
}
public ScopeType getScope()
{
return scope == null ? Seam.getComponentScope(componentClass) : scope;
}
public Class getComponentClass()
{
return componentClass;
}
public String getJndiName()
{
return jndiName;
}
public boolean isAutoCreate()
{
return autoCreate || componentClass.isAnnotationPresent(AutoCreate.class);
}
public String[] getDependencies()
{
Install install = componentClass.getAnnotation(Install.class);
if (install == null)
{
return null;
}
return install.dependencies();
}
public Class[] getGenericDependencies()
{
Install install = componentClass.getAnnotation(Install.class);
if (install == null)
{
return null;
}
return install.genericDependencies();
}
public String[] getClassDependencies()
{
Install install = componentClass.getAnnotation(Install.class);
if (install == null)
{
return null;
}
return install.classDependencies();
}
public boolean isInstalled()
{
if (installed != null)
{
return installed;
}
Install install = componentClass.getAnnotation(Install.class);
if (install == null)
{
return true;
}
return install.debug() ? Init.instance().isDebug() : install.value();
}
public int getPrecedence()
{
if (precedence != null)
{
return precedence;
}
Install install = componentClass.getAnnotation(Install.class);
if (install == null)
{
return Install.APPLICATION;
}
return install.precedence();
}
public int compareTo(ComponentDescriptor other)
{
return other.getPrecedence() - getPrecedence();
}
public boolean isFilter()
{
return Filter.class.isAssignableFrom(componentClass);
}
public boolean isResourceProvider()
{
return AbstractResource.class.isAssignableFrom(componentClass);
}
@Override
public String toString()
{
return "ComponentDescriptor(" + getName() + ":" + getComponentClass() + ')';
}
public static class PrecedenceComparator
implements Comparator<ComponentDescriptor>
{
public int compare(ComponentDescriptor obj1, ComponentDescriptor obj2) {
return obj2.getPrecedence() - obj1.getPrecedence();
}
}
}
1.1 date: 2007/03/10 05:50:40; author: nrichards; state: Exp;jboss-seam/src/main/org/jboss/seam/init/DependencyManager.java
Index: DependencyManager.java
===================================================================
package org.jboss.seam.init;
import java.util.*;
public class DependencyManager {
private Map<String, Set<ComponentDescriptor>> componentDescriptors;
private Set<ComponentDescriptor> currentTestSet;
private Set<ComponentDescriptor> installedSet;
public DependencyManager(Map<String, Set<ComponentDescriptor>> componentDescriptors) {
this.componentDescriptors = new HashMap<String, Set<ComponentDescriptor>>(componentDescriptors);
}
public Set<ComponentDescriptor> installedSet() {
computeInstallSet();
return installedSet;
}
private void computeInstallSet() {
installedSet = new HashSet<ComponentDescriptor>();
Set<String> keys = componentDescriptors.keySet();
for (String key: keys) {
currentTestSet = new HashSet<ComponentDescriptor>();
if (tryToInstall(key)) {
installedSet.addAll(currentTestSet);
}
currentTestSet = null;
}
}
private boolean tryToInstall(String key) {
Set<ComponentDescriptor> descriptors = componentDescriptors.get(key);
if (descriptors == null) {
return false;
}
for (ComponentDescriptor descriptor : descriptors) {
Set<ComponentDescriptor> saved = new HashSet<ComponentDescriptor>(currentTestSet);
if (tryToInstall(descriptor)) {
return true;
} else {
currentTestSet = saved;
}
}
return false;
}
private boolean tryToInstall(ComponentDescriptor descriptor) {
if (isInInstallSet(descriptor.getName())) {
return true;
}
currentTestSet.add(descriptor);
return checkAllDependencies(descriptor);
}
private boolean checkAllDependencies(ComponentDescriptor descriptor) {
return descriptor.isInstalled() &&
checkClassDependencies(descriptor) &&
checkComponentDependencies(descriptor) &&
checkGenericDependencies(descriptor);
}
private boolean checkComponentDependencies(ComponentDescriptor descriptor) {
String[] dependencies = descriptor.getDependencies();
if (dependencies == null) {
return true;
}
for (String componentName: dependencies) {
if (!tryToInstall(componentName)) {
return false;
}
}
return true;
}
private boolean checkClassDependencies(ComponentDescriptor descriptor) {
String[] classDependencies = descriptor.getClassDependencies();
if (classDependencies == null) {
return true;
}
for (String className: classDependencies) {
try {
descriptor.getComponentClass().getClassLoader().loadClass(className);
} catch (Exception e){
return false;
}
}
return true;
}
private boolean checkGenericDependencies(ComponentDescriptor descriptor) {
Class[] dependencies = descriptor.getGenericDependencies();
if (dependencies == null) {
return true;
}
for (Class dependency: dependencies) {
if (!isInInstallSet(dependency)) {
Set<String> searchList = findPotentialComponents(dependency);
if (!tryToSatisfyDependencyUsing(dependency, searchList)) {
return false;
}
}
}
return true;
}
private boolean tryToSatisfyDependencyUsing(Class dependency, Set<String> searchList) {
for (String componentName:searchList) {
Set<ComponentDescriptor> saved = new HashSet<ComponentDescriptor>(currentTestSet);
// the second check is important for edge case
if (tryToInstall(componentName) && isInInstallSet(dependency)) {
return true;
} else {
currentTestSet = saved;
}
}
return false;
}
private Set<String> findPotentialComponents(Class dependency) {
Set<String> keys = new HashSet<String>();
for (String candidateKey: componentDescriptors.keySet()) {
if (componentMightSatisfy(candidateKey, dependency)) {
keys.add(candidateKey);
}
}
return keys;
}
private boolean componentMightSatisfy(String candidateKey, Class dependency) {
for (ComponentDescriptor descriptor: componentDescriptors.get(candidateKey)) {
if (descriptor.getComponentClass().equals(dependency)) {
return true;
}
}
return false;
}
private boolean isInInstallSet(Class dependency) {
for (ComponentDescriptor descriptor: currentTestSet) {
if (dependency.equals(descriptor.getComponentClass())) {
return true;
}
}
for (ComponentDescriptor descriptor: installedSet) {
if (dependency.equals(descriptor.getComponentClass())) {
return true;
}
}
return false;
}
// install set is already installed or the current working set
private boolean isInInstallSet(String key) {
for (ComponentDescriptor descriptor: currentTestSet) {
if (key.equals(descriptor.getName())) {
return true;
}
}
for (ComponentDescriptor descriptor: installedSet) {
if (key.equals(descriptor.getName())) {
return true;
}
}
return false;
}
}
1.1 date: 2007/03/10 05:50:40; author: nrichards; state: Exp;jboss-seam/src/main/org/jboss/seam/init/FactoryDescriptor.java
Index: FactoryDescriptor.java
===================================================================
package org.jboss.seam.init;
import org.jboss.seam.ScopeType;
public class FactoryDescriptor
{
private String name;
private ScopeType scope;
private String method;
private String value;
private boolean autoCreate;
FactoryDescriptor(String name, ScopeType scope, String method, String value,
boolean autoCreate)
{
super();
this.name = name;
this.scope = scope;
this.method = method;
this.value = value;
this.autoCreate = autoCreate;
}
public String getMethod()
{
return method;
}
public String getValue()
{
return value;
}
public String getName()
{
return name;
}
public ScopeType getScope()
{
return scope;
}
public boolean isValueBinding()
{
return method == null;
}
public boolean isAutoCreate()
{
return autoCreate;
}
@Override
public String toString()
{
return "FactoryDescriptor(" + name + ')';
}
}
1.1 date: 2007/03/10 05:50:41; author: nrichards; state: Exp;jboss-seam/src/main/org/jboss/seam/init/NamespaceDescriptor.java
Index: NamespaceDescriptor.java
===================================================================
package org.jboss.seam.init;
import org.jboss.seam.annotations.Namespace;
public class NamespaceDescriptor
{
private Namespace namespace;
private Package pkg;
NamespaceDescriptor(Namespace namespace, Package pkg)
{
this.namespace = namespace;
this.pkg = pkg;
}
public Namespace getNamespace()
{
return namespace;
}
public Package getPackage()
{
return pkg;
}
@Override
public String toString()
{
return "EventListenerDescriptor(" + namespace + ')';
}
}
More information about the jboss-cvs-commits
mailing list