/** Get the link following the current link. */ private AnnotationFS getNextLink(AnnotationFS aLink) { return (AnnotationFS) aLink.getFeatureValue(aLink.getType().getFeatureByBaseName(linkNextFeatureName)); }
/** * Add annotations from the CAS, which is controlled by the window size, to the brat response * {@link GetDocumentResponse} * * @param aJcas The JCAS object containing annotations * @param aResponse A brat response containing annotations in brat protocol * @param aBratAnnotatorModel Data model for brat annotations * @param aColoringStrategy the coloring strategy to render this layer (ignored) */ @Override public void render( JCas aJcas, List<AnnotationFeature> aFeatures, GetDocumentResponse aResponse, BratAnnotatorModel aBratAnnotatorModel, ColoringStrategy aColoringStrategy) { // Get begin and end offsets of window content int windowBegin = BratAjaxCasUtil.selectByAddr( aJcas, Sentence.class, aBratAnnotatorModel.getSentenceAddress()) .getBegin(); int windowEnd = BratAjaxCasUtil.selectByAddr( aJcas, Sentence.class, BratAjaxCasUtil.getLastSentenceAddressInDisplayWindow( aJcas, aBratAnnotatorModel.getSentenceAddress(), aBratAnnotatorModel.getPreferences().getWindowSize())) .getEnd(); // Find the features for the arc and span labels - it is possible that we do not find a // feature for arc/span labels because they may have been disabled. AnnotationFeature spanLabelFeature = null; AnnotationFeature arcLabelFeature = null; for (AnnotationFeature f : aFeatures) { if (WebAnnoConst.COREFERENCE_TYPE_FEATURE.equals(f.getName())) { spanLabelFeature = f; } if (WebAnnoConst.COREFERENCE_RELATION_FEATURE.equals(f.getName())) { arcLabelFeature = f; } } // At this point arc and span feature labels must have been found! If not, the later code // will crash. Type chainType = getAnnotationType(aJcas.getCas()); Feature chainFirst = chainType.getFeatureByBaseName(chainFirstFeatureName); int colorIndex = 0; // Iterate over the chains for (FeatureStructure chainFs : selectFS(aJcas.getCas(), chainType)) { AnnotationFS linkFs = (AnnotationFS) chainFs.getFeatureValue(chainFirst); AnnotationFS prevLinkFs = null; // Every chain is supposed to have a different color String color = ColoringStrategy.PALETTE_NORMAL_FILTERED[ colorIndex % ColoringStrategy.PALETTE_NORMAL_FILTERED.length]; // The color index is updated even for chains that have no visible links in the current // window because we would like the chain color to be independent of visibility. In // particular the color of a chain should not change when switching pages/scrolling. colorIndex++; // Iterate over the links of the chain while (linkFs != null) { Feature linkNext = linkFs.getType().getFeatureByBaseName(linkNextFeatureName); AnnotationFS nextLinkFs = (AnnotationFS) linkFs.getFeatureValue(linkNext); // Is link after window? If yes, we can skip the rest of the chain if (linkFs.getBegin() >= windowEnd) { break; // Go to next chain } // Is link before window? We only need links that being within the window and that // end within the window if (!(linkFs.getBegin() >= windowBegin) && (linkFs.getEnd() <= windowEnd)) { // prevLinkFs remains null until we enter the window linkFs = nextLinkFs; continue; // Go to next link } String bratTypeName = TypeUtil.getBratTypeName(this); // Render span { String bratLabelText = TypeUtil.getBratLabelText( this, linkFs, (spanLabelFeature != null) ? asList(spanLabelFeature) : Collections.EMPTY_LIST); Offsets offsets = new Offsets(linkFs.getBegin() - windowBegin, linkFs.getEnd() - windowBegin); aResponse.addEntity( new Entity( BratAjaxCasUtil.getAddr(linkFs), bratTypeName, offsets, bratLabelText, color)); } // Render arc (we do this on prevLinkFs because then we easily know that the current // and last link are within the window ;) if (prevLinkFs != null) { String bratLabelText = null; if (linkedListBehavior && arcLabelFeature != null) { // Render arc label bratLabelText = TypeUtil.getBratLabelText(this, prevLinkFs, asList(arcLabelFeature)); } else { // Render only chain type bratLabelText = TypeUtil.getBratLabelText(this, prevLinkFs, Collections.EMPTY_LIST); } List<Argument> argumentList = asList( new Argument("Arg1", BratAjaxCasUtil.getAddr(prevLinkFs)), new Argument("Arg2", BratAjaxCasUtil.getAddr(linkFs))); aResponse.addRelation( new Relation( BratAjaxCasUtil.getAddr(prevLinkFs), bratTypeName, argumentList, bratLabelText, color)); } // if (BratAjaxCasUtil.isSame(linkFs, nextLinkFs)) { // log.error("Loop in CAS detected, aborting rendering of chains"); // break; // } prevLinkFs = linkFs; linkFs = nextLinkFs; } } }