[weld-commits] Weld SVN: r5193 - core/trunk/impl/src/main/java/org/jboss/weld/xml.

weld-commits at lists.jboss.org weld-commits at lists.jboss.org
Wed Dec 2 15:04:30 EST 2009


Author: nickarls
Date: 2009-12-02 15:04:29 -0500 (Wed, 02 Dec 2009)
New Revision: 5193

Added:
   core/trunk/impl/src/main/java/org/jboss/weld/xml/BeansXmlElement.java
   core/trunk/impl/src/main/java/org/jboss/weld/xml/EnabledClasses.java
   core/trunk/impl/src/main/java/org/jboss/weld/xml/MergedElements.java
Modified:
   core/trunk/impl/src/main/java/org/jboss/weld/xml/BeansXmlParser.java
   core/trunk/impl/src/main/java/org/jboss/weld/xml/WeldXmlException.java
Log:
Tidied up beans.xml parsing while looking at WELD-319

Added: core/trunk/impl/src/main/java/org/jboss/weld/xml/BeansXmlElement.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/xml/BeansXmlElement.java	                        (rev 0)
+++ core/trunk/impl/src/main/java/org/jboss/weld/xml/BeansXmlElement.java	2009-12-02 20:04:29 UTC (rev 5193)
@@ -0,0 +1,122 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.weld.xml;
+
+import static org.jboss.weld.logging.messages.XmlMessage.CANNOT_LOAD_CLASS;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.weld.DeploymentException;
+import org.jboss.weld.logging.messages.XmlMessage;
+import org.jboss.weld.resources.spi.ResourceLoader;
+import org.jboss.weld.resources.spi.ResourceLoadingException;
+import org.jboss.weld.util.dom.NodeListIterable;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * 
+ * @author Nicklas Karlsson
+ * 
+ */
+public class BeansXmlElement
+{
+   private URL file;
+   private Element element;
+   private List<String> classNames;
+
+   private BeansXmlElement(URL file, Element element)
+   {
+      super();
+      this.file = file;
+      this.element = element;
+      classNames = new ArrayList<String>();
+   }
+
+   public BeansXmlElement validateWithMessage(XmlMessage multipleViolationMessage)
+   {
+      for (Node child : new NodeListIterable(element.getChildNodes()))
+      {
+         String className = getClassNameFromNode(child);
+         if (className == null)
+         {
+            continue;
+         }
+         if (classNames.contains(className))
+         {
+            throw new DeploymentException(multipleViolationMessage);
+         }
+         classNames.add(className);
+      }
+      return this;
+   }
+
+   private String getClassNameFromNode(Node node)
+   {
+      if (node instanceof Element)
+      {
+         if (node.getChildNodes().getLength() == 1 && node.getChildNodes().item(0) instanceof Text)
+         {
+            String className = ((Text) node.getChildNodes().item(0)).getData();
+            return className;
+         }
+      }
+      return null;
+   }
+
+   public static BeansXmlElement of(URL file, Node element)
+   {
+      return new BeansXmlElement(file, (Element) element);
+   }
+
+   public List<Class<?>> getClasses(ResourceLoader resourceLoader)
+   {
+      List<Class<?>> classes = new ArrayList<Class<?>>();
+      for (String className : classNames)
+      {
+         try
+         {
+            classes.add(resourceLoader.classForName(className));
+         }
+         catch (ResourceLoadingException e)
+         {
+            throw new DeploymentException(CANNOT_LOAD_CLASS, className, file);
+         }
+      }
+      return classes;
+   }
+
+   public URL getFile()
+   {
+      return file;
+   }
+
+   public Element getElement()
+   {
+      return element;
+   }
+
+   @Override
+   public String toString()
+   {
+      return "File: " + getFile() + "; Node: " + getElement();
+   }
+
+}
\ No newline at end of file

Modified: core/trunk/impl/src/main/java/org/jboss/weld/xml/BeansXmlParser.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/xml/BeansXmlParser.java	2009-12-02 14:59:26 UTC (rev 5192)
+++ core/trunk/impl/src/main/java/org/jboss/weld/xml/BeansXmlParser.java	2009-12-02 20:04:29 UTC (rev 5193)
@@ -16,19 +16,14 @@
  */
 package org.jboss.weld.xml;
 
-import static org.jboss.weld.logging.messages.XmlMessage.CANNOT_LOAD_CLASS;
 import static org.jboss.weld.logging.messages.XmlMessage.CONFIGURATION_ERROR;
 import static org.jboss.weld.logging.messages.XmlMessage.LOAD_ERROR;
-import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_ALTERNATIVES;
-import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_DECORATORS;
-import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_INTERCEPTORS;
 import static org.jboss.weld.logging.messages.XmlMessage.PARSING_ERROR;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.List;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -37,266 +32,133 @@
 
 import org.jboss.weld.DeploymentException;
 import org.jboss.weld.resources.spi.ResourceLoader;
-import org.jboss.weld.resources.spi.ResourceLoadingException;
-import org.jboss.weld.util.dom.NodeListIterable;
 import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
 import org.xml.sax.SAXException;
 
 /**
  * Simple parser for beans.xml
  * 
  * @author Pete Muir
- *
+ * @author Nicklas Karlsson
  */
 public class BeansXmlParser
 {
-   
-   private static class XmlElement
-   {
-      private URL file;
-      private Element element;
-      
-      public XmlElement(URL file, Element element)
-      {
-         super();
-         this.file = file;
-         this.element = element;
-      }
-      
-      public URL getFile()
-      {
-         return file;
-      }
-      
-      public Element getElement()
-      {
-         return element;
-      }
-      
-      @Override
-      public String toString()
-      {
-         return "File: " + getFile() + "; Node: " + getElement();
-      }
-      
-   }
-   
-   private final Iterable<URL> beansXml;
+   private final Iterable<URL> beansXmls;
    private final ResourceLoader resourceLoader;
-   
-   private List<Class<? extends Annotation>> enabledPolicyStereotypes;
-   private List<Class<?>> enabledPolicyClasses;
-   private List<Class<?>> enabledDecoratorClasses;
-   private List<Class<?>> enabledInterceptorClasses;
-   
+   private EnabledClasses enabledClasses = null;
+
    public List<Class<?>> getEnabledPolicyClasses()
    {
-      return enabledPolicyClasses;
+      return enabledClasses.getEnabledPolicyClasses();
    }
-   
+
    public List<Class<? extends Annotation>> getEnabledPolicyStereotypes()
    {
-      return enabledPolicyStereotypes;
+      return enabledClasses.getEnabledPolicyStereotypes();
    }
-   
+
    public List<Class<?>> getEnabledDecoratorClasses()
    {
-      return enabledDecoratorClasses;
+      return enabledClasses.getEnabledDecoratorClasses();
    }
-   
+
    public List<Class<?>> getEnabledInterceptorClasses()
    {
-      return enabledInterceptorClasses;
+      return enabledClasses.getEnabledInterceptorClasses();
    }
-   
+
    public BeansXmlParser(ResourceLoader resourceLoader, Iterable<URL> beansXml)
    {
-      this.beansXml = beansXml;
+      this.beansXmls = beansXml;
       this.resourceLoader = resourceLoader;
    }
-   
+
    public void parse()
    {
-      DocumentBuilder documentBuilder;
-      try
+      DocumentBuilder documentBuilder = getDocumentBuilder();
+      MergedElements mergedElements = new MergedElements();
+      for (URL beansXml : beansXmls)
       {
-         documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-      }
-      catch (ParserConfigurationException e)
-      {
-         throw new WeldXmlException(CONFIGURATION_ERROR, e);
-      }
-      List<XmlElement> policiesElements = new ArrayList<XmlElement>(); 
-      List<XmlElement> decoratorsElements = new ArrayList<XmlElement>(); 
-      List<XmlElement> interceptorsElements = new ArrayList<XmlElement>(); 
-      for (URL url : beansXml)
-      {
-         InputStream is;
-         boolean fileHasContents;
-         try
+         // TODO: Do we really need to check if there is content?
+         if (!isBeansXmlOK(beansXml))
          {
-            is = url.openStream();
-            fileHasContents = is.available() > 0;
+            continue;
          }
-         catch (IOException e)
-         {
-            throw new WeldXmlException(LOAD_ERROR, e, url.toString());
-         }
-         if (fileHasContents)
-         {
-            Document document;
-            try
-            {
-               document = documentBuilder.parse(is);
-               document.normalize();
-            }
-            catch (SAXException e)
-            {
-               throw new DeploymentException(PARSING_ERROR, e, url.toString());
-            }
-            catch (IOException e)
-            {
-               throw new DeploymentException(LOAD_ERROR, e, url.toString());
-            }
-            Element beans = document.getDocumentElement();
-            for (Node child : new NodeListIterable(beans.getChildNodes()))
-            {
-               if (child instanceof Element && "alternatives".equals(child.getNodeName()))
-               {
-                  policiesElements.add(new XmlElement(url, (Element) child));
-               }
-               if (child instanceof Element && "interceptors".equals(child.getNodeName()))
-               {
-                  interceptorsElements.add(new XmlElement(url, (Element) child));
-               }
+         Document document = getDocument(documentBuilder, beansXml);
+         mergedElements.merge(beansXml, document);
+      }
+      enabledClasses = EnabledClasses.of(mergedElements, resourceLoader);
+   }
 
-               if (child instanceof Element && "decorators".equals(child.getNodeName()))
-               {
-                  decoratorsElements.add(new XmlElement(url, (Element) child));
-               }
-            }
-         }
+   private Document getDocument(DocumentBuilder documentBuilder, URL beansXml)
+   {
+      Document document;
+      InputStream in = null;
+      try
+      {
+         in = beansXml.openStream();
+         document = documentBuilder.parse(in);
+         document.normalize();
       }
-      
-      if (policiesElements.size() > 1)
+      catch (SAXException e)
       {
-         throw new DeploymentException(MULTIPLE_ALTERNATIVES, policiesElements);
+         throw new DeploymentException(PARSING_ERROR, e, beansXml.toString());
       }
-      else if (policiesElements.size() == 1)
+      catch (IOException e)
       {
-         enabledPolicyStereotypes = new ArrayList<Class<? extends Annotation>>();
-         enabledPolicyClasses = new ArrayList<Class<?>>();
-         processPolicyElement(resourceLoader, policiesElements.get(0), enabledPolicyClasses, enabledPolicyStereotypes);
+         throw new DeploymentException(LOAD_ERROR, e, beansXml.toString());
       }
-      
-      if (decoratorsElements.size() > 1)
+      finally
       {
-         throw new DeploymentException(MULTIPLE_DECORATORS, decoratorsElements);
+         closeStream(in);
       }
-      else if (decoratorsElements.size() == 1)
+      return document;
+   }
+
+   private void closeStream(InputStream in)
+   {
+      if (in == null)
       {
-         enabledDecoratorClasses = new ArrayList<Class<?>>();
-         enabledDecoratorClasses.addAll(processElement(resourceLoader, decoratorsElements.get(0)));
+         return;
       }
-      
-      if (interceptorsElements.size() > 1)
+      try
       {
-         throw new DeploymentException(MULTIPLE_INTERCEPTORS, interceptorsElements);
+         in.close();
       }
-      else if (interceptorsElements.size() == 1)
+      catch (IOException e)
       {
-         enabledInterceptorClasses = new ArrayList<Class<?>>();
-         enabledInterceptorClasses.addAll(processInterceptorElement(resourceLoader, interceptorsElements.get(0)));
+         e.printStackTrace();
       }
-      
    }
-   
-   private static void processPolicyElement(ResourceLoader resourceLoader, XmlElement element, List<Class<?>> enabledPolicyClasses, List<Class<? extends Annotation>> enabledPolicyStereotypes)
+
+   private boolean isBeansXmlOK(URL beansXml)
    {
-      for (Node child : new NodeListIterable(element.getElement().getChildNodes()))
+      InputStream in = null;
+      try
       {
-         String className = processNode(child);
-         if (className != null)
-         {
-            try
-            {
-               Class<?> clazz = resourceLoader.classForName(className);
-               if (clazz.isAnnotation())
-               {
-                  enabledPolicyStereotypes.add(clazz.asSubclass(Annotation.class));
-               }
-               else
-               {
-                  enabledPolicyClasses.add(clazz);
-               }
-            }
-            catch (ResourceLoadingException e)
-            {
-               throw new DeploymentException(CANNOT_LOAD_CLASS, className, element.getFile());
-            }
-         }
+         in = beansXml.openStream();
+         return in.available() > 0;
       }
-   }
-   
-   private static String processNode(Node node)
-   {
-      if (node instanceof Element)
+      catch (IOException e)
       {
-         if (node.getChildNodes().getLength() == 1 && node.getChildNodes().item(0) instanceof Text)
-         {
-            String className = ((Text) node.getChildNodes().item(0)).getData();
-            return className;
-         }
+         throw new WeldXmlException(LOAD_ERROR, e, beansXml.toString());
       }
-      return null;
-   }
-   
-   private static List<Class<?>> processElement(ResourceLoader resourceLoader, XmlElement element)
-   {
-      List<Class<?>> list = new ArrayList<Class<?>>();
-      for (Node child : new NodeListIterable(element.getElement().getChildNodes()))
+      finally
       {
-         String className = processNode(child);
-         if (className != null)
-         {
-            try
-            {
-               list.add(resourceLoader.classForName(className));
-            }
-            catch (ResourceLoadingException e)
-            {
-               throw new DeploymentException(CANNOT_LOAD_CLASS, className, element.getFile());
-            }
-         }
+         closeStream(in);
       }
-      return list;
    }
 
-
-   //TODO - move validation to Validator
-   private static List<Class<?>> processInterceptorElement(ResourceLoader resourceLoader, XmlElement element)
+   private DocumentBuilder getDocumentBuilder()
    {
-      List<Class<?>> list = new ArrayList<Class<?>>();
-      for (Node child : new NodeListIterable(element.getElement().getChildNodes()))
+      try
       {
-         String className = processNode(child);
-         if (className != null)
-         {
-            try
-            {
-               Class<?> clazz = resourceLoader.classForName(className);
-               list.add(clazz);
-            }
-            catch (ResourceLoadingException e)
-            {
-               throw new DeploymentException(CANNOT_LOAD_CLASS, className, element.getFile());
-            }
-         }
+         return DocumentBuilderFactory.newInstance().newDocumentBuilder();
       }
-      return list;
+      catch (ParserConfigurationException e)
+      {
+         throw new WeldXmlException(CONFIGURATION_ERROR, e);
+      }
    }
-   
+
 }

Added: core/trunk/impl/src/main/java/org/jboss/weld/xml/EnabledClasses.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/xml/EnabledClasses.java	                        (rev 0)
+++ core/trunk/impl/src/main/java/org/jboss/weld/xml/EnabledClasses.java	2009-12-02 20:04:29 UTC (rev 5193)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.weld.xml;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import org.jboss.weld.resources.spi.ResourceLoader;
+
+/**
+ * 
+ * @author Nicklas Karlsson
+ *
+ */
+public class EnabledClasses
+{
+   private List<Class<? extends Annotation>> enabledPolicyStereotypes;
+   private List<Class<?>> enabledPolicyClasses;
+   private List<Class<?>> enabledDecoratorClasses;
+   private List<Class<?>> enabledInterceptorClasses;
+   private ResourceLoader resourceLoader;
+
+   private EnabledClasses(MergedElements beanXmlElements, ResourceLoader resourceLoader)
+   {
+      enabledPolicyStereotypes = new ArrayList<Class<? extends Annotation>>();
+      enabledPolicyClasses = new ArrayList<Class<?>>();
+      enabledDecoratorClasses = new ArrayList<Class<?>>();
+      enabledInterceptorClasses = new ArrayList<Class<?>>();
+      this.resourceLoader = resourceLoader;
+      process(beanXmlElements);
+   }
+
+   public static EnabledClasses of(MergedElements beanXmlElements, ResourceLoader resourceLoader)
+   {
+      return new EnabledClasses(beanXmlElements, resourceLoader);
+   }
+
+   private void process(MergedElements beanXmlElements)
+   {
+      processPolicies(beanXmlElements.getPoliciesElements());
+      enabledDecoratorClasses.addAll(getClassesInElements(beanXmlElements.getDecoratorsElements()));
+      enabledInterceptorClasses.addAll(getClassesInElements(beanXmlElements.getInterceptorsElements()));
+   }
+
+   private void processPolicies(List<BeansXmlElement> policyElements)
+   {
+      Collection<Class<?>> classes = getClassesInElements(policyElements);
+      for (Class<?> clazz : classes) {
+         if (clazz.isAnnotation()) {
+            enabledPolicyStereotypes.add(clazz.asSubclass(Annotation.class));
+         } else {
+            enabledPolicyClasses.add(clazz);
+         }
+      }
+   }
+   
+   private Collection<Class<?>> getClassesInElements(List<BeansXmlElement> elements)
+   {
+      LinkedHashSet<Class<?>> classes = new LinkedHashSet<Class<?>>();
+      for (BeansXmlElement element : elements)
+      {
+         classes.addAll(element.getClasses(resourceLoader));
+      }
+      return classes;
+   }
+
+   public List<Class<? extends Annotation>> getEnabledPolicyStereotypes()
+   {
+      return enabledPolicyStereotypes;
+   }
+
+   public List<Class<?>> getEnabledPolicyClasses()
+   {
+      return enabledPolicyClasses;
+   }
+
+   public List<Class<?>> getEnabledDecoratorClasses()
+   {
+      return enabledDecoratorClasses;
+   }
+
+   public List<Class<?>> getEnabledInterceptorClasses()
+   {
+      return enabledInterceptorClasses;
+   }
+}

Added: core/trunk/impl/src/main/java/org/jboss/weld/xml/MergedElements.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/xml/MergedElements.java	                        (rev 0)
+++ core/trunk/impl/src/main/java/org/jboss/weld/xml/MergedElements.java	2009-12-02 20:04:29 UTC (rev 5193)
@@ -0,0 +1,87 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.weld.xml;
+
+import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_ALTERNATIVES;
+import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_DECORATORS;
+import static org.jboss.weld.logging.messages.XmlMessage.MULTIPLE_INTERCEPTORS;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.weld.DeploymentException;
+import org.jboss.weld.logging.messages.XmlMessage;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * 
+ * @author Nicklas Karlsson
+ * 
+ */
+public class MergedElements
+{
+   private List<BeansXmlElement> policiesElements = new ArrayList<BeansXmlElement>();
+   private List<BeansXmlElement> decoratorsElements = new ArrayList<BeansXmlElement>();
+   private List<BeansXmlElement> interceptorsElements = new ArrayList<BeansXmlElement>();
+
+
+   public void merge(URL url, Document beansXmlDocument)
+   {
+      Element documentElement = beansXmlDocument.getDocumentElement();
+      policiesElements.addAll(getNamedElement(url, documentElement, "alternatives", MULTIPLE_ALTERNATIVES));
+      interceptorsElements.addAll(getNamedElement(url, documentElement, "interceptors", MULTIPLE_INTERCEPTORS));
+      decoratorsElements.addAll(getNamedElement(url, documentElement, "decorators", MULTIPLE_DECORATORS));
+   }
+
+   // TODO: look over exception message when multiple blocks or multiple
+   // classes. Now they're the same.
+   private List<BeansXmlElement> getNamedElement(URL url, Element beans, String name, XmlMessage multipleViolationMessage)
+   {
+      List<BeansXmlElement> elements = new ArrayList<BeansXmlElement>();
+      NodeList nodeList = beans.getElementsByTagName(name);
+      if (nodeList.getLength() > 1)
+      {
+         throw new DeploymentException(multipleViolationMessage);
+      }
+      else if (nodeList.getLength() == 1)
+      {
+         BeansXmlElement element = BeansXmlElement.of(url, nodeList.item(0)).validateWithMessage(multipleViolationMessage);
+         elements.add(element);
+      }
+      return elements;
+   }
+
+   
+   public List<BeansXmlElement> getPoliciesElements()
+   {
+      return policiesElements;
+   }
+
+   public List<BeansXmlElement> getDecoratorsElements()
+   {
+      return decoratorsElements;
+   }
+
+   public List<BeansXmlElement> getInterceptorsElements()
+   {
+      return interceptorsElements;
+   }
+
+}

Modified: core/trunk/impl/src/main/java/org/jboss/weld/xml/WeldXmlException.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/xml/WeldXmlException.java	2009-12-02 14:59:26 UTC (rev 5192)
+++ core/trunk/impl/src/main/java/org/jboss/weld/xml/WeldXmlException.java	2009-12-02 20:04:29 UTC (rev 5193)
@@ -28,7 +28,7 @@
  * support.
  * 
  * @author David Allen
- *
+ * 
  */
 public class WeldXmlException extends InjectionException
 {



More information about the weld-commits mailing list