@Override
  public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {

    ObjectProperty property = (ObjectProperty) context.getKey();
    if (navigable && property != null && !property.isBaseType()) {
      SafeHtml startAnchor = null;
      SafeHtml endAnchor = null;
      startAnchor =
          new SafeHtml() {
            @Override
            public String asString() {
              return "<div style=\"cursor: pointer;\">";
            }
          };

      endAnchor =
          new SafeHtml() {
            @Override
            public String asString() {
              return "</div>";
            }
          };

      sb.append(startAnchor);
      sb.append(value);
      sb.append(endAnchor);

    } else {
      super.render(context, value, sb);
    }
  }
  public String resolveEquals(DataObject dataObject, String indent) {

    StringBuilder head = new StringBuilder();
    // head.append(EOL);
    head.append(indent + "@Override" + EOL);
    head.append(indent + "public boolean equals(Object o) {" + EOL);
    head.append(indent + TAB + "if (this == o) return true;" + EOL);
    head.append(indent + TAB + "if (o == null || getClass() != o.getClass()) return false;" + EOL);
    head.append(
        indent
            + TAB
            + dataObject.getClassName()
            + " that = ("
            + dataObject.getClassName()
            + ")o;"
            + EOL);

    StringBuilder end = new StringBuilder();
    end.append(indent + "}");

    StringBuilder sb = new StringBuilder();
    Map<String, ObjectProperty> props = dataObject.getProperties();

    boolean hasTerms = false;
    if (props != null && props.size() > 0) {
      for (String propName : props.keySet()) {
        ObjectProperty prop = props.get(propName);
        String _propName = toJavaVar(propName);
        if (prop.getAnnotation(org.kie.api.definition.type.Key.class.getName()) != null) {
          // Construction: "if (<_propName> != null ? !<_propName>.equals(that.<_propName>) :
          // that.<_propName> != null) return false;"
          sb.append(indent + TAB + "if (");
          sb.append(_propName)
              .append(" != null ? !")
              .append(_propName)
              .append(".equals(that.")
              .append(_propName)
              .append(")");
          sb.append(" : that.").append(_propName).append(" != null").append(") return false;");
          sb.append(EOL);
          hasTerms = true;
        }
      }
    }

    if (hasTerms) {
      sb.append(indent + TAB + "return true;" + EOL);
      head.append(sb);
      head.append(end);
      return head.toString();
    } else {
      return "";
    }
  }
  @Override
  public void onBrowserEvent(
      Context context,
      Element parent,
      String value,
      NativeEvent event,
      ValueUpdater<String> stringValueUpdater) {

    ObjectProperty property = (ObjectProperty) context.getKey();
    if (DOM.eventGetType((Event) event) == Event.ONCLICK && !property.isBaseType()) {
      editor.onTypeCellSelection(property);
    } else {
      super.onBrowserEvent(context, parent, value, event, stringValueUpdater);
    }
  }
  public void onTypeCellSelection(ObjectProperty property) {

    DataObject dataObject = getDataModel().getDataObject(property.getClassName());
    if (dataObject != null) {
      openDataObject(dataObject);
    }
  }
 public String resolveKeyFieldsConstructor(DataObject dataObject, String indent) {
   if (!dataObject.getProperties().isEmpty()) {
     List<ObjectProperty> sortedProperties = new ArrayList<ObjectProperty>();
     for (ObjectProperty property : dataObject.getProperties().values()) {
       if (property.getAnnotation(KeyAnnotationDefinition.getInstance().getClassName()) != null) {
         // the property is marked as key.
         sortedProperties.add(property);
       }
     }
     if (sortedProperties.size() > 0
         && sortedProperties.size() < dataObject.getProperties().size()) {
       return resolveConstructor(dataObject, sortByPosition(sortedProperties), indent);
     }
   }
   return "";
 }
  private String propertyTypeDisplay(ObjectProperty property) {
    String displayName = property.getClassName();

    if (property.isBaseType()) {
      displayName = DataModelerUtils.extractClassName(displayName);
    } else {
      String label = getContext().getHelper().getObjectLabelByClassName(displayName);
      if (label != null && !"".equals(label)) {
        displayName = label;
      }
    }

    if (property.isMultiple()) {
      displayName += " [" + Constants.INSTANCE.objectBrowser_typeLabelMultiple() + "]";
    }
    return displayName;
  }
  private void makeNewJavaTypes(
      final Path context, final List<String> declaredTypes, final ConversionResult result) {
    if (declaredTypes == null || declaredTypes.isEmpty()) {
      return;
    }

    final KieProject project = projectService.resolveProject(context);

    for (String declaredType : declaredTypes) {
      final FactModels factModels = FactModelPersistence.unmarshal(declaredType);
      final String packageName = factModels.getPackageName();
      final DataModel dataModel = new DataModelImpl();

      for (FactMetaModel factMetaModel : factModels.getModels()) {
        final DataObject dataObject = new DataObjectImpl(factMetaModel.getName(), packageName);
        dataObject.setSuperClassName(factMetaModel.getSuperType());
        final List<AnnotationMetaModel> annotationMetaModel = factMetaModel.getAnnotations();
        addAnnotations(dataObject, annotationMetaModel);

        final List<FieldMetaModel> fields = factMetaModel.getFields();

        for (FieldMetaModel fieldMetaModel : fields) {
          final String fieldName = fieldMetaModel.name;
          final String fieldType = fieldMetaModel.type;
          // Guvnor 5.5 (and earlier) does not have MultipleType
          boolean isMultiple = false;
          boolean isBaseType = orderedBaseTypes.containsValue(fieldType);
          ObjectProperty property = new ObjectPropertyImpl(fieldName, fieldType, isMultiple);
          property.setBaseType(isBaseType);

          // field has no annotation in Guvnor 5.5 (and earlier)
          dataObject.addProperty(property);

          result.addMessage(
              "Created Java Type " + getJavaTypeFQCN(dataObject), ConversionMessageType.INFO);
        }

        dataModel.getDataObjects().add(dataObject);
      }

      modellerService.saveModel(dataModel, project);
    }
  }
  public String resolveHashCode(DataObject dataObject, String indent) {

    StringBuilder head = new StringBuilder();
    // head.append(EOL);
    head.append(indent + "@Override" + EOL);
    head.append(indent + "public int hashCode() {" + EOL);
    head.append(indent + TAB + "int result = 17;" + EOL);

    StringBuilder end = new StringBuilder();
    end.append(indent + "}");

    StringBuilder sb = new StringBuilder();
    Map<String, ObjectProperty> props = dataObject.getProperties();

    boolean hasTerms = false;
    if (props != null && props.size() > 0) {
      for (String propName : props.keySet()) {
        ObjectProperty prop = props.get(propName);
        String _propName = toJavaVar(propName);
        if (prop.getAnnotation(org.kie.api.definition.type.Key.class.getName()) != null) {
          // Construction: "result = 13 * result + (<_propName> != null ? <_propName>.hashCode() :
          // 0);"
          sb.append(indent + TAB + "result = 13 * result + (")
              .append(_propName)
              .append(" != null ? ")
              .append(_propName)
              .append(".hashCode() : 0);");
          sb.append(EOL);
          hasTerms = true;
        }
      }
    }

    if (hasTerms) {
      sb.append(indent + TAB + "return result;" + EOL);
      head.append(sb);
      head.append(end);
      return head.toString();
    } else {
      return "";
    }
  }
  private void checkUsageAndDeleteDataObjectProperty(
      final ObjectProperty objectProperty, final int index) {

    final String className = dataObject.getClassName();
    final String fieldName = objectProperty.getName();

    if (getContext() != null) {

      final Path currentPath =
          getContext().getEditorModelContent() != null
              ? getContext().getEditorModelContent().getPath()
              : null;

      modelerService
          .call(
              new RemoteCallback<List<Path>>() {

                @Override
                public void callback(List<Path> paths) {

                  if (paths != null && paths.size() > 0) {
                    // If usages for this field were detected in project assets
                    // show the confirmation message to the user.

                    ShowUsagesPopup showUsagesPopup =
                        ShowUsagesPopup.newUsagesPopupForDeletion(
                            Constants.INSTANCE.modelEditor_confirm_deletion_of_used_field(
                                objectProperty.getName()),
                            paths,
                            new Command() {
                              @Override
                              public void execute() {
                                deleteDataObjectProperty(objectProperty, index);
                              }
                            },
                            new Command() {
                              @Override
                              public void execute() {
                                // do nothing.
                              }
                            });

                    showUsagesPopup.setClosable(false);
                    showUsagesPopup.show();

                  } else {
                    // no usages, just proceed with the deletion.
                    deleteDataObjectProperty(objectProperty, index);
                  }
                }
              })
          .findFieldUsages(currentPath, className, fieldName);
    }
  }
  public String resolveConstructor(
      DataObject dataObject, List<ObjectProperty> properties, String indent) {

    StringBuilder head = new StringBuilder();
    StringBuilder body = new StringBuilder();

    head.append(indent + "public " + dataObject.getName() + "(");

    if (properties != null && properties.size() > 0) {
      boolean isFirst = true;
      String propertyName;
      for (ObjectProperty property : properties) {
        if (!isFirst) {
          head.append(", ");
          body.append(EOL);
        }
        propertyName = toJavaVar(property.getName());
        head.append(resolveAttributeType(property));
        head.append(" ");
        head.append(propertyName);

        body.append(indent);
        body.append(indent);
        body.append("this.");
        body.append(propertyName);
        body.append(" = ");
        body.append(propertyName);
        body.append(";");

        isFirst = false;
      }
      body.append(EOL);
    }

    head.append(") {" + EOL);
    head.append(body);
    head.append(indent + "}");

    return head.toString();
  }
 public String resolveAttributeType(ObjectProperty attribute) {
   StringBuffer type = new StringBuffer("");
   if (attribute.isMultiple()) {
     if (attribute.getBag() != null && !"".equals(attribute.getBag())) {
       type.append(attribute.getBag());
     } else {
       type.append("java.util.List");
     }
     type.append("<");
   }
   type.append(attribute.getClassName());
   if (attribute.isMultiple()) {
     type.append(">");
   }
   return type.toString();
 }
  private void deleteDataObjectProperty(final ObjectProperty objectProperty, final int index) {
    if (dataObject != null) {
      dataObject.getProperties().remove(objectProperty);

      dataObjectPropertiesProvider.getList().remove(index);
      dataObjectPropertiesProvider.flush();
      dataObjectPropertiesProvider.refresh();

      getContext()
          .getHelper()
          .dataObjectUnReferenced(objectProperty.getClassName(), dataObject.getClassName());
      notifyFieldDeleted(objectProperty);
      if (dataObjectPropertiesProvider.getList().size() == 0) {
        context.setObjectProperty(null);
        dataModelerWBContextEvent.fire(new DataModelerWorkbenchContextChangeEvent());
      } else if (dataObjectPropertiesProvider.getList().size() == 1) {
        // BZ-1255449 tricky bug. Considerable time was spent, and it was no direct to find an
        // optimal/better solution.
        // Since in this use case the Data Object will have just one field, it's acceptable to
        // reload the list.
        setDataObject(dataObject);
      }
    }
  }