Skip to content

Commit

Permalink
some changes with parsing namespaces
Browse files Browse the repository at this point in the history
git-svn-id: http://anonsvn.jboss.org/repos/weld/ri/trunk@2143 1c488680-804c-0410-94cd-c6b725194a0e
  • Loading branch information
Victor Yarmolovich committed Mar 23, 2009
1 parent 12d37b8 commit 96980f5
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 98 deletions.
165 changes: 119 additions & 46 deletions impl/src/main/java/org/jboss/webbeans/xml/ParseXmlHelper.java
Expand Up @@ -7,6 +7,7 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

Expand All @@ -15,11 +16,14 @@
import javax.jms.Queue;
import javax.jms.Topic;

import org.dom4j.Attribute;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.jboss.webbeans.CurrentManager;
import org.jboss.webbeans.ManagerImpl;
import org.jboss.webbeans.introspector.AnnotatedItem;
import org.jboss.webbeans.introspector.jlr.AnnotatedClassImpl;
import org.jboss.webbeans.resources.spi.ResourceLoadingException;

public class ParseXmlHelper
{
Expand Down Expand Up @@ -196,8 +200,9 @@ private static boolean isSessionBean(Element element)

private static boolean isSimpleBean(Element element)
{
//TODO
String urn = element.getNamespace().getURI();
Class<?> beanClass = loadClassByURN(urn, element.getName());
Class<?> beanClass = null;//loadElementClass(urn, element.getName());

if (!Modifier.isAbstract(beanClass.getModifiers()) &&
beanClass.getTypeParameters().length == 0)
Expand All @@ -208,8 +213,9 @@ private static boolean isSimpleBean(Element element)

private static AnnotatedItem<?, ?> receiveSimpleBeanItem(Element element)
{
//TODO
String urn = element.getNamespace().getURI();
Class<?> beanClass = loadClassByURN(urn, element.getName());
Class<?> beanClass = null;//loadElementClass(urn, element.getName());

if (!Modifier.isStatic(beanClass.getModifiers()) &&
beanClass.isMemberClass())
Expand Down Expand Up @@ -258,73 +264,140 @@ public static boolean isJavaEeNamespace(Element element)
return element.getNamespace().getURI().equalsIgnoreCase(XmlConstants.JAVA_EE_NAMESPACE);
}

// TODO you can't reparse all files every time you want to load a class. Switch to an OO design and cache
// TODO Don't do your own classloading, use xml env
// TODO Don't load Class, use AnnotatedClass
public static Class<?> loadClassByURN(String urn, String className)
public static <T> Class<? extends T> loadElementClass(Element element, Class<T> expectedType, XmlEnvironment environment, Map<String, Set<String>> packagesMap)
{
List<Class<?>> classes = new ArrayList<Class<?>>();
List<String> packages = new ArrayList<String>();
URL namespaceFile = loadNamespaceFile(urn);
List<Class<? extends T>> classesList = new ArrayList<Class<? extends T>>();
String className = element.getName();
String prefix = element.getNamespacePrefix();

if(namespaceFile == null)
packages.add(urn.replaceFirst(XmlConstants.URN_PREFIX, ""));

else
packages.addAll(parseNamespaceFile(namespaceFile));

for(String possiblePackage : packages)
for(Map.Entry<String, Set<String>> packagesEntry : packagesMap.entrySet())
{
String classPath = possiblePackage + "." + className;
try
if(prefix.equalsIgnoreCase(packagesEntry.getKey()))
{
classes.add(Class.forName(classPath));
Set<String> packages = packagesEntry.getValue();
for(String packageName : packages)
{
String classPath = packageName + "." + element.getName();
try
{
Class<? extends T> classType = environment.loadClass(classPath, expectedType).getRawType();
classesList.add(classType);
}
catch(ResourceLoadingException e){}
}
}
catch (ClassNotFoundException e)
{}
}

if(classes.size() == 0)
throw new DefinitionException("Could not find '" + className + "'according to specified URN '" + urn + "'");
if(classesList.size() == 0)
throw new DefinitionException("Could not find '" + className + "'");

if(classes.size() == 1)
return classes.get(0);
if(classesList.size() == 1)
return classesList.get(0);

throw new DefinitionException("There are multiple packages containing a Java type with the same name '" + className + "'");
}

public static URL loadNamespaceFile(String urn)
public static void checkRootAttributes(Element root, Map<String, Set<String>> packagesMap)
{
Iterator<?> rootAttrIterator = root.attributeIterator();
while(rootAttrIterator.hasNext())
{
Set<String> packagesSet = new HashSet<String>();
Attribute attribute = (Attribute)rootAttrIterator.next();
String attrPrefix = attribute.getNamespacePrefix();
String attrData = attribute.getStringValue();

for(String attrVal : attrData.split(" "))
{
if(attrVal.startsWith(XmlConstants.URN_PREFIX))
{
URL namespaceFile = loadNamespaceFile(attrVal);
if(namespaceFile == null)
throw new DefinitionException("Could not find 'namespace' file according to specified URN '" + attrVal + "'");
packagesSet.addAll(parseNamespaceFile(namespaceFile));
}
}

addElementToPackagesMap(packagesMap, attrPrefix, packagesSet);
}
}

public static void checkRootDeclaredNamespaces(Element root, Map<String, Set<String>> packagesMap)
{
Iterator<?> namespacesIterator = root.declaredNamespaces().iterator();
while(namespacesIterator.hasNext())
{
Namespace namespace = (Namespace)namespacesIterator.next();
String prefix = namespace.getPrefix();
String uri = namespace.getURI();
if(uri.startsWith(XmlConstants.URN_PREFIX))
{
Set<String> packagesSet = new HashSet<String>();

URL namespaceFile = loadNamespaceFile(uri);
if(namespaceFile != null)
{
packagesSet.addAll(parseNamespaceFile(namespaceFile));
}
else
{
String packageName = uri.replaceFirst(XmlConstants.URN_PREFIX, "");
packagesSet.add(packageName);
}

addElementToPackagesMap(packagesMap, prefix, packagesSet);
}
}
}

private static URL loadNamespaceFile(String urn)
{
char separator = '/';
String packageName = urn.replaceFirst(XmlConstants.URN_PREFIX, "");
String path = packageName.replace('.', separator);
String filePath = separator + path + separator + XmlConstants.NAMESPACE_FILE_NAME;
return ParseXmlHelper.class.getResource(filePath);
URL namespaceFile = ParseXmlHelper.class.getResource(filePath);
return namespaceFile;
}

public static List<String> parseNamespaceFile(URL namespaceFile)
private static Set<String> parseNamespaceFile(URL namespaceFile)
{
List<String> packages = new ArrayList<String>();
Scanner fileScanner;
try
Set<String> packages = new HashSet<String>();
Scanner fileScanner;
try
{
fileScanner = new Scanner(namespaceFile.openStream());
while (fileScanner.hasNextLine() )
{
fileScanner = new Scanner(namespaceFile.openStream());
while (fileScanner.hasNextLine() )
String line = fileScanner.nextLine();
Scanner lineScanner = new Scanner(line);
lineScanner.useDelimiter(XmlConstants.NAMESPACE_FILE_DELIMETER);
while(lineScanner.hasNext())
{
String line = fileScanner.nextLine();
Scanner lineScanner = new Scanner(line);
lineScanner.useDelimiter(XmlConstants.NAMESPACE_FILE_DELIMETER);
while(lineScanner.hasNext())
{
packages.add(lineScanner.next());
}
packages.add(lineScanner.next());
}
return packages;
}
catch (IOException e)
{
throw new RuntimeException("Error opening " + namespaceFile.toString());
lineScanner.close();
}

fileScanner.close();
return packages;
}
catch (IOException e)
{
throw new RuntimeException("Error opening " + namespaceFile.toString());
}
}

private static void addElementToPackagesMap(Map<String, Set<String>> packagesMap, String prefix, Set<String> packagesSet)
{
if(packagesMap.containsKey(prefix))
{
Set<String> packages = packagesMap.get(prefix);
packages.addAll(packagesSet);
packagesMap.put(prefix, packages);
}
else
{
packagesMap.put(prefix, packagesSet);
}
}
}
44 changes: 26 additions & 18 deletions impl/src/main/java/org/jboss/webbeans/xml/XmlParser.java
Expand Up @@ -5,19 +5,21 @@
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.DefinitionException;
import javax.inject.DeploymentException;
import javax.inject.DeploymentType;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;
import org.jboss.webbeans.log.Log;
import org.jboss.webbeans.log.Logging;
Expand All @@ -30,6 +32,8 @@ public class XmlParser

private boolean haveAnyDeployElement = false;

private Map<String, Set<String>> packagesMap = new HashMap<String, Set<String>>();

public XmlParser(XmlEnvironment environment)
{
this.environment = environment;
Expand Down Expand Up @@ -94,6 +98,7 @@ private Document createDocument(URL url)
SAXReader reader = new SAXReader();
Document document = reader.read(xmlStream);
checkNamespaces(document);
fullFillPackagesMap(document);
return document;
}
catch (IOException e)
Expand Down Expand Up @@ -166,31 +171,34 @@ private List<Class<? extends Annotation>> obtainDeploymentTypes(Element element)
if(deployElements.size() - deployElementsSet.size() != 0)
throw new DefinitionException("The same deployment type is declared more than once");

// String standardName = XmlConstants.STANDARD;
// String standardPrefix = "";
// String standardUri = XmlConstants.JAVA_EE_NAMESPACE;
// Namespace standardNamespace = new Namespace(standardPrefix, standardUri);
// QName qName = new QName(standardName, standardNamespace);
// Element standardElement = element.element(qName);
// if (standardElement == null)
// throw new DeploymentException("The @Standard deployment type must be declared");
String standardName = XmlConstants.STANDARD;
String standardPrefix = "";
String standardUri = XmlConstants.JAVA_EE_NAMESPACE;
Namespace standardNamespace = new Namespace(standardPrefix, standardUri);
QName qName = new QName(standardName, standardNamespace);
Element standardElement = element.element(qName);
if (standardElement == null)
throw new DeploymentException("The @Standard deployment type must be declared");

List<Class<? extends Annotation>> deploymentClasses = new ArrayList<Class<? extends Annotation>>();
List<Element> children = element.elements();
for (Element child : children)
{
String urn = child.getNamespace().getURI();
Class<?> deploymentClass = ParseXmlHelper.loadClassByURN(urn, child.getName());

if(!deploymentClass.isAnnotation())
throw new DeploymentException("<Deploy> child " + element.getName() + " must be a Java annotation type");
{
Class<? extends Annotation> deploymentClass = ParseXmlHelper.loadElementClass(child, Annotation.class, environment, packagesMap);

if(deploymentClass.getAnnotation(DeploymentType.class) == null)
throw new DefinitionException("<Deploy> child " + element.getName() + " must be a deployment type");
// if(deploymentClass.getAnnotation(DeploymentType.class) == null)
// throw new DefinitionException("<Deploy> child <" + element.getName() + "> must be a deployment type");

deploymentClasses.add(deploymentClass.asSubclass(Annotation.class));
deploymentClasses.add(deploymentClass);
}
haveAnyDeployElement = true;
return deploymentClasses;
}

private void fullFillPackagesMap(Document document)
{
Element root = document.getRootElement();
ParseXmlHelper.checkRootAttributes(root, packagesMap);
ParseXmlHelper.checkRootDeclaredNamespaces(root, packagesMap);
}
}
2 changes: 1 addition & 1 deletion jboss-as/build.properties
@@ -1,5 +1,5 @@
# Container a number of properties associated with installing Web Beans into JBoss AS and running the TCK in JBoss AS
#jboss.home=/Applications/jboss-5.0.1.GA
jboss.home=C:\JBoss\jboss-5.0.0\
# recommended minimum JAVA_OPTS for running JBoss with the TCK
java.opts=-Xms128m -Xmx384m -XX:MaxPermSize=128m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000
Expand Down

0 comments on commit 96980f5

Please sign in to comment.