From e88d741deba1008af2127d123cc443d6ac591472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Dethier?= Date: Thu, 3 Mar 2022 22:21:34 +0100 Subject: [PATCH] feat: add doc generation. --- META-INF/MANIFEST.MF | 9 +- icons/doc.png | Bin 0 -> 774 bytes plugin.xml | 18 +++- .../plugin/builder/PousseCafeBuilder.java | 58 ++++++++----- .../plugin/builder/ResourceSource.java | 45 +++++++--- .../plugin/core/PousseCafeProject.java | 28 +++++- .../plugin/editors/EmilHyperlinkDetector.java | 14 ++- .../AddRemovePousseCafeNatureHandler.java | 30 ++----- .../plugin/handlers/GenerateDocHandler.java | 82 ++++++++++++++++++ .../handlers/ProjectSelectionIterator.java | 52 +++++++++++ .../MessageListenerHyperlinkDetector.java | 10 ++- .../PousseCafeProjectPropertyPage.java | 30 +++++++ 12 files changed, 304 insertions(+), 72 deletions(-) create mode 100644 icons/doc.png create mode 100644 src/poussecafe/eclipse/plugin/handlers/GenerateDocHandler.java create mode 100644 src/poussecafe/eclipse/plugin/handlers/ProjectSelectionIterator.java diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF index 0327610..c7bf4bc 100644 --- a/META-INF/MANIFEST.MF +++ b/META-INF/MANIFEST.MF @@ -8,17 +8,18 @@ Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, org.eclipse.core.resources, - poussecafe.source.eclipse.plugin;bundle-version="0.28.1", org.eclipse.jface.text, org.eclipse.ui.editors, - pousse-cafe-antlr4-runtime-eclipse-plugin;bundle-version="4.8.0", org.slf4j.api, org.eclipse.jdt.ui;bundle-version="3.22.0", org.eclipse.ui.ide;bundle-version="3.18.0", org.eclipse.jdt.core, - poussecafe.base.eclipse.plugin;bundle-version="0.26.0", org.apache.commons.lang3, - org.eclipse.ui.workbench.texteditor;bundle-version="3.15.100" + org.eclipse.ui.workbench.texteditor;bundle-version="3.15.100", + pousse-cafe-antlr4-runtime-eclipse-plugin;bundle-version="4.8.0", + poussecafe.doc.eclipse.plugin;bundle-version="0.29.0", + poussecafe.source.eclipse.plugin;bundle-version="0.29.0", + poussecafe.base.eclipse.plugin;bundle-version="0.29.0" Import-Package: javax.inject Bundle-Vendor: Pousse-Café Team Bundle-Activator: poussecafe.eclipse.plugin.core.PousseCafePlugin diff --git a/icons/doc.png b/icons/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..82b0d4fbddba40c06f7d151590a5202a2db9c6da GIT binary patch literal 774 zcmV+h1Nr=kP)L};~vtU6aQU*z(5kXK_ z213yiqJndyLCYx-NI@V}bP*(G1qFQ&7`C8{A`3&)rcS48>b7%q=e%!MNupBFbNl?C z-^Ii45B%ql#TKfn3ht$`Y6JWkW~R$({MWwxGvIn-^*+kW%`>8VnP&6atkLJ=gtDDA z{)TywIe;6DCpVd#+)O#yJCS`LW5&8303gLeR33dXY*2GcZEYYj4{-HzO`at2bs&8C zgtJu9>{~cN8-Q)#78s+@-DO~uO$#HhB7jl+CxkRLoULNayvxa%bi#9jhoQqBxd)<; z!?&v(S*{gmy?+z&>Dm!G_vsVr{jPm?_x$TcEpqkhSly7*Pnk zfCT44%CQYpaDYk1iA1lK`tNANqa!dB50a~^pbWQz5dmqtclMa26QDh< z#!B>}#OLEyc|6o2;35Cy$?N{Tdy0GP+Q;&4Jy%@j^nglESR<{>P;v<4GeE;HnHz&B z@D`Fxr<2%Z>0@Nz`&3^zV$OOH4EQUjA+~giN0p_HEaZz{86SQOYxYLuuFr=c3dCkr zy2ghF&91Hwx$(*PIlExqoFh^&;IEu!V#_leQEYY>e0nnqN)EwpRX%8w6Jw!JX!B@v z>^2pRi%qH;Ur^=WkO$L;m19|L@D?9>^tLm!;m40~FJa{LmHP9a{@R6Lz+Y)H(!z+W zMB + + @@ -112,9 +117,16 @@ commandId="poussecafe.eclipse.plugin.commands.generateCode" icon="icons/emil.png" id="poussecafe.eclipse.plugin.toolbars.generateCode" - label="Pousse-Café toolbar" + label="Generate code" tooltip="Generate code using active EMIL editor's content"> + + @@ -176,6 +188,10 @@ + + diff --git a/src/poussecafe/eclipse/plugin/builder/PousseCafeBuilder.java b/src/poussecafe/eclipse/plugin/builder/PousseCafeBuilder.java index 5ae2107..3c6e38e 100644 --- a/src/poussecafe/eclipse/plugin/builder/PousseCafeBuilder.java +++ b/src/poussecafe/eclipse/plugin/builder/PousseCafeBuilder.java @@ -14,8 +14,12 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.core.IClassFile; +import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import poussecafe.eclipse.plugin.core.PousseCafeCore; @@ -180,14 +184,39 @@ private void fullBuild(IProgressMonitor monitor) { logger.info("Starting full build..."); long start = System.currentTimeMillis(); try { - getProject().accept(new ResourceVisitor(monitor)); + var project = pousseCafeProject(); + for(var fragmentRoot : javaProject().getPackageFragments()) { + String fragmentRootName = fragmentRoot.getElementName(); + if(fragmentRootName.startsWith(project.getBasePackage())) { + include(monitor, fragmentRoot); + } + } } catch (CoreException e) { - platformLogger.error("Unable to validate project", e); + platformLogger.error("Unable to build project", e); } long end = System.currentTimeMillis(); logger.info("Scanned project in {} ms", (end - start)); } + private void include(IProgressMonitor monitor, IPackageFragment fragmentRoot) throws JavaModelException { + if(monitor.isCanceled()) { + throw new OperationCanceledException(); + } + for(var child : fragmentRoot.getChildren()) { + if(monitor.isCanceled()) { + throw new OperationCanceledException(); + } + if(child instanceof ICompilationUnit) { + var file = (IFile) child.getResource(); + monitor.subTask("Pousse-Café build: scanning " + file.getName()); + includeFile(new ResourceSource(file)); + } else if(child instanceof IClassFile) { + monitor.subTask("Pousse-Café build: scanning " + child.getElementName()); + includeFile(new ResourceSource((IClassFile) child)); + } + } + } + private List relevantDeltas(IResourceDelta delta) { var updatedResources = new ArrayList(); addRelevantDeltas(updatedResources, delta); @@ -224,29 +253,12 @@ private IJavaProject javaProject() { private SourceScanner scanner; - private class ResourceVisitor extends JavaSourceFileVisitor { - - ResourceVisitor(IProgressMonitor monitor) { - super(javaProject()); - this.monitor = monitor; - } - - private IProgressMonitor monitor; - - @Override - protected void visit(ResourceSource source) { - if(monitor.isCanceled()) { - throw new OperationCanceledException(); - } - monitor.subTask("Pousse-Café build: scanning " + source.id()); - includeFile(source); - } - } - private void includeFile(ResourceSource source) { try { - scanner.includeSource(source); - logger.debug("Included {}", source.id()); + if(source.hasSource()) { + scanner.includeSource(source); + logger.debug("Included {}", source.id()); + } } catch (Exception e) { platformLogger.error("Error while scanning " + source.id(), e); } diff --git a/src/poussecafe/eclipse/plugin/builder/ResourceSource.java b/src/poussecafe/eclipse/plugin/builder/ResourceSource.java index 39454b3..b7fbafa 100644 --- a/src/poussecafe/eclipse/plugin/builder/ResourceSource.java +++ b/src/poussecafe/eclipse/plugin/builder/ResourceSource.java @@ -4,6 +4,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; @@ -29,24 +30,26 @@ private void connectedOrThrow() { } public boolean isConnected() { - return type != null; + return type != null || source != null; } - public boolean hasFile() { - connectedOrThrow(); - return file != null; + public boolean hasSource() { + return compilationUnit != null || source != null; } @Override public void configure(ASTParser parser) { - parser.setSource(resourceCompilationUnit()); + if(compilationUnit != null) { + parser.setSource(resourceCompilationUnit()); + } else if(source != null) { + parser.setSource(source.toCharArray()); + } else { + throw new IllegalStateException("No source available"); + } } - public ICompilationUnit resourceCompilationUnit() { + private ICompilationUnit resourceCompilationUnit() { connectedOrThrow(); - if(compilationUnit == null) { - - } return compilationUnit; } @@ -82,6 +85,15 @@ public ResourceSource(IType type) { private String typeName; + public ResourceSource(IClassFile classFile) { + super(classFile.getElementName()); + + classFileHandleIdentifier = classFile.getHandleIdentifier(); + connect(classFile.getJavaProject()); + } + + private String classFileHandleIdentifier; + @Override public void connect(Object project) { requireNonNull(project); @@ -104,7 +116,7 @@ public void connect(Object project) { } } - if(type == null) { + if(type == null && typeName != null) { relativePath = null; try { type = javaProject.findType(typeName); @@ -112,8 +124,21 @@ public void connect(Object project) { // Do nothing } } + + if(type == null && classFileHandleIdentifier != null) { + relativePath = null; + try { + var classFile = (IClassFile) JavaCore.create(classFileHandleIdentifier); + type = classFile.findPrimaryType(); + source = classFile.getSource(); + } catch (Exception e) { + // Do nothing + } + } } + private String source; + ResourceSource() { } diff --git a/src/poussecafe/eclipse/plugin/core/PousseCafeProject.java b/src/poussecafe/eclipse/plugin/core/PousseCafeProject.java index b9590b6..d8de9c9 100644 --- a/src/poussecafe/eclipse/plugin/core/PousseCafeProject.java +++ b/src/poussecafe/eclipse/plugin/core/PousseCafeProject.java @@ -150,7 +150,12 @@ public String getBasePackage() { private String getProperty(QualifiedName name, String defaultValue) { var resource = project.getProject(); try { - return resource.getPersistentProperty(name); + String value = resource.getPersistentProperty(name); + if(value == null) { + return defaultValue; + } else { + return value; + } } catch (CoreException e) { return defaultValue; } @@ -195,4 +200,25 @@ public boolean hasProblems() throws CoreException { var problems = project.getProject().findMarkers(PousseCafeBuilder.MARKER_TYPE, true, IResource.DEPTH_INFINITE); return problems != null && problems.length > 0; } + + public Path getDocumentationFolder() throws CoreException { + var tempFolder = createPousseCafeTempFolder(); + var folder = tempFolder.getFolder("doc"); + folder.refreshLocal(IResource.DEPTH_ZERO, null); + if(!folder.exists()) { + folder.create(false, true, null); + } + return Path.of(folder.getLocation().toOSString()); + } + + public String getDomain() { + return getProperty(PousseCafeProjectPropertyPage.DOMAIN_PROPERTY_NAME, + PousseCafeProjectPropertyPage.DEFAULT_DOMAIN); + } + + public boolean openDocInExternalBrownser() { + var value = getProperty(PousseCafeProjectPropertyPage.OPEN_IN_EXTERNAL_BROWSER_PROPERTY_NAME, + PousseCafeProjectPropertyPage.DEFAULT_OPEN_IN_EXTERNAL_BROWSER); + return Boolean.parseBoolean(value); + } } diff --git a/src/poussecafe/eclipse/plugin/editors/EmilHyperlinkDetector.java b/src/poussecafe/eclipse/plugin/editors/EmilHyperlinkDetector.java index 18fb660..e04f3cc 100644 --- a/src/poussecafe/eclipse/plugin/editors/EmilHyperlinkDetector.java +++ b/src/poussecafe/eclipse/plugin/editors/EmilHyperlinkDetector.java @@ -107,7 +107,7 @@ private void tryAddLinksOfHeader(HeaderContext header) { var process = modelOrElseThrow().processes().stream() .filter(candidate -> candidate.simpleName().equals(processName.getText())) .findFirst(); - tryAddLink(processName.getSymbol(), process.map(ProcessModel::source), unit -> Optional.of(unit)); + tryAddLink(processName.getSymbol(), process.map(ProcessModel::source), Optional::of); } private SourceModel modelOrElseThrow() { @@ -153,7 +153,7 @@ private void tryAddLinksOfCommandConsumption(ConsumptionContext consumption) { if(commandConsumption != null) { var commandName = commandConsumption.command().NAME(); var command = modelOrElseThrow().command(commandName.getText()); - tryAddLink(commandName.getSymbol(), command.map(Command::source), unit -> Optional.of(unit)); + tryAddLink(commandName.getSymbol(), command.map(Command::source), Optional::of); tryAddLinks(commandName.getText(), commandConsumption.messageConsumptions()); } } @@ -233,7 +233,7 @@ private void tryAddLinksOfAggregateContainer(QualifiedNameContext qualifiedName) var aggregateNameNode = qualifiedName.NAME(0); var source = aggregateContainer(qualifiedName); if(source.isPresent()) { - tryAddLink(aggregateNameNode.getSymbol(), source.get(), unit -> Optional.of(unit)); + tryAddLink(aggregateNameNode.getSymbol(), source.get(), Optional::of); var typeNameNode = qualifiedName.NAME(1); tryAddLink(typeNameNode.getSymbol(), source.get(), unit -> Optional.of(unit.getType(typeNameNode.getText()))); @@ -249,7 +249,7 @@ private void tryAddLinkStandaloneComponent( var aggregate = modelOrElseThrow().aggregate(aggregateName); if(aggregate.isPresent()) { tryAddLink(simpleName, sourceProvider.apply(aggregate.get()), - unit -> Optional.of(unit)); + Optional::of); } } @@ -266,7 +266,6 @@ private void tryAddLinkListener( containerType); var listenerExtractor = listenerExtractor( containerQualifiedName, - containerSimpleName, listenerName.getText(), messageTypeName); tryAddLink(listenerName, listenerContainer, listenerExtractor); @@ -314,7 +313,6 @@ private Optional aggregate(QualifiedNameContext qualifiedName) { private Function> listenerExtractor( QualifiedNameContext qualifiedName, - Token simpleName, String methodName, String messageTypeName) { return type -> { @@ -374,7 +372,7 @@ private void tryAddLinks(EventProductionContext eventProduction) { private void tryAddLinkEvent(EventContext event) { var eventName = event.NAME(); var domainEvent = modelOrElseThrow().event(eventName.getText()); - tryAddLink(eventName.getSymbol(), domainEvent.map(DomainEvent::source), unit -> Optional.of(unit)); + tryAddLink(eventName.getSymbol(), domainEvent.map(DomainEvent::source), Optional::of); } private void tryAddLinks(String messageTypeName, AggregateRootConsumptionContext aggregateRootConsumption) { @@ -390,7 +388,7 @@ private void tryAddLinks(String messageTypeName, AggregateRootConsumptionContext var runner = modelOrElseThrow().runner(listener.get().runnerClass().orElseThrow()); tryAddLink(aggregateRootConsumption.runnerName, runner.map(Runner::runnerSource), - unit -> Optional.of(unit)); + Optional::of); } tryAddLinkListener( aggregateRootConsumption.aggregateRoot().qualifiedRootName, diff --git a/src/poussecafe/eclipse/plugin/handlers/AddRemovePousseCafeNatureHandler.java b/src/poussecafe/eclipse/plugin/handlers/AddRemovePousseCafeNatureHandler.java index 5424288..2fb5dc4 100644 --- a/src/poussecafe/eclipse/plugin/handlers/AddRemovePousseCafeNatureHandler.java +++ b/src/poussecafe/eclipse/plugin/handlers/AddRemovePousseCafeNatureHandler.java @@ -1,6 +1,5 @@ package poussecafe.eclipse.plugin.handlers; -import java.util.Iterator; import javax.inject.Inject; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; @@ -8,7 +7,6 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.ILog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; @@ -21,32 +19,20 @@ public class AddRemovePousseCafeNatureHandler extends AbstractHandler { public Object execute(ExecutionEvent event) throws ExecutionException { ISelection selection = HandlerUtil.getCurrentSelection(event); if(selection instanceof IStructuredSelection) { - for (Iterator it = ((IStructuredSelection) selection).iterator(); it.hasNext();) { - IProject project = nextProject(it); - if(project != null) { - try { - toggleNature(project); - } catch (CoreException e) { - logger.error("Failed to toggle nature"); - throw new ExecutionException("Failed to toggle nature", e); - } + var it = ProjectSelectionIterator.iterate((IStructuredSelection) selection); + while(it.hasNext()) { + IProject project = it.next(); + try { + toggleNature(project); + } catch (CoreException e) { + logger.error("Failed to toggle nature"); + throw new ExecutionException("Failed to toggle nature", e); } } } return null; } - private IProject nextProject(Iterator it) { - Object element = it.next(); - IProject project = null; - if(element instanceof IProject) { - project = (IProject) element; - } else if(element instanceof IAdaptable) { - project = ((IAdaptable) element).getAdapter(IProject.class); - } - return project; - } - private void toggleNature(IProject project) throws CoreException { IProjectDescription description = project.getDescription(); String[] natures = description.getNatureIds(); diff --git a/src/poussecafe/eclipse/plugin/handlers/GenerateDocHandler.java b/src/poussecafe/eclipse/plugin/handlers/GenerateDocHandler.java new file mode 100644 index 0000000..f65da29 --- /dev/null +++ b/src/poussecafe/eclipse/plugin/handlers/GenerateDocHandler.java @@ -0,0 +1,82 @@ +package poussecafe.eclipse.plugin.handlers; + +import java.net.URL; +import java.time.LocalDateTime; +import java.util.Optional; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; +import poussecafe.doc.PousseCafeDocGenerationConfiguration; +import poussecafe.doc.PousseCafeDocGenerator; +import poussecafe.eclipse.plugin.builder.PousseCafeNature; +import poussecafe.eclipse.plugin.core.PousseCafeCore; +import poussecafe.eclipse.plugin.core.PousseCafeProject; +import poussecafe.source.model.SourceModel; + +public class GenerateDocHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getCurrentSelection(event); + if(selection instanceof IStructuredSelection) { + var it = ProjectSelectionIterator.iterate((IStructuredSelection) selection); + while(it.hasNext()) { + var project = it.next(); + if(PousseCafeNature.isPousseCafeProject(project)) { + var pousseCafeProject = PousseCafeCore.getProject(JavaCore.create(project)); + generateDocAndOpen(pousseCafeProject); + } + } + } + return null; + } + + private boolean generateDocAndOpen(PousseCafeProject pousseCafeProject) { + var sourceModel = pousseCafeProject.model(); + if(sourceModel.isPresent()) { + try { + generateDoc(pousseCafeProject, sourceModel); + openDocInBrowser(pousseCafeProject); + return true; + } catch (CoreException e) { + Platform.getLog(getClass()).error("Error while generating doc", e); + } + } + return false; + } + + private void generateDoc(PousseCafeProject pousseCafeProject, Optional sourceModel) throws CoreException { + var generator = PousseCafeDocGenerator.builder() + .configuration(PousseCafeDocGenerationConfiguration.builder() + .domainName(pousseCafeProject.getDomain()) + .outputDirectory(pousseCafeProject.getDocumentationFolder().toString()) + .version(LocalDateTime.now().toString()) + .pdfFileName("project.pdf") + .build()) + .model(sourceModel.orElseThrow()) + .build(); + generator.generate(); + } + + private void openDocInBrowser(PousseCafeProject pousseCafeProject) { + try { + var url = new URL("file://" + pousseCafeProject.getDocumentationFolder().resolve("index.html").toString()); + if(pousseCafeProject.openDocInExternalBrownser()) { + PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(url); + } else { + var browserId = pousseCafeProject.getJavaProject().getProject().getName() + "PousseCafeDocBrowserId"; + var browser = PlatformUI.getWorkbench().getBrowserSupport().createBrowser(browserId); + browser.openURL(url); + } + } catch (Exception e) { + Platform.getLog(getClass()).error("Error while generating doc", e); + } + } +} diff --git a/src/poussecafe/eclipse/plugin/handlers/ProjectSelectionIterator.java b/src/poussecafe/eclipse/plugin/handlers/ProjectSelectionIterator.java new file mode 100644 index 0000000..6782d2f --- /dev/null +++ b/src/poussecafe/eclipse/plugin/handlers/ProjectSelectionIterator.java @@ -0,0 +1,52 @@ +package poussecafe.eclipse.plugin.handlers; + +import java.util.Iterator; +import java.util.NoSuchElementException; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.IStructuredSelection; + +public class ProjectSelectionIterator implements Iterator { + + @Override + public boolean hasNext() { + return nextProject != null; + } + + private Iterator selectionIterator; + + private IProject nextProject; + + @Override + public IProject next() { + if(nextProject == null) { + throw new NoSuchElementException(); + } + IProject project = nextProject; + moveToNext(); + return project; + } + + public static ProjectSelectionIterator iterate(IStructuredSelection selection) { + var iterator = new ProjectSelectionIterator(); + iterator.selectionIterator = selection.iterator(); + iterator.moveToNext(); + return iterator; + } + + private void moveToNext() { + nextProject = null; + while(selectionIterator.hasNext() && nextProject == null) { + Object element = selectionIterator.next(); + if(element instanceof IProject) { + nextProject = (IProject) element; + } else if(element instanceof IAdaptable) { + nextProject = ((IAdaptable) element).getAdapter(IProject.class); + } + } + } + + private ProjectSelectionIterator() { + + } +} diff --git a/src/poussecafe/eclipse/plugin/hyperlink/MessageListenerHyperlinkDetector.java b/src/poussecafe/eclipse/plugin/hyperlink/MessageListenerHyperlinkDetector.java index 4715095..5116dc5 100644 --- a/src/poussecafe/eclipse/plugin/hyperlink/MessageListenerHyperlinkDetector.java +++ b/src/poussecafe/eclipse/plugin/hyperlink/MessageListenerHyperlinkDetector.java @@ -40,10 +40,15 @@ public class MessageListenerHyperlinkDetector extends AbstractHyperlinkDetector @Override public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) { - if(!isEligibleContent()) { + ITextEditor editor = getAdapter(ITextEditor.class); + if(!(editor.getEditorInput() instanceof IFileEditorInput)) { return noResult(); } + try { + if(!isEligibleContent()) { + return noResult(); + } var links = new ArrayList(); links.addAll(detectLinksOfListener(region)); links.addAll(detectLinksOfMessage(region)); @@ -61,8 +66,7 @@ private boolean isEligibleContent() { private IFile editedFile() { ITextEditor editor = getAdapter(ITextEditor.class); IFileEditorInput input = (IFileEditorInput) editor.getEditorInput(); - IFile file = input.getFile(); - return file; + return input.getFile(); } private IHyperlink[] noResult() { diff --git a/src/poussecafe/eclipse/plugin/properties/PousseCafeProjectPropertyPage.java b/src/poussecafe/eclipse/plugin/properties/PousseCafeProjectPropertyPage.java index f17cfd1..8014623 100644 --- a/src/poussecafe/eclipse/plugin/properties/PousseCafeProjectPropertyPage.java +++ b/src/poussecafe/eclipse/plugin/properties/PousseCafeProjectPropertyPage.java @@ -30,6 +30,10 @@ public class PousseCafeProjectPropertyPage extends PropertyPage { public static final String DEFAULT_SOURCE_FOLDER = "src/"; + public static final QualifiedName DOMAIN_PROPERTY_NAME = new QualifiedName(POUSSE_CAFE_PROPERTY_QUALIFIER, "domain"); + + public static final String DEFAULT_DOMAIN = "My Domain"; + private static final int TEXT_FIELD_WIDTH = 50; public static final QualifiedName USES_INTERNAL_STORAGE_PROPERTY_NAME = new QualifiedName(POUSSE_CAFE_PROPERTY_QUALIFIER, "usesInternalStorage"); @@ -44,6 +48,10 @@ public class PousseCafeProjectPropertyPage extends PropertyPage { public static final String DEFAULT_USES_SPRING_JPA_STORAGE = "false"; + public static final QualifiedName OPEN_IN_EXTERNAL_BROWSER_PROPERTY_NAME = new QualifiedName(POUSSE_CAFE_PROPERTY_QUALIFIER, "openInExternalBrowser"); + + public static final String DEFAULT_OPEN_IN_EXTERNAL_BROWSER = "false"; + public PousseCafeProjectPropertyPage() { super(); } @@ -59,6 +67,8 @@ protected Control createContents(Composite parent) { addGeneralSection(); addSeparator(); + addDocumentationSection(); + addSeparator(); addStorageSection(); return pageRoot; @@ -126,6 +136,18 @@ private void addSeparator() { separator.setLayoutData(gridData); } + private void addDocumentationSection() { + var fieldsComposite = createTwoColumnsComposite(); + domainText = addField(fieldsComposite, "Domain name:", DOMAIN_PROPERTY_NAME, DEFAULT_DOMAIN); + openInExternalBrowser = addCheckbox(fieldsComposite, "Open in external browser", + OPEN_IN_EXTERNAL_BROWSER_PROPERTY_NAME, + Boolean.parseBoolean(DEFAULT_OPEN_IN_EXTERNAL_BROWSER)); + } + + private Text domainText; + + private Button openInExternalBrowser; + private void addStorageSection() { var storageComposite = createTwoColumnsComposite(); usesInternalStorage = addCheckbox(storageComposite, "Uses internal storage", @@ -169,6 +191,10 @@ protected void performDefaults() { super.performDefaults(); basePackageText.setText(DEFAULT_BASE_PACKAGE); sourceFolderText.setText(DEFAULT_SOURCE_FOLDER); + + domainText.setText(DEFAULT_DOMAIN); + openInExternalBrowser.setSelection(Boolean.parseBoolean(DEFAULT_OPEN_IN_EXTERNAL_BROWSER)); + usesInternalStorage.setSelection(Boolean.parseBoolean(DEFAULT_USES_INTERNAL_STORAGE)); usesSpringMongoStorage.setSelection(Boolean.parseBoolean(DEFAULT_USES_SPRING_MONGO_STORAGE)); usesSpringJpaStorage.setSelection(Boolean.parseBoolean(DEFAULT_USES_SPRING_JPA_STORAGE)); @@ -180,6 +206,10 @@ public boolean performOk() { getResource().setPersistentProperty(BASE_PACKAGE_PROPERTY_NAME, basePackageText.getText()); getResource().setPersistentProperty(SOURCE_FOLDER_PROPERTY_NAME, sourceFolderText.getText()); + getResource().setPersistentProperty(DOMAIN_PROPERTY_NAME, domainText.getText()); + getResource().setPersistentProperty(OPEN_IN_EXTERNAL_BROWSER_PROPERTY_NAME, + Boolean.toString(openInExternalBrowser.getSelection())); + getResource().setPersistentProperty(USES_INTERNAL_STORAGE_PROPERTY_NAME, Boolean.toString(usesInternalStorage.getSelection())); getResource().setPersistentProperty(USES_SPRING_MONGO_STORAGE_PROPERTY_NAME,