Skip to content

Commit

Permalink
Merge pull request #407 from wttech/add-data-source-support
Browse files Browse the repository at this point in the history
added data source support
  • Loading branch information
dprzybyl authored Nov 2, 2023
2 parents 5075f19 + f134354 commit 6afd12a
Show file tree
Hide file tree
Showing 27 changed files with 932 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@
public class ActionGroup {

public static final String CORE = "core";

public static final String DATASOURCE = "datasource";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* ========================LICENSE_START=================================
* AEM Permission Management
* %%
* Copyright (C) 2013 Wunderman Thompson Technology
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
package com.cognifide.apm.main.actions.internal.datasources;

import com.cognifide.apm.api.actions.Action;
import com.cognifide.apm.api.actions.annotations.Mapper;
import com.cognifide.apm.api.actions.annotations.Mapping;
import com.cognifide.apm.api.actions.annotations.Required;
import com.cognifide.apm.main.actions.ActionGroup;
import java.util.List;
import org.apache.commons.lang3.NotImplementedException;

@Mapper(value = "LEVELS", group = ActionGroup.DATASOURCE)
public class LevelsMapper {

@Mapping(
examples = "LEVELS('/content', [\n" +
"\t{regex: '(.+)_(.+)',paramNames: ['param1', 'param2']}, # 1st level\n" +
"\t{excludeRegex: '.+:.+'}, # 2nd level\n" +
"\t{template: '/apps/test/pageTemplate', resourceType: 'test/pageRenderer'}, # 3rd level\n" +
"\t{properties: [ # 4th level\n" +
"\t\t{name: 'jcr:primaryType', regex: 'cq:Page'},\n" +
"\t\t{name: 'jcr:primaryType', excludeRegex: 'cq:PageContent'},\n" +
"\t\t{name: 'jcr:content/cq:template', regex: '/apps/test/pageTemplate'},\n" +
"\t\t{name: 'jcr:content/sling:resourceType', regex: 'test/pageRenderer'}\n" +
"\t]}\n" +
"])",
reference = "Provides levels of content for given resource path matching given content structure map"
)
public Action mapAction(
@Required(value = "rootPath", description = "Root path") String rootPath,
@Required(value = "structureMap", description = "Map of content structure") List<Object> structureMap) {
throw new NotImplementedException("");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* ========================LICENSE_START=================================
* AEM Permission Management
* %%
* Copyright (C) 2013 Wunderman Thompson Technology
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
package com.cognifide.apm.main.actions.internal.datasources;

import com.cognifide.apm.api.actions.Action;
import com.cognifide.apm.api.actions.annotations.Mapper;
import com.cognifide.apm.api.actions.annotations.Mapping;
import com.cognifide.apm.api.actions.annotations.Required;
import com.cognifide.apm.main.actions.ActionGroup;
import org.apache.commons.lang3.NotImplementedException;

@Mapper(value = "LOWER", group = ActionGroup.DATASOURCE)
public class LowerMapper {

@Mapping(
examples = "LOWER('en_GB')",
reference = "Converts string to lower case"
)
public Action mapAction(
@Required(value = "value", description = "string") String value) {
throw new NotImplementedException("");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* ========================LICENSE_START=================================
* AEM Permission Management
* %%
* Copyright (C) 2013 Wunderman Thompson Technology
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
package com.cognifide.apm.main.actions.internal.datasources;

import com.cognifide.apm.api.actions.Action;
import com.cognifide.apm.api.actions.annotations.Mapper;
import com.cognifide.apm.api.actions.annotations.Mapping;
import com.cognifide.apm.api.actions.annotations.Required;
import com.cognifide.apm.main.actions.ActionGroup;
import org.apache.commons.lang3.NotImplementedException;

@Mapper(value = "UPPER", group = ActionGroup.DATASOURCE)
public class UpperMapper {

@Mapping(
examples = "UPPER('en_GB')",
reference = "Converts string to upper case"
)
public Action mapAction(
@Required(value = "value", description = "string") String value) {
throw new NotImplementedException("");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* ========================LICENSE_START=================================
* AEM Permission Management
* %%
* Copyright (C) 2013 Wunderman Thompson Technology
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
package com.cognifide.apm.main.actions.internal.datasources;

import com.cognifide.apm.api.actions.Action;
import com.cognifide.apm.api.actions.annotations.Mapper;
import com.cognifide.apm.api.actions.annotations.Mapping;
import com.cognifide.apm.api.actions.annotations.Required;
import com.cognifide.apm.main.actions.ActionGroup;
import java.util.Map;
import org.apache.commons.lang3.NotImplementedException;

@Mapper(value = "VALUEMAP", group = ActionGroup.DATASOURCE)
public class ValueMapMapper {

@Mapping(
examples = "VALUEMAP('/content/dam')",
reference = "Provides value map with all properties for given resource path"
)
public Action mapAction(
@Required(value = "path", description = "Resource path") String path) {
throw new NotImplementedException("");
}

@Mapping(
examples = "VALUEMAP('/content/dam', {\n" +
"\tregex: 'prop.+',\n" +
"\texcludeRegex: '.+:.+'\n" +
"})",
reference = "Provides value map with properties which matching given regex expressions for given resource path"
)
public Action mapAction(
@Required(value = "path", description = "Resource path") String path,
@Required(value = "regexMap", description = "Map of regex expressions") Map<String, String> regex) {
throw new NotImplementedException("");
}
}
13 changes: 12 additions & 1 deletion app/aem/core/src/main/antlr/ApmLang.g4
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ structureKey
| STRING_LITERAL
;

dataSource
: identifier BRACKET_BEGIN (argument (COMMA argument)*)? BRACKET_END
;

structureValue
: value
| argument
Expand Down Expand Up @@ -103,6 +107,7 @@ plus
expression
: expression plus expression
| value
| dataSource
;

argument
Expand Down Expand Up @@ -176,6 +181,12 @@ STRUCTURE_BEGIN
STRUCTURE_END
: '}'
;
BRACKET_BEGIN
: '('
;
BRACKET_END
: ')'
;
COMMA
: ','
;
Expand Down Expand Up @@ -271,7 +282,7 @@ fragment IdentifierPart
: Letter LetterOrDigit*
;
fragment VariablePart
: IdentifierPart (ARRAY_BEGIN LetterOrDigit+ ARRAY_END)?
: IdentifierPart (ARRAY_BEGIN (NUMBER_LITERAL | IDENTIFIER | STRING_LITERAL) ARRAY_END)*
;
fragment PathPart
: '/' (~[\r\n\t ])+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.cognifide.apm.core.grammar.antlr.ApmLangBaseVisitor;
import com.cognifide.apm.core.grammar.antlr.ApmLangParser;
import com.cognifide.apm.core.grammar.common.Functions;
import com.cognifide.apm.core.grammar.datasource.DataSourceInvoker;
import com.cognifide.apm.core.grammar.executioncontext.ExecutionContext;
import com.cognifide.apm.core.grammar.parsedscript.ParsedScript;
import com.cognifide.apm.core.progress.ProgressImpl;
Expand All @@ -46,9 +47,12 @@ public class ReferenceFinder {

private final ResourceResolver resourceResolver;

public ReferenceFinder(ScriptFinder scriptFinder, ResourceResolver resourceResolver) {
private final DataSourceInvoker dataSourceInvoker;

public ReferenceFinder(ScriptFinder scriptFinder, ResourceResolver resourceResolver, DataSourceInvoker dataSourceInvoker) {
this.scriptFinder = scriptFinder;
this.resourceResolver = resourceResolver;
this.dataSourceInvoker = dataSourceInvoker;
}

public List<Script> findReferences(Script script) {
Expand Down Expand Up @@ -81,7 +85,7 @@ public ReferenceGraph getReferenceGraph(Script... scripts) {
private void fillReferenceGraph(ReferenceGraph refGraph, Script script) {
if (refGraph.getNode(script) == null) {
ApmLangParser.ApmContext apmContext = ParsedScript.create(script).getApm();
ExecutionContext executionContext = ExecutionContext.create(scriptFinder, resourceResolver, script, new ProgressImpl(resourceResolver.getUserID()));
ExecutionContext executionContext = ExecutionContext.create(scriptFinder, resourceResolver, dataSourceInvoker, script, new ProgressImpl(resourceResolver.getUserID()));
findReferences(refGraph, refGraph.addNode(script), ImmutableList.of(script.getPath()), executionContext, apmContext);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.cognifide.apm.core.grammar.argument.ArgumentResolverException;
import com.cognifide.apm.core.grammar.argument.Arguments;
import com.cognifide.apm.core.grammar.common.Functions;
import com.cognifide.apm.core.grammar.datasource.DataSourceInvoker;
import com.cognifide.apm.core.grammar.executioncontext.ExecutionContext;
import com.cognifide.apm.core.grammar.parsedscript.InvalidSyntaxException;
import com.cognifide.apm.core.grammar.parsedscript.InvalidSyntaxMessageFactory;
Expand Down Expand Up @@ -69,16 +70,19 @@ public class ScriptRunner {

private final ActionInvoker actionInvoker;

public ScriptRunner(ScriptFinder scriptFinder, ResourceResolver resourceResolver, boolean validateOnly, ActionInvoker actionInvoker) {
private final DataSourceInvoker dataSourceInvoker;

public ScriptRunner(ScriptFinder scriptFinder, ResourceResolver resourceResolver, boolean validateOnly, ActionInvoker actionInvoker, DataSourceInvoker dataSourceInvoker) {
this.scriptFinder = scriptFinder;
this.resourceResolver = resourceResolver;
this.validateOnly = validateOnly;
this.actionInvoker = actionInvoker;
this.dataSourceInvoker = dataSourceInvoker;
}

public Progress execute(Script script, Progress progress, Map<String, String> initialDefinitions) {
try {
ExecutionContext executionContext = ExecutionContext.create(scriptFinder, resourceResolver, script, progress);
ExecutionContext executionContext = ExecutionContext.create(scriptFinder, resourceResolver, dataSourceInvoker, script, progress);
initialDefinitions.forEach((name, value) -> executionContext.setVariable(name, new ApmString(value)));
Executor executor = new Executor(executionContext);
executor.visit(executionContext.getRoot().getApm());
Expand Down Expand Up @@ -268,7 +272,7 @@ private Status visitGenericCommandValidateMode(ParserRuleContext ctx, String com

@Override
public Status visitImportScript(ImportScriptContext ctx) {
ImportScript.Result result = new ImportScript(executionContext).importScript(ctx);
ImportScript.Result result = new ImportScript(executionContext, resourceResolver, dataSourceInvoker).importScript(ctx);
executionContext.getVariableHolder().setAll(result.getVariableHolder());
progress(ctx, Status.SUCCESS, "import", result.toMessages());
return Status.SUCCESS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.cognifide.apm.core.grammar.antlr.ApmLangBaseVisitor;
import com.cognifide.apm.core.grammar.antlr.ApmLangParser;
import com.cognifide.apm.core.grammar.common.Functions;
import com.cognifide.apm.core.grammar.datasource.DataSourceInvoker;
import com.cognifide.apm.core.grammar.executioncontext.VariableHolder;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -44,15 +45,22 @@
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang.text.StrSubstitutor;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.ResourceResolver;

public class ArgumentResolver {

private final VariableHolder variableHolder;

private final SingleArgumentResolver singleArgumentResolver;

public ArgumentResolver(VariableHolder variableHolder) {
private final ResourceResolver resourceResolver;

private final DataSourceInvoker dataSourceInvoker;

public ArgumentResolver(VariableHolder variableHolder, ResourceResolver resourceResolver, DataSourceInvoker dataSourceInvoker) {
this.variableHolder = variableHolder;
this.resourceResolver = resourceResolver;
this.dataSourceInvoker = dataSourceInvoker;
this.singleArgumentResolver = new SingleArgumentResolver();
}

Expand Down Expand Up @@ -152,8 +160,8 @@ public ApmType visitStructure(ApmLangParser.StructureContext ctx) {
.collect(Collectors.toMap(
ApmPair::getKey,
ApmPair::getValue,
(key, value) -> {
throw new IllegalStateException(String.format("Duplicate key %s", key));
(existing, replacement) -> {
throw new IllegalStateException("Duplicate key");
},
LinkedHashMap::new
));
Expand Down Expand Up @@ -193,6 +201,8 @@ public ApmType visitExpression(ApmLangParser.ExpressionContext ctx) {
}
} else if (ctx.value() != null) {
return visit(ctx.value());
} else if (ctx.dataSource() != null) {
return visit(ctx.dataSource());
} else {
return super.visitExpression(ctx);
}
Expand Down Expand Up @@ -239,5 +249,17 @@ public ApmType visitVariable(ApmLangParser.VariableContext ctx) {
String name = Functions.getIdentifier(ctx.variableIdentifier());
return variableHolder.get(name);
}

@Override
public ApmType visitDataSource(ApmLangParser.DataSourceContext ctx) {
String name = Functions.getIdentifier(ctx.identifier());
List<ApmType> values = ctx.children
.stream()
.map(child -> child.accept(this))
.filter(value -> !(value instanceof ApmEmpty))
.collect(Collectors.toList());
return Optional.ofNullable(dataSourceInvoker.determine(name, resourceResolver, values))
.orElseThrow(() -> new ArgumentResolverException(String.format("Data source \"%s\" not found", name.toUpperCase())));
}
}
}
Loading

0 comments on commit 6afd12a

Please sign in to comment.