/*
* #!
* Ontopia OSL Schema
* #-
* Copyright (C) 2001 - 2014 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.schema.impl.osl.cmdline;
import java.util.Iterator;
import java.util.Collection;
import java.util.HashMap;
import java.util.ArrayList;
import net.ontopia.topicmaps.core.AssociationRoleIF;
import net.ontopia.topicmaps.core.OccurrenceIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.core.TopicNameIF;
import net.ontopia.topicmaps.core.VariantNameIF;
import net.ontopia.topicmaps.schema.core.TMObjectMatcherIF;
import net.ontopia.topicmaps.schema.impl.osl.OSLSchema;
import net.ontopia.topicmaps.schema.impl.osl.OccurrenceConstraint;
import net.ontopia.topicmaps.schema.impl.osl.ScopeSpecification;
import net.ontopia.topicmaps.schema.impl.osl.TopicClass;
import net.ontopia.topicmaps.schema.impl.osl.TopicNameConstraint;
import net.ontopia.topicmaps.schema.impl.osl.TopicRoleConstraint;
import net.ontopia.topicmaps.schema.impl.osl.TypeSpecification;
import net.ontopia.topicmaps.schema.impl.osl.VariantConstraint;
public class TopicClassAnalyzer extends AbstractSchemaAnalyzer {
private TopicClass tclass;
private TopicIF ttype;
private Collection otherClasses;
private OSLSchema schema;
private HashMap occtypes, bnames, players;
private Collection topics;
/**
*
*/
public TopicClassAnalyzer(OSLSchema schema, TopicIF topictype, Collection topics) {
// init
otherClasses = new ArrayList();
this.players = new HashMap();
this.occtypes = new HashMap();
this.bnames = new HashMap();
this.schema = schema;
this.ttype = topictype;
this.topics = topics;
// setup
TypeSpecification spec = getTypeSpecification(ttype);
if (spec != null) {
tclass = new TopicClass(schema, "tc" + ttype.getObjectId());
tclass.setIsStrict(false);
tclass.setTypeSpecification(spec);
schema.addTopicClass(tclass);
}
}
/**
* Analyzes the topics for this TopicClassAnalyzerz
*/
public void analyze() {
// Not setup properly return with nothing.
if (tclass == null) return;
// Adding the current topic types id, so that no duplicate
// statements is made.
otherClasses.add(tclass.getId());
Iterator it = topics.iterator();
while (it.hasNext()) {
TopicIF topic = (TopicIF) it.next();
// Add otherclasses that the topics of this type can belong to.
registerOtherClasses(topic);
// Add occurrences of this topic
registerOccurrences(topic);
// Add basenames of this topic
registerBasenames(topic);
// Add the different association role player types of this topic.
registerPlayerTypes(topic);
}
}
/**
* Register other classes of which this class is allowed to be an instance of.
* If the result set is empty, topics of this class can not be instances of any
* other class.
* @param topic the topic in which to look for other classes.
*/
public void registerOtherClasses(TopicIF topic) {
// Add otherclasses that the topics of this type can belong to.
Iterator othertypes = topic.getTypes().iterator();
while (othertypes.hasNext()) {
TopicIF othertype = (TopicIF)othertypes.next();
// Add if not equal to primary type
if (othertype != ttype &&
!otherClasses.contains(othertype.getObjectId())) {
tclass.addOtherClass(getTypeSpecification(othertype));
otherClasses.add(othertype.getObjectId());
}
}
}
public void registerOccurrences(TopicIF topic) {
Iterator it = topic.getOccurrences().iterator();
while (it.hasNext()) {
OccurrenceIF occ = (OccurrenceIF) it.next();
//analyzer.registerOccurrence(occ);
// try to find if this occurrence type is already
// registered.
OccurrenceConstraint constraint =
(OccurrenceConstraint) occtypes.get(occ.getType());
if (constraint == null) {
// Create a new OccurrenceConstraint
constraint = new OccurrenceConstraint(tclass);
constraint.setTypeSpecification(getTypeSpecification(occ.getType()));
occtypes.put(occ.getType(), constraint);
tclass.addOccurrenceConstraint(constraint);
ScopeSpecification spec = getScopeSpecification(occ);
spec.setMatch(ScopeSpecification.MATCH_SUPERSET);
constraint.setScopeSpecification(spec);
if (occ.getLocator() != null)
constraint.setInternal(OccurrenceConstraint.RESOURCE_EXTERNAL);
else if (occ.getValue() != null)
constraint.setInternal(OccurrenceConstraint.RESOURCE_INTERNAL);
} else {
// Gets the old scope specs
ScopeSpecification spec = constraint.getScopeSpecification();
Collection matchers = spec.getThemeMatchers();
// Gets the new scope specs
ScopeSpecification newSpec = getScopeSpecification(occ);
// Adds them together
Iterator iter = newSpec.getThemeMatchers().iterator();
while (iter.hasNext()) {
TMObjectMatcherIF matcher = (TMObjectMatcherIF)iter.next();
// Check if this scope already is registered.
boolean contains = false;
Iterator iter2 = spec.getThemeMatchers().iterator();
while (iter2.hasNext()) {
TMObjectMatcherIF tmp = (TMObjectMatcherIF)iter2.next();
if (tmp.equals(matcher)) contains = true;
}
// If not already registered, register the new scope.
if (!contains)
spec.addThemeMatcher(matcher);
}
// Adds all the scope specs to the constraint
spec.setMatch(ScopeSpecification.MATCH_SUPERSET);
constraint.setScopeSpecification(spec);
switch (constraint.getInternal()) {
case OccurrenceConstraint.RESOURCE_EXTERNAL:
if (occ.getValue() != null)
constraint.setInternal(OccurrenceConstraint.RESOURCE_EITHER);
break;
case OccurrenceConstraint.RESOURCE_INTERNAL:
if (occ.getLocator() != null)
constraint.setInternal(OccurrenceConstraint.RESOURCE_EITHER);
}
}
}
}
public void registerBasenames(TopicIF topic) {
Iterator it = topic.getTopicNames().iterator();
while (it.hasNext()) {
TopicNameIF bname = (TopicNameIF)it.next();
TopicNameConstraint constraint;
Iterator iter = bname.getScope().iterator();
while (iter.hasNext()) {
TopicIF scope = (TopicIF)iter.next();
if (!bnames.containsKey(scope)) {
constraint = new TopicNameConstraint(tclass);
ScopeSpecification spec = getScopeSpecification(bname);
if (spec != null)
constraint.setScopeSpecification(spec);
Iterator iter2 = bname.getVariants().iterator();
while (iter2.hasNext()) {
VariantNameIF variant = (VariantNameIF)iter2.next();
VariantConstraint vconstraint = new VariantConstraint(constraint);
ScopeSpecification sspec = getScopeSpecification(variant);
if (sspec != null)
vconstraint.setScopeSpecification(sspec);
constraint.addVariantConstraint(vconstraint);
}
bnames.put(scope, constraint);
tclass.addTopicNameConstraint(constraint);
}
}
}
}
public void registerPlayerTypes(TopicIF topic) {
Iterator it = topic.getRoles().iterator();
while (it.hasNext()) {
AssociationRoleIF assocrl = (AssociationRoleIF)it.next();
TopicIF atype = assocrl.getAssociation().getType();
TopicIF rtype = assocrl.getType();
String constraint_key = makeKey(ttype, atype, rtype);
// BUG: Need to key by player type + role type + association type
TopicRoleConstraint constraint;
if (!players.containsKey(constraint_key)) {
// If the constraint is null, then register a new one.
constraint = new TopicRoleConstraint(tclass);
constraint.setTypeSpecification(getTypeSpecification(rtype));
constraint.addAssociationType(getTypeSpecification(atype));
players.put(constraint_key, constraint);
// Register playing constraint
tclass.addRoleConstraint(constraint);
}
}
}
}