com.reandroid.common.ReferenceResolver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ARSCLib Show documentation
Show all versions of ARSCLib Show documentation
Android binary resources read/write library
/*
* 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.common;
import com.reandroid.arsc.chunk.TableBlock;
import com.reandroid.arsc.model.ResourceEntry;
import com.reandroid.arsc.value.Entry;
import com.reandroid.arsc.value.ResConfig;
import com.reandroid.arsc.value.ResValue;
import com.reandroid.arsc.value.ValueType;
import java.util.*;
import java.util.function.Predicate;
public class ReferenceResolver{
private final TableBlock entryStore;
private final List results;
private final Set resolvedIds;
private int limit;
public ReferenceResolver(TableBlock entryStore){
this.entryStore = entryStore;
this.results = new ArrayList<>();
this.resolvedIds = new HashSet<>();
this.limit = -1;
}
public Entry resolve(int referenceId){
return resolve(referenceId, null);
}
public synchronized Entry resolve(int referenceId, Predicate filter){
resolveReference(referenceId, filter);
List results = new ArrayList<>(this.results);
reset();
if(results.size() > 0){
return results.get(0);
}
return null;
}
public List resolveWithConfig(int referenceId, ResConfig resConfig){
ConfigFilter configFilter = new ConfigFilter(resConfig);
List results = resolveAll(referenceId, configFilter);
results.sort(configFilter);
return results;
}
public List resolveAll(int referenceId){
return resolveAll(referenceId, (Predicate)null);
}
public synchronized List resolveAll(int referenceId, Predicate filter){
resolveReference(referenceId, filter);
List results = new ArrayList<>(this.results);
reset();
return results;
}
private void resolveReference(int referenceId, Predicate filter){
if(referenceId == 0 || isFinished() || this.resolvedIds.contains(referenceId)){
return;
}
this.resolvedIds.add(referenceId);
List entryList = listNonNullEntries(referenceId);
List results = this.results;
for(Entry entry:entryList){
if(isFinished()){
return;
}
if(results.contains(entry)){
continue;
}
if(entry.isComplex()){
addResult(filter, entry);
continue;
}
ResValue resValue = entry.getResValue();
if(resValue.getValueType() != ValueType.REFERENCE){
addResult(filter, entry);
continue;
}
resolveReference(resValue.getData(), filter);
}
}
private void reset(){
this.results.clear();
this.resolvedIds.clear();
this.limit = -1;
}
private boolean isFinished(){
return this.limit >= this.results.size();
}
private void addResult(Predicate filter, Entry entry){
if(filter == null || filter.test(entry)){
this.results.add(entry);
}
}
private List listNonNullEntries(int resourceId){
List results = new ArrayList<>();
ResourceEntry resourceEntry = this.entryStore.getResource(resourceId);
if(resourceEntry == null){
return results;
}
Iterator itr = resourceEntry.iterator(true);
while (itr.hasNext()){
results.add(itr.next());
}
return results;
}
public static class ConfigFilter implements Predicate, Comparator{
private final ResConfig config;
public ConfigFilter(ResConfig config){
this.config = config;
}
@Override
public boolean test(Entry entry) {
ResConfig resConfig = entry.getResConfig();
if(resConfig == null){
return false;
}
return resConfig.isEqualOrMoreSpecificThan(this.config);
}
@Override
public int compare(Entry entry1, Entry entry2) {
ResConfig config1 = entry1.getResConfig();
ResConfig config2 = entry2.getResConfig();
if (config.equals(config1)){
return -1;
}
if(config.equals(config2)){
return 1;
}
return 0;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy