List of usage examples for java.util ListIterator hasPrevious
boolean hasPrevious();
From source file:org.zenoss.zep.index.impl.EventIndexDaoImplIT.java
@Test public void testArchiveMissingInDb() throws ZepException { List<EventSummary> created = Lists.newArrayList(); for (int i = 0; i < 10; i++) { String summary = String.format("Event Archive %03d", i); EventSummary event = createArchiveClosed( Event.newBuilder(EventTestUtils.createSampleEvent()).setSummary(summary).build()); created.add(event);/*from w w w . j a v a2 s .c om*/ } this.eventArchiveIndexDao.indexMany(created); // Delete the first 3 events from the database (but don't delete from index) List<String> summariesToDelete = Lists.newArrayList(); for (int i = 0; i < 3; i++) { summariesToDelete.add(created.get(i).getOccurrence(0).getSummary()); } Map<String, List<String>> args = Collections.singletonMap("_summaries", summariesToDelete); this.simpleJdbcTemplate.update("DELETE FROM event_archive WHERE summary IN (:_summaries)", args); EventSort sort = EventSort.newBuilder().setField(Field.EVENT_SUMMARY).build(); EventSummaryRequest req = EventSummaryRequest.newBuilder().addSort(sort).build(); EventSummaryResult result = this.eventArchiveIndexDao.list(req); assertContainsEvents(result, created.subList(3, 10)); // Test sorting descending by summary sort = EventSort.newBuilder().setField(Field.EVENT_SUMMARY).setDirection(Direction.DESCENDING).build(); req = EventSummaryRequest.newBuilder().addSort(sort).build(); result = this.eventArchiveIndexDao.list(req); List<EventSummary> subList = created.subList(3, 10); assertContainsEvents(result, subList); ListIterator<EventSummary> it = subList.listIterator(subList.size()); int i = 0; while (it.hasPrevious()) { assertEquals(result.getEvents(i), it.previous()); ++i; } }
From source file:org.eclipse.jubula.rc.swt.driver.RobotSwtImpl.java
/** * @param options options/*from w ww. j a va 2 s . co m*/ * @param alreadyDown set of pressed keys * @param i ListIterator */ private void releaseKeys(final InterceptorOptions options, final Set alreadyDown, final ListIterator i) { // Release all keys in reverse order. final Set alreadyUp = new HashSet(); try { while (i.hasPrevious()) { IRobotEventConfirmer confirmer = m_interceptor.intercept(options); m_queuer.invokeAndWait(this.getClass().getName() + ".type", //$NON-NLS-1$ new IRunnable() { public Object run() { // SYNCH THREAD START AbstractKeyTyper keyTyper = (AbstractKeyTyper) i.previous(); if (log.isDebugEnabled()) { log.debug("trying to release: " + keyTyper); //$NON-NLS-1$ } if (alreadyDown.contains(keyTyper) && !alreadyUp.contains(keyTyper)) { if (log.isDebugEnabled()) { log.debug("releasing: " + keyTyper); //$NON-NLS-1$ } post(keyTyper.createKeyUpEvent()); alreadyUp.add(keyTyper); } return null; } }); confirmer.waitToConfirm(null, new KeySwtEventMatcher(SWT.KeyUp)); } } catch (RobotException e) { log.error("error releasing keys", e); //$NON-NLS-1$ if (!i.hasPrevious()) { throw e; } } }
From source file:org.slc.sli.dashboard.manager.impl.PopulationManagerImpl.java
/** * /* w w w . jav a 2s . c o m*/ * Finds the chronologically (strictly) earlier date on the list as compared * to the anchorDate. Note that this method assumes the dates list has been * chronologically sorted, the anchorDate is contained on it, and it has no * "null" entries. The input parameters themselves can be null, in which * case null is returned. * * @param dates * @param anchorDate */ @SuppressWarnings({ "unchecked", "rawtypes" }) private Date findPrevDate(List<Date> dates, Date anchorDate) { if (anchorDate == null || dates == null) { return null; } Date prevDate = null; ListIterator<Date> li = dates.listIterator(dates.indexOf(anchorDate)); while (li.hasPrevious()) { Date d = li.previous(); if (d.before(anchorDate)) { prevDate = d; break; } } return prevDate; }
From source file:com.projity.script.object.TimeIntervals.java
public TimeIntervals translate(int winCount) { //TODO case winCount<0 // for (TimeWindow w : history) System.out.println("history0: "+w); // for (TimeWindow w : win) System.out.println("win0: "+w); //for (TimeWindow w : history) System.out.println("id="+w.getId()); TimeIntervals t = new TimeIntervals(); t.setScale(scale);/*from ww w . j a v a 2 s . c om*/ LinkedList<TimeWindow> twin = t.getWin(); if (winCount == 0 || win.size() == 0) return t; //or null if (winCount > 0) { t.winId = winId + win.size(); int lastId = t.winId - 1 + winCount; int maxHistoryId = Math.min(history.getLast().getId(), lastId); int i = t.winId; if (i <= maxHistoryId) { ListIterator<TimeWindow> it = history.listIterator(); TimeWindow w; while (it.hasNext()) { w = it.next(); if (w.getId() == t.winId) { it.previous(); break; } } for (; i <= maxHistoryId && it.hasNext(); i++) { w = it.next(); twin.add(w); // System.out.println("Found in history: "+w); } } LinkedList<TimeWindow> newWin = new LinkedList<TimeWindow>(); generateWindows(scale, (twin.size() > 0 ? twin : win).getLast().getE(), start, end, lastId - i + 1, newWin); t.indexWindows(t.winId + t.getWin().size(), newWin); // for (TimeWindow w : newWin) System.out.println("New window: "+w); t.getWin().addAll(newWin); history.addAll(newWin); } else { t.winId = winId - 1; int lastId = t.winId + 1 + winCount; int minHistoryId = Math.max(history.getFirst().getId(), lastId); int i = t.winId; if (i >= minHistoryId) { ListIterator<TimeWindow> it = history.listIterator(history.size() - 1); TimeWindow w; while (it.hasPrevious()) { w = it.previous(); if (w.getId() == t.winId) { it.next(); break; } } for (; i >= minHistoryId; i--) { w = it.previous(); twin.addFirst(w); // System.out.println("Found in history: "+w); } } // System.out.println("winId="+winId+", t.winId="+t.winId+", lastId="+lastId+", i="+i+" minHistoryId="+minHistoryId); LinkedList<TimeWindow> newWin = new LinkedList<TimeWindow>(); generateWindows(scale, (twin.size() > 0 ? twin : win).getFirst().getS(), start, end, lastId - i - 1, newWin); t.indexWindows(lastId, newWin); // for (TimeWindow w : newWin) System.out.println("New window: "+w); t.getWin().addAll(0, newWin); history.addAll(0, newWin); } int translation = 0; for (TimeWindow w : t.getWin()) { if (winCount > 0) { win.removeFirst(); win.addLast(w); translation++; } else { win.removeLast(); win.addFirst(w); translation--; } } winId = winId + translation; t.setTranslation(translation); // for (TimeWindow w : history) System.out.println("history1: "+w); // for (TimeWindow w : win) System.out.println("win1: "+w); // for (TimeWindow w : twin) System.out.println("t.win1: "+w); return t; }
From source file:org.apache.fop.layoutmgr.inline.TextLayoutManager.java
/** {@inheritDoc} */ public boolean applyChanges(final List oldList, int depth) { // make sure the LM appears unfinished in between this call // and the next call to getChangedKnuthElements() setFinished(false);/*from ww w .jav a2 s . com*/ if (oldList.isEmpty()) { return false; } // Find the first and last positions in oldList that point to an AreaInfo // (i.e. getLeafPos() != -1) LeafPosition startPos = null; LeafPosition endPos = null; ListIterator oldListIter; for (oldListIter = oldList.listIterator(); oldListIter.hasNext();) { Position pos = ((KnuthElement) oldListIter.next()).getPosition(); startPos = (LeafPosition) pos.getPosition(depth); if (startPos != null && startPos.getLeafPos() != -1) { break; } } for (oldListIter = oldList.listIterator(oldList.size()); oldListIter.hasPrevious();) { Position pos = ((KnuthElement) oldListIter.previous()).getPosition(); endPos = (LeafPosition) pos.getPosition(depth); if (endPos != null && endPos.getLeafPos() != -1) { break; } } // set start/end index, taking into account any offset due to // changes applied to previous paragraphs returnedIndices[0] = (startPos != null ? startPos.getLeafPos() : -1) + changeOffset; returnedIndices[1] = (endPos != null ? endPos.getLeafPos() : -1) + changeOffset; int areaInfosAdded = 0; int areaInfosRemoved = 0; if (!changeList.isEmpty()) { int oldIndex = -1; int changeIndex; PendingChange currChange; ListIterator changeListIterator = changeList.listIterator(); while (changeListIterator.hasNext()) { currChange = (PendingChange) changeListIterator.next(); if (currChange.index == oldIndex) { areaInfosAdded++; changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved; } else { areaInfosRemoved++; areaInfosAdded++; oldIndex = currChange.index; changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved; removeAreaInfo(changeIndex); } addAreaInfo(changeIndex, currChange.areaInfo); } changeList.clear(); } // increase the end index for getChangedKnuthElements() returnedIndices[1] += (areaInfosAdded - areaInfosRemoved); // increase offset to use for subsequent paragraphs changeOffset += (areaInfosAdded - areaInfosRemoved); return hasChanged; }
From source file:net.sourceforge.fenixedu.domain.DegreeCurricularPlan.java
public ExecutionDegree getMostRecentExecutionDegree() { if (getExecutionDegreesSet().isEmpty()) { return null; }//from ww w . j a v a 2 s . c o m final ExecutionYear currentYear = ExecutionYear.readCurrentExecutionYear(); ExecutionDegree result = getExecutionDegreeByYear(currentYear); if (result != null) { return result; } final List<ExecutionDegree> sorted = new ArrayList<ExecutionDegree>(getExecutionDegreesSet()); Collections.sort(sorted, ExecutionDegree.EXECUTION_DEGREE_COMPARATORY_BY_YEAR); final ExecutionDegree first = sorted.iterator().next(); if (sorted.size() == 1) { return first; } if (first.getExecutionYear().isAfter(currentYear)) { return first; } else { final ListIterator<ExecutionDegree> iter = sorted.listIterator(sorted.size()); while (iter.hasPrevious()) { final ExecutionDegree executionDegree = iter.previous(); if (executionDegree.getExecutionYear().isBeforeOrEquals(currentYear)) { return executionDegree; } } } return null; }
From source file:org.apache.fop.layoutmgr.inline.LineLayoutManager.java
/** * Add a line with inline content/*from www . j av a2 s .c o m*/ * @param context the context for adding areas * @param lbp the position for which the line is generated * @param isLastPosition true if this is the last position of this LM */ private void addInlineArea(LayoutContext context, LineBreakPosition lbp, boolean isLastPosition) { KnuthSequence seq = knuthParagraphs.get(lbp.parIndex); int startElementIndex = lbp.startIndex; int endElementIndex = lbp.getLeafPos(); LineArea lineArea = new LineArea((lbp.getLeafPos() < seq.size() - 1 ? textAlignment : textAlignmentLast), lbp.difference, lbp.availableStretch, lbp.availableShrink); if (lbp.startIndent != 0) { lineArea.addTrait(Trait.START_INDENT, lbp.startIndent); } if (lbp.endIndent != 0) { lineArea.addTrait(Trait.END_INDENT, new Integer(lbp.endIndent)); } lineArea.setBPD(lbp.lineHeight); lineArea.setIPD(lbp.lineWidth); lineArea.setBidiLevel(bidiLevel); lineArea.addTrait(Trait.SPACE_BEFORE, lbp.spaceBefore); lineArea.addTrait(Trait.SPACE_AFTER, lbp.spaceAfter); alignmentContext.resizeLine(lbp.lineHeight, lbp.baseline); if (seq instanceof Paragraph) { Paragraph currPar = (Paragraph) seq; // ignore the first elements added by the LineLayoutManager startElementIndex += (startElementIndex == 0) ? currPar.ignoreAtStart : 0; // if this is the last line area that for this paragraph, // ignore the last elements added by the LineLayoutManager and // subtract the last-line-end-indent from the area ipd if (endElementIndex == (currPar.size() - 1)) { endElementIndex -= currPar.ignoreAtEnd; lineArea.setIPD(lineArea.getIPD() - lastLineEndIndent.getValue(this)); } } // ignore the last element in the line if it is a KnuthGlue object ListIterator seqIterator = seq.listIterator(endElementIndex); KnuthElement lastElement = (KnuthElement) seqIterator.next(); // the TLM which created the last KnuthElement in this line LayoutManager lastLM = lastElement.getLayoutManager(); if (lastElement.isGlue()) { // Remove trailing spaces if allowed so if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED || whiteSpaceTreament == EN_IGNORE || whiteSpaceTreament == EN_IGNORE_IF_BEFORE_LINEFEED) { endElementIndex--; // this returns the same KnuthElement seqIterator.previous(); if (seqIterator.hasPrevious()) { lastLM = ((KnuthElement) seqIterator.previous()).getLayoutManager(); } } } // Remove leading spaces if allowed so if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED || whiteSpaceTreament == EN_IGNORE || whiteSpaceTreament == EN_IGNORE_IF_AFTER_LINEFEED) { // ignore KnuthGlue and KnuthPenalty objects // at the beginning of the line seqIterator = seq.listIterator(startElementIndex); while (seqIterator.hasNext() && !((KnuthElement) seqIterator.next()).isBox()) { startElementIndex++; } } // Add the inline areas to lineArea PositionIterator inlinePosIter = new KnuthPossPosIter(seq, startElementIndex, endElementIndex + 1); LayoutContext lc = new LayoutContext(0); lc.setAlignmentContext(alignmentContext); lc.setSpaceAdjust(lbp.dAdjust); lc.setIPDAdjust(lbp.ipdAdjust); lc.setLeadingSpace(new SpaceSpecifier(true)); lc.setTrailingSpace(new SpaceSpecifier(false)); lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); setCurrentArea(lineArea); setChildContext(lc); LayoutManager childLM; while ((childLM = inlinePosIter.getNextChildLM()) != null) { lc.setFlags(LayoutContext.LAST_AREA, (childLM == lastLM)); childLM.addAreas(inlinePosIter, lc); lc.setLeadingSpace(lc.getTrailingSpace()); lc.setTrailingSpace(new SpaceSpecifier(false)); } // if display-align is distribute, add space after if (context.getSpaceAfter() > 0 && (!context.isLastArea() || !isLastPosition)) { lineArea.setBPD(lineArea.getBPD() + context.getSpaceAfter()); } lineArea.finish(); if (lineArea.getBidiLevel() >= 0) { BidiResolver.reorder(lineArea); } parentLayoutManager.addChildArea(lineArea); }
From source file:com.android.systemui.qs.QSDragPanel.java
public void setTiles(final Collection<QSTile<?>> tilesCollection) { // we try to be as efficient as possible here because this can happen while the user // is in edit mode, or maybe even while tiles are animating // step 1: stop all animations // step 2: remove tiles no longer to be used, cache ones that are still valid // step 3: remove empty viewpager pages // step 4: generate new tiles, re-add cached ones if (DEBUG_TILES) { Log.i(TAG, "setTiles() called with tiles = [" + tilesCollection + "]"); }/*from w w w. j a va 2s.com*/ if (mLastDragRecord != null && mRecords.indexOf(mLastDragRecord) == -1) { // the last removed record might be stored in mLastDragRecord if we just shifted // re-add it to the list so we'll clean it up below mRecords.add(mLastDragRecord); mLastDragRecord = null; } // step kinda-1 if (mDraggingRecord != null) { // dragging record might be animating back, force it to finished position mDraggingRecord.tileView.animate().cancel(); } int currentViewPagerPage = mViewPager.getCurrentItem(); int removedPages = 0; Map<QSTile<?>, DragTileRecord> cachedRecords = new ArrayMap<>(); ListIterator<TileRecord> iterator = mRecords.listIterator(mRecords.size()); int recordsRemoved = 0; // cleanup current records while (iterator.hasPrevious()) { // mRecords DragTileRecord dr = (DragTileRecord) iterator.previous(); // step 1 dr.tileView.animate().cancel(); // step 2 if (tilesCollection.contains(dr.tile)) { if (DEBUG_TILES) { Log.i(TAG, "caching tile: " + dr.tile); } cachedRecords.put(dr.tile, dr); } else { if (dr.page >= 0) { if (DEBUG_TILES) { Log.w(TAG, "removed dr.tileView: " + dr.tileView + " from page: " + dr.page + " (dest page: " + dr.destinationPage + ")"); } removeTileView(dr.tileView); } if (DEBUG_TILES) { Log.i(TAG, "removing tile: " + dr.tile); } // remove record iterator.remove(); recordsRemoved++; dr.page = -1; dr.destinationPage = -1; } } // at this point cachedRecords should have all retained tiles, no new or old tiles int delta = tilesCollection.size() - cachedRecords.size() - recordsRemoved; if (DEBUG_TILES) { Log.i(TAG, "record map delta: " + delta); } // step 3 final Iterator<QSPage> pageIterator = mPages.iterator(); while (pageIterator.hasNext()) { final QSPage page = pageIterator.next(); final int viewpagerIndex = page.getPageIndex() + (mEditing ? 1 : 0); final int childCount = page.getChildCount(); if (DEBUG_TILES) { Log.d(TAG, "page " + viewpagerIndex + " has " + childCount); } if (page.getPageIndex() >= getCurrentMaxPageCount() - 1) { if (DEBUG_TILES) { Log.d(TAG, "page : " + page + " has " + childCount + " children"); } if (childCount == 0) { removedPages++; page.removeAllViews(); mPagerAdapter.startUpdate(mViewPager); mPagerAdapter.destroyItem(mViewPager, viewpagerIndex, page); mPagerAdapter.finishUpdate(mViewPager); mPagerAdapter.notifyDataSetChanged(); } } } if (removedPages > 0) { // even though we explicitly destroy old pages, without this call, // the viewpager doesn't seem to want to pick up the fact that we have less pages // and allows "empty" scrolls to the right where there is no page. if (DEBUG_TILES) { Log.d(TAG, "re-setting adapter, page: " + currentViewPagerPage); } mViewPager.setAdapter(mPagerAdapter); mViewPager.setCurrentItem(Math.min(currentViewPagerPage, mPagerAdapter.getCount()), false); mPagerAdapter.notifyDataSetChanged(); } // step 4 mRecords.ensureCapacity(tilesCollection.size()); int runningCount = 0; final Iterator<QSTile<?>> newTileIterator = tilesCollection.iterator(); while (newTileIterator.hasNext()) { QSTile<?> tile = newTileIterator.next(); if (tile instanceof CustomQSTile) { if (((CustomQSTile) tile).isUserRemoved() || ((CustomQSTile) tile).getTile() == null) { // tile not published yet continue; } } final int tileDestPage = getPagesForCount(runningCount + 1) - 1; if (DEBUG_TILES) { Log.d(TAG, "tile at : " + runningCount + ": " + tile + " to dest page: " + tileDestPage); } DragTileRecord record; if (!cachedRecords.containsKey(tile)) { if (DEBUG_TILES) { Log.d(TAG, "tile at: " + runningCount + " not cached, adding it to records"); } record = makeRecord(tile); record.destinationPage = tileDestPage; mRecords.add(runningCount, record); mPagerAdapter.notifyDataSetChanged(); } else { record = cachedRecords.get(tile); if (DEBUG_TILES) { Log.d(TAG, "tile at : " + runningCount + ": cached, restoring: " + record); } mPages.get(record.page).removeView(record.tileView); record.page = -1; record.destinationPage = tileDestPage; mRecords.remove(record); mRecords.add(runningCount, record); mPagerAdapter.notifyDataSetChanged(); } if (record.page == -1) { // add the view mPages.get(record.destinationPage).addView(record.tileView); record.page = record.destinationPage; if (DEBUG_TILES) { Log.d(TAG, "added view " + record); } } runningCount++; } if (isShowingDetail()) { mDetail.bringToFront(); } mPagerAdapter.notifyDataSetChanged(); refreshAllTiles(); requestLayout(); }
From source file:org.trnltk.experiment.morphology.ambiguity.DataDiffUtil.java
/** * Reorder and merge like edit sections. Merge equalities. * Any edit section can move as long as it doesn't cross an equality. * * @param diffs LinkedList of Diff objects. *//* w w w .j av a 2 s. com*/ public void diff_cleanupMerge(LinkedList<Diff<T>> diffs) { diffs.add(new Diff<T>(Operation.EQUAL, new ArrayList<T>())); // Add a dummy entry at the end. ListIterator<Diff<T>> pointer = diffs.listIterator(); int count_delete = 0; int count_insert = 0; List<T> text_delete = new ArrayList<T>(); List<T> text_insert = new ArrayList<T>(); Diff thisDiff = pointer.next(); Diff prevEqual = null; int commonlength; while (thisDiff != null) { switch (thisDiff.operation) { case INSERT: count_insert++; text_insert = ListUtils.union(text_insert, thisDiff.text); prevEqual = null; break; case DELETE: count_delete++; text_delete = ListUtils.union(text_delete, thisDiff.text); prevEqual = null; break; case EQUAL: if (count_delete + count_insert > 1) { boolean both_types = count_delete != 0 && count_insert != 0; // Delete the offending records. pointer.previous(); // Reverse direction. while (count_delete-- > 0) { pointer.previous(); pointer.remove(); } while (count_insert-- > 0) { pointer.previous(); pointer.remove(); } if (both_types) { // Factor out any common prefixies. commonlength = diff_commonPrefix(text_insert, text_delete); if (commonlength != 0) { if (pointer.hasPrevious()) { thisDiff = pointer.previous(); assert thisDiff.operation == Operation.EQUAL : "Previous diff should have been an equality."; thisDiff.text = ListUtils.union(thisDiff.text, text_insert.subList(0, commonlength)); pointer.next(); } else { pointer.add(new Diff(Operation.EQUAL, text_insert.subList(0, commonlength))); } text_insert = text_insert.subList(commonlength, text_insert.size()); text_delete = text_delete.subList(commonlength, text_delete.size()); } // Factor out any common suffixies. commonlength = diff_commonSuffix(text_insert, text_delete); if (commonlength != 0) { thisDiff = pointer.next(); thisDiff.text = ListUtils.union( text_insert.subList(text_insert.size() - commonlength, text_insert.size()), thisDiff.text); text_insert = text_insert.subList(0, text_insert.size() - commonlength); text_delete = text_delete.subList(0, text_delete.size() - commonlength); pointer.previous(); } } // Insert the merged records. if (text_delete.size() != 0) { pointer.add(new Diff(Operation.DELETE, text_delete)); } if (text_insert.size() != 0) { pointer.add(new Diff(Operation.INSERT, text_insert)); } // Step forward to the equality. thisDiff = pointer.hasNext() ? pointer.next() : null; } else if (prevEqual != null) { // Merge this equality with the previous one. prevEqual.text = ListUtils.union(prevEqual.text, thisDiff.text); pointer.remove(); thisDiff = pointer.previous(); pointer.next(); // Forward direction } count_insert = 0; count_delete = 0; text_delete = new ArrayList<T>(); text_insert = new ArrayList<T>(); prevEqual = thisDiff; break; } thisDiff = pointer.hasNext() ? pointer.next() : null; } if (diffs.getLast().text.size() == 0) { diffs.removeLast(); // Remove the dummy entry at the end. } /* * Second pass: look for single edits surrounded on both sides by equalities * which can be shifted sideways to eliminate an equality. * e.g: A<ins>BA</ins>C -> <ins>AB</ins>AC */ boolean changes = false; // Create a new iterator at the start. // (As opposed to walking the current one back.) pointer = diffs.listIterator(); Diff<T> prevDiff = pointer.hasNext() ? pointer.next() : null; thisDiff = pointer.hasNext() ? pointer.next() : null; Diff nextDiff = pointer.hasNext() ? pointer.next() : null; // Intentionally ignore the first and last element (don't need checking). while (nextDiff != null) { if (prevDiff.operation == Operation.EQUAL && nextDiff.operation == Operation.EQUAL) { // This is a single edit surrounded by equalities. if (endsWith(thisDiff.text, prevDiff.text)) { // Shift the edit over the previous equality. thisDiff.text = ListUtils.union(prevDiff.text, thisDiff.text.subList(0, thisDiff.text.size() - prevDiff.text.size())); nextDiff.text = ListUtils.union(prevDiff.text, nextDiff.text); pointer.previous(); // Walk past nextDiff. pointer.previous(); // Walk past thisDiff. pointer.previous(); // Walk past prevDiff. pointer.remove(); // Delete prevDiff. pointer.next(); // Walk past thisDiff. thisDiff = pointer.next(); // Walk past nextDiff. nextDiff = pointer.hasNext() ? pointer.next() : null; changes = true; } else if (startsWith(thisDiff.text, nextDiff.text)) { // Shift the edit over the next equality. prevDiff.text = ListUtils.union(prevDiff.text, nextDiff.text); thisDiff.text = ListUtils.union( thisDiff.text.subList(nextDiff.text.size(), thisDiff.text.size()), nextDiff.text); pointer.remove(); // Delete nextDiff. nextDiff = pointer.hasNext() ? pointer.next() : null; changes = true; } } prevDiff = thisDiff; thisDiff = nextDiff; nextDiff = pointer.hasNext() ? pointer.next() : null; } // If shifts were made, the diff needs reordering and another shift sweep. if (changes) { diff_cleanupMerge(diffs); } }
From source file:marytts.modules.phonemiser.AllophoneSet.java
/** * Syllabify a string of allophones. If stress markers are provided, they are preserved; otherwise, primary stress will be * assigned to the initial syllable.// w w w .j a v a2s . c om * <p> * The syllabification algorithm itself follows the <i>Core Syllabification Principle (CSP)</i> from <blockquote>G.N. Clements * (1990) "The role of the sonority cycle in core syllabification." In: J. Kingston & M.E. Beckman (Eds.), * <em>Papers in Laboratory Phonology I: Between the Grammar and Physics of Speech</em>, Ch. 17, pp. 283-333, Cambridge * University Press.</blockquote> * * @param phoneString * phoneString * @return a syllabified string; individual allophones are separated by spaces, and syllables, by dashes. * @throws IllegalArgumentException * if the <b>phoneString</b> is empty or contains a symbol that satisfies none of the following conditions: * <ol> * <li>the symbol corresponds to an Allophone, or</li> <li>the symbol is a stress symbol (cf. {@link Stress}), or * </li> <li>the symbol is a syllable boundary (<code>-</code>)</li> * </ol> * */ public String syllabify(String phoneString) throws IllegalArgumentException { // Before we process, a sanity check: if (phoneString.trim().isEmpty()) { throw new IllegalArgumentException("Cannot syllabify empty phone string"); } // First, split phoneString into a List of allophone Strings... List<String> allophoneStrings = splitIntoAllophoneList(phoneString, true); // ...and create from it a List of generic Objects List<Object> phonesAndSyllables = new ArrayList<Object>(allophoneStrings); // Create an iterator ListIterator<Object> iterator = phonesAndSyllables.listIterator(); // First iteration (left-to-right): // CSP (a): Associate each [+syllabic] segment to a syllable node. Syllable currentSyllable = null; while (iterator.hasNext()) { String phone = (String) iterator.next(); try { // either it's an Allophone Allophone allophone = getAllophone(phone); if (allophone.isSyllabic()) { // if /6/ immediately follows a non-diphthong vowel, it should be appended instead of forming its own syllable boolean appendR = false; if (allophone.getFeature("ctype").equals("r")) { // it's an /6/ if (iterator.previousIndex() > 1) { Object previousPhoneOrSyllable = phonesAndSyllables.get(iterator.previousIndex() - 1); if (previousPhoneOrSyllable == currentSyllable) { // the /6/ immediately follows the current syllable if (!currentSyllable.getLastAllophone().isDiphthong()) { // the vowel immediately preceding the /6/ is not a diphthong appendR = true; } } } } if (appendR) { iterator.remove(); currentSyllable.appendAllophone(allophone); } else { currentSyllable = new Syllable(allophone); iterator.set(currentSyllable); } } } catch (IllegalArgumentException e) { // or a stress or boundary marker if (!getIgnoreChars().contains(phone)) { throw e; } } } // Second iteration (right-to-left): // CSP (b): Given P (an unsyllabified segment) preceding Q (a syllabified segment), adjoin P to the syllable containing Q // iff P has lower sonority rank than Q (iterative). currentSyllable = null; boolean foundPrimaryStress = false; iterator = phonesAndSyllables.listIterator(phonesAndSyllables.size()); while (iterator.hasPrevious()) { Object phoneOrSyllable = iterator.previous(); if (phoneOrSyllable instanceof Syllable) { currentSyllable = (Syllable) phoneOrSyllable; } else if (currentSyllable == null) { // haven't seen a Syllable yet in this iteration continue; } else { String phone = (String) phoneOrSyllable; try { // it's an Allophone -- prepend to the Syllable Allophone allophone = getAllophone(phone); if (allophone.sonority() < currentSyllable.getFirstAllophone().sonority()) { iterator.remove(); currentSyllable.prependAllophone(allophone); } } catch (IllegalArgumentException e) { // it's a provided stress marker -- assign it to the Syllable switch (phone) { case Stress.PRIMARY: iterator.remove(); currentSyllable.setStress(Stress.PRIMARY); foundPrimaryStress = true; break; case Stress.SECONDARY: iterator.remove(); currentSyllable.setStress(Stress.SECONDARY); break; case "-": iterator.remove(); // TODO handle syllable boundaries break; default: throw e; } } } } // Third iteration (left-to-right): // CSP (c): Given Q (a syllabified segment) followed by R (an unsyllabified segment), adjoin R to the syllable containing // Q iff has a lower sonority rank than Q (iterative). Syllable initialSyllable = currentSyllable; currentSyllable = null; iterator = phonesAndSyllables.listIterator(); while (iterator.hasNext()) { Object phoneOrSyllable = iterator.next(); if (phoneOrSyllable instanceof Syllable) { currentSyllable = (Syllable) phoneOrSyllable; } else { String phone = (String) phoneOrSyllable; try { // it's an Allophone -- append to the Syllable Allophone allophone; try { allophone = getAllophone(phone); } catch (IllegalArgumentException e) { // or a stress or boundary marker -- remove if (getIgnoreChars().contains(phone)) { iterator.remove(); continue; } else { throw e; } } if (currentSyllable == null) { // haven't seen a Syllable yet in this iteration iterator.remove(); if (initialSyllable == null) { // haven't seen any syllable at all initialSyllable = new Syllable(allophone); iterator.add(initialSyllable); } else { initialSyllable.prependAllophone(allophone); } } else { // append it to the last seen Syllable iterator.remove(); currentSyllable.appendAllophone(allophone); } } catch (IllegalArgumentException e) { throw e; } } } // if primary stress was not provided, assign it to initial syllable if (!foundPrimaryStress) { initialSyllable.setStress(Stress.PRIMARY); } // join Syllables with dashes and return the String return StringUtils.join(phonesAndSyllables, " - "); }