org.odftoolkit.odfdom.incubator.search.TextNavigation Maven / Gradle / Ivy
/************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
************************************************************************/
package org.odftoolkit.odfdom.incubator.search;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.odftoolkit.odfdom.pkg.OdfElement;
import org.odftoolkit.odfdom.pkg.OdfFileDom;
import org.odftoolkit.odfdom.doc.OdfTextDocument;
import org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeMasterStyles;
import org.odftoolkit.odfdom.incubator.doc.text.OdfWhitespaceProcessor;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* A derived Navigation class used for navigate the text content
* it is used to search the document and find the matched text
* and would return TextSelection instance
*
* @deprecated As of release 0.8.8, replaced by {@link org.odftoolkit.simple.common.navigation.TextNavigation} in Simple API.
*/
public class TextNavigation extends Navigation {
private String mMatchedElementName = "text:p,text:h";
private String mPatternText;
private OdfTextDocument mTextDocument;
private TextSelection mCurrentSelectedItem;
private String mCurrentText;
private int mCurrentIndex;
private boolean mbFinishFindInHeaderFooter;
/**
* Construct TextNavigation with matched condition and navigation scope
* @param pattern the matched pattern String
* @param doc the navigation scope
*/
public TextNavigation(String pattern, OdfTextDocument doc) {
this.mPatternText = pattern;
mTextDocument = doc;
mCurrentSelectedItem = null;
mbFinishFindInHeaderFooter = false;
}
//the matched text might exist in header/footer
private TextSelection findInHeaderFooter(TextSelection selected) {
OdfFileDom styledom = null;
OdfOfficeMasterStyles masterpage = null;
OdfElement element = null;
if (selected != null) {
OdfElement containerElement = selected.getContainerElement();
int index = selected.getIndex();
OdfWhitespaceProcessor textProcessor = new OdfWhitespaceProcessor();
String content = textProcessor.getText(containerElement);
int nextIndex = -1;
Pattern pattern = Pattern.compile(mPatternText);
Matcher matcher = pattern.matcher(content);
//start from the end index of the selected item
if (matcher.find(index + selected.getText().length())) {
// here just consider \n\r\t occupy one char
nextIndex = matcher.start();
int eIndex = matcher.end();
mCurrentText = content.substring(nextIndex, eIndex);
}
if (nextIndex != -1) {
TextSelection item = new TextSelection(mCurrentText, selected.getContainerElement(), nextIndex);
return item;
}
}
try {
styledom = mTextDocument.getStylesDom();
NodeList list = styledom.getElementsByTagName("office:master-styles");
if (styledom == null) {
return null;
}
if (list.getLength() > 0) {
masterpage = (OdfOfficeMasterStyles) list.item(0);
} else {
return null;
}
if (selected == null) {
element = (OdfElement) getNextMatchElementInTree(masterpage, masterpage);
} else {
element = (OdfElement) getNextMatchElementInTree(selected.getContainerElement(), masterpage);
}
if (element != null) {
TextSelection item = new TextSelection(mCurrentText, element, mCurrentIndex);
return item;
} else {
return null;
}
} catch (Exception ex) {
Logger.getLogger(TextNavigation.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
}
return null;
}
//found the next selection start from the 'selected' TextSelection
private TextSelection findnext(TextSelection selected) {
if (!mbFinishFindInHeaderFooter) {
TextSelection styleselected = findInHeaderFooter(selected);
if (styleselected != null) {
return styleselected;
}
selected = null;
mbFinishFindInHeaderFooter = true;
}
if (selected == null) {
OdfElement element = null;
try {
element = (OdfElement) getNextMatchElement((Node) mTextDocument.getContentRoot());
} catch (Exception ex) {
Logger.getLogger(TextNavigation.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
}
if (element != null) {
return new TextSelection(mCurrentText, element, mCurrentIndex);
} else {
return null;
}
}
OdfElement containerElement = selected.getContainerElement();
int index = selected.getIndex();
OdfWhitespaceProcessor textProcessor = new OdfWhitespaceProcessor();
String content = textProcessor.getText(containerElement);
int nextIndex = -1;
Pattern pattern = Pattern.compile(mPatternText);
Matcher matcher = pattern.matcher(content);
//start from the end index of the selected item
if (matcher.find(index + selected.getText().length())) {
// here just consider \n\r\t occupy one char
nextIndex = matcher.start();
int eIndex = matcher.end();
mCurrentText = content.substring(nextIndex, eIndex);
}
if (nextIndex != -1) {
TextSelection item = new TextSelection(mCurrentText, selected.getContainerElement(), nextIndex);
return item;
} else {
OdfElement element = (OdfElement) getNextMatchElement((Node) containerElement);
if (element != null) {
TextSelection item = new TextSelection(mCurrentText, element, mCurrentIndex);
return item;
} else {
return null;
}
}
}
/* (non-Javadoc)
* @see org.odftoolkit.odfdom.incubator.search.Navigation#getCurrentItem()
*/
@Override
public Selection getCurrentItem() {
Selection.SelectionManager.registerItem(mCurrentSelectedItem);
return mCurrentSelectedItem;
}
/* (non-Javadoc)
* @see org.odftoolkit.odfdom.incubator.search.Navigation#hasNext()
*/
@Override
public boolean hasNext() {
mCurrentSelectedItem = findnext(mCurrentSelectedItem);
return (mCurrentSelectedItem != null);
}
/**
* check if the text content of element match the specified pattern string
* @param element navigate this element
* @return true if the text content of this element match this pattern;
* false if not match
*/
@Override
public boolean match(Node element) {
if (element instanceof OdfElement) {
if (mMatchedElementName.indexOf(element.getNodeName()) != -1) {
OdfWhitespaceProcessor textProcessor = new OdfWhitespaceProcessor();
String content = textProcessor.getText(element);
Pattern pattern = Pattern.compile(mPatternText);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
// here just consider \n\r\t occupy one char
mCurrentIndex = matcher.start();
int eIndex = matcher.end();
mCurrentText = content.substring(mCurrentIndex, eIndex);
return true;
}
}
}
return false;
}
}