/*
* #!
* Ontopia Engine
* #-
* 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 net.ontopia.topicmaps.cmdlineutils.sanity;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.topicmaps.core.AssociationIF;
import net.ontopia.topicmaps.core.AssociationRoleIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.topicmaps.utils.TopicStringifiers;
import net.ontopia.utils.StringifierIF;
/**
* Topic map sanity controller.
*/
public class AssociationSanity {
private StringifierIF ts = TopicStringifiers.getDefaultStringifier();
/**
* This class finds all duplicate associations.
*/
private HashMap checkedAssociations, duplicateAssociations;
private HashMap numberOfDuplicates, assocTypes;
private Collection assocs;
private TopicMapIF tm;
public AssociationSanity(TopicMapIF tm) {
this.tm = tm;
checkedAssociations = new HashMap();
duplicateAssociations = new HashMap();
numberOfDuplicates = new HashMap();
assocTypes = new HashMap();
}
/**
* Returns a HashMap containing the duplicate Associations
*/
public HashMap getDuplicateAssociations() {
return duplicateAssociations;
}
/**
* Returns a HashMap containing the number of duplicate Associations.
*/
public HashMap getNumberOfDuplicates() {
return numberOfDuplicates;
}
/**
* Returns a HashMap of all the duplicate association types, using the string key
* as the keyvalue.
*/
public HashMap getAssociationTypes() {
return assocTypes;
}
//Traverses the Topic Map.
public void traverse() throws NullPointerException {
assocs = tm.getAssociations();
Iterator it = assocs.iterator();
while (it.hasNext()) {
AssociationIF temp = (AssociationIF)it.next();
String key = createKey(temp);
if (checkedAssociations.containsKey(key)) {
//This association already exist.
//Update number of occurrences and put it back in the
//HashMap.
Integer tempint = (Integer)numberOfDuplicates.get(key);
if (tempint == null){
//first occurrences of this duplicate Association.
numberOfDuplicates.put(key, new Integer(2));
} else {
//update the number of occurrences for this duplicate assoc.
int number = tempint.intValue() + 1;
numberOfDuplicates.put(key, new Integer(number));
}
//add the duplicate assoc to a HashMap.
duplicateAssociations.put(key, temp);
} else {
//This association has no duplicates - (yet).
checkedAssociations.put(key, temp);
}
}
}
//Creates a string key for the association.
//This key is made from the association and it's roles.
private String createKey(AssociationIF aif) {
//Creates a key for the association, and its roles.
HashMap types = new HashMap();
String assocname = "";
//assoc name as a single string.
try {
assocname = getTopicId(aif.getType());
} catch (NullPointerException e) {
assocname = "null";
}
//Role names as an array of strings.
Collection roles = aif.getRoles();
Iterator it = roles.iterator();
int size = roles.size();
int i = 0;
String [] rolenames = new String[size];
//Places the rolesnames in the array.
while (it.hasNext()) {
AssociationRoleIF arif = (AssociationRoleIF)it.next();
//rolenames[i] = getTopicId(arif.getPlayer());
rolenames[i] = ts.toString(arif.getPlayer());
types.put(rolenames[i], arif.getType());
i++;
}
//Sorts the rolenames in lexiographical order.
java.util.Arrays.sort(rolenames);
//Places the assocname first in the return string.
String retur = assocname;
//Adds the sorted rolenames using a '$'as a delimiter
for (i = 0; i < rolenames.length; i++) {
if (types.get(rolenames[i]) != null) {
retur += "$" +rolenames[i] + "$" + getTopicId((TopicIF)types.get(rolenames[i]));
} else {
retur += "$" +rolenames[i] + "$null";
}
}
assocTypes.put(retur, aif.getType());
return retur;
}
private String getTopicId(TopicIF topic) {
String id = null;
if (topic.getTopicMap().getStore().getBaseAddress() != null) {
String base = topic.getTopicMap().getStore().getBaseAddress().getAddress();
Iterator it = topic.getItemIdentifiers().iterator();
while (it.hasNext()) {
LocatorIF sloc = (LocatorIF) it.next();
if (sloc.getAddress().startsWith(base)) {
String addr = sloc.getAddress();
id = addr.substring(addr.indexOf('#') + 1);
break;
}
}
}
if (id == null)
id = "id" + topic.getObjectId();
return id;
}
}