Skip to content

Commit

Permalink
Merge pull request #324 from VineetReynolds/FORGE-917
Browse files Browse the repository at this point in the history
FORGE-917 Fixes to ensure that immutable classes are not scaffolded.
  • Loading branch information
gastaldi committed Jun 17, 2013
2 parents cbf85a0 + bddb7ba commit aba1427
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -27,9 +28,11 @@
import org.jboss.forge.parser.JavaParser;
import org.jboss.forge.parser.java.Annotation;
import org.jboss.forge.parser.java.Field;
import org.jboss.forge.parser.java.FieldHolder;
import org.jboss.forge.parser.java.JavaClass;
import org.jboss.forge.parser.java.Member;
import org.jboss.forge.parser.java.Method;
import org.jboss.forge.parser.java.Parameter;
import org.jboss.forge.parser.xml.Node;
import org.jboss.forge.parser.xml.XMLParser;
import org.jboss.forge.project.Project;
Expand All @@ -49,6 +52,8 @@
import org.jboss.forge.scaffold.TemplateStrategy;
import org.jboss.forge.scaffold.faces.metawidget.config.ForgeConfigReader;
import org.jboss.forge.scaffold.util.ScaffoldUtil;
import org.jboss.forge.shell.ShellMessages;
import org.jboss.forge.shell.ShellPrintWriter;
import org.jboss.forge.shell.ShellPrompt;
import org.jboss.forge.shell.plugins.Alias;
import org.jboss.forge.shell.plugins.Help;
Expand Down Expand Up @@ -76,6 +81,7 @@
import org.metawidget.statically.html.widgetbuilder.HtmlTag;
import org.metawidget.statically.javacode.StaticJavaMetawidget;
import org.metawidget.util.ArrayUtils;
import org.metawidget.util.ClassUtils;
import org.metawidget.util.CollectionUtils;
import org.metawidget.util.XmlUtils;
import org.metawidget.util.simple.StringUtils;
Expand Down Expand Up @@ -159,6 +165,7 @@ public class FacesScaffold extends BaseFacet implements ScaffoldProvider
protected StaticJavaMetawidget qbeMetawidget;

private Configuration config;
private ShellPrintWriter writer;

//
// Constructor
Expand All @@ -168,12 +175,14 @@ public class FacesScaffold extends BaseFacet implements ScaffoldProvider
public FacesScaffold(final Configuration config,
final ShellPrompt prompt,
final TemplateCompiler compiler,
final Event<InstallFacets> install)
final Event<InstallFacets> install,
final ShellPrintWriter writer)
{
this.config = config;
this.prompt = prompt;
this.compiler = compiler;
this.install = install;
this.writer = writer;

this.resolver = new ClassLoaderTemplateResolver(FacesScaffold.class.getClassLoader());

Expand Down Expand Up @@ -236,6 +245,12 @@ private void resetMetaWidgets()
public List<Resource<?>> generateFromEntity(String targetDir, final Resource<?> template, final JavaClass entity,
final boolean overwrite)
{
if(!isScaffoldable(entity))
{
ShellMessages.info(writer, "Skipping @Entity Java resource [" + entity.getQualifiedName() + "]");
return Collections.emptyList();
}

resetMetaWidgets();

// FORGE-460: setupRichFaces during generateFromEntity, not during setup, as generally 'richfaces setup' is called
Expand Down Expand Up @@ -911,4 +926,92 @@ else if ("long".equals(pkType))
context.put("primaryKeyType", pkType);
context.put("nullablePrimaryKeyType", nullablePkType);
}

private boolean isScaffoldable(JavaClass entity)
{
int setterCount = 0;
for (Method<JavaClass> method : entity.getMethods())
{
// Exclude static methods

if (method.isStatic())
{
continue;
}

// Get type

List<Parameter<JavaClass>> parameters = method.getParameters();

if (parameters.size() != 1)
{
continue;
}

// Get name

String setterPropertyName = getSetterProperty(method);

if (setterPropertyName == null)
{
continue;
}

Field<?> privateField = getPrivateField((FieldHolder<?>) entity, setterPropertyName);

if (privateField != null)
{
// TODO Verify other aspects like whether the property is transient or has a generated value etc.
setterCount++;
}
}
if (setterCount > 0)
{
return true;
}
else
{
return false;
}
}

/**
* Returns the property name corresponding to the given 'setter' method.
* Returns null if the supplied method is not a setter.
*
* @param method a single-parametered method. May return non-void (ie. for Fluent interfaces)
* @return the property name
*/
private String getSetterProperty(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);
}

/**
* Gets the private field representing the given <code>propertyName</code> within the given class.
*
* @return the private Field for this propertyName, or null if no such field (should not throw NoSuchFieldException)
*/
private Field<?> getPrivateField(final FieldHolder<?> fieldHolder, final String propertyName)
{
Field<?> field = fieldHolder.getField(propertyName);

// FORGE-402: support fields starting with capital letter

if (field == null && !Character.isUpperCase(propertyName.charAt( 0 )))
{
field = fieldHolder.getField(StringUtils.capitalize(propertyName));
}

return field;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.jboss.forge.resources.java.JavaResource;
import org.jboss.forge.scaffold.faces.metawidget.widgetbuilder.EntityWidgetBuilder;
import org.jboss.forge.scaffold.faces.metawidget.widgetbuilder.EntityWidgetBuilderConfig;
import org.jboss.forge.scaffold.util.ScaffoldUtil;
import org.jboss.forge.shell.exceptions.PluginExecutionException;
import org.jboss.forge.shell.util.Streams;
import org.jboss.forge.spec.javaee.ServletFacet;
Expand Down Expand Up @@ -116,6 +117,28 @@ public void testCannotGenerateFromEntityUntilScaffoldInstalled() throws Exceptio
queueInputLines("", "");
getShell().execute("scaffold from-entity");
}

@Test()
public void testCannotGenerateFromImmutableEntity() throws Exception
{
Project project = setupScaffoldProject();

JavaSourceFacet java = project.getFacet(JavaSourceFacet.class);
ScaffoldUtil
.createOrOverwrite(
null,
java.getJavaResource("org/jboss/forge/scaffold/faces/ImmutableClass.java"),
getClass()
.getResourceAsStream(
"/org/jboss/forge/scaffold/faces/ImmutableClass.java"),
true);

queueInputLines("", "");
getShell().execute("scaffold from-entity org.jboss.forge.scaffold.faces.ImmutableClass");

String commandOutput = getOutput();
Assert.assertTrue(commandOutput.contains("Skipped non-@Entity Java resource [org.jboss.forge.scaffold.faces.ImmutableClass]"));
}

@Test
public void testGenerateFromEntity() throws Exception
Expand Down Expand Up @@ -1104,7 +1127,7 @@ public void testInsertRichFacesWidgetBuilder() throws Exception

CompositeWidgetBuilder<StaticXmlWidget, StaticXmlMetawidget> newWidgetBuilder = new FacesScaffold(null, null,
null,
null).insertRichFacesWidgetBuilder(existingWidgetBuilder);
null, null).insertRichFacesWidgetBuilder(existingWidgetBuilder);

assertTrue(newWidgetBuilder.getWidgetBuilders()[0] instanceof EntityWidgetBuilder);
assertTrue(newWidgetBuilder.getWidgetBuilders()[1] instanceof ReadOnlyWidgetBuilder);
Expand All @@ -1115,7 +1138,7 @@ public void testInsertRichFacesWidgetBuilder() throws Exception
new CompositeWidgetBuilderConfig<StaticXmlWidget, StaticXmlMetawidget>().setWidgetBuilders(
new ReadOnlyWidgetBuilder(), new HtmlWidgetBuilder()));

newWidgetBuilder = new FacesScaffold(null, null, null, null).insertRichFacesWidgetBuilder(existingWidgetBuilder);
newWidgetBuilder = new FacesScaffold(null, null, null, null, null).insertRichFacesWidgetBuilder(existingWidgetBuilder);

assertTrue(newWidgetBuilder.getWidgetBuilders()[0] instanceof ReadOnlyWidgetBuilder);
assertTrue(newWidgetBuilder.getWidgetBuilders()[1] instanceof RichFacesWidgetBuilder);
Expand All @@ -1127,7 +1150,7 @@ public void testInsertRichFacesWidgetBuilder() throws Exception
new CompositeWidgetBuilderConfig<StaticXmlWidget, StaticXmlMetawidget>().setWidgetBuilders(
new EntityWidgetBuilder(new EntityWidgetBuilderConfig()), new ReadOnlyWidgetBuilder()));

newWidgetBuilder = new FacesScaffold(null, null, null, null).insertRichFacesWidgetBuilder(existingWidgetBuilder);
newWidgetBuilder = new FacesScaffold(null, null, null, null, null).insertRichFacesWidgetBuilder(existingWidgetBuilder);

assertTrue(newWidgetBuilder.getWidgetBuilders()[0] instanceof EntityWidgetBuilder);
assertTrue(newWidgetBuilder.getWidgetBuilders()[1] instanceof ReadOnlyWidgetBuilder);
Expand All @@ -1139,7 +1162,7 @@ public void testInsertRichFacesWidgetBuilder() throws Exception
new CompositeWidgetBuilderConfig<StaticXmlWidget, StaticXmlMetawidget>().setWidgetBuilders(
new EntityWidgetBuilder(new EntityWidgetBuilderConfig()), new HtmlWidgetBuilder()));

newWidgetBuilder = new FacesScaffold(null, null, null, null).insertRichFacesWidgetBuilder(existingWidgetBuilder);
newWidgetBuilder = new FacesScaffold(null, null, null, null, null).insertRichFacesWidgetBuilder(existingWidgetBuilder);

assertTrue(newWidgetBuilder.getWidgetBuilders()[0] instanceof RichFacesWidgetBuilder);
assertTrue(newWidgetBuilder.getWidgetBuilders()[1] instanceof EntityWidgetBuilder);
Expand All @@ -1152,7 +1175,7 @@ public void testInsertRichFacesWidgetBuilder() throws Exception
new EntityWidgetBuilder(new EntityWidgetBuilderConfig()), new RichFacesWidgetBuilder(),
new HtmlWidgetBuilder()));

newWidgetBuilder = new FacesScaffold(null, null, null, null).insertRichFacesWidgetBuilder(existingWidgetBuilder);
newWidgetBuilder = new FacesScaffold(null, null, null, null, null).insertRichFacesWidgetBuilder(existingWidgetBuilder);

assertTrue(newWidgetBuilder.getWidgetBuilders()[0] instanceof EntityWidgetBuilder);
assertTrue(newWidgetBuilder.getWidgetBuilders()[1] instanceof RichFacesWidgetBuilder);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.jboss.forge.scaffold.faces;

/**
* Used to test scaffold generation of an immutable class - no setters only getters
*/

public class ImmutableClass
{
//
// Field with Getter
//

private String normalField;

public String getNormalField()
{
return this.normalField;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ public void generateFromEntity(
if (!generatedResources.isEmpty())
{
generatedEvent.fire(new ScaffoldGeneratedResources(provider, prepareResources(generatedResources)));
ShellMessages.success(writer, "Generated UI for [" + entity.getQualifiedName() + "]");
}

ShellMessages.success(writer, "Generated UI for [" + entity.getQualifiedName() + "]");
}

}
Expand Down

0 comments on commit aba1427

Please sign in to comment.