/*
* #!
* 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.conversion;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.infoset.impl.basic.URILocator;
import net.ontopia.topicmaps.core.AssociationIF;
import net.ontopia.topicmaps.core.OccurrenceIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TopicMapBuilderIF;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.topicmaps.core.TopicMapStoreIF;
import net.ontopia.topicmaps.core.TopicNameIF;
import net.ontopia.topicmaps.core.index.ScopeIndexIF;
import net.ontopia.topicmaps.entry.TopicMapReferenceIF;
import net.ontopia.topicmaps.entry.TopicMapRepositoryIF;
import net.ontopia.topicmaps.entry.TopicMapSourceIF;
import net.ontopia.topicmaps.impl.utils.AbstractTopicMapStore;
import net.ontopia.topicmaps.query.core.DeclarationContextIF;
import net.ontopia.topicmaps.query.core.InvalidQueryException;
import net.ontopia.topicmaps.query.core.QueryProcessorIF;
import net.ontopia.topicmaps.query.core.QueryResultIF;
import net.ontopia.topicmaps.query.utils.QueryUtils;
import net.ontopia.topicmaps.utils.DuplicateSuppressionUtils;
import net.ontopia.topicmaps.utils.MergeUtils;
import net.ontopia.topicmaps.utils.TopicStringifiers;
import net.ontopia.topicmaps.xml.XTMTopicMapReference;
import net.ontopia.utils.ObjectUtils;
import net.ontopia.utils.OntopiaRuntimeException;
import net.ontopia.utils.StringUtils;
import net.ontopia.utils.URIUtils;
import ontopoly.OntopolyApplication;
import ontopoly.OntopolyContext;
import ontopoly.model.PSI;
import ontopoly.model.TopicMap;
import ontopoly.sysmodel.OntopolyRepository;
import ontopoly.sysmodel.TopicMapSource;
public class ConversionUtils {
private static final LocatorIF psibase;
private static final LocatorIF xsdbase;
private static final LocatorIF xtmbase;
private static final LocatorIF teqbase;
static {
psibase = URILocator.create("http://psi.ontopia.net/ontology/");
xsdbase = URILocator.create("http://www.w3.org/2001/XMLSchema");
xtmbase = URILocator.create("http://www.topicmaps.org/xtm/1.0/core.xtm");
teqbase = URILocator.create("http://www.techquila.com/psi/hierarchy/");
}
public static String upgradeExisting(TopicMap topicMap) {
UpgradeUtils.upgradeTopicMap(topicMap);
String referenceId = topicMap.getId();
OntopolyContext.getOntopolyRepository().registerOntopolyTopicMap(referenceId, topicMap.getName());
return referenceId;
}
public static String convertExisting(TopicMap topicMap, String tmname) {
OntopolyRepository ontopolyRepository = OntopolyContext.getOntopolyRepository();
TopicMapRepositoryIF repository = ontopolyRepository.getTopicMapRepository();
String referenceId = inferAndCreateSchema(null, topicMap, tmname, repository);
OntopolyContext.getOntopolyRepository().registerOntopolyTopicMap(referenceId, topicMap.getName());
return referenceId;
}
public static String convertNew(TopicMap oldTopicMap, String tmname, TopicMapSource tmsource) {
TopicMapRepositoryIF repository = OntopolyContext.getOntopolyRepository().getTopicMapRepository();
try {
String referenceId = OntopolyContext.getOntopolyRepository().createOntopolyTopicMap(tmsource.getId(), tmname);
TopicMapIF topicMapIF = OntopolyContext.getOntopolyRepository().getTopicMapRepository()
.getReferenceByKey(referenceId).createStore(false).getTopicMap();
TopicMap newTopicMap = new TopicMap(topicMapIF, referenceId);
return inferAndCreateSchema(oldTopicMap, newTopicMap, tmname, repository);
} catch (Exception e) {
throw new OntopiaRuntimeException(e);
}
}
private static String inferAndCreateSchema(TopicMap oldTopicMap, TopicMap newTopicMap, String tmname, TopicMapRepositoryIF repository) {
boolean newtopicmap = (oldTopicMap != null);
// create new topic map
TopicMapStoreIF store = newTopicMap.getTopicMapIF().getStore();
try {
TopicMapStoreIF oldstore = null;
LocatorIF oldbaseloc = null;
if (newtopicmap) {
// get old store
oldstore = oldTopicMap.getTopicMapIF().getStore();
oldbaseloc = oldstore.getBaseAddress();
}
// convert topic map
TopicMapIF tm = store.getTopicMap();
Collection<LocatorIF> reifier_subinds = new HashSet<LocatorIF>();
LocatorIF versionTopicPSI = URIUtils.getURILocator("http://psi.ontopia.net/ontology/ted-ontology-version");
if (newtopicmap) {
// get hold of old reifier
TopicIF oreifier = oldstore.getTopicMap().getReifier();
if (oreifier == null) {
reifier_subinds = Collections.emptySet();
} else {
reifier_subinds = oreifier.getSubjectIdentifiers();
}
// merge in old topic map
try {
MergeUtils.mergeInto(store.getTopicMap(), oldstore.getTopicMap());
} finally {
oldstore.close();
}
} else {
// import TED ontology
TopicMapReferenceIF ontologyTopicMapReference = repository.getReferenceByKey(OntopolyRepository.ONTOLOGY_TOPIC_MAP_ID);
if (ontologyTopicMapReference == null)
throw new OntopiaRuntimeException("Could not find ontology topic map '" + OntopolyRepository.ONTOLOGY_TOPIC_MAP_ID + "'");
TopicMapStoreIF ontologyTopicMapStore = ontologyTopicMapReference.createStore(true);
try {
MergeUtils.mergeInto(tm, ontologyTopicMapStore.getTopicMap());
} finally {
ontologyTopicMapStore.close();
}
// reify topic map
TopicMapBuilderIF tmbuilder = tm.getBuilder();
TopicIF reifier = tm.getReifier();
if (reifier == null) {
reifier = tmbuilder.makeTopic();
tm.setReifier(reifier);
tmbuilder.makeTopicName(reifier, tmname);
TopicIF versionTopic = tm.getTopicBySubjectIdentifier(versionTopicPSI);
tmbuilder.makeOccurrence(reifier, versionTopic, Float.toString(OntopolyApplication.CURRENT_VERSION_NUMBER));
}
}
// copy old reifier reify topic map if not already done
TopicIF nreifier = tm.getReifier();
TopicIF oreifier = null;
Iterator<LocatorIF> iiter = reifier_subinds.iterator();
while (iiter.hasNext()) {
LocatorIF reifier_subind = iiter.next();
oreifier = tm.getTopicBySubjectIdentifier(reifier_subind);
if (oreifier != null) break;
}
TopicMapBuilderIF tmbuilder = tm.getBuilder();
if (nreifier == null) {
if (oreifier != null) {
nreifier = oreifier;
} else {
nreifier = tmbuilder.makeTopic();
tm.setReifier(nreifier);
}
} else {
if (oreifier != null && ObjectUtils.different(oreifier, nreifier))
MergeUtils.mergeInto(nreifier, oreifier);
}
// make topic map reifier and instance of on:topic-map
nreifier.addType(topicByPSI(psibase.resolveAbsolute("topic-map"), tm));
// replace reifier names with new one
if (newtopicmap) {
Object[] nrnames = nreifier.getTopicNames().toArray();
for (int i=0; i < nrnames.length; i++) {
TopicNameIF tn = (TopicNameIF)nrnames[i];
tn.remove();
}
// String tmname = oldTopicMap.getName();1
tmbuilder.makeTopicName(nreifier, tmname);
}
// Check ontology version:
TopicIF versionTopic = tm.getTopicBySubjectIdentifier(versionTopicPSI);
String versionNumber = Float.toString(OntopolyApplication.CURRENT_VERSION_NUMBER);
OccurrenceIF versionOcc = getOccurrenceOfType(nreifier, versionTopic);
if (versionOcc == null)
// create new ontology version occurrence
tmbuilder.makeOccurrence(nreifier, versionTopic, versionNumber);
else
// Update ontology version value
versionOcc.setValue(versionNumber);
// infer TED schema
inferAndCreateSchema(tm, nreifier);
// run duplicate suppression
DuplicateSuppressionUtils.removeDuplicates(tm);
TopicMapReferenceIF ref = store.getReference();
if (ref instanceof XTMTopicMapReference) {
// use old base address
LocatorIF newbaseloc = store.getBaseAddress();
if (oldbaseloc != null)
((AbstractTopicMapStore)store).setBaseAddress(oldbaseloc);
// save topic map with TED ontology
((XTMTopicMapReference)ref).save();
// revert to new base address
if (oldbaseloc != null)
((AbstractTopicMapStore)store).setBaseAddress(newbaseloc);
// close reference
ref.close();
}
// commit changes to topic map
store.commit();
} catch (Throwable e) {
if (store != null) store.abort();
throw new OntopiaRuntimeException(e);
} finally {
if (store != null) store.close();
}
// refresh repository, so that new reference is visible
repository.refresh();
return newTopicMap.getId();
}
private static void inferAndCreateSchema(TopicMapIF tm, TopicIF reifier)
throws InvalidQueryException, MalformedURLException {
// create tracker instance
SchemaTracker tracker = new SchemaTracker();
// track topics and associations
tracker.trackTopics(tm.getTopics());
tracker.trackAssociations(tm.getAssociations());
TopicMapBuilderIF tmbuilder = tm.getBuilder();
QueryProcessorIF queryProcessor = QueryUtils.getQueryProcessor(tm);
QueryResultIF result = null;
// declaration context
DeclarationContextIF dc = QueryUtils.parseDeclarations(tm,
"using on for i\"http://psi.ontopia.net/ontology/\" " +
"using xtm for i\"http://www.topicmaps.org/xtm/1.0/core.xtm#\" " +
"supertype-of($SUB, $SUP) :-" +
" { xtm:superclass-subclass($SUB : xtm:subclass, $SUP : xtm:superclass) |" +
" xtm:superclass-subclass($SUB : xtm:subclass, $X : xtm:superclass)," +
" supertype-of($X, $SUP) }. " +
"descendant-of($ANC, $DES) :- " +
" { xtm:superclass-subclass($ANC : xtm:superclass, $DES : xtm:subclass) |" +
" xtm:superclass-subclass($ANC : xtm:superclass, $MID : xtm:subclass)," +
" descendant-of($MID, $DES) }.");
// load superclass-subclass hierarchy
Map<TopicIF,Collection<TopicIF>> subsup = new HashMap<TopicIF,Collection<TopicIF>>();
Map<TopicIF,Collection<TopicIF>> supsub = new HashMap<TopicIF,Collection<TopicIF>>();
result = queryProcessor.execute("select $SUP, $SUB from xtm:superclass-subclass($SUB : xtm:subclass, $SUP : xtm:superclass)?", dc);
try {
while (result.next()) {
TopicIF sup = (TopicIF)result.getValue(0);
TopicIF sub = (TopicIF)result.getValue(1);
// subtype to supertype mapping
Collection<TopicIF> x = subsup.get(sub);
if (x == null) {
x = new HashSet<TopicIF>();
subsup.put(sub, x);
}
x.add(sup);
// supertype to subtype mapping
Collection<TopicIF> y = supsub.get(sup);
if (y == null) {
y = new HashSet<TopicIF>();
supsub.put(sup, y);
}
y.add(sub);
}
} finally {
result.close();
}
// aggregate all ontology types
Collection<TopicIF> onto_types = tracker.getOntologyTypes();
// translate name scopes into name types
ScopeIndexIF sindex = (ScopeIndexIF)tm.getIndex("net.ontopia.topicmaps.core.index.ScopeIndexIF");
Collection<TopicIF> nstypes = new HashSet<TopicIF>();
Iterator<TopicIF> nsiter = tracker.getSuspectNameScopes().iterator();
while (nsiter.hasNext()) {
TopicIF ntheme = nsiter.next();
if (onto_types.contains(ntheme) || isTEDTopic(ntheme) || ntheme == reifier) continue;
nstypes.add(ntheme);
// translate name scope into name type
Iterator<TopicNameIF> tniter = sindex.getTopicNames(ntheme).iterator();
while (tniter.hasNext()) {
TopicNameIF tn = tniter.next();
tn.setType(ntheme);
tn.removeTheme(ntheme);
// WARN: what if basename have other themes in its name scope?
}
// register name field on topic type
Iterator<TopicIF> nstiter = tracker.getNameScopeTopicTypes(ntheme).iterator();
while (nstiter.hasNext()) {
TopicIF ttype = nstiter.next();
if (ttype == null) continue; // HACK: don't know what to do here.
TopicIF nfield = registerNameType(ntheme, tm);
registerNameField(ttype, nfield,
topicByPSI(psibase.resolveAbsolute("cardinality-0-M"), tm), tm);
}
}
// untyped topics
Iterator<TopicIF> utyped = tracker.getUntypedTopics().iterator();
while (utyped.hasNext()) {
TopicIF untyped = utyped.next();
if (untyped == null ||
onto_types.contains(untyped) ||
isTEDTopic(untyped) ||
untyped == reifier ||
nstypes.contains(untyped) ||
supsub.containsKey(untyped) ||
subsup.containsKey(untyped)) continue;
registerUntypedTopic(untyped, tm);
}
// add super types to list of topic types
Collection<TopicIF> all_topic_types = new HashSet<TopicIF>(tracker.getTopicTypes());
all_topic_types.addAll(supsub.keySet());
// get topmost super types
Collection<TopicIF> topmost_types = getTopMostTypes(all_topic_types, subsup);
// create schema
Iterator<TopicIF> ttypes = all_topic_types.iterator();
while (ttypes.hasNext()) {
TopicIF ttype = ttypes.next();
if (ttype == null || isTEDTopic(ttype)) continue;
// topic type
registerTopicType(ttype, tm);
// register default name
if (topmost_types.contains(ttype))
registerDefaultNameField(ttype, tm);
// subject locator
if (!isSubjectLocatorDeclaredOnSuperType(ttype, tracker, subsup)) {
int maxcard = getBroadestSubjectLocatorMaxCardinality(ttype, tracker, supsub);
if (maxcard > 0) {
TopicIF subloc_card = getCardinalityTopic(getBroadestSubjectLocatorMinCardinality(ttype, tracker, supsub),
maxcard, tm);
registerSubjectLocatorField(ttype, subloc_card, tm);
}
}
// subject indicator
if (!isSubjectIndicatorDeclaredOnSuperType(ttype, tracker, subsup)) {
int maxcard = getBroadestSubjectIndicatorMaxCardinality(ttype, tracker, supsub);
if (maxcard > 0) {
TopicIF subind_card = getCardinalityTopic(getBroadestSubjectIndicatorMinCardinality(ttype, tracker, supsub),
maxcard, tm);
registerSubjectIndicatorField(ttype, subind_card, tm);
}
}
// name types
Collection<TopicIF> n_decl_on_supertype = getNamesDeclaredOnSuperType(ttype, tracker, subsup);
Iterator<TopicIF> ntypes = tracker.getNameTypes(ttype).iterator();
while (ntypes.hasNext()) {
TopicIF ntype = ntypes.next();
if (ntype == null || isTEDTopic(ntype) || n_decl_on_supertype.contains(ntype)) continue;
TopicIF cardinality = getCardinalityTopic(getBroadestNameTypeMinCardinality(ttype, ntype, tracker, supsub),
getBroadestNameTypeMaxCardinality(ttype, ntype, tracker, supsub), tm);
TopicIF nfield = registerNameType(ntype, tm);
registerNameField(ttype, nfield, cardinality, tm);
}
// external occurrence types
Collection<TopicIF> oe_decl_on_supertype = getExternalOccurrencesDeclaredOnSuperType(ttype, tracker, subsup);
TopicIF datatype_uri = topicByPSI(xsdbase.resolveAbsolute("#anyURI"), tm);
Iterator<TopicIF> oetypes = tracker.getExternalOccurrenceTypes(ttype).iterator();
while (oetypes.hasNext()) {
TopicIF oetype = oetypes.next();
if (oetype == null || isTEDTopic(oetype) || oe_decl_on_supertype.contains(oetype)) continue;
TopicIF cardinality = getCardinalityTopic(getBroadestExternalOccurrenceTypeMinCardinality(ttype, oetype, tracker, supsub),
getBroadestExternalOccurrenceTypeMaxCardinality(ttype, oetype, tracker, supsub), tm);
oetype = registerOccurrenceType(oetype, datatype_uri, tm);
registerOccurrenceField(ttype, oetype, cardinality, tm);
}
// internal occurrence types
Collection<TopicIF> oi_decl_on_supertype = getInternalOccurrencesDeclaredOnSuperType(ttype, tracker, subsup);
TopicIF datatype_string = topicByPSI(xsdbase.resolveAbsolute("#string"), tm);
Iterator<TopicIF> oitypes = tracker.getInternalOccurrenceTypes(ttype).iterator();
while (oitypes.hasNext()) {
TopicIF oitype = oitypes.next();
if (oitype == null || isTEDTopic(oitype) || oi_decl_on_supertype.contains(oitype)) continue;
TopicIF cardinality = getCardinalityTopic(getBroadestInternalOccurrenceTypeMinCardinality(ttype, oitype, tracker, supsub),
getBroadestInternalOccurrenceTypeMaxCardinality(ttype, oitype, tracker, supsub), tm);
oitype = registerOccurrenceType(oitype, datatype_string, tm);
registerOccurrenceField(ttype, oitype, cardinality, tm);
}
}
// association types
Collection<TopicIF> excluded_atypes = new HashSet<TopicIF>();
excluded_atypes.add(topicByPSI(xtmbase.resolveAbsolute("#superclass-subclass"), tm));
excluded_atypes.add(topicByPSI(teqbase.resolveAbsolute("#hierarchical-relation-type"), tm));
Iterator<TopicIF> atypes = tracker.getAssociationTypes().iterator();
while (atypes.hasNext()) {
TopicIF atype = atypes.next();
if (atype == null || isTEDTopic(atype) || excluded_atypes.contains(atype)) continue;
// association type
atype = registerAssociationType(atype, tm);
// symmetric association
if (tracker.isSymmetricAssociationType(atype))
addAssociation1(psibase.resolveAbsolute("is-symmetric"),
atype, psibase.resolveAbsolute("association-type"), tm);
// role types
Iterator<TopicIF> rtypes = tracker.getRoleTypes(atype).iterator();
while (rtypes.hasNext()) {
TopicIF rtype = rtypes.next();
if (rtype == null || isTEDTopic(rtype)) continue;
// role type
rtype = registerRoleType(rtype, tm);
// count player type instances
Collection<TopicIF> ptypes = tracker.getPlayerTypes(atype, rtype);
int ptypes_count = 0;
Iterator<TopicIF> ptiter = ptypes.iterator();
while (ptiter.hasNext()) {
ptypes_count += tracker.getTopicTypeInstances(ptiter.next());
}
// use search-dialog if drop-down list too long (> 50 elements)
TopicIF interfaceControl;
if (ptypes_count > 50)
interfaceControl = topicByPSI(psibase.resolveAbsolute("search-dialog"), tm);
else
interfaceControl = topicByPSI(psibase.resolveAbsolute("drop-down-list"), tm);
TopicIF rfield = registerRoleField(atype, rtype, interfaceControl, tm);
ptiter = ptypes.iterator();
while (ptiter.hasNext()) {
TopicIF ptype = ptiter.next();
if (ptype == null)
ptype = getUntypedTopic(psibase, tm);
else if (isTEDTopic(ptype))
continue;
if (!isRoleDeclaredOnSuperType(ptype, ptypes, subsup)) {
TopicIF cardinality = getCardinalityTopic(getBroadestPlayerTypeMinCardinality(atype, rtype, ptype, tracker, supsub),
getBroadestPlayerTypeMaxCardinality(atype, rtype, ptype, tracker, supsub), tm);
registerPlayerTypeField(rfield, ptype, cardinality, tm);
}
}
}
}
// remove identity fields duplicated on subtypes
// remove name fields duplicated on subtypes
// remove occurrence fields duplicated on subtypes
// remove fields duplicated on subtypes
result = queryProcessor.execute("select $A1 from direct-instance-of($TTYPE, on:topic-type), descendant-of($XTYPE, $TTYPE), " +
"role-player($R1, $TTYPE), type($R1, on:field-owner), " +
"association-role($A1, $R1), type($A1, on:has-field), " +
"association-role($A1, $R2), $R1 /= $R2, type($R2, on:field-definition), role-player($R2, $FIELD), " +
"role-player($R3, $XTYPE), type($R3, on:field-owner), " +
"association-role($A2, $R3), type($A2, on:has-field), " +
"association-role($A2, $R4), $R3 /= $R4, type($R4, on:field-definition), role-player($R4, $FIELD)?", dc);
try {
while (result.next()) {
AssociationIF assoc = (AssociationIF)result.getValue(0);
assoc.remove();
}
} finally {
result.close();
}
// generate field order
TopicIF ted_field_order = topicByPSI(psibase.resolveAbsolute("field-order"), tm);
List<Object[]> fields = new ArrayList<Object[]>();
result = queryProcessor.execute("/* #OPTION: optimizer.reorder=false */ " +
"select $topic, $owner, $field from " +
"direct-instance-of($topic, on:topic-type), { descendant-of($owner, $topic) | $owner = $topic }, " +
"role-player($R1, $owner), type($R1, on:field-owner), " +
"association-role($A, $R1), type($A, on:has-field), " +
"association-role($A, $R2), $R1 /= $R2, type($R2, on:field-definition), role-player($R2, $field), "+
"not(instance-of($topic, on:system-topic))" +
"order by $topic ?", dc);
try {
while (result.next()) {
fields.add(result.getValues());
}
} finally {
result.close();
}
// sort the fields
Collections.sort(fields, new FieldsComparator(tm, psibase));
// update/create field order values
int fOrder = 1000;
TopicIF prevTopic = null;
Iterator<Object[]> fiter = fields.iterator();
while (fiter.hasNext()) {
Object[] f = fiter.next();
TopicIF curTopic = (TopicIF)f[0];
if (prevTopic != curTopic) {
fOrder = 1000;
prevTopic = curTopic;
}
// create new field order
OccurrenceIF occ = tmbuilder.makeOccurrence(curTopic, ted_field_order, StringUtils.pad(fOrder, '0', 9));
occ.addTheme((TopicIF)f[2]);
fOrder = fOrder + 1000;
}
}
private static class FieldsComparator implements Comparator<Object> {
TopicIF ted_nt;
TopicIF ted_si;
TopicIF ted_sl;
TopicIF ted_ot;
TopicIF ted_at;
TopicIF ted_untyped_name;
private FieldsComparator(TopicMapIF tm, LocatorIF psibase) throws MalformedURLException {
ted_nt = topicByPSI(psibase.resolveAbsolute("name-type"), tm);
ted_si = topicByPSI(psibase.resolveAbsolute("subject-identifier"), tm);
ted_sl = topicByPSI(psibase.resolveAbsolute("subject-locator"), tm);
ted_ot = topicByPSI(psibase.resolveAbsolute("occurrence-type"), tm);
ted_at = topicByPSI(psibase.resolveAbsolute("association-type"), tm);
ted_untyped_name = topicByPSI(PSI.TMDM_TOPIC_NAME, tm);
}
public int compare(Object o1, Object o2) {
Object[] f1 = (Object[])o1;
Object[] f2 = (Object[])o2;
// sort by topic type
int tids = ((TopicIF)f1[0]).getObjectId().compareTo(((TopicIF)f2[0]).getObjectId());
if (tids != 0) return tids;
// sort by field class
int fkey1 = 1000;
int fkey2 = 1000;
if (ted_sl.equals(f1[2]))
fkey1 = 2;
else if (ted_si.equals(f1[2]))
fkey1 = 3;
else {
Iterator<TopicIF> fit = ((TopicIF)f1[2]).getTypes().iterator();
while (fit.hasNext()) {
TopicIF ft1 = fit.next();
if (ted_nt.equals(ft1)) {
if (ted_untyped_name.equals(f1[2]))
fkey1 = 0;
else
fkey1 = 1;
}
else if (ted_ot.equals(ft1))
fkey1 = 4;
else if (ted_at.equals(ft1))
fkey1 = 5;
else
continue;
break;
}
}
if (ted_sl.equals(f2[2]))
fkey2 = 2;
else if (ted_si.equals(f2[2]))
fkey2 = 3;
else {
Iterator<TopicIF> fit = ((TopicIF)f2[2]).getTypes().iterator();
while (fit.hasNext()) {
TopicIF ft2 = fit.next();
if (ted_nt.equals(ft2)) {
if (ted_untyped_name.equals(f2[2]))
fkey2 = 0;
else
fkey2 = 1;
}
else if (ted_ot.equals(ft2))
fkey2 = 4;
else if (ted_at.equals(ft2))
fkey2 = 5;
else
continue;
break;
}
}
//! if (fkey1 == 1000) System.out.println("FT1 type unknown: " + f1[2]);
//! if (fkey2 == 1000) System.out.println("FT2 type unknown: " + f2[2]);
if (fkey1 != fkey2) return (fkey1 > fkey2 ? 1 : -1);
// sort by field type name
String fn1 = TopicStringifiers.toString((TopicIF)(fkey1 == 5 ? f1[3] : f1[2]));
String fn2 = TopicStringifiers.toString((TopicIF)(fkey2 == 5 ? f2[3] : f2[2]));
return fn1.compareTo(fn2);
}
}
private static void registerTopicType(TopicIF topic, TopicMapIF tm) throws MalformedURLException {
// topic to be an instance of on:topic-type
TopicIF topicType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("topic-type"));
topic.addType(topicType);
}
private static void registerUntypedTopic(TopicIF topic, TopicMapIF tm) throws MalformedURLException {
// topic to be an instance of on:untyped-topic
topic.addType(getUntypedTopic(psibase, tm));
}
private static TopicIF registerNameType(TopicIF ntype, TopicMapIF tm) throws MalformedURLException {
// topic to be an instance of on:name-type
TopicIF nameType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("name-type"));
ntype.addType(nameType);
return ntype;
}
private static TopicIF registerOccurrenceType(TopicIF otype, TopicIF datatype, TopicMapIF tm) throws MalformedURLException {
// topic to be an instance of on:occurrence-type
TopicIF occType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("occurrence-type"));
otype.addType(occType);
// datatype
addAssociation2(psibase.resolveAbsolute("has-datatype"),
otype, psibase.resolveAbsolute("field-definition"),
datatype, psibase.resolveAbsolute("datatype"), tm);
return otype;
}
private static TopicIF registerAssociationType(TopicIF atype, TopicMapIF tm) throws MalformedURLException {
// topic to be an instance of on:association-type
TopicIF assocType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("association-type"));
atype.addType(assocType);
return atype;
}
private static TopicIF registerRoleType(TopicIF rtype, TopicMapIF tm) throws MalformedURLException {
// topic to be an instance of on:role-type
TopicIF roleType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("role-type"));
rtype.addType(roleType);
return rtype;
}
private static TopicIF registerSubjectLocatorField(TopicIF ttype, TopicIF cardinality, TopicMapIF tm) throws MalformedURLException {
TopicIF ifield = findIdentityField(topicByPSI(psibase.resolveAbsolute("subject-locator"), tm), tm);
registerField(ttype, ifield, cardinality, tm);
return ifield;
}
private static TopicIF registerSubjectIndicatorField(TopicIF ttype, TopicIF cardinality, TopicMapIF tm) throws MalformedURLException {
TopicIF ifield = findIdentityField(topicByPSI(psibase.resolveAbsolute("subject-identifier"), tm), tm);
registerField(ttype, ifield, cardinality, tm);
return ifield;
}
// private static TopicIF registerItemIdentifierField(TopicIF ttype, TopicIF cardinality, TopicMapIF tm) throws MalformedURLException {
// TopicIF ifield = findIdentityField(topicByPSI(psibase.resolveAbsolute("item-identifier"), tm), tm);
// registerField(ttype, ifield, cardinality, tm);
// return ifield;
// }
private static TopicIF findIdentityField(TopicIF itype, TopicMapIF tm) throws MalformedURLException {
QueryProcessorIF qp = QueryUtils.getQueryProcessor(tm);
QueryResultIF qr = null;
TopicIF ifield = null;
try {
Map<String,TopicIF> params = Collections.singletonMap("itype", itype);
qr = qp.execute("using on for i\"http://psi.ontopia.net/ontology/\"\n" +
"select $ifield from on:has-identity-type(%itype% : on:identity-type, $ofield : on:identity-field)?", params);
if (qr.next())
ifield = (TopicIF)qr.getValue(0);
} catch (Exception e) {
if (qr != null) qr.close();
}
if (ifield == null) {
TopicIF fieldType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("identity-field"));
ifield = tm.getBuilder().makeTopic(fieldType);
addAssociation2(psibase.resolveAbsolute("has-identity-type"),
itype, psibase.resolveAbsolute("identity-type"),
ifield, psibase.resolveAbsolute("identity-field"), tm);
}
return ifield;
}
private static void registerDefaultNameField(TopicIF topic, TopicMapIF tm) throws MalformedURLException {
// mandatory default name
registerNameField(topic, topicByPSI(PSI.TMDM_TOPIC_NAME, tm),
topicByPSI(psibase.resolveAbsolute("cardinality-1-1"), tm), tm);
}
private static TopicIF registerNameField(TopicIF ttype, TopicIF ntype, TopicIF cardinality, TopicMapIF tm) throws MalformedURLException {
TopicIF nfield = findNameField(ntype, tm);
registerField(ttype, nfield, cardinality, tm);
return nfield;
}
private static TopicIF findNameField(TopicIF ntype, TopicMapIF tm) throws MalformedURLException {
QueryProcessorIF qp = QueryUtils.getQueryProcessor(tm);
QueryResultIF qr = null;
TopicIF nfield = null;
try {
Map<String,TopicIF> params = Collections.singletonMap("ntype", ntype);
qr = qp.execute("using on for i\"http://psi.ontopia.net/ontology/\"\n" +
"select $nfield from on:has-name-type(%ntype% : on:name-type, $nfield : on:name-field)?", params);
if (qr.next())
nfield = (TopicIF)qr.getValue(0);
} catch (Exception e) {
if (qr != null) qr.close();
}
if (nfield == null) {
TopicIF fieldType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("name-field"));
nfield = tm.getBuilder().makeTopic(fieldType);
addAssociation2(psibase.resolveAbsolute("has-name-type"),
ntype, psibase.resolveAbsolute("name-type"),
nfield, psibase.resolveAbsolute("name-field"), tm);
}
return nfield;
}
private static void registerField(TopicIF ttype, TopicIF xfield, TopicIF cardinality, TopicMapIF tm) throws MalformedURLException {
addAssociation2(psibase.resolveAbsolute("has-field"),
ttype, psibase.resolveAbsolute("field-owner"),
xfield, psibase.resolveAbsolute("field-definition"), tm);
addAssociation2(psibase.resolveAbsolute("has-cardinality"),
xfield, psibase.resolveAbsolute("field-definition"),
cardinality, psibase.resolveAbsolute("cardinality"), tm);
}
private static TopicIF registerOccurrenceField(TopicIF ttype, TopicIF otype, TopicIF cardinality, TopicMapIF tm) throws MalformedURLException {
TopicIF ofield = findOccurrenceField(otype, tm);
registerField(ttype, ofield, cardinality, tm);
addAssociation2(psibase.resolveAbsolute("has-datatype"),
ofield, psibase.resolveAbsolute("field-definition"),
topicByPSI(psibase.resolveAbsolute("datatype-string"), tm), psibase.resolveAbsolute("datatype"), tm);
return ofield;
}
private static TopicIF findOccurrenceField(TopicIF otype, TopicMapIF tm) throws MalformedURLException {
QueryProcessorIF qp = QueryUtils.getQueryProcessor(tm);
QueryResultIF qr = null;
TopicIF ofield = null;
try {
Map<String,TopicIF> params = Collections.singletonMap("otype", otype);
qr = qp.execute("using on for i\"http://psi.ontopia.net/ontology/\"\n" +
"select $ofield from on:has-occurrence-type(%otype% : on:occurrence-type, $ofield : on:occurrence-field)?", params);
if (qr.next())
ofield = (TopicIF)qr.getValue(0);
} catch (Exception e) {
if (qr != null) qr.close();
}
if (ofield == null) {
TopicIF fieldType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("occurrence-field"));
ofield = tm.getBuilder().makeTopic(fieldType);
addAssociation2(psibase.resolveAbsolute("has-occurrence-type"),
otype, psibase.resolveAbsolute("occurrence-type"),
ofield, psibase.resolveAbsolute("occurrence-field"), tm);
}
return ofield;
}
private static TopicIF registerRoleField(TopicIF atype, TopicIF rtype, TopicIF interfaceControl, TopicMapIF tm) throws MalformedURLException {
TopicIF afield = findAssociationField(atype, tm);
TopicIF rfield = findRoleField(afield, rtype, tm);
// addAssociation2(psibase.resolveAbsolute("has-association-field"),
// afield, psibase.resolveAbsolute("association-field"),
// rfield, psibase.resolveAbsolute("role-field"), tm);
return rfield;
}
private static TopicIF findAssociationField(TopicIF atype, TopicMapIF tm) throws MalformedURLException {
QueryProcessorIF qp = QueryUtils.getQueryProcessor(tm);
QueryResultIF qr = null;
TopicIF afield = null;
try {
Map<String,TopicIF> params = Collections.singletonMap("atype", atype);
qr = qp.execute("using on for i\"http://psi.ontopia.net/ontology/\"\n" +
"select $afield from on:has-association-type(%atype% : on:association-type, $afield : on:association-field)?", params);
if (qr.next())
afield = (TopicIF)qr.getValue(0);
} catch (Exception e) {
if (qr != null) qr.close();
}
if (afield == null) {
TopicIF fieldType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("association-field"));
afield = tm.getBuilder().makeTopic(fieldType);
addAssociation2(psibase.resolveAbsolute("has-association-type"),
atype, psibase.resolveAbsolute("association-type"),
afield, psibase.resolveAbsolute("association-field"), tm);
}
return afield;
}
private static TopicIF findRoleField(TopicIF afield, TopicIF rtype, TopicMapIF tm) throws MalformedURLException {
QueryProcessorIF qp = QueryUtils.getQueryProcessor(tm);
QueryResultIF qr = null;
TopicIF rfield = null;
try {
Map<String,TopicIF> params = new HashMap<String,TopicIF>(2);
params.put("afield", afield);
params.put("rtype", rtype);
qr = qp.execute("using on for i\"http://psi.ontopia.net/ontology/\"\n" +
"select $rfield from on:has-association-field(%afield% : on:association-field, $rfield : on:role-field), " +
"on:has-role-type($rfield : on:role-field, %rtype% : on:role-type)?", params);
if (qr.next())
rfield = (TopicIF)qr.getValue(0);
} catch (Exception e) {
if (qr != null) qr.close();
}
if (rfield == null) {
TopicIF fieldType = tm.getTopicBySubjectIdentifier(psibase.resolveAbsolute("role-field"));
rfield = tm.getBuilder().makeTopic(fieldType);
addAssociation2(psibase.resolveAbsolute("has-role-type"),
rtype, psibase.resolveAbsolute("role-type"),
rfield, psibase.resolveAbsolute("role-field"), tm);
addAssociation2(psibase.resolveAbsolute("has-association-field"),
afield, psibase.resolveAbsolute("association-field"),
rfield, psibase.resolveAbsolute("role-field"), tm);
}
return rfield;
}
private static void registerPlayerTypeField(TopicIF rfield, TopicIF ptype, TopicIF cardinality, TopicMapIF tm) throws MalformedURLException {
registerField(ptype, rfield, cardinality, tm);
}
private static void addAssociation1(LocatorIF atypePSI,
TopicIF player1, LocatorIF rtype1PSI, TopicMapIF tm) throws MalformedURLException {
TopicMapBuilderIF tmbuilder = tm.getBuilder();
AssociationIF assoc = tmbuilder.makeAssociation(topicByPSI(atypePSI, tm));
tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype1PSI, tm), player1);
}
private static void addAssociation2(LocatorIF atypePSI,
TopicIF player1, LocatorIF rtype1PSI,
TopicIF player2, LocatorIF rtype2PSI, TopicMapIF tm) throws MalformedURLException {
TopicMapBuilderIF tmbuilder = tm.getBuilder();
AssociationIF assoc = tmbuilder.makeAssociation(topicByPSI(atypePSI, tm));
tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype1PSI, tm), player1);
tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype2PSI, tm), player2);
}
// private static void addAssociation3(LocatorIF atypePSI,
// TopicIF player1, LocatorIF rtype1PSI,
// TopicIF player2, LocatorIF rtype2PSI,
// TopicIF player3, LocatorIF rtype3PSI, TopicMapIF tm) throws MalformedURLException {
// TopicMapBuilderIF tmbuilder = tm.getBuilder();
// AssociationIF assoc = tmbuilder.makeAssociation(topicByPSI(atypePSI, tm));
// tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype1PSI, tm), player1);
// tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype2PSI, tm), player2);
// tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype3PSI, tm), player3);
// }
//
// private static void addAssociation4(LocatorIF atypePSI,
// TopicIF player1, LocatorIF rtype1PSI,
// TopicIF player2, LocatorIF rtype2PSI,
// TopicIF player3, LocatorIF rtype3PSI,
// TopicIF player4, LocatorIF rtype4PSI, TopicMapIF tm) throws MalformedURLException {
// TopicMapBuilderIF tmbuilder = tm.getBuilder();
// AssociationIF assoc = tmbuilder.makeAssociation(topicByPSI(atypePSI, tm));
// tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype1PSI, tm), player1);
// tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype2PSI, tm), player2);
// tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype3PSI, tm), player3);
// tmbuilder.makeAssociationRole(assoc, topicByPSI(rtype4PSI, tm), player4);
// }
private static TopicIF topicByPSI(LocatorIF psiloc, TopicMapIF tm) throws MalformedURLException {
TopicIF topic = tm.getTopicBySubjectIdentifier(psiloc);
if (topic == null)
throw new OntopiaRuntimeException("Could not find topic with PSI '" + psiloc + "'");
return topic;
}
private static boolean isTEDTopic(TopicIF topic) {
Iterator<LocatorIF> iter = topic.getSubjectIdentifiers().iterator();
while (iter.hasNext()) {
LocatorIF loc = iter.next();
String address = loc.getAddress();
if (address.startsWith("http://psi.ontopia.net/ontology/") ||
address.startsWith("http://www.techquila.com/psi/hierarchy/"))
return true;
}
return false;
}
private static TopicIF getUntypedTopic(LocatorIF psibase, TopicMapIF tm) throws MalformedURLException {
LocatorIF psi = psibase.resolveAbsolute("untyped-topic");
TopicIF untyped = tm.getTopicBySubjectIdentifier(psi);
if (untyped == null) {
// create untyped type
TopicMapBuilderIF builder = tm.getBuilder();
untyped = builder.makeTopic();
untyped.addSubjectIdentifier(psi);
builder.makeTopicName(untyped, "Untyped topic");
// register topic type
registerTopicType(untyped, tm);
// register default name
registerDefaultNameField(untyped, tm);
}
return untyped;
}
protected static TopicIF getCardinalityTopic(int mincard, int maxcard, TopicMapIF tm) throws MalformedURLException {
//! mincard = 0; // HACK! ignoring min cardinality for now as it is harder to compute
if (maxcard == 1) {
if (mincard == 1)
return topicByPSI(psibase.resolveAbsolute("cardinality-1-1"), tm);
else
return topicByPSI(psibase.resolveAbsolute("cardinality-0-1"), tm);
} else if (maxcard > 1) {
if (mincard > 0)
return topicByPSI(psibase.resolveAbsolute("cardinality-1-M"), tm);
else
return topicByPSI(psibase.resolveAbsolute("cardinality-0-M"), tm);
} else
return topicByPSI(psibase.resolveAbsolute("cardinality-0-M"), tm);
}
protected TopicIF getCardinalityTopic(int cardinalityCount, TopicMapIF tm) throws MalformedURLException {
if (cardinalityCount <= 1)
return topicByPSI(psibase.resolveAbsolute("cardinality-0-1"), tm);
else
return topicByPSI(psibase.resolveAbsolute("cardinality-0-M"), tm);
}
protected static boolean isSubjectLocatorDeclaredOnSuperType(TopicIF ttype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> subsup) {
Collection<TopicIF> supertypes = subsup.get(ttype);
if (supertypes == null) return false;
Iterator<TopicIF> iter = supertypes.iterator();
while (iter.hasNext()) {
TopicIF supertype = iter.next();
if (tracker.getSubjectLocatorMaxCardinality(supertype) > 0)
return true;
boolean onsup = isSubjectLocatorDeclaredOnSuperType(supertype, tracker, subsup);
if (onsup) return true;
}
return false;
}
protected static boolean isSubjectIndicatorDeclaredOnSuperType(TopicIF ttype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> subsup) {
Collection<TopicIF> supertypes = subsup.get(ttype);
if (supertypes == null) return false;
Iterator<TopicIF> iter = supertypes.iterator();
while (iter.hasNext()) {
TopicIF supertype = iter.next();
if (tracker.getSubjectIndicatorMaxCardinality(supertype) > 0)
return true;
boolean onsup = isSubjectIndicatorDeclaredOnSuperType(supertype, tracker, subsup);
if (onsup) return true;
}
return false;
}
protected static Collection<TopicIF> getNamesDeclaredOnSuperType(TopicIF ttype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> subsup) {
Collection<TopicIF> supertypes = subsup.get(ttype);
if (supertypes == null) return Collections.emptySet();
Collection<TopicIF> result = new HashSet<TopicIF>();
Iterator<TopicIF> iter = supertypes.iterator();
while (iter.hasNext()) {
TopicIF supertype = iter.next();
result.addAll(tracker.getNameTypes(supertype));
result.addAll(getNamesDeclaredOnSuperType(supertype, tracker, subsup));
}
return result;
}
protected static Collection<TopicIF> getInternalOccurrencesDeclaredOnSuperType(TopicIF ttype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> subsup) {
Collection<TopicIF> supertypes = subsup.get(ttype);
if (supertypes == null) return Collections.emptySet();
Collection<TopicIF> result = new HashSet<TopicIF>();
Iterator<TopicIF> iter = supertypes.iterator();
while (iter.hasNext()) {
TopicIF supertype = iter.next();
result.addAll(tracker.getInternalOccurrenceTypes(supertype));
result.addAll(getInternalOccurrencesDeclaredOnSuperType(supertype, tracker, subsup));
}
return result;
}
protected static Collection<TopicIF> getExternalOccurrencesDeclaredOnSuperType(TopicIF ttype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> subsup) {
Collection<TopicIF> supertypes = subsup.get(ttype);
if (supertypes == null) return Collections.emptySet();
Collection<TopicIF> result = new HashSet<TopicIF>();
Iterator<TopicIF> iter = supertypes.iterator();
while (iter.hasNext()) {
TopicIF supertype = iter.next();
result.addAll(tracker.getExternalOccurrenceTypes(supertype));
result.addAll(getExternalOccurrencesDeclaredOnSuperType(supertype, tracker, subsup));
}
return result;
}
protected static boolean isRoleDeclaredOnSuperType(TopicIF ttype, Collection<TopicIF> ptypes, Map<TopicIF,Collection<TopicIF>> subsup) {
Collection<TopicIF> supertypes = subsup.get(ttype);
if (supertypes == null) return false;
Iterator<TopicIF> iter = supertypes.iterator();
while (iter.hasNext()) {
TopicIF supertype = (TopicIF)iter.next();
if (ptypes.contains(supertype)) return true;
boolean onsup = isRoleDeclaredOnSuperType(supertype, ptypes, subsup);
if (onsup) return true;
}
return false;
}
protected static int getBroadestSubjectLocatorMinCardinality(TopicIF ttype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getSubjectLocatorMinCardinality(ttype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestSubjectLocatorMinCardinality(subtype, tracker, supsub);
if (card < cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestSubjectLocatorMaxCardinality(TopicIF ttype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getSubjectLocatorMaxCardinality(ttype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestSubjectLocatorMaxCardinality(subtype, tracker, supsub);
if (card < cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestSubjectIndicatorMinCardinality(TopicIF ttype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getSubjectIndicatorMinCardinality(ttype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestSubjectIndicatorMinCardinality(subtype, tracker, supsub);
if (card < cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestSubjectIndicatorMaxCardinality(TopicIF ttype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getSubjectIndicatorMaxCardinality(ttype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestSubjectIndicatorMaxCardinality(subtype, tracker, supsub);
if (card < cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestNameTypeMinCardinality(TopicIF ttype, TopicIF ntype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getNameTypeMinCardinality(ttype, ntype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestNameTypeMinCardinality(subtype, ntype, tracker, supsub);
if (card > cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestNameTypeMaxCardinality(TopicIF ttype, TopicIF ntype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getNameTypeMaxCardinality(ttype, ntype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestNameTypeMaxCardinality(subtype, ntype, tracker, supsub);
if (card > cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestExternalOccurrenceTypeMinCardinality(TopicIF ttype, TopicIF oetype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getExternalOccurrenceTypeMinCardinality(ttype, oetype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestExternalOccurrenceTypeMinCardinality(subtype, oetype, tracker, supsub);
if (card < cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestExternalOccurrenceTypeMaxCardinality(TopicIF ttype, TopicIF oetype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getExternalOccurrenceTypeMaxCardinality(ttype, oetype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestExternalOccurrenceTypeMaxCardinality(subtype, oetype, tracker, supsub);
if (card > cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestInternalOccurrenceTypeMinCardinality(TopicIF ttype, TopicIF oitype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getInternalOccurrenceTypeMinCardinality(ttype, oitype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestInternalOccurrenceTypeMinCardinality(subtype, oitype, tracker, supsub);
if (card < cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestInternalOccurrenceTypeMaxCardinality(TopicIF ttype, TopicIF oitype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ttype);
int cardinality = tracker.getInternalOccurrenceTypeMaxCardinality(ttype, oitype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestInternalOccurrenceTypeMaxCardinality(subtype, oitype, tracker, supsub);
if (card > cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestPlayerTypeMinCardinality(TopicIF atype, TopicIF rtype, TopicIF ptype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ptype);
int cardinality = tracker.getPlayerTypeMinCardinality(atype, rtype, ptype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestPlayerTypeMinCardinality(atype, rtype, subtype, tracker, supsub);
if (card < cardinality)
cardinality = card;
}
return cardinality;
}
protected static int getBroadestPlayerTypeMaxCardinality(TopicIF atype, TopicIF rtype, TopicIF ptype, SchemaTracker tracker, Map<TopicIF,Collection<TopicIF>> supsub) {
Collection<TopicIF> subtypes = supsub.get(ptype);
int cardinality = tracker.getPlayerTypeMaxCardinality(atype, rtype, ptype);
if (subtypes == null) return cardinality;
Iterator<TopicIF> iter = subtypes.iterator();
while (iter.hasNext()) {
TopicIF subtype = iter.next();
int card = getBroadestPlayerTypeMaxCardinality(atype, rtype, subtype, tracker, supsub);
if (card > cardinality)
cardinality = card;
}
return cardinality;
}
protected static Collection<TopicIF> getTopMostTypes(Collection<TopicIF> ttypes, Map<TopicIF,Collection<TopicIF>> subsup) {
Collection<TopicIF> result = new HashSet<TopicIF>();
Iterator<TopicIF> iter = ttypes.iterator();
while (iter.hasNext()) {
TopicIF ttype = iter.next();
if (!subsup.containsKey(ttype))
result.add(ttype);
}
return result;
}
public static TopicMapSourceIF getSource(TopicMapRepositoryIF rep, String tmsource) {
TopicMapSourceIF source = null;
if (tmsource != null)
source = rep.getSourceById(tmsource);
else {
// if tmsource is null, it means the list wasn't displayed,
// because there's only one source which supports create. so we
// have to find it.
Iterator<TopicMapSourceIF> it = rep.getSources().iterator();
while (it.hasNext()) {
TopicMapSourceIF candidate = it.next();
if (candidate.supportsCreate()) {
source = candidate;
break;
}
}
if (source == null)
throw new OntopiaRuntimeException("No source supporting create was found!");
}
if (!source.supportsCreate())
throw new OntopiaRuntimeException("Topic map source '" + tmsource
+ "' does not support creating new topic maps.");
return source;
}
public static OccurrenceIF getOccurrenceOfType(TopicIF topic,
TopicIF occType) {
Collection<OccurrenceIF> result = getOccurrencesOfType(topic, occType);
if (result.isEmpty())
return null;
return result.iterator().next();
}
public static Collection<OccurrenceIF> getOccurrencesOfType(TopicIF topic,
TopicIF occType) {
List<OccurrenceIF> result = new ArrayList<OccurrenceIF>();
for (Iterator<OccurrenceIF> iter = topic.getOccurrences().iterator(); iter.hasNext();) {
OccurrenceIF occurrence = iter.next();
TopicIF otype = occurrence.getType();
if (otype != null && otype .equals(occType))
result.add(occurrence);
}
return result;
}
}