You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2020/05/20 22:01:20 UTC
[incubator-streampipes] branch dev updated: [STREAMPIPES-134]: Add
initial version of UserDefinedOutputStrategy
This is an automated email from the ASF dual-hosted git repository.
riemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git
The following commit(s) were added to refs/heads/dev by this push:
new c5d8ecd [STREAMPIPES-134]: Add initial version of UserDefinedOutputStrategy
c5d8ecd is described below
commit c5d8ecd9f50ec88cb3180682b13e2a2d49c08bdd
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Thu May 21 00:01:07 2020 +0200
[STREAMPIPES-134]: Add initial version of UserDefinedOutputStrategy
---
.../model/output/UserDefinedOutputStrategy.java | 57 ++++++++++++++
.../org/apache/streampipes/model/util/Cloner.java | 13 +---
.../matching/output/OutputSchemaFactory.java | 11 +--
.../output/UserDefinedOutputSchemaGenerator.java | 50 +++++++++++++
.../streampipes/sdk/helpers/OutputStrategies.java | 18 +++--
.../jsonld/CustomAnnotationProvider.java | 1 +
.../apache/streampipes/vocabulary/StreamPipes.java | 1 +
.../user-defined-output.component.ts | 33 ++++++++
.../user-defined-output.controller.ts | 87 ++++++++++++++++++++++
.../user-defined-output.tmpl.html | 55 ++++++++++++++
.../customizeElementDialog.tmpl.html | 12 ++-
ui/src/app/editor/editor.module.ts | 2 +
12 files changed, 312 insertions(+), 28 deletions(-)
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/output/UserDefinedOutputStrategy.java b/streampipes-model/src/main/java/org/apache/streampipes/model/output/UserDefinedOutputStrategy.java
new file mode 100644
index 0000000..e364dc3
--- /dev/null
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/output/UserDefinedOutputStrategy.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.streampipes.model.output;
+
+import io.fogsy.empire.annotations.RdfProperty;
+import io.fogsy.empire.annotations.RdfsClass;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.vocabulary.StreamPipes;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.OneToMany;
+import java.util.List;
+
+@RdfsClass(StreamPipes.USER_DEFINED_OUTPUT_STRATEGY)
+@Entity
+public class UserDefinedOutputStrategy extends OutputStrategy {
+
+ @OneToMany(fetch = FetchType.EAGER,
+ cascade = {CascadeType.ALL})
+ @RdfProperty(StreamPipes.PRODUCES_PROPERTY)
+ private List<EventProperty> eventProperties;
+
+ public UserDefinedOutputStrategy() {
+ super();
+ }
+
+ public UserDefinedOutputStrategy(UserDefinedOutputStrategy other) {
+ super(other);
+ this.eventProperties = other.getEventProperties();
+ }
+
+ public List<EventProperty> getEventProperties() {
+ return eventProperties;
+ }
+
+ public void setEventProperties(List<EventProperty> eventProperties) {
+ this.eventProperties = eventProperties;
+ }
+}
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/util/Cloner.java b/streampipes-model/src/main/java/org/apache/streampipes/model/util/Cloner.java
index 4f66239..7d3b871 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/util/Cloner.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/util/Cloner.java
@@ -18,6 +18,7 @@
package org.apache.streampipes.model.util;
+import org.apache.streampipes.model.output.*;
import org.apache.streampipes.model.staticproperty.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,16 +43,6 @@ import org.apache.streampipes.model.grounding.TransportFormat;
import org.apache.streampipes.model.grounding.TransportProtocol;
import org.apache.streampipes.model.grounding.WildcardTopicDefinition;
import org.apache.streampipes.model.grounding.WildcardTopicMapping;
-import org.apache.streampipes.model.output.AppendOutputStrategy;
-import org.apache.streampipes.model.output.CustomOutputStrategy;
-import org.apache.streampipes.model.output.CustomTransformOutputStrategy;
-import org.apache.streampipes.model.output.FixedOutputStrategy;
-import org.apache.streampipes.model.output.KeepOutputStrategy;
-import org.apache.streampipes.model.output.ListOutputStrategy;
-import org.apache.streampipes.model.output.OutputStrategy;
-import org.apache.streampipes.model.output.PropertyRenameRule;
-import org.apache.streampipes.model.output.TransformOperation;
-import org.apache.streampipes.model.output.TransformOutputStrategy;
import org.apache.streampipes.model.quality.Accuracy;
import org.apache.streampipes.model.quality.EventPropertyQualityDefinition;
import org.apache.streampipes.model.quality.EventPropertyQualityRequirement;
@@ -89,6 +80,8 @@ public class Cloner {
return new TransformOutputStrategy((TransformOutputStrategy) other);
} else if (other instanceof CustomTransformOutputStrategy) {
return new CustomTransformOutputStrategy((CustomTransformOutputStrategy) other);
+ } else if (other instanceof UserDefinedOutputStrategy) {
+ return new UserDefinedOutputStrategy((UserDefinedOutputStrategy) other);
} else {
return new AppendOutputStrategy((AppendOutputStrategy) other);
}
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/matching/output/OutputSchemaFactory.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/matching/output/OutputSchemaFactory.java
index 9859a06..2828b8a 100644
--- a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/matching/output/OutputSchemaFactory.java
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/matching/output/OutputSchemaFactory.java
@@ -19,14 +19,7 @@
package org.apache.streampipes.manager.matching.output;
import org.apache.streampipes.model.graph.DataProcessorInvocation;
-import org.apache.streampipes.model.output.AppendOutputStrategy;
-import org.apache.streampipes.model.output.CustomOutputStrategy;
-import org.apache.streampipes.model.output.CustomTransformOutputStrategy;
-import org.apache.streampipes.model.output.FixedOutputStrategy;
-import org.apache.streampipes.model.output.KeepOutputStrategy;
-import org.apache.streampipes.model.output.ListOutputStrategy;
-import org.apache.streampipes.model.output.OutputStrategy;
-import org.apache.streampipes.model.output.TransformOutputStrategy;
+import org.apache.streampipes.model.output.*;
public class OutputSchemaFactory {
@@ -53,6 +46,8 @@ public class OutputSchemaFactory {
return TransformOutputSchemaGenerator.from(outputStrategy, dataProcessorInvocation);
} else if (outputStrategy instanceof CustomTransformOutputStrategy) {
return CustomTransformOutputSchemaGenerator.from(outputStrategy, dataProcessorInvocation);
+ } else if (outputStrategy instanceof UserDefinedOutputStrategy) {
+ return UserDefinedOutputSchemaGenerator.from(outputStrategy);
} else {
throw new IllegalArgumentException();
}
diff --git a/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/matching/output/UserDefinedOutputSchemaGenerator.java b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/matching/output/UserDefinedOutputSchemaGenerator.java
new file mode 100644
index 0000000..e070f98
--- /dev/null
+++ b/streampipes-pipeline-management/src/main/java/org/apache/streampipes/manager/matching/output/UserDefinedOutputSchemaGenerator.java
@@ -0,0 +1,50 @@
+package org.apache.streampipes.manager.matching.output;/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+
+import org.apache.streampipes.model.SpDataStream;
+import org.apache.streampipes.model.output.OutputStrategy;
+import org.apache.streampipes.model.output.UserDefinedOutputStrategy;
+import org.apache.streampipes.model.schema.EventProperty;
+import org.apache.streampipes.model.schema.EventSchema;
+import org.apache.streampipes.sdk.helpers.Tuple2;
+
+import java.util.List;
+
+public class UserDefinedOutputSchemaGenerator extends OutputSchemaGenerator<UserDefinedOutputStrategy> {
+
+ private List<EventProperty> producedProperties;
+
+ public static UserDefinedOutputSchemaGenerator from(OutputStrategy strategy) {
+ return new UserDefinedOutputSchemaGenerator((UserDefinedOutputStrategy) strategy);
+ }
+
+ public UserDefinedOutputSchemaGenerator(UserDefinedOutputStrategy strategy) {
+ super(strategy);
+ this.producedProperties = strategy.getEventProperties();
+ }
+
+ @Override
+ public Tuple2<EventSchema, UserDefinedOutputStrategy> buildFromOneStream(SpDataStream stream) {
+ return makeTuple(new EventSchema(producedProperties));
+ }
+
+ @Override
+ public Tuple2<EventSchema, UserDefinedOutputStrategy> buildFromTwoStreams(SpDataStream stream1, SpDataStream stream2) {
+ return buildFromOneStream(stream1);
+ }
+}
diff --git a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/helpers/OutputStrategies.java b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/helpers/OutputStrategies.java
index 11f8414..e58e6b2 100644
--- a/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/helpers/OutputStrategies.java
+++ b/streampipes-sdk/src/main/java/org/apache/streampipes/sdk/helpers/OutputStrategies.java
@@ -18,14 +18,7 @@
package org.apache.streampipes.sdk.helpers;
-import org.apache.streampipes.model.output.AppendOutputStrategy;
-import org.apache.streampipes.model.output.CustomOutputStrategy;
-import org.apache.streampipes.model.output.CustomTransformOutputStrategy;
-import org.apache.streampipes.model.output.FixedOutputStrategy;
-import org.apache.streampipes.model.output.KeepOutputStrategy;
-import org.apache.streampipes.model.output.ListOutputStrategy;
-import org.apache.streampipes.model.output.TransformOperation;
-import org.apache.streampipes.model.output.TransformOutputStrategy;
+import org.apache.streampipes.model.output.*;
import org.apache.streampipes.model.schema.EventProperty;
import java.util.Arrays;
@@ -91,6 +84,15 @@ public class OutputStrategies {
return new KeepOutputStrategy();
}
+ /**
+ * Creates a {@link org.apache.streampipes.model.output.UserDefinedOutputStrategy}. User-defined output strategies are
+ * fully flexible output strategies which are created by users at pipeline development time.
+ * @return UserDefinedOutputStrategy
+ */
+ public static UserDefinedOutputStrategy userDefined() {
+ return new UserDefinedOutputStrategy();
+ }
+
public static KeepOutputStrategy keep(boolean mergeInputStreams) {
return new KeepOutputStrategy("Rename", mergeInputStreams);
}
diff --git a/streampipes-serializers/src/main/java/org/apache/streampipes/serializers/jsonld/CustomAnnotationProvider.java b/streampipes-serializers/src/main/java/org/apache/streampipes/serializers/jsonld/CustomAnnotationProvider.java
index b04b7f1..91c8a62 100644
--- a/streampipes-serializers/src/main/java/org/apache/streampipes/serializers/jsonld/CustomAnnotationProvider.java
+++ b/streampipes-serializers/src/main/java/org/apache/streampipes/serializers/jsonld/CustomAnnotationProvider.java
@@ -191,6 +191,7 @@ public class CustomAnnotationProvider implements EmpireAnnotationProvider {
EventRateTransformationRuleDescription.class,
SecretStaticProperty.class,
DashboardWidgetModel.class,
+ UserDefinedOutputStrategy.class,
VisualizablePipeline.class,
StreamPipesJsonLdContainer.class
diff --git a/streampipes-vocabulary/src/main/java/org/apache/streampipes/vocabulary/StreamPipes.java b/streampipes-vocabulary/src/main/java/org/apache/streampipes/vocabulary/StreamPipes.java
index 2beb33a..55e3ac0 100644
--- a/streampipes-vocabulary/src/main/java/org/apache/streampipes/vocabulary/StreamPipes.java
+++ b/streampipes-vocabulary/src/main/java/org/apache/streampipes/vocabulary/StreamPipes.java
@@ -386,4 +386,5 @@ public class StreamPipes {
public static final String HAS_LANGUAGE = NS + "hasLanguage";
public static final String HAS_CODE_INPUT = NS + "hasCodeInput";
public static final String HAS_CODE_TEMPLATE = NS + "hasCodeTemplate";
+ public static final String USER_DEFINED_OUTPUT_STRATEGY = NS + "UserDefinedOutputStrategy";
}
diff --git a/ui/src/app/editor/components/userdefinedoutput/user-defined-output.component.ts b/ui/src/app/editor/components/userdefinedoutput/user-defined-output.component.ts
new file mode 100644
index 0000000..d89210e
--- /dev/null
+++ b/ui/src/app/editor/components/userdefinedoutput/user-defined-output.component.ts
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+
+import {UserDefinedOutputController} from "./user-defined-output.controller";
+
+declare const require: any;
+
+export let UserDefinedOutputComponent = {
+ template: require('./user-defined-output.tmpl.html'),
+ bindings: {
+ outputStrategy: "=",
+ selectedElement: "=",
+ customizeForm: "=",
+ restrictedEditMode: "<"
+ },
+ controller: UserDefinedOutputController,
+ controllerAs: 'ctrl'
+};
diff --git a/ui/src/app/editor/components/userdefinedoutput/user-defined-output.controller.ts b/ui/src/app/editor/components/userdefinedoutput/user-defined-output.controller.ts
new file mode 100644
index 0000000..d605049
--- /dev/null
+++ b/ui/src/app/editor/components/userdefinedoutput/user-defined-output.controller.ts
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+
+import {RdfId} from "../../../platform-services/tsonld/RdfId";
+
+export class UserDefinedOutputController {
+
+ private prefix = "urn:streampipes.org:spi:";
+ private chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ outputStrategy: any;
+ selectedElement: any;
+ collectedPropertiesFirstStream: any;
+ collectedPropertiesSecondStream: any;
+ customizeForm: any;
+
+ primitiveClasses = [{"label": "String", "id": "http://www.w3.org/2001/XMLSchema#string"},
+ {"label": "Boolean", "id": "http://www.w3.org/2001/XMLSchema#boolean"},
+ {"label": "Integer", "id": "http://www.w3.org/2001/XMLSchema#integer"},
+ {"label": "Long", "id": "http://www.w3.org/2001/XMLSchema#long"},
+ {"label": "Double", "id": "http://www.w3.org/2001/XMLSchema#double"},
+ {"label": "Float", "id": "http://www.w3.org/2001/XMLSchema#float"}];
+
+ constructor() {
+
+ }
+
+ $onInit() {
+ if (!this.outputStrategy.properties.eventProperties) {
+ this.outputStrategy.properties.eventProperties = [];
+ }
+ }
+
+ applyDefaultSchema() {
+ this.outputStrategy.properties.eventProperties =
+ this.selectedElement.inputStreams[0].eventSchema.eventProperties;
+ }
+
+ removeProperty(ep: any) {
+ this.outputStrategy.properties.eventProperties
+ .splice(this.outputStrategy.properties.eventProperties.indexOf(ep), 1);
+ }
+
+ addProperty() {
+ this.outputStrategy.properties.eventProperties.push(this.makeDefaultProperty());
+ }
+
+ makeDefaultProperty() {
+ let ep = {} as any;
+ ep.type = "org.apache.streampipes.model.schema.EventPropertyPrimitive";
+ ep.properties = {};
+ ep.properties.domainProperties = [];
+ ep.properties.elementId = "urn:streampipes.org:spi:eventpropertyprimitive:" + this.makeId();
+
+ return ep;
+ }
+
+ makeId() {
+ return this.prefix + this.randomString(6);
+ }
+
+ randomString(length) {
+ let result = '';
+ for (let i = length; i > 0; --i) result += this.chars[Math.floor(Math.random() * this.chars.length)];
+ return result;
+ }
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/ui/src/app/editor/components/userdefinedoutput/user-defined-output.tmpl.html b/ui/src/app/editor/components/userdefinedoutput/user-defined-output.tmpl.html
new file mode 100644
index 0000000..ad56102
--- /dev/null
+++ b/ui/src/app/editor/components/userdefinedoutput/user-defined-output.tmpl.html
@@ -0,0 +1,55 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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.
+ ~
+ -->
+
+<div flex="100" layout="row" layout-align="start center" style="margin-bottom:20px;">
+ <sp-button sp-button-blue sp-button-small-padding ng-click="ctrl.applyDefaultSchema()" ng-disabled="ctrl.restrictedEditMode">Use input schema
+ </sp-button>
+</div>
+
+<div flex="100" layout="row" ng-repeat="ep in ctrl.outputStrategy.properties.eventProperties track by $index">
+ <div layout="column" flex="30">
+ <md-input-container flex="100">
+ <label>Runtime name</label>
+ <input ng-model="ep.properties.runtimeName" ng-disabled="ctrl.restrictedEditMode">
+ </md-input-container>
+ </div>
+ <div layout="column" flex="30">
+ <md-input-container>
+ <label>Runtime type</label>
+ <md-select ng-model="ep.properties.runtimeType" ng-disabled="ctrl.restrictedEditMode">
+ <md-option ng-repeat="primitive in ctrl.primitiveClasses" ng-value="primitive.id">
+ {{primitive.label}}
+ </md-option>
+ </md-select>
+ </md-input-container>
+ </div>
+ <div layout="column" flex="30">
+ <md-input-container flex="100">
+ <label>Semantic type</label>
+ <input ng-model="ep.properties.domainProperties[0]" ng-disabled="ctrl.restrictedEditMode">
+ </md-input-container>
+ </div>
+ <div layout="column" flex="10">
+ <md-button class="md-icon-button" ng-click="ctrl.removeProperty(ep)" ng-disabled="ctrl.restrictedEditMode">
+ <i class="material-icons">delete</i>
+ </md-button>
+ </div>
+</div>
+<md-button ng-click="ctrl.addProperty()" ng-disabled="ctrl.restrictedEditMode">
+ Add Field
+</md-button>
diff --git a/ui/src/app/editor/dialog/customize-pipeline-element/customizeElementDialog.tmpl.html b/ui/src/app/editor/dialog/customize-pipeline-element/customizeElementDialog.tmpl.html
index 24b38e7..87cafed 100644
--- a/ui/src/app/editor/dialog/customize-pipeline-element/customizeElementDialog.tmpl.html
+++ b/ui/src/app/editor/dialog/customize-pipeline-element/customizeElementDialog.tmpl.html
@@ -103,7 +103,8 @@
</div>
</div>
</div>
- <div ng-if="outputStrategy.type === 'org.apache.streampipes.model.output.CustomOutputStrategy'">
+ <div ng-if="outputStrategy.type === 'org.apache.streampipes.model.output.CustomOutputStrategy' ||
+ outputStrategy.type === 'org.apache.streampipes.model.output.UserDefinedOutputStrategy'">
<div layout="column" class="customize-item-main sp-blue-border-nopadding">
<div class="customize-item-title sp-blue-bg" layout="row" flex="100">
<div flex="80" layout="row" layout-align="start center">
@@ -114,13 +115,20 @@
</div>
</div>
- <div class="customize-item-content">
+ <div class="customize-item-content" ng-if="outputStrategy.type === 'org.apache.streampipes.model.output.CustomOutputStrategy'">
<custom-output output-strategy="outputStrategy"
selected-element="ctrl.selectedElement"
customize-form="ctrl.customizeForm"
restricted-edit-mode="ctrl.restrictedEditMode">
</custom-output>
</div>
+ <div class="customize-item-content" ng-if="outputStrategy.type === 'org.apache.streampipes.model.output.UserDefinedOutputStrategy'">
+ <user-defined-output output-strategy="outputStrategy"
+ selected-element="ctrl.selectedElement"
+ customize-form="ctrl.customizeForm"
+ restricted-edit-mode="ctrl.restrictedEditMode">
+ </user-defined-output>
+ </div>
</div>
</div>
</div>
diff --git a/ui/src/app/editor/editor.module.ts b/ui/src/app/editor/editor.module.ts
index 1305c2a..db4c26e 100644
--- a/ui/src/app/editor/editor.module.ts
+++ b/ui/src/app/editor/editor.module.ts
@@ -73,6 +73,7 @@ import {FileUploadComponent} from "./components/fileupload/fileupload.component"
import {AnyRemoteComponent} from "./components/any-remote/any-remote.component";
import {CodeInputComponent} from "./components/code/code.component";
import {CodeEditorDirective} from "./components/code/code-editor.directive";
+import {UserDefinedOutputComponent} from "./components/userdefinedoutput/user-defined-output.component";
export default angular.module('sp.editor', [spServices, 'ngSanitize', 'angularTrix', 'ngAnimate', 'datatables', 'ng-showdown'])
@@ -87,6 +88,7 @@ export default angular.module('sp.editor', [spServices, 'ngSanitize', 'angularTr
.component('any', AnyComponent)
.component('anyRemote', AnyRemoteComponent)
.component('customOutput', CustomOutputComponent)
+ .component('userDefinedOutput', UserDefinedOutputComponent)
.component('domainConceptInput', DomainConceptComponent)
.component('freetext', FreeTextComponent)
.component('secret', SecretComponent)