Skip to content

Commit

Permalink
FORGE-1076 Added support to detect conflicting top-level @paths.
Browse files Browse the repository at this point in the history
This is done through a JavaResourceVisitor that verifies whether
existing JAX-RS resource classes contain @path annotation values
that match the one for the Resource being created.

The visitor also verifies whether the matching @path is for an
existing JAX-RS resource that will eventually be overwritten.
  • Loading branch information
VineetReynolds committed Aug 3, 2013
1 parent 2a8c58c commit ced1c2c
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.jboss.forge.resources.Resource;
import org.jboss.forge.resources.java.JavaResource;
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.Command;
Expand Down Expand Up @@ -92,7 +93,13 @@ public class RestPlugin implements Plugin

@Inject
private ShellPrompt prompt;


@Inject
private ShellPrintWriter writer;

@Inject
private RestResourceTypeVisitor resourceTypeVisitor;

@Inject
@ProjectScoped
Configuration configuration;
Expand Down Expand Up @@ -171,11 +178,12 @@ public void endpointFromEntity(
String entityTable = getEntityTable(entity);
String selectExpression = getSelectExpression(entity, entityTable);
String idClause = getIdClause(entity, entityTable);
String resourcePath = getResourcePath(java, entityTable);
map.put("persistenceUnitName", persistenceUnitName);
map.put("entityTable", entityTable);
map.put("selectExpression", selectExpression);
map.put("idClause", idClause);
map.put("resourcePath", entityTable.toLowerCase() + "s");
map.put("resourcePath", resourcePath);

Writer output = new StringWriter();
try
Expand All @@ -195,14 +203,7 @@ public void endpointFromEntity(

JavaClass resource = JavaParser.parse(JavaClass.class, output.toString());
resource.addImport(entity.getQualifiedName());
if (project.hasFacet(RestApplicationFacet.class))
{
resource.setPackage(configuration.getString(REST_APPLICATIONCLASS_PACKAGE));
}
else
{
resource.setPackage(java.getBasePackage() + ".rest");
}
resource.setPackage(getPackageName(java));

/*
* Save the sources
Expand All @@ -225,6 +226,50 @@ public void endpointFromEntity(
}
}

public String getPackageName(final JavaSourceFacet java)
{
if (project.hasFacet(RestApplicationFacet.class))
{
return configuration.getString(REST_APPLICATIONCLASS_PACKAGE);
}
else
{
return java.getBasePackage() + ".rest";
}
}

private String getResourcePath(JavaSourceFacet java, String entityTable)
{
String proposedQualifiedClassName = getPackageName(java) + "." + entityTable + "Endpoint";
String proposedResourcePath = "/" + entityTable.toLowerCase() + "s";
resourceTypeVisitor.setFound(false);
resourceTypeVisitor.setProposedPath(proposedResourcePath);
while (true)
{
java.visitJavaSources(resourceTypeVisitor);
if (resourceTypeVisitor.isFound())
{
if (proposedQualifiedClassName.equals(resourceTypeVisitor.getQualifiedClassNameForMatch()))
{
// The class might be overwritten later, so break out
break;
}
ShellMessages.warn(writer, "The @Path " + proposedResourcePath + " conflicts with an existing @Path.");
String computedPath = proposedResourcePath.startsWith("/") ? "forge" + proposedResourcePath : "forge/"
+ proposedResourcePath;
proposedResourcePath = prompt.prompt("Provide a different URI path value for the generated resource.",
computedPath);
resourceTypeVisitor.setProposedPath(proposedResourcePath);
resourceTypeVisitor.setFound(false);
}
else
{
break;
}
}
return proposedResourcePath;
}

private String resolveIdType(JavaClass entity)
{
for (Member<JavaClass, ?> member : entity.getMembers())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.jboss.forge.spec.javaee.rest;

import java.io.FileNotFoundException;

import org.jboss.forge.parser.java.JavaSource;
import org.jboss.forge.resources.java.JavaResource;
import org.jboss.forge.resources.java.JavaResourceVisitor;

class RestResourceTypeVisitor implements JavaResourceVisitor
{
private String proposedPath;
private boolean found;
private JavaSource<?> javaSource;

public void setProposedPath(String proposedPath)
{
this.proposedPath = proposedPath;
}

public String getQualifiedClassNameForMatch()
{
if(javaSource != null)
{
return javaSource.getQualifiedName();
}
return null;
}

public boolean isFound()
{
return found;
}

public void setFound(boolean found)
{
this.found = found;
}

@Override
public void visit(JavaResource javaResource)
{
if (!found)
{
try
{
if (javaResource.getJavaSource().getAnnotation("javax.ws.rs.Path") != null)
{
String path = javaResource.getJavaSource().getAnnotation("javax.ws.rs.Path")
.getStringValue();
String absolutePath = path.endsWith("/") ? path.substring(0,path.lastIndexOf('/')) : path;
if (absolutePath.equals(proposedPath))
{
javaSource = javaResource.getJavaSource();
found = true;
}
}
}
catch (FileNotFoundException e)
{
throw new RuntimeException(e);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import javax.ws.rs.core.UriBuilder;
*
*/
@Stateless
@Path("/${resourcePath}")
@Path("${resourcePath}")
public class ${entityTable}Endpoint
{
@PersistenceContext(unitName="${persistenceUnitName}")
Expand Down

0 comments on commit ced1c2c

Please sign in to comment.