Skip to content

Commit

Permalink
Usability improvements for some UaNode builders (#799)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinherron committed Mar 18, 2021
1 parent e1b7f6c commit c9e30a4
Show file tree
Hide file tree
Showing 6 changed files with 520 additions and 66 deletions.
Expand Up @@ -301,24 +301,29 @@ private void addArrayNodes(UaFolderNode rootNode) {
}
Variant variant = new Variant(array);

UaVariableNode node = new UaVariableNode.UaVariableNodeBuilder(getNodeContext())
.setNodeId(newNodeId("HelloWorld/ArrayTypes/" + name))
.setAccessLevel(AccessLevel.READ_WRITE)
.setUserAccessLevel(AccessLevel.READ_WRITE)
.setBrowseName(newQualifiedName(name))
.setDisplayName(LocalizedText.english(name))
.setDataType(typeId)
.setTypeDefinition(Identifiers.BaseDataVariableType)
.setValueRank(ValueRank.OneDimension.getValue())
.setArrayDimensions(new UInteger[]{uint(0)})
.build();

node.setValue(new DataValue(variant));

node.getFilterChain().addLast(new AttributeLoggingFilter(AttributeId.Value::equals));

getNodeManager().addNode(node);
arrayTypesFolder.addOrganizes(node);
UaVariableNode.build(getNodeContext(), builder -> {
builder.setNodeId(newNodeId("HelloWorld/ArrayTypes/" + name));
builder.setAccessLevel(AccessLevel.READ_WRITE);
builder.setUserAccessLevel(AccessLevel.READ_WRITE);
builder.setBrowseName(newQualifiedName(name));
builder.setDisplayName(LocalizedText.english(name));
builder.setDataType(typeId);
builder.setTypeDefinition(Identifiers.BaseDataVariableType);
builder.setValueRank(ValueRank.OneDimension.getValue());
builder.setArrayDimensions(new UInteger[]{uint(0)});
builder.setValue(new DataValue(variant));

builder.addAttributeFilter(new AttributeLoggingFilter(AttributeId.Value::equals));

builder.addReference(new Reference(
builder.getNodeId(),
Identifiers.Organizes,
arrayTypesFolder.getNodeId().expanded(),
Reference.Direction.INVERSE
));

return builder.buildAndAdd();
});
}
}

Expand Down
Expand Up @@ -10,17 +10,23 @@

package org.eclipse.milo.opcua.sdk.server.nodes;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import com.google.common.base.Preconditions;
import org.eclipse.milo.opcua.sdk.core.Reference;
import org.eclipse.milo.opcua.sdk.core.nodes.MethodNode;
import org.eclipse.milo.opcua.sdk.core.nodes.MethodNodeProperties;
import org.eclipse.milo.opcua.sdk.core.nodes.Node;
import org.eclipse.milo.opcua.sdk.core.nodes.ObjectNode;
import org.eclipse.milo.opcua.sdk.server.api.NodeManager;
import org.eclipse.milo.opcua.sdk.server.api.methods.MethodInvocationHandler;
import org.eclipse.milo.opcua.sdk.server.nodes.filters.AttributeFilter;
import org.eclipse.milo.opcua.sdk.server.nodes.filters.AttributeFilterChain;
import org.eclipse.milo.opcua.stack.core.AttributeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
Expand Down Expand Up @@ -227,8 +233,31 @@ public static UaMethodNodeBuilder builder(UaNodeContext context) {
return new UaMethodNodeBuilder(context);
}

/**
* Build a {@link UaMethodNode} using the {@link UaMethodNodeBuilder} supplied to the
* {@code build} function.
*
* @param context a {@link UaNodeContext}.
* @param build a function that accepts a {@link UaMethodNodeBuilder} and uses it to build
* and return a {@link UaMethodNode}.
* @return a {@link UaMethodNode} built using the supplied {@link UaMethodNodeBuilder}.
*/
public static UaMethodNode build(
UaNodeContext context,
Function<UaMethodNodeBuilder, UaMethodNode> build
) {

UaMethodNodeBuilder builder = new UaMethodNodeBuilder(context);

return build.apply(builder);
}

public static class UaMethodNodeBuilder implements Supplier<UaMethodNode> {

private final List<AttributeFilter> attributeFilters = new ArrayList<>();

private final List<Reference> references = new ArrayList<>();

private NodeId nodeId;
private QualifiedName browseName;
private LocalizedText displayName;
Expand All @@ -245,17 +274,27 @@ public UaMethodNodeBuilder(UaNodeContext context) {
this.context = context;
}

/**
* @see #build()
*/
@Override
public UaMethodNode get() {
return build();
}

/**
* Build and return the {@link UaMethodNode}.
* <p>
* The following fields are required: NodeId, BrowseName, DisplayName.
*
* @return a {@link UaMethodNode} built from the configuration of this builder.
*/
public UaMethodNode build() {
Preconditions.checkNotNull(nodeId, "NodeId cannot be null");
Preconditions.checkNotNull(browseName, "BrowseName cannot be null");
Preconditions.checkNotNull(displayName, "DisplayName cannot be null");

return new UaMethodNode(
UaMethodNode node = new UaMethodNode(
context,
nodeId,
browseName,
Expand All @@ -266,6 +305,25 @@ public UaMethodNode build() {
executable,
userExecutable
);

references.forEach(node::addReference);

node.getFilterChain().addLast(attributeFilters);

return node;
}

/**
* Build the {@link UaMethodNode} using the configured values and add it to the
* {@link NodeManager} from the {@link UaNodeContext}.
*
* @return a {@link UaMethodNode} built from the configured values.
* @see #build()
*/
public UaMethodNode buildAndAdd() {
UaMethodNode node = build();
context.getNodeManager().addNode(node);
return node;
}

public UaMethodNodeBuilder setNodeId(NodeId nodeId) {
Expand Down Expand Up @@ -308,6 +366,63 @@ public UaMethodNodeBuilder setUserExecutable(boolean userExecutable) {
return this;
}

public NodeId getNodeId() {
return nodeId;
}

public QualifiedName getBrowseName() {
return browseName;
}

public LocalizedText getDisplayName() {
return displayName;
}

public LocalizedText getDescription() {
return description;
}

public UInteger getWriteMask() {
return writeMask;
}

public UInteger getUserWriteMask() {
return userWriteMask;
}

public boolean isExecutable() {
return executable;
}

public boolean isUserExecutable() {
return userExecutable;
}

/**
* Add an {@link AttributeFilter} that will be added to the node's
* {@link AttributeFilterChain} when it's built.
* <p>
* The order filters are added in this builder is maintained.
*
* @param attributeFilter the {@link AttributeFilter} to add.
* @return this {@link UaMethodNodeBuilder}.
*/
public UaMethodNodeBuilder addAttributeFilter(AttributeFilter attributeFilter) {
attributeFilters.add(attributeFilter);
return this;
}

/**
* Add a {@link Reference} to the node when it's built.
*
* @param reference the {@link Reference} to add.
* @return this {@link UaMethodNodeBuilder}.
*/
public UaMethodNodeBuilder addReference(Reference reference) {
references.add(reference);
return this;
}

}

}

0 comments on commit c9e30a4

Please sign in to comment.