/* * #! * 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.statistics; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; 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; /** * Class used for locating associations and their types. */ public class TopicAssocDep { private TopicMapIF tm; private HashMap assocTypes, assocRoleTypes, assocDetails, associations; private StringifierIF ts = TopicStringifiers.getDefaultStringifier(); private String[] roles; public TopicAssocDep(TopicMapIF tm) throws NullPointerException { this.tm = tm; associations = new HashMap(); traverse(tm.getAssociations()); } /** * Returns a set of keys for the associations */ public Collection getAssociations() { return associations.keySet(); } /** * Gets the id for the association type. */ public String getAssociationTypeId(String key) { if (key == null || !associations.containsKey(key)) return "null"; return ((InternalAssociation)associations.get(key)).getAssociationTypeId(); } /** * Gets the name of the association. */ public String getAssociationType(String key) { if (key == null || !associations.containsKey(key)) return "null"; return ((InternalAssociation)associations.get(key)).getAssociationType(); } /** * Gets the number of times this association occurres in the topicmap. */ public int getNumberOfOccurrences(String key) { return ((InternalAssociation)associations.get(key)).getNumberOfOccurrences(); } /** * Returns a hashmap containg the id of the assocrltype, and the name of assocrltype */ public HashMap getAssociationRoleTypes(String key) { if (key == null || !associations.containsKey(key)) return null; return ((InternalAssociation)associations.get(key)).getAssociationRoleTypes(); } /** * Return a hashmap containg the id and the name of all the topictypes for all the * topics that play in this association. */ public HashMap getAssociationRoles(String key) { if (key == null || !associations.containsKey(key)) return null; return ((InternalAssociation)associations.get(key)).getAssociationRoles(); } /** * Returns a Collection of the different associations that have this associationtype. */ public Collection getAssociationDetails(String key) { if (key == null || !associations.containsKey(key)) return null; return ((InternalAssociation)associations.get(key)).getAssociationDetails(); } /** * Gets the association roles ordered aplhabetically */ public String[] getAssociationRoleTypesOrdered(String key) { if (key == null || !associations.containsKey(key)) return null; return ((InternalAssociation)associations.get(key)).getAssociationRoleTypesOrdered(); } public String[] getAssociationDetails(String key, AssociationIF association) { if (key == null || !associations.containsKey(key)) return null; return ((InternalAssociation)associations.get(key)).getAssociationDetails(association); } //---------------------------------------------------- // Internal methods //---------------------------------------------------- //Traverses the Topic Map. private void traverse(Collection assocs) { Iterator it = assocs.iterator(); while (it.hasNext()) { AssociationIF temp = (AssociationIF)it.next(); String key = createKey(temp); InternalAssociation assoc; if (associations.containsKey(key)) { assoc = (InternalAssociation)associations.get(key); assoc.increment(); } else { assoc = new InternalAssociation(temp); associations.put(key, assoc); } assoc.addAssociation(temp); } } //Creates a string key for the association. private String createKey(AssociationIF aif) { HashMap types = new HashMap(); String assocname = ""; try { assocname = ts.toString(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(); if (arif.getType() != null) rolenames[i] = getName(arif.getType()); else rolenames[i] = "null"; i++; } //Sorts the rolenames in lexiographical order. sortKey(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++) { retur += "$" + rolenames[i]; } return retur; } /** * Insert Sort, which sorts an array of strings in lexiographical order */ private void sortKey(String [] names) { for (int i = 0; i+1 < names.length; i++) { if (names[i].compareTo(names[i+1]) > 0){ //Found one, shuffle it to the lowest index possible. String temp = names[i]; names[i] = names[i+1]; names[i+1] = temp; int j = i; boolean done = false; while (j != 0 && !done) { if (names[j].compareTo(names[j-1]) < 0) { temp = names[j]; names[j] = names[j-1]; names[j-1] = temp; } else done = true; j--; }//end of while. }//end of if }//end of for }//end of method public String[] sortAlpha(Collection collection) { String[] retur = new String[collection.size()]; Iterator it = collection.iterator(); int k = 0; for (int i = 0; i < collection.size(); i++) { retur[i] = (String)it.next(); } //Starting at the first index in the array. for (int i = 0; i < retur.length - 1; i++) { if (retur[i].compareTo(retur[i+1]) > 0){ //Found one, shuffle it to the lowest index possible. String temp = retur[i]; retur[i] = retur[i+1]; retur[i+1] = temp; int j = i; boolean done = false; while (j != 0 && !done) { if (retur[j].compareTo(retur[j-1]) < 0) { temp = retur[j]; retur[j] = retur[j-1]; retur[j-1] = temp; } else done = true; j--; }//end of while. }//end of if }//end of for return retur; } //Gets the name of the topic private String getName(TopicIF topic) { if (topic == null) return "null"; else { String name = ts.toString(topic); if (name.equalsIgnoreCase("[No name]")) name = "{topicid: " + topic.getObjectId() + "}"; return name; } } /** * Innerclass that is used to represent each type of association, and * also keep track of all the different assocations of this type. */ private class InternalAssociation { AssociationIF association; TopicIF associationtype; HashMap roleTypes; HashMap assocRoles; int number_of_assocs; Collection associations; String[] roles; InternalAssociation(AssociationIF association) { this.associationtype = association.getType(); this.association = association; roleTypes = addAssocRoleTypes(association); number_of_assocs = 1; assocRoles = new HashMap(); associations = new ArrayList(); //roles = getAssociationRoleTypesOrdered(); } /** * Returns the object id for the association type */ protected String getAssociationTypeId() { return (associationtype == null ? "null" : associationtype.getObjectId()); } /** * Returns the association type. */ protected String getAssociationType() { return getName(associationtype); } /** * Returns the number of occurrences for this association */ protected int getNumberOfOccurrences() { return number_of_assocs; } /** * Returns a hashmap containg the id of the assocrltype, and the name of assocrltype */ protected HashMap getAssociationRoleTypes() { return roleTypes; } /** * Return a hashmap containg the id and the name of all the topictypes for all the * topics that play in this association. */ protected HashMap getAssociationRoles() { return assocRoles; } /** * Returns all the associations of this type. */ protected Collection getAssociationDetails() { return associations; } /** * Returns the players of of this association ordred by the role types. */ protected String[] getAssociationDetails(AssociationIF association) { String[] result = new String[association.getRoles().size()]; Iterator it = association.getRoles().iterator(); while (it.hasNext()) { AssociationRoleIF role = (AssociationRoleIF)it.next(); String name = getName(role.getType()); roles = getAssociationRoleTypesOrdered(); for (int i = 0; i < roles.length; i++) { // Inserts the correct player name and id in the correct alphabetical order. if (name.equals(roles[i]) && result[i] == null) { result[i] = getName(role.getPlayer()) + "$" + role.getPlayer().getObjectId(); } } } return result; } /** * Gets the assoc types ordered. */ protected String[] getAssociationRoleTypesOrdered() { Collection roletypes = new ArrayList(); Iterator it = association.getRoles().iterator(); while (it.hasNext()) { String name = getName(((AssociationRoleIF)it.next()).getType()); roletypes.add(name); } return sortAlpha(roletypes); } /** * Increments the number of associations with the same role types. */ protected void increment() { number_of_assocs++; } /** * Adds an association to the collection of assocation with the same * types, and roles. */ protected void addAssociation(AssociationIF association) { associations.add(association); addAssociationRoles(association); } /** * Gets the id for the assocrltypes, and their names. */ private HashMap addAssocRoleTypes(AssociationIF association) { HashMap temp = new HashMap(); Iterator it = association.getRoles().iterator(); while (it.hasNext()) { AssociationRoleIF assocrl = (AssociationRoleIF) it.next(); TopicIF type = assocrl.getType(); if (type != null) temp.put(type.getObjectId(), getName(type)); else temp.put("null", getName(null)); } return temp; } /** * Adds the id for all the different topic types that play a role * in this association. */ private void addAssociationRoles(AssociationIF association) { Iterator it = association.getRoles().iterator(); while (it.hasNext()) { AssociationRoleIF assocrl = (AssociationRoleIF)it.next(); if (assocrl.getPlayer() == null) { if (!assocRoles.containsValue(getName(null))) assocRoles.put("null", getName(null)); } else { Iterator iter = assocrl.getPlayer().getTypes().iterator(); while (iter.hasNext()) { TopicIF temp_topic = (TopicIF)iter.next(); assocRoles.put(temp_topic.getObjectId(), getName(temp_topic)); } } } } } // inner class }//end of class.