package org.jactr.eclipse.ui.wizards.inject; /* * default logging */ import java.util.ArrayList; import java.util.Collection; import org.antlr.runtime.tree.CommonTree; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchWizard; import org.jactr.eclipse.core.bundles.descriptors.CommonExtensionDescriptor; import org.jactr.eclipse.core.bundles.descriptors.ModelExtensionDescriptor; import org.jactr.eclipse.core.bundles.descriptors.ModuleDescriptor; import org.jactr.eclipse.core.bundles.registry.ModuleRegistry; import org.jactr.eclipse.core.comp.CompilationUnitManager; import org.jactr.eclipse.core.comp.IProjectCompilationUnit; import org.jactr.eclipse.core.parser.ProjectSensitiveParserImportDelegate; import org.jactr.eclipse.ui.wizards.pages.CommonExtensionDescriptorLabelProvider; import org.jactr.eclipse.ui.wizards.pages.CommonExtensionWizardPage; import org.jactr.eclipse.ui.wizards.pages.ToolsExplanationWizardPage; import org.jactr.io.antlr3.builder.JACTRBuilder; import org.jactr.io.antlr3.misc.ASTSupport; import org.jactr.io.antlr3.misc.DetailedCommonTree; import org.jactr.io.generator.CodeGeneratorFactory; import org.jactr.io.generator.ICodeGenerator; import org.jactr.io.participant.ASTParticipantRegistry; import org.jactr.io.participant.IASTInjector; import org.jactr.io.participant.IASTParticipant; import org.jactr.io.participant.impl.BasicASTInjector; public class InjectIntoModelWizard extends Wizard implements IWorkbenchWizard { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(InjectIntoModelWizard.class); private IProjectCompilationUnit _compilationUnit; private Collection<CommonExtensionWizardPage> _commonPages = new ArrayList<CommonExtensionWizardPage>(); public InjectIntoModelWizard() { } @Override public void addPages() { addPage(new ToolsExplanationWizardPage( "toolsExp", "Library of Tools", "On the following pages you will select what tools you'd like your project to use.\nYou can always change your mind later.", "jACT-R uses modular bundles of code to contribute or change your model's behavior.\nYou need to select those tools in order to use them." + "\nThis is a convenience to avoid having to directly edit your projects dependencies.")); CommonExtensionWizardPage inst = new CommonExtensionWizardPage( () -> ModuleRegistry.getRegistry().getAllDescriptors(), new CommonExtensionDescriptorLabelProvider(), "module", "Modules", "Select modules you'd like to use in your project."); addPage(inst); _commonPages.add(inst); inst = new CommonExtensionWizardPage( () -> org.jactr.eclipse.core.bundles.registry.ExtensionRegistry .getRegistry().getAllDescriptors(), new CommonExtensionDescriptorLabelProvider(), "ext", "Extensions", "Select runtime extensions that you'd like to use in your project."); addPage(inst); _commonPages.add(inst); } @Override public boolean performFinish() { IProject project = _compilationUnit.getResource().getProject(); /* * make sure everyone is closed.. This is done here, otherwise we can get * some weird unmodifiable messages. */ for (CommonExtensionWizardPage extPage : _commonPages) extPage.ensureDependencies(project); ProjectSensitiveParserImportDelegate delegate = new ProjectSensitiveParserImportDelegate(); delegate.setProject(project); ICodeGenerator codeGen = CodeGeneratorFactory .getCodeGenerator(_compilationUnit.getResource() .getFileExtension()); ASTSupport astSupport = new ASTSupport(); CommonTree modelAST = _compilationUnit.getModelDescriptor(); /* * now let's edit the file itself.. */ for (CommonExtensionWizardPage extPage : _commonPages) { if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("for extension")); // get the descriptor and the class name, then the ASTParticipant for that for (CommonExtensionDescriptor desc : extPage.getSelectedDescriptors()) { String moduleOrExtension = desc.getClassName(); CommonTree injectedNode = null; long insertionPoint = 0; /* * use the codegen to create the correct bit.. */ if (desc instanceof ModuleDescriptor) { injectedNode = astSupport.createModuleTree(moduleOrExtension); for (CommonTree ct : ASTSupport.getTrees(modelAST, JACTRBuilder.MODULE)) { DetailedCommonTree dct = (DetailedCommonTree) ct; long end = dct.getStopOffset(); if (end > insertionPoint) insertionPoint = end + 1; } } else if (desc instanceof ModelExtensionDescriptor) { boolean hasExtsBlock = ASTSupport.getFirstDescendantWithType( modelAST, JACTRBuilder.EXTENSIONS) != null; Collection<CommonTree> definedExtensions = ASTSupport.getTrees( modelAST, JACTRBuilder.EXTENSION); /* * */ injectedNode = astSupport.createExtensionTree(moduleOrExtension); if (!hasExtsBlock) { CommonTree exts = astSupport.create(JACTRBuilder.EXTENSIONS); exts.addChild(injectedNode); injectedNode = exts; } if (!hasExtsBlock) { // our insertion point is after the modules block DetailedCommonTree dct = (DetailedCommonTree) ASTSupport .getFirstDescendantWithType(modelAST, JACTRBuilder.MODULES); insertionPoint = dct.getStopOffset() + 1; } else if(definedExtensions.size()>0) for (CommonTree ct : definedExtensions) { DetailedCommonTree dct = (DetailedCommonTree) ct; long end = dct.getStopOffset(); if (end > insertionPoint) insertionPoint = end + 1; } else { /* * we have the extensions block, but no extensions.. * it could be tough to squeeze this in correctly.. */ } } /* * if there is a participant that will contribute default parameters, * let's grab it. */ IASTParticipant participant = ASTParticipantRegistry .getParticipant(moduleOrExtension); if (participant != null) { IASTInjector injector = participant.getInjector(delegate); if (injector != null) if (injector instanceof BasicASTInjector) ((BasicASTInjector) injector).injectParameters(injectedNode); } Collection<StringBuilder> code = codeGen.generate(injectedNode, false); if (LOGGER.isDebugEnabled()) LOGGER.debug(String.format("Want to insert %s at %d", code, insertionPoint)); } } return false; } public void init(IWorkbench workbench, IStructuredSelection selection) { Object obj = selection.getFirstElement(); if (obj instanceof IResource) { IResource resource = (IResource) obj; _compilationUnit = CompilationUnitManager.acquire(resource); } } }