From b6dd963faee603301515e9d6e49a0995674de608 Mon Sep 17 00:00:00 2001 From: "Lincoln Baxter, III" Date: Wed, 23 Apr 2014 15:48:48 -0400 Subject: [PATCH] FORGE-1745: Fix crazy Templates API (Breaks backwards compatibility) And solve FreemarkerTemplate proxy issue. --- .../rest/generator/dto/DTOClassBuilder.java | 28 ++++---- .../impl/EntityBasedResourceGenerator.java | 8 +-- .../RootAndNestedDTOResourceGenerator.java | 14 ++-- .../addon/resource/DirectoryResourceImpl.java | 11 ++- templates/README.asciidoc | 19 +++--- .../addon/templates/TemplateFactory.java | 23 +++++++ .../addon/templates/TemplateProcessor.java | 28 -------- .../templates/TemplateProcessorFactory.java | 37 ---------- .../freemarker/FreemarkerTemplate.java | 20 +++--- .../FreemarkerTemplateGenerator.java | 66 ++---------------- .../freemarker/FreemarkerTemplateImpl.java | 67 +++++++++++++++++++ .../templates/freemarker/ResourceId.java | 35 ++++++++++ .../freemarker/ResourceTemplateLoader.java | 54 +++++++-------- .../addon/templates/TemplateFactoryImpl.java | 44 ++++++++++++ .../TemplateProcessorFactoryImpl.java | 57 ---------------- .../templates/TemplateProcessorImpl.java | 65 ------------------ .../addon/templates/AbstractTemplate.java | 16 ++--- .../jboss/forge/addon/templates/Template.java | 24 ++++--- .../addon/templates/TemplateGenerator.java | 34 ++-------- templates/tests/pom.xml | 5 ++ .../addon/templates/TemplateTestCase.java | 40 +++++------ 21 files changed, 303 insertions(+), 392 deletions(-) create mode 100644 templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateFactory.java delete mode 100644 templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateProcessor.java delete mode 100644 templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorFactory.java create mode 100644 templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplateImpl.java create mode 100644 templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/ResourceId.java create mode 100644 templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateFactoryImpl.java delete mode 100644 templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorFactoryImpl.java delete mode 100644 templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorImpl.java diff --git a/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/dto/DTOClassBuilder.java b/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/dto/DTOClassBuilder.java index 8c1789f5f6..cce6c9d4d2 100644 --- a/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/dto/DTOClassBuilder.java +++ b/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/dto/DTOClassBuilder.java @@ -17,8 +17,8 @@ import javax.xml.bind.annotation.XmlRootElement; import org.jboss.forge.addon.resource.ResourceFactory; -import org.jboss.forge.addon.templates.TemplateProcessor; -import org.jboss.forge.addon.templates.TemplateProcessorFactory; +import org.jboss.forge.addon.templates.Template; +import org.jboss.forge.addon.templates.TemplateFactory; import org.jboss.forge.addon.templates.freemarker.FreemarkerTemplate; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.JavaClass; @@ -46,25 +46,27 @@ public class DTOClassBuilder private MethodSource assembleJPA; private MethodSource copyCtor; private final Property idProperty; - private final TemplateProcessor initializeJPAEntityFromId; - private final TemplateProcessor assembleCollection; - private final TemplateProcessor initializeNestedDTOCollection; + private final Template initializeJPAEntityFromId; + private final Template assembleCollection; + private final Template initializeNestedDTOCollection; public DTOClassBuilder(JavaClass entity, Property idProperty, boolean topLevel, - TemplateProcessorFactory processorFactory, ResourceFactory resourceFactory) + TemplateFactory templateFactory, ResourceFactory resourceFactory) { this.entity = entity; this.idProperty = idProperty; this.topLevel = topLevel; this.copyCtorBuilder = new StringBuilder(); this.assembleJPABuilder = new StringBuilder(); - this.initializeJPAEntityFromId = processorFactory.fromTemplate(new FreemarkerTemplate(resourceFactory - .create(getClass().getResource("InitializeJPAEntityFromId.jv")))); - this.assembleCollection = processorFactory.fromTemplate(new FreemarkerTemplate(resourceFactory.create(getClass() - .getResource("AssembleCollection.jv")))); - - this.initializeNestedDTOCollection = processorFactory.fromTemplate(new FreemarkerTemplate(resourceFactory - .create(getClass().getResource("InitializeNestedDTOCollection.jv")))); + this.initializeJPAEntityFromId = templateFactory.create( + resourceFactory.create(getClass().getResource("InitializeJPAEntityFromId.jv")), + FreemarkerTemplate.class); + this.assembleCollection = templateFactory.create( + resourceFactory.create(getClass().getResource("AssembleCollection.jv")), FreemarkerTemplate.class); + + this.initializeNestedDTOCollection = templateFactory.create( + resourceFactory.create(getClass().getResource("InitializeNestedDTOCollection.jv")), + FreemarkerTemplate.class); initName(); initClassStructure(); diff --git a/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/impl/EntityBasedResourceGenerator.java b/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/impl/EntityBasedResourceGenerator.java index dca2fcdd07..da50fe4533 100644 --- a/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/impl/EntityBasedResourceGenerator.java +++ b/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/impl/EntityBasedResourceGenerator.java @@ -22,8 +22,8 @@ import org.jboss.forge.addon.projects.Project; import org.jboss.forge.addon.resource.Resource; import org.jboss.forge.addon.resource.ResourceFactory; -import org.jboss.forge.addon.templates.TemplateProcessor; -import org.jboss.forge.addon.templates.TemplateProcessorFactory; +import org.jboss.forge.addon.templates.Template; +import org.jboss.forge.addon.templates.TemplateFactory; import org.jboss.forge.addon.templates.freemarker.FreemarkerTemplate; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.JavaClassSource; @@ -34,7 +34,7 @@ public class EntityBasedResourceGenerator implements RestResourceGenerator { @Inject - TemplateProcessorFactory processorFactory; + TemplateFactory templateFactory; @Inject ResourceFactory resourceFactory; @@ -73,7 +73,7 @@ public List generateFrom(RestGenerationContext context) throws map.put("resourcePath", resourcePath); Resource templateResource = resourceFactory.create(getClass().getResource("Endpoint.jv")); - TemplateProcessor processor = processorFactory.fromTemplate(new FreemarkerTemplate(templateResource)); + Template processor = templateFactory.create(templateResource, FreemarkerTemplate.class); String output = processor.process(map); JavaClassSource resource = Roaster.parse(JavaClassSource.class, output); resource.addImport(entity.getQualifiedName()); diff --git a/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/impl/RootAndNestedDTOResourceGenerator.java b/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/impl/RootAndNestedDTOResourceGenerator.java index 2f73ef2738..9829f1096b 100644 --- a/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/impl/RootAndNestedDTOResourceGenerator.java +++ b/javaee/impl/src/main/java/org/jboss/forge/addon/javaee/rest/generator/impl/RootAndNestedDTOResourceGenerator.java @@ -35,8 +35,8 @@ import org.jboss.forge.addon.resource.Resource; import org.jboss.forge.addon.resource.ResourceException; import org.jboss.forge.addon.resource.ResourceFactory; -import org.jboss.forge.addon.templates.TemplateProcessor; -import org.jboss.forge.addon.templates.TemplateProcessorFactory; +import org.jboss.forge.addon.templates.Template; +import org.jboss.forge.addon.templates.TemplateFactory; import org.jboss.forge.addon.templates.freemarker.FreemarkerTemplate; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.Field; @@ -49,13 +49,13 @@ /** * A JAX-RS resource generator that creates root and nested DTOs for JPA entities, and references these DTOs in the * created REST resources. - * + * * @author George Gastaldi */ public class RootAndNestedDTOResourceGenerator implements RestResourceGenerator { @Inject - TemplateProcessorFactory processorFactory; + TemplateFactory templateFactory; @Inject ResourceFactory resourceFactory; @@ -95,7 +95,7 @@ public List generateFrom(RestGenerationContext context) throws map.put("resourcePath", resourcePath); Resource templateResource = resourceFactory.create(getClass().getResource("EndpointWithDTO.jv")); - TemplateProcessor processor = processorFactory.fromTemplate(new FreemarkerTemplate(templateResource)); + Template processor = templateFactory.create(templateResource, FreemarkerTemplate.class); String output = processor.process(map); JavaClassSource resource = Roaster.parse(JavaClassSource.class, output); resource.addImport(rootDto.getQualifiedName()); @@ -109,7 +109,7 @@ public List generateFrom(RestGenerationContext context) throws /** * Creates a collection of DTOs for the provided JPA entity, and any JPA entities referenced in the JPA entity. - * + * * @param entity The JPA entity for which DTOs are to be generated * @param dtoPackage The Java package in which the DTOs are to be created * @return The {@link DTOCollection} containing the DTOs created for the JPA entity. @@ -136,7 +136,7 @@ private JavaClassSource generatedDTOGraphForEntity(Project project, JavaClass Property idProperty = parseIdPropertyForJPAEntity(entity); - DTOClassBuilder dtoClassBuilder = new DTOClassBuilder(entity, idProperty, topLevel, processorFactory, + DTOClassBuilder dtoClassBuilder = new DTOClassBuilder(entity, idProperty, topLevel, templateFactory, resourceFactory) .setPackage(dtoPackage) .setEmbeddedType(isEmbeddedType); diff --git a/resources/impl/src/main/java/org/jboss/forge/addon/resource/DirectoryResourceImpl.java b/resources/impl/src/main/java/org/jboss/forge/addon/resource/DirectoryResourceImpl.java index 1afa5089c1..91e2db800d 100644 --- a/resources/impl/src/main/java/org/jboss/forge/addon/resource/DirectoryResourceImpl.java +++ b/resources/impl/src/main/java/org/jboss/forge/addon/resource/DirectoryResourceImpl.java @@ -28,6 +28,8 @@ public class DirectoryResourceImpl extends AbstractFileResource ---- == Features -TemplateProcessorFactory for template processing:: -Allows a template to be processed by replacing the variables with the provided parameters +TemplateFactory for template creation:: +Allows a Template to be created, which will replace its template's variables with the provided parameters + [source,java] ---- -@Inject private TemplateProcessorFactory factory; +@Inject private TemplateFactory factory; ... FileResource resource = ...; // A file resource containing "Hello ${name}" -Template template = new FreemarkerTemplate(resource); // Mark this resource as a Freemarker template -TemplateProcessor processor = factory.fromTemplate(template); -Map params = new HashMap(); //Could be a POJO also. +Template template = factory.create(resource, FreemarkerTemplate.class); // Create a freemarker template for the given Resource +Map params = new HashMap(); //Could also be a POJO also. params.put("name", "JBoss Forge"); -String output = processor.process(params); // should return "Hello JBoss Forge". +String output = template.process(params); // should return "Hello JBoss Forge". ---- + [TIP] ==== -If your addon uses a container that does not support "@Inject" annotations, services such as the `TemplateProcessorFactory` may also be +If your addon uses a container that does not support "@Inject" annotations, services such as the `TemplateFactory` may also be accessed via the `AddonRegistry`: ---- -Imported imported = addonRegistry.getServices(TemplateProcessorFactory.class); -TemplateProcessorFactory factory = imported.get(); +Imported imported = addonRegistry.getServices(TemplateProcessorFactory.class); +TemplateFactory factory = imported.get(); ---- ==== diff --git a/templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateFactory.java b/templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateFactory.java new file mode 100644 index 0000000000..87b98c5b32 --- /dev/null +++ b/templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateFactory.java @@ -0,0 +1,23 @@ +/** + * 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.addon.templates; + +import org.jboss.forge.addon.resource.Resource; + +/** + * Creates a {@link TemplateProcessor} based on a {@link Template} + * + * @author George Gastaldi + * @author Lincoln Baxter, III + */ +public interface TemplateFactory +{ + /** + * Create a {@link TemplateProcessor} for the supplied {@link Resource} and {@link Template} type. + */ + Template create(Resource template, Class type); +} diff --git a/templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateProcessor.java b/templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateProcessor.java deleted file mode 100644 index 02fad5c165..0000000000 --- a/templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateProcessor.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 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.addon.templates; - -import java.io.IOException; -import java.io.Writer; - -/** - * Process a template - * - * @author George Gastaldi - */ -public interface TemplateProcessor -{ - /** - * Returns a {@link String} - */ - String process(Object dataModel) throws IOException; - - /** - * Writes the output to the {@link Writer} - */ - void process(Object dataModel, Writer output) throws IOException; -} diff --git a/templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorFactory.java b/templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorFactory.java deleted file mode 100644 index 40d0d9120a..0000000000 --- a/templates/api/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * 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.addon.templates; - -import org.jboss.forge.addon.resource.Resource; - -/** - * Creates a {@link TemplateProcessor} based on a {@link Template} - * - * @author George Gastaldi - */ -public interface TemplateProcessorFactory -{ - /** - * Create a {@link TemplateProcessor} for the supplied {@link Template}. The created TemplateProcessor is associated - * with a template engine, and can be provided with a data model to eventually produce some output. - * - * @param template The template for which the processor is to be created - * @return A {@link TemplateProcessor} instance - */ - TemplateProcessor fromTemplate(Template template); - - /** - * Create a {@link TemplateProcessor} for the supplied {@link Resource}. The created TemplateProcessor is associated - * with a template engine, and can be provided with a data model to eventually produce some output. - * - * @deprecated Deprecated after Forge 2.1.1. Use the method requiring {@link Template} instances instead. - * @param template The template for which the processor is to be created - * @return A {@link TemplateProcessor} instance - */ - @Deprecated - TemplateProcessor fromTemplate(Resource template); -} diff --git a/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplate.java b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplate.java index ce6b98ac8e..afd84b3f63 100644 --- a/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplate.java +++ b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplate.java @@ -1,19 +1,17 @@ package org.jboss.forge.addon.templates.freemarker; -import org.jboss.forge.addon.resource.Resource; -import org.jboss.forge.addon.templates.AbstractTemplate; +import org.jboss.forge.addon.templates.Template; /** - * An abstract representation of a Freemarker template. Consumers of this class create instances of it with - * {@link Resource} instances to wrap Freemarker template resources. This class is used to distinguish Freemarker - * templates from other templates. - * + * A Freemarker {@link Template}. + * * @author Vineet Reynolds + * @author Lincoln Baxter, III */ -public class FreemarkerTemplate extends AbstractTemplate +public interface FreemarkerTemplate extends Template { - public FreemarkerTemplate(Resource resource) - { - super(resource); - } + /** + * Get the Freemarker engine template Configuration. + */ + public freemarker.template.Configuration getFreemarkerConfig(); } diff --git a/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplateGenerator.java b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplateGenerator.java index 9a8e4f24cc..e8902dedec 100644 --- a/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplateGenerator.java +++ b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplateGenerator.java @@ -7,9 +7,6 @@ package org.jboss.forge.addon.templates.freemarker; -import java.io.IOException; -import java.io.Writer; - import javax.inject.Inject; import javax.inject.Singleton; @@ -17,80 +14,27 @@ import org.jboss.forge.addon.templates.Template; import org.jboss.forge.addon.templates.TemplateGenerator; -import freemarker.template.TemplateException; - /** * A Freemarker implementation of a {@link TemplateGenerator} - * + * * @author George Gastaldi */ @Singleton public class FreemarkerTemplateGenerator implements TemplateGenerator { - private freemarker.template.Configuration freemarkerConfig; - @Inject private ResourceTemplateLoader loader; @Override - public void process(Object dataModel, Template template, Writer writer) throws IOException - { - String id = loader.register(template.getResource()); - try - { - freemarker.template.Template templateFile = getFreemarkerConfig().getTemplate(id); - templateFile.process(dataModel, writer); - writer.flush(); - } - catch (TemplateException e) - { - throw new RuntimeException(e); - } - finally - { - loader.dispose(id); - } - } - - @Override - public void process(Object dataModel, Resource template, Writer writer) throws IOException + public boolean handles(Class type) { - String id = loader.register(template); - try - { - freemarker.template.Template templateFile = getFreemarkerConfig().getTemplate(id); - templateFile.process(dataModel, writer); - writer.flush(); - } - catch (TemplateException e) - { - throw new RuntimeException(e); - } - finally - { - loader.dispose(id); - } + return FreemarkerTemplate.class.isAssignableFrom(type); } @Override - public boolean handles(Template template) + public Template create(Resource template, Class type) { - return template instanceof FreemarkerTemplate; + return new FreemarkerTemplateImpl(loader, template); } - @Override - public boolean handles(Resource template) - { - return true; - } - - public freemarker.template.Configuration getFreemarkerConfig() - { - if (freemarkerConfig == null) - { - freemarkerConfig = new freemarker.template.Configuration(); - freemarkerConfig.setTemplateLoader(loader); - } - return freemarkerConfig; - } } diff --git a/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplateImpl.java b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplateImpl.java new file mode 100644 index 0000000000..77641f3290 --- /dev/null +++ b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/FreemarkerTemplateImpl.java @@ -0,0 +1,67 @@ +package org.jboss.forge.addon.templates.freemarker; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; + +import org.jboss.forge.addon.resource.Resource; +import org.jboss.forge.addon.templates.AbstractTemplate; + +import freemarker.template.TemplateException; + +/** + * An abstract representation of a Freemarker template. Consumers of this class create instances of it with + * {@link Resource} instances to wrap Freemarker template resources. This class is used to distinguish Freemarker + * templates from other templates. + * + * @author Vineet Reynolds + * @author Lincoln Baxter, III + */ +class FreemarkerTemplateImpl extends AbstractTemplate implements FreemarkerTemplate +{ + private final freemarker.template.Configuration freemarkerConfig; + private final ResourceTemplateLoader loader; + + public FreemarkerTemplateImpl(ResourceTemplateLoader loader, Resource resource) + { + super(resource); + this.loader = loader; + + freemarkerConfig = new freemarker.template.Configuration(); + freemarkerConfig.setTemplateLoader(loader); + } + + @Override + public String process(Object model) throws IOException + { + StringWriter writer = new StringWriter(); + process(model, writer); + return writer.toString(); + } + + @Override + public void process(Object model, Writer output) throws IOException + { + String id = loader.register(this.getResource()); + try + { + freemarker.template.Template templateFile = getFreemarkerConfig().getTemplate(id); + templateFile.process(model, output); + output.flush(); + } + catch (TemplateException e) + { + throw new RuntimeException(e); + } + finally + { + loader.dispose(id); + } + } + + @Override + public freemarker.template.Configuration getFreemarkerConfig() + { + return freemarkerConfig; + } +} diff --git a/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/ResourceId.java b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/ResourceId.java new file mode 100644 index 0000000000..6352ee0ca0 --- /dev/null +++ b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/ResourceId.java @@ -0,0 +1,35 @@ +/* + * Copyright 2014 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.addon.templates.freemarker; + +import org.jboss.forge.addon.resource.Resource; + +/** + * @author Lincoln Baxter, III + */ +class ResourceId +{ + private final Resource resource; + private final String id; + + public ResourceId(Resource resource) + { + super(); + this.id = resource.getName().toString(); + this.resource = resource; + } + + public String getId() + { + return id; + } + + public Resource getResource() + { + return resource; + } +} \ No newline at end of file diff --git a/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/ResourceTemplateLoader.java b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/ResourceTemplateLoader.java index 7ce9e8ae60..0627bbb824 100644 --- a/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/ResourceTemplateLoader.java +++ b/templates/freemarker/src/main/java/org/jboss/forge/addon/templates/freemarker/ResourceTemplateLoader.java @@ -11,6 +11,7 @@ import java.io.InputStreamReader; import java.io.Reader; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import javax.inject.Inject; @@ -24,13 +25,14 @@ /** * Loader for Resource objects - * + * * @author George Gastaldi + * @author Lincoln Baxter, III */ @Singleton public class ResourceTemplateLoader implements StatefulTemplateLoader { - private Map resourceMap = new ConcurrentHashMap(); + private final Map resourceMap = new ConcurrentHashMap<>(); /** * Needed for includes @@ -41,8 +43,8 @@ public class ResourceTemplateLoader implements StatefulTemplateLoader String register(Resource resource) { ResourceId resourceId = generateResourceId(resource); - resourceMap.put(resourceId.id, resourceId); - return resourceId.id; + resourceMap.put(resourceId.getId(), resourceId); + return resourceId.getId(); } void dispose(String id) @@ -53,26 +55,38 @@ void dispose(String id) @Override public Object findTemplateSource(String name) throws IOException { - ResourceId resource = resourceMap.get(name); - if (resource == null) + ResourceId id = resourceMap.get(name); + if (id == null) + { + for (Entry entry : resourceMap.entrySet()) + { + if (name.startsWith(entry.getKey())) + { + id = entry.getValue(); + break; + } + } + } + + if (id == null) { Resource includedResource = resourceFactory.create(name); if (includedResource != null && includedResource.exists()) { - resource = generateResourceId(includedResource); + id = generateResourceId(includedResource); } } - return resource; + return id; } @Override public long getLastModified(Object templateSource) { ResourceId resourceId = (ResourceId) templateSource; - Resource resource = resourceId.resource; + Resource resource = resourceId.getResource(); if (resource instanceof FileResource) { - return ((FileResource) resource).getUnderlyingResourceObject().lastModified(); + return ((FileResource) resource).getLastModified(); } return 0L; } @@ -81,14 +95,14 @@ public long getLastModified(Object templateSource) public Reader getReader(Object templateSource, String encoding) throws IOException { ResourceId resourceId = (ResourceId) templateSource; - return new InputStreamReader(resourceId.resource.getResourceInputStream(), encoding); + return new InputStreamReader(resourceId.getResource().getResourceInputStream(), encoding); } @Override public void closeTemplateSource(Object templateSource) throws IOException { ResourceId resourceId = (ResourceId) templateSource; - dispose(resourceId.id); + dispose(resourceId.getId()); } @Override @@ -99,21 +113,7 @@ public void resetState() private ResourceId generateResourceId(Resource resource) { - String id = resource.getName(); - return new ResourceId(id, resource); - } - - private static class ResourceId - { - final String id; - final Resource resource; - - ResourceId(String id, Resource resource) - { - super(); - this.id = id; - this.resource = resource; - } + return new ResourceId(resource); } } diff --git a/templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateFactoryImpl.java b/templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateFactoryImpl.java new file mode 100644 index 0000000000..b6e1455ce3 --- /dev/null +++ b/templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateFactoryImpl.java @@ -0,0 +1,44 @@ +/** + * 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.addon.templates; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jboss.forge.addon.resource.Resource; +import org.jboss.forge.furnace.services.Imported; +import org.jboss.forge.furnace.util.Assert; + +/** + * + * @author George Gastaldi + * @author Lincoln Baxter, III + */ +@Singleton +public class TemplateFactoryImpl implements TemplateFactory +{ + @Inject + private Imported generators; + + @Override + public Template create(Resource template, Class type) + { + Assert.notNull(template, "Template resource cannot be null"); + Assert.isTrue(template.exists(), "Template does not exist: " + template); + + for (TemplateGenerator generator : generators) + { + if (generator.handles(type)) + { + return generator.create(template, type); + } + } + + return null; + } +} diff --git a/templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorFactoryImpl.java b/templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorFactoryImpl.java deleted file mode 100644 index 0eb294db31..0000000000 --- a/templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorFactoryImpl.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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.addon.templates; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import org.jboss.forge.addon.resource.Resource; -import org.jboss.forge.furnace.services.Imported; -import org.jboss.forge.furnace.util.Assert; - -/** - * - * @author George Gastaldi - */ -@Singleton -public class TemplateProcessorFactoryImpl implements TemplateProcessorFactory -{ - @Inject - private Imported generators; - - @Override - public TemplateProcessor fromTemplate(Template template) - { - Assert.notNull(template, "Template resource cannot be null"); - Assert.isTrue(template.exists(), "Template does not exist: " + template); - for (TemplateGenerator generator : generators) - { - if (generator.handles(template)) - { - return new TemplateProcessorImpl(generator, template); - } - } - throw new IllegalStateException("No generator found for [" + template + "]"); - } - - @SuppressWarnings("deprecation") - @Override - public TemplateProcessor fromTemplate(Resource template) - { - Assert.notNull(template, "Template resource cannot be null"); - Assert.isTrue(template.exists(), "Template does not exist: " + template); - for (TemplateGenerator generator : generators) - { - if (generator.handles(template)) - { - return new TemplateProcessorImpl(generator, template); - } - } - throw new IllegalStateException("No generator found for [" + template + "]"); - } -} diff --git a/templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorImpl.java b/templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorImpl.java deleted file mode 100644 index 67c778955a..0000000000 --- a/templates/impl/src/main/java/org/jboss/forge/addon/templates/TemplateProcessorImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 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.addon.templates; - -import org.jboss.forge.addon.resource.Resource; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; - -/** - * {@link TemplateProcessor} implementation - * - * @author George Gastaldi - */ -public class TemplateProcessorImpl implements TemplateProcessor -{ - private final TemplateGenerator generator; - private Template template; - private Resource resource; - - TemplateProcessorImpl(TemplateGenerator generator, Template template) - { - super(); - this.generator = generator; - this.template = template; - } - - /** - * @deprecated Deprecated after Forge 2.1.1. Use the {@link Template} based constructor instead. - */ - TemplateProcessorImpl(TemplateGenerator generator, Resource resource) - { - super(); - this.generator = generator; - this.resource = resource; - } - - @Override - public String process(Object dataModel) throws IOException - { - StringWriter writer = new StringWriter(); - process(dataModel, writer); - return writer.toString(); - } - - @SuppressWarnings("deprecation") - @Override - public void process(Object dataModel, Writer output) throws IOException - { - if (template != null) - { - generator.process(dataModel, template, output); - } - else if (resource != null) - { - generator.process(dataModel, resource, output); - } - } -} \ No newline at end of file diff --git a/templates/spi/src/main/java/org/jboss/forge/addon/templates/AbstractTemplate.java b/templates/spi/src/main/java/org/jboss/forge/addon/templates/AbstractTemplate.java index 55e88a66c4..c1a46e2f28 100644 --- a/templates/spi/src/main/java/org/jboss/forge/addon/templates/AbstractTemplate.java +++ b/templates/spi/src/main/java/org/jboss/forge/addon/templates/AbstractTemplate.java @@ -6,8 +6,9 @@ /** * An abstract representation of a template. Concrete instances of this class are used to wrap {@link Resource} * instances representing template resources. - * + * * @author Vineet Reynolds + * @author Lincoln Baxter, III */ public abstract class AbstractTemplate implements Template { @@ -22,21 +23,12 @@ protected AbstractTemplate(Resource resource) /** * Fetches the underlying resource associated with this Template instance. - * + * * @return the resource associated with this instance */ + @Override public Resource getResource() { return resource; } - - /** - * Indicates whether the template exists or not, usually through it's underlying resource. - * - * @return whether the template exists or not - */ - public boolean exists() - { - return resource.exists(); - } } diff --git a/templates/spi/src/main/java/org/jboss/forge/addon/templates/Template.java b/templates/spi/src/main/java/org/jboss/forge/addon/templates/Template.java index a133aad20f..9bc4eb41b4 100644 --- a/templates/spi/src/main/java/org/jboss/forge/addon/templates/Template.java +++ b/templates/spi/src/main/java/org/jboss/forge/addon/templates/Template.java @@ -1,26 +1,30 @@ package org.jboss.forge.addon.templates; +import java.io.IOException; +import java.io.Writer; + import org.jboss.forge.addon.resource.Resource; /** - * An abstract representation of a template. Concrete instances of this class are used to wrap {@link Resource} - * instances representing template resources. - * + * A representation of a {@link Template} that knows how to render a specific {@link Resource} instance. + * * @author Vineet Reynolds + * @author Lincoln Baxter, III */ public interface Template { /** - * Fetches the underlying resource associated with this Template instance. - * - * @return the resource associated with this instance + * Fetches the underlying {@link Resource} associated with this {@link Template} instance. */ Resource getResource(); /** - * Indicates whether the template exists or not, usually through it's underlying resource. - * - * @return whether the template exists or not + * Process the given model and return a {@link String} result containing {@link Template} output. + */ + public String process(Object model) throws IOException; + + /** + * Process the given model and write the {@link Template} output to the given {@link Writer}. */ - boolean exists(); + public void process(Object model, Writer output) throws IOException; } diff --git a/templates/spi/src/main/java/org/jboss/forge/addon/templates/TemplateGenerator.java b/templates/spi/src/main/java/org/jboss/forge/addon/templates/TemplateGenerator.java index 656b819d99..50ca7ed21e 100644 --- a/templates/spi/src/main/java/org/jboss/forge/addon/templates/TemplateGenerator.java +++ b/templates/spi/src/main/java/org/jboss/forge/addon/templates/TemplateGenerator.java @@ -8,41 +8,21 @@ import org.jboss.forge.addon.resource.Resource; -import java.io.IOException; -import java.io.Writer; - /** - * Process a template - * + * Generator for {@link Template} instances. + * * @author George Gastaldi + * @author Lincoln Baxter, III */ public interface TemplateGenerator { /** - * Returns true if the given template can be handled by this {@link TemplateGenerator} - */ - public boolean handles(Template template); - - /** - * Returns true if the given template can be handled by this {@link TemplateGenerator} - * - * @deprecated Deprecated after Forge 2.1.1. Use the {@link Template} accepting method instead. - */ - @Deprecated - public boolean handles(Resource template); - - /** - * Processes the template specified by the {@link Template} parameter and writes the output to the {@link Writer} - * parameter + * Returns true if the given template can be generated by this {@link TemplateGenerator} */ - public void process(Object dataModel, Template template, Writer writer) throws IOException; + public boolean handles(Class type); /** - * Processes the template specified by the {@link Resource} parameter and writes the output to the {@link Writer} - * parameter - * - * @deprecated Deprecated after Forge 2.1.1. Use the {@link Template} accepting method instead. + * Returns a {@link Template} instance for the requested {@link Resource} and template {@link Class} type. */ - @Deprecated - public void process(Object dataModel, Resource template, Writer writer) throws IOException; + public Template create(Resource template, Class type); } diff --git a/templates/tests/pom.xml b/templates/tests/pom.xml index 10e53037de..5c52963171 100644 --- a/templates/tests/pom.xml +++ b/templates/tests/pom.xml @@ -15,6 +15,11 @@ forge-addon provided + + org.jboss.forge.furnace + furnace-se + test + org.jboss.forge.furnace.test furnace-test-harness diff --git a/templates/tests/src/test/java/org/jboss/forge/addon/templates/TemplateTestCase.java b/templates/tests/src/test/java/org/jboss/forge/addon/templates/TemplateTestCase.java index 595db321b8..74a76ba730 100644 --- a/templates/tests/src/test/java/org/jboss/forge/addon/templates/TemplateTestCase.java +++ b/templates/tests/src/test/java/org/jboss/forge/addon/templates/TemplateTestCase.java @@ -55,38 +55,38 @@ public static ForgeArchive getDeployment() private ResourceFactory resourceFactory; @Inject - private TemplateProcessorFactory templateProcessorFactory; + private TemplateFactory templateFactory; @Test public void testProcessorFactoryInjection() throws Exception { - Assert.assertNotNull(templateProcessorFactory); + Assert.assertNotNull(templateFactory); } @Test @SuppressWarnings("rawtypes") public void testTemplateProcessor() throws Exception { - String template = "Hello ${name}!"; + String templateContents = "Hello ${name}!"; String expected = "Hello JBoss Forge!"; File tempFile = File.createTempFile("template", ".tmp"); tempFile.deleteOnExit(); FileResource resource = resourceFactory.create(tempFile).reify(FileResource.class); - resource.setContents(template); - TemplateProcessor processor = templateProcessorFactory.fromTemplate(new FreemarkerTemplate(resource)); - String actual = processor.process(Collections.singletonMap("name", "JBoss Forge")); + resource.setContents(templateContents); + Template template = templateFactory.create(resource, FreemarkerTemplate.class); + String actual = template.process(Collections.singletonMap("name", "JBoss Forge")); Assert.assertEquals(expected, actual); } @Test public void testClasspathTemplateProcessor() throws Exception { - URL template = getClass().getResource("template.ftl"); - Assert.assertNotNull(template); + URL templateURL = getClass().getResource("template.ftl"); + Assert.assertNotNull(templateURL); String expected = "Hello JBoss Forge!"; - Resource resource = resourceFactory.create(template); - TemplateProcessor processor = templateProcessorFactory.fromTemplate(new FreemarkerTemplate(resource)); - String actual = processor.process(Collections.singletonMap("name", "JBoss Forge")); + Resource resource = resourceFactory.create(templateURL); + Template template = templateFactory.create(resource, FreemarkerTemplate.class); + String actual = template.process(Collections.singletonMap("name", "JBoss Forge")); Assert.assertEquals(expected, actual); } @@ -94,28 +94,28 @@ public void testClasspathTemplateProcessor() throws Exception @SuppressWarnings("rawtypes") public void testTemplateProcessorJavaBean() throws Exception { - String template = "Hello ${name}!"; + String templateContents = "Hello ${name}!"; String expected = "Hello JBoss Forge!"; File tempFile = File.createTempFile("template", ".tmp"); tempFile.deleteOnExit(); FileResource resource = resourceFactory.create(tempFile).reify(FileResource.class); - resource.setContents(template); - TemplateProcessor processor = templateProcessorFactory.fromTemplate(new FreemarkerTemplate(resource)); + resource.setContents(templateContents); + Template template = templateFactory.create(resource, FreemarkerTemplate.class); JavaBean dataModel = new JavaBean(); dataModel.setName("JBoss Forge"); - String actual = processor.process(dataModel); + String actual = template.process(dataModel); Assert.assertEquals(expected, actual); } @Test public void testIncludesTemplateProcessor() throws Exception { - URL template = getClass().getResource("includes.ftl"); - Assert.assertNotNull(template); + URL templateURL = getClass().getResource("includes.ftl"); + Assert.assertNotNull(templateURL); String expected = "Hello JBoss Forge! And Goodbye JBoss Forge!"; - Resource resource = resourceFactory.create(template); - TemplateProcessor processor = templateProcessorFactory.fromTemplate(new FreemarkerTemplate(resource)); - String actual = processor.process(Collections.singletonMap("name", "JBoss Forge")); + Resource resource = resourceFactory.create(templateURL); + Template template = templateFactory.create(resource, FreemarkerTemplate.class); + String actual = template.process(Collections.singletonMap("name", "JBoss Forge")); Assert.assertEquals(expected, actual); }