/*
* #!
* Ontopoly Editor
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* 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 ontopoly.utils;
// TODO javadoc
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.topicmaps.core.AssociationIF;
import net.ontopia.topicmaps.core.AssociationRoleIF;
import net.ontopia.topicmaps.core.OccurrenceIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TopicMapBuilderIF;
import net.ontopia.topicmaps.core.TopicNameIF;
import net.ontopia.topicmaps.query.core.QueryResultIF;
import net.ontopia.topicmaps.query.utils.RowMapperIF;
import net.ontopia.topicmaps.utils.AssociationBuilder;
import net.ontopia.utils.CollectionUtils;
import net.ontopia.utils.ObjectUtils;
import ontopoly.model.QueryMapper;
import ontopoly.model.TopicMap;
public class OntopolyModelUtils {
private OntopolyModelUtils() {
}
public static RowMapperIF<Object> getRowMapperOneColumn() {
return RowMapperOneColumn.INSTANCE;
}
private static class RowMapperOneColumn<T> implements RowMapperIF<T> {
public static final RowMapperIF<Object> INSTANCE = new RowMapperOneColumn<Object>();
@SuppressWarnings("unchecked")
public T mapRow(QueryResultIF queryResult, int rowno) {
// return the value in the first column
return (T)queryResult.getValue(0);
}
}
public static TopicIF getTopicIF(TopicMap tm, LocatorIF base, String subjectIndicator) {
return getTopicIF(tm, base.resolveAbsolute(subjectIndicator), true);
}
public static TopicIF getTopicIF(TopicMap tm, LocatorIF subjectIdentifier) {
return getTopicIF(tm, subjectIdentifier, true);
}
public static TopicIF getTopicIF(TopicMap tm, LocatorIF subjectIdentifier, boolean mustExist) {
TopicIF t = tm.getTopicMapIF().getTopicBySubjectIdentifier(subjectIdentifier);
if (t == null && mustExist)
throw new RuntimeException("Topic not found by subject identifier: " + subjectIdentifier);
return t;
}
public static boolean isUnaryPlayer(
TopicMap tm, TopicIF aType, TopicIF player, TopicIF rType) {
return findUnaryAssociation(tm, aType, player, rType) != null;
}
public static AssociationIF findUnaryAssociation(
TopicMap tm, TopicIF aType, TopicIF player, TopicIF rType) {
Iterator<AssociationRoleIF> iter = player.getRoles().iterator();
while (iter.hasNext()) {
AssociationRoleIF role = iter.next();
AssociationIF assoc = role.getAssociation();
if (ObjectUtils.equals(role.getType(), rType) &&
ObjectUtils.equals(assoc.getType(), aType))
return assoc;
}
return null;
}
public static boolean hasBinaryAssociation(TopicIF player1, TopicIF aType,
TopicIF rType1, TopicIF rType2) {
for (AssociationRoleIF role : player1.getRolesByType(rType1, aType)) {
AssociationIF assoc = role.getAssociation();
for (AssociationRoleIF role2 : assoc.getRoles())
if (ObjectUtils.different(role2, role) && role2.getType().equals(rType2))
return true;
}
return false;
}
public static TopicIF findBinaryPlayer(TopicMap tm, LocatorIF atypeId,
TopicIF player1, LocatorIF rtype1Id, LocatorIF rtype2Id) {
TopicIF aType = OntopolyModelUtils.getTopicIF(tm, atypeId);
TopicIF rType1 = OntopolyModelUtils.getTopicIF(tm, rtype1Id);
TopicIF rType2 = OntopolyModelUtils.getTopicIF(tm, rtype2Id);
Iterator<AssociationRoleIF> iter = player1.getRoles().iterator();
while (iter.hasNext()) {
AssociationRoleIF role1 = iter.next();
AssociationIF assoc = role1.getAssociation();
Collection<AssociationRoleIF> roles = assoc.getRoles();
if (roles.size() != 2) continue;
if (ObjectUtils.equals(role1.getType(), rType1) &&
ObjectUtils.equals(assoc.getType(), aType)) {
Iterator<AssociationRoleIF> riter = roles.iterator();
while (riter.hasNext()) {
AssociationRoleIF role2 = riter.next();
if (ObjectUtils.different(role1, role2) && role2.getType().equals(rType2)) {
return role2.getPlayer();
}
}
}
}
return null;
}
public static Collection<TopicIF> findBinaryPlayers(
TopicMap tm, TopicIF aType, TopicIF player1, TopicIF rType1, TopicIF rType2) {
List<TopicIF> result = new ArrayList<TopicIF>();
Iterator<AssociationRoleIF> iter = player1.getRoles().iterator();
while (iter.hasNext()) {
AssociationRoleIF role1 = iter.next();
AssociationIF assoc = role1.getAssociation();
Collection<AssociationRoleIF> roles = assoc.getRoles();
if (roles.size() != 2) continue;
if (ObjectUtils.equals(role1.getType(), rType1) &&
ObjectUtils.equals(assoc.getType(), aType)) {
Iterator<AssociationRoleIF> riter = roles.iterator();
while (riter.hasNext()) {
AssociationRoleIF role2 = riter.next();
if (ObjectUtils.different(role1, role2) && role2.getType().equals(rType2)) {
result.add(role2.getPlayer());
}
}
}
}
return result;
}
public static Collection<TopicIF> findBinaryPlayers(TopicMap tm, TopicIF aType,
TopicIF player1, TopicIF rType1, TopicIF rType2, TopicIF theme) {
List<TopicIF> result = new ArrayList<TopicIF>();
Iterator<AssociationRoleIF> iter = player1.getRoles().iterator();
while (iter.hasNext()) {
AssociationRoleIF role1 = iter.next();
AssociationIF assoc = role1.getAssociation();
Collection<TopicIF> scope = assoc.getScope();
if (!(scope.size() == 1 && scope.contains(theme))) continue;
Collection<AssociationRoleIF> roles = assoc.getRoles();
if (roles.size() != 2) continue;
if (ObjectUtils.equals(role1.getType(), rType1) &&
ObjectUtils.equals(assoc.getType(), aType)) {
Iterator<AssociationRoleIF> riter = roles.iterator();
while (riter.hasNext()) {
AssociationRoleIF role2 = riter.next();
if (ObjectUtils.different(role1, role2) && role2.getType().equals(rType2)) {
result.add(role2.getPlayer());
}
}
}
}
return result;
}
public static AssociationIF findBinaryAssociation(
TopicMap tm, TopicIF aType,
TopicIF player1, TopicIF rType1, TopicIF player2, TopicIF rType2) {
Iterator<AssociationRoleIF> iter = player1.getRoles().iterator();
while (iter.hasNext()) {
AssociationRoleIF role1 = iter.next();
AssociationIF assoc = role1.getAssociation();
Collection<AssociationRoleIF> roles = assoc.getRoles();
if (roles.size() != 2) continue;
if (ObjectUtils.equals(role1.getType(), rType1) &&
ObjectUtils.equals(assoc.getType(), aType)) {
Iterator<AssociationRoleIF> riter = roles.iterator();
while (riter.hasNext()) {
AssociationRoleIF role2 = riter.next();
if (ObjectUtils.different(role1, role2) && role2.getType().equals(rType2) && role2.getPlayer().equals(player2)) {
return assoc;
}
}
}
}
return null;
}
public static Collection<AssociationIF> findBinaryAssociations(
TopicMap tm, TopicIF aType,
TopicIF player1, TopicIF rType1, TopicIF rType2) {
String query = "select $A from role-player($R1, %player1%), "
+ "type($R1, %rType1%), association-role($A, $R1) ,"
+ "type($A, %aType%), association-role($A, $R2) ,"
+ "type($R2, %rType2%)?";
Map<String,TopicIF> params = new HashMap<String,TopicIF>();
params.put("player1", player1);
params.put("rType1", rType1);
params.put("aType", aType);
params.put("rType2", rType2);
QueryMapper<AssociationIF> qm = tm.newQueryMapperNoWrap();
return qm.queryForList(query, params);
}
public static Collection<TopicIF> findTernaryPlayers(
TopicMap tm, TopicIF aType, TopicIF player1, TopicIF rType1, TopicIF player2, TopicIF rType2, TopicIF rType3) {
AssociationRoleIF secondRole;
AssociationRoleIF thirdRole;
List<TopicIF> result = new ArrayList<TopicIF>();
Iterator<AssociationRoleIF> iter = player1.getRoles().iterator();
while (iter.hasNext()) {
secondRole = null;
thirdRole = null;
AssociationRoleIF role1 = iter.next();
AssociationIF assoc = role1.getAssociation();
if (ObjectUtils.equals(role1.getType(), rType1) &&
ObjectUtils.equals(assoc.getType(), aType)) {
Iterator<AssociationRoleIF> riter = assoc.getRoles().iterator();
while (riter.hasNext()) {
AssociationRoleIF role2 = riter.next();
if (ObjectUtils.different(role1, role2)) {
if (ObjectUtils.equals(rType2, role2.getType()) && ObjectUtils.equals(player2, role2.getPlayer()))
secondRole = role2;
else if (ObjectUtils.equals(rType3, role2.getType()))
thirdRole = role2;
else
break;
}
}
if (secondRole != null && thirdRole != null)
result.add(thirdRole.getPlayer());
}
}
return result;
}
public static AssociationIF findTernaryAssociation(
TopicMap tm, TopicIF aType, TopicIF player1,
TopicIF rType1, TopicIF player2, TopicIF rType2, TopicIF player3,
TopicIF rType3) {
String query = "select $A from role-player($R1, %player1%), "
+ "type($R1, %rType1%), association-role($A, $R1) ,"
+ "type($A, %aType%), association-role($A, $R2) ,"
+ "role-player($R2, %player2%), type($R2, %rType2%) ,"
+ "association-role($A, $R3) , role-player($R3, %player3%),"
+ "type($R3, %rType3%)?";
Map<String,TopicIF> params = new HashMap<String,TopicIF>();
params.put("player1", player1);
params.put("rType1", rType1);
params.put("aType", aType);
params.put("player2", player2);
params.put("rType2", rType2);
params.put("player3", player3);
params.put("rType3", rType3);
QueryMapper<AssociationIF> qm = tm.newQueryMapperNoWrap();
return removeDuplicateAssociations(qm.queryForList(query, params));
}
public static List<AssociationIF> findAssociations(
TopicIF aType, TopicIF[] rTypes, TopicIF[] players, Collection<TopicIF> scope) {
List<AssociationIF> result = new ArrayList<AssociationIF>();
TopicIF player = players[0];
Collection<AssociationRoleIF> proles = player.getRoles();
Iterator<AssociationRoleIF> iter = proles.iterator();
while (iter.hasNext()) {
AssociationRoleIF role = iter.next();
// compare current player
if (!ObjectUtils.equals(role.getType(), rTypes[0])) continue;
// compare association type
AssociationIF assoc = role.getAssociation();
if (!ObjectUtils.equals(assoc.getType(), aType)) continue;
// compare arity
Collection<AssociationRoleIF> roles = assoc.getRoles();
if (rTypes.length != roles.size()) continue;
// compare scope
if (!CollectionUtils.equalsUnorderedSet(assoc.getScope(), scope)) continue;
// compare other players
int matchCount = 1;
boolean[] matches = new boolean[players.length];
matches[0] = true;
Iterator<AssociationRoleIF> riter = roles.iterator();
while (riter.hasNext()) {
AssociationRoleIF orole = riter.next();
if (ObjectUtils.equals(orole, role)) continue;
TopicIF ortype = orole.getType();
TopicIF oplayer = orole.getPlayer();
int match = -1;
for (int i=1; i < players.length; i++) {
if (ObjectUtils.equals(ortype, rTypes[i]) &&
ObjectUtils.equals(oplayer, players[i]) && !matches[i]) {
match = i;
matches[i] = true;
matchCount++;
break;
}
}
if (match == -1) break;
}
if (matchCount == players.length)
result.add(assoc);
}
return result;
}
private static AssociationIF removeDuplicateAssociations(Collection<AssociationIF> associations) {
AssociationIF uniqueAssoc = null;
Iterator<AssociationIF> it = associations.iterator();
if (it.hasNext()) {
uniqueAssoc = it.next();
}
while (it.hasNext()) {
it.next().remove();
}
return uniqueAssoc;
}
public static void makeUnaryAssociation(TopicIF aType, TopicIF player,
TopicIF rType) {
AssociationBuilder assocBuilder = new AssociationBuilder(aType, rType);
assocBuilder.makeAssociation(player);
}
public static void makeBinaryAssociation(TopicIF aType, TopicIF player1,
TopicIF rType1, TopicIF player2, TopicIF rType2) {
AssociationBuilder assocBuilder = new AssociationBuilder(aType, rType1,
rType2);
assocBuilder.makeAssociation(player1, player2);
}
public static void makeTernaryAssociation(TopicIF aType, TopicIF player1,
TopicIF rType1, TopicIF player2, TopicIF rType2, TopicIF player3,
TopicIF rType3) {
AssociationBuilder assocBuilder = new AssociationBuilder(aType, rType1,
rType2, rType3);
assocBuilder.makeAssociation(player1, player2, player3);
}
public static void makeQuadaryAssociation(TopicIF aType, TopicIF player1,
TopicIF rType1, TopicIF player2, TopicIF rType2, TopicIF player3,
TopicIF rType3, TopicIF player4,
TopicIF rType4) {
AssociationBuilder assocBuilder = new AssociationBuilder(aType, rType1,
rType2, rType3, rType4);
assocBuilder.makeAssociation(player1, player2, player3, player4);
}
public static AssociationIF makeAssociation(
TopicIF aType, TopicIF[] rTypes, TopicIF[] players, Collection<TopicIF> scope) {
TopicMapBuilderIF builder = aType.getTopicMap().getBuilder();
AssociationIF assoc = builder.makeAssociation(aType);
for (int i=0; i < rTypes.length; i++) {
builder.makeAssociationRole(assoc, rTypes[i], players[i]);
}
return assoc;
}
public static OccurrenceIF findOccurrence(TopicIF oType, TopicIF topicIF) {
Iterator<OccurrenceIF> it = topicIF.getOccurrences().iterator();
while (it.hasNext()) {
OccurrenceIF occurIF = it.next();
if (ObjectUtils.equals(occurIF.getType(), oType))
return occurIF;
}
return null;
}
public static OccurrenceIF findOccurrence(TopicIF oType, TopicIF topicIF, LocatorIF datatype, Collection<TopicIF> scope) {
Iterator<OccurrenceIF> it = topicIF.getOccurrences().iterator();
while (it.hasNext()) {
OccurrenceIF occurIF = it.next();
if (ObjectUtils.equals(occurIF.getType(), oType) &&
ObjectUtils.equals(occurIF.getDataType(), datatype) &&
CollectionUtils.equalsUnorderedSet(occurIF.getScope(), scope))
return occurIF;
}
return null;
}
public static List<OccurrenceIF> findOccurrences(TopicIF oType, TopicIF topicIF) {
List<OccurrenceIF> result = new ArrayList<OccurrenceIF>();
Iterator<OccurrenceIF> it = topicIF.getOccurrences().iterator();
while (it.hasNext()) {
OccurrenceIF occurIF = it.next();
if (ObjectUtils.equals(occurIF.getType(), oType))
result.add(occurIF);
}
return result;
}
public static List<OccurrenceIF> findOccurrences(TopicIF oType, TopicIF topicIF, LocatorIF datatype) {
List<OccurrenceIF> result = new ArrayList<OccurrenceIF>();
Iterator<OccurrenceIF> it = topicIF.getOccurrences().iterator();
while (it.hasNext()) {
OccurrenceIF occurIF = it.next();
if (ObjectUtils.equals(occurIF.getType(), oType) &&
ObjectUtils.equals(occurIF.getDataType(), datatype) )
result.add(occurIF);
}
return result;
}
public static List<OccurrenceIF> findOccurrences(TopicIF oType, TopicIF topicIF, Collection<TopicIF> scope) {
List<OccurrenceIF> result = new ArrayList<OccurrenceIF>();
Iterator<OccurrenceIF> it = topicIF.getOccurrences().iterator();
while (it.hasNext()) {
OccurrenceIF occurIF = it.next();
if (ObjectUtils.equals(occurIF.getType(), oType) &&
CollectionUtils.equalsUnorderedSet(occurIF.getScope(), scope))
result.add(occurIF);
}
return result;
}
public static List<OccurrenceIF> findOccurrences(TopicIF oType, TopicIF topicIF, LocatorIF datatype, Collection<TopicIF> scope) {
List<OccurrenceIF> result = new ArrayList<OccurrenceIF>();
Iterator<OccurrenceIF> it = topicIF.getOccurrences().iterator();
while (it.hasNext()) {
OccurrenceIF occurIF = it.next();
if (ObjectUtils.equals(occurIF.getType(), oType) &&
ObjectUtils.equals(occurIF.getDataType(), datatype) &&
CollectionUtils.equalsUnorderedSet(occurIF.getScope(), scope))
result.add(occurIF);
}
return result;
}
public static List<OccurrenceIF> findOccurrences(TopicIF oType, TopicIF topicIF, String value, Collection<TopicIF> scope) {
List<OccurrenceIF> result = new ArrayList<OccurrenceIF>();
Iterator<OccurrenceIF> it = topicIF.getOccurrences().iterator();
while (it.hasNext()) {
OccurrenceIF occurIF = it.next();
if (ObjectUtils.equals(occurIF.getValue(), value) &&
ObjectUtils.equals(occurIF.getType(), oType) &&
CollectionUtils.equalsUnorderedSet(occurIF.getScope(), scope))
result.add(occurIF);
}
return result;
}
public static List<OccurrenceIF> findOccurrences(TopicIF oType, TopicIF topicIF, String value, LocatorIF datatype, Collection<TopicIF> scope) {
List<OccurrenceIF> result = new ArrayList<OccurrenceIF>();
Iterator<OccurrenceIF> it = topicIF.getOccurrences().iterator();
while (it.hasNext()) {
OccurrenceIF occurIF = it.next();
if (ObjectUtils.equals(occurIF.getValue(), value) &&
ObjectUtils.equals(occurIF.getType(), oType) &&
ObjectUtils.equals(occurIF.getDataType(), datatype) &&
CollectionUtils.equalsUnorderedSet(occurIF.getScope(), scope))
result.add(occurIF);
}
return result;
}
public static OccurrenceIF makeOccurrence(TopicIF otype, TopicIF topicIF, String value, LocatorIF datatype, Collection<TopicIF> scope) {
TopicMapBuilderIF builder = topicIF.getTopicMap().getBuilder();
OccurrenceIF occ = builder.makeOccurrence(topicIF, otype, value, datatype);
Iterator<TopicIF> iter = scope.iterator();
while (iter.hasNext()) {
TopicIF scopingTopic = iter.next();
occ.addTheme(scopingTopic);
}
return occ;
}
public static List<TopicNameIF> findTopicNames(TopicIF nType, TopicIF topicIF) {
List<TopicNameIF> result = new ArrayList<TopicNameIF>();
Iterator<TopicNameIF> it = topicIF.getTopicNames().iterator();
while (it.hasNext()) {
TopicNameIF nameIF = it.next();
if (ObjectUtils.equals(nameIF.getType(), nType))
result.add(nameIF);
}
return result;
}
public static List<TopicNameIF> findTopicNames(TopicIF nType, TopicIF topicIF, Collection<TopicIF> scope) {
List<TopicNameIF> result = new ArrayList<TopicNameIF>();
Iterator<TopicNameIF> it = topicIF.getTopicNames().iterator();
while (it.hasNext()) {
TopicNameIF nameIF = it.next();
if (ObjectUtils.equals(nameIF.getType(), nType) &&
CollectionUtils.equalsUnorderedSet(nameIF.getScope(), scope))
result.add(nameIF);
}
return result;
}
public static List<TopicNameIF> findTopicNames(TopicIF nType, TopicIF topicIF, String value) {
List<TopicNameIF> result = new ArrayList<TopicNameIF>();
Iterator<TopicNameIF> it = topicIF.getTopicNames().iterator();
while (it.hasNext()) {
TopicNameIF nameIF = it.next();
if (ObjectUtils.equals(nameIF.getValue(), value) &&
ObjectUtils.equals(nameIF.getType(), nType))
result.add(nameIF);
}
return result;
}
public static List<TopicNameIF> findTopicNames(TopicIF nType, TopicIF topicIF, String value, Collection<TopicIF> scope) {
List<TopicNameIF> result = new ArrayList<TopicNameIF>();
Iterator<TopicNameIF> it = topicIF.getTopicNames().iterator();
while (it.hasNext()) {
TopicNameIF nameIF = it.next();
if (ObjectUtils.equals(nameIF.getValue(), value) &&
ObjectUtils.equals(nameIF.getType(), nType) &&
CollectionUtils.equalsUnorderedSet(nameIF.getScope(), scope))
result.add(nameIF);
}
return result;
}
public static TopicNameIF makeTopicName(TopicIF ntype, TopicIF topicIF, String value, Collection<TopicIF> scope) {
TopicMapBuilderIF builder = topicIF.getTopicMap().getBuilder();
TopicNameIF name = builder.makeTopicName(topicIF, ntype, value);
Iterator<TopicIF> iter = scope.iterator();
while (iter.hasNext()) {
TopicIF scopingTopic = iter.next();
name.addTheme(scopingTopic);
}
return name;
}
public static List<AssociationRoleIF> findRoles(TopicIF aType, TopicIF rType, TopicIF player) {
List<AssociationRoleIF> result = new ArrayList<AssociationRoleIF>();
Iterator<AssociationRoleIF> it = player.getRoles().iterator();
while (it.hasNext()) {
AssociationRoleIF role = it.next();
AssociationIF association = role.getAssociation();
if (ObjectUtils.equals(role.getType(), rType) &&
ObjectUtils.equals(association.getType(), aType))
result.add(role);
}
return result;
}
public static List<AssociationRoleIF> findRoles(TopicIF aType, TopicIF rType, TopicIF player, Collection<TopicIF> scope) {
List<AssociationRoleIF> result = new ArrayList<AssociationRoleIF>();
Iterator<AssociationRoleIF> it = player.getRoles().iterator();
while (it.hasNext()) {
AssociationRoleIF role = it.next();
AssociationIF association = role.getAssociation();
if (ObjectUtils.equals(role.getType(), rType) &&
ObjectUtils.equals(association.getType(), aType) &&
CollectionUtils.equalsUnorderedSet(association.getScope(), scope))
result.add(role);
}
return result;
}
public static void setName(TopicIF nType, TopicIF topic, String value, Collection<TopicIF> scope) {
if (value != null && topic != null) {
// update existing new name or create a new one
Collection<TopicNameIF> names = OntopolyModelUtils.findTopicNames(null, topic, scope);
Iterator<TopicNameIF> iter = names.iterator();
if (iter.hasNext()) {
TopicNameIF bn = iter.next();
bn.setValue(value);
} else {
topic.getTopicMap().getBuilder().makeTopicName(topic, value);
}
// remove superfluous names
while (iter.hasNext())
((TopicNameIF) iter.next()).remove();
}
}
}