/*
* #!
* 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;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;
import net.ontopia.topicmaps.core.TMObjectIF;
import net.ontopia.topicmaps.core.ScopedIF;
import net.ontopia.topicmaps.core.TopicIF;
import net.ontopia.topicmaps.schema.core.TMObjectMatcherIF;
/**
* INTERNAL: Represents a specification of a particular class of scopes.
* Used by many constraint objects to represent their allowed scopes.
*/
public class ScopeSpecification {
/**
* INTERNAL: Means that the scope match must be exact.
*/
public static final int MATCH_EXACT = 0;
/**
* INTERNAL: Means that the allowed scope can be a superset of the
* specified scope.
*/
public static final int MATCH_SUPERSET = 1;
/**
* INTERNAL: Means that the allowed scope can be a subset of the
* specified scope.
*/
public static final int MATCH_SUBSET = 2;
protected Collection topicMatchers;
protected int match;
public ScopeSpecification() {
this.topicMatchers = new ArrayList();
this.match = MATCH_EXACT;
}
/**
* INTERNAL: Returns a value indicating the match policy used.
* The MATCH_* constants contain the allowed values.
*/
public int getMatch() {
return match;
}
/**
* INTERNAL: Sets the match policy used. The MATCH_* constants
* contain the allowed values.
*/
public void setMatch(int match) {
this.match = match;
}
/**
* INTERNAL: Add a new allowed theme.
*/
public void addThemeMatcher(TMObjectMatcherIF matcher) {
topicMatchers.add(matcher);
}
/**
* INTERNAL: Returns the matchers of the allowed themes.
* @return A collection of TMObjectMatcherIF objects.
*/
public Collection getThemeMatchers() {
return topicMatchers;
}
/**
* INTERNAL: Removes a topic matcher from the set of allowed themes.
*/
public void removeThemeMatcher(TMObjectMatcherIF matcher) {
topicMatchers.remove(matcher);
}
/**
* INTERNAL: Matches the specified scope against that of a topic
* map object (which must implement ScopedIF).
*/
public boolean matches(TMObjectIF object) {
if (!(object instanceof ScopedIF))
return false;
int number_found = 0;
ScopedIF scoped = (ScopedIF) object;
Collection themes = scoped.getScope();
Collection matchers = new ArrayList(topicMatchers);
Iterator it = themes.iterator();
while (it.hasNext()) {
TopicIF theme = (TopicIF)it.next();
Iterator it2 = topicMatchers.iterator();
while (it2.hasNext()) {
TMObjectMatcherIF matcher = (TMObjectMatcherIF)it2.next();
if (matcher.matches(theme)) {
matchers.remove(matcher);
number_found++;
}
}
}
boolean result = false;
switch (match) {
case MATCH_EXACT:
// If the number we found equals the number of possible scopes
// given in the schema, and the number of themes is the same,
// then we have found a match
result = (number_found == topicMatchers.size() &&
number_found == scoped.getScope().size());
break;
case MATCH_SUPERSET:
// If the number we found is less or equal to the possible
// scopes given in the schema, and the number of themes is
// equal, then we have found a match.
result = (number_found <= topicMatchers.size() &&
number_found == scoped.getScope().size());
break;
case MATCH_SUBSET:
// If the number we found is equal (minimum) to the possible
// scopes given in the schema, and the number of themes is equal
// or greater, then we have found a match.
result = (number_found == topicMatchers.size() &&
number_found <= scoped.getScope().size());
break;
default:
result = false;
}
return result;
}
}