📄 notimegapwithinparent.java
字号:
/* * File: NoTimeGapWithinParent.java * Project: MPI Linguistic Application * Date: 02 May 2007 * * Copyright (C) 2001-2007 Max Planck Institute for Psycholinguistics * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package mpi.eudico.server.corpora.clomimpl.type;import mpi.eudico.server.corpora.clom.Annotation;import mpi.eudico.server.corpora.clom.Tier;import mpi.eudico.server.corpora.clom.TimeOrder;import mpi.eudico.server.corpora.clom.TimeSlot;import mpi.eudico.server.corpora.clomimpl.abstr.AlignableAnnotation;import mpi.eudico.server.corpora.clomimpl.abstr.SVGAlignableAnnotation;import mpi.eudico.server.corpora.clomimpl.abstr.TierImpl;import mpi.eudico.server.corpora.clomimpl.abstr.TimeSlotImpl;import mpi.eudico.server.corpora.clomimpl.abstr.TranscriptionImpl;import java.util.ArrayList;import java.util.Iterator;import java.util.Vector;/** * DOCUMENT ME! $Id: NoTimeGapWithinParent.java,v 1.9 2005/01/18 12:22:55 * hasloe Exp $ * * @author $Author: hasloe $ * @version $Revision: 1.16 $ */public class NoTimeGapWithinParent extends ConstraintImpl { /** * Creates a new NoTimeGapWithinParent instance */ public NoTimeGapWithinParent() { super(); } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public int getStereoType() { return Constraint.NO_GAP_WITHIN_PARENT; } /** * Creates new or finds existing TimeSlots for a new Annotation on a Tier. * New TimeSlots will be added to the Transcription's TimeOrder, existing * TimeSlots will be adjusted if needed. The Tier object should then add * the Annotation to it's list of Annotations, correct overlaps and mark * Annotations for deletion, if necessary. Note HS aug 2005: the * mechanism applied here sometimes conflicts with the the graph based * mechanism applied in TierImpl to solve overlaps etc. This was the cause * of the faulty behavior (bug) when an Annotation was created on a * TimeSubdivision Tier, with a begin time equal to that of the parent * Annotation's begin time while there already were one or more child * Annotations on that Tier, on that position (the begin time of parent * and new child would be equal to the end time). Existing annotations * are marked for deletion based on their begin and end time (begin >= * end). To acclompish this time values of TimeSlots are altered. But * since the new and the existing annotation share the same begin time * slot (the begin slot of the parent), this can not be applied in such * case. Disconnecting the existing annotation from the graph would make * the graph based iteration over a chain of depending annotations fail. * To (temporarely) solve this an exisitng annotation is now sometimes * marked for deletion here, which looks odd. This whole mechanism * maybe be should be redesigned. * * @param begin time for new begin time slot * @param end time for new end time slot * @param forTier the tier to which an annotation is going to be created * * @return a Vector containing the */ /* public Vector getTimeSlotsForNewAnnotation(long begin, long end, Tier forTier) { Vector slots = new Vector(); TimeOrder timeOrder = ((TranscriptionImpl) (forTier.getParent())).getTimeOrder(); TierImpl parentTier = (TierImpl) ((TierImpl) forTier).getParentTier(); if (parentTier == null) { // erroneous situation return slots; } AlignableAnnotation parentAnn = (AlignableAnnotation) (parentTier.getAnnotationAtTime(begin, true)); if (parentAnn == null) { return slots; } // HS june 2006 adjust begin and end time to fall inside the parent's boundary if (parentAnn.getBegin().isTimeAligned() && begin < parentAnn.getBegin().getTime()) { begin = parentAnn.getBegin().getTime(); } if (parentAnn.getEnd().isTimeAligned() && end > parentAnn.getEnd().getTime()) { end = parentAnn.getEnd().getTime(); } boolean insertAtParentBegin = false; if (parentAnn.getBegin().getTime() == begin) { insertAtParentBegin = true; } // get next existing TimeSlot on tier AlignableAnnotation currAnn = (AlignableAnnotation) ((TierImpl) forTier).getAnnotationAtTime(begin, true); TimeSlot bts = null; TimeSlot ets = null; if (currAnn == null) { // no enclosed annotation for this parent yet // connect to extremes of parent annotation bts = parentAnn.getBegin(); ets = parentAnn.getEnd(); } else if (!insertAtParentBegin) { bts = new TimeSlotImpl(begin, timeOrder); // timeOrder.insertTimeSlot(bts); ets = currAnn.getEnd(); if (ets != parentAnn.getEnd()) { ets.setTime(end); } timeOrder.insertTimeSlot(bts, currAnn.getBegin(), currAnn.getEnd()); // correct end of current annotation // currAnn.setEnd(bts); Vector endingAtTs = ((TranscriptionImpl) (forTier.getParent())).getAnnotsEndingAtTimeSlot(currAnn.getEnd(), forTier, true); if (endingAtTs.contains(parentAnn)) { endingAtTs.remove(parentAnn); } //HS jan 2005 only update annotations on the same tier or on depending tiers Vector depTiers = ((TierImpl) forTier).getDependentTiers(); for (int i = 0; i < endingAtTs.size(); i++) { AlignableAnnotation nextAA = (AlignableAnnotation) endingAtTs.elementAt(i); if ((nextAA.getTier() == forTier) || depTiers.contains(nextAA.getTier())) { nextAA.setEnd(bts); } } } else { // insert at parent begin, see javadoc comments bts = currAnn.getBegin(); ets = currAnn.getEnd(); if (end == parentAnn.getEnd().getTime()) { // removes any number of existing child annotations ets.setTime(end); currAnn.markDeleted(true); } else { AlignableAnnotation currEndAnn = null; currEndAnn = (AlignableAnnotation) (((TierImpl) forTier).getAnnotationAtTime(end, true)); TimeSlotImpl nextEndTs = new TimeSlotImpl(end, timeOrder); if ((ets == parentAnn.getEnd()) || (currAnn == currEndAnn)) { // only one child annotation // insert new timeOrder.insertTimeSlot(nextEndTs, bts, ets); Vector beginningAtTs = ((TranscriptionImpl) (forTier.getParent())).getAnnotsBeginningAtTimeSlot(bts, forTier, true); if (beginningAtTs.contains(parentAnn)) { beginningAtTs.remove(parentAnn); } // HS jan 2005 only update annotations on the same tier or on depending tiers Vector depTiers = ((TierImpl) forTier).getDependentTiers(); for (int i = 0; i < beginningAtTs.size(); i++) { AlignableAnnotation nextAA = (AlignableAnnotation) beginningAtTs.elementAt(i); if ((nextAA.getTier() == forTier) || depTiers.contains(nextAA.getTier())) { nextAA.setBegin(nextEndTs); } } ets = nextEndTs; } else { // more than one child annotations ets.setTime(end); Vector endingAtTs = ((TranscriptionImpl) (forTier.getParent())).getAnnotsEndingAtTimeSlot(ets, forTier, true); if (endingAtTs.contains(parentAnn)) { endingAtTs.remove(parentAnn); } // HS jan 2005 only update annotations on the same tier or on depending tiers Vector depTiers = ((TierImpl) forTier).getDependentTiers(); for (int i = 0; i < endingAtTs.size(); i++) { AlignableAnnotation nextAA = (AlignableAnnotation) endingAtTs.elementAt(i); if ((nextAA.getTier() == forTier) || depTiers.contains(nextAA.getTier())) { nextAA.setBegin(bts); } } currAnn.markDeleted(true);// fix for bug see next line } //currAnn.markDeleted(true); //bug introduced in 2.5.1 } } slots.add(bts); slots.add(ets); // System.out.println("end of getTimeSlotsForNewAnnotation, returning " + slots.size() + " slots"); return slots; } */ /** * July 2006. New implementation that tries to correctly handle as much situations and special cases on Time Subdivision * tiers as possible. <br> * Some special cases are: <br> * - begin and/or end time are the same as that/those of an existing annotation and/or the parent annotation<br> * - begin and/or end time are the same as that/those of an annotation on a dependent tier<br> * - end time is out of the bounds of the parent annotation, end time will be adjusted, the annotation on the parent tier * at begin time is always the parent annotation<br> * - begin and end time are within the boundaries of the parent annotation; the end time will be adjusted to be the * same as the end time of the parent annotation (otherwise two annotations would have to be created. * * Annotations are no longer marked for deletion here. The whole operation depends on proper deletion of overlapping * annotations in TierImpl. * @param begin the (requested) begin time for the new annotation * @param end the (requested) end time for the new annotation * @param forTier the tier the new annotation should be placed on * @return a Vector containing two time slots, either new ones or existing slots */ public Vector getTimeSlotsForNewAnnotation(long begin, long end, Tier forTier) { Vector slots = new Vector(); TierImpl parentTier = (TierImpl) ((TierImpl) forTier).getParentTier(); if (parentTier == null) { // erroneous situation return slots; } AlignableAnnotation parentAnn = (AlignableAnnotation) (parentTier.getAnnotationAtTime(begin, true)); if (parentAnn == null) { // can't create a new child annotation here return slots; } // HS june 2006 adjust begin and end time to fall inside the parent's boundary // maybe the test should be begin < parentAnn.getBeginTimeBoundary() if (parentAnn.getBegin().isTimeAligned() && (begin < parentAnn.getBegin().getTime())) { begin = parentAnn.getBegin().getTime(); } if (parentAnn.getEnd().isTimeAligned() && (end > parentAnn.getEnd().getTime())) { end = parentAnn.getEnd().getTime(); } boolean insertAtParentEnd = false; if (parentAnn.getEnd().getTime() == end) { insertAtParentEnd = true; } // get existing annotation on this tier at begin time AlignableAnnotation currAnn = (AlignableAnnotation) ((TierImpl) forTier).getAnnotationAtTime(begin, true); if (currAnn == null) { // no enclosed annotation for this parent yet // connect to extremes of parent annotation slots.add(parentAnn.getBegin()); slots.add(parentAnn.getEnd()); return slots; } boolean multiOverlappingAnns = false; // get existing annotation on this tier at end time AlignableAnnotation currEndAnn = null; if (insertAtParentEnd) { // getAnnotationAtTime compares annotation end time exclusive... currEndAnn = (AlignableAnnotation) ((TierImpl) forTier).getAnnotationAtTime(end - 1, true); } else { currEndAnn = (AlignableAnnotation) ((TierImpl) forTier).getAnnotationAtTime(end, true); } if ((currEndAnn != null) && (currEndAnn != currAnn) && (end != currAnn.getEnd().getTime())) { multiOverlappingAnns = true; } if (!multiOverlappingAnns && (begin != currAnn.getBegin().getTime()) && (end < currAnn.getEnd().getTime())) { // special case: adjust end time to be the same as the end time of the current annotation // we do not split the current annotation; this would mean that more than one annotation would be created, implicitely // so the current annotation is adjusted and the new annotation is inserted with the old end time end = currAnn.getEnd().getTime(); } TimeOrder timeOrder = ((TranscriptionImpl) (forTier.getParent())).getTimeOrder(); Vector childTiers = ((TierImpl) forTier).getChildTiers(); TimeSlot bts = null; TimeSlot ets = null; boolean coincidingBegin = false; boolean coincidingEnd = false; if (begin == currAnn.getBegin().getTime()) { coincidingBegin = true; } if ((currEndAnn != null) && ((currEndAnn.getBegin().getTime() == end) || (currEndAnn.getEnd().getTime() == end))) { coincidingEnd = true; // coincides with some existing time slot } // different scenarios depending on the situation.... // 1 begin and end coincide with the current annotation. either at parent begin or end or both // 2 begin coincides, end doesn't, a. one overlapping ann., b. multiple overlapping anns, either or not at parents end // 3 end coincides, begin doesn't, a. one overlapping ann., b. multiple overlapping anns, either or not at parents end // 4 begin and end in new positions, always multiple overlapping annotations // with 2, 3 and 4 begin or end might coincide with a timeslot on a depending tier bts = currAnn.getBegin(); ets = currAnn.getEnd(); // case 1 if (coincidingBegin && (end == currAnn.getEnd().getTime())) { //currAnn.setEnd(bts); } else if (coincidingBegin) { // case 2, begin is the same as an existing ann. end is within that ann's boundaries if (!multiOverlappingAnns) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -