Пример #1
0
 protected void processParticle(XSDParticle content, Node node) throws RepositoryException {
   if (content == null) {
     return;
   }
   XSDParticleContent particle = content.getContent();
   Node particleNode = null;
   if (particle instanceof XSDModelGroupDefinition) {
     particleNode = processModelGroupDefinition((XSDModelGroupDefinition) particle, node);
   } else if (particle instanceof XSDElementDeclaration) {
     particleNode = processElementDeclaration((XSDElementDeclaration) particle, node);
   } else if (particle instanceof XSDModelGroup) {
     particleNode = processModelGroup((XSDModelGroup) particle, node);
   } else if (particle instanceof XSDWildcard) {
     particleNode = processWildcard((XSDWildcard) particle, node);
   }
   if (particleNode != null) {
     long minOccurs = content.getMinOccurs();
     long maxOccurs = content.getMaxOccurs();
     particleNode.setProperty(XsdLexicon.MIN_OCCURS, minOccurs);
     if (maxOccurs >= 0) {
       particleNode.setProperty(XsdLexicon.MAX_OCCURS, maxOccurs);
     } else {
       // unbounded ...
     }
   }
 }
Пример #2
0
  /**
   * Given an XSD Complex Type Definition, return the model group containing its child elements.
   *
   * @param cType
   * @return the model group
   */
  public static XSDModelGroup getModelGroup(XSDComplexTypeDefinition cType) {

    XSDParticle particle = cType.getComplexType();

    // In cases where cType doesn't have a model group AND cType has a parent with a modelgroup, the
    // call above will rather unexpectedly give us cType's PARENT's model group, rather than the
    // null we
    // might expect.  We don't want that here, if the model group returned is null or belongs to
    // someone
    // other than us, return null
    if (particle == null || particle.eContainer() != cType) {
      return null;
    }

    // get the model group
    Object particleContent = particle.getContent();
    XSDModelGroup group = null;

    if (particleContent instanceof XSDModelGroupDefinition) {
      group =
          ((XSDModelGroupDefinition) particleContent)
              .getResolvedModelGroupDefinition()
              .getModelGroup();
    } else if (particleContent instanceof XSDModelGroup) {
      group = (XSDModelGroup) particleContent;
    }

    if (group == null) {
      return null;
    }

    // if the content of the complex type is empty then the content
    // must be in the complexContent, ie. we're extending another BO.
    // if the group and the type are not in the same resource then
    // we are extending another BO and we don't want to show inherited
    // attributes.
    if (group.getContents().isEmpty() || group.eResource() != cType.eResource()) {
      // if we are extending another BO then get the elements
      // we are adding
      if (cType.getBaseType() != null) {
        XSDComplexTypeContent content = cType.getContent();

        if (content instanceof XSDParticle) {
          particleContent = ((XSDParticle) content).getContent();
          if (particleContent instanceof XSDModelGroupDefinition) {
            group =
                ((XSDModelGroupDefinition) particleContent)
                    .getResolvedModelGroupDefinition()
                    .getModelGroup();
          } else if (particleContent instanceof XSDModelGroup) {
            group = (XSDModelGroup) particleContent;
          }
        }
      }
    }

    return group;
  }
Пример #3
0
  /**
   * Gets the "maxOccurs" attribute value for the given XSDFeature, if there is none then it returns
   * the default 1.
   *
   * @param xsdElem
   * @return max occurs
   */
  public static int getMaxOccurs(XSDFeature xsdElem) {
    int max = 1;

    // not a particle means an attribute use.  attributes are maxed at 1.
    if (!(xsdElem.eContainer() instanceof XSDParticle)) return max;

    XSDParticle particle = (XSDParticle) xsdElem.eContainer();
    if (particle.isSetMaxOccurs()) max = particle.getMaxOccurs();

    return max;
  }
Пример #4
0
  /**
   * Gets the "minOccurs" attribute value for the given XSDFeature, if there is none then it returns
   * the default 1.
   *
   * @param xsdElem
   * @return min occurs
   */
  public static int getMinOccurs(XSDFeature xsdElem) {
    if (xsdElem.eContainer() instanceof XSDAttributeUse) {
      return (((XSDAttributeUse) xsdElem.eContainer()).getUse()
              == XSDAttributeUseCategory.REQUIRED_LITERAL
          ? 1
          : 0);
    }

    XSDParticle particle = (XSDParticle) xsdElem.eContainer();
    int min = 1;
    if (particle.isSetMinOccurs()) min = particle.getMinOccurs();

    return min;
  }
  protected Object[] getXSDParticleChildren(XSDParticle particle) {

    if (particle.getTerm() instanceof XSDElementDeclaration) {
      return getXSDElementDeclarationChildren((XSDElementDeclaration) particle.getTerm());
    }

    if (particle.getTerm() instanceof XSDModelGroup) {
      return getXSDModelGroupChildren((XSDModelGroup) particle.getTerm());
    }

    if (particle.getTerm() instanceof XSDWildcard) {}

    return new Object[] {};
  }
Пример #6
0
  /**
   * Given a Model group, return a list of the XSDFeatures declared within.
   *
   * @param group
   * @return the child elements.
   */
  public static List<XSDParticleContent> getChildElements(XSDModelGroup group) {
    if (group == null) {
      return new ArrayList<XSDParticleContent>();
    }

    List<XSDParticleContent> children = new ArrayList<XSDParticleContent>();

    for (XSDParticle next : group.getContents()) {
      if (next.getContent() instanceof XSDFeature) {
        children.add(next.getContent());
      } else if (next.getTerm() instanceof XSDModelGroup) {
        children.addAll(getChildElements((XSDModelGroup) next.getTerm()));
      }
    }
    return children;
  }
Пример #7
0
 public static void visit(XSDParticle particle) {
   XSDParticleContent particleContent = particle.getContent();
   if (particleContent instanceof XSDModelGroupDefinition) {
   } else if (particleContent instanceof XSDTerm) {
     visit((XSDTerm) particleContent);
   }
 }
  private void handleContainer(XSDModelGroup xsdModelGroup) {
    for (Iterator i = xsdModelGroup.getParticles().iterator(); i.hasNext(); ) {
      XSDParticle childXSDParticle = (XSDParticle) i.next();
      XSDTerm childXSDTerm = childXSDParticle.getTerm();

      if (childXSDTerm instanceof XSDElementDeclaration) {
        XSDElementDeclaration eldeclaration = (XSDElementDeclaration) childXSDTerm;
        if (!this.tags.containsKey(getFullDeclarationName(eldeclaration))) {
          this.handleLeaf(eldeclaration);
          this.handleElementDeclaration(eldeclaration);
        }
      } else if (childXSDTerm instanceof XSDModelGroup) {
        this.handleContainer((XSDModelGroup) childXSDTerm);
      }
    }
  }
Пример #9
0
  public static void visit(XSDComplexTypeDefinition complexType) {
    List<String> attributeNames = new ArrayList<String>();
    for (XSDAttributeGroupContent attribute : complexType.getAttributeContents()) {
      if (attribute instanceof XSDAttributeUse) {
        XSDAttributeDeclaration attr = ((XSDAttributeUse) attribute).getContent();
        String name = attr.getName();
        if (name != null) {
          if (attributeNames.contains(name)) {
            messages.add(
                MessageFormat.format(
                    Structured_Messages.ComplexTypePropertyPage_DuplicateFieldErrorMessage,
                    new Object[] {name}));
          }
          attributeNames.add(name);
        }
      }
    }

    List<String> names = new ArrayList<String>();
    XSDComplexTypeContent content = complexType.getContent();
    if (content instanceof XSDParticle) {
      visit((XSDParticle) content);
      XSDParticleContent particleContent = ((XSDParticle) content).getContent();
      if (particleContent instanceof XSDModelGroup) {
        for (XSDParticle xsdParticle : ((XSDModelGroup) particleContent).getContents()) {
          XSDParticleContent xsdParticleContent = xsdParticle.getContent();
          if (xsdParticleContent instanceof XSDElementDeclaration) {
            String name = ((XSDElementDeclaration) xsdParticleContent).getName();
            if (name != null) {
              if (names.contains(name)) {
                messages.add(
                    MessageFormat.format(
                        Structured_Messages.ComplexTypePropertyPage_DuplicateFieldErrorMessage,
                        new Object[] {name}));
              }
              names.add(name);
            }
          }
        }
      }
    }
  }
Пример #10
0
  public static void visit(XSDModelGroup group) {
    List<String> names = new ArrayList<String>();
    for (XSDParticle xsdParticle : ((XSDModelGroup) group).getContents()) {
      XSDParticleContent particleContent = xsdParticle.getContent();

      // check for element declarations
      if (particleContent instanceof XSDElementDeclaration) {
        String name = ((XSDElementDeclaration) particleContent).getName();
        if (name != null) {
          if (names.contains(name)) {
            messages.add(
                MessageFormat.format(
                    Structured_Messages.ComplexTypePropertyPage_DuplicateFieldErrorMessage,
                    new Object[] {name}));
          }
          names.add(name);
        }
      }
      visit((XSDParticle) xsdParticle);
    }
  }
 private void handleElementDeclaration(XSDElementDeclaration tagDeclaration) {
   XSDTypeDefinition type = tagDeclaration.getTypeDefinition();
   if (type instanceof XSDComplexTypeDefinition) {
     XSDComplexTypeDefinition xsdComplexTypeDefinition = (XSDComplexTypeDefinition) type;
     int contentType = xsdComplexTypeDefinition.getContentTypeCategory().getValue();
     if (contentType == XSDContentTypeCategory.ELEMENT_ONLY
         || contentType == XSDContentTypeCategory.MIXED) {
       XSDParticle xsdParticle = (XSDParticle) xsdComplexTypeDefinition.getContentType();
       if (xsdParticle != null) {
         XSDTerm xsdTerm = xsdParticle.getTerm();
         if (xsdTerm instanceof XSDModelGroup) {
           XSDModelGroup xsdModelGroup = (XSDModelGroup) xsdTerm;
           this.handleContainer(xsdModelGroup);
         } else if (xsdTerm instanceof XSDElementDeclaration) {
           XSDElementDeclaration eldeclaration = (XSDElementDeclaration) xsdTerm;
           this.handleLeaf(eldeclaration);
         }
       }
     }
   }
 }
 protected String createGroupInstance() {
   String groupID = genID();
   EList particles = getXSDModelGroup().getParticles();
   String[] groupMemberIDs = new String[particles.size()];
   for (int i = 0; i < particles.size(); i++) {
     XSDParticle xsdParticle = (XSDParticle) particles.get(i);
     XSDParticleContent xsdParticleContent = xsdParticle.getContent();
     XSDToFragmentConfiguration thisConfig = getXSDToFragmentConfiguration();
     XSDToFragmentConfiguration xsdConfig = new XSDToFragmentConfiguration();
     if (xsdParticleContent instanceof XSDComponent)
       xsdConfig.setXSDComponent((XSDComponent) xsdParticleContent);
     else xsdConfig.setXSDComponent(null);
     xsdConfig.setStyle(thisConfig.getStyle());
     xsdConfig.setPartEncoding(thisConfig.getPartEncoding());
     xsdConfig.setWSDLPartName(thisConfig.getWSDLPartName());
     groupMemberIDs[i] = genID();
     addFragment(
         groupMemberIDs[i],
         getXSDToFragmentController()
             .getFragment(xsdConfig, groupMemberIDs[i], groupMemberIDs[i]));
   }
   setGroupMemberIDs(groupID, groupMemberIDs);
   return groupID;
 }
Пример #13
0
  private void setSubstitutionGroup(
      XSDComplexTypeDefinition container,
      XSDElementDeclaration elemDecl,
      PropertyDescriptor descriptor,
      CoordinateReferenceSystem crs) {

    if (descriptor.getUserData().get("substitutionGroup") != null) {
      // this has been done before
      return;
    }

    List<AttributeDescriptor> substitutionGroup = new ArrayList<AttributeDescriptor>();
    descriptor.getUserData().put("substitutionGroup", substitutionGroup);

    int minOccurs = Schemas.getMinOccurs(container, elemDecl);
    int maxOccurs = Schemas.getMaxOccurs(container, elemDecl);
    boolean nillable = elemDecl.isNillable();

    Iterator substitutions = elemDecl.getSubstitutionGroup().iterator();
    XSDElementDeclaration sub;
    while (substitutions.hasNext()) {
      sub = (XSDElementDeclaration) substitutions.next();
      if (!(sub.getName().equals(elemDecl.getName()))
          || !(sub.getTargetNamespace().equals(elemDecl.getTargetNamespace()))) {
        Name elemName = Types.typeName(sub.getTargetNamespace(), sub.getName());
        AttributeType type = getTypeOf(sub, crs);
        if (type != null) {
          substitutionGroup.add(
              createAttributeDescriptor(type, crs, elemName, minOccurs, maxOccurs, nillable, null));
        }
      }
    }

    XSDTypeDefinition typeDef = elemDecl.getType();

    if (typeDef instanceof XSDComplexTypeDefinition) {
      Name typeName = Types.typeName(typeDef.getTargetNamespace(), typeDef.getName());
      AttributeType attType = typeRegistry.get(typeName);

      if (!processingTypes.contains(typeName)) {
        // ignore processingTypes to avoid endless recursion
        if (attType == null || attType instanceof AbstractLazyComplexTypeImpl) {
          // type is not yet registered or it's a lazy type from foundation types
          // recreate lazy type to ensure everything is loaded
          // it will eventually call this method so substitution groups will be set then
          LOGGER.finest("Creating attribute type " + typeName);
          createType(typeName, typeDef, crs, false);
          LOGGER.finest("Registering attribute type " + typeName);
        } else if (attType instanceof ComplexType) {
          // ensure substitution groups are set for children including non lazy foundation
          // types
          ComplexType complexType = (ComplexType) attType;
          Collection<PropertyDescriptor> children = complexType.getDescriptors();

          List<XSDParticle> childParticles = Schemas.getChildElementParticles(typeDef, true);

          for (XSDParticle particle : childParticles) {
            XSDElementDeclaration element = (XSDElementDeclaration) particle.getContent();

            if (element.isElementDeclarationReference()) {
              element = element.getResolvedElementDeclaration();
            }
            PropertyDescriptor childDesc = null;
            for (PropertyDescriptor desc : children) {
              if (desc.getName().getLocalPart().equals(element.getName())
                  && desc.getName().getNamespaceURI().equals(element.getTargetNamespace())) {
                childDesc = desc;
                break;
              }
            }
            if (childDesc != null) {
              setSubstitutionGroup((XSDComplexTypeDefinition) typeDef, element, childDesc, crs);
            }
          }
        }
      }
    }
  }
Пример #14
0
  public void encode(Object object, QName name, ContentHandler handler)
      throws IOException, SAXException {

    // maintain a stack of (encoding,element declaration pairs)
    Stack encoded = null;

    try {
      serializer = handler;

      if (!inline) {
        serializer.startDocument();
      }

      if (namespaceAware) {
        // write out all the namespace prefix value mappings
        for (Enumeration e = namespaces.getPrefixes(); e.hasMoreElements(); ) {
          String prefix = (String) e.nextElement();
          String uri = namespaces.getURI(prefix);

          if ("xml".equals(prefix)) {
            continue;
          }
          serializer.startPrefixMapping(prefix, uri);
        }
        for (Iterator itr = schema.getQNamePrefixToNamespaceMap().entrySet().iterator();
            itr.hasNext(); ) {
          Map.Entry entry = (Map.Entry) itr.next();
          String pre = (String) entry.getKey();
          String ns = (String) entry.getValue();

          if (XSDUtil.SCHEMA_FOR_SCHEMA_URI_2001.equals(ns)) {
            continue;
          }

          serializer.startPrefixMapping(pre, ns);
          serializer.endPrefixMapping(pre);

          namespaces.declarePrefix((pre != null) ? pre : "", ns);
        }

        // ensure a default namespace prefix set
        if (namespaces.getURI("") == null) {
          namespaces.declarePrefix("", schema.getTargetNamespace());
        }
      }

      // create the document
      DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();

      try {
        doc = docFactory.newDocumentBuilder().newDocument();
      } catch (ParserConfigurationException e) {
        new IOException().initCause(e);
      }

      encoded = new Stack();

      // add the first entry
      XSDElementDeclaration root = index.getElementDeclaration(name);

      if (root == null) {
        // check for context hint, this is only used when running the encoder
        // in test mode
        QName typeDefintion =
            (QName) context.getComponentInstance("http://geotools.org/typeDefinition");

        if (typeDefintion != null) {
          XSDTypeDefinition type = index.getTypeDefinition(typeDefintion);

          if (type == null) {
            throw new NullPointerException();
          }

          // create a mock element declaration
          root = XSDFactory.eINSTANCE.createXSDElementDeclaration();
          root.setName(name.getLocalPart());
          root.setTargetNamespace(name.getNamespaceURI());
          root.setTypeDefinition(type);
        }
      }

      if (root == null) {
        String msg = "Could not find element declaration for:" + name;
        throw new IllegalArgumentException(msg);
      }

      encoded.add(new EncodingEntry(object, root, null));

      while (!encoded.isEmpty()) {
        EncodingEntry entry = (EncodingEntry) encoded.peek();

        if (entry.encoding != null) {
          // element has been started, get the next child
          if (!entry.children.isEmpty()) {
            Object[] child = (Object[]) entry.children.get(0);
            XSDElementDeclaration element = (XSDElementDeclaration) child[0];
            Iterator itr = (Iterator) child[1];

            if (itr.hasNext()) {
              Object next = itr.next();
              if (next == null) {
                logger.warning("Iterator returned null for " + element.getName());
              }

              // here we check for instanceof EncoderDelegate
              if (next instanceof EncoderDelegate) {
                // do not add entry to the stack, just delegate to encode
                try {
                  ((EncoderDelegate) next).encode(handler);
                } catch (Exception e) {
                  throw new RuntimeException(e);
                }
              } else {
                // add the next object to be encoded to the stack
                encoded.push(new EncodingEntry(next, element, entry));
              }
            } else {
              // iterator done, close it
              Object source = child[2];
              closeIterator(itr, source);

              // this child is done, remove from child list
              entry.children.remove(0);
            }
          } else {
            // no more children, finish the element
            end(entry.encoding);
            encoded.pop();

            // clean up the entry
            entry.object = null;
            entry.element = null;
            entry.encoding = null;
            entry.children = null;
            entry.parent = null;
          }
        } else {
          // start the encoding of the entry

          // first make sure the element is not abstract
          if (entry.element.isAbstract()) {
            // look for a non abstract substitute - substitution groups are subject to
            // changes over time, so we make a copy to avoid being hit with a
            // ConcurrentModificationException
            List sub = safeCopy(entry.element.getSubstitutionGroup());

            if (sub.size() > 0) {
              // match up by type
              List matches = new ArrayList();

              for (Iterator s = sub.iterator(); s.hasNext(); ) {
                XSDElementDeclaration e = (XSDElementDeclaration) s.next();

                if (e == null || e.equals(entry.element)) {
                  continue;
                }

                if (e.getName() == null) {
                  continue;
                }

                // look up hte binding
                Binding binding =
                    bindingLoader.loadBinding(
                        new QName(e.getTargetNamespace(), e.getName()), context);

                if (binding == null) {
                  // try the type
                  XSDTypeDefinition type = e.getType();

                  if (type == null || type.getName() == null) {
                    continue;
                  }

                  binding =
                      bindingLoader.loadBinding(
                          new QName(type.getTargetNamespace(), type.getName()), context);
                }

                if (binding == null) {
                  continue;
                }

                if (binding.getType() == null) {
                  logger.warning("Binding: " + binding.getTarget() + " returns null type.");
                  continue;
                }

                // match up the type
                if (binding.getType().isAssignableFrom(entry.object.getClass())) {
                  // we have a match, store as an (element,binding) tuple
                  matches.add(new Object[] {e, binding});
                }
              }

              // if one, we are gold
              if (matches.size() == 1) {
                entry.element = (XSDElementDeclaration) ((Object[]) matches.get(0))[0];
              }
              // if multiple we have a problem
              else if (matches.size() > 0) {
                if (logger.isLoggable(Level.FINE)) {
                  StringBuffer msg = new StringBuffer("Found multiple non-abstract bindings for ");
                  msg.append(entry.element.getName()).append(": ");

                  for (Iterator m = matches.iterator(); m.hasNext(); ) {
                    msg.append(m.next().getClass().getName());
                    msg.append(", ");
                  }

                  logger.fine(msg.toString());
                }

                // try sorting by the type of the binding
                Collections.sort(
                    matches,
                    new Comparator() {
                      public int compare(Object o1, Object o2) {
                        Object[] match1 = (Object[]) o1;
                        Object[] match2 = (Object[]) o2;

                        Binding b1 = (Binding) match1[1];
                        Binding b2 = (Binding) match2[1];

                        if (b1.getType() != b2.getType()) {
                          if (b2.getType().isAssignableFrom(b1.getType())) {
                            return -1;
                          }

                          if (b1.getType().isAssignableFrom(b2.getType())) {
                            return 1;
                          }
                        }

                        // use binding comparability
                        if (b1 instanceof Comparable) {
                          return ((Comparable) b1).compareTo(b2);
                        }

                        if (b2 instanceof Comparable) {
                          return -1 * ((Comparable) b2).compareTo(b1);
                        }

                        return 0;
                      }
                    });
              }

              if (matches.size() > 0) {
                entry.element = (XSDElementDeclaration) ((Object[]) matches.get(0))[0];
              }

              // if zero, just use the abstract element
            }
          }

          if (entry.element.isAbstract()) {
            logger.fine(entry.element.getName() + " is abstract");
          }

          entry.encoding =
              entry.parent != null
                  ? (Element) encode(entry.object, entry.element, entry.parent.element.getType())
                  : (Element) encode(entry.object, entry.element);

          // add any more attributes
          List attributes = index.getAttributes(entry.element);

          for (Iterator itr = attributes.iterator(); itr.hasNext(); ) {
            XSDAttributeDeclaration attribute = (XSDAttributeDeclaration) itr.next();

            // do not encode the attribute if it has already been
            // encoded by the parent
            String ns = attribute.getTargetNamespace();
            String local = attribute.getName();

            if ((entry.encoding.getAttributeNS(ns, local) != null)
                && !"".equals(entry.encoding.getAttributeNS(ns, local))) {
              continue;
            }

            // get the object(s) for this attribute
            GetPropertyExecutor executor = new GetPropertyExecutor(entry.object, attribute);

            BindingVisitorDispatch.walk(object, bindingWalker, entry.element, executor, context);

            if (executor.getChildObject() != null) {
              // encode the attribute
              Attr attr = (Attr) encode(executor.getChildObject(), attribute);

              if (attr != null) {
                entry.encoding.setAttributeNodeNS(attr);
              }
            }
          }

          // write out the leading edge of the element
          if (schemaLocations != null) {
            // root element, add schema locations if set
            if (!schemaLocations.isEmpty()) {
              // declare the schema instance mapping
              serializer.startPrefixMapping("xsi", XSDUtil.SCHEMA_INSTANCE_URI_2001);
              serializer.endPrefixMapping("xsi");
              namespaces.declarePrefix("xsi", XSDUtil.SCHEMA_INSTANCE_URI_2001);

              StringBuffer schemaLocation = new StringBuffer();

              for (Iterator e = schemaLocations.entrySet().iterator(); e.hasNext(); ) {
                Map.Entry tuple = (Map.Entry) e.next();
                String namespaceURI = (String) tuple.getKey();
                String location = (String) tuple.getValue();

                schemaLocation.append(namespaceURI + " " + location);

                if (e.hasNext()) {
                  schemaLocation.append(" ");
                }
              }

              entry.encoding.setAttributeNS(
                  XSDUtil.SCHEMA_INSTANCE_URI_2001,
                  "xsi:schemaLocation",
                  schemaLocation.toString());
            }

            schemaLocations = null;
          }

          start(entry.encoding, entry.element);

          // TODO: this method of getting at properties wont maintain order very well, need
          // to come up with a better system that is capable of hanlding feature types
          for (Iterator pe = propertyExtractors.iterator(); pe.hasNext(); ) {
            PropertyExtractor propertyExtractor = (PropertyExtractor) pe.next();

            if (propertyExtractor.canHandle(entry.object)) {
              List extracted = propertyExtractor.properties(entry.object, entry.element);
              O:
              for (Iterator e = extracted.iterator(); e.hasNext(); ) {
                Object[] tuple = (Object[]) e.next();
                XSDParticle particle = (XSDParticle) tuple[0];
                XSDElementDeclaration child = (XSDElementDeclaration) particle.getContent();

                // check for a comment
                if ((child != null)
                    && (COMMENT.getNamespaceURI().equals(child.getTargetNamespace()))
                    && COMMENT.getLocalPart().equals(child.getName())) {
                  comment(child.getElement());

                  continue;
                }

                if (child.isElementDeclarationReference()) {
                  child = child.getResolvedElementDeclaration();
                }

                // do not encode the element if the parent has already
                // been encoded by the parent
                String ns = child.getTargetNamespace();
                String local = child.getName();

                for (int i = 0; i < entry.encoding.getChildNodes().getLength(); i++) {
                  Node node = entry.encoding.getChildNodes().item(i);

                  if (node instanceof Element) {
                    if (ns != null) {
                      if (ns.equals(node.getNamespaceURI()) && local.equals(node.getLocalName())) {
                        continue O;
                      }
                    } else {
                      if (local.equals(node.getLocalName())) {
                        continue O;
                      }
                    }
                  }
                }

                Object obj = tuple[1];

                if (obj == null) {
                  if (particle.getMinOccurs() == 0) {
                    // cool
                  } else {
                    // log an error
                    logger.fine("Property " + ns + ":" + local + " not found but minoccurs > 0 ");
                  }

                  // skip this regardless
                  continue;
                }

                // figure out the maximum number of occurences
                int maxOccurs = 1;

                if (particle.isSetMaxOccurs()) {
                  maxOccurs = particle.getMaxOccurs();
                } else {
                  // look the containing group
                  if (particle.eContainer() instanceof XSDModelGroup) {
                    XSDModelGroup group = (XSDModelGroup) particle.eContainer();

                    if (group.eContainer() instanceof XSDParticle) {
                      XSDParticle cParticle = (XSDParticle) group.eContainer();

                      if (cParticle.isSetMaxOccurs()) {
                        maxOccurs = cParticle.getMaxOccurs();
                      }
                    }
                  }
                }

                if ((maxOccurs == -1) || (maxOccurs > 1)) {
                  // may have a collection or array, unwrap it
                  Iterator iterator = null;

                  if (obj instanceof Iterator) {
                    iterator = (Iterator) obj;
                  } else if (obj.getClass().isArray()) {
                    Object[] array = (Object[]) obj;
                    iterator = Arrays.asList(array).iterator();
                  } else if (obj instanceof Collection) {
                    Collection collection = (Collection) obj;
                    iterator = collection.iterator();
                  } else if (obj instanceof FeatureCollection) {
                    FeatureCollection collection = (FeatureCollection) obj;
                    iterator = collection.iterator();
                  } else {
                    iterator = new SingleIterator(obj);
                  }

                  entry.children.add(new Object[] {child, iterator, obj});
                } else {
                  // only one, just add the object
                  entry.children.add(new Object[] {child, new SingleIterator(obj), obj});
                }
              }
            }
          }
        }
      }

      if (!inline) {
        serializer.endDocument();
      }

    } finally {
      // cleanup
      index.destroy();

      // close any iterators still present in the stack, this will only occur in an exception
      // case
      if (encoded != null) {
        while (!encoded.isEmpty()) {
          EncodingEntry entry = (EncodingEntry) encoded.pop();
          if (!entry.children.isEmpty()) {
            Object[] child = (Object[]) entry.children.get(0);
            Iterator itr = (Iterator) child[1];
            try {
              closeIterator(itr, child[2]);
            } catch (Exception e) {
              // ignore, we are already in an error case.
            }
          }
        }
      }
      // TODO: there are probably other refences to elements of XSDScheam objects, we should
      // kill them too
    }
  }
  protected void updatePreviewText(IStructuredSelection selection) {
    if (previewText == null) return;

    VariableTreeContentProvider contentProvider =
        (VariableTreeContentProvider) super.getTreeViewer().getContentProvider();
    Object[] path = contentProvider.getPathToRoot(selection.getFirstElement());
    String preview = "$"; // $NON-NLS-1$
    if (path != null) {
      Variable var = null;
      for (int i = path.length - 1; i >= 0; i--) {
        String targetNamespace = null;
        String namespacePrefix = null;
        String segment = null;
        Object modelObject = BPELUtil.resolveXSDObject(((ITreeNode) path[i]).getModelObject());
        ;
        if (modelObject instanceof Variable) {
          var = (Variable) modelObject;
          segment = var.getName();
        } else if (modelObject instanceof XSDAttributeDeclaration) {

          XSDAttributeDeclaration att = (XSDAttributeDeclaration) modelObject;

          targetNamespace = att.getTargetNamespace();
          if (targetNamespace != null) {
            namespacePrefix = BPELUtils.getNamespacePrefix(var, targetNamespace);
            Assert.isNotNull(namespacePrefix, XPathExpressionUtil.MSG_NS_PREFIX_NULL);
            segment = "/@" + namespacePrefix + ":" + att.getName(); // $NON-NLS-1$ //$NON-NLS-2$
          } else {
            segment = "/@" + att.getName(); // $NON-NLS-1$
          }

        } else if (modelObject instanceof XSDElementDeclaration) {

          XSDElementDeclaration elm = (XSDElementDeclaration) modelObject;
          targetNamespace = elm.getTargetNamespace();

          XSDTypeDefinition typeDef = elm.getType();
          XSDParticle particle = typeDef.getComplexType();

          boolean isArray =
              particle != null
                  && (particle.getMaxOccurs() == XSDParticle.UNBOUNDED
                      || particle.getMaxOccurs() > 1);

          if (targetNamespace != null) {
            namespacePrefix = BPELUtils.getNamespacePrefix(var, targetNamespace);
            Assert.isNotNull(namespacePrefix, XPathExpressionUtil.MSG_NS_PREFIX_NULL);
            segment = "/" + namespacePrefix + ":" + elm.getName(); // $NON-NLS-1$ //$NON-NLS-2$
          } else {
            segment = "/" + elm.getName(); // $NON-NLS-1$
          }

          if (isArray) {
            segment += "[1]"; // $NON-NLS-1$
          }

        } else if (modelObject instanceof Part) {
          Part part = (Part) modelObject;
          segment = "." + part.getName(); // $NON-NLS-1$
        }

        if (segment != null) preview += segment;
      }

      // store away value
      previewText.setText(preview);
      thePreviewText = preview;
    }
  }