Skip to content

Commit

Permalink
Data model template matcher support
Browse files Browse the repository at this point in the history
Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Nov 6, 2024
1 parent 820e7d2 commit 52b6008
Show file tree
Hide file tree
Showing 17 changed files with 403 additions and 14 deletions.
1 change: 1 addition & 0 deletions qute.jdt/com.redhat.qute.jdt/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
<!-- =========== Roq extension =========== -->

<extension point="com.redhat.qute.jdt.dataModelProviders">
<provider class="com.redhat.qute.jdt.internal.extensions.roq.RoqDataModelProvider" />
<provider class="com.redhat.qute.jdt.internal.extensions.roq.DataMappingSupport" />
</extension>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import java.util.Map;
import java.util.Optional;

import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

import com.redhat.qute.commons.datamodel.resolvers.NamespaceResolverInfo;
import com.redhat.qute.commons.datamodel.resolvers.ValueResolverInfo;
Expand Down Expand Up @@ -124,7 +124,12 @@ public String getUriWithoutExtension(String templateUri) {

private T findDataModelTemplate(String templateUri, List<T> templates) {
Optional<T> dataModelForTemplate = templates.stream() //
.filter(t -> templateUri.endsWith(t.getTemplateUri())) //
.filter(t -> {
/*if (t instanceof ExtendedDataModelTemplate) {
return ((ExtendedDataModelTemplate) t).matches(templateUri);
}*/
return templateUri.endsWith(t.getTemplateUri());
}) //
.findFirst();
if (dataModelForTemplate.isPresent()) {
return dataModelForTemplate.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public class DataModelTemplate<T extends DataModelParameter> extends DataModelBa

private String templateUri;

private DataModelTemplateMatcher templateMatcher;

private String sourceField;

private List<DataModelFragment<T>> fragments;
Expand All @@ -50,6 +52,14 @@ public void setTemplateUri(String templateUri) {
this.templateUri = templateUri;
}

public DataModelTemplateMatcher getTemplateMatcher() {
return templateMatcher;
}

public void setTemplateMatcher(DataModelTemplateMatcher templateMatcher) {
this.templateMatcher = templateMatcher;
}

/**
* Returns the Java source field where this data model template is defined and
* null otherwise.
Expand Down Expand Up @@ -131,6 +141,7 @@ public DataModelFragment<T> getFragment(String fragmentId) {
public String toString() {
ToStringBuilder b = new ToStringBuilder(this);
b.add("templateUri", this.templateUri);
b.add("templateMatcher", this.templateMatcher);
b.add("sourceType", this.getSourceType());
b.add("sourceMethod", this.getSourceMethod());
b.add("sourceField", this.sourceField);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.qute.commons.datamodel;

import java.util.List;

import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;

/**
* Data model template matcher used to inject data parameters with patterns.
*/
public class DataModelTemplateMatcher {

private List<String> includes;

public DataModelTemplateMatcher() {

}

public DataModelTemplateMatcher(List<String> includes) {
setIncludes(includes);
}

public List<String> getIncludes() {
return includes;
}

public void setIncludes(List<String> includes) {
this.includes = includes;
}

@Override
public String toString() {
ToStringBuilder b = new ToStringBuilder(this);
b.add("includes", this.includes);
return b.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.qute.jdt.internal.extensions.roq;

import java.util.Arrays;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchPattern;

import com.redhat.qute.commons.datamodel.DataModelParameter;
import com.redhat.qute.commons.datamodel.DataModelTemplate;
import com.redhat.qute.commons.datamodel.DataModelTemplateMatcher;
import com.redhat.qute.jdt.template.datamodel.AbstractDataModelProvider;
import com.redhat.qute.jdt.template.datamodel.SearchContext;
import com.redhat.qute.jdt.utils.JDTTypeUtils;

/**
* Inject 'site' and 'page' as data model parameters for all Qute templates
* which belong to a Roq application.
*/
public class RoqDataModelProvider extends AbstractDataModelProvider {

@Override
public void beginSearch(SearchContext context, IProgressMonitor monitor) {
if (JDTTypeUtils.findType(context.getJavaProject(), RoqJavaConstants.SITE_CLASS) == null) {
// It is not a Roq application, don't inject site and page.
return;
}

DataModelTemplate<DataModelParameter> roqTemplate = new DataModelTemplate<DataModelParameter>();
roqTemplate.setTemplateMatcher(new DataModelTemplateMatcher(Arrays.asList("**/**")));

// site
DataModelParameter site = new DataModelParameter();
site.setKey("site");
site.setSourceType("io.quarkiverse.roq.frontmatter.runtime.model.Site");
roqTemplate.addParameter(site);

// page
DataModelParameter page = new DataModelParameter();
page.setKey("page");
page.setSourceType("io.quarkiverse.roq.frontmatter.runtime.model.Page");
roqTemplate.addParameter(page);

context.getDataModelProject().getTemplates().add(roqTemplate);
}

@Override
public void collectDataModel(SearchMatch match, SearchContext context, IProgressMonitor monitor) {
// Do nothing
}

@Override
protected String[] getPatterns() {
return null;
}

@Override
protected SearchPattern createSearchPattern(String pattern) {
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.redhat.qute.commons.datamodel.resolvers.NamespaceResolverInfo;
import com.redhat.qute.commons.datamodel.resolvers.ValueResolverInfo;
import com.redhat.qute.project.datamodel.ExtendedDataModelTemplate;

/**
* Data model project hosts for a given Qute project:
Expand Down Expand Up @@ -124,7 +125,12 @@ public String getUriWithoutExtension(String templateUri) {

private T findDataModelTemplate(String templateUri, List<T> templates) {
Optional<T> dataModelForTemplate = templates.stream() //
.filter(t -> templateUri.endsWith(t.getTemplateUri())) //
.filter(t -> {
if (t instanceof ExtendedDataModelTemplate) {
return ((ExtendedDataModelTemplate) t).matches(templateUri);
}
return templateUri.endsWith(t.getTemplateUri());
}) //
.findFirst();
if (dataModelForTemplate.isPresent()) {
return dataModelForTemplate.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public class DataModelTemplate<T extends DataModelParameter> extends DataModelBa

private String templateUri;

private DataModelTemplateMatcher templateMatcher;

private String sourceField;

private List<DataModelFragment<T>> fragments;
Expand All @@ -50,6 +52,14 @@ public void setTemplateUri(String templateUri) {
this.templateUri = templateUri;
}

public DataModelTemplateMatcher getTemplateMatcher() {
return templateMatcher;
}

public void setTemplateMatcher(DataModelTemplateMatcher templateMatcher) {
this.templateMatcher = templateMatcher;
}

/**
* Returns the Java source field where this data model template is defined and
* null otherwise.
Expand Down Expand Up @@ -131,6 +141,7 @@ public DataModelFragment<T> getFragment(String fragmentId) {
public String toString() {
ToStringBuilder b = new ToStringBuilder(this);
b.add("templateUri", this.templateUri);
b.add("templateMatcher", this.templateMatcher);
b.add("sourceType", this.getSourceType());
b.add("sourceMethod", this.getSourceMethod());
b.add("sourceField", this.sourceField);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.qute.commons.datamodel;

import java.util.List;

import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;

/**
* Data model template matcher used to inject data parameters with patterns.
*/
public class DataModelTemplateMatcher {

private List<String> includes;

public DataModelTemplateMatcher() {

}

public DataModelTemplateMatcher(List<String> includes) {
setIncludes(includes);
}

public List<String> getIncludes() {
return includes;
}

public void setIncludes(List<String> includes) {
this.includes = includes;
}

@Override
public String toString() {
ToStringBuilder b = new ToStringBuilder(this);
b.add("includes", this.includes);
return b.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
public class ExtendedDataModelTemplate extends DataModelTemplate<ExtendedDataModelParameter>
implements DataModelSourceProvider {

private ExtendedDataModelTemplateMatcher templateMatcher;

public ExtendedDataModelTemplate(DataModelTemplate<DataModelParameter> template) {
super.setTemplateUri(template.getTemplateUri());
super.setTemplateMatcher(template.getTemplateMatcher());
super.setSourceType(template.getSourceType());
super.setSourceMethod(template.getSourceMethod());
super.setSourceField(template.getSourceField());
Expand Down Expand Up @@ -64,4 +67,17 @@ public QuteJavaDefinitionParams toJavaDefinitionParams(String projectUri) {
params.setSourceMethod(sourceMethod);
return params;
}

public boolean matches(String templateUri) {
if (getTemplateUri() != null && templateUri.endsWith(getTemplateUri())) {
return true;
}
if (super.getTemplateMatcher() == null) {
return false;
}
if (templateMatcher == null) {
templateMatcher = new ExtendedDataModelTemplateMatcher(super.getTemplateMatcher().getIncludes());
}
return templateMatcher.matches(templateUri);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package com.redhat.qute.project.datamodel;

import java.net.URI;
import java.util.List;
import java.util.stream.Collectors;

import com.redhat.qute.commons.FileUtils;
import com.redhat.qute.commons.datamodel.DataModelTemplateMatcher;
import com.redhat.qute.settings.PathPatternMatcher;

/**
* Data model template matcher extension.
*/
public class ExtendedDataModelTemplateMatcher extends DataModelTemplateMatcher {

private Boolean anyMatches;

private List<PathPatternMatcher> includes;

public ExtendedDataModelTemplateMatcher(List<String> includes) {
super(includes);
}

public boolean matches(String templateFileUri) {
if (super.getIncludes() == null) {
return false;
}
if (includes == null && anyMatches == null) {
// Compute anyMatches flag or path pattern matcher.
if (super.getIncludes().size() == 1
&& ("**".equals(super.getIncludes().get(0)) || "**/**".equals(super.getIncludes().get(0)))) {
// To avoid computing path pattern matcher, if pattern is '**' or '**/**'
// we consider that it is an any matches.
anyMatches = true;
} else {
includes = super.getIncludes() //
.stream() //
.map(p -> new PathPatternMatcher(p)) //
.collect(Collectors.toList());
}
}

if (anyMatches != null && anyMatches) {
// Pattern is '**' or '**/**'
return true;
}

// Checks if the template uri matches the includes which defines glob pattern
URI uri = FileUtils.createUri(templateFileUri);
for (PathPatternMatcher include : includes) {
if (include.matches(uri)) {
return true;
}
}
return false;
}

}
Loading

0 comments on commit 52b6008

Please sign in to comment.