@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")); }
/** * Returns whether the given method is a 'getter' method. * * @param method a parameterless method that returns a non-void * @return the property name */ protected String isGetter(final Method<?> method) { String methodName = method.getName(); String propertyName; if (methodName.startsWith(ClassUtils.JAVABEAN_GET_PREFIX)) { propertyName = methodName.substring(ClassUtils.JAVABEAN_GET_PREFIX.length()); } else if (methodName.startsWith(ClassUtils.JAVABEAN_IS_PREFIX) && boolean.class.equals(method.getQualifiedReturnType())) { // As per section 8.3.2 (Boolean properties) of The JavaBeans API specification, 'is' // only applies to boolean (little 'b') propertyName = methodName.substring(ClassUtils.JAVABEAN_IS_PREFIX.length()); } else { return null; } if (!StringUtils.isCapitalized(propertyName)) { return null; } return StringUtils.decapitalize(propertyName); }
@Test public void testCreateEndpoint() throws Exception { Project project = getProject(); JavaClass entity = generateEntity(project, null, "User"); assertFalse(entity.hasAnnotation(XmlRootElement.class)); setupRest(); queueInputLines(""); getShell().execute("rest endpoint-from-entity"); JavaSourceFacet java = project.getFacet(JavaSourceFacet.class); JavaResource resource = java.getJavaResource(java.getBasePackage() + ".rest.UserEndpoint"); JavaClass endpoint = (JavaClass) resource.getJavaSource(); assertEquals("/user", endpoint.getAnnotation(Path.class).getStringValue()); assertEquals("java.util.List", endpoint.getMethod("listAll").getQualifiedReturnType()); Method<JavaClass> method = endpoint.getMethod("findById", Long.class); Type<JavaClass> returnTypeInspector = method.getReturnTypeInspector(); assertEquals( "com.test." + PersistenceFacetImpl.DEFAULT_ENTITY_PACKAGE + ".User", returnTypeInspector.getQualifiedName()); assertTrue(java.getJavaResource(entity).getJavaSource().hasAnnotation(XmlRootElement.class)); getShell().execute("build"); }
@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 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)); }
/** * Lookup getter-based properties. * * <p>This method will be called after <code>lookupFields</code> but before <code>lookupSetters * </code>. */ protected void lookupGetters( final Map<String, Property> properties, final MethodHolder<?> clazz) { // Hack until https://issues.jboss.org/browse/FORGE-368 for (Method<?> method : clazz.getMethods()) { // Exclude static methods if (method.isStatic()) { continue; } // Get type if (!method.getParameters().isEmpty()) { continue; } String returnType = method.getQualifiedReturnType(); if (returnType == null) { continue; } // Get name String propertyName = isGetter(method); if (propertyName == null) { continue; } Field<?> privateField = getPrivateField((FieldHolder<?>) clazz, propertyName); if (privateField != null && this.privateFieldConvention == null) { propertyName = privateField.getName(); } properties.put( propertyName, new ForgeProperty(propertyName, returnType, method, null, privateField, this.project)); } }
/** * Returns whether the given method is a 'setter' method. * * @param method a single-parametered method. May return non-void (ie. for Fluent interfaces) * @return the property name */ protected String isSetter(final Method<?> method) { String methodName = method.getName(); if (!methodName.startsWith(ClassUtils.JAVABEAN_SET_PREFIX)) { return null; } String propertyName = methodName.substring(ClassUtils.JAVABEAN_SET_PREFIX.length()); return StringUtils.decapitalize(propertyName); }
@Command("new-method") @RequiresResource(JavaResource.class) public void newMethod( @PipeIn final String in, final PipeOut out, @Option( required = false, help = "the method definition: surround with single quotes", description = "method definition") final String... def) throws FileNotFoundException { JavaSourceFacet java = project.getFacet(JavaSourceFacet.class); String methodDef = null; if (def != null) { methodDef = Strings.join(Arrays.asList(def), " "); } else if (in != null) { methodDef = in; } else { throw new RuntimeException("arguments required"); } JavaSource<?> source = resource.getJavaSource(); if (source instanceof MethodHolder) { MethodHolder<?> clazz = ((MethodHolder<?>) source); Method<JavaClass> method = JavaParser.parse(JavaClass.class, "public class Temp{}").addMethod(methodDef); if (clazz.hasMethodSignature(method)) { throw new IllegalStateException( "Method with signature [" + method.toSignature() + "] already exists."); } clazz.addMethod(methodDef); java.saveJavaSource(source); } }
/** * Lookup setter-based properties. * * <p>This method will be called after <code>lookupFields</code> and <code>lookupGetters</code>. */ protected void lookupSetters( final Map<String, Property> properties, final MethodHolder<?> clazz) { for (Method<?> method : clazz.getMethods()) { // Exclude static methods if (method.isStatic()) { continue; } // Get type List<Parameter> parameters = method.getParameters(); if (parameters.size() != 1) { continue; } // Get name String propertyName = isSetter(method); if (propertyName == null) { continue; } // Exclude based on other criteria // // (explicitly set to null in case we encountered an imbalanced field/getter) String type = parameters.get(0).getType(); Field<?> privateField = getPrivateField((FieldHolder<?>) clazz, propertyName); if (privateField != null && this.privateFieldConvention == null) { propertyName = privateField.getName(); } // Already found via its getter? Property existingProperty = properties.get(propertyName); if (existingProperty instanceof ForgeProperty) { ForgeProperty existingForgeProperty = (ForgeProperty) existingProperty; // Beware covariant return types: always prefer the getter's type properties.put( propertyName, new ForgeProperty( propertyName, existingForgeProperty.getType(), existingForgeProperty.getReadMethod(), method, getPrivateField((FieldHolder<?>) clazz, propertyName))); continue; } // Explicitly excluded based on getter already? if ((existingProperty == null) && properties.containsKey(propertyName)) { continue; } properties.put( propertyName, new ForgeProperty(propertyName, type, null, method, privateField)); } }
@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"); }