/** * Returns the annotations to which should be displayed together with their namespace. * * <p>This will check the "show_ns" paramter for determining. the annotations to display. It also * iterates over all nodes of the graph matching the type. * * @param input The input for the visualizer. * @param types Which types of nodes to include * @return */ public static Set<String> computeDisplayedNamespace( VisualizerInput input, List<Class<? extends SNode>> types) { if (input == null) { return new HashSet<>(); } String showNamespaceConfig = input.getMappings().getProperty(GridComponent.MAPPING_SHOW_NAMESPACE); if (showNamespaceConfig != null) { SDocumentGraph graph = input.getDocument().getDocumentGraph(); Set<String> annoPool = new LinkedHashSet<>(); for (Class<? extends SNode> t : types) { annoPool.addAll( SToken.class.isAssignableFrom(t) ? getAnnotationLevelSet(graph, null, t) : getAnnotationLevelSet(graph, input.getNamespace(), t)); } if ("true".equalsIgnoreCase(showNamespaceConfig)) { // all annotations should be displayed with a namespace return annoPool; } else if ("false".equalsIgnoreCase(showNamespaceConfig)) { return new LinkedHashSet<>(); } else { Set<String> annos = new LinkedHashSet<>(); List<String> defs = Splitter.on(',').omitEmptyStrings().trimResults().splitToList(showNamespaceConfig); for (String s : defs) { // is regular expression? if (s.startsWith("/") && s.endsWith("/")) { // go over all remaining items in our pool of all annotations and // check if they match Pattern regex = Pattern.compile(StringUtils.strip(s, "/")); LinkedList<String> matchingAnnos = new LinkedList<>(); for (String a : annoPool) { if (regex.matcher(a).matches()) { matchingAnnos.add(a); } } annos.addAll(matchingAnnos); annoPool.removeAll(matchingAnnos); } else { annos.add(s); annoPool.remove(s); } } return annos; } } return new LinkedHashSet<>(); }
/** * Converts Salt document graph to rows. * * @param input * @param showSpanAnnos * @param showTokenAnnos * @param mediaLayer A set of all annotation layers which should be treated as special media * layer. * @param annotationNames * @param replaceValueWithMediaIcon If true the actual value is removed and an icon for playing * the media file is shown instead. * @param startTokenIndex token index of the first token in the match * @param endTokenIndex token index of the last token in the match * @param pdfController makes status of all pdfviewer available for the events. * @param text If non-null only include annotations for nodes of the specified text. * @return */ public static LinkedHashMap<String, ArrayList<Row>> parseSalt( VisualizerInput input, boolean showSpanAnnos, boolean showTokenAnnos, List<String> annotationNames, Set<String> mediaLayer, boolean replaceValueWithMediaIcon, long startTokenIndex, long endTokenIndex, PDFController pdfController, STextualDS text) { SDocumentGraph graph = input.getDocument().getDocumentGraph(); // only look at annotations which were defined by the user LinkedHashMap<String, ArrayList<Row>> rowsByAnnotation = new LinkedHashMap<>(); for (String anno : annotationNames) { rowsByAnnotation.put(anno, new ArrayList<Row>()); } AtomicInteger eventCounter = new AtomicInteger(); PDFPageHelper pageNumberHelper = new PDFPageHelper(input); if (showSpanAnnos) { for (SSpan span : graph.getSpans()) { if (text == null || text == CommonHelper.getTextualDSForNode(span, graph)) { addAnnotationsForNode( span, graph, startTokenIndex, endTokenIndex, pdfController, pageNumberHelper, eventCounter, rowsByAnnotation, true, mediaLayer, replaceValueWithMediaIcon); } } // end for each span } if (showTokenAnnos) { for (SToken tok : graph.getTokens()) { if (text == null || text == CommonHelper.getTextualDSForNode(tok, graph)) { addAnnotationsForNode( tok, graph, startTokenIndex, endTokenIndex, pdfController, pageNumberHelper, eventCounter, rowsByAnnotation, false, mediaLayer, replaceValueWithMediaIcon); } } } // 2. merge rows when possible for (Map.Entry<String, ArrayList<Row>> e : rowsByAnnotation.entrySet()) { mergeAllRowsIfPossible(e.getValue()); } // 3. sort events on one row by left token index for (Map.Entry<String, ArrayList<Row>> e : rowsByAnnotation.entrySet()) { for (Row r : e.getValue()) { sortEventsByTokenIndex(r); } } // 4. split up events if they cover islands for (Map.Entry<String, ArrayList<Row>> e : rowsByAnnotation.entrySet()) { for (Row r : e.getValue()) { splitRowsOnIslands(r, graph, text, startTokenIndex, endTokenIndex); } } // 5. split up events if they have gaps for (Map.Entry<String, ArrayList<Row>> e : rowsByAnnotation.entrySet()) { for (Row r : e.getValue()) { splitRowsOnGaps(r, graph, startTokenIndex, endTokenIndex); } } return rowsByAnnotation; }
/** * Returns the annotations to display according to the mappings configuration. * * <p>This will check the "annos" and "annos_regex" paramters for determining. the annotations to * display. It also iterates over all nodes of the graph matching the type. * * @param input The input for the visualizer. * @param type Which type of nodes to include * @return */ public static List<String> computeDisplayAnnotations( VisualizerInput input, Class<? extends SNode> type) { if (input == null) { return new LinkedList<>(); } SDocumentGraph graph = input.getDocument().getDocumentGraph(); Set<String> annoPool = SToken.class.isAssignableFrom(type) ? getAnnotationLevelSet(graph, null, type) : getAnnotationLevelSet(graph, input.getNamespace(), type); List<String> annos = new LinkedList<>(annoPool); String annosConfiguration = input.getMappings().getProperty(MAPPING_ANNOS_KEY); if (annosConfiguration != null && annosConfiguration.trim().length() > 0) { String[] split = annosConfiguration.split(","); annos.clear(); for (String s : split) { s = s.trim(); // is regular expression? if (s.startsWith("/") && s.endsWith("/")) { // go over all remaining items in our pool of all annotations and // check if they match Pattern regex = Pattern.compile(StringUtils.strip(s, "/")); LinkedList<String> matchingAnnos = new LinkedList<>(); for (String a : annoPool) { if (regex.matcher(a).matches()) { matchingAnnos.add(a); } } annos.addAll(matchingAnnos); annoPool.removeAll(matchingAnnos); } else { annos.add(s); annoPool.remove(s); } } } // filter already found annotation names by regular expression // if this was given as mapping String regexFilterRaw = input.getMappings().getProperty(MAPPING_ANNO_REGEX_KEY); if (regexFilterRaw != null) { try { Pattern regexFilter = Pattern.compile(regexFilterRaw); ListIterator<String> itAnnos = annos.listIterator(); while (itAnnos.hasNext()) { String a = itAnnos.next(); // remove entry if not matching if (!regexFilter.matcher(a).matches()) { itAnnos.remove(); } } } catch (PatternSyntaxException ex) { log.warn("invalid regular expression in mapping for grid visualizer", ex); } } return annos; }