You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by fo...@apache.org on 2020/12/22 12:54:34 UTC
svn commit: r1884702 - in /jackrabbit/oak/trunk:
oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/
oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/async/
oak-search-elastic/src/test...
Author: fortino
Date: Tue Dec 22 12:54:34 2020
New Revision: 1884702
URL: http://svn.apache.org/viewvc?rev=1884702&view=rev
Log:
OAK-9302: oak-search-elastic -> configurable query fetch sizes
Modified:
jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexDefinition.java
jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/async/ElasticResultRowAsyncIterator.java
jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticAbstractQueryTest.java
jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticContentTest.java
jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/IndexDefinition.java
jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/util/ConfigUtil.java
Modified: jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexDefinition.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexDefinition.java?rev=1884702&r1=1884701&r2=1884702&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexDefinition.java (original)
+++ jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexDefinition.java Tue Dec 22 12:54:34 2020
@@ -31,6 +31,7 @@ import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import static org.apache.jackrabbit.oak.plugins.index.search.util.ConfigUtil.getOptionalValue;
+import static org.apache.jackrabbit.oak.plugins.index.search.util.ConfigUtil.getOptionalValues;
public class ElasticIndexDefinition extends IndexDefinition {
@@ -57,6 +58,9 @@ public class ElasticIndexDefinition exte
public static final String NUMBER_OF_REPLICAS = "numberOfReplicas";
public static final int NUMBER_OF_REPLICAS_DEFAULT = 1;
+ public static final String QUERY_FETCH_SIZES = "queryFetchSizes";
+ public static final Long[] QUERY_FETCH_SIZES_DEFAULT = new Long[]{100L, 1000L};
+
/**
* Hidden property for storing a seed value to be used as suffix in remote index name.
*/
@@ -95,6 +99,7 @@ public class ElasticIndexDefinition exte
private final String remoteAlias;
public final int numberOfShards;
public final int numberOfReplicas;
+ public final int[] queryFetchSizes;
private final Map<String, List<PropertyDefinition>> propertiesByName;
private final List<PropertyDefinition> dynamicBoostProperties;
@@ -109,6 +114,8 @@ public class ElasticIndexDefinition exte
this.bulkRetriesBackoff = getOptionalValue(defn, BULK_RETRIES_BACKOFF, BULK_RETRIES_BACKOFF_DEFAULT);
this.numberOfShards = getOptionalValue(defn, NUMBER_OF_SHARDS, NUMBER_OF_SHARDS_DEFAULT);
this.numberOfReplicas = getOptionalValue(defn, NUMBER_OF_REPLICAS, NUMBER_OF_REPLICAS_DEFAULT);
+ this.queryFetchSizes = Arrays.stream(getOptionalValues(defn, QUERY_FETCH_SIZES, Type.LONGS, Long.class, QUERY_FETCH_SIZES_DEFAULT))
+ .mapToInt(Long::intValue).toArray();
this.propertiesByName = getDefinedRules()
.stream()
Modified: jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/async/ElasticResultRowAsyncIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/async/ElasticResultRowAsyncIterator.java?rev=1884702&r1=1884701&r2=1884702&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/async/ElasticResultRowAsyncIterator.java (original)
+++ jackrabbit/oak/trunk/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elastic/query/async/ElasticResultRowAsyncIterator.java Tue Dec 22 12:54:34 2020
@@ -169,8 +169,6 @@ public class ElasticResultRowAsyncIterat
class ElasticQueryScanner implements ActionListener<SearchResponse> {
private static final int SMALL_RESULT_SET_SIZE = 10;
- private static final int MEDIUM_RESULT_SET_SIZE = 100;
- private static final int LARGE_RESULT_SET_SIZE = 1000;
private final Set<ElasticResponseListener> allListeners = new HashSet<>();
private final List<SearchHitListener> searchHitListeners = new ArrayList<>();
@@ -183,9 +181,9 @@ public class ElasticResultRowAsyncIterat
// concurrent data structures to coordinate chunks loading
private final AtomicBoolean anyDataLeft = new AtomicBoolean(false);
- private int scannedRows = 0;
- private boolean firstRequest = true;
- private boolean fullScan = false;
+ private int scannedRows;
+ private int requests;
+ private boolean fullScan;
private long searchStartTime;
// reference to the last document sort values for search_after queries
@@ -224,9 +222,9 @@ public class ElasticResultRowAsyncIterat
final SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
.query(query)
- // use a smaller size when the client asks for facets. This improves performance
+ // use a smaller size when the query contains aggregations. This improves performance
// when the client is only interested in insecure facets
- .size(needsAggregations.get() ? SMALL_RESULT_SET_SIZE : MEDIUM_RESULT_SET_SIZE)
+ .size(needsAggregations.get() ? Math.min(SMALL_RESULT_SET_SIZE, getFetchSize(requests)) : getFetchSize(requests))
.fetchSource(sourceFields, null);
this.sorts.forEach(searchSourceBuilder::sort);
@@ -242,6 +240,7 @@ public class ElasticResultRowAsyncIterat
semaphore.tryAcquire();
searchStartTime = System.currentTimeMillis();
+ requests++;
indexNode.getConnection().getClient().searchAsync(searchRequest, RequestOptions.DEFAULT, this);
elasticMetricHandler.markQuery(true);
}
@@ -271,7 +270,7 @@ public class ElasticResultRowAsyncIterat
// now that we got the last hit we can release the semaphore to potentially unlock other requests
semaphore.release();
- if (firstRequest) {
+ if (requests == 1) {
for (SearchHitListener l : searchHitListeners) {
l.startData(totalHits);
}
@@ -283,8 +282,6 @@ public class ElasticResultRowAsyncIterat
l.on(aggregations);
}
}
-
- firstRequest = false;
}
LOG.trace("Emitting {} search hits, for a total of {} scanned results", searchHits.length, scannedRows);
@@ -321,7 +318,7 @@ public class ElasticResultRowAsyncIterat
if (semaphore.tryAcquire() && anyDataLeft.get()) {
final SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
.query(query)
- .size(LARGE_RESULT_SET_SIZE)
+ .size(getFetchSize(requests++))
.fetchSource(sourceFields, null)
.searchAfter(lastHitSortValues);
@@ -339,6 +336,13 @@ public class ElasticResultRowAsyncIterat
}
}
+ /* picks the size in the fetch array at index=requests or the last if out of bound */
+ private int getFetchSize(int requestId) {
+ int[] queryFetchSizes = indexNode.getDefinition().queryFetchSizes;
+ return queryFetchSizes.length > requestId ?
+ queryFetchSizes[requestId] : queryFetchSizes[queryFetchSizes.length -1];
+ }
+
// close all listeners
private void close() {
semaphore.release();
Modified: jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticAbstractQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticAbstractQueryTest.java?rev=1884702&r1=1884701&r2=1884702&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticAbstractQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticAbstractQueryTest.java Tue Dec 22 12:54:34 2020
@@ -143,8 +143,7 @@ public abstract class ElasticAbstractQue
esConnection = elasticRule.useDocker() ? elasticRule.getElasticConnectionForDocker() :
elasticRule.getElasticConnectionFromString();
ElasticIndexEditorProvider editorProvider = getElasticIndexEditorProvider(esConnection);
- ElasticIndexProvider indexProvider = new ElasticIndexProvider(esConnection,
- new ElasticMetricHandler(StatisticsProvider.NOOP));
+ ElasticIndexProvider indexProvider = new ElasticIndexProvider(esConnection, getMetricHandler());
nodeStore = getNodeStore();
@@ -172,6 +171,10 @@ public abstract class ElasticAbstractQue
return oak.createContentRepository();
}
+ protected ElasticMetricHandler getMetricHandler() {
+ return new ElasticMetricHandler(StatisticsProvider.NOOP);
+ }
+
protected void assertEventually(Runnable r) {
ElasticTestUtils.assertEventually(r,
((useAsyncIndexing() ? DEFAULT_ASYNC_INDEXING_TIME_IN_SECONDS : 0) + BULK_FLUSH_INTERVAL_MS_DEFAULT) * 5);
Modified: jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticContentTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticContentTest.java?rev=1884702&r1=1884701&r2=1884702&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticContentTest.java (original)
+++ jackrabbit/oak/trunk/oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticContentTest.java Tue Dec 22 12:54:34 2020
@@ -17,20 +17,39 @@
package org.apache.jackrabbit.oak.plugins.index.elastic;
import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
import org.junit.Ignore;
import org.junit.Test;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Random;
import java.util.UUID;
+import java.util.function.BiConsumer;
+import java.util.stream.IntStream;
import static org.apache.jackrabbit.oak.plugins.index.elastic.ElasticTestUtils.randomString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
public class ElasticContentTest extends ElasticAbstractQueryTest {
+ private final ElasticMetricHandler spyMetricHandler = spy(new ElasticMetricHandler(StatisticsProvider.NOOP));
+
+ @Override
+ protected ElasticMetricHandler getMetricHandler() {
+ return spyMetricHandler;
+ }
+
@Test
public void indexWithAnalyzedProperty() throws Exception {
IndexDefinitionBuilder builder = createIndex("a").noAsync();
@@ -115,7 +134,7 @@ public class ElasticContentTest extends
assertTrue(exists(index));
builder = createIndex("a").noAsync();
- index = setIndex(testId, builder);
+ setIndex(testId, builder);
root.commit();
}
@@ -135,4 +154,43 @@ public class ElasticContentTest extends
assertEventually(() -> assertThat(countDocuments(index), equalTo(1L)));
}
+
+ @Test
+ public void indexWithCustomFetchSizes() throws Exception {
+ BiConsumer<String, Iterable<Long>> buildIndex = (p, fetchSizes) -> {
+ IndexDefinitionBuilder builder = createIndex(p).noAsync();
+ builder.getBuilderTree().setProperty("queryFetchSizes", fetchSizes, Type.LONGS);
+ builder.indexRule("nt:base").property(p).propertyIndex();
+ setIndex(UUID.randomUUID().toString(), builder);
+ };
+
+ buildIndex.accept("a", Collections.singletonList(1L));
+ buildIndex.accept("b", Arrays.asList(1L, 2L));
+ buildIndex.accept("c", Arrays.asList(3L, 100L));
+ root.commit();
+
+ Tree content = root.getTree("/").addChild("content");
+ IntStream.range(0, 3).forEach(n -> {
+ Tree child = content.addChild("child_" + n);
+ child.setProperty("a", "text");
+ child.setProperty("b", "text");
+ child.setProperty("c", "text");
+ }
+ );
+ root.commit(Collections.singletonMap("sync-mode", "rt"));
+
+ List<String> results = Arrays.asList("/content/child_0", "/content/child_1", "/content/child_2");
+
+ reset(spyMetricHandler);
+ assertQuery("select [jcr:path] from [nt:base] where [a] = 'text'", results);
+ verify(spyMetricHandler, times(3)).markQuery(anyBoolean());
+
+ reset(spyMetricHandler);
+ assertQuery("select [jcr:path] from [nt:base] where [b] = 'text'", results);
+ verify(spyMetricHandler, times(2)).markQuery(anyBoolean());
+
+ reset(spyMetricHandler);
+ assertQuery("select [jcr:path] from [nt:base] where [c] = 'text'", results);
+ verify(spyMetricHandler, times(1)).markQuery(anyBoolean());
+ }
}
Modified: jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/IndexDefinition.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/IndexDefinition.java?rev=1884702&r1=1884701&r2=1884702&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/IndexDefinition.java (original)
+++ jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/IndexDefinition.java Tue Dec 22 12:54:34 2020
@@ -85,6 +85,7 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants.*;
import static org.apache.jackrabbit.oak.plugins.index.search.PropertyDefinition.DEFAULT_BOOST;
import static org.apache.jackrabbit.oak.plugins.index.search.util.ConfigUtil.getOptionalValue;
+import static org.apache.jackrabbit.oak.plugins.index.search.util.ConfigUtil.getOptionalValues;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
import static org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants.NODE_TYPES_PATH;
@@ -362,7 +363,7 @@ public class IndexDefinition implements
this.definition = defn;
this.indexPath = checkNotNull(indexPath);
this.indexName = indexPath;
- this.indexTags = getOptionalStrings(defn, IndexConstants.INDEX_TAGS);
+ this.indexTags = getOptionalValues(defn, IndexConstants.INDEX_TAGS, Type.STRINGS, String.class);
this.nodeTypeIndex = getOptionalValue(defn, FulltextIndexConstants.PROP_INDEX_NODE_TYPE, false);
this.blobSize = getOptionalValue(defn, BLOB_SIZE, DEFAULT_BLOB_SIZE);
@@ -411,7 +412,7 @@ public class IndexDefinition implements
this.scorerProviderName = getOptionalValue(defn, FulltextIndexConstants.PROP_SCORER_PROVIDER, null);
this.reindexCount = getOptionalValue(defn, REINDEX_COUNT, 0);
this.pathFilter = PathFilter.from(new ReadOnlyBuilder(defn));
- this.queryPaths = getOptionalStrings(defn, IndexConstants.QUERY_PATHS);
+ this.queryPaths = getOptionalValues(defn, IndexConstants.QUERY_PATHS, Type.STRINGS, String.class);
this.suggestAnalyzed = evaluateSuggestAnalyzed(defn, false);
{
@@ -678,8 +679,7 @@ public class IndexDefinition implements
@Nullable
public Aggregate getAggregate(String nodeType){
- Aggregate agg = aggregates.get(nodeType);
- return agg;
+ return aggregates.get(nodeType);
}
private Map<String, Aggregate> collectAggregates(NodeState defn) {
@@ -728,8 +728,7 @@ public class IndexDefinition implements
List<IndexingRule> rules = null;
List<IndexingRule> r = indexRules.get(primaryNodeType);
if (r != null) {
- rules = new ArrayList<IndexingRule>();
- rules.addAll(r);
+ rules = new ArrayList<>(r);
}
if (rules != null) {
@@ -758,15 +757,14 @@ public class IndexDefinition implements
List<IndexingRule> rules = null;
List<IndexingRule> r = indexRules.get(getPrimaryTypeName(state));
if (r != null) {
- rules = new ArrayList<IndexingRule>();
- rules.addAll(r);
+ rules = new ArrayList<>(r);
}
for (String name : getMixinTypeNames(state)) {
r = indexRules.get(name);
if (r != null) {
if (rules == null) {
- rules = new ArrayList<IndexingRule>();
+ rules = new ArrayList<>();
}
rules.addAll(r);
}
@@ -819,11 +817,7 @@ public class IndexDefinition implements
for (String ntName : ntNames) {
if (ntReg.isNodeType(ntName, rule.getNodeTypeName())) {
- List<IndexingRule> perNtConfig = nt2rules.get(ntName);
- if (perNtConfig == null) {
- perNtConfig = new ArrayList<IndexingRule>();
- nt2rules.put(ntName, perNtConfig);
- }
+ List<IndexingRule> perNtConfig = nt2rules.computeIfAbsent(ntName, k -> new ArrayList<>());
log.trace("Registering rule '{}' for name '{}'", rule, ntName);
perNtConfig.add(new IndexingRule(rule, ntName));
}
@@ -837,11 +831,6 @@ public class IndexDefinition implements
return ImmutableMap.copyOf(nt2rules);
}
- private boolean areAllTypesIndexed() {
- IndexingRule ntBaseRule = getApplicableIndexingRule(NT_BASE);
- return ntBaseRule != null;
- }
-
private boolean evaluateSuggestionEnabled() {
for (IndexingRule indexingRule : definedRules) {
for (PropertyDefinition propertyDefinition : indexingRule.propConfigs.values()) {
@@ -1505,7 +1494,7 @@ public class IndexDefinition implements
}
}
- List<String> propNames = new ArrayList<String>(propNamesSet);
+ List<String> propNames = new ArrayList<>(propNamesSet);
final String includeAllProp = FulltextIndexConstants.REGEX_ALL_PROPS;
if (fullTextEnabled
@@ -1616,7 +1605,7 @@ public class IndexDefinition implements
private static Set<String> getMultiProperty(NodeState definition, String propName){
PropertyState pse = definition.getProperty(propName);
- return pse != null ? ImmutableSet.copyOf(pse.getValue(Type.STRINGS)) : Collections.<String>emptySet();
+ return pse != null ? ImmutableSet.copyOf(pse.getValue(Type.STRINGS)) : Collections.emptySet();
}
private static Set<String> toLowerCase(Set<String> values) {
@@ -1784,14 +1773,6 @@ public class IndexDefinition implements
return result;
}
- private static String[] getOptionalStrings(NodeState defn, String propertyName) {
- PropertyState ps = defn.getProperty(propertyName);
- if (ps != null) {
- return Iterables.toArray(ps.getValue(Type.STRINGS), String.class);
- }
- return null;
- }
-
private static IndexFormatVersion versionFrom(PropertyState ps){
return IndexFormatVersion.getVersion(Ints.checkedCast(ps.getValue(Type.LONG)));
}
Modified: jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/util/ConfigUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/util/ConfigUtil.java?rev=1884702&r1=1884701&r2=1884702&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/util/ConfigUtil.java (original)
+++ jackrabbit/oak/trunk/oak-search/src/main/java/org/apache/jackrabbit/oak/plugins/index/search/util/ConfigUtil.java Tue Dec 22 12:54:34 2020
@@ -21,6 +21,7 @@ package org.apache.jackrabbit.oak.plugin
import java.util.Collections;
+import com.google.common.collect.Iterables;
import com.google.common.primitives.Ints;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.Blob;
@@ -40,10 +41,10 @@ public class ConfigUtil {
public static boolean getOptionalValue(NodeState definition, String propName, boolean defaultVal) {
try {
- PropertyState ps = definition.getProperty(propName);
- return ps == null ? defaultVal : ps.getValue(Type.BOOLEAN);
+ PropertyState ps = definition.getProperty(propName);
+ return ps == null ? defaultVal : ps.getValue(Type.BOOLEAN);
} catch (IllegalStateException e) {
- throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
+ throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
}
}
@@ -52,7 +53,7 @@ public class ConfigUtil {
PropertyState ps = definition.getProperty(propName);
return ps == null ? defaultVal : Ints.checkedCast(ps.getValue(Type.LONG));
} catch (IllegalStateException e) {
- throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
+ throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
}
}
@@ -61,7 +62,7 @@ public class ConfigUtil {
PropertyState ps = definition.getProperty(propName);
return ps == null ? defaultVal : ps.getValue(Type.STRING);
} catch (IllegalStateException e) {
- throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
+ throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
}
}
@@ -70,7 +71,7 @@ public class ConfigUtil {
PropertyState ps = definition.getProperty(propName);
return ps == null ? defaultVal : ps.getValue(Type.DOUBLE).floatValue();
} catch (IllegalStateException e) {
- throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
+ throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
}
}
@@ -79,10 +80,10 @@ public class ConfigUtil {
PropertyState ps = definition.getProperty(propName);
return ps == null ? defaultVal : ps.getValue(Type.DOUBLE);
} catch (IllegalStateException e) {
- throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
+ throw new IllegalStateException(String.format(ILLEGAL_STATE_EXCEPTION_ERROR_MESSAGE, propName), e);
}
}
-
+
public static long getOptionalValue(NodeState definition, String propName, long defaultVal) {
try {
PropertyState ps = definition.getProperty(propName);
@@ -103,7 +104,7 @@ public class ConfigUtil {
public static Iterable<String> getMixinNames(NodeState nodeState) {
PropertyState ps = nodeState.getProperty(JcrConstants.JCR_MIXINTYPES);
- return (ps == null) ? Collections.<String>emptyList() : ps.getValue(Type.NAMES);
+ return (ps == null) ? Collections.emptyList() : ps.getValue(Type.NAMES);
}
/**
@@ -117,4 +118,22 @@ public class ConfigUtil {
PropertyState property = contentNode.getProperty(JcrConstants.JCR_DATA);
return property != null ? property.getValue(Type.BINARY) : null;
}
+
+ /**
+ * Returns an array of optional values for the a given property
+ */
+ public static<T> T[] getOptionalValues(NodeState definition, String propName, Type<Iterable<T>> type, Class<T> typeParam) {
+ return getOptionalValues(definition, propName, type, typeParam, null);
+ }
+
+ /**
+ * Returns an array of optional values for the a given property if present, otherwise returns the specified default
+ */
+ public static<T> T[] getOptionalValues(NodeState definition, String propName, Type<Iterable<T>> type, Class<T> typeParam, T[] defaultValues) {
+ PropertyState ps = definition.getProperty(propName);
+ if (ps != null) {
+ return Iterables.toArray(ps.getValue(type), typeParam);
+ }
+ return defaultValues;
+ }
}