Adding rest utility component
diff --git a/pom.xml b/pom.xml
index eb54458..190e1f1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,6 +74,7 @@
<module>spring-cache</module>
<module>spring-taskqueue</module>
<module>spring-quartz</module>
+ <module>rest-util</module>
</modules>
<repositories>
@@ -188,6 +189,12 @@
<version>${jakarta.annotation.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
+ <version>${jakarta.ws.rs.version}</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
@@ -228,6 +235,17 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>io.swagger.core.v3</groupId>
+ <artifactId>swagger-core</artifactId>
+ <version>${io.swagger.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.swagger.core.v3</groupId>
+ <artifactId>swagger-annotations</artifactId>
+ <version>${io.swagger.version}</version>
+ </dependency>
+
</dependencies>
</dependencyManagement>
<dependencies>
diff --git a/rest-util/pom.xml b/rest-util/pom.xml
new file mode 100644
index 0000000..ecc9f78
--- /dev/null
+++ b/rest-util/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>archiva-components</artifactId>
+ <groupId>org.apache.archiva.components</groupId>
+ <version>3.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <name>Archiva Components :: REST Utility</name>
+ <description>Utility classes for REST services used by Redback and Archiva.</description>
+
+ <artifactId>archiva-components-rest-util</artifactId>
+
+ <properties>
+ <maven.compiler.source>8</maven.compiler.source>
+ <maven.compiler.target>8</maven.compiler.target>
+ <site.staging.base>${project.parent.basedir}</site.staging.base>
+ </properties>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.swagger.core.v3</groupId>
+ <artifactId>swagger-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.swagger.core.v3</groupId>
+ <artifactId>swagger-annotations</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+
+ </dependencies>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${javadocPluginVersion}</version>
+ <inherited>false</inherited>
+ <reportSets>
+ <reportSet>
+ <id>aggregate</id>
+ <reports>
+ <report>aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+
+
+</project>
diff --git a/rest-util/src/main/java/org/apache/archiva/components/rest/model/BeanInformation.java b/rest-util/src/main/java/org/apache/archiva/components/rest/model/BeanInformation.java
new file mode 100644
index 0000000..57b3a31
--- /dev/null
+++ b/rest-util/src/main/java/org/apache/archiva/components/rest/model/BeanInformation.java
@@ -0,0 +1,91 @@
+package org.apache.archiva.components.rest.model;/*
+ * 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.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@XmlRootElement(name="beanInformation")
+public class BeanInformation implements Serializable
+{
+ private static final long serialVersionUID = -432385743277355987L;
+ String id;
+ String displayName;
+ String descriptionKey;
+ String defaultDescription;
+ boolean readonly;
+
+ @Schema(description = "The identifier")
+ public String getId( )
+ {
+ return id;
+ }
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+ @Schema(description = "The display name")
+ public String getDisplayName( )
+ {
+ return displayName;
+ }
+
+ public void setDisplayName( String displayName )
+ {
+ this.displayName = displayName;
+ }
+
+ @Schema(description = "The translation key for the description")
+ public String getDescriptionKey( )
+ {
+ return descriptionKey;
+ }
+
+ public void setDescriptionKey( String descriptionKey )
+ {
+ this.descriptionKey = descriptionKey;
+ }
+
+ @Schema(description = "The description translated in the default language")
+ public String getDefaultDescription( )
+ {
+ return defaultDescription;
+ }
+
+ public void setDefaultDescription( String defaultDescription )
+ {
+ this.defaultDescription = defaultDescription;
+ }
+
+ @Schema(description = "True, if this bean cannot be removed")
+ public boolean isReadonly( )
+ {
+ return readonly;
+ }
+
+ public void setReadonly( boolean readonly )
+ {
+ this.readonly = readonly;
+ }
+}
diff --git a/rest-util/src/main/java/org/apache/archiva/components/rest/model/PagedResult.java b/rest-util/src/main/java/org/apache/archiva/components/rest/model/PagedResult.java
new file mode 100644
index 0000000..786c1b8
--- /dev/null
+++ b/rest-util/src/main/java/org/apache/archiva/components/rest/model/PagedResult.java
@@ -0,0 +1,71 @@
+package org.apache.archiva.components.rest.model;
+
+/*
+ * 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.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+/**
+ * A Paged result puts the data into an envelope
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@XmlRootElement(name="pagedResult")
+@Schema(name = "PagedResult", description = "Contains paged data. Pages are defined by limit and offset.")
+public class PagedResult<T>
+{
+ PaginationInfo pagination;
+ List<T> data;
+
+ public PagedResult() {
+
+ }
+
+ public PagedResult( int totalCount, int offset, int limit, List<T> data ) {
+ this.data = data;
+ this.pagination = new PaginationInfo( totalCount, offset, limit );
+ }
+
+ public static final <T> PagedResult<T> of(int totalSize, int offset, int limit, List<T> element) {
+ return new PagedResult( totalSize, offset, limit, element);
+ }
+
+ @Schema(description = "This is the payload of the paged data. The type of data depends on the REST method. ")
+ public List<T> getData( )
+ {
+ return data;
+ }
+
+ public void setData( List<T> data )
+ {
+ this.data = data;
+ }
+
+ @Schema(description = "The pagination information")
+ public PaginationInfo getPagination( )
+ {
+ return pagination;
+ }
+
+ public void setPagination( PaginationInfo pagination )
+ {
+ this.pagination = pagination;
+ }
+}
diff --git a/rest-util/src/main/java/org/apache/archiva/components/rest/model/PaginationInfo.java b/rest-util/src/main/java/org/apache/archiva/components/rest/model/PaginationInfo.java
new file mode 100644
index 0000000..3755522
--- /dev/null
+++ b/rest-util/src/main/java/org/apache/archiva/components/rest/model/PaginationInfo.java
@@ -0,0 +1,82 @@
+package org.apache.archiva.components.rest.model;
+
+/*
+ * 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.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ *
+ * Informational attributes for pagination.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@XmlRootElement(name="pagination")
+@Schema(name="PaginationInfo", description = "Contains paging information (limit, offset, totalCount)")
+public class PaginationInfo
+{
+ long totalCount;
+ long offset;
+ long limit;
+
+ public PaginationInfo() {
+
+ }
+
+ public PaginationInfo( long totalCount, long offset, long limit )
+ {
+ this.totalCount = totalCount;
+ this.offset = offset;
+ this.limit = limit;
+ }
+
+ @Schema(description = "The total number of data available.")
+ public long getTotalCount( )
+ {
+ return totalCount;
+ }
+
+ public void setTotalCount( long totalCount )
+ {
+ this.totalCount = totalCount;
+ }
+
+ @Schema(description = "The offset of the first element of the returned dataset.")
+ public long getOffset( )
+ {
+ return offset;
+ }
+
+ public void setOffset( long offset )
+ {
+ this.offset = offset;
+ }
+
+ @Schema(description = "The maximum number of elements returned per page.")
+ public long getLimit( )
+ {
+ return limit;
+ }
+
+ public void setLimit( long limit )
+ {
+ this.limit = limit;
+ }
+}
diff --git a/rest-util/src/main/java/org/apache/archiva/components/rest/model/PropertyEntry.java b/rest-util/src/main/java/org/apache/archiva/components/rest/model/PropertyEntry.java
new file mode 100644
index 0000000..ef41ef2
--- /dev/null
+++ b/rest-util/src/main/java/org/apache/archiva/components/rest/model/PropertyEntry.java
@@ -0,0 +1,85 @@
+package org.apache.archiva.components.rest.model;/*
+ * 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.
+ */
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+@XmlRootElement(name="propertyEntry")
+@Schema(name="PropertyEntry", description = "Key/Value-Pair")
+public class PropertyEntry implements Serializable
+{
+ private static final long serialVersionUID = -4486042628710420898L;
+ private String key;
+ private String value;
+
+ public String getKey( )
+ {
+ return key;
+ }
+
+ public void setKey( String key )
+ {
+ this.key = key;
+ }
+
+ public String getValue( )
+ {
+ return value;
+ }
+
+ public void setValue( String value )
+ {
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( o == null || getClass( ) != o.getClass( ) ) return false;
+
+ PropertyEntry that = (PropertyEntry) o;
+
+ if ( !Objects.equals( key, that.key ) ) return false;
+ return Objects.equals( value, that.value );
+ }
+
+ @Override
+ public int hashCode( )
+ {
+ int result = key != null ? key.hashCode( ) : 0;
+ result = 31 * result + ( value != null ? value.hashCode( ) : 0 );
+ return result;
+ }
+
+ @Override
+ public String toString( )
+ {
+ final StringBuilder sb = new StringBuilder( "PropertyEntry{" );
+ sb.append( "key='" ).append( key ).append( '\'' );
+ sb.append( ", value='" ).append( value ).append( '\'' );
+ sb.append( '}' );
+ return sb.toString( );
+ }
+}
diff --git a/rest-util/src/main/java/org/apache/archiva/components/rest/util/PagingHelper.java b/rest-util/src/main/java/org/apache/archiva/components/rest/util/PagingHelper.java
new file mode 100644
index 0000000..13cbbfe
--- /dev/null
+++ b/rest-util/src/main/java/org/apache/archiva/components/rest/util/PagingHelper.java
@@ -0,0 +1,47 @@
+package org.apache.archiva.components.rest.util;
+
+/*
+ * 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.
+ */
+
+
+import org.apache.archiva.components.rest.model.PagedResult;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Helper class for creating paged results.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class PagingHelper
+{
+ public static <T> PagedResult<T> getResultFromList( int offset, int limit, List<T> data) {
+ if (offset>=data.size()) {
+ return new PagedResult<>( data.size( ), offset, limit, Collections.emptyList( ) );
+ }
+ int lastIndex = getLastIndex( offset, limit, data.size( ) );
+ return new PagedResult<>( data.size(), offset, limit, data.subList( offset, lastIndex ) );
+ }
+
+ public static int getLastIndex(int offset, int limit, int listSize) {
+ return Math.min( Math.max( 0, offset + limit ), listSize );
+ }
+
+
+}
diff --git a/rest-util/src/main/java/org/apache/archiva/components/rest/util/QueryHelper.java b/rest-util/src/main/java/org/apache/archiva/components/rest/util/QueryHelper.java
new file mode 100644
index 0000000..a111fab
--- /dev/null
+++ b/rest-util/src/main/java/org/apache/archiva/components/rest/util/QueryHelper.java
@@ -0,0 +1,168 @@
+package org.apache.archiva.components.rest.util;/*
+ * 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.
+ */
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ *
+ * Helper class that returns combined filter and comparison objects for ordering.
+ *
+ * The query term may be consist of simple query terms separated by whitespace or attribute queries
+ * in the form <code>attribute:query</code>, which means only the attribute is searched for the query string.
+ * <br />
+ * Example:
+ * <dl>
+ * <dt>`user1 test`</dt>
+ * <dd>
+ * searches for the tokens user1 and test in the default attributes.
+ * </dd>
+ * <dt>`user1 name:test`</dt>
+ * <dd>searches for the token user1 in the default attributes and for the token test in the attribute name.</dd>
+ * </dl>
+ *
+ *
+ * @since 3.0
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class QueryHelper<T>
+{
+
+ private final Map<String, BiPredicate<String, T>> FILTER_MAP;
+ private final Map<String, Comparator<T>> ORDER_MAP;
+ private final String[] DEFAULT_SEARCH_FIELDS;
+ private final Predicate<T> DEFAULT_FILTER = ( T att ) -> false;
+
+
+ /**
+ * Creates a new query helper with the given filters and comparators.
+ *
+ * @param filterMap a map of filters, where the key is the attribute name and the value is a predicate that matches
+ * the filter value and the object instance.
+ * @param orderMap a map of comparators, where key is the attribute name and the value is a comparator for the given
+ * object instance
+ * @param defaultSearchFields A array of attribute names, that are used as default search fields.
+ */
+ public QueryHelper(Map<String, BiPredicate<String, T>> filterMap, Map<String, Comparator<T>> orderMap,
+ String[] defaultSearchFields)
+ {
+ this.FILTER_MAP = filterMap;
+ this.DEFAULT_SEARCH_FIELDS = defaultSearchFields;
+ this.ORDER_MAP = new HashMap<>( orderMap );
+ }
+
+ public <U extends Comparable<? super U>> void addNullsafeFieldComparator( String fieldName, Function<? super T, U> keyExtractor) {
+ ORDER_MAP.put( fieldName, Comparator.comparing( keyExtractor, Comparator.nullsLast( Comparator.naturalOrder( ) ) ) );
+ }
+
+ public void addStringFilter(String attribute, Function<? super T, String> keyExtractor) {
+ this.FILTER_MAP.put( attribute, ( String q, T r ) -> StringUtils.containsIgnoreCase( keyExtractor.apply( r ), q ) );
+ }
+
+ public void addBooleanFilter(String attribute, Function<? super T, Boolean> keyExtractor) {
+ this.FILTER_MAP.put( attribute, ( String q, T r ) -> Boolean.valueOf( q ) == keyExtractor.apply( r ) );
+ }
+
+ /**
+ * Get the comparator for a specific attribute.
+ * @param attributeName the name of the attribute.
+ * @return
+ */
+ Comparator<T> getAttributeComparator( String attributeName )
+ {
+ return ORDER_MAP.get( attributeName );
+ }
+
+ /**
+ * Get the combined order for the given attributes in the given order.
+ *
+ * @param orderBy the attributes to compare. The first attribute in the list will be used first for comparing.
+ * @param ascending
+ * @return
+ */
+ Comparator<T> getComparator( List<String> orderBy, boolean ascending )
+ {
+ if ( ascending )
+ {
+ return orderBy.stream( ).map( ( String name ) -> getAttributeComparator( name ) ).filter( Objects::nonNull )
+ .reduce( Comparator::thenComparing )
+ .orElseThrow( () -> new IllegalArgumentException( "No attribute ordering found" ) );
+ }
+
+ else
+ {
+ return orderBy.stream( ).map( ( String name ) -> getAttributeComparator( name ) == null ? null : getAttributeComparator( name )
+ .reversed( ) ).filter( Objects::nonNull ).reduce( Comparator::thenComparing )
+ .orElseThrow( () -> new IllegalArgumentException( "No attribute ordering found" ) );
+ }
+ }
+
+ /**
+ * Returns a query filter for a specific attribute and query token.
+ * @param attribute the attribute name to filter for.
+ * @param queryToken the search token.
+ * @return The predicate used to filter the token
+ */
+ Predicate<T> getAttributeQueryFilter( final String attribute, final String queryToken )
+ {
+ if ( FILTER_MAP.containsKey( attribute ) )
+ {
+ return ( T u ) -> FILTER_MAP.get( attribute ).test( queryToken, u );
+ }
+ else
+ {
+ return DEFAULT_FILTER;
+ }
+ }
+
+ /**
+ * Returns the combined query filter for the given query terms.
+ * The query terms may be either simple strings separated by whitespace or use the
+ * <code>attribute:query</code> syntax, that searches only the attribute for the query term.
+ * @param queryTerms the query string
+ * @return the combined query filter
+ */
+ Predicate<T> getQueryFilter( String queryTerms )
+ {
+ return Arrays.stream( queryTerms.split( "\\s+" ) )
+ .map( s -> {
+ if ( s.contains( ":" ) )
+ {
+ String attr = StringUtils.substringBefore( s, ":" );
+ String term = StringUtils.substringAfter( s, ":" );
+ return getAttributeQueryFilter( attr, term );
+ }
+ else
+ {
+ return Arrays.stream( DEFAULT_SEARCH_FIELDS )
+ .map( att -> getAttributeQueryFilter( att, s ) ).reduce( Predicate::or ).get( );
+ }
+ }
+ ).reduce( Predicate::or ).get( );
+ }
+
+}
diff --git a/rest-util/src/main/java/org/apache/archiva/components/rest/util/RestUtil.java b/rest-util/src/main/java/org/apache/archiva/components/rest/util/RestUtil.java
new file mode 100644
index 0000000..da745a6
--- /dev/null
+++ b/rest-util/src/main/java/org/apache/archiva/components/rest/util/RestUtil.java
@@ -0,0 +1,59 @@
+package org.apache.archiva.components.rest.util;/*
+ * 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.
+ */
+
+import org.apache.commons.lang3.StringUtils;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriInfo;
+
+/**
+ * Central utility class that may be used by service implementations.
+ *
+ * @author Martin Stockhammer <martin_s@apache.org>
+ */
+public class RestUtil
+{
+ /**
+ * Returns <code>false</code>, if the given parameter is not present in the given uriInfo, or is present and set to 'false' or '0'.
+ * In all other cases it returns <code>true</code>.
+ *
+ * This means you can activate a flag by setting '?param', '?param=true', '?param=1', ...
+ * It is deactivated, if the parameter is absent, or '?param=false', or '?param=0'
+ *
+ * @param uriInfo the uriInfo context instance, that is used to check for the parameter
+ * @param queryParameterName the query parameter name
+ * @return
+ */
+ public static boolean isFlagSet( final UriInfo uriInfo, final String queryParameterName) {
+ MultivaluedMap<String, String> params = uriInfo.getQueryParameters( );
+ if (!params.containsKey( queryParameterName )) {
+ return false;
+ }
+ // parameter is available
+ String value = params.getFirst( queryParameterName );
+ // if its available but without a value it is flagged as present
+ if (StringUtils.isEmpty( value )) {
+ return true;
+ }
+ // if it has a value, we check for false values:
+ if ("false".equalsIgnoreCase( value ) || "0".equalsIgnoreCase( value )) {
+ return false;
+ }
+ return true;
+ }
+}