com.reandroid.arsc.chunk.xml.ResXmlTextNode Maven / Gradle / Ivy
/*
* Copyright (C) 2022 github.com/REAndroid
*
* Licensed 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 com.reandroid.arsc.chunk.xml;
import com.reandroid.arsc.base.BlockCounter;
import com.reandroid.arsc.coder.XmlSanitizer;
import com.reandroid.json.JSONObject;
import com.reandroid.xml.XMLText;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
public class ResXmlTextNode extends ResXmlNode {
private final ResXmlText resXmlText;
private String mIndentText;
public ResXmlTextNode(ResXmlText resXmlText) {
super(1);
this.resXmlText = resXmlText;
addChild(0, resXmlText);
}
public ResXmlTextNode() {
this(new ResXmlText());
}
ResXmlText getResXmlText() {
return resXmlText;
}
public int getLineNumber(){
return getResXmlText().getLineNumber();
}
public void autoSetLineNumber(){
ResXmlElement root = getParentResXmlElement();
if(root == null){
return;
}
root = root.getRootResXmlElement();
BlockCounter counter = new BlockCounter(this);
root.calculateLineNumber(counter, true);
setLineNumber(counter.getCount());
}
@Override
void calculateLineNumber(BlockCounter counter, boolean startLine){
if(counter.FOUND){
return;
}
if(startLine && counter.END == this){
counter.FOUND = true;
return;
}
String text = getText();
if(text == null){
return;
}
int result = 1;
char[] chars = text.toCharArray();
for(char ch : chars){
if(ch == '\n'){
result ++;
}
}
counter.addCount(result);
if(counter.END == this){
counter.FOUND = true;
}
}
public String getComment() {
return getResXmlText().getComment();
}
@Override
public int getDepth(){
ResXmlElement parent = getParentResXmlElement();
if(parent!=null){
return parent.getDepth() + 1;
}
return 0;
}
@Override
void addEvents(ParserEventList parserEventList){
String comment = getComment();
if(comment!=null){
parserEventList.add(
new ParserEvent(ParserEvent.COMMENT, this, comment, false));
}
parserEventList.add(new ParserEvent(ParserEvent.TEXT, this));
}
public ResXmlElement getParentResXmlElement(){
return getResXmlText().getParentResXmlElement();
}
public void setLineNumber(int lineNumber){
getResXmlText().setLineNumber(lineNumber);
}
public String getText(){
return getResXmlText().getText();
}
public void setText(String text){
getResXmlText().setText(text);
mIndentText = null;
}
public void append(String text){
String exist = getText();
if(exist == null || exist.length() == 0){
exist = mIndentText;
}
if(exist == null && isIndent(text)){
mIndentText = text;
return;
}
if(exist != null){
text = exist + text;
}
setText(text);
}
@Override
public boolean isNull() {
return getResXmlText().isNull();
}
@Override
void onRemoved(){
getResXmlText().onRemoved();
}
@Override
void linkStringReferences(){
getResXmlText().linkStringReferences();
}
@Override
public void serialize(XmlSerializer serializer) throws IOException {
if(isNull()){
return;
}
serializer.text(getText());
}
@Override
public void parse(XmlPullParser parser) throws IOException, XmlPullParserException {
setLineNumber(parser.getLineNumber());
String text;
int event = parser.getEventType();
if(event == XmlPullParser.ENTITY_REF){
text = decodeEntityRef(parser.getText());
}else if(event == XmlPullParser.TEXT){
text = parser.getText();
text = XmlSanitizer.unEscapeUnQuote(text);
}else {
throw new XmlPullParserException("Invalid text event: "
+ event + ", " + parser.getPositionDescription());
}
append(text);
}
@Override
public JSONObject toJson() {
JSONObject jsonObject=new JSONObject();
jsonObject.put(NAME_node_type, NAME_text);
jsonObject.put(NAME_text, getText());
return jsonObject;
}
@Override
public void fromJson(JSONObject json) {
setText(json.optString(NAME_text, null));
setLineNumber(getParentResXmlElement().getStartLineNumber());
}
public XMLText decodeToXml() {
XMLText xmlText=new XMLText(XmlSanitizer.escapeSpecialCharacter(getText()));
xmlText.setLineNumber(getLineNumber());
return xmlText;
}
@Override
public String toString(){
return "line = " + getLineNumber() + ", \"" + getText() + "\"";
}
private static String decodeEntityRef(String entityRef) {
if(entityRef == null){
return "";
}
String decode;
if(entityRef.equals("lt")){
decode = "<";
}else if(entityRef.equals("gt")){
decode = ">";
}else if(entityRef.equals("amp")){
decode = "&";
}else if(entityRef.equals("quote")){
decode = "\"";
}else {
decode = "&" + entityRef + ";";
}
return decode;
}
static boolean isTextEvent(int event){
return event == XmlPullParser.TEXT
|| event == XmlPullParser.ENTITY_REF;
}
private static boolean isIndent(String text){
if(text.length() == 0){
return true;
}
char[] chars = text.toCharArray();
if(chars[0] != '\n'){
return false;
}
for(int i = 1; i < chars.length; i++){
if(chars[i] != ' '){
return false;
}
}
return true;
}
public static final String NAME_text="text";
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy