Пример #1
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);
    }
  }
Пример #2
0
  @NbBundle.Messages({
    "# {0} - attribute local name",
    "ERR_unexpectedReferenceAttribute=Unexpected attribute in fx:reference or fx:copy: {0}",
    "ERR_missingReferenceSource=Missing 'source' attribute in fx:reference or fx:copy"
  })
  private FxNode handleFxReference(Attributes atts, boolean copy) {
    String refId = null;
    String id = null;

    for (int i = 0; i < atts.getLength(); i++) {
      String ns = atts.getURI(i);
      String name = atts.getLocalName(i);
      if (!FXML_FX_NAMESPACE.equals(ns)) {
        if (FX_ATTR_REFERENCE_SOURCE.equals(name) && refId == null) {
          refId = atts.getValue(i);
        } else if (!copy) {
          // error, references do not support normal attributes
          addAttributeError(
              atts.getQName(i),
              "invalid-reference-attribute",
              ERR_unexpectedReferenceAttribute(name),
              name);
        }
      } else {
        if (FX_ID.equals(name) && id == null) {
          id = atts.getValue(i);
        } else {
          // error, unexpected attribute
          addAttributeError(
              atts.getQName(i),
              "invalid-reference-attribute",
              ERR_unexpectedReferenceAttribute(name),
              name);
        }
      }
    }

    FxObjectBase ref = accessor.createCopyReference(copy, refId);
    if (refId == null || "".equals(refId)) {
      // error, no source attribute found
      addError("missing-reference-source", ERR_missingReferenceSource());
      accessor.makeBroken(ref);
    }
    return ref;
  }
Пример #3
0
  @NbBundle.Messages({
    "# {0} - attribute name",
    "ERR_lowercasePropertyName=Invalid property name: {0}. Property name, or the last component of a static property name must start with lowercase.",
    "# {0} - attribute name",
    "ERR_invalidReservedPropertyName=Unknown name in FXML reserved namespace: {0}",
    "# {0} - attribute qname",
    "# {1} - tag name",
    "ERR_unsupportedAttribute=Unsupported attribute {0} on {1}"
  })
  private void processInstanceAttributes(Attributes atts) {
    for (int i = 0; i < atts.getLength(); i++) {
      String uri = atts.getURI(i);
      String name = atts.getLocalName(i);
      String qname = atts.getQName(i);

      PropertySetter ps = null;

      FxNode node;

      if (qname.startsWith("xmlns")) { // NOI18N
        // FIXME - xmlns attributes will be represented as FxNodes :-/
        continue;
      }

      if (FXML_FX_NAMESPACE.equals(uri)) {
        if (!(FX_ID.equals(name)
            || FX_CONTROLLER.equals(name)
            || FX_VALUE.equals(name)
            || FX_FACTORY.contains(name))) {
          addAttributeError(
              qname,
              "error-unsupported-attribute",
              ERR_unsupportedAttribute(qname, tagName),
              qname,
              tagName);
        }
        continue;
      }

      if (current instanceof FxInstanceCopy) {
        if (FxXmlSymbols.FX_ATTR_REFERENCE_SOURCE.equals(name) && uri == null) {
          // ignore source in fx:copy
          continue;
        }
      }

      // if the name begins with "on", it's an event handler.
      if (name.startsWith(EVENT_HANDLER_PREFIX) && name.length() > EVENT_HANDLER_PREFIX_LEN) {
        String en =
            Character.toLowerCase(name.charAt(EVENT_HANDLER_PREFIX_LEN))
                + name.substring(EVENT_HANDLER_PREFIX_LEN + 1);
        node = processEventHandlerAttribute(en, atts.getValue(i));
        // special hack for fx:copy or fx:reference
      } else {
        // FIXME - error detection for static property
        int stProp = FxXmlSymbols.findStaticProperty(name);
        if (stProp == -2) {
          // report error, not a well formed property name.
          addAttributeError(qname, "invalid-property-name", ERR_lowercasePropertyName(name), name);
          node = accessor.makeBroken(accessor.createProperty(name, false));
        } else if (stProp == -1) {
          // this is a normal property
          node = ps = accessor.createProperty(name, false);
        } else {
          // it is a static property
          node =
              ps =
                  accessor.createStaticProperty(
                      name.substring(stProp + 1), name.substring(0, stProp));
        }
        if (ps != null) {
          accessor.addContent(ps, atts.getValue(i));
          node = ps;
        }
      }
      initAttribute(node, qname);
      attachProperty(ps);
      attachChildNode(node);
    }
  }
Пример #4
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;
  }