package mtas.analysis.parser; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import mtas.analysis.token.MtasToken; import mtas.analysis.token.MtasTokenIdFactory; import mtas.analysis.token.MtasTokenString; import mtas.analysis.util.MtasConfigException; import mtas.analysis.util.MtasConfiguration; import mtas.analysis.util.MtasParserException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter; import org.apache.lucene.analysis.payloads.PayloadHelper; import org.apache.lucene.util.BytesRef; /** * The Class MtasBasicParser. */ public abstract class MtasBasicParser extends MtasParser { /** The Constant log. */ private static final Log log = LogFactory.getLog(MtasBasicParser.class); /** The Constant MAPPING_TYPE_REF. */ protected static final String MAPPING_TYPE_REF = "ref"; /** The Constant MAPPING_TYPE_RELATION. */ protected static final String MAPPING_TYPE_RELATION = "relation"; /** The Constant MAPPING_TYPE_RELATION_ANNOTATION. */ protected static final String MAPPING_TYPE_RELATION_ANNOTATION = "relationAnnotation"; /** The Constant MAPPING_TYPE_GROUP. */ protected static final String MAPPING_TYPE_GROUP = "group"; /** The Constant MAPPING_TYPE_GROUP_ANNOTATION. */ protected static final String MAPPING_TYPE_GROUP_ANNOTATION = "groupAnnotation"; /** The Constant MAPPING_TYPE_WORD. */ protected static final String MAPPING_TYPE_WORD = "word"; /** The Constant MAPPING_TYPE_WORD_ANNOTATION. */ protected static final String MAPPING_TYPE_WORD_ANNOTATION = "wordAnnotation"; /** The Constant ITEM_TYPE_STRING. */ protected static final String ITEM_TYPE_STRING = "string"; /** The Constant ITEM_TYPE_NAME. */ protected static final String ITEM_TYPE_NAME = "name"; /** The Constant ITEM_TYPE_NAME_ANCESTOR. */ protected static final String ITEM_TYPE_NAME_ANCESTOR = "ancestorName"; /** The Constant ITEM_TYPE_NAME_ANCESTOR_GROUP. */ protected static final String ITEM_TYPE_NAME_ANCESTOR_GROUP = "ancestorGroupName"; /** The Constant ITEM_TYPE_NAME_ANCESTOR_GROUP_ANNOTATION. */ protected static final String ITEM_TYPE_NAME_ANCESTOR_GROUP_ANNOTATION = "ancestorGroupAnnotationName"; /** The Constant ITEM_TYPE_NAME_ANCESTOR_WORD. */ protected static final String ITEM_TYPE_NAME_ANCESTOR_WORD = "ancestorWordName"; /** The Constant ITEM_TYPE_NAME_ANCESTOR_WORD_ANNOTATION. */ protected static final String ITEM_TYPE_NAME_ANCESTOR_WORD_ANNOTATION = "ancestorWordAnnotationName"; /** The Constant ITEM_TYPE_NAME_ANCESTOR_RELATION. */ protected static final String ITEM_TYPE_NAME_ANCESTOR_RELATION = "ancestorRelationName"; /** The Constant ITEM_TYPE_NAME_ANCESTOR_RELATION_ANNOTATION. */ protected static final String ITEM_TYPE_NAME_ANCESTOR_RELATION_ANNOTATION = "ancestorRelationAnnotationName"; /** The Constant ITEM_TYPE_ATTRIBUTE. */ protected static final String ITEM_TYPE_ATTRIBUTE = "attribute"; /** The Constant ITEM_TYPE_ATTRIBUTE_ANCESTOR. */ protected static final String ITEM_TYPE_ATTRIBUTE_ANCESTOR = "ancestorAttribute"; /** The Constant ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP. */ protected static final String ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP = "ancestorGroupAttribute"; /** The Constant ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP_ANNOTATION. */ protected static final String ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP_ANNOTATION = "ancestorGroupAnnotationAttribute"; /** The Constant ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD. */ protected static final String ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD = "ancestorWordAttribute"; /** The Constant ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD_ANNOTATION. */ protected static final String ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD_ANNOTATION = "ancestorWordAnnotationAttribute"; /** The Constant ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION. */ protected static final String ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION = "ancestorRelationAttribute"; /** The Constant ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION_ANNOTATION. */ protected static final String ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION_ANNOTATION = "ancestorRelationAnnotationAttribute"; /** The Constant ITEM_TYPE_TEXT. */ protected static final String ITEM_TYPE_TEXT = "text"; /** The Constant ITEM_TYPE_TEXT_SPLIT. */ protected static final String ITEM_TYPE_TEXT_SPLIT = "textSplit"; /** The Constant ITEM_TYPE_UNKNOWN_ANCESTOR. */ protected static final String ITEM_TYPE_UNKNOWN_ANCESTOR = "unknownAncestor"; /** The Constant ITEM_TYPE_ANCESTOR. */ protected static final String ITEM_TYPE_ANCESTOR = "ancestor"; /** The Constant ITEM_TYPE_ANCESTOR_GROUP. */ protected static final String ITEM_TYPE_ANCESTOR_GROUP = "ancestorGroup"; /** The Constant ITEM_TYPE_ANCESTOR_GROUP_ANNOTATION. */ protected static final String ITEM_TYPE_ANCESTOR_GROUP_ANNOTATION = "ancestorGroupAnnotation"; /** The Constant ITEM_TYPE_ANCESTOR_WORD. */ protected static final String ITEM_TYPE_ANCESTOR_WORD = "ancestorWord"; /** The Constant ITEM_TYPE_ANCESTOR_WORD_ANNOTATION. */ protected static final String ITEM_TYPE_ANCESTOR_WORD_ANNOTATION = "ancestorWordAnnotation"; /** The Constant ITEM_TYPE_ANCESTOR_RELATION. */ protected static final String ITEM_TYPE_ANCESTOR_RELATION = "ancestorRelation"; /** The Constant ITEM_TYPE_ANCESTOR_RELATION_ANNOTATION. */ protected static final String ITEM_TYPE_ANCESTOR_RELATION_ANNOTATION = "ancestorRelationAnnotation"; /** The Constant ITEM_TYPE_VARIABLE_FROM_ATTRIBUTE. */ protected static final String ITEM_TYPE_VARIABLE_FROM_ATTRIBUTE = "variableFromAttribute"; /** The Constant VARIABLE_SUBTYPE_VALUE. */ protected static final String VARIABLE_SUBTYPE_VALUE = "value"; /** The Constant VARIABLE_SUBTYPE_VALUE_ITEM. */ protected static final String VARIABLE_SUBTYPE_VALUE_ITEM = "item"; /** The Constant MAPPING_SUBTYPE_TOKEN. */ protected static final String MAPPING_SUBTYPE_TOKEN = "token"; /** The Constant MAPPING_SUBTYPE_TOKEN_PRE. */ protected static final String MAPPING_SUBTYPE_TOKEN_PRE = "pre"; /** The Constant MAPPING_SUBTYPE_TOKEN_POST. */ protected static final String MAPPING_SUBTYPE_TOKEN_POST = "post"; /** The Constant MAPPING_SUBTYPE_PAYLOAD. */ protected static final String MAPPING_SUBTYPE_PAYLOAD = "payload"; /** The Constant MAPPING_SUBTYPE_CONDITION. */ protected static final String MAPPING_SUBTYPE_CONDITION = "condition"; /** The Constant MAPPING_FILTER_UPPERCASE. */ protected static final String MAPPING_FILTER_UPPERCASE = "uppercase"; /** The Constant MAPPING_FILTER_LOWERCASE. */ protected static final String MAPPING_FILTER_LOWERCASE = "lowercase"; /** The Constant MAPPING_FILTER_ASCII. */ protected static final String MAPPING_FILTER_ASCII = "ascii"; /** The Constant MAPPING_FILTER_SPLIT. */ protected static final String MAPPING_FILTER_SPLIT = "split"; /** The Constant UPDATE_TYPE_OFFSET. */ protected static final String UPDATE_TYPE_OFFSET = "offsetUpdate"; /** The Constant UPDATE_TYPE_POSITION. */ protected static final String UPDATE_TYPE_POSITION = "positionUpdate"; /** The Constant UPDATE_TYPE_VARIABLE. */ protected static final String UPDATE_TYPE_VARIABLE = "variableUpdate"; /** The Constant UPDATE_TYPE_LOCAL_REF_OFFSET_START. */ protected static final String UPDATE_TYPE_LOCAL_REF_OFFSET_START = "localRefOffsetStartUpdate"; /** The Constant UPDATE_TYPE_LOCAL_REF_OFFSET_END. */ protected static final String UPDATE_TYPE_LOCAL_REF_OFFSET_END = "localRefOffsetEndUpdate"; /** The Constant UPDATE_TYPE_LOCAL_REF_POSITION_START. */ protected static final String UPDATE_TYPE_LOCAL_REF_POSITION_START = "localRefPositionStartUpdate"; /** The Constant UPDATE_TYPE_LOCAL_REF_POSITION_END. */ protected static final String UPDATE_TYPE_LOCAL_REF_POSITION_END = "localRefPositionEndUpdate"; /** The Constant MAPPING_VALUE_VALUE. */ protected static final String MAPPING_VALUE_VALUE = "value"; /** The Constant MAPPING_VALUE_TYPE. */ protected static final String MAPPING_VALUE_TYPE = "type"; /** The Constant MAPPING_VALUE_NAME. */ protected static final String MAPPING_VALUE_NAME = "name"; /** The Constant MAPPING_VALUE_NAME. */ protected static final String MAPPING_VALUE_NAMESPACE = "namespace"; /** The Constant MAPPING_VALUE_PREFIX. */ protected static final String MAPPING_VALUE_PREFIX = "prefix"; /** The Constant MAPPING_VALUE_FILTER. */ protected static final String MAPPING_VALUE_FILTER = "filter"; /** The Constant MAPPING_VALUE_DISTANCE. */ protected static final String MAPPING_VALUE_DISTANCE = "distance"; /** The Constant MAPPING_VALUE_SOURCE. */ protected static final String MAPPING_VALUE_SOURCE = "source"; /** The Constant MAPPING_VALUE_ANCESTOR. */ protected static final String MAPPING_VALUE_ANCESTOR = "ancestor"; /** The Constant MAPPING_VALUE_SPLIT. */ protected static final String MAPPING_VALUE_SPLIT = "split"; /** The Constant MAPPING_VALUE_NUMBER. */ protected static final String MAPPING_VALUE_NUMBER = "number"; /** The Constant MAPPING_VALUE_CONDITION. */ protected static final String MAPPING_VALUE_CONDITION = "condition"; /** The Constant MAPPING_VALUE_TEXT. */ protected static final String MAPPING_VALUE_TEXT = "text"; /** The Constant MAPPING_VALUE_NOT. */ protected static final String MAPPING_VALUE_NOT = "not"; /** The enc. */ private Base64.Encoder enc = Base64.getEncoder(); /** The dec. */ private Base64.Decoder dec = Base64.getDecoder(); /** * Instantiates a new mtas basic parser. */ public MtasBasicParser() { super(); } /** * Instantiates a new mtas basic parser. * * @param config the config */ public MtasBasicParser(MtasConfiguration config) { super(config); } /** * Creates the current list. * * @return the map */ protected Map<String, List<MtasParserObject>> createCurrentList() { Map<String, List<MtasParserObject>> currentList = new HashMap<>(); currentList.put(MAPPING_TYPE_RELATION, new ArrayList<MtasParserObject>()); currentList.put(MAPPING_TYPE_RELATION_ANNOTATION, new ArrayList<MtasParserObject>()); currentList.put(MAPPING_TYPE_REF, new ArrayList<MtasParserObject>()); currentList.put(MAPPING_TYPE_GROUP, new ArrayList<MtasParserObject>()); currentList.put(MAPPING_TYPE_GROUP_ANNOTATION, new ArrayList<MtasParserObject>()); currentList.put(MAPPING_TYPE_WORD, new ArrayList<MtasParserObject>()); currentList.put(MAPPING_TYPE_WORD_ANNOTATION, new ArrayList<MtasParserObject>()); return currentList; } /** * Creates the update list. * * @return the map */ protected Map<String, Map<Integer, Set<String>>> createUpdateList() { Map<String, Map<Integer, Set<String>>> updateList = new HashMap<>(); updateList.put(UPDATE_TYPE_OFFSET, new HashMap<>()); updateList.put(UPDATE_TYPE_POSITION, new HashMap<>()); updateList.put(UPDATE_TYPE_LOCAL_REF_POSITION_START, new HashMap<>()); updateList.put(UPDATE_TYPE_LOCAL_REF_POSITION_END, new HashMap<>()); updateList.put(UPDATE_TYPE_LOCAL_REF_OFFSET_START, new HashMap<>()); updateList.put(UPDATE_TYPE_LOCAL_REF_OFFSET_END, new HashMap<>()); updateList.put(UPDATE_TYPE_VARIABLE, new HashMap<>()); return updateList; } /** * Creates the variables. * * @return the map */ protected Map<String, Map<String, String>> createVariables() { return new HashMap<>(); } /** * Compute mappings from object. * * @param mtasTokenIdFactory the mtas token id factory * @param object the object * @param currentList the current list * @param updateList the update list * @throws MtasParserException the mtas parser exception * @throws MtasConfigException the mtas config exception */ protected void computeMappingsFromObject( MtasTokenIdFactory mtasTokenIdFactory, MtasParserObject object, Map<String, List<MtasParserObject>> currentList, Map<String, Map<Integer, Set<String>>> updateList) throws MtasParserException, MtasConfigException { MtasParserType<MtasParserMapping<?>> objectType = object.getType(); List<MtasParserMapping<?>> mappings = objectType.getItems(); if (!object.updateableMappingsWithPosition.isEmpty()) { for (int tokenId : object.updateableMappingsWithPosition) { updateList.get(UPDATE_TYPE_POSITION).put(tokenId, object.getRefIds()); } } if (!object.updateableMappingsWithOffset.isEmpty()) { for (int tokenId : object.updateableMappingsWithOffset) { updateList.get(UPDATE_TYPE_OFFSET).put(tokenId, object.getRefIds()); } } for (MtasParserMapping<?> mapping : mappings) { try { if (mapping.getTokens().isEmpty()) { // empty exception } else { for (int i = 0; i < mapping.getTokens().size(); i++) { MtasParserMappingToken mappingToken = mapping.getTokens().get(i); // empty exception if (mappingToken.preValues.isEmpty()) { // continue, but no token } else { // check conditions postcheckMappingConditions(object, mapping.getConditions(), currentList); boolean containsVariables = checkForVariables( mappingToken.preValues); containsVariables = !containsVariables ? checkForVariables(mappingToken.postValues) : containsVariables; // construct preValue String[] preValue = computeValueFromMappingValues(object, mappingToken.preValues, currentList, containsVariables); // at least preValue if (preValue == null || preValue.length == 0) { throw new MtasParserException("no preValues"); } else { // no delimiter in preValue for (int k = 0; k < preValue.length; k++) { if ((preValue[k] = preValue[k].replace(MtasToken.DELIMITER, "")).isEmpty()) { throw new MtasParserException("empty preValue"); } } } // construct postValue String[] postValue = computeValueFromMappingValues(object, mappingToken.postValues, currentList, containsVariables); // construct value String[] value; if (postValue == null || postValue.length == 0) { value = preValue.clone(); for (int k = 0; k < value.length; k++) { value[k] = value[k] + MtasToken.DELIMITER; } } else if (postValue.length == 1) { value = preValue.clone(); for (int k = 0; k < value.length; k++) { value[k] = value[k] + MtasToken.DELIMITER + postValue[0]; } } else if (preValue.length == 1) { value = postValue.clone(); for (int k = 0; k < value.length; k++) { value[k] = preValue[0] + MtasToken.DELIMITER + value[k]; } } else { value = new String[preValue.length * postValue.length]; int number = 0; for (int k1 = 0; k1 < preValue.length; k1++) { for (int k2 = 0; k2 < postValue.length; k2++) { value[number] = preValue[k1] + MtasToken.DELIMITER + postValue[k2]; number++; } } } // construct payload BytesRef payload = computePayloadFromMappingPayload(object, mappingToken.payload, currentList); // create token and get id: from now on, we must continue, no // exceptions allowed... for (int k = 0; k < value.length; k++) { MtasTokenString token = new MtasTokenString( mtasTokenIdFactory.createTokenId(), value[k]); // store settings offset, realoffset and parent token.setProvideOffset(mappingToken.offset); token.setProvideRealOffset(mappingToken.realoffset); token.setProvideParentId(mappingToken.parent); String checkType = object.objectType.getType(); // register token if it contains variables if (containsVariables) { updateList.get(UPDATE_TYPE_VARIABLE).put(token.getId(), null); } // register id for update when parent is created if (!currentList.get(checkType).isEmpty()) { if (currentList.get(checkType).contains(object)) { int listPosition = currentList.get(checkType) .indexOf(object); if (listPosition > 0) { currentList.get(checkType).get(listPosition - 1) .registerUpdateableMappingAtParent(token.getId()); } } else { currentList.get(checkType) .get(currentList.get(checkType).size() - 1) .registerUpdateableMappingAtParent(token.getId()); } // if no real ancestor, register id update when group // ancestor is created } else if (!currentList.get(MAPPING_TYPE_GROUP).isEmpty()) { currentList.get(MAPPING_TYPE_GROUP) .get(currentList.get(MAPPING_TYPE_GROUP).size() - 1) .registerUpdateableMappingAtParent(token.getId()); } else if (!currentList.get(MAPPING_TYPE_RELATION).isEmpty()) { currentList.get(MAPPING_TYPE_RELATION) .get(currentList.get(MAPPING_TYPE_RELATION).size() - 1) .registerUpdateableMappingAtParent(token.getId()); } // update children for (Integer tmpId : object.getUpdateableMappingsAsParent()) { if (tokenCollection.get(tmpId) != null) { tokenCollection.get(tmpId).setParentId(token.getId()); } } object.resetUpdateableMappingsAsParent(); // use own position if (mapping.position.equals(MtasParserMapping.SOURCE_OWN)) { token.addPositions(object.getPositions()); // use position from ancestorGroup } else if (mapping.position .equals(MtasParserMapping.SOURCE_ANCESTOR_GROUP) && (!currentList.get(MAPPING_TYPE_GROUP).isEmpty())) { currentList.get(MAPPING_TYPE_GROUP) .get(currentList.get(MAPPING_TYPE_GROUP).size() - 1) .addUpdateableMappingWithPosition(token.getId()); // use position from ancestorWord } else if (mapping.position .equals(MtasParserMapping.SOURCE_ANCESTOR_WORD) && (!currentList.get(MAPPING_TYPE_WORD).isEmpty())) { currentList.get(MAPPING_TYPE_WORD) .get(currentList.get(MAPPING_TYPE_WORD).size() - 1) .addUpdateableMappingWithPosition(token.getId()); // use position from ancestorRelation } else if (mapping.position .equals(MtasParserMapping.SOURCE_ANCESTOR_RELATION) && (!currentList.get(MAPPING_TYPE_RELATION).isEmpty())) { currentList.get(MAPPING_TYPE_RELATION) .get(currentList.get(MAPPING_TYPE_RELATION).size() - 1) .addUpdateableMappingWithPosition(token.getId()); // register id to get positions later from references } else if (mapping.position .equals(MtasParserMapping.SOURCE_REFS)) { if (mapping.type.equals(MAPPING_TYPE_GROUP_ANNOTATION)) { if (mapping.start != null && mapping.end != null) { String start = object.getAttribute(mapping.start); String end = object.getAttribute(mapping.end); if (start != null && !start.isEmpty() && end != null && !end.isEmpty()) { if (start.startsWith("#")) { start = start.substring(1); } if (end.startsWith("#")) { end = end.substring(1); } updateList.get(UPDATE_TYPE_LOCAL_REF_POSITION_START) .put(token.getId(), new HashSet<String>(Arrays.asList(start))); updateList.get(UPDATE_TYPE_LOCAL_REF_POSITION_END).put( token.getId(), new HashSet<String>(Arrays.asList(end))); updateList.get(UPDATE_TYPE_LOCAL_REF_OFFSET_START).put( token.getId(), new HashSet<String>(Arrays.asList(start))); updateList.get(UPDATE_TYPE_LOCAL_REF_OFFSET_END).put( token.getId(), new HashSet<String>(Arrays.asList(end))); } } } else { updateList.get(UPDATE_TYPE_POSITION).put(token.getId(), object.getRefIds()); } } else { // should not happen } // use own offset if (mapping.offset.equals(MtasParserMapping.SOURCE_OWN)) { token.setOffset(object.getOffsetStart(), object.getOffsetEnd()); // use offset from ancestorGroup } else if (mapping.offset .equals(MtasParserMapping.SOURCE_ANCESTOR_GROUP) && (!currentList.get(MAPPING_TYPE_GROUP).isEmpty())) { currentList.get(MAPPING_TYPE_GROUP) .get(currentList.get(MAPPING_TYPE_GROUP).size() - 1) .addUpdateableMappingWithOffset(token.getId()); // use offset from ancestorWord } else if (mapping.offset .equals(MtasParserMapping.SOURCE_ANCESTOR_WORD) && !currentList.get(MAPPING_TYPE_WORD).isEmpty()) { currentList.get(MAPPING_TYPE_WORD) .get(currentList.get(MAPPING_TYPE_WORD).size() - 1) .addUpdateableMappingWithOffset(token.getId()); // use offset from ancestorRelation } else if (mapping.offset .equals(MtasParserMapping.SOURCE_ANCESTOR_RELATION) && !currentList.get(MAPPING_TYPE_RELATION).isEmpty()) { currentList.get(MAPPING_TYPE_RELATION) .get(currentList.get(MAPPING_TYPE_RELATION).size() - 1) .addUpdateableMappingWithOffset(token.getId()); // register id to get offset later from refs } else if (mapping.offset .equals(MtasParserMapping.SOURCE_REFS)) { updateList.get(UPDATE_TYPE_OFFSET).put(token.getId(), object.getRefIds()); } // always use own realOffset token.setRealOffset(object.getRealOffsetStart(), object.getRealOffsetEnd()); // set payload token.setPayload(payload); // add token to collection tokenCollection.add(token); } } } } // register start and end if (mapping.start != null && mapping.end != null) { String startAttribute = null; String endAttribute = null; if (mapping.start.equals("#")) { startAttribute = object.getId(); } else { startAttribute = object.getAttribute(mapping.start); if (startAttribute != null && startAttribute.startsWith("#")) { startAttribute = startAttribute.substring(1); } } if (mapping.end.equals("#")) { endAttribute = object.getId(); } else { endAttribute = object.getAttribute(mapping.end); if (endAttribute != null && endAttribute.startsWith("#")) { endAttribute = endAttribute.substring(1); } } if (startAttribute != null && endAttribute != null && !object.getPositions().isEmpty()) { object.setReferredStartPosition(startAttribute, object.getPositions().first()); object.setReferredEndPosition(endAttribute, object.getPositions().last()); object.setReferredStartOffset(startAttribute, object.getOffsetStart()); object.setReferredEndOffset(endAttribute, object.getOffsetEnd()); } } } catch (MtasParserException e) { log.debug("Rejected mapping " + object.getType().getName(), e); // ignore, no new token is created } } // copy remaining updateableMappings to new parent if (!currentList.get(objectType.getType()).isEmpty()) { if (currentList.get(objectType.getType()).contains(object)) { int listPosition = currentList.get(objectType.getType()) .indexOf(object); if (listPosition > 0) { currentList.get(objectType.getType()).get(listPosition - 1) .registerUpdateableMappingsAtParent( object.getUpdateableMappingsAsParent()); } } else { currentList.get(objectType.getType()) .get(currentList.get(objectType.getType()).size() - 1) .registerUpdateableMappingsAtParent( object.getUpdateableMappingsAsParent()); } } else if (!currentList.get(MAPPING_TYPE_GROUP).isEmpty()) { currentList.get(MAPPING_TYPE_GROUP) .get(currentList.get(MAPPING_TYPE_GROUP).size() - 1) .registerUpdateableMappingsAtParent( object.getUpdateableMappingsAsParent()); } else if (!currentList.get(MAPPING_TYPE_RELATION).isEmpty()) { currentList.get(MAPPING_TYPE_RELATION) .get(currentList.get(MAPPING_TYPE_RELATION).size() - 1) .registerUpdateableMappingsAtParent( object.getUpdateableMappingsAsParent()); } updateMappingsWithLocalReferences(object, currentList, updateList); } /** * Compute variables from object. * * @param object the object * @param currentList the current list * @param variables the variables */ protected void computeVariablesFromObject(MtasParserObject object, Map<String, List<MtasParserObject>> currentList, Map<String, Map<String, String>> variables) { MtasParserType<MtasParserVariable> parserType = object.getType(); String id = object.getId(); if (id != null) { for (MtasParserVariable variable : parserType.getItems()) { if (!variables.containsKey(variable.variable)) { variables.put(variable.variable, new HashMap<String, String>()); } StringBuilder builder = new StringBuilder(); for (MtasParserVariableValue variableValue : variable.values) { if (variableValue.type.equals("attribute")) { String subValue = object.getAttribute(variableValue.name); if (subValue != null) { builder.append(subValue); } } } variables.get(variable.variable).put(id, builder.toString()); } } } /** * Check for variables. * * @param values the values * @return true, if successful */ private boolean checkForVariables(List<Map<String, String>> values) { if (values == null || values.isEmpty()) { return false; } else { for (Map<String, String> list : values) { if (list.containsKey("type") && list.get("type") .equals(MtasParserMapping.PARSER_TYPE_VARIABLE)) { return true; } } } return false; } /** * Update mappings with local references. * * @param currentObject the current object * @param currentList the current list * @param updateList the update list */ private void updateMappingsWithLocalReferences(MtasParserObject currentObject, Map<String, List<MtasParserObject>> currentList, Map<String, Map<Integer, Set<String>>> updateList) { if (currentObject.getType().type.equals(MAPPING_TYPE_GROUP)) { for (Integer tokenId : updateList .get(UPDATE_TYPE_LOCAL_REF_POSITION_START).keySet()) { if (updateList.get(UPDATE_TYPE_LOCAL_REF_POSITION_END) .containsKey(tokenId) && updateList.get(UPDATE_TYPE_LOCAL_REF_OFFSET_START) .containsKey(tokenId) && updateList.get(UPDATE_TYPE_LOCAL_REF_OFFSET_END) .containsKey(tokenId)) { Iterator<String> startPositionIt = updateList .get(UPDATE_TYPE_LOCAL_REF_POSITION_START).get(tokenId) .iterator(); Iterator<String> endPositionIt = updateList .get(UPDATE_TYPE_LOCAL_REF_POSITION_END).get(tokenId).iterator(); Iterator<String> startOffsetIt = updateList .get(UPDATE_TYPE_LOCAL_REF_OFFSET_START).get(tokenId).iterator(); Iterator<String> endOffsetIt = updateList .get(UPDATE_TYPE_LOCAL_REF_OFFSET_END).get(tokenId).iterator(); Integer startPosition = null; Integer endPosition = null; Integer startOffset = null; Integer endOffset = null; Integer newValue = null; while (startPositionIt.hasNext()) { String localKey = startPositionIt.next(); if (currentObject.referredStartPosition.containsKey(localKey)) { newValue = currentObject.referredStartPosition.get(localKey); startPosition = (startPosition == null) ? newValue : Math.min(startPosition, newValue); } } while (endPositionIt.hasNext()) { String localKey = endPositionIt.next(); if (currentObject.referredEndPosition.containsKey(localKey)) { newValue = currentObject.referredEndPosition.get(localKey); endPosition = (endPosition == null) ? newValue : Math.max(endPosition, newValue); } } while (startOffsetIt.hasNext()) { String localKey = startOffsetIt.next(); if (currentObject.referredStartOffset.containsKey(localKey)) { newValue = currentObject.referredStartOffset.get(localKey); startOffset = (startOffset == null) ? newValue : Math.min(startOffset, newValue); } } while (endOffsetIt.hasNext()) { String localKey = endOffsetIt.next(); if (currentObject.referredEndOffset.containsKey(localKey)) { newValue = currentObject.referredEndOffset.get(localKey); endOffset = (endOffset == null) ? newValue : Math.max(endOffset, newValue); } } if (startPosition != null && endPosition != null && startOffset != null && endOffset != null) { MtasToken token = tokenCollection.get(tokenId); token.addPositionRange(startPosition, endPosition); token.setOffset(startOffset, endOffset); } } } } if (!currentList.get(MAPPING_TYPE_GROUP).isEmpty()) { MtasParserObject parentGroup = currentList.get(MAPPING_TYPE_GROUP) .get(currentList.get(MAPPING_TYPE_GROUP).size() - 1); parentGroup.referredStartPosition .putAll(currentObject.referredStartPosition); parentGroup.referredEndPosition.putAll(currentObject.referredEndPosition); parentGroup.referredStartOffset.putAll(currentObject.referredStartOffset); parentGroup.referredEndOffset.putAll(currentObject.referredEndOffset); } currentObject.referredStartPosition.clear(); currentObject.referredEndPosition.clear(); currentObject.referredStartOffset.clear(); currentObject.referredEndOffset.clear(); } /** * Compute type from mapping source. * * @param source the source * @return the string * @throws MtasParserException the mtas parser exception */ private String computeTypeFromMappingSource(String source) throws MtasParserException { if (source.equals(MtasParserMapping.SOURCE_OWN)) { return null; } else if (source.equals(MtasParserMapping.SOURCE_ANCESTOR_GROUP)) { return MAPPING_TYPE_GROUP; } else if (source .equals(MtasParserMapping.SOURCE_ANCESTOR_GROUP_ANNOTATION)) { return MAPPING_TYPE_GROUP_ANNOTATION; } else if (source.equals(MtasParserMapping.SOURCE_ANCESTOR_WORD)) { return MAPPING_TYPE_WORD; } else if (source .equals(MtasParserMapping.SOURCE_ANCESTOR_WORD_ANNOTATION)) { return MAPPING_TYPE_WORD_ANNOTATION; } else if (source.equals(MtasParserMapping.SOURCE_ANCESTOR_RELATION)) { return MAPPING_TYPE_RELATION; } else if (source .equals(MtasParserMapping.SOURCE_ANCESTOR_RELATION_ANNOTATION)) { return MAPPING_TYPE_RELATION_ANNOTATION; } else { throw new MtasParserException("unknown source " + source); } } /** * Compute object from mapping value. * * @param object the object * @param mappingValue the mapping value * @param currentList the current list * @return the mtas parser object[] * @throws MtasParserException the mtas parser exception */ private MtasParserObject[] computeObjectFromMappingValue( MtasParserObject object, Map<String, String> mappingValue, Map<String, List<MtasParserObject>> currentList) throws MtasParserException { MtasParserObject[] checkObjects = null; MtasParserObject checkObject; Integer ancestorNumber = null; String ancestorType = null; // try to get relevant object if (mappingValue.get(MAPPING_VALUE_SOURCE) .equals(MtasParserMapping.SOURCE_OWN)) { checkObjects = new MtasParserObject[] { object }; } else { ancestorNumber = mappingValue.get(MAPPING_VALUE_ANCESTOR) != null ? Integer.parseInt(mappingValue.get(MAPPING_VALUE_ANCESTOR)) : null; ancestorType = computeTypeFromMappingSource( mappingValue.get(MAPPING_VALUE_SOURCE)); // get ancestor object if (ancestorType != null) { int s = currentList.get(ancestorType).size(); // check existence ancestor for conditions if (ancestorNumber != null) { if ((s > 0) && (ancestorNumber < s) && (checkObject = currentList .get(ancestorType).get((s - ancestorNumber - 1))) != null) { checkObjects = new MtasParserObject[] { checkObject }; } } else { checkObjects = new MtasParserObject[s]; for (int i = s - 1; i >= 0; i--) { checkObjects[s - i - 1] = currentList.get(ancestorType).get(i); } } } } return checkObjects; } /** * Compute value from mapping values. * * @param object the object * @param mappingValues the mapping values * @param currentList the current list * @param containsVariables the contains variables * @return the string[] * @throws MtasParserException the mtas parser exception * @throws MtasConfigException the mtas config exception */ private String[] computeValueFromMappingValues(MtasParserObject object, List<Map<String, String>> mappingValues, Map<String, List<MtasParserObject>> currentList, boolean containsVariables) throws MtasParserException, MtasConfigException { String[] value = { "" }; for (Map<String, String> mappingValue : mappingValues) { // directly if (mappingValue.get(MAPPING_VALUE_SOURCE) .equals(MtasParserMapping.SOURCE_STRING)) { if (mappingValue.get("type") .equals(MtasParserMapping.PARSER_TYPE_STRING)) { String subvalue = computeFilteredPrefixedValue( mappingValue.get(MAPPING_VALUE_TYPE), mappingValue.get(MAPPING_VALUE_TEXT), null, null); if (subvalue != null) { for (int i = 0; i < value.length; i++) { value[i] = addAndEncodeValue(value[i], subvalue, containsVariables); } } } // from objects } else { MtasParserObject[] checkObjects = computeObjectFromMappingValue(object, mappingValue, currentList); // create value if (checkObjects != null && checkObjects.length > 0) { MtasParserType checkType = checkObjects[0].getType(); // add name to value if (mappingValue.get(MAPPING_VALUE_TYPE) .equals(MtasParserMapping.PARSER_TYPE_NAME)) { String subvalue = computeFilteredPrefixedValue( mappingValue.get(MAPPING_VALUE_TYPE), checkType.getName(), mappingValue.get(MAPPING_VALUE_FILTER), mappingValue.get(MAPPING_VALUE_PREFIX) == null || mappingValue.get(MAPPING_VALUE_PREFIX).isEmpty() ? null : mappingValue.get(MAPPING_VALUE_PREFIX)); if (subvalue != null) { for (int i = 0; i < value.length; i++) { value[i] = addAndEncodeValue(value[i], subvalue, containsVariables); } } // add attribute to value } else if (mappingValue.get(MAPPING_VALUE_TYPE) .equals(MtasParserMapping.PARSER_TYPE_ATTRIBUTE)) { String tmpValue = null; if (mappingValue.get(MAPPING_VALUE_NAME).equals("#")) { tmpValue = checkObjects[0].getId(); } else { String namespace = mappingValue.get(MAPPING_VALUE_NAMESPACE); if(namespace==null) { tmpValue = checkObjects[0] .getAttribute(mappingValue.get(MAPPING_VALUE_NAME)); } else { tmpValue = checkObjects[0] .getOtherAttribute(namespace, mappingValue.get(MAPPING_VALUE_NAME)); } } String subvalue = computeFilteredPrefixedValue( mappingValue.get(MAPPING_VALUE_TYPE), tmpValue, mappingValue.get(MAPPING_VALUE_FILTER), mappingValue.get(MAPPING_VALUE_PREFIX) == null || mappingValue.get(MAPPING_VALUE_PREFIX).isEmpty() ? null : mappingValue.get(MAPPING_VALUE_PREFIX)); if (subvalue != null) { for (int i = 0; i < value.length; i++) { value[i] = addAndEncodeValue(value[i], subvalue, containsVariables); } } // value from text } else if (mappingValue.get("type") .equals(MtasParserMapping.PARSER_TYPE_TEXT)) { String subvalue = computeFilteredPrefixedValue( mappingValue.get(MAPPING_VALUE_TYPE), checkObjects[0].getText(), mappingValue.get(MAPPING_VALUE_FILTER), mappingValue.get(MAPPING_VALUE_PREFIX) == null || mappingValue.get(MAPPING_VALUE_PREFIX).isEmpty() ? null : mappingValue.get(MAPPING_VALUE_PREFIX)); if (subvalue != null) { for (int i = 0; i < value.length; i++) { value[i] = addAndEncodeValue(value[i], subvalue, containsVariables); } } } else if (mappingValue.get("type") .equals(MtasParserMapping.PARSER_TYPE_TEXT_SPLIT)) { String[] textValues = checkObjects[0].getText() .split(Pattern.quote(mappingValue.get(MAPPING_VALUE_SPLIT))); textValues = computeFilteredSplitValues(textValues, mappingValue.get(MAPPING_VALUE_FILTER)); if (textValues != null && textValues.length > 0) { String[] nextValue = new String[value.length * textValues.length]; boolean nullValue = false; int number = 0; for (int k = 0; k < textValues.length; k++) { String subvalue = computeFilteredPrefixedValue( mappingValue.get(MAPPING_VALUE_TYPE), textValues[k], mappingValue.get(MAPPING_VALUE_FILTER), mappingValue.get(MAPPING_VALUE_PREFIX) == null || mappingValue.get(MAPPING_VALUE_PREFIX).isEmpty() ? null : mappingValue.get(MAPPING_VALUE_PREFIX)); if (subvalue != null) { for (int i = 0; i < value.length; i++) { nextValue[number] = addAndEncodeValue(value[i], subvalue, containsVariables); number++; } } else if (!nullValue) { for (int i = 0; i < value.length; i++) { nextValue[number] = value[i]; number++; } nullValue = true; } } value = new String[number]; System.arraycopy(nextValue, 0, value, 0, number); } } else if (mappingValue.get("type") .equals(MtasParserMapping.PARSER_TYPE_VARIABLE)) { if (containsVariables) { String variableName = mappingValue.get(MAPPING_VALUE_NAME); String variableValue = mappingValue.get(MAPPING_VALUE_VALUE); String prefix = mappingValue.get(MAPPING_VALUE_PREFIX); if (variableName != null && variableValue != null && mappingValue.get(MAPPING_VALUE_SOURCE) .equals(MtasParserMapping.SOURCE_OWN)) { String subvalue = object.getAttribute(variableValue); if (subvalue != null && subvalue.startsWith("#")) { subvalue = subvalue.substring(1); } if (subvalue != null) { for (int i = 0; i < value.length; i++) { if (prefix != null && !prefix.isEmpty()) { value[i] = addAndEncodeValue(value[i], prefix, containsVariables); } value[i] = addAndEncodeVariable(value[i], variableName, subvalue, containsVariables); } } } } else { throw new MtasParserException("unexpected variable"); } } else { throw new MtasParserException( "unknown type " + mappingValue.get("type")); } } } } if (value.length == 1 && value[0].isEmpty()) { return new String[] {}; } else { return value; } } /** * Adds the and encode variable. * * @param originalValue the original value * @param newVariable the new variable * @param newVariableName the new variable name * @param encode the encode * @return the string */ private String addAndEncodeVariable(String originalValue, String newVariable, String newVariableName, boolean encode) { return addAndEncode(originalValue, newVariable, newVariableName, encode); } /** * Adds the and encode value. * * @param originalValue the original value * @param newValue the new value * @param encode the encode * @return the string */ private String addAndEncodeValue(String originalValue, String newValue, boolean encode) { return addAndEncode(originalValue, null, newValue, encode); } /** * Adds the and encode. * * @param originalValue the original value * @param newType the new type * @param newValue the new value * @param encode the encode * @return the string */ private String addAndEncode(String originalValue, String newType, String newValue, boolean encode) { if (newValue == null) { return originalValue; } else { String finalNewValue; if (encode) { if (newType == null) { finalNewValue = new String( enc.encode(newValue.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); } else { finalNewValue = new String( enc.encode(newType.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8) + ":" + new String( enc.encode(newValue.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); } } else { finalNewValue = newValue; } if (originalValue == null || originalValue.isEmpty()) { return finalNewValue; } else { return originalValue + (encode ? " " : "") + finalNewValue; } } } /** * Decode and update with variables. * * @param encodedPrefix the encoded prefix * @param encodedPostfix the encoded postfix * @param variables the variables * @return the string */ protected String decodeAndUpdateWithVariables(String encodedPrefix, String encodedPostfix, Map<String, Map<String, String>> variables) { String[] prefixSplit; String[] postfixSplit; if (encodedPrefix != null && !encodedPrefix.isEmpty()) { prefixSplit = encodedPrefix.split(" "); } else { prefixSplit = new String[0]; } if (encodedPostfix != null && !encodedPostfix.isEmpty()) { postfixSplit = encodedPostfix.split(" "); } else { postfixSplit = new String[0]; } try { String prefix = decodeAndUpdateWithVariables(prefixSplit, variables); String postfix = decodeAndUpdateWithVariables(postfixSplit, variables); return prefix + MtasToken.DELIMITER + postfix; } catch (MtasParserException e) { log.debug(e); return null; } } /** * Decode and update with variables. * * @param splitList the split list * @param variables the variables * @return the string * @throws MtasParserException the mtas parser exception */ private String decodeAndUpdateWithVariables(String[] splitList, Map<String, Map<String, String>> variables) throws MtasParserException { StringBuilder builder = new StringBuilder(); for (String split : splitList) { if (split.contains(":")) { String[] subSplit = split.split(":"); if (subSplit.length == 2) { String decodedVariableName = new String(dec.decode(subSplit[0]), StandardCharsets.UTF_8); String decodedVariableValue = new String(dec.decode(subSplit[1]), StandardCharsets.UTF_8); if (variables.containsKey(decodedVariableName)) { if (variables.get(decodedVariableName) .containsKey(decodedVariableValue)) { String valueFromVariable = variables.get(decodedVariableName) .get(decodedVariableValue); builder.append(valueFromVariable); } else { throw new MtasParserException("id " + decodedVariableValue + " not found in " + decodedVariableName); } } else { throw new MtasParserException( "variable " + decodedVariableName + " unknown"); } } } else { try { builder.append(new String(dec.decode(split), StandardCharsets.UTF_8)); } catch (IllegalArgumentException e) { log.info(e); } } } return builder.toString(); } /** * Compute payload from mapping payload. * * @param object the object * @param mappingPayloads the mapping payloads * @param currentList the current list * @return the bytes ref * @throws MtasParserException the mtas parser exception */ private BytesRef computePayloadFromMappingPayload(MtasParserObject object, List<Map<String, String>> mappingPayloads, Map<String, List<MtasParserObject>> currentList) throws MtasParserException { BytesRef payload = null; for (Map<String, String> mappingPayload : mappingPayloads) { if (mappingPayload.get(MAPPING_VALUE_SOURCE) .equals(MtasParserMapping.SOURCE_STRING)) { if (mappingPayload.get(MAPPING_VALUE_TYPE) .equals(MtasParserMapping.PARSER_TYPE_STRING) && mappingPayload.get(MAPPING_VALUE_TEXT) != null) { BytesRef subpayload = computeMaximumFilteredPayload( mappingPayload.get(MAPPING_VALUE_TEXT), payload, null); payload = (subpayload != null) ? subpayload : payload; } // from objects } else { MtasParserObject[] checkObjects = computeObjectFromMappingValue(object, mappingPayload, currentList); // do checks and updates if (checkObjects != null) { // payload from attribute if (mappingPayload.get("type") .equals(MtasParserMapping.PARSER_TYPE_ATTRIBUTE)) { BytesRef subpayload = computeMaximumFilteredPayload( checkObjects[0].getAttribute(mappingPayload.get("name")), payload, mappingPayload.get(MAPPING_VALUE_FILTER)); payload = (subpayload != null) ? subpayload : payload; // payload from text } else if (mappingPayload.get("type") .equals(MtasParserMapping.PARSER_TYPE_TEXT)) { BytesRef subpayload = computeMaximumFilteredPayload( object.getText(), payload, mappingPayload.get(MAPPING_VALUE_FILTER)); payload = (subpayload != null) ? subpayload : payload; } } } } return payload; } /** * Prevalidate object. * * @param object the object * @param currentList the current list * @return the boolean */ Boolean prevalidateObject(MtasParserObject object, Map<String, List<MtasParserObject>> currentList) { MtasParserType objectType = object.getType(); List<MtasParserMapping<?>> mappings = objectType.getItems(); if (mappings.isEmpty()) { return true; } for (MtasParserMapping<?> mapping : mappings) { try { precheckMappingConditions(object, mapping.getConditions(), currentList); return true; } catch (MtasParserException e) { log.debug(e); } } return false; } /** * Precheck mapping conditions. * * @param object the object * @param mappingConditions the mapping conditions * @param currentList the current list * @throws MtasParserException the mtas parser exception */ void precheckMappingConditions(MtasParserObject object, List<Map<String, String>> mappingConditions, Map<String, List<MtasParserObject>> currentList) throws MtasParserException { for (Map<String, String> mappingCondition : mappingConditions) { // condition existence ancestor if (mappingCondition.get("type") .equals(MtasParserMapping.PARSER_TYPE_EXISTENCE)) { int number = 0; try { number = Integer.parseInt(mappingCondition.get("number")); } catch (Exception e) { log.debug(e); } String type = computeTypeFromMappingSource( mappingCondition.get(MAPPING_VALUE_SOURCE)); if (number != currentList.get(type).size()) { throw new MtasParserException( "condition mapping is " + number + " ancestors of " + type + " (but " + currentList.get(type).size() + " found)"); } // condition unknown ancestors } else if (mappingCondition.get("type") .equals(MtasParserMapping.PARSER_TYPE_UNKNOWN_ANCESTOR)) { int number = 0; try { number = Integer.parseInt(mappingCondition.get("number")); } catch (Exception e) { log.debug(e); } if (number != object.getUnknownAncestorNumber()) { throw new MtasParserException( "condition mapping is " + number + " unknown ancestors (but " + object.getUnknownAncestorNumber() + " found)"); } } else { MtasParserObject[] checkObjects = computeObjectFromMappingValue(object, mappingCondition, currentList); Boolean notCondition = false; if (mappingCondition.get("not") != null) { notCondition = true; } // do checks if (checkObjects != null) { checkObjectLoop: for (MtasParserObject checkObject : checkObjects) { MtasParserType checkType = checkObject.getType(); // condition on name if (mappingCondition.get("type") .equals(MtasParserMapping.PARSER_TYPE_NAME)) { if (notCondition && mappingCondition.get(MAPPING_VALUE_CONDITION) .equals(checkType.getName())) { throw new MtasParserException("condition NOT " + mappingCondition.get(MAPPING_VALUE_CONDITION) + " on name not matched (is " + checkType.getName() + ")"); } else if (!notCondition && mappingCondition .get(MAPPING_VALUE_CONDITION).equals(checkType.getName())) { break checkObjectLoop; } else if (!notCondition && !mappingCondition .get(MAPPING_VALUE_CONDITION).equals(checkType.getName())) { throw new MtasParserException("condition " + mappingCondition.get(MAPPING_VALUE_CONDITION) + " on name not matched (is " + checkType.getName() + ")"); } // condition on attribute } else if (mappingCondition.get("type") .equals(MtasParserMapping.PARSER_TYPE_ATTRIBUTE)) { String attributeCondition = mappingCondition .get(MAPPING_VALUE_CONDITION); String namespace = mappingCondition.get(MAPPING_VALUE_NAMESPACE); String attributeValue; if(namespace==null) { attributeValue = checkObject.getAttribute(mappingCondition.get(MAPPING_VALUE_NAME)); } else { attributeValue = checkObject.getOtherAttribute(namespace, mappingCondition.get(MAPPING_VALUE_NAME)); } if ((attributeCondition == null) && (attributeValue == null)) { if (!notCondition) { throw new MtasParserException("attribute " + mappingCondition.get("name") + " not available"); } } else if ((attributeCondition != null) && (attributeValue == null)) { if (!notCondition) { throw new MtasParserException( "condition " + attributeCondition + " on attribute " + mappingCondition.get("name") + " not matched (is null)"); } } else if (attributeCondition != null) { if (!notCondition && !attributeCondition.equals(attributeValue)) { throw new MtasParserException( "condition " + attributeCondition + " on attribute " + mappingCondition.get("name") + " not matched (is " + attributeValue + ")"); } else if (!notCondition && attributeCondition.equals(attributeValue)) { break checkObjectLoop; } else if (notCondition && attributeCondition.equals(attributeValue)) { throw new MtasParserException( "condition NOT " + attributeCondition + " on attribute " + mappingCondition.get("name") + " not matched (is " + attributeValue + ")"); } } // condition on text } else if (mappingCondition.get("type") .equals(MtasParserMapping.PARSER_TYPE_TEXT) && object.getType().precheckText()) { String textCondition = mappingCondition .get(MAPPING_VALUE_CONDITION); String textValue = object.getText(); if ((textCondition == null) && ((textValue == null) || textValue.equals(""))) { if (!notCondition) { throw new MtasParserException("no text available"); } } else if ((textCondition != null) && (textValue == null)) { if (!notCondition) { throw new MtasParserException("condition " + textCondition + " on text not matched (is null)"); } } else if (textCondition != null) { if (!notCondition && !textCondition.equals(textValue)) { throw new MtasParserException("condition " + textCondition + " on text not matched (is " + textValue + ")"); } else if (notCondition && textCondition.equals(textValue)) { throw new MtasParserException("condition NOT " + textCondition + " on text not matched (is " + textValue + ")"); } } } } } else if (!notCondition) { throw new MtasParserException( "no object found to match condition" + mappingCondition); } } } } /** * Postcheck mapping conditions. * * @param object the object * @param mappingConditions the mapping conditions * @param currentList the current list * @throws MtasParserException the mtas parser exception */ private void postcheckMappingConditions(MtasParserObject object, List<Map<String, String>> mappingConditions, Map<String, List<MtasParserObject>> currentList) throws MtasParserException { precheckMappingConditions(object, mappingConditions, currentList); for (Map<String, String> mappingCondition : mappingConditions) { // condition on text if (mappingCondition.get("type") .equals(MtasParserMapping.PARSER_TYPE_TEXT)) { MtasParserObject[] checkObjects = computeObjectFromMappingValue(object, mappingCondition, currentList); if (checkObjects != null) { String textCondition = mappingCondition.get(MAPPING_VALUE_CONDITION); String textValue = object.getText(); Boolean notCondition = false; if (mappingCondition.get("not") != null) { notCondition = true; } if ((textCondition == null) && ((textValue == null) || textValue.isEmpty())) { if (!notCondition) { throw new MtasParserException("no text available"); } } else if ((textCondition != null) && (textValue == null)) { if (!notCondition) { throw new MtasParserException("condition " + textCondition + " on text not matched (is null)"); } } else if (textCondition != null) { if (!notCondition && !textCondition.equals(textValue)) { throw new MtasParserException("condition " + textCondition + " on text not matched (is " + textValue + ")"); } else if (notCondition && textCondition.equals(textValue)) { throw new MtasParserException("condition NOT " + textCondition + " on text not matched (is " + textValue + ")"); } } } } } } /** * Compute filtered split values. * * @param values the values * @param filter the filter * @return the string[] * @throws MtasConfigException the mtas config exception */ private String[] computeFilteredSplitValues(String[] values, String filter) throws MtasConfigException { if (filter != null) { String[] filters = filter.split(","); boolean[] valuesFilter = new boolean[values.length]; boolean doSplitFilter = false; for (String item : filters) { if (item.trim().matches( "^" + Pattern.quote(MAPPING_FILTER_SPLIT) + "\\([0-9\\-]+\\)$")) { doSplitFilter = true; Pattern splitContent = Pattern .compile("^" + Pattern.quote(MAPPING_FILTER_SPLIT) + "\\(([0-9]+)(-([0-9]+))?\\)$"); Matcher splitContentMatcher = splitContent.matcher(item.trim()); while (splitContentMatcher.find()) { if (splitContentMatcher.group(3) == null) { int i = Integer.parseInt(splitContentMatcher.group(1)); if (i >= 0 && i < values.length) { valuesFilter[i] = true; } } else { int i1 = Integer.parseInt(splitContentMatcher.group(1)); int i2 = Integer.parseInt(splitContentMatcher.group(3)); for (int i = Math.max(0, i1); i < Math.min(values.length, i2); i++) { valuesFilter[i] = true; } } } } } if (doSplitFilter) { int number = 0; for (int i = 0; i < valuesFilter.length; i++) { if (valuesFilter[i]) { number++; } } if (number > 0) { String[] newValues = new String[number]; number = 0; for (int i = 0; i < valuesFilter.length; i++) { if (valuesFilter[i]) { newValues[number] = values[i]; number++; } } return newValues; } else { return new String[] {}; } } } return values; } /** * Compute filtered prefixed value. * * @param type the type * @param value the value * @param filter the filter * @param prefix the prefix * @return the string * @throws MtasConfigException the mtas config exception */ private String computeFilteredPrefixedValue(String type, String value, String filter, String prefix) throws MtasConfigException { String localValue = value; // do magic with filter if (filter != null) { String[] filters = filter.split(","); for (String item : filters) { if (item.trim().equals(MAPPING_FILTER_UPPERCASE)) { localValue = localValue == null ? null : localValue.toUpperCase(); } else if (item.trim().equals(MAPPING_FILTER_LOWERCASE)) { localValue = localValue == null ? null : localValue.toLowerCase(); } else if (item.trim().equals(MAPPING_FILTER_ASCII)) { if (localValue != null) { char[] old = localValue.toCharArray(); char[] ascii = new char[4 * old.length]; ASCIIFoldingFilter.foldToASCII(old, 0, ascii, 0, localValue.length()); localValue = new String(ascii); } } else if (item.trim() .matches(Pattern.quote(MAPPING_FILTER_SPLIT) + "\\([0-9\\-]+\\)")) { if (!type.equals(MtasParserMapping.PARSER_TYPE_TEXT_SPLIT)) { throw new MtasConfigException( "split filter not allowed for " + type); } } else { throw new MtasConfigException( "unknown filter " + item + " for value " + localValue); } } } if (localValue != null && prefix != null) { localValue = prefix + localValue; } return localValue; } /** * Compute maximum filtered payload. * * @param value the value * @param payload the payload * @param filter the filter * @return the bytes ref */ private BytesRef computeMaximumFilteredPayload(String value, BytesRef payload, String filter) { // do magic with filter if (value != null) { if (payload != null) { Float payloadFloat = PayloadHelper.decodeFloat(payload.bytes, payload.offset); Float valueFloat = Float.parseFloat(value); return new BytesRef( PayloadHelper.encodeFloat(Math.max(payloadFloat, valueFloat))); } else { return new BytesRef(PayloadHelper.encodeFloat(Float.parseFloat(value))); } } else { return payload; } } /** * The Class MtasParserType. * * @param <T> the generic type */ protected static class MtasParserType<T> { /** The type. */ private String type; /** The name. */ private String name; /** The precheck text. */ protected boolean precheckText; /** The ref attribute name. */ private String refAttributeName; /** The items. */ protected ArrayList<T> items = new ArrayList<>(); /** * Instantiates a new mtas parser type. * * @param type the type * @param name the name * @param precheckText the precheck text */ MtasParserType(String type, String name, boolean precheckText) { this.type = type; this.name = name; this.precheckText = precheckText; } /** * Instantiates a new mtas parser type. * * @param type the type * @param name the name * @param precheckText the precheck text * @param refAttributeName the ref attribute name */ MtasParserType(String type, String name, boolean precheckText, String refAttributeName) { this(type, name, precheckText); this.refAttributeName = refAttributeName; } /** * Gets the ref attribute name. * * @return the ref attribute name */ public String getRefAttributeName() { return refAttributeName; } /** * Gets the name. * * @return the name */ public String getName() { return name; } /** * Gets the type. * * @return the type */ public String getType() { return type; } /** * Precheck text. * * @return true, if successful */ public boolean precheckText() { return precheckText; } /** * Adds the item. * * @param item the item */ public void addItem(T item) { items.add(item); } /** * Gets the items. * * @return the items */ public List<T> getItems() { return items; } } /** * The Class MtasParserVariableValue. */ protected static class MtasParserVariableValue { /** The type. */ public String type; /** The name. */ public String name; /** * Instantiates a new mtas parser variable value. * * @param type the type * @param name the name */ public MtasParserVariableValue(String type, String name) { this.type = type; this.name = name; } } /** * The Class MtasParserMappingToken. */ protected static class MtasParserMappingToken { /** The type. */ public String type; /** The offset. */ public Boolean offset; /** The realoffset. */ public Boolean realoffset; /** The parent. */ public Boolean parent; /** The pre values. */ public List<Map<String, String>> preValues; /** The post values. */ public List<Map<String, String>> postValues; /** The payload. */ public List<Map<String, String>> payload; /** * Instantiates a new mtas parser mapping token. * * @param tokenType the token type */ public MtasParserMappingToken(String tokenType) { type = tokenType; offset = true; realoffset = true; parent = true; preValues = new ArrayList<>(); postValues = new ArrayList<>(); payload = new ArrayList<>(); } /** * Sets the offset. * * @param tokenOffset the new offset */ public void setOffset(Boolean tokenOffset) { offset = tokenOffset; } /** * Sets the real offset. * * @param tokenRealOffset the new real offset */ public void setRealOffset(Boolean tokenRealOffset) { realoffset = tokenRealOffset; } /** * Sets the parent. * * @param tokenParent the new parent */ public void setParent(Boolean tokenParent) { parent = tokenParent; } } /** * The Class MtasParserVariable. */ protected static class MtasParserVariable { /** The name. */ public String name; /** The variable. */ public String variable; /** The values. */ protected ArrayList<MtasParserVariableValue> values; /** * Instantiates a new mtas parser variable. * * @param name the name * @param value the value */ public MtasParserVariable(String name, String value) { this.name = name; this.variable = value; values = new ArrayList<>(); } /** * Process config. * * @param config the config * @throws MtasConfigException the mtas config exception */ public void processConfig(MtasConfiguration config) throws MtasConfigException { for (int k = 0; k < config.children.size(); k++) { if (config.children.get(k).name.equals(VARIABLE_SUBTYPE_VALUE)) { for (int m = 0; m < config.children.get(k).children.size(); m++) { if (config.children.get(k).children.get(m).name .equals(VARIABLE_SUBTYPE_VALUE_ITEM)) { String valueType = config.children.get(k).children .get(m).attributes.get("type"); String nameType = config.children.get(k).children .get(m).attributes.get("name"); if ((valueType != null) && valueType.equals("attribute") && nameType != null) { MtasParserVariableValue variableValue = new MtasParserVariableValue( valueType, nameType); values.add(variableValue); } } } } else { throw new MtasConfigException( "unknown variable subtype " + config.children.get(k).name + " in variable " + config.attributes.get("name")); } } } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("variable " + variable + " from " + name); for (int i = 0; i < values.size(); i++) { builder.append("\n\tvalue " + i); builder.append(" - " + values.get(i).type); } return builder.toString(); } } /** * The Class MtasParserMapping. * * @param <T> the generic type */ protected abstract class MtasParserMapping<T extends MtasParserMapping<T>> { /** * Self. * * @return the t */ protected abstract T self(); /** The Constant SOURCE_OWN. */ protected static final String SOURCE_OWN = "own"; /** The Constant SOURCE_REFS. */ protected static final String SOURCE_REFS = "refs"; /** The Constant SOURCE_ANCESTOR_GROUP. */ protected static final String SOURCE_ANCESTOR_GROUP = "ancestorGroup"; /** The Constant SOURCE_ANCESTOR_GROUP_ANNOTATION. */ protected static final String SOURCE_ANCESTOR_GROUP_ANNOTATION = "ancestorGroupAnnotation"; /** The Constant SOURCE_ANCESTOR_WORD. */ protected static final String SOURCE_ANCESTOR_WORD = "ancestorWord"; /** The Constant SOURCE_ANCESTOR_WORD_ANNOTATION. */ protected static final String SOURCE_ANCESTOR_WORD_ANNOTATION = "ancestorWordAnnotation"; /** The Constant SOURCE_ANCESTOR_RELATION. */ protected static final String SOURCE_ANCESTOR_RELATION = "ancestorRelation"; /** The Constant SOURCE_ANCESTOR_RELATION_ANNOTATION. */ protected static final String SOURCE_ANCESTOR_RELATION_ANNOTATION = "ancestorRelationAnnotation"; /** The Constant SOURCE_STRING. */ protected static final String SOURCE_STRING = "string"; /** The Constant PARSER_TYPE_VARIABLE. */ protected static final String PARSER_TYPE_VARIABLE = "variable"; /** The Constant PARSER_TYPE_STRING. */ protected static final String PARSER_TYPE_STRING = "string"; /** The Constant PARSER_TYPE_NAME. */ protected static final String PARSER_TYPE_NAME = "name"; /** The Constant PARSER_TYPE_ATTRIBUTE. */ protected static final String PARSER_TYPE_ATTRIBUTE = "attribute"; /** The Constant PARSER_TYPE_TEXT. */ protected static final String PARSER_TYPE_TEXT = "text"; /** The Constant PARSER_TYPE_TEXT_SPLIT. */ protected static final String PARSER_TYPE_TEXT_SPLIT = "textSplit"; /** The Constant PARSER_TYPE_EXISTENCE. */ protected static final String PARSER_TYPE_EXISTENCE = "existence"; /** The Constant PARSER_TYPE_UNKNOWN_ANCESTOR. */ protected static final String PARSER_TYPE_UNKNOWN_ANCESTOR = "unknownAncestor"; /** The type. */ protected String type; /** The offset. */ protected String offset; /** The real offset. */ protected String realOffset; /** The position. */ protected String position; /** The start. */ protected String start; /** The end. */ protected String end; /** The tokens. */ protected List<MtasParserMappingToken> tokens; /** The conditions. */ protected List<Map<String, String>> conditions; /** * Instantiates a new mtas parser mapping. */ public MtasParserMapping() { type = null; offset = null; realOffset = null; position = null; tokens = new ArrayList<>(); conditions = new ArrayList<>(); start = null; end = null; } /** * Process config. * * @param config the config * @throws MtasConfigException the mtas config exception */ public void processConfig(MtasConfiguration config) throws MtasConfigException { setStartEnd(config.attributes.get("start"), config.attributes.get("end")); for (int k = 0; k < config.children.size(); k++) { if (config.children.get(k).name.equals(MAPPING_SUBTYPE_TOKEN)) { String tokenType = config.children.get(k).attributes.get("type"); if ((tokenType != null) && tokenType.equals("string")) { MtasParserMappingToken mappingToken = new MtasParserMappingToken( tokenType); tokens.add(mappingToken); // check attributes for (String tokenAttributeName : config.children.get(k).attributes .keySet()) { String attributeValue = config.children.get(k).attributes .get(tokenAttributeName); if (tokenAttributeName.equals(TOKEN_OFFSET)) { if (!attributeValue.equals("true") && !attributeValue.equals("1")) { mappingToken.setOffset(false); } else { mappingToken.setOffset(true); } } else if (tokenAttributeName.equals(TOKEN_REALOFFSET)) { if (!attributeValue.equals("true") && !attributeValue.equals("1")) { mappingToken.setRealOffset(false); } else { mappingToken.setRealOffset(true); } } else if (tokenAttributeName.equals(TOKEN_PARENT)) { if (!attributeValue.equals("true") && !attributeValue.equals("1")) { mappingToken.setParent(false); } else { mappingToken.setParent(true); } } } for (int m = 0; m < config.children.get(k).children.size(); m++) { if (config.children.get(k).children.get(m).name .equals(MAPPING_SUBTYPE_TOKEN_PRE) || config.children.get(k).children.get(m).name .equals(MAPPING_SUBTYPE_TOKEN_POST)) { MtasConfiguration items = config.children.get(k).children .get(m); for (int l = 0; l < items.children.size(); l++) { if (items.children.get(l).name.equals("item")) { String itemType = items.children.get(l).attributes .get(MAPPING_VALUE_TYPE); String nameAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_NAME); String namespaceAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_NAMESPACE); String prefixAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_PREFIX); String filterAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_FILTER); String distanceAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_DISTANCE); String valueAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_VALUE); if (itemType.equals(ITEM_TYPE_STRING)) { addString(mappingToken, items.name, valueAttribute); } else if (itemType.equals(ITEM_TYPE_NAME)) { addName(mappingToken, items.name, prefixAttribute, filterAttribute); } else if (itemType.equals(ITEM_TYPE_ATTRIBUTE)) { addAttribute(mappingToken, items.name, nameAttribute, namespaceAttribute, prefixAttribute, filterAttribute); } else if (itemType.equals(ITEM_TYPE_TEXT)) { addText(mappingToken, items.name, prefixAttribute, filterAttribute); } else if (itemType.equals(ITEM_TYPE_TEXT_SPLIT)) { addTextSplit(mappingToken, items.name, valueAttribute, prefixAttribute, filterAttribute); } else if (itemType.equals(ITEM_TYPE_NAME_ANCESTOR)) { addAncestorName(computeAncestorSourceType(type), mappingToken, items.name, computeDistance(distanceAttribute), prefixAttribute, filterAttribute); } else if (itemType.equals(ITEM_TYPE_NAME_ANCESTOR_GROUP)) { addAncestorName(SOURCE_ANCESTOR_GROUP, mappingToken, items.name, computeDistance(distanceAttribute), prefixAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_NAME_ANCESTOR_GROUP_ANNOTATION)) { addAncestorName(SOURCE_ANCESTOR_GROUP_ANNOTATION, mappingToken, items.name, computeDistance(distanceAttribute), prefixAttribute, filterAttribute); } else if (itemType.equals(ITEM_TYPE_NAME_ANCESTOR_WORD)) { addAncestorName(SOURCE_ANCESTOR_WORD, mappingToken, items.name, computeDistance(distanceAttribute), prefixAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_NAME_ANCESTOR_WORD_ANNOTATION)) { addAncestorName(SOURCE_ANCESTOR_WORD_ANNOTATION, mappingToken, items.name, computeDistance(distanceAttribute), prefixAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_NAME_ANCESTOR_RELATION)) { addAncestorName(SOURCE_ANCESTOR_RELATION, mappingToken, items.name, computeDistance(distanceAttribute), prefixAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_NAME_ANCESTOR_RELATION_ANNOTATION)) { addAncestorName(SOURCE_ANCESTOR_RELATION_ANNOTATION, mappingToken, items.name, computeDistance(distanceAttribute), prefixAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP)) { addAncestorAttribute(SOURCE_ANCESTOR_GROUP, mappingToken, items.name, computeDistance(distanceAttribute), nameAttribute, prefixAttribute, filterAttribute); } else if (itemType.equals( ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP_ANNOTATION)) { addAncestorAttribute(SOURCE_ANCESTOR_GROUP_ANNOTATION, mappingToken, items.name, computeDistance(distanceAttribute), nameAttribute, prefixAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD)) { addAncestorAttribute(SOURCE_ANCESTOR_WORD, mappingToken, items.name, computeDistance(distanceAttribute), nameAttribute, prefixAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD_ANNOTATION)) { addAncestorAttribute(SOURCE_ANCESTOR_WORD_ANNOTATION, mappingToken, items.name, computeDistance(distanceAttribute), nameAttribute, prefixAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION)) { addAncestorAttribute(SOURCE_ANCESTOR_RELATION, mappingToken, items.name, computeDistance(distanceAttribute), nameAttribute, prefixAttribute, filterAttribute); } else if (itemType.equals( ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION_ANNOTATION)) { addAncestorAttribute(SOURCE_ANCESTOR_RELATION_ANNOTATION, mappingToken, items.name, computeDistance(distanceAttribute), nameAttribute, prefixAttribute, filterAttribute); } else if (itemType.equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR)) { addAncestorAttribute(computeAncestorSourceType(this.type), mappingToken, items.name, computeDistance(distanceAttribute), nameAttribute, prefixAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_VARIABLE_FROM_ATTRIBUTE)) { addVariableFromAttribute(mappingToken, items.name, nameAttribute, prefixAttribute, valueAttribute); } else { throw new MtasConfigException(String.format( "unknown itemType %s for %s in mapping %s", itemType, items.name, config.attributes.get("name"))); } } } } else if (config.children.get(k).children.get(m).name .equals(MAPPING_SUBTYPE_PAYLOAD)) { MtasConfiguration items = config.children.get(k).children .get(m); for (int l = 0; l < items.children.size(); l++) { if (items.children.get(l).name.equals("item")) { String itemType = items.children.get(l).attributes .get("type"); String valueAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_VALUE); String nameAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_NAME); String filterAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_FILTER); String distanceAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_DISTANCE); if (itemType.equals(ITEM_TYPE_STRING)) { payloadString(mappingToken, valueAttribute); } else if (itemType.equals(ITEM_TYPE_TEXT)) { payloadText(mappingToken, filterAttribute); } else if (itemType.equals(ITEM_TYPE_ATTRIBUTE)) { payloadAttribute(mappingToken, nameAttribute, filterAttribute); } else if (itemType.equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR)) { payloadAncestorAttribute(mappingToken, computeAncestorSourceType(type), computeDistance(distanceAttribute), nameAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP)) { payloadAncestorAttribute(mappingToken, SOURCE_ANCESTOR_GROUP, computeDistance(distanceAttribute), nameAttribute, filterAttribute); } else if (itemType.equals( ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP_ANNOTATION)) { payloadAncestorAttribute(mappingToken, SOURCE_ANCESTOR_GROUP_ANNOTATION, computeDistance(distanceAttribute), nameAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD)) { payloadAncestorAttribute(mappingToken, SOURCE_ANCESTOR_WORD, computeDistance(distanceAttribute), nameAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD_ANNOTATION)) { payloadAncestorAttribute(mappingToken, SOURCE_ANCESTOR_WORD_ANNOTATION, computeDistance(distanceAttribute), nameAttribute, filterAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION)) { payloadAncestorAttribute(mappingToken, SOURCE_ANCESTOR_RELATION, computeDistance(distanceAttribute), nameAttribute, filterAttribute); } else if (itemType.equals( ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION_ANNOTATION)) { payloadAncestorAttribute(mappingToken, SOURCE_ANCESTOR_RELATION_ANNOTATION, computeDistance(distanceAttribute), nameAttribute, filterAttribute); } else { throw new MtasConfigException(String.format( "unknown itemType %s for %s in mapping %s", itemType, items.name, config.attributes.get("name"))); } } } } } } } else if (config.children.get(k).name .equals(MAPPING_SUBTYPE_CONDITION)) { MtasConfiguration items = config.children.get(k); for (int l = 0; l < items.children.size(); l++) { if (items.children.get(l).name.equals("item")) { String itemType = items.children.get(l).attributes.get("type"); String nameAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_NAME); String namespaceAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_NAMESPACE); String conditionAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_CONDITION); String filterAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_FILTER); String numberAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_NUMBER); String distanceAttribute = items.children.get(l).attributes .get(MAPPING_VALUE_DISTANCE); String notAttribute = items.children.get(l).attributes.get("not"); if ((notAttribute != null) && !notAttribute.equals("true") && !notAttribute.equals("1")) { notAttribute = null; } if (itemType.equals(ITEM_TYPE_ATTRIBUTE)) { conditionAttribute(nameAttribute, namespaceAttribute, conditionAttribute, filterAttribute, notAttribute); } else if (itemType.equals(ITEM_TYPE_NAME)) { conditionName(conditionAttribute, notAttribute); } else if (itemType.equals(ITEM_TYPE_TEXT)) { conditionText(conditionAttribute, filterAttribute, notAttribute); } else if (itemType.equals(ITEM_TYPE_UNKNOWN_ANCESTOR)) { conditionUnknownAncestor(computeNumber(numberAttribute)); } else if (itemType.equals(ITEM_TYPE_ANCESTOR)) { conditionAncestor(computeAncestorSourceType(type), computeNumber(numberAttribute)); } else if (itemType.equals(ITEM_TYPE_ANCESTOR_GROUP)) { conditionAncestor(SOURCE_ANCESTOR_GROUP, computeNumber(numberAttribute)); } else if (itemType.equals(ITEM_TYPE_ANCESTOR_GROUP_ANNOTATION)) { conditionAncestor(SOURCE_ANCESTOR_GROUP_ANNOTATION, computeNumber(numberAttribute)); } else if (itemType.equals(ITEM_TYPE_ANCESTOR_WORD)) { conditionAncestor(SOURCE_ANCESTOR_WORD, computeNumber(numberAttribute)); } else if (itemType.equals(ITEM_TYPE_ANCESTOR_WORD_ANNOTATION)) { conditionAncestor(SOURCE_ANCESTOR_WORD_ANNOTATION, computeNumber(numberAttribute)); } else if (itemType.equals(ITEM_TYPE_ANCESTOR_RELATION)) { conditionAncestor(SOURCE_ANCESTOR_RELATION, computeNumber(numberAttribute)); } else if (itemType .equals(ITEM_TYPE_ANCESTOR_RELATION_ANNOTATION)) { conditionAncestor(SOURCE_ANCESTOR_RELATION_ANNOTATION, computeNumber(numberAttribute)); } else if (itemType.equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR)) { conditionAncestorAttribute(computeAncestorSourceType(type), computeDistance(distanceAttribute), nameAttribute, conditionAttribute, filterAttribute, notAttribute); } else if (itemType.equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP)) { conditionAncestorAttribute(SOURCE_ANCESTOR_GROUP, computeDistance(distanceAttribute), nameAttribute, conditionAttribute, filterAttribute, notAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_GROUP_ANNOTATION)) { conditionAncestorAttribute(SOURCE_ANCESTOR_GROUP_ANNOTATION, computeDistance(distanceAttribute), nameAttribute, conditionAttribute, filterAttribute, notAttribute); } else if (itemType.equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD)) { conditionAncestorAttribute(SOURCE_ANCESTOR_WORD, computeDistance(distanceAttribute), nameAttribute, conditionAttribute, filterAttribute, notAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_WORD_ANNOTATION)) { conditionAncestorAttribute(SOURCE_ANCESTOR_WORD_ANNOTATION, computeDistance(distanceAttribute), nameAttribute, conditionAttribute, filterAttribute, notAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION)) { conditionAncestorAttribute(SOURCE_ANCESTOR_RELATION, computeDistance(distanceAttribute), nameAttribute, conditionAttribute, filterAttribute, notAttribute); } else if (itemType .equals(ITEM_TYPE_ATTRIBUTE_ANCESTOR_RELATION_ANNOTATION)) { conditionAncestorAttribute(SOURCE_ANCESTOR_RELATION_ANNOTATION, computeDistance(distanceAttribute), nameAttribute, conditionAttribute, filterAttribute, notAttribute); } else if (itemType.equals(ITEM_TYPE_NAME_ANCESTOR)) { conditionAncestorName(computeAncestorSourceType(type), computeDistance(distanceAttribute), conditionAttribute, filterAttribute, notAttribute); } else if (itemType.equals(ITEM_TYPE_NAME_ANCESTOR_GROUP)) { conditionAncestorName(SOURCE_ANCESTOR_GROUP, computeDistance(distanceAttribute), conditionAttribute, filterAttribute, notAttribute); } else if (itemType .equals(ITEM_TYPE_NAME_ANCESTOR_GROUP_ANNOTATION)) { conditionAncestorName(SOURCE_ANCESTOR_GROUP_ANNOTATION, computeDistance(distanceAttribute), conditionAttribute, filterAttribute, notAttribute); } else if (itemType.equals(ITEM_TYPE_NAME_ANCESTOR_WORD)) { conditionAncestorName(SOURCE_ANCESTOR_WORD, computeDistance(distanceAttribute), conditionAttribute, filterAttribute, notAttribute); } else if (itemType .equals(ITEM_TYPE_NAME_ANCESTOR_WORD_ANNOTATION)) { conditionAncestorName(SOURCE_ANCESTOR_WORD_ANNOTATION, computeDistance(distanceAttribute), conditionAttribute, filterAttribute, notAttribute); } else if (itemType.equals(ITEM_TYPE_NAME_ANCESTOR_RELATION)) { conditionAncestorName(SOURCE_ANCESTOR_RELATION, computeDistance(distanceAttribute), conditionAttribute, filterAttribute, notAttribute); } else if (itemType .equals(ITEM_TYPE_NAME_ANCESTOR_RELATION_ANNOTATION)) { conditionAncestorName(SOURCE_ANCESTOR_RELATION_ANNOTATION, computeDistance(distanceAttribute), conditionAttribute, filterAttribute, notAttribute); } else { throw new MtasConfigException( String.format("unknown itemType %s for %s in mapping %s", itemType, config.children.get(k).name, config.attributes.get("name"))); } } } } else { throw new MtasConfigException( String.format("unknown mapping subType %s in mapping %s", config.children.get(k).name, config.attributes.get("name"))); } } } /** * Sets the start end. * * @param start the start * @param end the end */ protected void setStartEnd(String start, String end) { if (start != null && !start.isEmpty() && end != null && !end.isEmpty()) { this.start = start; this.end = end; } } /** * Condition unknown ancestor. * * @param number the number */ private void conditionUnknownAncestor(String number) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put("type", PARSER_TYPE_UNKNOWN_ANCESTOR); mapConstructionItem.put("number", number); conditions.add(mapConstructionItem); } /** * Adds the string. * * @param mappingToken the mapping token * @param type the type * @param text the text */ private void addString(MtasParserMappingToken mappingToken, String type, String text) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_STRING); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_STRING); mapConstructionItem.put(MAPPING_VALUE_TEXT, text); if (type.equals(MAPPING_SUBTYPE_TOKEN_PRE)) { mappingToken.preValues.add(mapConstructionItem); } else if (type.equals(MAPPING_SUBTYPE_TOKEN_POST)) { mappingToken.postValues.add(mapConstructionItem); } } /** * Payload string. * * @param mappingToken the mapping token * @param text the text */ private void payloadString(MtasParserMappingToken mappingToken, String text) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_STRING); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_STRING); mapConstructionItem.put(MAPPING_VALUE_TEXT, text); mappingToken.payload.add(mapConstructionItem); } /** * Adds the name. * * @param mappingToken the mapping token * @param type the type * @param prefix the prefix * @param filter the filter */ private void addName(MtasParserMappingToken mappingToken, String type, String prefix, String filter) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_NAME); mapConstructionItem.put(MAPPING_VALUE_PREFIX, prefix); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); if (type.equals(MAPPING_SUBTYPE_TOKEN_PRE)) { mappingToken.preValues.add(mapConstructionItem); } else if (type.equals(MAPPING_SUBTYPE_TOKEN_POST)) { mappingToken.postValues.add(mapConstructionItem); } } /** * Condition name. * * @param condition the condition * @param not the not */ private void conditionName(String condition, String not) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_NAME); mapConstructionItem.put(MAPPING_VALUE_CONDITION, condition); mapConstructionItem.put(MAPPING_VALUE_NOT, not); conditions.add(mapConstructionItem); } /** * Adds the text. * * @param mappingToken the mapping token * @param type the type * @param prefix the prefix * @param filter the filter */ private void addText(MtasParserMappingToken mappingToken, String type, String prefix, String filter) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_TEXT); mapConstructionItem.put(MAPPING_VALUE_PREFIX, prefix); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); if (type.equals(MAPPING_SUBTYPE_TOKEN_PRE)) { mappingToken.preValues.add(mapConstructionItem); } else if (type.equals(MAPPING_SUBTYPE_TOKEN_POST)) { mappingToken.postValues.add(mapConstructionItem); } } /** * Adds the text split. * * @param mappingToken the mapping token * @param type the type * @param split the split * @param prefix the prefix * @param filter the filter */ private void addTextSplit(MtasParserMappingToken mappingToken, String type, String split, String prefix, String filter) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_TEXT_SPLIT); mapConstructionItem.put(MAPPING_VALUE_SPLIT, split); mapConstructionItem.put(MAPPING_VALUE_PREFIX, prefix); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); if (type.equals(MAPPING_SUBTYPE_TOKEN_PRE)) { mappingToken.preValues.add(mapConstructionItem); } else if (type.equals(MAPPING_SUBTYPE_TOKEN_POST)) { mappingToken.postValues.add(mapConstructionItem); } } /** * Condition text. * * @param condition the condition * @param filter the filter * @param not the not */ private void conditionText(String condition, String filter, String not) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_TEXT); mapConstructionItem.put(MAPPING_VALUE_CONDITION, condition); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); mapConstructionItem.put(MAPPING_VALUE_NOT, not); conditions.add(mapConstructionItem); } /** * Payload text. * * @param mappingToken the mapping token * @param filter the filter */ private void payloadText(MtasParserMappingToken mappingToken, String filter) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_TEXT); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); mappingToken.payload.add(mapConstructionItem); } /** * Adds the attribute. * * @param mappingToken the mapping token * @param type the type * @param name the name * @param prefix the prefix * @param filter the filter */ private void addAttribute(MtasParserMappingToken mappingToken, String type, String name, String namespace, String prefix, String filter) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_ATTRIBUTE); mapConstructionItem.put(MAPPING_VALUE_NAME, name); mapConstructionItem.put(MAPPING_VALUE_NAMESPACE, namespace); mapConstructionItem.put(MAPPING_VALUE_PREFIX, prefix); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); if (name != null) { if (type.equals(MAPPING_SUBTYPE_TOKEN_PRE)) { mappingToken.preValues.add(mapConstructionItem); } else if (type.equals(MAPPING_SUBTYPE_TOKEN_POST)) { mappingToken.postValues.add(mapConstructionItem); } } } /** * Adds the variable from attribute. * * @param mappingToken the mapping token * @param type the type * @param name the name * @param prefix the prefix * @param value the value */ private void addVariableFromAttribute(MtasParserMappingToken mappingToken, String type, String name, String prefix, String value) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_VARIABLE); mapConstructionItem.put(MAPPING_VALUE_NAME, name); mapConstructionItem.put(MAPPING_VALUE_PREFIX, prefix); mapConstructionItem.put(MAPPING_VALUE_VALUE, value); if (name != null && value != null) { if (type.equals(MAPPING_SUBTYPE_TOKEN_PRE)) { mappingToken.preValues.add(mapConstructionItem); } else if (type.equals(MAPPING_SUBTYPE_TOKEN_POST)) { mappingToken.postValues.add(mapConstructionItem); } } } /** * Condition attribute. * * @param name the name * @param condition the condition * @param filter the filter * @param not the not */ private void conditionAttribute(String name, String namespace, String condition, String filter, String not) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_ATTRIBUTE); mapConstructionItem.put(MAPPING_VALUE_NAME, name); mapConstructionItem.put(MAPPING_VALUE_NAMESPACE, namespace); mapConstructionItem.put(MAPPING_VALUE_CONDITION, condition); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); mapConstructionItem.put(MAPPING_VALUE_NOT, not); if (name != null) { conditions.add(mapConstructionItem); } } /** * Payload attribute. * * @param mappingToken the mapping token * @param name the name * @param filter the filter */ private void payloadAttribute(MtasParserMappingToken mappingToken, String name, String filter) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, SOURCE_OWN); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_ATTRIBUTE); mapConstructionItem.put(MAPPING_VALUE_NAME, name); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); mappingToken.payload.add(mapConstructionItem); } /** * Condition ancestor. * * @param ancestorType the ancestor type * @param number the number */ public void conditionAncestor(String ancestorType, String number) { if (ancestorType.equals(SOURCE_ANCESTOR_GROUP) || ancestorType.equals(SOURCE_ANCESTOR_GROUP_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_WORD) || ancestorType.equals(SOURCE_ANCESTOR_WORD_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION_ANNOTATION)) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, ancestorType); mapConstructionItem.put(MAPPING_VALUE_NUMBER, number); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_EXISTENCE); conditions.add(mapConstructionItem); } } /** * Adds the ancestor name. * * @param ancestorType the ancestor type * @param mappingToken the mapping token * @param type the type * @param distance the distance * @param prefix the prefix * @param filter the filter */ private void addAncestorName(String ancestorType, MtasParserMappingToken mappingToken, String type, String distance, String prefix, String filter) { if (ancestorType.equals(SOURCE_ANCESTOR_GROUP) || ancestorType.equals(SOURCE_ANCESTOR_GROUP_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_WORD) || ancestorType.equals(SOURCE_ANCESTOR_WORD_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION_ANNOTATION)) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, ancestorType); mapConstructionItem.put(MAPPING_VALUE_ANCESTOR, distance); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_NAME); mapConstructionItem.put(MAPPING_VALUE_PREFIX, prefix); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); if (type.equals(MAPPING_SUBTYPE_TOKEN_PRE)) { mappingToken.preValues.add(mapConstructionItem); } else if (type.equals(MAPPING_SUBTYPE_TOKEN_POST)) { mappingToken.postValues.add(mapConstructionItem); } } } /** * Condition ancestor name. * * @param ancestorType the ancestor type * @param distance the distance * @param condition the condition * @param filter the filter * @param not the not */ public void conditionAncestorName(String ancestorType, String distance, String condition, String filter, String not) { if (ancestorType.equals(SOURCE_ANCESTOR_GROUP) || ancestorType.equals(SOURCE_ANCESTOR_GROUP_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_WORD) || ancestorType.equals(SOURCE_ANCESTOR_WORD_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION_ANNOTATION)) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, ancestorType); mapConstructionItem.put(MAPPING_VALUE_ANCESTOR, distance); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_NAME); mapConstructionItem.put(MAPPING_VALUE_CONDITION, condition); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); mapConstructionItem.put(MAPPING_VALUE_NOT, not); conditions.add(mapConstructionItem); } } /** * Adds the ancestor attribute. * * @param ancestorType the ancestor type * @param mappingToken the mapping token * @param type the type * @param distance the distance * @param name the name * @param prefix the prefix * @param filter the filter */ public void addAncestorAttribute(String ancestorType, MtasParserMappingToken mappingToken, String type, String distance, String name, String prefix, String filter) { if (ancestorType.equals(SOURCE_ANCESTOR_GROUP) || ancestorType.equals(SOURCE_ANCESTOR_GROUP_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_WORD) || ancestorType.equals(SOURCE_ANCESTOR_WORD_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION_ANNOTATION)) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, ancestorType); mapConstructionItem.put(MAPPING_VALUE_ANCESTOR, distance); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_ATTRIBUTE); mapConstructionItem.put(MAPPING_VALUE_NAME, name); mapConstructionItem.put(MAPPING_VALUE_PREFIX, prefix); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); if (name != null) { if (type.equals(MAPPING_SUBTYPE_TOKEN_PRE)) { mappingToken.preValues.add(mapConstructionItem); } else if (type.equals(MAPPING_SUBTYPE_TOKEN_POST)) { mappingToken.postValues.add(mapConstructionItem); } } } } /** * Condition ancestor attribute. * * @param ancestorType the ancestor type * @param distance the distance * @param name the name * @param condition the condition * @param filter the filter * @param not the not */ public void conditionAncestorAttribute(String ancestorType, String distance, String name, String condition, String filter, String not) { if (ancestorType.equals(SOURCE_ANCESTOR_GROUP) || ancestorType.equals(SOURCE_ANCESTOR_GROUP_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_WORD) || ancestorType.equals(SOURCE_ANCESTOR_WORD_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION_ANNOTATION)) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, ancestorType); mapConstructionItem.put(MAPPING_VALUE_ANCESTOR, distance); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_ATTRIBUTE); mapConstructionItem.put(MAPPING_VALUE_NAME, name); mapConstructionItem.put(MAPPING_VALUE_CONDITION, condition); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); mapConstructionItem.put(MAPPING_VALUE_NOT, not); if (name != null) { conditions.add(mapConstructionItem); } } } /** * Payload ancestor attribute. * * @param mappingToken the mapping token * @param ancestorType the ancestor type * @param distance the distance * @param name the name * @param filter the filter */ private void payloadAncestorAttribute(MtasParserMappingToken mappingToken, String ancestorType, String distance, String name, String filter) { if (ancestorType.equals(SOURCE_ANCESTOR_GROUP) || ancestorType.equals(SOURCE_ANCESTOR_GROUP_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_WORD) || ancestorType.equals(SOURCE_ANCESTOR_WORD_ANNOTATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION) || ancestorType.equals(SOURCE_ANCESTOR_RELATION_ANNOTATION)) { HashMap<String, String> mapConstructionItem = new HashMap<>(); mapConstructionItem.put(MAPPING_VALUE_SOURCE, ancestorType); mapConstructionItem.put(MAPPING_VALUE_ANCESTOR, distance); mapConstructionItem.put(MAPPING_VALUE_TYPE, PARSER_TYPE_ATTRIBUTE); mapConstructionItem.put(MAPPING_VALUE_NAME, name); mapConstructionItem.put(MAPPING_VALUE_FILTER, filter); if (name != null) { mappingToken.payload.add(mapConstructionItem); } } } /** * Compute ancestor source type. * * @param type the type * @return the string * @throws MtasConfigException the mtas config exception */ private String computeAncestorSourceType(String type) throws MtasConfigException { if (type.equals(MAPPING_TYPE_GROUP)) { return SOURCE_ANCESTOR_GROUP; } else if (type.equals(MAPPING_TYPE_GROUP_ANNOTATION)) { return SOURCE_ANCESTOR_GROUP_ANNOTATION; } else if (type.equals(MAPPING_TYPE_WORD)) { return SOURCE_ANCESTOR_WORD; } else if (type.equals(MAPPING_TYPE_WORD_ANNOTATION)) { return SOURCE_ANCESTOR_WORD_ANNOTATION; } else if (type.equals(MAPPING_TYPE_RELATION)) { return SOURCE_ANCESTOR_RELATION; } else if (type.equals(MAPPING_TYPE_RELATION_ANNOTATION)) { return SOURCE_ANCESTOR_RELATION_ANNOTATION; } else { throw new MtasConfigException("unknown type " + type); } } /** * Compute distance. * * @param distance the distance * @return the string */ private String computeDistance(String distance) { Integer i = 0; if (distance != null) { Integer d = Integer.parseInt(distance); if ((d != null) && (d >= i)) { return distance; } else { return i.toString(); } } return null; } /** * Compute number. * * @param number the number * @return the string */ private String computeNumber(String number) { return computeDistance(number); } /** * Gets the tokens. * * @return the tokens */ public List<MtasParserMappingToken> getTokens() { return tokens; } /** * Gets the conditions. * * @return the conditions */ public List<Map<String, String>> getConditions() { return conditions; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("mapping - type:" + type + ", offset:" + offset + ", realOffset:" + realOffset + ", position:" + position); for (int i = 0; i < conditions.size(); i++) { builder.append("\n\tcondition " + i + ": "); for (Entry<String, String> entry : conditions.get(i).entrySet()) { builder.append(entry.getKey() + ":" + entry.getValue() + ","); } } for (int i = 0; i < tokens.size(); i++) { builder.append("\n\ttoken " + i); builder.append(" - " + tokens.get(i).type); builder.append(" [offset:" + tokens.get(i).offset); builder.append(",realoffset:" + tokens.get(i).realoffset); builder.append(",parent:" + tokens.get(i).parent + "]"); for (int j = 0; j < tokens.get(i).preValues.size(); j++) { builder.append("\n\t- pre " + j + ": "); for (Entry<String, String> entry : tokens.get(i).preValues.get(j) .entrySet()) { builder.append(entry.getKey() + ":" + entry.getValue() + ","); } } for (int j = 0; j < tokens.get(i).postValues.size(); j++) { builder.append("\n\t- post " + j + ": "); for (Entry<String, String> entry : tokens.get(i).postValues.get(j) .entrySet()) { builder.append(entry.getKey() + ":" + entry.getValue() + ","); } } for (int j = 0; j < tokens.get(i).payload.size(); j++) { builder.append("\n\t- payload " + j + ": "); for (Entry<String, String> entry : tokens.get(i).payload.get(j) .entrySet()) { builder.append(entry.getKey() + ":" + entry.getValue() + ","); } } } return builder.toString(); } } /** * The Class MtasParserObject. */ protected class MtasParserObject { /** The object type. */ MtasParserType objectType; /** The object real offset start. */ private Integer objectRealOffsetStart = null; /** The object real offset end. */ private Integer objectRealOffsetEnd = null; /** The object offset start. */ private Integer objectOffsetStart = null; /** The object offset end. */ private Integer objectOffsetEnd = null; /** The object text. */ private String objectText = null; /** The object id. */ protected String objectId = null; /** The object unknown ancestor number. */ private Integer objectUnknownAncestorNumber = null; /** The object attributes. */ protected HashMap<String, String> objectAttributes = null; /** The other object attributes. */ protected HashMap<String, HashMap<String, String>> objectOtherAttributes = null; /** The object positions. */ private SortedSet<Integer> objectPositions = new TreeSet<>(); /** The ref ids. */ private Set<String> refIds = new HashSet<>(); /** The updateable mappings as parent. */ private Set<Integer> updateableMappingsAsParent = new HashSet<>(); /** The updateable ids with position. */ private Set<String> updateableIdsWithPosition = new HashSet<>(); /** The updateable mappings with position. */ protected Set<Integer> updateableMappingsWithPosition = new HashSet<>(); /** The updateable ids with offset. */ private Set<String> updateableIdsWithOffset = new HashSet<>(); /** The updateable mappings with offset. */ protected Set<Integer> updateableMappingsWithOffset = new HashSet<>(); /** The referred start position. */ protected Map<String, Integer> referredStartPosition = new HashMap<>(); /** The referred end position. */ protected Map<String, Integer> referredEndPosition = new HashMap<>(); /** The referred start offset. */ protected Map<String, Integer> referredStartOffset = new HashMap<>(); /** The referred end offset. */ protected Map<String, Integer> referredEndOffset = new HashMap<>(); /** * Instantiates a new mtas parser object. * * @param type the type */ MtasParserObject(MtasParserType type) { objectType = type; objectAttributes = new HashMap<>(); objectOtherAttributes = new HashMap<>(); } /** * Register updateable mapping at parent. * * @param mappingId the mapping id */ public void registerUpdateableMappingAtParent(Integer mappingId) { updateableMappingsAsParent.add(mappingId); } /** * Register updateable mappings at parent. * * @param mappingIds the mapping ids */ public void registerUpdateableMappingsAtParent(Set<Integer> mappingIds) { updateableMappingsAsParent.addAll(mappingIds); } /** * Gets the updateable mappings as parent. * * @return the updateable mappings as parent */ public Set<Integer> getUpdateableMappingsAsParent() { return updateableMappingsAsParent; } /** * Reset updateable mappings as parent. */ public void resetUpdateableMappingsAsParent() { updateableMappingsAsParent.clear(); } /** * Adds the updateable mapping with position. * * @param mappingId the mapping id */ public void addUpdateableMappingWithPosition(Integer mappingId) { updateableMappingsWithPosition.add(mappingId); } /** * Adds the updateable id with offset. * * @param id the id */ public void addUpdateableIdWithOffset(String id) { updateableIdsWithOffset.add(id); } /** * Adds the updateable mapping with offset. * * @param mappingId the mapping id */ public void addUpdateableMappingWithOffset(Integer mappingId) { updateableMappingsWithOffset.add(mappingId); } /** * Update mappings. * * @param idPositions the id positions * @param idOffsets the id offsets */ public void updateMappings(Map<String, Set<Integer>> idPositions, Map<String, Integer[]> idOffsets) { for (Integer mappingId : updateableMappingsWithPosition) { tokenCollection.get(mappingId).addPositions(objectPositions); } for (Integer mappingId : updateableMappingsWithOffset) { tokenCollection.get(mappingId).addOffset(objectOffsetStart, objectOffsetEnd); } for (String id : updateableIdsWithPosition) { if (idPositions.containsKey(id)) { if (idPositions.get(id) == null) { idPositions.put(id, objectPositions); } else { idPositions.get(id).addAll(objectPositions); } } } for (String id : updateableIdsWithOffset) { if (idOffsets.containsKey(id)) { Integer[] currentOffset = idOffsets.get(id); if (currentOffset == null || currentOffset.length == 0) { idOffsets.put(id, new Integer[] { objectOffsetStart, objectOffsetEnd }); } } } } /** * Gets the attribute. * * @param name the name * @return the attribute */ public String getAttribute(String name) { if (name != null) { return objectAttributes.get(name); } else { return null; } } public String getOtherAttribute(String other, String name) { if(other==null) { return getAttribute(name); } else { if(objectOtherAttributes.containsKey(other)) { if (name != null) { return objectOtherAttributes.get(other).get(name); } else { return null; } } else { return null; } } } /** * Gets the id. * * @return the id */ public String getId() { return objectId; } /** * Gets the type. * * @return the type */ MtasParserType getType() { return objectType; } /** * Sets the text. * * @param text the new text */ public void setText(String text) { objectText = text; } /** * Adds the text. * * @param text the text */ public void addText(String text) { if (objectText == null) { objectText = text; } else { objectText += text; } } /** * Gets the text. * * @return the text */ public String getText() { return objectText; } /** * Sets the unknown ancestor number. * * @param i the new unknown ancestor number */ public void setUnknownAncestorNumber(Integer i) { objectUnknownAncestorNumber = i; } /** * Gets the unknown ancestor number. * * @return the unknown ancestor number */ public Integer getUnknownAncestorNumber() { return objectUnknownAncestorNumber; } /** * Sets the real offset start. * * @param start the new real offset start */ public void setRealOffsetStart(Integer start) { objectRealOffsetStart = start; } /** * Gets the real offset start. * * @return the real offset start */ public Integer getRealOffsetStart() { return objectRealOffsetStart; } /** * Sets the real offset end. * * @param end the new real offset end */ public void setRealOffsetEnd(Integer end) { objectRealOffsetEnd = end; } /** * Gets the real offset end. * * @return the real offset end */ public Integer getRealOffsetEnd() { return objectRealOffsetEnd; } /** * Sets the offset start. * * @param start the new offset start */ public void setOffsetStart(Integer start) { objectOffsetStart = start; } /** * Adds the offset start. * * @param start the start */ public void addOffsetStart(Integer start) { if ((start != null) && ((objectOffsetStart == null) || (start < objectOffsetStart))) { objectOffsetStart = start; } } /** * Adds the offset end. * * @param end the end */ public void addOffsetEnd(Integer end) { if ((end != null) && ((objectOffsetEnd == null) || (end > objectOffsetEnd))) { objectOffsetEnd = end; } } /** * Gets the offset start. * * @return the offset start */ public Integer getOffsetStart() { return objectOffsetStart; } /** * Sets the offset end. * * @param end the new offset end */ public void setOffsetEnd(Integer end) { objectOffsetEnd = end; } /** * Gets the offset end. * * @return the offset end */ public Integer getOffsetEnd() { return objectOffsetEnd; } /** * Gets the offset. * * @return the offset */ public Integer[] getOffset() { if (objectOffsetStart != null) { return new Integer[] { objectOffsetStart, objectOffsetEnd }; } else { return new Integer[0]; } } /** * Adds the position. * * @param position the position */ public void addPosition(Integer position) { objectPositions.add(position); } /** * Adds the positions. * * @param positions the positions */ public void addPositions(Set<Integer> positions) { objectPositions.addAll(positions); } /** * Gets the positions. * * @return the positions */ public SortedSet<Integer> getPositions() { return objectPositions; } /** * Adds the ref id. * * @param id the id */ public void addRefId(String id) { if (id != null) { refIds.add(id); } } /** * Gets the ref ids. * * @return the ref ids */ public Set<String> getRefIds() { return refIds; } /** * Sets the referred start position. * * @param id the id * @param position the position */ public void setReferredStartPosition(String id, Integer position) { referredStartPosition.put(id, position); } /** * Sets the referred end position. * * @param id the id * @param position the position */ public void setReferredEndPosition(String id, Integer position) { referredEndPosition.put(id, position); } /** * Sets the referred start offset. * * @param id the id * @param offset the offset */ public void setReferredStartOffset(String id, Integer offset) { referredStartOffset.put(id, offset); } /** * Sets the referred end offset. * * @param id the id * @param offset the offset */ public void setReferredEndOffset(String id, Integer offset) { referredEndOffset.put(id, offset); } /** * Clear referred. */ public void clearReferred() { referredStartPosition.clear(); referredEndPosition.clear(); referredStartOffset.clear(); referredEndOffset.clear(); } } }