Skip to content

Commit

Permalink
[KOGITO-9594] Adding new relative scheme (#3183)
Browse files Browse the repository at this point in the history
* [KOGITO-9594] Refactoring URIContentLoader

* [KOGITO-9594] More refactoring

* [KOGITO-9594] Supporting nested schema

* [KOGITO-5954] Supporting Java serialization for WorkflowValidator

* [KOGITO-9594] Sonar is...

* [KOGITO-9594] Handling absolute paths

* Helbers comments

Co-authored-by: Helber Belmiro <[email protected]>

---------

Co-authored-by: Helber Belmiro <[email protected]>
  • Loading branch information
fjtirado and hbelmiro committed Aug 25, 2023
1 parent e150fa8 commit 75eb858
Show file tree
Hide file tree
Showing 51 changed files with 737 additions and 544 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import org.drools.codegen.common.GeneratedFile;
import org.drools.codegen.common.GeneratedFileType;
import org.drools.io.InternalResource;
import org.jbpm.bpmn2.xml.BPMNDISemanticModule;
import org.jbpm.bpmn2.xml.BPMNExtensionsSemanticModule;
import org.jbpm.bpmn2.xml.BPMNSemanticModule;
Expand Down Expand Up @@ -120,7 +121,7 @@ public static ProcessCodegen ofCollectedResources(KogitoBuildContext context, Co
}
return p.stream().map(KogitoWorkflowProcess.class::cast).map(GeneratedInfo::new).map(info -> addResource(info, resource));
} else if (SupportedExtensions.getSWFExtensions().stream().anyMatch(resource.getSourcePath()::endsWith)) {
GeneratedInfo<KogitoWorkflowProcess> generatedInfo = parseWorkflowFile(resource, WorkflowFormat.fromFileName(resource.getSourcePath()), context);
GeneratedInfo<KogitoWorkflowProcess> generatedInfo = parseWorkflowFile(resource, context);
notifySourceFileCodegenBindListeners(context, resource, Collections.singletonList(generatedInfo.info()));
return Stream.of(addResource(generatedInfo, resource));
}
Expand Down Expand Up @@ -212,9 +213,16 @@ private static ProcessCodegen ofProcesses(KogitoBuildContext context, List<Gener
return new ProcessCodegen(context, processes);
}

protected static GeneratedInfo<KogitoWorkflowProcess> parseWorkflowFile(Resource r, WorkflowFormat format, KogitoBuildContext context) {
try (Reader reader = r.getReader()) {
return ServerlessWorkflowParser.of(reader, format, context).getProcessInfo();
protected static GeneratedInfo<KogitoWorkflowProcess> parseWorkflowFile(Resource r, KogitoBuildContext context) {
InternalResource resource = (InternalResource) r;
try (Reader reader = resource.getReader()) {
ServerlessWorkflowParser parser = ServerlessWorkflowParser.of(reader, WorkflowFormat.fromFileName(resource.getSourcePath()), context);
if (resource.hasURL()) {
parser.withBaseURI(resource.getURL());
} else {
parser.withBaseURI("classpath:" + resource.getSourcePath());
}
return parser.getProcessInfo();
} catch (Exception e) {
throw new ProcessParsingException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.kie.kogito.codegen.api.context.impl.JavaKogitoBuildContext;
import org.kie.kogito.internal.SupportedExtensions;
import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
import org.kie.kogito.serverless.workflow.utils.WorkflowFormat;

/**
* Utilities for unit Process generation tests
Expand Down Expand Up @@ -62,7 +61,7 @@ private static List<Process> parseProcesses(Collection<File> processFiles) {
if (SupportedExtensions.getBPMNExtensions().stream().anyMatch(processSourceFile.getPath()::endsWith)) {
processes.addAll(ProcessCodegen.parseProcessFile(r));
} else if (SupportedExtensions.getSWFExtensions().stream().anyMatch(processSourceFile.getPath()::endsWith)) {
processes.add(ProcessCodegen.parseWorkflowFile(r, WorkflowFormat.fromFileName(processSourceFile.getPath()), JavaKogitoBuildContext.builder().build()).info());
processes.add(ProcessCodegen.parseWorkflowFile(r, JavaKogitoBuildContext.builder().build()).info());
}
if (processes.isEmpty()) {
throw new IllegalArgumentException("Unable to process file with unsupported extension: " + processSourceFile);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,39 @@
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.URL;
import java.util.Objects;
import java.util.Optional;

public class ClassPathContentLoader extends CachedContentLoader {

private final Optional<URL> resource;
private final String path;

public ClassPathContentLoader(URI uri, Optional<ClassLoader> cl) {
ClassPathContentLoader(URI uri, Optional<ClassLoader> cl) {
super(uri);
this.path = getPath(uri);
this.resource = Optional.ofNullable(cl.orElse(Thread.currentThread().getContextClassLoader()).getResource(path));
}

private static String getPath(URI uri) {
String path = uri.getPath();
Objects.requireNonNull(path, "classpath cannot be null");
while (path.startsWith("/")) {
path = path.substring(1);
static String getPath(URI uri) {
final String classPathPrefix = "classpath:";
String str = uri.toString();
if (str.toLowerCase().startsWith(classPathPrefix)) {
str = str.substring(classPathPrefix.length());
while (str.startsWith("/")) {
str = str.substring(1);
}
}
return path;
return str;
}

public Optional<URL> getResource() {
return resource;
}

public String getPath() {
return path;
}

@Override
protected byte[] loadURI(URI uri) {
return resource.map(this::loadBytes).orElseThrow(() -> new IllegalArgumentException("cannot find classpath resource " + path));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;

public class FileContentLoader extends FallbackContentLoader {
public class FileContentLoader extends CachedContentLoader {

private final Path path;

public FileContentLoader(URI uri, Optional<URIContentLoader> fallbackLoader) {
super(uri, fallbackLoader);
this.path = Path.of(uri);
FileContentLoader(URI uri) {
super(uri);
this.path = Path.of(getPath(uri));
}

public Path getPath() {
Expand All @@ -48,4 +47,8 @@ protected byte[] loadURI(URI uri) {
throw new UncheckedIOException(io);
}
}

static String getPath(URI uri) {
return uri.getPath();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@
import io.serverlessworkflow.api.auth.OauthDefinition;
import io.serverlessworkflow.api.workflow.Auth;

class HttpContentLoader extends FallbackContentLoader {
class HttpContentLoader extends CachedContentLoader {

private static final Logger logger = LoggerFactory.getLogger(HttpContentLoader.class);

private Optional<Workflow> workflow;
private String authRef;

public HttpContentLoader(URI uri, Optional<URIContentLoader> fallback, Optional<Workflow> workflow, String authRef) {
super(uri, fallback);
HttpContentLoader(URI uri, Optional<Workflow> workflow, String authRef) {
super(uri);
this.workflow = workflow;
this.authRef = authRef;
}
Expand Down Expand Up @@ -133,6 +133,7 @@ private String eval(String expr) {
return BuildEvaluator.eval(ExpressionHandlerUtils.trimExpr(expr));
}

@SuppressWarnings("squid:S2647")
private void basicAuth(HttpURLConnection conn, BasicAuthDefinition basicAuth) {
conn.setRequestProperty("Authorization", "Basic " + encode(eval(basicAuth.getUsername()) + ":" + eval(basicAuth.getPassword())));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates.
*
* 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.
*/
package org.kie.kogito.serverless.workflow.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Optional;

import org.kie.kogito.serverless.workflow.parser.ParserContext;

import io.serverlessworkflow.api.Workflow;

import static org.kie.kogito.serverless.workflow.utils.ServerlessWorkflowUtils.getBaseURI;

public class URIContentLoaderFactory {

public static byte[] readAllBytes(URIContentLoader loader) {
try (InputStream is = loader.getInputStream()) {
return is.readAllBytes();
} catch (IOException io) {
throw new UncheckedIOException(io);
}
}

public static byte[] readAllBytes(Builder builder) {
return readAllBytes(builder.build());
}

public static String readString(URIContentLoader loader) {
return new String(readAllBytes(loader));
}

public static String getFileName(URI uri) {
URIContentLoaderType type = URIContentLoaderType.from(uri);
String path = uriToPath(type, uri);
return type.lastPart(path);
}

private static String uriToPath(URIContentLoaderType type, URI uri) {
switch (type) {
case CLASSPATH:
return ClassPathContentLoader.getPath(uri);
case FILE:
return FileContentLoader.getPath(uri);
case HTTP:
default:
return uri.getPath();
}
}

public static String readString(Builder builder) {
return readString(builder.build());
}

public static URIContentLoader buildLoader(URI uri, Workflow workflow, Optional<ParserContext> context, String authRef) {
Builder builder = new Builder(uri).withWorkflow(workflow).withAuthRef(authRef);
context.map(c -> c.getContext().getClassLoader()).ifPresent(builder::withClassloader);
getBaseURI(workflow).ifPresent(builder::withBaseURI);
return builder.build();
}

public static byte[] readBytes(String uriStr, Workflow workflow, ParserContext parserContext) {
return readBytes(uriStr, workflow, Optional.ofNullable(parserContext));
}

public static byte[] readBytes(String uriStr, Workflow workflow, Optional<ParserContext> parserContext) {
return readAllBytes(buildLoader(URI.create(uriStr), workflow, parserContext, null));
}

public static Builder builder(URI uri) {
return new Builder(uri);
}

public static Builder builder(String uri) {
return new Builder(URI.create(uri));
}

public static class Builder {
private URI uri;
private ClassLoader cl;
private Workflow workflow;
private String authRef;
private URI baseURI;

private Builder(URI uri) {
this.uri = uri;
}

public Builder withClassloader(ClassLoader cl) {
this.cl = cl;
return this;
}

public Builder withWorkflow(Workflow workflow) {
this.workflow = workflow;
return this;
}

public Builder withAuthRef(String authRef) {
this.authRef = authRef;
return this;
}

public Builder withBaseURI(URI baseURI) {
this.baseURI = baseURI;
return this;
}

public URIContentLoader build() {
if (baseURI != null) {
uri = compoundURI(baseURI, uri);
}
switch (URIContentLoaderType.from(uri)) {
default:
case FILE:
return new FileContentLoader(uri);
case HTTP:
return new HttpContentLoader(uri, Optional.ofNullable(workflow), authRef);
case CLASSPATH:
return new ClassPathContentLoader(uri, Optional.ofNullable(cl));
}
}
}

public static URI compoundURI(URI baseURI, URI uri) {
if (uri.getScheme() != null) {
return uri;
}
URIContentLoaderType type = URIContentLoaderType.from(baseURI);
String basePath = type.trimLast(uriToPath(type, baseURI));
String additionalPath = uriToPath(type, uri);
String path;
if (type.isAbsolutePath(additionalPath)) {
path = additionalPath;
} else {
path = type.concat(basePath, additionalPath);
}
try {
return new URI(type.toString().toLowerCase(), baseURI.getAuthority(), path, uri.getQuery(), uri.getFragment());
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
}

private URIContentLoaderFactory() {
}
}
Loading

0 comments on commit 75eb858

Please sign in to comment.