@Override
 public void validate(UIValidationContext validator) {
   boolean overwriteValue = overwrite.getValue() != null && overwrite.getValue();
   JavaResource resource = (JavaResource) validator.getUIContext().getInitialSelection().get();
   JavaClass javaClass;
   if (!overwriteValue) {
     try {
       String fieldName = conversationFieldName.getValue();
       String beginName = beginMethodName.getValue();
       String endName = endMethodName.getValue();
       javaClass = (JavaClass) resource.getJavaSource();
       if (javaClass.hasField(fieldName)
           && !javaClass.getField(fieldName).isType(Conversation.class)) {
         validator.addValidationError(
             conversationFieldName, "Field [" + fieldName + "] already exists.");
       }
       if (javaClass.hasMethodSignature(beginName)
           && (javaClass.getMethod(beginName).getParameters().size() == 0)) {
         validator.addValidationError(beginMethodName, "Method [" + beginName + "] exists.");
       }
       if (javaClass.hasMethodSignature(endName)
           && (javaClass.getMethod(endName).getParameters().size() == 0)) {
         validator.addValidationError(endMethodName, "Method [" + endName + "] exists.");
       }
     } catch (FileNotFoundException e) {
       validator.addValidationError(null, "The selected resource file was not found");
     }
   }
 }
  @Test
  public void testAddPatternConstraint() throws Exception {
    final String message = "Message";
    getShell()
        .execute(
            CONSTRAINT_PLUGIN_NAME
                + " Pattern --onProperty "
                + PROPERTY_NAME
                + " --regexp [a-z]* --message "
                + message);
    getShell()
        .execute(
            CONSTRAINT_PLUGIN_NAME
                + " Pattern --onProperty "
                + PROPERTY_NAME
                + " --regexp [a-z]* --onAccessor");

    final JavaClass fooClass = getJavaClassFromResource(getShell().getCurrentResource());
    final Field<JavaClass> property = fooClass.getField(PROPERTY_NAME);

    assertNotNull(property);
    assertTrue(property.hasAnnotation(Pattern.class));
    assertEquals("[a-z]*", property.getAnnotation(Pattern.class).getStringValue("regexp"));
    assertEquals(message, property.getAnnotation(Pattern.class).getStringValue("message"));
    assertEquals(null, property.getAnnotation(Pattern.class).getStringValue("flags"));

    final Method<JavaClass> accessor = fooClass.getMethod(PROPERTY_ACESSOR_NAME);

    assertNotNull(accessor);
    assertTrue(accessor.hasAnnotation(Pattern.class));
    assertEquals("[a-z]*", accessor.getAnnotation(Pattern.class).getStringValue("regexp"));
  }
  @Test
  public void testAddDigitsConstraint() throws Exception {
    final String message = "Message";
    getShell()
        .execute(
            CONSTRAINT_PLUGIN_NAME
                + " Digits --onProperty "
                + PROPERTY_NAME
                + " --integer 3 --fraction 4 --message "
                + message);
    getShell()
        .execute(
            CONSTRAINT_PLUGIN_NAME
                + " Digits --onProperty "
                + PROPERTY_NAME
                + " --integer 4 --fraction 3 --onAccessor");

    final JavaClass fooClass = getJavaClassFromResource(getShell().getCurrentResource());
    final Field<JavaClass> property = fooClass.getField(PROPERTY_NAME);

    assertNotNull(property);
    assertTrue(property.hasAnnotation(Digits.class));
    assertEquals("3", property.getAnnotation(Digits.class).getLiteralValue("integer"));
    assertEquals("4", property.getAnnotation(Digits.class).getLiteralValue("fraction"));
    assertEquals(message, property.getAnnotation(Digits.class).getStringValue("message"));

    final Method<JavaClass> accessor = fooClass.getMethod(PROPERTY_ACESSOR_NAME);

    assertNotNull(accessor);
    assertTrue(accessor.hasAnnotation(Digits.class));
    assertEquals("4", accessor.getAnnotation(Digits.class).getLiteralValue("integer"));
    assertEquals("3", accessor.getAnnotation(Digits.class).getLiteralValue("fraction"));
  }
  @Test
  public void testAddSizeConstraintWithMinMax() throws Exception {
    getShell()
        .execute(
            CONSTRAINT_PLUGIN_NAME + " Size --onProperty " + PROPERTY_NAME + " --min 0 --max 3");

    final JavaClass fooClass = getJavaClassFromResource(getShell().getCurrentResource());
    final Field<JavaClass> property = fooClass.getField(PROPERTY_NAME);

    assertNotNull(property);
    assertTrue(property.hasAnnotation(Size.class));
    assertEquals("0", property.getAnnotation(Size.class).getLiteralValue("min"));
    assertEquals("3", property.getAnnotation(Size.class).getLiteralValue("max"));
  }
  @Test
  public void testAddValidConstraint() throws Exception {
    getShell().execute(CONSTRAINT_PLUGIN_NAME + " Valid --onProperty " + PROPERTY_NAME);
    getShell()
        .execute(CONSTRAINT_PLUGIN_NAME + " Valid --onProperty " + PROPERTY_NAME + " --onAccessor");

    final JavaClass fooClass = getJavaClassFromResource(getShell().getCurrentResource());
    final Field<JavaClass> property = fooClass.getField(PROPERTY_NAME);

    assertNotNull(property);
    assertTrue(property.hasAnnotation(Valid.class));

    final Method<JavaClass> accessor = fooClass.getMethod(PROPERTY_ACESSOR_NAME);

    assertNotNull(accessor);
    assertTrue(accessor.hasAnnotation(Valid.class));
  }
  @Override
  public Result execute(UIExecutionContext context) throws Exception {
    UIContext uiContext = context.getUIContext();
    JavaResource resource = (JavaResource) uiContext.getInitialSelection().get();
    String name = named.getValue();
    String fieldName = conversationFieldName.getValue();
    String beginName = beginMethodName.getValue();
    String endName = endMethodName.getValue();
    Boolean overwriteValue = overwrite.getValue();
    UIOutput output = uiContext.getProvider().getOutput();
    if (resource.exists()) {
      if (resource.getJavaSource().isClass()) {
        JavaClass javaClass = (JavaClass) resource.getJavaSource();

        if (javaClass.hasField(fieldName)
            && !javaClass.getField(fieldName).isType(Conversation.class)) {
          if (overwriteValue) {
            javaClass.removeField(javaClass.getField(fieldName));
          } else {
            return Results.fail("Field [" + fieldName + "] already exists.");
          }
        }
        if (javaClass.hasMethodSignature(beginName)
            && (javaClass.getMethod(beginName).getParameters().size() == 0)) {
          if (overwriteValue) {
            javaClass.removeMethod(javaClass.getMethod(beginName));
          } else {
            return Results.fail("Method [" + beginName + "] exists.");
          }
        }
        if (javaClass.hasMethodSignature(endName)
            && (javaClass.getMethod(endName).getParameters().size() == 0)) {
          if (overwriteValue) {
            javaClass.removeMethod(javaClass.getMethod(endName));
          } else {
            return Results.fail("Method [" + endName + "] exists.");
          }
        }

        javaClass
            .addField()
            .setPrivate()
            .setName(fieldName)
            .setType(Conversation.class)
            .addAnnotation(Inject.class);

        Method<JavaClass> beginMethod =
            javaClass.addMethod().setName(beginName).setReturnTypeVoid().setPublic();
        if (Strings.isNullOrEmpty(name)) {
          beginMethod.setBody(fieldName + ".begin();");
        } else {
          beginMethod.setBody(fieldName + ".begin(\"" + name + "\");");
        }

        if (timeout.getValue() != null) {
          beginMethod.setBody(
              beginMethod.getBody() + "\n" + fieldName + ".setTimeout(" + timeout + ");");
        }

        javaClass
            .addMethod()
            .setName(endName)
            .setReturnTypeVoid()
            .setPublic()
            .setBody(fieldName + ".end();");

        if (javaClass.hasSyntaxErrors()) {
          output.err().println("Modified Java class contains syntax errors:");
          for (SyntaxError error : javaClass.getSyntaxErrors()) {
            output.err().print(error.getDescription());
          }
        }

        resource.setContents(javaClass);
      } else {
        return Results.fail(
            "Must operate on a Java Class file, not an ["
                + resource.getJavaSource().getSourceType()
                + "]");
      }
    }
    return Results.success("Conversation block created");
  }