mirror of
https://github.com/revanced/ARSCLib.git
synced 2025-05-03 23:54:27 +02:00
140 lines
4.3 KiB
Java
140 lines
4.3 KiB
Java
/*
|
|
* 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.xml;
|
|
|
|
import com.reandroid.xml.parser.XMLSpanParser;
|
|
|
|
import java.util.*;
|
|
|
|
public class XMLSpannable implements Comparable<XMLSpannable>{
|
|
private XMLElement mElement;
|
|
private String mText;
|
|
private List<XMLSpanInfo> mSpanInfoList;
|
|
private XMLSpannable(XMLElement element){
|
|
this.mElement=element;
|
|
}
|
|
public boolean isValid(){
|
|
List<XMLSpanInfo> spanInfoList = getSpanInfoList();
|
|
if(spanInfoList.size()==0){
|
|
return false;
|
|
}
|
|
for(XMLSpanInfo spanInfo:spanInfoList){
|
|
if(spanInfo.end<spanInfo.start){
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
public String getText(){
|
|
if(mText==null){
|
|
buildSpanInfo();
|
|
}
|
|
return mText;
|
|
}
|
|
public List<XMLSpanInfo> getSpanInfoList(){
|
|
if(mSpanInfoList==null){
|
|
buildSpanInfo();
|
|
}
|
|
return mSpanInfoList;
|
|
}
|
|
private void buildSpanInfo(){
|
|
mSpanInfoList=new ArrayList<>();
|
|
StringBuilder builder=new StringBuilder();
|
|
buildSpanInfo(mElement, builder);
|
|
mText=builder.toString();
|
|
mElement=null;
|
|
}
|
|
private void buildSpanInfo(XMLElement element, StringBuilder builder){
|
|
XMLSpanInfo info=null;
|
|
for(XMLNode node:element.listSpannable()){
|
|
if(info!=null){
|
|
info.end=builder.length();
|
|
info=null;
|
|
}
|
|
if(node instanceof XMLText){
|
|
builder.append(((XMLText)node).getText());
|
|
continue;
|
|
}
|
|
XMLElement child = (XMLElement) node;
|
|
info=new XMLSpanInfo(
|
|
child.getSpannableText(),
|
|
builder.length(), 0);
|
|
mSpanInfoList.add(info);
|
|
buildSpanInfo(child, builder);
|
|
}
|
|
if(info!=null){
|
|
info.end=builder.length();
|
|
}
|
|
}
|
|
@Override
|
|
public int compareTo(XMLSpannable xmlSpannable) {
|
|
return getText().compareTo(xmlSpannable.getText());
|
|
}
|
|
|
|
public static XMLSpannable parse(String text){
|
|
if(!hasStyle(text)){
|
|
return null;
|
|
}
|
|
try {
|
|
XMLSpannable spannable=new XMLSpannable(PARSER.parse(text));
|
|
if(spannable.isValid()){
|
|
return spannable;
|
|
}
|
|
} catch (Exception ignored) {
|
|
}
|
|
return null;
|
|
}
|
|
public static Set<String> tagList(Collection<XMLSpannable> spannableList){
|
|
Set<String> results=new HashSet<>();
|
|
for(XMLSpannable xmlSpannable:spannableList){
|
|
for(XMLSpanInfo spanInfo: xmlSpannable.getSpanInfoList()){
|
|
results.add(spanInfo.tag);
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
public static List<String> toTextList(Collection<XMLSpannable> spannableList){
|
|
List<String> results=new ArrayList<>(spannableList.size());
|
|
for(XMLSpannable xmlSpannable:spannableList){
|
|
results.add(xmlSpannable.getText());
|
|
}
|
|
return results;
|
|
}
|
|
public static void sort(List<XMLSpannable> spannableList){
|
|
Comparator<XMLSpannable> cmp=new Comparator<XMLSpannable>() {
|
|
@Override
|
|
public int compare(XMLSpannable s1, XMLSpannable s2) {
|
|
return s1.compareTo(s2);
|
|
}
|
|
};
|
|
spannableList.sort(cmp);
|
|
}
|
|
private static boolean hasStyle(String text){
|
|
if(text==null){
|
|
return false;
|
|
}
|
|
int i=text.indexOf('<');
|
|
if(i<0){
|
|
return false;
|
|
}
|
|
i=text.indexOf('>');
|
|
return i>1;
|
|
}
|
|
|
|
private static final XMLSpanParser PARSER=new XMLSpanParser();
|
|
|
|
}
|