/* * JBoss, Home of Professional Open Source * Copyright 2010, Red Hat, Inc., and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.solder.config.xml.parser.namespace; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.jboss.solder.config.xml.model.AnnotationXmlItem; import org.jboss.solder.config.xml.model.ClassXmlItem; import org.jboss.solder.config.xml.model.MethodXmlItem; import org.jboss.solder.config.xml.model.ParameterXmlItem; import org.jboss.solder.config.xml.model.PropertyXmlItem; import org.jboss.solder.config.xml.model.XmlItem; import org.jboss.solder.config.xml.model.XmlItemType; import org.jboss.solder.config.xml.parser.SaxNode; import org.jboss.solder.config.xml.util.TypeOccuranceInformation; import org.jboss.solder.properties.Property; import org.jboss.solder.properties.query.NamedPropertyCriteria; import org.jboss.solder.properties.query.PropertyQueries; import org.jboss.solder.properties.query.PropertyQuery; import org.jboss.solder.reflection.Reflections; public class PackageNamespaceElementResolver implements NamespaceElementResolver { private final String pack; private final Map<String, Class<?>> cache = new HashMap<String, Class<?>>(); private final Set<String> notFound = new HashSet<String>(); public PackageNamespaceElementResolver(String pack) { this.pack = pack + "."; } public XmlItem getItemForNamespace(SaxNode node, XmlItem parent) { String name = node.getName(); if (notFound.contains(name)) { return null; } try { Class<?> c; if (cache.containsKey(name)) { c = cache.get(name); } else { c = getClass().getClassLoader().loadClass(pack + name); cache.put(name, c); } if (c.isAnnotation()) { return new AnnotationXmlItem(parent, c, node.getInnerText(), node.getAttributes(), node.getDocument(), node.getLineNo()); } else { // if it is a method or constructor parameter if (parent != null && parent.getType() == XmlItemType.PARAMETERS) { return new ParameterXmlItem(parent, c, node.getDocument(), node.getLineNo()); } else { return new ClassXmlItem(parent, c, node.getAttributes(), node.getDocument(), node.getLineNo()); } } } catch (ClassNotFoundException e) { } catch (NoClassDefFoundError e) // this can get thrown when there is a // case insensitive file system { } catch (LinkageError e) { // this may be thrown by jboss modules instead of NoClassDefFoundError } if (parent != null) { // if the item can be a method of a FIELD if (TypeOccuranceInformation.isTypeInSet(parent.getAllowedItem(), XmlItemType.METHOD) || TypeOccuranceInformation.isTypeInSet(parent.getAllowedItem(), XmlItemType.FIELD)) { return resolveMethodOrField(name, parent, node); } else { notFound.add(name); } } else { notFound.add(name); } return null; } public static XmlItem resolveMethodOrField(String name, XmlItem parent, SaxNode node) { Class<?> p = parent.getJavaClass(); boolean methodFound = Reflections.methodExists(p, name); PropertyQuery<Object> query = PropertyQueries.createQuery(parent.getJavaClass()); query.addCriteria(new NamedPropertyCriteria(name)); Property<Object> property = query.getFirstWritableResult(); if (methodFound && property != null) { // if there is both a method and a field of the same name // we look for the <parameters> element for (SaxNode child : node.getChildren()) { if (child.getName().equals(XmlItemType.PARAMETERS.getElementName())) { property = null; } } if (property != null) { methodFound = false; } } if (methodFound) { return new MethodXmlItem(parent, name, node.getDocument(), node.getLineNo()); } else if (property != null) { // ensure the property is accessible property.setAccessible(); return new PropertyXmlItem(parent, property, node.getInnerText(), null, node.getDocument(), node.getLineNo()); } return null; } }