/*
* Copyright 2015-2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.hawkular.inventory.api.model;
import java.util.Map;
import org.hawkular.inventory.api.Relationships;
import org.hawkular.inventory.paths.CanonicalPath;
import org.hawkular.inventory.paths.Path;
import org.hawkular.inventory.paths.SegmentType;
import io.swagger.annotations.ApiModel;
/**
* Represents a relationship between 2 entities. A relationship has a source and target entities (somewhat obviously),
* a name, id (multiple relationships of the same name can exist between the same source and target) and also a map of
* properties.
*
* @author Lukas Krejci
* @author Jirka Kremser
* @since 0.0.1
*/
@ApiModel(description = "A relationship between two entities.")
public final class Relationship extends AbstractElement<Relationship.Blueprint, Relationship.Update> {
public static final SegmentType SEGMENT_TYPE = SegmentType.rl;
private final String id;
private final String name;
private final CanonicalPath source;
private final CanonicalPath target;
/** JAXB support */
@SuppressWarnings("unused")
private Relationship() {
this(null, null, null, null, null);
}
@Override
public <R, P> R accept(ElementVisitor<R, P> visitor, P parameter) {
return visitor.visitRelationship(this, parameter);
}
public Relationship(String id, String name, CanonicalPath source, CanonicalPath target) {
this(id, name, source, target, null);
}
public Relationship(String id, String name, CanonicalPath source, CanonicalPath target,
Map<String, Object> properties) {
super(CanonicalPath.of().relationship(id).get(), properties);
this.id = id;
this.name = name;
this.source = source;
this.target = target;
}
@Override
public Updater<Update, Relationship> update() {
return new Updater<>((u) -> new Relationship(getId(), getName(), getSource(), getTarget(), u.getProperties()),
this, Update.builder());
}
@Override
public String getId() {
return id;
}
public String getName() {
return name;
}
public CanonicalPath getSource() {
return source;
}
public CanonicalPath getTarget() {
return target;
}
@Override
public String toString() {
StringBuilder bld = new StringBuilder(getClass().getSimpleName());
bld.append("[id='").append(id).append('\'');
bld.append(", name='").append(name).append('\'');
bld.append(", source=").append(source);
bld.append(" --").append(name).append("--> ");
bld.append(" target=").append(target);
bld.append(']');
return bld.toString();
}
@ApiModel("RelationshipUpdate")
public static final class Update extends AbstractElement.Update {
public static Builder builder() {
return new Builder();
}
//JAXB support
@SuppressWarnings("unused")
private Update() {
this(null);
}
public Update(Map<String, Object> properties) {
super(properties);
}
@Override
public <R, P> R accept(ElementUpdateVisitor<R, P> visitor, P parameter) {
return visitor.visitRelationship(this, parameter);
}
public static final class Builder extends AbstractElement.Update.Builder<Relationship, Update, Builder> {
@Override
public Update build() {
return new Update(properties);
}
}
}
@ApiModel("RelationshipBlueprint")
public static final class Blueprint extends AbstractElement.Blueprint {
private final String name;
private final Path otherEnd;
private final Relationships.Direction direction;
public static Builder builder() {
return new Builder();
}
//Jackson support
private Blueprint() {
this(null, null, null, null);
}
public Blueprint(Relationships.Direction direction, String name, Path otherEnd,
Map<String, Object> properties) {
super(properties);
this.name = name;
this.otherEnd = otherEnd;
this.direction = direction == null ? Relationships.Direction.outgoing : direction;
}
public String getName() {
return name;
}
public Relationships.Direction getDirection() {
return direction;
}
public Path getOtherEnd() {
return otherEnd;
}
@Override
public <R, P> R accept(ElementBlueprintVisitor<R, P> visitor, P parameter) {
return visitor.visitRelationship(this, parameter);
}
public static final class Builder extends AbstractElement.Blueprint.Builder<Blueprint, Builder> {
private String name;
private Path otherEnd;
private Relationships.Direction direction = Relationships.Direction.outgoing;
public Builder withName(String name) {
this.name = name;
return this;
}
public Builder withOtherEnd(Path path) {
this.otherEnd = path;
return this;
}
public Builder withDirection(Relationships.Direction direction) {
this.direction = direction;
return this;
}
@Override
public Blueprint build() {
return new Blueprint(direction, name, otherEnd, properties);
}
}
}
}