private JCas createCorrectionCas( JCas mergeJCas, BratAnnotatorModel aBratAnnotatorModel, AnnotationDocument randomAnnotationDocument) throws UIMAException, ClassNotFoundException, IOException { User userLoggedIn = userRepository.get(SecurityContextHolder.getContext().getAuthentication().getName()); mergeJCas = repository.readAnnotationCas(aBratAnnotatorModel.getDocument(), userLoggedIn); repository.writeCorrectionCas(mergeJCas, randomAnnotationDocument.getDocument(), userLoggedIn); return mergeJCas; }
private void update(AjaxRequestTarget target) { JCas jCas = null; try { CuratorUtil.updatePanel( target, automateView, curationContainer, mergeVisualizer, repository, annotationSelectionByUsernameAndAddress, curationSegment, annotationService, userRepository); jCas = repository.readCorrectionCas(bModel.getDocument()); } catch (UIMAException e) { error(ExceptionUtils.getRootCauseMessage(e)); } catch (ClassNotFoundException e) { error(e.getMessage()); } catch (IOException e) { error(e.getMessage()); } catch (BratAnnotationException e) { error(e.getMessage()); } gotoPageTextField.setModelObject(getFirstSentenceNumber(jCas, bModel.getSentenceAddress()) + 1); gotoPageAddress = getSentenceAddress(jCas, gotoPageTextField.getModelObject()); target.add(gotoPageTextField); target.add(automateView); target.add(numberOfPages); }
public Map<String, JCas> listJcasesforCuration( List<AnnotationDocument> annotationDocuments, AnnotationDocument randomAnnotationDocument, Mode aMode) throws UIMAException, ClassNotFoundException, IOException { Map<String, JCas> jCases = new HashMap<String, JCas>(); for (AnnotationDocument annotationDocument : annotationDocuments) { String username = annotationDocument.getUser(); if (!annotationDocument.getState().equals(AnnotationDocumentState.FINISHED)) { continue; } if (randomAnnotationDocument == null) { randomAnnotationDocument = annotationDocument; } // Upgrading should be an explicit action during the opening of a document at the end // of the open dialog - it must not happen during editing because the CAS addresses // are used as IDs in the UI // repository.upgradeCasAndSave(annotationDocument.getDocument(), aMode, username); JCas jCas = repository.readAnnotationCas(annotationDocument); jCases.put(username, jCas); } return jCases; }
public Map<String, JCas> listJcasesforCorrection( AnnotationDocument randomAnnotationDocument, SourceDocument aDocument, Mode aMode) throws UIMAException, ClassNotFoundException, IOException { Map<String, JCas> jCases = new HashMap<String, JCas>(); User user = userRepository.get(SecurityContextHolder.getContext().getAuthentication().getName()); randomAnnotationDocument = repository.getAnnotationDocument(aDocument, user); // Upgrading should be an explicit action during the opening of a document at the end // of the open dialog - it must not happen during editing because the CAS addresses // are used as IDs in the UI // repository.upgradeCasAndSave(aDocument, aMode, user.getUsername()); JCas jCas = repository.readAnnotationCas(randomAnnotationDocument); jCases.put(user.getUsername(), jCas); return jCases; }
public void updatePanel(AjaxRequestTarget aTarget, CurationContainer aCC) throws UIMAException, ClassNotFoundException, IOException, BratAnnotationException { JCas jCas = repository.readCurationCas(bModel.getDocument()); final int sentenceAddress = getAddr( selectSentenceAt(jCas, bModel.getSentenceBeginOffset(), bModel.getSentenceEndOffset())); bModel.setSentenceAddress(sentenceAddress); final Sentence sentence = selectByAddr(jCas, Sentence.class, sentenceAddress); List<Sentence> followingSentences = selectFollowing(jCas, Sentence.class, sentence, bModel.getPreferences().getWindowSize()); // Check also, when getting the last sentence address in the display window, if this is the // last sentence or the ONLY sentence in the document Sentence lastSentenceAddressInDisplayWindow = followingSentences.size() == 0 ? sentence : followingSentences.get(followingSentences.size() - 1); if (curationView == null) { curationView = new SourceListView(); } curationView.setCurationBegin(sentence.getBegin()); curationView.setCurationEnd(lastSentenceAddressInDisplayWindow.getEnd()); int ws = bModel.getPreferences().getWindowSize(); Sentence fs = BratAjaxCasUtil.selectSentenceAt( jCas, bModel.getSentenceBeginOffset(), bModel.getSentenceEndOffset()); int l = BratAjaxCasUtil.getLastSentenceAddressInDisplayWindow(jCas, getAddr(fs), ws); Sentence ls = (Sentence) selectByAddr(jCas, FeatureStructure.class, l); fSn = BratAjaxCasUtil.getSentenceNumber(jCas, fs.getBegin()); lSn = BratAjaxCasUtil.getSentenceNumber(jCas, ls.getBegin()); sentencesListView.addOrReplace(sentenceList); aTarget.add(sentencesListView); /* * corssSentAnnoView.addOrReplace(crossSentAnnoList); aTarget.add(corssSentAnnoView); */ aTarget.add(suggestionViewPanel); if (annotate) { annotator.bratRender(aTarget, editor.getCas(bModel)); annotator.bratSetHighlight(aTarget, bModel.getSelection().getAnnotation()); } else { annotator.bratRenderLater(aTarget); } annotate = false; CuratorUtil.updatePanel( aTarget, suggestionViewPanel, aCC, annotator, repository, annotationSelectionByUsernameAndAddress, curationView, annotationService, userRepository); }
/** * Fetches the CAS that the user will be able to edit. In AUTOMATION/CORRECTION mode, this is the * CAS for the CORRECTION_USER and in CURATION mode it is the CAS for the CURATION user. * * @param aBratAnnotatorModel the model. * @param aDocument the source document. * @param jCases the JCases. * @param randomAnnotationDocument an annotation document. * @return the JCas. * @throws UIMAException hum? * @throws ClassNotFoundException hum? * @throws IOException if an I/O error occurs. * @throws BratAnnotationException hum? */ public JCas getMergeCas( BratAnnotatorModel aBratAnnotatorModel, SourceDocument aDocument, Map<String, JCas> jCases, AnnotationDocument randomAnnotationDocument) throws UIMAException, ClassNotFoundException, IOException, BratAnnotationException { JCas mergeJCas = null; try { if (aBratAnnotatorModel.getMode().equals(Mode.AUTOMATION) || aBratAnnotatorModel.getMode().equals(Mode.CORRECTION)) { // Upgrading should be an explicit action during the opening of a document at the // end // of the open dialog - it must not happen during editing because the CAS addresses // are used as IDs in the UI // repository.upgradeCasAndSave(aDocument, aBratAnnotatorModel.getMode(), // aBratAnnotatorModel.getUser().getUsername()); mergeJCas = repository.readCorrectionCas(aDocument); } else { // Upgrading should be an explicit action during the opening of a document at the // end // of the open dialog - it must not happen during editing because the CAS addresses // are used as IDs in the UI // repository.upgradeCasAndSave(aDocument, aBratAnnotatorModel.getMode(), // aBratAnnotatorModel.getUser().getUsername()); mergeJCas = repository.readCurationCas(aDocument); } } // Create jcas, if it could not be loaded from the file system catch (Exception e) { if (aBratAnnotatorModel.getMode().equals(Mode.AUTOMATION) || aBratAnnotatorModel.getMode().equals(Mode.CORRECTION)) { mergeJCas = createCorrectionCas(mergeJCas, aBratAnnotatorModel, randomAnnotationDocument); } else { mergeJCas = createCurationCas( aBratAnnotatorModel.getProject(), randomAnnotationDocument, jCases, aBratAnnotatorModel.getAnnotationLayers()); } } return mergeJCas; }
/** * Set annotation preferences of users for a given project such as window size, annotation * layers,... reading from the file system. * * @param aUsername The {@link User} for whom we need to read the preference (preferences are * stored per user) * @param aRepositoryService the repository service. * @param aAnnotationService the annotation service. * @param aBModel The {@link BratAnnotatorModel} that will be populated with preferences from the * file * @param aMode the mode. * @throws BeansException hum? * @throws IOException hum? */ public static void setAnnotationPreference( String aUsername, RepositoryService aRepositoryService, AnnotationService aAnnotationService, BratAnnotatorModel aBModel, Mode aMode) throws BeansException, IOException { AnnotationPreference preference = new AnnotationPreference(); BeanWrapper wrapper = new BeanWrapperImpl(preference); // get annotation preference from file system try { Properties props = aRepositoryService.loadUserSettings(aUsername, aBModel.getProject()); for (Entry<Object, Object> entry : props.entrySet()) { String property = entry.getKey().toString(); int index = property.lastIndexOf("."); String propertyName = property.substring(index + 1); String mode = property.substring(0, index); if (wrapper.isWritableProperty(propertyName) && mode.equals(aMode.getName())) { if (AnnotationPreference.class.getDeclaredField(propertyName).getGenericType() instanceof ParameterizedType) { List<String> value = Arrays.asList( StringUtils.replaceChars(entry.getValue().toString(), "[]", "").split(",")); if (!value.get(0).equals("")) { wrapper.setPropertyValue(propertyName, value); } } else { wrapper.setPropertyValue(propertyName, entry.getValue()); } } } aBModel.setPreferences(preference); // Get tagset using the id, from the properties file aBModel.getAnnotationLayers().clear(); if (preference.getAnnotationLayers() != null) { for (Long id : preference.getAnnotationLayers()) { aBModel.getAnnotationLayers().add(aAnnotationService.getLayer(id)); } } else { // If no layer preferences are defined, then just assume all layers are enabled List<AnnotationLayer> layers = aAnnotationService.listAnnotationLayer(aBModel.getProject()); aBModel.setAnnotationLayers(layers); } } // no preference found catch (Exception e) { // If no layer preferences are defined, then just assume all layers are enabled List<AnnotationLayer> layers = aAnnotationService.listAnnotationLayer(aBModel.getProject()); aBModel.setAnnotationLayers(layers); } }
public static void savePreference(BratAnnotatorModel aBModel, RepositoryService aRepository) throws FileNotFoundException, IOException { AnnotationPreference preference = aBModel.getPreferences(); ArrayList<Long> layers = new ArrayList<Long>(); for (AnnotationLayer layer : aBModel.getAnnotationLayers()) { layers.add(layer.getId()); } preference.setAnnotationLayers(layers); String username = SecurityContextHolder.getContext().getAuthentication().getName(); aRepository.saveUserSettings(username, aBModel.getProject(), aBModel.getMode(), preference); }
/** * For the first time a curation page is opened, create a MergeCas that contains only agreeing * annotations Using the CAS of the curator user. * * @param aProject the project * @param randomAnnotationDocument an annotation document. * @param jCases the JCases * @param aAnnotationLayers the layers. * @return the JCas. * @throws IOException if an I/O error occurs. */ public JCas createCurationCas( Project aProject, AnnotationDocument randomAnnotationDocument, Map<String, JCas> jCases, List<AnnotationLayer> aAnnotationLayers) throws IOException { User userLoggedIn = userRepository.get(SecurityContextHolder.getContext().getAuthentication().getName()); JCas mergeJCas = repository.readAnnotationCas(randomAnnotationDocument); jCases.put(CurationPanel.CURATION_USER, mergeJCas); List<Type> entryTypes = getEntryTypes(mergeJCas, aAnnotationLayers, annotationService); DiffResult diff = CasDiff2.doDiffSingle( annotationService, aProject, entryTypes, jCases, 0, mergeJCas.getDocumentText().length()); for (Entry<Position, ConfigurationSet> diffEntry : diff.getDifferingConfigurationSets().entrySet()) { // Remove FSes with differences from the merge CAS List<Configuration> cfgsForCurationUser = diffEntry.getValue().getConfigurations(CurationPanel.CURATION_USER); for (Configuration cfg : cfgsForCurationUser) { FeatureStructure fs = cfg.getFs(CurationPanel.CURATION_USER, jCases); mergeJCas.removeFsFromIndexes(fs); } } repository.writeCurationCas(mergeJCas, randomAnnotationDocument.getDocument(), userLoggedIn); return mergeJCas; }
private void addJCas(List<JCas> jCases, User user, SourceDocument sourceDocument) { try { // Check if there is an annotation document entry in the database. If there is none, // create one. AnnotationDocument annotationDocument = repository.createOrGetAnnotationDocument(sourceDocument, user); // Read the CAS JCas jcas = repository.readAnnotationCas(annotationDocument); // Update the annotation document CAS repository.upgradeCas(jcas.getCas(), annotationDocument); // After creating an new CAS or upgrading the CAS, we need to save it repository.writeAnnotationCas( jcas.getCas().getJCas(), annotationDocument.getDocument(), user); jCases.add(jcas); } catch (UIMAException e) { error(e.getMessage() + " : " + ExceptionUtils.getRootCauseMessage(e)); } catch (IOException e) { error(e.getMessage()); } }
private void setCurationSegmentBeginEnd() throws UIMAException, ClassNotFoundException, IOException { JCas jCas = repository.readAnnotationCas(bModel.getDocument(), bModel.getUser()); final int sentenceAddress = getAddr( selectSentenceAt(jCas, bModel.getSentenceBeginOffset(), bModel.getSentenceEndOffset())); final Sentence sentence = selectByAddr(jCas, Sentence.class, sentenceAddress); List<Sentence> followingSentences = selectFollowing(jCas, Sentence.class, sentence, bModel.getPreferences().getWindowSize()); // Check also, when getting the last sentence address in the display window, if this is the // last sentence or the ONLY sentence in the document Sentence lastSentenceAddressInDisplayWindow = followingSentences.size() == 0 ? sentence : followingSentences.get(followingSentences.size() - 1); curationSegment.setBegin(sentence.getBegin()); curationSegment.setEnd(lastSentenceAddressInDisplayWindow.getEnd()); }
@Override protected String getDocumentData() { if (!dirty) { return docData; } dirty = false; // Clear the rendered document docData = EMPTY_DOC; // Check if a document is set if (getModelObject() == null) { return docData; } // Get CAS from the repository JCas jCas = null; try { jCas = repository.readAnnotationCas(getModelObject()); } catch (IOException | DataRetrievalFailureException e) { LOG.error("Unable to read annotation document", e); error("Unable to read annotation document: " + ExceptionUtils.getRootCauseMessage(e)); } // Generate BRAT object model from CAS GetDocumentResponse response = new GetDocumentResponse(); response.setText(jCas.getDocumentText()); BratAnnotatorModel bratAnnotatorModel = new BratAnnotatorModel(); SpanAdapter.renderTokenAndSentence(jCas, response, bratAnnotatorModel); Map<String[], Queue<String>> colorQueues = new HashMap<>(); for (AnnotationLayer layer : bratAnnotatorModel.getAnnotationLayers()) { if (layer.getName().equals(Token.class.getName())) { continue; } List<AnnotationFeature> features = annotationService.listAnnotationFeature(layer); List<AnnotationFeature> invisibleFeatures = new ArrayList<AnnotationFeature>(); for (AnnotationFeature feature : features) { if (!feature.isVisible()) { invisibleFeatures.add(feature); } } features.removeAll(invisibleFeatures); ColoringStrategy coloringStrategy = ColoringStrategy.getBestStrategy( annotationService, layer, bratAnnotatorModel.getPreferences(), colorQueues); getAdapter(annotationService, layer) .render(jCas, features, response, bratAnnotatorModel, coloringStrategy); } // Serialize BRAT object model to JSON try { StringWriter out = new StringWriter(); JsonGenerator jsonGenerator = JSONUtil.getJsonConverter().getObjectMapper().getFactory().createGenerator(out); jsonGenerator.writeObject(response); docData = out.toString(); } catch (IOException e) { error(ExceptionUtils.getRootCauseMessage(e)); } return docData; }
private void loadDocumentAction() throws UIMAException, ClassNotFoundException, IOException, BratAnnotationException { String username = SecurityContextHolder.getContext().getAuthentication().getName(); User logedInUser = userRepository.get(SecurityContextHolder.getContext().getAuthentication().getName()); bModel.setUser(logedInUser); JCas jCas = null; try { AnnotationDocument logedInUserAnnotationDocument = repository.getAnnotationDocument(bModel.getDocument(), logedInUser); jCas = repository.readAnnotationCas(logedInUserAnnotationDocument); } catch (IOException e) { throw e; } // Get information to be populated to bratAnnotatorModel from the JCAS of the logged in user // catch (DataRetrievalFailureException e) { jCas = repository.readAnnotationCas(bModel.getDocument(), logedInUser); // This is the auto annotation, save it under CORRECTION_USER, Only if it is not created // by another annotater if (!repository.existsCorrectionCas(bModel.getDocument())) { repository.writeCorrectionCas(jCas, bModel.getDocument(), logedInUser); } } catch (NoResultException e) { jCas = repository.readAnnotationCas(bModel.getDocument(), logedInUser); // This is the auto annotation, save it under CORRECTION_USER, Only if it is not created // by another annotater if (!repository.existsCorrectionCas(bModel.getDocument())) { repository.writeCorrectionCas(jCas, bModel.getDocument(), logedInUser); } } // (Re)initialize brat model after potential creating / upgrading CAS bModel.initForDocument(jCas); // Load user preferences PreferencesUtil.setAnnotationPreference( username, repository, annotationService, bModel, Mode.AUTOMATION); // if project is changed, reset some project specific settings if (currentprojectId != bModel.getProject().getId()) { bModel.initForProject(); } currentprojectId = bModel.getProject().getId(); currentDocumentId = bModel.getDocument().getId(); LOG.debug( "Configured BratAnnotatorModel for user [" + bModel.getUser() + "] f:[" + bModel.getFirstSentenceAddress() + "] l:[" + bModel.getLastSentenceAddress() + "] s:[" + bModel.getSentenceAddress() + "]"); }
public CurationContainer buildCurationContainer(BratAnnotatorModel aBModel) throws UIMAException, ClassNotFoundException, IOException, BratAnnotationException { CurationContainer curationContainer = new CurationContainer(); // initialize Variables SourceDocument sourceDocument = aBModel.getDocument(); Map<Integer, Integer> segmentBeginEnd = new HashMap<Integer, Integer>(); Map<Integer, Integer> segmentNumber = new HashMap<Integer, Integer>(); Map<String, Map<Integer, Integer>> segmentAdress = new HashMap<String, Map<Integer, Integer>>(); // get annotation documents List<AnnotationDocument> finishedAnnotationDocuments = new ArrayList<AnnotationDocument>(); for (AnnotationDocument annotationDocument : repository.listAnnotationDocuments(aBModel.getDocument())) { if (annotationDocument.getState().equals(AnnotationDocumentState.FINISHED)) { finishedAnnotationDocuments.add(annotationDocument); } } Map<String, JCas> jCases = new HashMap<String, JCas>(); AnnotationDocument randomAnnotationDocument = null; JCas mergeJCas; // get the correction/automation JCas for the logged in user if (aBModel.getMode().equals(Mode.AUTOMATION) || aBModel.getMode().equals(Mode.CORRECTION)) { jCases = listJcasesforCorrection(randomAnnotationDocument, sourceDocument, aBModel.getMode()); mergeJCas = getMergeCas(aBModel, sourceDocument, jCases, randomAnnotationDocument); String username = jCases.keySet().iterator().next(); updateSegment( aBModel, segmentBeginEnd, segmentNumber, segmentAdress, jCases.get(username), username, aBModel.getPreferences().getWindowSize()); } else { jCases = listJcasesforCuration( finishedAnnotationDocuments, randomAnnotationDocument, aBModel.getMode()); mergeJCas = getMergeCas(aBModel, sourceDocument, jCases, randomAnnotationDocument); updateSegment( aBModel, segmentBeginEnd, segmentNumber, segmentAdress, mergeJCas, CurationPanel.CURATION_USER, aBModel.getPreferences().getCurationWindowSize()); } List<Type> entryTypes = null; segmentAdress.put(CurationPanel.CURATION_USER, new HashMap<Integer, Integer>()); for (Sentence sentence : selectCovered(mergeJCas, Sentence.class, begin, end)) { segmentAdress.get(CurationPanel.CURATION_USER).put(sentence.getBegin(), getAddr(sentence)); } if (entryTypes == null) { entryTypes = getEntryTypes(mergeJCas, aBModel.getAnnotationLayers(), annotationService); } // for cross-sentences annotation, update the end of the segment if (firstload) { updateCrossSentAnnoList(segmentBeginEnd, jCases, entryTypes); firstload = false; } for (Integer begin : segmentBeginEnd.keySet()) { Integer end = segmentBeginEnd.get(begin); DiffResult diff = CasDiff2.doDiffSingle( annotationService, aBModel.getProject(), entryTypes, jCases, begin, end); SourceListView curationSegment = new SourceListView(); curationSegment.setBegin(begin); curationSegment.setEnd(end); if (diff.hasDifferences() || !diff.getIncompleteConfigurationSets().isEmpty()) { curationSegment.setSentenceState(SentenceState.DISAGREE); } else { curationSegment.setSentenceState(SentenceState.AGREE); } curationSegment.setSentenceNumber(segmentNumber.get(begin)); for (String username : segmentAdress.keySet()) { curationSegment.getSentenceAddress().put(username, segmentAdress.get(username).get(begin)); } curationContainer.getCurationViewByBegin().put(begin, curationSegment); } return curationContainer; }