Ejemplo n.º 1
0
    @Override
    public String componentToTag(Component component, DesignContext context) {
      Class<?> componentClass = component.getClass();
      String packageName = componentClass.getPackage().getName();
      String prefix = context.getPackagePrefix(packageName);
      if (prefix == null) {
        prefix = packageName.replace('.', '_');
        context.addPackagePrefix(prefix, packageName);
      }
      prefix = prefix + "-";
      String className = classNameToElementName(componentClass.getSimpleName());
      String tagName = prefix + className;

      return tagName;
    }
Ejemplo n.º 2
0
  /**
   * Generates an html tree representation of the component hierarchy having the root
   * designContext.getRootComponent(). The hierarchy is stored under &lt;body&gt; in the tree. The
   * generated tree represents a valid html document.
   *
   * @param designContext a DesignContext object specifying the root component
   *     (designContext.getRootComponent()) of the hierarchy
   * @return an html tree representation of the component hierarchy
   */
  private static Document createHtml(DesignContext designContext) {
    // Create the html tree skeleton.
    Document doc = new Document("");
    DocumentType docType = new DocumentType("html", "", "", "");
    doc.appendChild(docType);
    Element html = doc.createElement("html");
    doc.appendChild(html);
    html.appendChild(doc.createElement("head"));
    Element body = doc.createElement("body");
    html.appendChild(body);

    // Append the design under <body> in the html tree. createNode
    // creates the entire component hierarchy rooted at the
    // given root node.
    Component root = designContext.getRootComponent();
    if (root != null) {
      Node rootNode = designContext.createElement(root);
      body.appendChild(rootNode);
    }
    designContext.writePackageMappings(doc);
    return doc;
  }
Ejemplo n.º 3
0
 /**
  * Constructs a component hierarchy from the design specified as an html tree.
  *
  * <p>If a component root is given, the component instances created during reading the design are
  * assigned to its member fields based on their id, local id, and caption
  *
  * @param doc the html tree
  * @param componentRoot optional component root instance. The type must match the type of the root
  *     element in the design.
  * @param classWithFields a class (componentRoot class or a super class) with some member fields.
  *     The member fields whose type is assignable from {@link Component} are bound to fields in
  *     the design based on id/local id/caption
  */
 private static DesignContext designToComponentTree(
     Document doc, Component componentRoot, Class<?> classWithFields) {
   DesignContext designContext = new DesignContext(doc);
   designContext.readPackageMappings(doc);
   // No special handling for a document without a body element - should be
   // taken care of by jsoup.
   Element root = doc.body();
   Elements children = root.children();
   if (children.size() > 1) {
     throw new DesignException(
         "The first level of a component hierarchy should contain at most one root component, but found "
             + children.size()
             + ".");
   }
   Element element = children.size() == 0 ? null : children.first();
   if (componentRoot != null) {
     if (element == null) {
       throw new DesignException(
           "The root element cannot be null when the specified root Component is" + " not null.");
     }
     // user has specified root instance that may have member fields that
     // should be bound
     final FieldBinder binder;
     try {
       binder = new FieldBinder(componentRoot, classWithFields);
     } catch (IntrospectionException e) {
       throw new DesignException("Could not bind fields of the root component", e);
     }
     // create listener for component creations that binds the created
     // components to the componentRoot instance fields
     ComponentCreationListener creationListener =
         new ComponentCreationListener() {
           @Override
           public void componentCreated(ComponentCreatedEvent event) {
             binder.bindField(event.getComponent(), event.getLocalId());
           }
         };
     designContext.addComponentCreationListener(creationListener);
     // create subtree
     designContext.readDesign(element, componentRoot);
     // make sure that all the member fields are bound
     Collection<String> unboundFields = binder.getUnboundFields();
     if (!unboundFields.isEmpty()) {
       throw new DesignException("Found unbound fields from component root " + unboundFields);
     }
     // no need to listen anymore
     designContext.removeComponentCreationListener(creationListener);
   } else {
     // createChild creates the entire component hierarchy
     componentRoot = element == null ? null : designContext.readDesign(element);
   }
   designContext.setRootComponent(componentRoot);
   return designContext;
 }
Ejemplo n.º 4
0
    @Override
    public Component tagToComponent(
        String tagName, ComponentFactory componentFactory, DesignContext context) {
      // Extract the package and class names.
      // Otherwise, get the full class name using the prefix to package
      // mapping. Example: "v-vertical-layout" ->
      // "com.vaadin.ui.VerticalLayout"
      String[] parts = tagName.split("-", 2);
      if (parts.length < 2) {
        throw new DesignException("The tagname '" + tagName + "' is invalid: missing prefix.");
      }
      String prefixName = parts[0];
      String packageName = context.getPackage(prefixName);
      if (packageName == null) {
        throw new DesignException("Unknown tag: " + tagName);
      }
      String[] classNameParts = parts[1].split("-");
      String className = "";
      for (String classNamePart : classNameParts) {
        // Split will ignore trailing and multiple dashes but that
        // should be
        // ok
        // <v-button--> will be resolved to <v-button>
        // <v--button> will be resolved to <v-button>
        className += SharedUtil.capitalize(classNamePart);
      }
      String qualifiedClassName = packageName + "." + className;

      Component component = componentFactory.createComponent(qualifiedClassName, context);

      if (component == null) {
        throw new DesignException(
            "Got unexpected null component from "
                + componentFactory.getClass().getName()
                + " for class "
                + qualifiedClassName);
      }

      return component;
    }
Ejemplo n.º 5
0
 /**
  * Writes the given component tree in design format to the given output stream.
  *
  * @param component the root component of the component tree, null can be used for generating an
  *     empty design
  * @param outputStream the output stream to write the design to. The design is always written as
  *     UTF-8
  * @throws IOException
  */
 public static void write(Component component, OutputStream outputStream) throws IOException {
   DesignContext dc = new DesignContext();
   dc.setRootComponent(component);
   write(dc, outputStream);
 }
Ejemplo n.º 6
0
 /**
  * Loads a design from the given input stream
  *
  * @param design The stream to read the design from
  * @return The root component of the design
  */
 public static Component read(InputStream design) {
   DesignContext context = read(design, null);
   return context.getRootComponent();
 }