private boolean checkForAdapter(String s, Set<IRelation> filtered) {
    IClass adapter = findClass(s);
    IClass adaptee = null;
    IClass target = null;
    for (IRelation r : filtered) {
      if (r.getSrc().equals(s) && r.getType().equals("ASSOCIATION")) {
        adaptee = findClass(r.getDest());
      }
      if (r.getSrc().equals(s) && r.getType().equals("IMPLEMENTS")) {
        target = findClass(r.getDest());
      }
    }
    if (adaptee == null || target == null) return false;
    for (IField f : adapter.getFields()) {
      if (f.getType().equals(adaptee.getName())) {
        adapter.setStereotype("adapter");
        adaptee.setStereotype("adaptee");
        target.setStereotype("target");
        adapter.setPattern("ADAPTER");
        adaptee.setPattern("ADAPTER");
        target.setPattern("ADAPTER");
        for (IRelation r : m.getRelations()) {
          if (r.getSrc().equals(s)
              && r.getDest().equals(adaptee.getName())
              && r.getType().equals("ASSOCIATION")) {
            r.setLabel("adapts");
          }
        }
        return true;
      }
    }

    return false;
  }
 /**
  * Check that child components are of types compatible with the collection item-type. This method
  * may call itself recursively to process the children of child components which do not themselves
  * set a type.
  *
  * @param vctx validation context
  * @param type collection item type
  * @param children list of child components to be checked
  */
 private void checkCollectionChildren(ValidationContext vctx, IClass type, ArrayList children) {
   for (int i = 0; i < children.size(); i++) {
     ElementBase child = (ElementBase) children.get(i);
     if (!vctx.isSkipped(child)) {
       boolean expand = true;
       if (child instanceof IComponent) {
         IComponent comp = (IComponent) child;
         IClass ctype = comp.getType();
         expand = false;
         if (comp instanceof ContainerElementBase) {
           ContainerElementBase contain = (ContainerElementBase) comp;
           if (contain.hasObject()) {
             ctype = contain.getObjectType();
           } else {
             expand = true;
           }
         }
         if (!expand) {
           if (!ctype.isAssignable(type)) {
             vctx.addFatal(
                 "References to collection items must "
                     + "use compatible types: "
                     + ctype.getName()
                     + " cannot be used as "
                     + type.getName(),
                 child);
           }
         }
       }
       if (expand && child instanceof NestingElementBase) {
         checkCollectionChildren(vctx, type, ((NestingElementBase) child).children());
       }
     }
   }
 }
 /**
  * Get best binding component for class. Finds the component based on a fully qualified class
  * name. If a specific component for the actual class is not found (either in this or a containing
  * level) this returns the most specific superclass component.
  *
  * @param clas information for target class
  * @return binding component definition for class, or <code>null</code> if none found
  */
 public ElementBase getMostSpecificComponent(IClass clas) {
   ElementBase comp = getSpecificComponent(clas.getName());
   while (comp == null) {
     IClass sclas = clas.getSuperClass();
     if (sclas == null) {
       break;
     }
     clas = sclas;
     comp = getSpecificComponent(clas.getName());
   }
   return comp;
 }
 private IClass findClass(String s) {
   for (IClass c : m.getClasses()) {
     if (c.getName().equals(s)) {
       return c;
     }
   }
   return null;
 }
  /**
   * Add typed component to set defined at this level. This associated the component with the type
   * for class hierarchy-based lookups.
   *
   * @param type type name to be associated with component
   * @param comp definition component to be added
   * @param vctx validation context in use
   */
  public void addTypedComponent(IClass clas, ElementBase comp, ValidationContext vctx) {
    String type = clas.getName();
    if (m_typeToComponentMap.put(type, comp) == null) {

      // new type, add all interfaces and supertypes to compatible set
      String[] interfaces = clas.getInterfaces();
      for (int i = 0; i < interfaces.length; i++) {
        m_compatibleTypeSet.add(interfaces[i]);
      }
      IClass sclas = clas;
      do {
        m_compatibleTypeSet.add(sclas.getName());
      } while ((sclas = sclas.getSuperClass()) != null);

    } else {
      vctx.addError("Duplicate conversion defined for type " + type, comp);
    }
  }
 /**
  * Checks if a class is compatible with one or more components. If a specific component for the
  * actual class is not found (either in this or a containing level) this checks for components
  * that handle subclasses or implementations of the class.
  *
  * @param clas information for target class
  * @return <code>true</code> if compatible type, <code>false</code> if not
  */
 public boolean isCompatibleType(IClass clas) {
   if (m_compatibleTypeSet.contains(clas.getName())) {
     return true;
   } else if (m_outerContext != null) {
     return m_outerContext.isCompatibleType(clas);
   } else {
     return false;
   }
 }
  /* (non-Javadoc)
   * @see org.jibx.binding.model.ElementBase#prevalidate(org.jibx.binding.model.ValidationContext)
   */
  public void prevalidate(ValidationContext vctx) {

    // first process attributes and check for errors
    super.prevalidate(vctx);
    if (!vctx.isSkipped(this)) {

      // check for ignored attributes
      if (isAllowRepeats()) {
        vctx.addWarning("'allow-repeats' attribute ignored on collection");
      }
      if (isChoice()) {
        vctx.addWarning("'choice' attribute ignored on collection");
      }

      // get the actual collection type and item type
      IClass clas = getType();
      if (clas == null) {
        clas = vctx.getContextObject().getObjectType();
      }
      String tname = m_itemTypeName;
      if (tname == null) {
        String ctype = clas.getName();
        if (ctype.endsWith("[]")) {
          tname = ctype.substring(0, ctype.length() - 2);
        } else {
          tname = "java.lang.Object";
        }
      }
      m_itemTypeClass = vctx.getClassInfo(tname);
      if (m_itemTypeClass == null) {
        vctx.addFatal("Can't find class " + tname);
      }

      // handle input and output bindings separately
      if (vctx.isInBinding()) {

        // check store techniques
        String sname = m_storeMethodName;
        String aname = m_addMethodName;
        if (sname != null && aname != null) {
          vctx.addWarning("Both store-method and add-method " + "supplied; using add-method");
          sname = null;
        }

        // set defaults based on collection type if needed
        if (sname == null && aname == null) {
          if (clas.isSuperclass("java.util.ArrayList")
              || clas.isSuperclass("java.util.Vector")
              || clas.isImplements("Ljava/util/Collection;")) {
            aname = "add";
          } else if (!clas.getName().endsWith("[]")) {
            vctx.addError("Need store-method or add-method for " + "input binding");
          }
        }

        // find the actual method information
        if (sname != null) {
          m_storeMethodItem = clas.getBestMethod(sname, null, new String[] {"int", tname});
          if (m_storeMethodItem == null) {
            vctx.addError("store-method " + sname + " not found in class " + clas.getName());
          }
        }
        if (aname != null) {
          m_addMethodItem = clas.getBestMethod(aname, null, new String[] {tname});
          if (m_addMethodItem == null) {
            vctx.addError("add-method " + aname + " not found in class " + clas.getName());
          }
        }
      }
      if (vctx.isOutBinding()) {

        // precheck load techniques
        String lname = m_loadMethodName;
        String sname = m_sizeMethodName;
        String iname = m_iterMethodName;
        if (lname == null) {
          if (sname != null) {
            vctx.addWarning("size-method requires load-method; " + "ignoring supplied size-method");
            sname = null;
          }
        } else {
          if (sname == null) {
            vctx.addWarning("load-method requires " + "size-method; ignoring supplied load-method");
            lname = null;
          } else {
            if (iname != null) {
              vctx.addWarning("Both load-method and " + "iter-method supplied; using load-method");
              iname = null;
            }
          }
        }

        // set defaults based on collection type if needed
        if (lname == null && iname == null) {
          if (clas.isSuperclass("java.util.ArrayList") || clas.isSuperclass("java.util.Vector")) {
            lname = "get";
            sname = "size";
          } else if (clas.isImplements("Ljava/util/Collection;")) {
            iname = "iterator";
          }
        }

        // postcheck load techniques with defaults set
        if (lname == null) {
          if (iname == null && !clas.getName().endsWith("[]")) {
            vctx.addError(
                "Need load-method and size-method, or " + "iter-method, for output binding");
          }
        } else {
          if (sname == null && iname == null) {
            vctx.addError(
                "Need load-method and size-method," + " or iter-method, for output binding");
          }
        }

        // find the actual method information
        if (lname != null) {
          m_loadMethodItem = clas.getBestMethod(lname, tname, new String[] {"int"});
          if (m_loadMethodItem == null) {
            vctx.addError("load-method " + lname + " not found in class " + clas.getName());
          }
        }
        if (iname != null) {
          m_iterMethodItem = clas.getBestMethod(iname, "java.util.Iterator", new String[0]);
          if (m_iterMethodItem == null) {
            vctx.addError("iter-method " + iname + " not found in class " + clas.getName());
          }
        }
      }
    }
  }