Пример #1
0
  @NbBundle.Messages({
    "ERR_instructionBadPlacement=Bad placement for processing instruction. Must be before all elements."
  })
  @Override
  public void processingInstruction(String target, String data) throws SAXException {
    start = contentLocator.getElementOffset();
    end = contentLocator.getEndOffset();

    addElementErrors();

    FxNode node = null;
    boolean broken = false;
    if (!isTopLevel() || rootComponent != null) {
      addError("instruction-bad-placement", ERR_instructionBadPlacement());
      broken = true;
    }

    if (FX_IMPORT.equals(target)) {
      node = handleFxImport(data);
    } else if (FX_LANGUAGE.equals(target)) {
      node = handleFxLanguage(data);
    } else if (!"xml".equals(target)) {
      handleErrorInstruction(target, data);
    }
    if (node == null) {
      return;
    }
    i(node).makePI().startAt(start).endsAt(end);
    if (broken) {
      accessor.makeBroken(node);
    }
    attachChildNode(node);
  }
Пример #2
0
  @NbBundle.Messages({
    "# {0} - NS prefix",
    "ERR_undeclaredElementPrefix=XML namespace prefix ''{0}'' is undeclared"
  })
  @Override
  public void startElement(String uri, String localName, String qName, Attributes atts)
      throws SAXException {
    this.tagName = localName;

    FxNode newElement;

    start = contentLocator.getElementOffset();
    end = contentLocator.getEndOffset();

    addElementErrors();

    if (uri == null && !qName.equals(localName)) {
      // undeclared prefix
      int prefColon = qName.indexOf(':');
      String prefix = qName.substring(0, prefColon);
      addError("undeclared-prefix", ERR_undeclaredElementPrefix(prefix));
      newElement = accessor.createErrorElement(localName);
    } else if ("".equals(localName)) {
      newElement = accessor.createErrorElement(localName);
    } else if (FXML_FX_NAMESPACE.equals(uri)) {
      newElement = handleFxmlElement(localName, atts);
    } else {
      // non-fx namespace, should be either an instance, or a property or an event
      String eventName = FxXmlSymbols.getEventHandlerName(localName);
      if (rootComponent == null || FxXmlSymbols.isClassTagName(localName)) {
        newElement = handleClassTag(localName, atts);
      } else if (eventName != null) {
        newElement = handleEventHandlerTag(eventName);
      } else {
        newElement = handlePropertyTag(localName, atts);
      }
    }
    if (newElement == null) {
      throw new IllegalStateException();
    }
    initElement(newElement);

    FxNode newNode = newElement;

    // if not broken attempt to attach the Element to a parent
    if (!newElement.isBroken()) {
      if (newElement instanceof FxObjectBase) {
        newNode = attachInstance((FxObjectBase) newElement);
      } else if (newElement instanceof PropertyValue) {
        newNode = attachProperty((PropertyValue) newElement);
      }
    }
    attachChildNode(newNode);

    // process attributes, iff it is an instance. Attribute processing needs the node pushed
    // on the stack, so it is delayed after attachChildNode
    if (newNode.getKind() == Kind.Instance) {
      processInstanceAttributes(atts);
    }
  }
Пример #3
0
 private ErrorMark addError(String errCode, String message, Object... params) {
   int offs = contentLocator.getElementOffset();
   ErrorMark m =
       new ErrorMark(offs, contentLocator.getEndOffset() - offs, errCode, message, params);
   addError(m);
   return m;
 }
Пример #4
0
  @Override
  public void characterSequence(CharSequence seq) {

    addElementErrors();

    int length = seq.length();
    FxNode node = nodeStack.peek();
    FxNode addedNode = null;

    switch (node.getKind()) {
      case Event:
        addedNode = handleEventContent(seq);
        break;
      case Instance:
        addedNode = handleInstanceContent(seq);
        break;
      case Property:
        addedNode = handlePropertyContent(seq);
        break;

      default:
        addError(
            new ErrorMark(
                contentLocator.getElementOffset(),
                length,
                "unexpected-characters",
                ERR_unexpectedCharacters()));
    }
    if (addedNode != null) {
      i(addedNode).endsAt(contentLocator.getEndOffset());
    }
  }
Пример #5
0
  @NbBundle.Messages({
    "# {0} - PI target",
    "ERR_invalidProcessingInstruction=Invalid processing instruction: {0}. Expected 'import', 'include' or 'language'",
    "ERR_missingProcessingInstruction=Missing processing intruction."
  })
  private void handleErrorInstruction(String target, String data) {
    int start = contentLocator.getElementOffset();
    int offset = -1;
    int piOffset = -1;

    TokenSequence<XMLTokenId> seq = contentLocator.getTokenSequence();

    // lex up to the invalid target:
    seq.move(start);
    boolean found = false;
    while (!found && seq.moveNext()) {
      Token<XMLTokenId> t = seq.token();
      switch (t.id()) {
        case PI_START:
          piOffset = offset;
          if (target == null) {
            found = true;
          }
        case WS:
          break;

        default:
        case PI_TARGET:
          offset = seq.offset();
          found = true;
          break;
      }
    }
    ErrorMark mark;

    if (target != null) {
      mark =
          new ErrorMark(
              offset,
              seq.token().length(),
              "invalid-processing-instruction",
              ERR_invalidProcessingInstruction(target),
              target);
    } else {
      mark =
          new ErrorMark(
              piOffset,
              seq.token().length(),
              "missing-processing-instruction",
              ERR_missingProcessingInstruction());
    }
    addError(mark);
  }
Пример #6
0
 @Override
 public void endDocument() throws SAXException {
   addElementErrors();
   accessor.initModel(fxModel, controllerName, rootComponent, language);
   int end = contentLocator.getElementOffset();
   i(fxModel).endContent(end).endsAt(end, true);
   // attempt to fix up unclosed elements
   // fixNodes(i(fxModel), end);
 }
Пример #7
0
 private void initAttribute(FxNode node, String atQName) {
   NodeInfo ni = i(node);
   ni.makeAttribute();
   int[] offsets = contentLocator.getAttributeOffsets(atQName);
   ni.startAt(offsets[ContentLocator.OFFSET_START])
       .endsAt(offsets[ContentLocator.OFFSET_END])
       .startContent(offsets[ContentLocator.OFFSET_VALUE_START])
       .endContent(offsets[ContentLocator.OFFSET_VALUE_END]);
 }
Пример #8
0
 @Override
 public void endElement(String uri, String localName, String qName) throws SAXException {
   addElementErrors();
   FxNode node = nodeStack.pop();
   i(node).endsAt(contentLocator.getEndOffset()).endContent(contentLocator.getElementOffset());
   if (node instanceof PropertySetter) {
     PropertySetter s = (PropertySetter) node;
     if (s.isImplicit()) {
       // actually the outer element ends
       node = nodeStack.pop();
       // copy the offset information
       i(node).endsAt(contentLocator.getEndOffset()).endContent(contentLocator.getElementOffset());
     }
   }
   String tn = node.getSourceName();
   if (!tn.equals(localName)) {
     throw new IllegalStateException();
   }
   // special hack for parent nodes, which are implicit property setters:
   FxNode parentNode = nodeStack.peek();
   if (parentNode instanceof PropertySetter) {
     PropertySetter ps = (PropertySetter) parentNode;
     if (ps.isImplicit() && ps.getContent() == null) {
       i(ps).endsAt(contentLocator.getEndOffset()).endContent(contentLocator.getEndOffset());
     }
   }
   if (!nodeStack.isEmpty() && nodeStack.peek().getKind() == Kind.Instance) {
     current = (FxInstance) nodeStack.peek();
   } else {
     current = null;
   }
 }
Пример #9
0
  private void addAttributeError(String qName, String code, String message, Object... params) {
    int[] offsets = contentLocator.getAttributeOffsets(qName);
    int s;

    if (offsets == null) {
      FxNode n = nodeStack.peek();
      if (n != null) {
        s = i(n).getStart();
      } else {
        s = -1;
      }
    } else {
      s = offsets[ContentLocator.OFFSET_START];
    }
    addError(new ErrorMark(s, qName.length(), code, message, params));
  }
Пример #10
0
  private FxNode handleInstanceContent(CharSequence seq) {
    // find among properties as setter, which is marked as implicit. If there's none, create one.
    PropertySetter defaultSetter = null;

    for (PropertyValue p : current.getProperties()) {
      if (p instanceof PropertySetter) {
        PropertySetter ps = (PropertySetter) p;
        if (ps.isImplicit()) {
          defaultSetter = ps;
        }
      }
    }

    if (defaultSetter == null) {
      defaultSetter = accessor.createProperty(null, true);
      i(defaultSetter).startAt(contentLocator.getElementOffset());
      attachProperty(defaultSetter);
      attachChildNode(defaultSetter);
    }
    accessor.addContent(defaultSetter, seq);
    return defaultSetter;
  }
Пример #11
0
  /**
   * Checks that the instance is allowed in this context. May even create e.g. default property
   * setter etc. Will return true, if the instance can be attached to the parent.
   */
  @NbBundle.Messages({
    "# {0} - tag name",
    "ERR_moreRootElements=Duplicate root element: {0}",
    "ERR_instanceInMapProperty=Cannot add instances directly to readonly Map",
    "# {0} - parent tag name",
    "ERR_parentNotSupportInstance=Instances cannot be added to the parent {0}"
  })
  private FxNode attachInstance(FxObjectBase instance) {
    String localName = instance.getSourceName();
    int off = contentLocator.getElementOffset() + 1;

    // check the parent, whether it is appropriate to host such a node:
    FxNode parent = nodeStack.peek();

    if (parent.getKind() == Kind.Instance) {
      // pretend we have a default property
      PropertySetter s = accessor.createProperty(null, true);
      i(s).startAt(contentLocator.getElementOffset());
      attachChildNode(s);
      parent = s;
    }

    if (parent.getKind() == Kind.Source) {
      FxObjectBase old = rootComponent;
      if (old != null) {
        addError(
            new ErrorMark(
                off,
                contentLocator.getEndOffset() - off,
                "duplicate-root",
                ERR_moreRootElements(localName),
                localName));
        accessor.makeBroken(instance);
      } else if (!(instance instanceof FxInstance)) {
        // FIXME - report error that fx:reference is not accepted on root element
        throw new UnsupportedOperationException();
      } else {
        rootComponent = (FxInstance) instance;
      }
    } else if (parent.getKind() == Kind.Property) {
      if (parent instanceof MapProperty) {
        addError(
            new ErrorMark(
                off,
                contentLocator.getEndOffset() - off,
                "instance-in-map-property",
                ERR_instanceInMapProperty(),
                localName));
        accessor.makeBroken(instance);
      }
    } else if (parent.getKind() == Kind.Element
        && parent.getSourceName().equals(FxXmlSymbols.FX_DEFINITIONS)
        && (instance instanceof FxNewInstance)) {
      instanceDefinitions.add((FxNewInstance) instance);
    } else {
      if (parent.getKind() != Kind.Error) {
        addError(
            new ErrorMark(
                off,
                contentLocator.getEndOffset() - off,
                "parent-not-support-instance",
                ERR_parentNotSupportInstance(parent.getSourceName())));
        accessor.makeBroken(instance);
      }
    }
    return instance;
  }
Пример #12
0
  @NbBundle.Messages({
    "# {0} - tag name",
    "ERR_tagNotJavaIdentifier=Invalid class name: {0}",
    "# {0} - tag name",
    "ERR_fxControllerPermittedOnRoot=fx:controller is not permitted on tag {0}. Can be only present on root element."
  })
  private FxNewInstance handleClassTag(String localName, Attributes atts) {
    String fxValueContent = null;
    String fxFactoryContent = null;
    String fxId = null;

    int off = contentLocator.getElementOffset() + 1; // the <

    for (int i = 0; i < atts.getLength(); i++) {
      String uri = atts.getURI(i);
      if (!FXML_FX_NAMESPACE.equals(uri)) {
        // no special attribute
        continue;
      }
      String name = atts.getLocalName(i);
      if (FX_VALUE.equals(name)) {
        fxValueContent = atts.getValue(i);
      } else if (FX_FACTORY.equals(name)) {
        fxFactoryContent = atts.getValue(i);
      } else if (FX_ID.equals(name)) {
        fxId = atts.getValue(i);
      } else if (FX_CONTROLLER.equals(name)) {
        if (nodeStack.peek().getKind() != Kind.Source) {
          addAttributeError(
              atts.getQName(i),
              "fx-controller-permitted-on-root",
              ERR_fxControllerPermittedOnRoot(localName),
              localName);
        } else {
          controllerName = atts.getValue(i);
        }
      } else {
        addAttributeError(
            atts.getQName(i),
            "invalid-property-reserved-name",
            ERR_invalidReservedPropertyName(name),
            name);
      }
    }

    // first we must check how this class tag is created.
    FxNewInstance instance =
        accessor.createInstance(localName, fxValueContent, fxFactoryContent, fxId);

    if (!FxXmlSymbols.isQualifiedIdentifier(localName)) {
      // not a java identifier, error
      addError(
          new ErrorMark(
              off,
              localName.length(),
              "invalid-class-name",
              ERR_tagNotJavaIdentifier(localName),
              localName));
      accessor.makeBroken(instance);
      return instance;
    }

    return instance;
  }
Пример #13
0
 private void initElement(FxNode node) {
   NodeInfo ni = i(node);
   ni.startAt(contentLocator.getElementOffset()).startContent(contentLocator.getEndOffset());
   ni.setTagName(tagName);
 }
Пример #14
0
 void addElementErrors() {
   this.errors.addAll(contentLocator.getErrors());
 }