Skip to content

Commit

Permalink
Refactored out testing contracts.
Browse files Browse the repository at this point in the history
  • Loading branch information
VineetReynolds committed Feb 14, 2013
1 parent cfb5313 commit 003463f
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 148 deletions.
173 changes: 25 additions & 148 deletions src/main/java/org/jboss/forge/scaffold/html5/Html5Scaffold.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,47 +123,19 @@ public List<Resource<?>> generateIndex(String targetDir, Resource<?> template, b
for (Resource<?> resource : partialsDirectory.listResources()) {
entityNames.add(resource.getName());
}
Map root = new HashMap();
Map<String, Object> root = new HashMap<String, Object>();
root.put("entityNames", entityNames);
MetadataFacet metadata = this.project.getFacet(MetadataFacet.class);
root.put("project", metadata);

try {
Template indexTemplate = config.getTemplate("index.html.ftl");
Writer contents = new StringWriter();
indexTemplate.process(root, contents);
contents.flush();
result.add(ScaffoldUtil.createOrOverwrite(prompt, web.getWebResource("index.html"), contents.toString(), overwrite));
} catch (IOException e) {
throw new RuntimeException(e);
} catch (TemplateException e) {
throw new RuntimeException(e);
}

try {
Template appJsTemplate = config.getTemplate("scripts/app.js.ftl");
Writer contents = new StringWriter();
appJsTemplate.process(root, contents);
contents.flush();
result.add(ScaffoldUtil.createOrOverwrite(prompt, web.getWebResource("scripts/app.js"), contents.toString(),
overwrite));
} catch (IOException e) {
throw new RuntimeException(e);
} catch (TemplateException e) {
throw new RuntimeException(e);
}

try {
Template controllerTemplate = config.getTemplate("scripts/filters.js.ftl");
Writer contents = new StringWriter();
controllerTemplate.process(root, contents);
contents.flush();
result.add(ScaffoldUtil.createOrOverwrite(prompt, web.getWebResource("scripts/filters.js"), contents.toString(),
overwrite));
} catch (IOException e) {
throw new RuntimeException(e);
} catch (TemplateException e) {
throw new RuntimeException(e);
Map<String, String> projectGlobalTemplates = new HashMap<String, String>();
projectGlobalTemplates.put("index.html.ftl", "index.html");
projectGlobalTemplates.put("scripts/app.js.ftl", "scripts/app.js");
projectGlobalTemplates.put("scripts/filters.js.ftl", "scripts/filters.js");
for (String projectGlobalTemplate : projectGlobalTemplates.keySet()) {
String output = processFTL(config, root, projectGlobalTemplate);
String outputPath = projectGlobalTemplates.get(projectGlobalTemplate);
result.add(ScaffoldUtil.createOrOverwrite(prompt, web.getWebResource(outputPath), output, overwrite));
}
return result;
}
Expand All @@ -178,121 +150,37 @@ public List<Resource<?>> generateFromEntity(String targetDir, Resource<?> templa
ArrayList<Resource<?>> result = new ArrayList<Resource<?>>();
WebResourceFacet web = this.project.getFacet(WebResourceFacet.class);

Map root = new HashMap();
// TODO: Provide a 'utility' class for allowing transliteration across language naming schemes
// We need this to use contextual naming schemes instead of performing toLowerCase etc. in FTLs.
root.put("entityName", entity.getName());

ForgePropertyStyleConfig forgePropertyStyleConfig = new ForgePropertyStyleConfig();
forgePropertyStyleConfig.setProject(project);
BaseObjectInspectorConfig baseObjectInspectorConfig = new BaseObjectInspectorConfig();
baseObjectInspectorConfig.setPropertyStyle(new ForgePropertyStyle(forgePropertyStyleConfig));

PropertyTypeInspector propertyTypeInspector = new PropertyTypeInspector(baseObjectInspectorConfig);

ForgeInspector forgeInspector = new ForgeInspector(baseObjectInspectorConfig);

JpaInspectorConfig jpaInspectorConfig = new JpaInspectorConfig();
jpaInspectorConfig.setHideIds(true);
jpaInspectorConfig.setHideVersions(true);
jpaInspectorConfig.setHideTransients(true);
jpaInspectorConfig.setPropertyStyle(new ForgePropertyStyle(forgePropertyStyleConfig));
JpaInspector jpaInspector = new JpaInspector(jpaInspectorConfig);

BeanValidationInspector beanValidationInspector = new BeanValidationInspector(baseObjectInspectorConfig);

CompositeInspectorConfig compositeInspectorConfig = new CompositeInspectorConfig();
compositeInspectorConfig.setInspectors(propertyTypeInspector,forgeInspector,jpaInspector,beanValidationInspector);
CompositeInspector compositeInspector = new CompositeInspector(compositeInspectorConfig);

Element inspectionResult = compositeInspector.inspectAsDom(null, entity.getQualifiedName(), null);
Element inspectedEntity = XmlUtils.getFirstChildElement( inspectionResult );
System.out.println(XmlUtils.nodeToString(inspectedEntity, true));

Element inspectedProperty = XmlUtils.getFirstChildElement(inspectedEntity);
List<Map<String,String>> viewPropertyAttributes = new ArrayList<Map<String,String>>();
while (inspectedProperty != null) {
System.out.println(XmlUtils.nodeToString(inspectedProperty, true));
Map<String, String> propertyAttributes = XmlUtils.getAttributesAsMap(inspectedProperty);

// Canonicalize all numerical types in Java to "number" for HTML5 form input type support
String propertyType = propertyAttributes.get("type");
if (propertyType.equals(short.class.getName()) || propertyType.equals(int.class.getName())
|| propertyType.equals(long.class.getName()) || propertyType.equals(float.class.getName())
|| propertyType.equals(double.class.getName()) || propertyType.equals(Short.class.getName())
|| propertyType.equals(Integer.class.getName()) || propertyType.equals(Long.class.getName())
|| propertyType.equals(Float.class.getName()) || propertyType.equals(Double.class.getName())) {
propertyAttributes.put("type", "number");
}

// Extract simple type name of the relationship types
String manyToOneRel = propertyAttributes.get("many-to-one");
if("true".equals(manyToOneRel)){
String manyToOneType = propertyAttributes.get("type");
propertyAttributes.put("simpleType", getSimpleName(manyToOneType));
}
String oneToOneRel = propertyAttributes.get("one-to-one");
if("true".equals(oneToOneRel)){
String oneToOneType = propertyAttributes.get("type");
propertyAttributes.put("simpleType", getSimpleName(oneToOneType));
}
String oneToManyRel = propertyAttributes.get("n-to-many");
if("true".equals(oneToManyRel)){
String oneToManyType = propertyAttributes.get("parameterized-type");
propertyAttributes.put("simpleType", getSimpleName(oneToManyType));
}

// Add the property attributes into a list, made accessible as a sequence to the FTL
viewPropertyAttributes.add(propertyAttributes);
inspectedProperty = XmlUtils.getNextSiblingElement(inspectedProperty);
}
root.put("properties", viewPropertyAttributes);
System.out.println("Root:" + root);
Map<String, Object> root = new IntrospectorClient(project).inspect(entity);

// TODO: The list of template files to be processed per-entity (like detail.html.ftl and search.html.ftl) needs to
// be obtained dynamically. Another list to be processed for all entities (like index.html.ftl) also needs to be
// maintained. In short, a template should be associated with a processing directive like PER_ENTITY, ALL_ENTITIES etc.
try {
Template indexTemplate = config.getTemplate("partials/detail.html.ftl");
Writer out = new StringWriter();
indexTemplate.process(root, out);
out.flush();
result.add(ScaffoldUtil.createOrOverwrite(prompt,
web.getWebResource("/partials/" + entity.getName() + "/detail.html"), out.toString(), overwrite));
} catch (IOException e) {
throw new RuntimeException(e);
} catch (TemplateException e) {
throw new RuntimeException(e);
Map<String, String> perEntityTemplates = new HashMap<String, String>();
perEntityTemplates.put("partials/detail.html.ftl", "/partials/" + entity.getName() + "/detail.html");
perEntityTemplates.put("partials/search.html.ftl", "/partials/" + entity.getName() + "/search.html");
perEntityTemplates.put("scripts/entityModule.js.ftl", "/scripts/" + entity.getName() + "/" + entity.getName() + ".js");
for (String entityTemplate : perEntityTemplates.keySet()) {
String output = processFTL(config, root, entityTemplate);
String outputPath = perEntityTemplates.get(entityTemplate);
result.add(ScaffoldUtil.createOrOverwrite(prompt, web.getWebResource(outputPath), output, overwrite));
}

try {
Template indexTemplate = config.getTemplate("partials/search.html.ftl");
Writer out = new StringWriter();
indexTemplate.process(root, out);
out.flush();
result.add(ScaffoldUtil.createOrOverwrite(prompt,
web.getWebResource("/partials/" + entity.getName() + "/search.html"), out.toString(), overwrite));
} catch (IOException e) {
throw new RuntimeException(e);
} catch (TemplateException e) {
throw new RuntimeException(e);
}
generateIndex(targetDir, template, overwrite);
return result;
}

protected String processFTL(Configuration config, Map<String, Object> root, String inputPath) {
try {
Template indexTemplate = config.getTemplate("scripts/entityModule.js.ftl");
Template templateFile = config.getTemplate(inputPath);
Writer out = new StringWriter();
indexTemplate.process(root, out);
templateFile.process(root, out);
out.flush();
result.add(ScaffoldUtil.createOrOverwrite(prompt,
web.getWebResource("/scripts/" + entity.getName() + "/" + entity.getName() + ".js"), out.toString(),
overwrite));
return out.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (TemplateException e) {
throw new RuntimeException(e);
}
generateIndex(targetDir, template, overwrite);
return result;
}

@Override
Expand All @@ -313,15 +201,4 @@ public TemplateStrategy getTemplateStrategy() {
return null;
}

private String getSimpleName(String manyToOneType) {
JavaSourceFacet java = this.project.getFacet(JavaSourceFacet.class);
try {
JavaResource relatedResource = java.getJavaResource(manyToOneType);
return relatedResource.getJavaSource().getName();
} catch (FileNotFoundException fileEx) {
// This is not supposed to happen, since the JPA entity class/file is supposed to be present by now.
throw new RuntimeException(fileEx);
}
}

}
118 changes: 118 additions & 0 deletions src/main/java/org/jboss/forge/scaffold/html5/IntrospectorClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package org.jboss.forge.scaffold.html5;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jboss.forge.parser.java.JavaClass;
import org.jboss.forge.project.Project;
import org.jboss.forge.project.facets.JavaSourceFacet;
import org.jboss.forge.resources.java.JavaResource;
import org.jboss.forge.scaffold.html5.metawidget.inspector.ForgeInspector;
import org.jboss.forge.scaffold.html5.metawidget.inspector.propertystyle.ForgePropertyStyle;
import org.jboss.forge.scaffold.html5.metawidget.inspector.propertystyle.ForgePropertyStyleConfig;
import org.metawidget.inspector.beanvalidation.BeanValidationInspector;
import org.metawidget.inspector.composite.CompositeInspector;
import org.metawidget.inspector.composite.CompositeInspectorConfig;
import org.metawidget.inspector.impl.BaseObjectInspectorConfig;
import org.metawidget.inspector.jpa.JpaInspector;
import org.metawidget.inspector.jpa.JpaInspectorConfig;
import org.metawidget.inspector.propertytype.PropertyTypeInspector;
import org.metawidget.util.XmlUtils;
import org.w3c.dom.Element;

public class IntrospectorClient {

private Project project;

public IntrospectorClient(Project project) {
this.project = project;
}

public Map<String, Object> inspect(JavaClass entity) {
Map<String, Object> root = new HashMap<String, Object>();
// TODO: Provide a 'utility' class for allowing transliteration across language naming schemes
// We need this to use contextual naming schemes instead of performing toLowerCase etc. in FTLs.
root.put("entityName", entity.getName());

ForgePropertyStyleConfig forgePropertyStyleConfig = new ForgePropertyStyleConfig();
forgePropertyStyleConfig.setProject(this.project);
BaseObjectInspectorConfig baseObjectInspectorConfig = new BaseObjectInspectorConfig();
baseObjectInspectorConfig.setPropertyStyle(new ForgePropertyStyle(forgePropertyStyleConfig));

PropertyTypeInspector propertyTypeInspector = new PropertyTypeInspector(baseObjectInspectorConfig);

ForgeInspector forgeInspector = new ForgeInspector(baseObjectInspectorConfig);

JpaInspectorConfig jpaInspectorConfig = new JpaInspectorConfig();
jpaInspectorConfig.setHideIds(true);
jpaInspectorConfig.setHideVersions(true);
jpaInspectorConfig.setHideTransients(true);
jpaInspectorConfig.setPropertyStyle(new ForgePropertyStyle(forgePropertyStyleConfig));
JpaInspector jpaInspector = new JpaInspector(jpaInspectorConfig);

BeanValidationInspector beanValidationInspector = new BeanValidationInspector(baseObjectInspectorConfig);

CompositeInspectorConfig compositeInspectorConfig = new CompositeInspectorConfig();
compositeInspectorConfig.setInspectors(propertyTypeInspector, forgeInspector, jpaInspector, beanValidationInspector);
CompositeInspector compositeInspector = new CompositeInspector(compositeInspectorConfig);

Element inspectionResult = compositeInspector.inspectAsDom(null, entity.getQualifiedName(), (String[]) null);
Element inspectedEntity = XmlUtils.getFirstChildElement(inspectionResult);
System.out.println(XmlUtils.nodeToString(inspectedEntity, true));

Element inspectedProperty = XmlUtils.getFirstChildElement(inspectedEntity);
List<Map<String, String>> viewPropertyAttributes = new ArrayList<Map<String, String>>();
while (inspectedProperty != null) {
System.out.println(XmlUtils.nodeToString(inspectedProperty, true));
Map<String, String> propertyAttributes = XmlUtils.getAttributesAsMap(inspectedProperty);

// Canonicalize all numerical types in Java to "number" for HTML5 form input type support
String propertyType = propertyAttributes.get("type");
if (propertyType.equals(short.class.getName()) || propertyType.equals(int.class.getName())
|| propertyType.equals(long.class.getName()) || propertyType.equals(float.class.getName())
|| propertyType.equals(double.class.getName()) || propertyType.equals(Short.class.getName())
|| propertyType.equals(Integer.class.getName()) || propertyType.equals(Long.class.getName())
|| propertyType.equals(Float.class.getName()) || propertyType.equals(Double.class.getName())) {
propertyAttributes.put("type", "number");
}

// Extract simple type name of the relationship types
String manyToOneRel = propertyAttributes.get("many-to-one");
if ("true".equals(manyToOneRel)) {
String manyToOneType = propertyAttributes.get("type");
propertyAttributes.put("simpleType", getSimpleName(manyToOneType));
}
String oneToOneRel = propertyAttributes.get("one-to-one");
if ("true".equals(oneToOneRel)) {
String oneToOneType = propertyAttributes.get("type");
propertyAttributes.put("simpleType", getSimpleName(oneToOneType));
}
String oneToManyRel = propertyAttributes.get("n-to-many");
if ("true".equals(oneToManyRel)) {
String oneToManyType = propertyAttributes.get("parameterized-type");
propertyAttributes.put("simpleType", getSimpleName(oneToManyType));
}

// Add the property attributes into a list, made accessible as a sequence to the FTL
viewPropertyAttributes.add(propertyAttributes);
inspectedProperty = XmlUtils.getNextSiblingElement(inspectedProperty);
}
root.put("properties", viewPropertyAttributes);
System.out.println("Root:" + root);
return root;
}

private String getSimpleName(String manyToOneType) {
JavaSourceFacet java = this.project.getFacet(JavaSourceFacet.class);
try {
JavaResource relatedResource = java.getJavaResource(manyToOneType);
return relatedResource.getJavaSource().getName();
} catch (FileNotFoundException fileEx) {
// This is not supposed to happen, since the JPA entity class/file is supposed to be present by now.
throw new RuntimeException(fileEx);
}
}
}

0 comments on commit 003463f

Please sign in to comment.