blob: cfeae7fd2d7aa2012c6f4a6598c9f37b26252ce3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.uima.analysis_engine.impl;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* This object holds the set of RsTypes for a result spec
* There is one instance of this per ResultSpecification_impl
*/
public class RsTypesMap implements Iterable<RsType> {
private final Map<String, RsType> types;
RsTypesMap() {
types = new HashMap<String, RsType>();
}
/**
* cloning constructor - clones its arg
* @param src
*/
RsTypesMap(RsTypesMap src) {
types = new HashMap<String, RsType>(src.types);
for (Map.Entry<String, RsType> e : types.entrySet()) {
e.setValue(new RsType(e.getValue())); // copy
}
}
/**
* add a type (not a type:feat)
* @param typeName
* @param isAllFeat
* @param languages
* @param replace
*/
void add(String typeName, boolean isAllFeat, String[] languages, boolean replace) {
RsType t = types.get(typeName);
if (null == t) {
t = new RsType(typeName);
types.put(typeName, t);
}
if (isAllFeat) {
if (!t.isAllFeatures) {
replace = true; // if setting for the 1st time, replace the x-unspec which is the default
}
t.isAllFeatures = true;
t.languagesAllFeat = addLanguages(t.languagesAllFeat, languages, replace);
} else {
if (!t.isSpecified) {
replace = true;
}
t.isSpecified = true;
t.languagesNotAllFeat = addLanguages(t.languagesNotAllFeat, languages, replace);
}
}
void add(String typeName, boolean isAllFeat, RsLangs rslangs, boolean replace) {
RsType t = types.get(typeName);
if (null == t) {
t = new RsType(typeName);
types.put(typeName, t);
}
if (isAllFeat) {
if (!t.isAllFeatures) {
replace = true;
}
t.isAllFeatures = true;
t.languagesAllFeat = addLanguages(t.languagesAllFeat, rslangs, replace);
} else {
if (!t.isSpecified) {
replace = true;
}
t.isSpecified = true;
t.languagesNotAllFeat = addLanguages(t.languagesNotAllFeat, rslangs, replace);
}
}
/**
* add a feature (not a plain type)
* If feature exists, augments (union) its languages or replaces it
* @param typeName
* @param featName
* @param languages
* @param replace
*/
void add(String typeName, String shortFeatName, Object rslangs, boolean replace) {
RsType t = types.get(typeName);
if (null == t) {
t = new RsType(typeName);
types.put(typeName, t);
}
RsFeats feats = t.features;
RsFeat feat = null;
if (null == feats) {
feats = new RsFeats();
t.features = feats;
} else {
feat = feats.get(shortFeatName);
}
if (null == feat) {
feats.add(shortFeatName, rslangs);
} else {
feat.languages = addLanguages(feat.languages, rslangs, replace);
}
}
RsLangs addLanguages(RsLangs existing, Object langs, boolean replace) {
String[] saLangs = null;
RsLangs rsLangs = null;
if (langs instanceof String[]) {
saLangs = (String[])langs;
} else {
rsLangs = (RsLangs)langs;
}
boolean noLangs = (null == langs) ? true
: (null != saLangs) ? (0 == ((String[])langs).length)
: RsLangs.isEmpty(rsLangs);
if (noLangs) {
if (replace) {
return null;
}
return existing;
}
if (null == existing && !replace) { // existing is x-unspecified
return null; // subsumes everything
}
if (replace) {
if (saLangs != null) {
return RsLangs.createOrNull(saLangs);
} else {
rsLangs.setShared();
return rsLangs;
}
}
// not replace, and existing
existing = (null != saLangs) ? RsLangs.addAll(existing, saLangs)
: RsLangs.addAll(existing, rsLangs);
return existing;
}
RsLangs addLanguages(RsLangs existing, RsLangs rslangs, boolean replace) {
if (RsLangs.isEmpty(rslangs)) {
if (replace) {
return null;
}
return existing;
}
if (null == existing && !replace) { // existing is x-unspecified
return null;
}
if (replace) {
rslangs.setShared();
return rslangs;
}
existing = RsLangs.addAll(existing, rslangs);
return existing;
}
/**
* Remove a type, regardless of languages
* NOTE: doesn't remove type:feature entries associated with that type
* @param type
*/
void remove(String type) {
RsType t = types.get(type);
if (null != t) {
if (null == t.features || t.features.size() == 0) {
types.remove(type);
return;
}
t.isAllFeatures = false;
t.isSpecified = false;
t.languagesAllFeat = null;
t.languagesNotAllFeat = null;
}
}
/**
* remove a feature, regardless of languages
* If all features are removed, null out the rsFeats slot.
* If all features are removed, and no type instance, remove the type also.
* @param typeName
* @param feature Short Name
*/
void remove(String type, String feature) {
RsType t = types.get(type);
if (null != t) {
if (null != t.features) {
t.features.remove(type, feature);
if (0 == t.features.size()) {
t.features = null;
if (!t.isAllFeatures && !t.isSpecified) {
types.remove(type);
}
}
}
}
}
RsType getRsType(String typeName) {
return types.get(typeName);
}
RsFeat get(String typeName, String shortFeatName) {
RsType t = types.get(typeName);
if (t == null || t.features == null) {
return null;
}
return t.features.get(shortFeatName);
}
int nbrOfTypes() {
return types.size();
}
public Iterator<RsType> iterator() {
return types.values().iterator();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((types == null) ? 0 : types.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
RsTypesMap other = (RsTypesMap) obj;
if (types == null) {
if (other.types != null) {
return false;
}
} else if (!types.equals(other.types)) {
return false;
}
return true;
}
}