org.protempa.dest.table.Reference Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of protempa-framework Show documentation
Show all versions of protempa-framework Show documentation
Protempa Framework is the core of Protempa.
/*
* #%L
* Protempa Framework
* %%
* Copyright (C) 2012 - 2013 Emory University
* %%
* 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.
* #L%
*/
package org.protempa.dest.table;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.protempa.KnowledgeSource;
import org.protempa.KnowledgeSourceCache;
import org.protempa.KnowledgeSourceReadException;
import org.protempa.PropositionDefinition;
import org.protempa.ProtempaUtil;
import org.protempa.ReferenceDefinition;
import org.protempa.proposition.Proposition;
import org.protempa.proposition.UniqueId;
/**
* Specifies reference traversals from one proposition to other propositions.
*
* @author Andrew Post
*/
public final class Reference extends Link {
private final String[] referenceNames;
/**
* Creates an instance that specifies traversals using the specified
* references from a proposition to all referred-to propositions.
*
* @param referenceNames a {@link String[]} of reference names. An empty *
* or null
array specifies that all references should be
* traversed.
*/
public Reference(String[] referenceNames) {
this(referenceNames, null);
}
/**
* Creates an instance that specifies traversals using the specified
* references from a proposition only to propositions with the given ids.
*
* @param referenceNames a {@link String[]} of reference names. An empty *
* or null
array specifies that all references should be
* traversed.
* @param propositionIds a {@link String[]} of proposition ids. An empty *
* or null
array specifies that all propositions on the
* right-hand-side of the reference should be used.
*/
public Reference(String[] referenceNames, String[] propositionIds) {
this(referenceNames, propositionIds, null);
}
/**
* Creates an instance that specifies traversals using the specified
* references from a proposition only to propositions with the given ids and
* that satisfy the specified constraints.
*
* @param referenceNames a {@link String[]} of reference names. An empty *
* or null
array specifies that all references should be
* traversed.
* @param propositionIds a {@link String[]} of proposition ids. An empty *
* or null
array specifies that all propositions on the
* right-hand-side of a reference should be used.
* @param constraints a {@link PropertyConstraint[]} of property constraints
* on the propositions on the right-hand-side of a reference. An empty or
* null array specifies that no constraints should be applied.
*/
public Reference(String[] referenceNames, String[] propositionIds,
PropertyConstraint[] constraints) {
this(referenceNames, propositionIds, constraints, null, -1, -1);
}
/**
* Creates an instance that specifies traversals using the specified
* references from a proposition only to propositions with the given ids and
* that satisfy the specified constraints. It also allows specifying the
* first, second, or other proposition on the right-hand-side of the
* reference.
*
* @param referenceNames a {@link String[]} of reference names. An empty *
* or null
array specifies that all references should be
* traversed.
* @param propositionIds a {@link String[]} of proposition ids. An empty *
* or null
array specifies that all propositions on the
* right-hand-side of a reference should be used.
* @param constraints a {@link PropertyConstraint[]} of property constraints
* on the propositions on the right-hand-side of a reference. An empty * or null
array specifies that no constraints should be
* applied.
* @param comparator a comparison function representing the total order to
* apply to propositions on the right-hand-side of the reference when using
* the index
parameter. If null
and an
* index
is specified, the total order is unspecified.
* @param index the position of the proposition on the right-hand-side of
* the reference to traverse to, using the total order specified by the
* comparator
argument. An index of -1
means that
* all propositions on the right-hand-side will be traversed to.
*/
public Reference(String[] referenceNames, String[] propositionIds,
PropertyConstraint[] constraints,
Comparator comparator, int index) {
this(referenceNames, propositionIds, constraints, comparator, index,
index >= 0 ? index + 1 : -1);
}
/**
* Creates an instance that specifies traversals using the specified
* references from a proposition only to propositions with the given ids and
* that satisfy the specified constraints. It also allows specifying a range
* of propositions on the right-hand-side of the reference to be traversed
* to (first and second, first through third, etc.).
*
* @param referenceNames a {@link String[]} of reference names. An empty *
* or null
array specifies that all references should be
* traversed.
* @param propositionIds a {@link String[]} of proposition ids. An empty *
* or null
array specifies that all propositions on the
* right-hand-side of a reference should be used.
* @param constraints a {@link PropertyConstraint[]} of property constraints
* on the propositions on the right-hand-side of a reference. An empty * or null
array specifies that no constraints should be
* applied.
* @param comparator a comparison function representing the total order to
* apply to propositions on the right-hand-side of the reference when using
* the index
parameter. If null
and an
* index
is specified, the total order is unspecified.
* @param fromIndex the lower-bound on the positions of the propositions on
* the right-hand-side of the reference to traverse to, inclusive, using the
* total order specified by the comparator
argument. An index
* of -1
means that all propositions on the right-hand-side
* will be traversed to.
* @param toIndex the upper-bound on the positions of the propositions on
* the right-hand-side of the reference to traverse to, exclusive, using the
* total order specified by the comparator
argument. An index
* of -1
means that all propositions on the right-hand-side
* will be traversed to.
*/
public Reference(String[] referenceNames, String[] propositionIds,
PropertyConstraint[] constraints,
Comparator comparator, int fromIndex, int toIndex) {
super(propositionIds, constraints, comparator, fromIndex, toIndex);
if (referenceNames != null) {
ProtempaUtil.checkArrayForNullElement(referenceNames,
"referenceNames");
String[] refNames = referenceNames.clone();
for (int i = 0; i < refNames.length; i++) {
refNames[i] = refNames[i].intern();
}
this.referenceNames = refNames;
} else {
this.referenceNames = ArrayUtils.EMPTY_STRING_ARRAY;
}
}
/**
* Creates an instance that specifies traversals using the specified
* reference from a proposition to all referred-to propositions.
*
* @param referenceName a reference name {@link String} A value of
* null
specifies that all references should be traversed.
*/
public Reference(String referenceName) {
this(referenceName, null);
}
/**
* Creates an instance that specifies traversals using the specified
* reference from a proposition only to propositions with the given ids.
*
* @param referenceName a reference name {@link String} A value of
* null
specifies that all references should be traversed.
* @param propositionIds a {@link String[]} of proposition ids. An empty *
* or null
array specifies that all propositions on the
* right-hand-side of the reference should be used.
*/
public Reference(String referenceName, String[] propositionIds) {
this(referenceName, propositionIds, null);
}
/**
* Creates an instance that specifies traversals using the specified
* references from a proposition only to propositions with the given ids and
* that satisfy the specified property constraints.
*
* @param referenceName a reference name {@link String} A value of
* null
specifies that all references should be traversed.
* @param propositionIds a {@link String[]} of proposition ids. An empty *
* or null
array specifies that all propositions on the
* right-hand-side of a reference should be used.
* @param constraints a {@link PropertyConstraint[]} of property constraints
* on the propositions on the right-hand-side of a reference. An empty or
* null array specifies that no constraints should be applied.
*/
public Reference(String referenceName, String[] propositionIds,
PropertyConstraint[] constraints) {
this(referenceName, propositionIds, constraints, null, -1, -1);
}
/**
* Creates an instance that specifies traversals using the specified
* reference from a proposition only to propositions with the given ids and
* that satisfy the specified property constraints. It also allows
* specifying the first, second, or other proposition on the right-hand-side
* of the reference.
*
* @param referenceName a reference name {@link String} A value of
* null
specifies that all references should be traversed.
* @param propositionIds a {@link String[]} of proposition ids. An empty *
* or null
array specifies that all propositions on the
* right-hand-side of a reference should be used.
* @param constraints a {@link PropertyConstraint[]} of property constraints
* on the propositions on the right-hand-side of a reference. An empty * or null
array specifies that no constraints should be
* applied.
* @param comparator a comparison function representing the total order to
* apply to propositions on the right-hand-side of the reference when using
* the index
parameter. If null
and an
* index
is specified, the total order is unspecified.
* @param index the position of the proposition on the right-hand-side of
* the reference to traverse to, using the total order specified by the
* comparator
argument. An index of -1
means that
* all propositions on the right-hand-side will be traversed to.
*/
public Reference(String referenceName, String[] propositionIds,
PropertyConstraint[] constraints,
Comparator comparator, int index) {
this(referenceName, propositionIds, constraints, comparator, index,
index >= 0 ? index + 1 : -1);
}
/**
* Creates an instance that specifies traversals using the specified
* reference from a proposition only to propositions with the given ids and
* that satisfy the specified constraints. It also allows specifying a range
* of propositions on the right-hand-side of the reference to be traversed
* to (first and second, first through third, etc.).
*
* @param referenceName a reference name {@link String} A value of
* null
specifies that all references should be traversed.
* @param propositionIds a {@link String[]} of proposition ids. An empty *
* or null
array specifies that all propositions on the
* right-hand-side of a reference should be used.
* @param constraints a {@link PropertyConstraint[]} of property constraints
* on the propositions on the right-hand-side of a reference. An empty * or null
array specifies that no constraints should be
* applied.
* @param comparator a comparison function representing the total order to
* apply to propositions on the right-hand-side of the reference when using
* the index
parameter. If null
and an
* index
is specified, the total order is unspecified.
* @param fromIndex the lower-bound on the positions of the propositions on
* the right-hand-side of the reference to traverse to, inclusive, using the
* ordering specified by the comparator
argument. An index * of -1
means that all propositions on the
* right-hand-side will be traversed to.
* @param toIndex the upper-bound on the positions of the propositions on
* the right-hand-side of the reference to traverse to, exclusive, using the
* ordering specified by the comparator
argument. An index * of -1
means that all propositions on the
* right-hand-side will be traversed to.
*/
public Reference(String referenceName, String[] propositionIds,
PropertyConstraint[] constraints,
Comparator comparator, int fromIndex, int toIndex) {
super(propositionIds, constraints, comparator, fromIndex, toIndex);
if (referenceName == null) {
throw new IllegalArgumentException("referenceName cannot be null");
}
this.referenceNames = new String[]{referenceName.intern()};
}
/**
* Gets the names of the reference(s) to be traversed.
*
* @return a {@link String[]} of reference names.
*/
public String[] getReferenceNames() {
if (this.referenceNames != null) {
return this.referenceNames.clone();
} else {
return this.referenceNames;
}
}
@Override
String headerFragment() {
String references = StringUtils.join(this.referenceNames, ',');
return createHeaderFragment(references);
}
/**
* Traverses a reference.
*
* @param proposition a {@link Proposition} at which to start the traversal.
* @param forwardDerivations a {@link Map>} of
* derived propositions.
* @param backwardDerivations a {@link Map>}
* of derived propositions.
* @param references a {@link Map} of unique
* identifiers to {@link Proposition}s, used to resolve references.
* @param knowledgeSource the {@link KnowledgeSource}.
* @param cache a {@link Set} for convenience in checking if
* duplicate propositions are traversed to. It is cleared in between calls
* to this method.
* @return the {@link Collection} at the end of the traversal
* step.
*/
@Override
Collection traverse(Proposition proposition,
Map> forwardDerivations,
Map> backwardDerivations,
Map references,
KnowledgeSourceCache ksCache, Set cache) {
List props = new ArrayList<>();
String[] refNames =
this.referenceNames.length > 0
? this.referenceNames
: proposition.getReferenceNames();
for (String referenceName : refNames) {
List uids = proposition.getReferences(
referenceName);
for (UniqueId uid : uids) {
Proposition prop = references.get(uid);
if (prop != null && cache.add(prop) && isMatch(prop)) {
props.add(prop);
}
}
}
return createResults(props);
}
@Override
public String[] getInferredPropositionIds(KnowledgeSource knowledgeSource,
String[] inPropIds) throws KnowledgeSourceReadException {
String[] explicitPropIds = getPropositionIds();
if (explicitPropIds.length > 0) {
return explicitPropIds.clone();
} else {
Set result = new HashSet<>();
for (PropositionDefinition propDef : knowledgeSource.readPropositionDefinitions(inPropIds)) {
for (String refName : this.referenceNames) {
ReferenceDefinition refDef =
propDef.referenceDefinition(refName);
if (refDef != null) {
org.arp.javautil.arrays.Arrays.addAll(result,
refDef.getPropositionIds());
}
}
}
return result.toArray(new String[result.size()]);
}
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + Arrays.hashCode(referenceNames);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Reference other = (Reference) obj;
if (!Arrays.equals(referenceNames, other.referenceNames)) {
return false;
}
return true;
}
}