[
https://issues.jboss.org/browse/FORGE-2469?page=com.atlassian.jira.plugin...
]
Antonio Goncalves commented on FORGE-2469:
------------------------------------------
agoncal So the question of this JIRA is "how do I write a proper add command"
gastaldi Right. We might need an AbstractAddxxx class
agoncal (targetClass being the real pain)
agoncal That's what I thought
gastaldi Or we could have a class that creates and sets up these inputs properly
gastaldi Something like: Inputs.createTargetClass()
agoncal While we still use inheritance vs aggregation, I was thinking of having
AbstractCDICommand at the top, and then AbstractCDINewCommand and AbstractCDIAddCommand
agoncal yes, that goes back to the main idea of aggregating parameters
gastaldi Yeah
agoncal But is there a possible quick win ? We don't break everything (too
expensive), keep on with inheritance, and get a nice pattern that can be reused in most of
the add commands
gastaldi Thats a good question
gastaldi I'd like to minimize the number of inherited classes
agoncal yes
agoncal But I realize that most of the AbstractCDICommand, AbstractFacesCommand.... are
good for new commands, not add
gastaldi what if we moved these common inputs to another class and @Inject them in the
add commands
gastaldi I mean in an encapsulating class
gastaldi @Inject CommonAddInputs
gastaldi food for thought :)
agoncal I would like it to be even more flexible :
agoncal @Inject TargetPackage
agoncal @Inject TargetClass
gastaldi ah-ha
agoncal @Inject Named
gastaldi that's interesting
agoncal This way you create a command that fits your needs
gastaldi so what if we could come with an API that allows you to aggregate this input?
gastaldi hmmm or maybe:
agoncal This way we could even keep the inheritance (eg. AbstractCDICommand) and use
these @Inject
gastaldi @Produces public TargetPackage produceTargetPackage() { ...}
gastaldi public interface TargetPackage extends UIInput<String>
agoncal Also remember that targetClass can be customized
agoncal example :
agoncal java-add-annotation : target class is any class
gastaldi sure, as it is an UIInput, you can call the methods you'd like
agoncal cdi-add-producer : target class is most of the classes, except Entities
gastaldi that would be in the initializeUI of the commands afaik
gastaldi or we could have a factory class that could accept parameters
agoncal Would you have time to give it a try in the coming days ? If yes and we find a
nice pattern, then I could apply it to the Java EE addon and start developing new
commands
gastaldi I can try, sure
gastaldi that would be awesome
agoncal Yes, that would allow me to kiil a few "add" commands that are still
waiting to be developped ;o)
Getting a design pattern right for add commands
-----------------------------------------------
Key: FORGE-2469
URL:
https://issues.jboss.org/browse/FORGE-2469
Project: Forge
Issue Type: Sub-task
Components: Java EE
Affects Versions: 2.19.0.Final
Reporter: Antonio Goncalves
Fix For: 2.x Future
The {{new}} commands are straight forward, we just create a new artifact (mostly classes
in the Java EE addon). {{add}} commands are meant to add code to existing code. So all the
add}} commands have a {{targetClass}} attribute. The {{targetClass}} points to the current
class, or can point to a different one.
The algorithm to get the {{targetClass}} is very different from command to command (see
below). It would be very helpfull to find a generic design pattern that could be
applicable to most of the {{add}} commands.
{code:title=JavaEqualsHashcodeCommand}
@Override
public void initializeUI(UIBuilder builder) throws Exception
{
(...)
UISelection<Object> initialSelection = uiContext.getInitialSelection();
if (initialSelection.get() instanceof JavaResource)
{
targetClass.setValue((JavaResource) initialSelection.get());
}
targetClass.setValueChoices(projectOperations.getProjectClasses(project));
@Override
public Result execute(UIExecutionContext context) throws Exception
{
(...)
if (targetClass.hasMethodSignature("equals", Object.class))
{
if (prompt.promptBoolean("Class already has an equals method. Would you
like it to be overwritten?"))
{code}
{code:title=CDIAddInjectionPointCommand}
private void setupTargetClasses(UIContext uiContext)
{
UISelection<FileResource<?>> selection =
uiContext.getInitialSelection();
Project project = getSelectedProject(uiContext);
final List<JavaResource> classes =
cdiOperations.getProjectInjectionPointBeans(project);
targetClass.setValueChoices(classes);
int idx = -1;
if (!selection.isEmpty())
{
idx = classes.indexOf(selection.get());
}
if (idx == -1)
{
idx = classes.size() - 1;
}
if (idx != -1)
{
targetClass.setDefaultValue(classes.get(idx));
}
}
{code}
{code:title=CDIAddObserverMethodCommand}
private void setupTargetClass(UIContext uiContext, Project project)
{
UISelection<Resource<?>> resource = uiContext.getInitialSelection();
if (resource.get() instanceof JavaResource)
{
targetClass.setDefaultValue((JavaResource) resource.get());
}
targetClass.setValueChoices(projectOperations.getProjectClasses(project));
}
{code}
{code:title=FacesNewValidatorMethodCommand}
public void initializeUI(UIBuilder builder) throws Exception
{
Object selection = builder.getUIContext().getInitialSelection().get();
if (selection instanceof JavaResource)
{
targetClass.setDefaultValue((JavaResource) selection);
}
builder.add(targetClass).add(named);
}
@Override
public void validate(UIValidationContext validator)
{
try
{
JavaClassSource source =
targetClass.getValue().reify(JavaResource.class).getJavaType();
(...)
}
catch (FileNotFoundException e)
{
validator.addValidationError(targetClass, "Target Java class not
found.");
}
}
{code}
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)