001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package gov.nist.secauto.oscal.lib.profile.resolver.support;
007
008import gov.nist.secauto.metaschema.core.metapath.item.node.IModelNodeItem;
009import gov.nist.secauto.metaschema.core.util.ObjectUtils;
010
011import java.net.URI;
012
013import edu.umd.cs.findbugs.annotations.NonNull;
014
015public abstract class AbstractEntityItem implements IEntityItem {
016
017  @NonNull
018  private final String originalIdentifier;
019  @NonNull
020  private IModelNodeItem<?, ?> instance;
021  @NonNull
022  private final ItemType itemType;
023  @NonNull
024  private final URI source;
025  private int referenceCount; // 0 by default
026  // private boolean resolved; // false by default
027
028  protected AbstractEntityItem(@NonNull Builder builder) {
029    this.itemType = ObjectUtils.requireNonNull(builder.itemType, "itemType");
030    this.originalIdentifier = ObjectUtils.requireNonNull(builder.originalIdentifier, "originalIdentifier");
031    this.instance = ObjectUtils.requireNonNull(builder.instance, "instance");
032    this.source = ObjectUtils.requireNonNull(builder.source, "source");
033  }
034
035  @Override
036  @NonNull
037  public String getOriginalIdentifier() {
038    return originalIdentifier;
039  }
040
041  @Override
042  @NonNull
043  public abstract String getIdentifier();
044
045  // @NonNull
046  // public String getIdentifier() {
047  // final String checkedReassignedIdentifier = reassignedIdentifier;
048  // return checkedReassignedIdentifier == null ? originalIdentifier :
049  // checkedReassignedIdentifier;
050  // }
051
052  @Override
053  @NonNull
054  public IModelNodeItem<?, ?> getInstance() {
055    return instance;
056  }
057
058  @Override
059  public void setInstance(IModelNodeItem<?, ?> item) {
060    instance = item;
061  }
062
063  @Override
064  @NonNull
065  @SuppressWarnings("unchecked")
066  public <T> T getInstanceValue() {
067    return ObjectUtils.notNull((T) getInstance().getValue());
068  }
069
070  @Override
071  @NonNull
072  public ItemType getItemType() {
073    return itemType;
074  }
075
076  @Override
077  @NonNull
078  public URI getSource() {
079    return source;
080  }
081
082  @Override
083  public int getReferenceCount() {
084    return referenceCount;
085  }
086
087  // public boolean isResolved() {
088  // return resolved;
089  // }
090  //
091  // public void markResolved() {
092  // resolved = true;
093  // }
094
095  @Override
096  public void incrementReferenceCount() {
097    referenceCount += 1;
098  }
099
100  @Override
101  public int resetReferenceCount() {
102    int retval = referenceCount;
103    referenceCount = 0;
104    return retval;
105  }
106
107  static final class Builder {
108    private String originalIdentifier;
109    private String reassignedIdentifier;
110    private IModelNodeItem<?, ?> instance;
111    private ItemType itemType;
112    private URI source;
113
114    @NonNull
115    public Builder instance(@NonNull IModelNodeItem<?, ?> item, @NonNull ItemType itemType) {
116      this.instance = item;
117      this.itemType = itemType;
118      return this;
119    }
120
121    // @NonNull
122    // public Builder reassignedIdentifier(@NonNull UUID identifier) {
123    // // no need to normalize, since UUIDs are formatted lower case
124    // return reassignedIdentifier(identifier.toString());
125    // }
126
127    @NonNull
128    public Builder reassignedIdentifier(@NonNull String identifier) {
129      this.reassignedIdentifier = identifier;
130      return this;
131    }
132    //
133    // @NonNull
134    // public Builder originalIdentifier(@NonNull UUID identifier) {
135    // // no need to normalize, since UUIDs are formatted lower case
136    // return originalIdentifier(identifier.toString());
137    // }
138
139    @NonNull
140    public Builder originalIdentifier(@NonNull String identifier) {
141      this.originalIdentifier = identifier;
142      return this;
143    }
144
145    @NonNull
146    public Builder source(@NonNull URI source) {
147      this.source = source;
148      return this;
149    }
150
151    @NonNull
152    public IEntityItem build() {
153      return reassignedIdentifier == null ? new OriginalEntityItem(this) : new ReassignedEntityItem(this);
154    }
155  }
156
157  static final class OriginalEntityItem
158      extends AbstractEntityItem {
159
160    protected OriginalEntityItem(@NonNull Builder builder) {
161      super(builder);
162    }
163
164    @Override
165    public String getIdentifier() {
166      return getOriginalIdentifier();
167    }
168
169    @Override
170    public boolean isIdentifierReassigned() {
171      return false;
172    }
173  }
174
175  static final class ReassignedEntityItem
176      extends AbstractEntityItem {
177    @NonNull
178    private final String reassignedIdentifier;
179
180    protected ReassignedEntityItem(@NonNull Builder builder) {
181      super(builder);
182      this.reassignedIdentifier = ObjectUtils.requireNonNull(builder.reassignedIdentifier);
183    }
184
185    @Override
186    public String getIdentifier() {
187      return reassignedIdentifier;
188    }
189
190    @Override
191    public boolean isIdentifierReassigned() {
192      return true;
193    }
194  }
195}