Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
    * JBoss, Home of Professional Open Source
    * Copyright 2005, JBoss Inc., and individual contributors as indicated
    * 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.xb.binding.group;
 
 import java.util.Map;
 
 import  org.jboss.util.Classes;

Author(s):
Alexey Loubyansky
Version:
$Revision: 2045 $
 
 public interface ValueListHandler
 {
    {
       public Object newInstance(ParticleBinding particleValueList valueList)
       {
          Class cls = valueList.getTargetClass();
          Map map = valueList.getNonRequiredValues();
 
          Collection values = map.values();
          if(values.isEmpty())
          {
             throw new JBossXBRuntimeException("Value list does not contain non-required values.");
          }
 
          Constructor ctor = null;
          Constructor[] ctors = cls.getConstructors();
 
          if(ctors == null || ctors.length == 0)
          {
             throw new JBossXBRuntimeException("The class has no declared constructors: " + cls);
          }
 
          for(int i = 0; i < ctors.length; ++i)
          {
             Class[] types = ctors[i].getParameterTypes();
 
             if(types == null || types.length == 0)
             {
                throw new IllegalStateException("Found no-arg constructor for immutable " + cls);
             }
 
             if(types.length == map.size())
             {
                ctor = ctors[i];
 
                int typeInd = 0;
                Iterator iter = values.iterator();
                while(iter.hasNext())
                {
                   Class type = types[typeInd++];
                   if(type.isPrimitive())
                   {
                      type = Classes.getPrimitiveWrapper(type);
                   }
 
                   if(!type.isAssignableFrom(iter.next().getClass()))
                   {
                      ctor = null;
                      break;
                   }
                }
 
                if(ctor != null)
               {
                  break;
               }
            }
         }
         if(ctor == null)
         {
            StringBuffer buf = new StringBuffer();
            buf.append("There is no ctor in ")
               .append(cls)
               .append(" that would take the following arguments:\n");
            int cnt = 0;
            for(Iterator i = values.iterator(); i.hasNext();)
            {
               Object o = i.next();
               buf.append(' ').append(++cnt).append(") ").append(o.getClass()).append(": ").append(o).append('\n');
            }
            throw new IllegalStateException(buf.toString());
         }
         try
         {
            return ctor.newInstance(values.toArray());
         }
         catch(Exception e)
         {
            throw new IllegalStateException("Failed to create immutable instance of " +
               cls +
               " using arguments: "
               + values + ": " + e.getMessage()
            );
         }
      }
   };
   {
      public Object newInstance(ParticleBinding particleValueList valueList)
      {
         Class cls = valueList.getTargetClass();
         int size = valueList.size();
         if(size == 0)
         {
            try
            {
               return newInstance(cls.getConstructor(null), null);
            }
            catch(NoSuchMethodException e)
            {
               throw new JBossXBRuntimeException(
                  "Value list does not contain non-required values and there is no no-arg ctor in " + cls
               );
            }
         }
         Constructor ctor = matchBestCtor(clsvalueList);
         if(ctor == null)
         {
            StringBuffer buf = new StringBuffer();
            buf.append("Failed to find no-arg ctor or best-match ctor in ")
               .append(cls)
               .append(", property values:\n");
            int cnt = 0;
            for(int i = 0; i < size; ++i)
            {
               Object o = valueList.getValue(i).;
               buf.append(' ').append(++cnt).append(") ").append(o).append('\n');
            }
            throw new JBossXBRuntimeException(buf.toString());
         }
         Object o;
         int argsTotal = ctor.getParameterTypes().length;
         if(argsTotal == size)
         {
            Object[] args = getArgs(ctorvalueList);
            o = newInstance(ctorargs);
         }
         else
         {
            Object[] args = getArgs(ctorvalueList);
            o = newInstance(ctorargs);
            int i = argsTotal;
            while(i < size)
            {
               ValueList.NonRequiredValue valueEntry = valueList.getValue(i++);
               Object binding = valueEntry.binding;
               if(binding instanceof ParticleBinding)
               {
                  Object handler = valueEntry.handler;
                  ParticleBinding childParticle = (ParticleBinding)binding;
                  if(handler instanceof ParticleHandler)
                  {
                     ParticleHandler pHandler = (ParticleHandler)handler;
                     if(childParticle.isRepeatable())
                     {
                        TermBinding term = childParticle.getTerm();
                        if(!(o instanceof GenericValueContainer) &&
                              term.getAddMethodMetaData() == null &&
                              term.getMapEntryMetaData() == null &&
                              term.getPutMethodMetaData() == null)
                        {
                           pHandler.setParent(ovalueEntry.valuevalueEntry.qNamechildParticleparticle);
                        }
                        else
                        {
                           Collection col = (Collection)valueEntry.value;
                           for(Iterator iter = col.iterator(); iter.hasNext();)
                           {
                              pHandler.setParent(oiter.next(), valueEntry.qNamechildParticleparticle);
                           }
                        }
                     }
                     else
                     {
                        pHandler.setParent(ovalueEntry.valuevalueEntry.qNamechildParticleparticle);
                     }
                  }
                  else
                  {
                     ((CharactersHandler)handler).setValue(valueEntry.qName,
                        (ElementBinding)childParticle.getTerm(),
                        o,
                        valueEntry.value
                     );
                  }
               }
               else if(binding instanceof AttributeBinding)
               {
                  AttributeBinding attr = (AttributeBinding)binding;
                  AttributeHandler handler = attr.getHandler();
                  if(handler != null)
                  {
                     handler.attribute(valueEntry.qNameattr.getQName(), attrovalueEntry.value);
                  }
                  else
                  {
                     throw new JBossXBRuntimeException("Attribute binding present but has no handler: element=" +
                        valueEntry.qName +
                        ", attrinute=" +
                        attr.getQName()
                     );
                  }
               }
               else
               {
                  throw new JBossXBRuntimeException("Unexpected binding type: " + binding);
               }
            }
         }
         return o;
      }
      private Constructor matchBestCtor(Class clsValueList valueList)
      {
         Constructor bestMatch = null;
         int bestMatchArgsTotal = 0;
         Constructor[] ctors = cls.getConstructors();
         int size = valueList.size();
         for(int i = 0; i < ctors.length; ++i)
         {
            Constructor ctor = ctors[i];
            Class[] types = ctor.getParameterTypes();
            if((types == null || types.length == 0) && bestMatch == null)
            {
               bestMatch = ctor;
               continue;
            }
            if(bestMatchArgsTotal <= types.length)
            {
               int typeInd = 0;
               for(int valueInd = 0; typeInd < types.length && valueInd < size; ++typeInd, ++valueInd)
               {
                  Class type = types[typeInd];
                  if(type.isPrimitive())
                  {
                     type = Classes.getPrimitiveWrapper(type);
                  }
                  ValueList.NonRequiredValue valueEntry = valueList.getValue(valueInd);
                  Object value = valueEntry.value;
                  if(value != null &&
                     !(type.isAssignableFrom(value.getClass()) ||
                     // if particle is repeatable and the type is array of a specific collection
                     // then we assume we can convert the arg later at creation time
                     // todo this code should be smarter
                     valueEntry.binding instanceof ParticleBinding &&
                     ((ParticleBinding)valueEntry.binding).isRepeatable() &&
                     type.isArray()
                     ))
                  {
                     break;
                  }
                  if(bestMatchArgsTotal == types.length &&
                     !bestMatch.getParameterTypes()[typeInd].isAssignableFrom(type))
                  {
                     break;
                  }
               }
               if(typeInd == types.length)
               {
                  bestMatch = ctor;
                  bestMatchArgsTotal = types.length;
               }
            }
         }
         return bestMatch;
      }
      private Object newInstance(Constructor bestMatchObject[] args)
      {
         try
         {
            return bestMatch.newInstance(args);
         }
         catch(Exception e)
         {
            throw new JBossXBRuntimeException("Failed to create an instance of " +
               bestMatch.getDeclaringClass() +
               " using the following ctor arguments " +
               Arrays.asList(args), e
            );
         }
      }
      private Object[] getArgs(Constructor ctorValueList valueList)
      {
         Class[] types = ctor.getParameterTypes();
         Object[] args = new Object[types.length];
         for(int i = 0; i < types.length; ++i)
         {
            ValueList.NonRequiredValue valueEntry = valueList.getValue(i);
            Object arg = valueEntry.value;
            if(valueEntry.value != null && !types[i].isAssignableFrom(arg.getClass()))
            {
               // if type is array then convert collection to array
               // todo this part should be smarter about collections
               if(types[i].isArray() && Collection.class.isAssignableFrom(arg.getClass()))
               {
                  Collection col = (Collection)arg;
                  arg = Array.newInstance(types[i].getComponentType(), col.size());
                  int arrInd = 0;
                  for(Iterator iter = col.iterator(); iter.hasNext();)
                  {
                     Array.set(argarrInd++, iter.next());
                  }
               }
            }
            args[i] = arg;
         }
         return args;
      }
   };
   class FACTORY
   {
      
Collects children and adds them all at the time the newInstance is called.

Parameters:
parent the parent object
Returns:
the parent object
      public static ValueListHandler lazy(final Object parent)
      {
         return new ValueListHandler()
         {
            private final ValueList parentValueList = parent instanceof ValueList ? (ValueList)parent : null;
            
            public Object newInstance(ParticleBinding particleValueList valueList)
            {
               for(int i = 0; i < valueList.size(); ++i)
               {
                  ValueList.NonRequiredValue valueEntry = valueList.getValue(i);
                  Object binding = valueEntry.binding;
                  if(binding instanceof ParticleBinding)
                  {
                     Object handler = valueEntry.handler;
                     ParticleBinding childParticle = (ParticleBinding)binding;
                     if(handler instanceof ParticleHandler)
                     {
                        ParticleHandler pHandler = (ParticleHandler)handler;
                        if(childParticle.isRepeatable())
                        {
                           if( != null)
                           {
                              .addTermValue(valueEntry.qNamechildParticlepHandlervalueEntry.valuenull);
                           }
                           else
                           {
                              Collection col = (CollectionvalueEntry.value;
                              //System.out.println("newInstance: " + childParticle.getTerm() + "=" + col);
                              pHandler.setParent(parentcolvalueEntry.qNamechildParticlevalueEntry.parentParticle);
/*                              for (Iterator iter = col.iterator(); iter.hasNext();)
                              {
                                 pHandler.setParent(parent, iter.next(), valueEntry.qName, childParticle,
                                       valueEntry.parentParticle);
                              }                              
*/
                           }
                        }
                        else
                        {
                           if( != null)
                           {
                              .addTermValue(valueEntry.qNamechildParticlepHandlervalueEntry.valuevalueEntry.parentParticle);
                           }
                           else
                           {
                              pHandler.setParent(parentvalueEntry.valuevalueEntry.qNamechildParticlevalueEntry.parentParticle);
                           }
                        }
                     }
                     else
                     {
                        CharactersHandler cHandler = (CharactersHandler)handler;
                        if( != null)
                        {
                           .addTextValue(valueEntry.qNamechildParticlecHandlervalueEntry.value);
                        }
                        else
                        {
                           cHandler.setValue(valueEntry.qName, (ElementBindingchildParticle.getTerm(), parentvalueEntry.value);
                        }
                     }
                  }
                  else if(binding instanceof AttributeBinding)
                  {
                     AttributeBinding attr = (AttributeBinding)binding;
                     AttributeHandler handler = attr.getHandler();
                     if(handler != null)
                     {
                        if( != null)
                        {
                           .setAttributeValue(attr.getQName(), attrvalueEntry.value);
                        }
                        else
                        {
                           handler.attribute(valueEntry.qNameattr.getQName(), attrparentvalueEntry.value);
                        }
                     }
                     else
                     {
                        throw new JBossXBRuntimeException("Attribute binding present but has no handler: element=" +
                           valueEntry.qName +
                           ", attrinute=" +
                           attr.getQName()
                        );
                     }
                  }
                  else
                  {
                     throw new JBossXBRuntimeException("Unexpected binding type: " + binding);
                  }
               }
               return parent;
            }
         };
      }
      
      public static ValueListHandler child()
      {
         return new ValueListHandler()
         {
            public Object newInstance(ParticleBinding particleValueList valueList)
            {
               if(valueList.size() > 1)
               {
                  String msg = "Expected only one child for " + particle.getTerm() + " but got:";
                  for(int i = 0; i < valueList.size(); ++i)
                  {
                     ValueList.NonRequiredValue valueEntry = valueList.getValue(0);
                     msg += " " + valueEntry.value + ";";
                  }
                  throw new JBossXBRuntimeException(msg);
               }
               
               ValueList.NonRequiredValue valueEntry = valueList.getValue(0);
               return valueEntry.value;
            }            
         };
      }
   };
      
   Object newInstance(ParticleBinding particleValueList valueList);
New to GrepCode? Check out our FAQ X