/* * #! * 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.impl.tmapi2; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import net.ontopia.topicmaps.core.TopicIF; import net.ontopia.topicmaps.core.TopicNameIF; import net.ontopia.topicmaps.core.VariantNameIF; import org.tmapi.core.Locator; import org.tmapi.core.ModelConstraintException; import org.tmapi.core.Name; import org.tmapi.core.Topic; import org.tmapi.core.Variant; /** * INTERNAL: OKS->TMAPI 2 object wrapper. */ public class NameImpl extends ScopedImpl implements Name { private TopicNameIF wrapped; // The scope of variants is handled different in TMAPI2. Therefore // the wrappers of variants have a state, containing explicitly set // themes from the name. These wrappers need to be stored in the // name wrapper. private Set<Variant> wrappedVariants = null; public NameImpl(TopicMapImpl topicMap, TopicNameIF name) { super(topicMap); wrapped = name; } /* * (non-Javadoc) * * @see net.ontopia.topicmaps.impl.tmapi2.Construct#getWrapped() */ public TopicNameIF getWrapped() { return wrapped; } /* * (non-Javadoc) * * @see org.tmapi.core.Name#createVariant(java.lang.String, * org.tmapi.core.Topic[]) */ public Variant createVariant(String value, Topic... scope) { Check.scopeNotNull(this, scope); Check.scopeNotEmpty(this, scope); return createVariant(value, Arrays.asList(scope)); } /* * (non-Javadoc) * * @see org.tmapi.core.Name#createVariant(java.lang.String, * java.util.Collection) */ public Variant createVariant(String value, Collection<Topic> scope) { Check.valueNotNull(this, value); Check.scopeNotNull(this, scope); Check.scopeNotEmpty(this, scope); checkScope(scope); Collection<Topic> explScope = new ArrayList<Topic>(scope); VariantNameIF variant = topicMap.getWrapped().getBuilder().makeVariantName( wrapped, value, unwrapScope(scope)); VariantImpl v = topicMap.wrapVariant(variant); v.setExplicitScope(explScope); return v; } private void checkScope(Collection<org.tmapi.core.Topic> scope) { if (getScope().containsAll(scope)) throw new ModelConstraintException(this, "The variant has the same scope as the name!"); } void addVariant(Variant variant) { if (wrappedVariants == null) { wrappedVariants = new HashSet<Variant>(); } wrappedVariants.add(variant); } void clearVariants() { if (wrappedVariants != null) { wrappedVariants.clear(); } } /* * (non-Javadoc) * * @see org.tmapi.core.Name#createVariant(org.tmapi.core.Locator, * org.tmapi.core.Topic[]) */ public Variant createVariant(Locator value, Topic... scope) { Check.scopeNotNull(this, scope); return createVariant(value, Arrays.asList(scope)); } /* * (non-Javadoc) * * @see org.tmapi.core.Name#createVariant(org.tmapi.core.Locator, * java.util.Collection) */ public Variant createVariant(Locator value, Collection<Topic> scope) { Check.valueNotNull(this, value); Check.scopeNotNull(this, scope); Check.scopeNotEmpty(this, scope); Collection<Topic> explicitScope = new ArrayList<Topic>(scope); VariantNameIF variant = topicMap.getWrapped().getBuilder().makeVariantName( wrapped, topicMap.unwrapLocator(value), unwrapScope(scope)); VariantImpl v = topicMap.wrapVariant(variant); v.setExplicitScope(explicitScope); return v; } /* * (non-Javadoc) * * @see Name#createVariant(java.lang.String, org.tmapi.core.Locator, * org.tmapi.core.Topic[]) */ public Variant createVariant(String value, Locator datatype, Topic... scope) { Check.scopeNotNull(this, scope); Check.scopeNotEmpty(this, scope); return createVariant(value, datatype, Arrays.asList(scope)); } /* * (non-Javadoc) * * @see org.tmapi.core.Name#createVariant(java.lang.String, * org.tmapi.core.Locator, java.util.Collection) */ public Variant createVariant(String value, Locator datatype, Collection<Topic> scope) { Check.valueNotNull(this, value, datatype); Check.scopeNotNull(this, scope); Check.scopeNotEmpty(this, scope); Check.scopeInTopicMap(getTopicMap(), scope.toArray(new Topic[scope.size()])); VariantNameIF variant = topicMap.getWrapped().getBuilder().makeVariantName( wrapped, value, topicMap.unwrapLocator(datatype), unwrapScope(scope)); return topicMap.wrapVariant(variant); } private Collection<TopicIF> unwrapScope(Collection<Topic> scope) { Collection<TopicIF> result = new ArrayList<TopicIF>(scope.size()); for (Topic theme : scope) { result.add(topicMap.unwrapTopic(theme)); } return result; } /* * (non-Javadoc) * * @see org.tmapi.core.Name#getParent() */ public Topic getParent() { return topicMap.wrapTopic(wrapped.getTopic()); } /* * (non-Javadoc) * * @see org.tmapi.core.Name#getValue() */ public String getValue() { return wrapped.getValue(); } /* * (non-Javadoc) * * @see org.tmapi.core.Name#getVariants() */ public Set<Variant> getVariants() { return wrappedVariants != null ? wrappedVariants : Collections.<Variant>emptySet(); } /* * (non-Javadoc) * * @see org.tmapi.core.Name#setValue(java.lang.String) */ public void setValue(String value) { Check.valueNotNull(this, value); wrapped.setValue(value); } /* * (non-Javadoc) * * @see org.tmapi.core.Typed#getType() */ public Topic getType() { return topicMap.wrapTopic(wrapped.getType()); } /* * (non-Javadoc) * * @see org.tmapi.core.Typed#setType(org.tmapi.core.Topic) */ public void setType(Topic type) { Check.typeNotNull(this, type); Check.typeInTopicMap(getTopicMap(), type); wrapped.setType(topicMap.unwrapTopic(type)); } @Override public void removeTheme(Topic theme) { super.removeTheme(theme); // when a theme is removed from a name it also is removed from // all variants. However TMAPI defines, if a scope of a name is explicitly // added to the variant, it may not be removed when the theme is removed // from the name. So the following line will add the theme to // the variant again. for (Variant v : getVariants()) { if (((VariantImpl) v).getExplicitScope().contains(theme)) v.addTheme(theme); } } void removeVariant(VariantImpl variantImpl) { wrappedVariants.remove(variantImpl); } }