Skip to content

Commit

Permalink
Fix REST plugin generation on non-standard @Entities
Browse files Browse the repository at this point in the history
  • Loading branch information
lincolnthree committed Mar 26, 2012
1 parent 8c1c1da commit 8964ab1
Show file tree
Hide file tree
Showing 6 changed files with 337 additions and 31 deletions.
Expand Up @@ -51,6 +51,7 @@
import org.jboss.forge.project.facets.JavaSourceFacet;
import org.jboss.forge.project.facets.events.InstallFacets;
import org.jboss.forge.resources.Resource;
import org.jboss.forge.resources.java.JavaMethodResource;
import org.jboss.forge.resources.java.JavaResource;
import org.jboss.forge.shell.PromptType;
import org.jboss.forge.shell.ShellMessages;
Expand Down Expand Up @@ -113,12 +114,15 @@ public void setup(@Option(name = "activatorType") RestActivatorType activatorTyp
String rootpath = prompt.prompt("What root path do you want to use for your resources?", "/rest");
configuration.addProperty(RestFacet.ROOTPATH, rootpath);

if (activatorType == null || activatorType == RestActivatorType.WEB_XML && !project.hasFacet(RestWebXmlFacetImpl.class))
if (activatorType == null || activatorType == RestActivatorType.WEB_XML
&& !project.hasFacet(RestWebXmlFacetImpl.class))
{
request.fire(new InstallFacets(RestWebXmlFacetImpl.class));
} else if (activatorType == RestActivatorType.APP_CLASS && !project.hasFacet(RestApplicationFacet.class))
}
else if (activatorType == RestActivatorType.APP_CLASS && !project.hasFacet(RestApplicationFacet.class))
{
String pkg = prompt.promptCommon("In what package do you want to store the Application class?", PromptType.JAVA_PACKAGE);
String pkg = prompt.promptCommon("In what package do you want to store the Application class?",
PromptType.JAVA_PACKAGE);
String restApplication = prompt.prompt("How do you want to name the Application class?", "RestApplication");
configuration.addProperty(RestApplicationFacet.REST_APPLICATIONCLASS_PACKAGE, pkg);
configuration.addProperty(RestApplicationFacet.REST_APPLICATIONCLASS_NAME, restApplication);
Expand All @@ -134,23 +138,23 @@ public void setup(@Option(name = "activatorType") RestActivatorType activatorTyp
@SuppressWarnings("unchecked")
@Command(value = "endpoint-from-entity", help = "Creates a REST endpoint from an existing domain @Entity object")
public void endpointFromEntity(
final PipeOut out,
@Option(name = "contentType", defaultValue = MediaType.APPLICATION_XML, completer = ContentTypeCompleter.class) String contentType,
@Option(required = false) JavaResource[] targets)
throws FileNotFoundException
final PipeOut out,
@Option(name = "contentType", defaultValue = MediaType.APPLICATION_XML, completer = ContentTypeCompleter.class) String contentType,
@Option(required = false) JavaResource[] targets)
throws FileNotFoundException
{
/*
* Make sure we have all the features we need for this to work.
*/
* Make sure we have all the features we need for this to work.
*/
if (!project.hasAllFacets(Arrays.asList(EJBFacet.class, PersistenceFacet.class)))
{
request.fire(new InstallFacets(true, JTAFacet.class, EJBFacet.class, PersistenceFacet.class));
}

if (((targets == null) || (targets.length < 1))
&& (currentResource instanceof JavaResource))
&& (currentResource instanceof JavaResource))
{
targets = new JavaResource[]{(JavaResource) currentResource};
targets = new JavaResource[] { (JavaResource) currentResource };
}

List<JavaResource> javaTargets = selectTargets(out, targets);
Expand All @@ -170,13 +174,14 @@ public void endpointFromEntity(
String idType = resolveIdType(entity);
if (!Types.isBasicType(idType))
{
ShellMessages.error(out, "Skipping class because @Id type [" + idType + "] is not supported by endpoint generation.");
ShellMessages.error(out, "Skipping class because @Id type [" + idType
+ "] is not supported by endpoint generation.");
continue;
}
String idSetterName = resolveIdSetterName(entity);

CompiledTemplateResource template = compiler.compileResource(getClass().getResourceAsStream(
"/org/jboss/forge/rest/Endpoint.jv"));
"/org/jboss/forge/rest/Endpoint.jv"));

Map<Object, Object> map = new HashMap<Object, Object>();
map.put("entity", entity);
Expand All @@ -191,16 +196,17 @@ public void endpointFromEntity(
endpoint.getAnnotation(Path.class).setStringValue("/" + getEntityTable(entity).toLowerCase());

/*
* Save the sources
*/
* Save the sources
*/
java.saveJavaSource(entity);

if (!java.getJavaResource(endpoint).exists()
|| prompt.promptBoolean("Endpoint [" + endpoint.getQualifiedName() + "] already, exists. Overwrite?"))
|| prompt.promptBoolean("Endpoint [" + endpoint.getQualifiedName() + "] already, exists. Overwrite?"))
{
java.saveJavaSource(endpoint);
ShellMessages.success(out, "Generated REST endpoint for [" + entity.getQualifiedName() + "]");
} else
}
else
ShellMessages.info(out, "Aborted endpoint generation for [" + entity.getQualifiedName() + "]");
}
}
Expand Down Expand Up @@ -241,7 +247,8 @@ private String resolveIdSetterName(JavaClass entity)
{
name = name.substring(2);
}
} else if (member instanceof Field)
}
else if (member instanceof Field)
{
type = ((Field) member).getType();
}
Expand All @@ -258,7 +265,7 @@ private String resolveIdSetterName(JavaClass entity)
// The type matches ID field's type
if (type.equals(param.getType()))
{
if (method.getName().toLowerCase().contains(name))
if (method.getName().toLowerCase().contains(name.toLowerCase()))
{
result = method.getName() + "(id)";
break;
Expand All @@ -271,17 +278,25 @@ private String resolveIdSetterName(JavaClass entity)
if (result != null)
{
break;
} else if (type != null && result == null && member.isPublic())
}
else if (type != null && result == null && member.isPublic())
{
String memberName = member.getName();
// Cheat a little if the member is public
result = member.getName() + "= id";
if (member instanceof Method && memberName.startsWith("get"))
{
memberName = memberName.substring(3);
memberName = Strings.uncapitalize(memberName);
}
result = memberName + " = id";
}
}
}

if (result == null)
{
result = "setId(id)";
throw new RuntimeException("Could not determine @Id field and setter method for @Entity [" + entity.getQualifiedName()
+ "]. Aborting.");
}

return result;
Expand All @@ -296,7 +311,8 @@ private String getEntityTable(final JavaClass entity)
if (!Strings.isNullOrEmpty(a.getStringValue("name")))
{
table = a.getStringValue("name");
} else if (!Strings.isNullOrEmpty(a.getStringValue()))
}
else if (!Strings.isNullOrEmpty(a.getStringValue()))
{
table = a.getStringValue();
}
Expand All @@ -305,12 +321,12 @@ private String getEntityTable(final JavaClass entity)
}

private List<JavaResource> selectTargets(final PipeOut out, Resource<?>[] targets)
throws FileNotFoundException
throws FileNotFoundException
{
List<JavaResource> results = new ArrayList<JavaResource>();
if (targets == null)
{
targets = new Resource<?>[]{};
targets = new Resource<?>[] {};
}
for (Resource<?> r : targets)
{
Expand All @@ -322,11 +338,13 @@ private List<JavaResource> selectTargets(final PipeOut out, Resource<?>[] target
if (entity.hasAnnotation(Entity.class))
{
results.add((JavaResource) r);
} else
}
else
{
displaySkippingResourceMsg(out, entity);
}
} else
}
else
{
displaySkippingResourceMsg(out, entity);
}
Expand All @@ -340,8 +358,7 @@ private void displaySkippingResourceMsg(final PipeOut out, final JavaSource<?> e
if (!out.isPiped())
{
ShellMessages.info(out, "Skipped non-@Entity Java resource ["
+ entity.getQualifiedName() + "]");
+ entity.getQualifiedName() + "]");
}
}
}

Expand Up @@ -22,7 +22,9 @@

package org.jboss.forge.spec.plugin;

import org.apache.log4j.pattern.RelativeTimePatternConverter;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.forge.parser.JavaParser;
import org.jboss.forge.parser.java.JavaClass;
import org.jboss.forge.parser.java.Method;
import org.jboss.forge.parser.java.Type;
Expand Down Expand Up @@ -95,7 +97,7 @@ public void testInstallAfterOtherServletMapping() throws Exception

org.jboss.forge.parser.xml.Node webXml = XMLParser.parse(web.getConfig().exportAsString());
assertEquals(1, webXml.get("servlet-mapping").size());

assertTrue(config.exportAsString().contains("servlet-mapping"));

setupRest();
Expand All @@ -110,7 +112,7 @@ public void testInstallAfterOtherServletMapping() throws Exception
assertTrue(project.hasFacet(RestWebXmlFacet.class));
RestWebXmlFacet restWebXmlFacet = project.getFacet(RestWebXmlFacet.class);
assertEquals("/rest/*", restWebXmlFacet.getServletPath());

webXml = XMLParser.parse(web.getConfig().exportAsString());
assertEquals(2, webXml.get("servlet-mapping").size());
}
Expand Down Expand Up @@ -158,6 +160,82 @@ public void testCreateEndpoint() throws Exception
.getQualifiedName());

assertTrue(java.getJavaResource(entity).getJavaSource().hasAnnotation(XmlRootElement.class));
getShell().execute("build");
}

@Test
public void testCreateEndpointNonStandardId() throws Exception
{
Project project = getProject();
JavaSourceFacet java = project.getFacet(JavaSourceFacet.class);
JavaClass entity = JavaParser.parse(JavaClass.class,
RestPluginTest.class.getResourceAsStream("User.java"));
entity.setPackage(java.getBasePackage() + ".model");
java.saveJavaSource(entity);

getShell().setCurrentResource(java.getJavaResource(entity));

setupRest();

queueInputLines("");
getShell().execute("rest endpoint-from-entity");

JavaResource resource = java.getJavaResource(java.getBasePackage() + ".rest.UserEndpoint");
JavaClass endpoint = (JavaClass) resource.getJavaSource();

assertEquals("/user", endpoint.getAnnotation(Path.class).getStringValue());
assertTrue(endpoint.toString().contains("entity.setObjectId(id);"));
getShell().execute("build");
}

@Test
public void testCreateEndpointPrimitiveNonStandardId() throws Exception
{
Project project = getProject();
JavaSourceFacet java = project.getFacet(JavaSourceFacet.class);
JavaClass entity = JavaParser.parse(JavaClass.class,
RestPluginTest.class.getResourceAsStream("User2.java"));
entity.setPackage(java.getBasePackage() + ".model");
java.saveJavaSource(entity);

getShell().setCurrentResource(java.getJavaResource(entity));

setupRest();

queueInputLines("");
getShell().execute("rest endpoint-from-entity");

JavaResource resource = java.getJavaResource(java.getBasePackage() + ".rest.User2Endpoint");
JavaClass endpoint = (JavaClass) resource.getJavaSource();

assertEquals("/user2", endpoint.getAnnotation(Path.class).getStringValue());
assertTrue(endpoint.toString().contains("entity.setObjectId(id);"));
getShell().execute("build");
}

@Test
public void testCreateEndpointPrimitiveNonStandardGetterId() throws Exception
{
Project project = getProject();
JavaSourceFacet java = project.getFacet(JavaSourceFacet.class);
JavaClass entity = JavaParser.parse(JavaClass.class,
RestPluginTest.class.getResourceAsStream("User3.java"));
entity.setPackage(java.getBasePackage() + ".model");
java.saveJavaSource(entity);

getShell().setCurrentResource(java.getJavaResource(entity));

setupRest();

queueInputLines("");
getShell().execute("rest endpoint-from-entity");

JavaResource resource = java.getJavaResource(java.getBasePackage() + ".rest.User3Endpoint");
JavaClass endpoint = (JavaClass) resource.getJavaSource();

assertEquals("/user3", endpoint.getAnnotation(Path.class).getStringValue());
assertTrue(endpoint.toString().contains("entity.setObjectId(id);"));
getShell().execute("build");
}

@Test
Expand Down
@@ -0,0 +1,81 @@
import javax.persistence.Entity;
import java.io.Serializable;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Column;
import javax.persistence.Version;
import java.lang.Override;

@Entity
public class User implements Serializable
{

@Id
private @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)
Long objectId = null;
@Version
private @Column(name = "version")
int version = 0;

public Long getObjectId()
{
return this.objectId;
}

public void setObjectId(final Long id)
{
this.objectId = id;
}

public int getVersion()
{
return this.version;
}

public void setVersion(final int version)
{
this.version = version;
}

public String toString()
{
String result = "";
if (objectId != null)
result += objectId;
return result;
}

@Override
public boolean equals(Object that)
{
if (this == that)
{
return true;
}
if (that == null)
{
return false;
}
if (getClass() != that.getClass())
{
return false;
}
if (objectId != null)
{
return objectId.equals(((User) that).objectId);
}
return super.equals(that);
}

@Override
public int hashCode()
{
if (objectId != null)
{
return objectId.hashCode();
}
return super.hashCode();
}
}

0 comments on commit 8964ab1

Please sign in to comment.