001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.server.matcher;
018
019import static org.apache.juneau.commons.utils.CollectionUtils.*;
020import static org.apache.juneau.commons.utils.Shorts.*;
021
022import java.util.*;
023
024import org.apache.juneau.commons.inject.*;
025
026/**
027 * A list of {@link RestMatcher} objects.
028 *
029 * <h5 class='section'>See Also:</h5><ul>
030 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestOpAnnotatedMethods">@RestOp-Annotated Method</a>
031 * </ul>
032 */
033public class RestMatcherList {
034
035   /**
036    * Builder class.
037    */
038   public static class Builder {
039
040      private final BeanStore beanStore;
041      List<BeanInstantiator.Builder<RestMatcher>> entries;
042
043      /**
044       * Constructor.
045       *
046       * @param beanStore The bean store to use for creating beans.
047       */
048      protected Builder(BeanStore beanStore) {
049         this.beanStore = beanStore;
050         entries = list();
051      }
052
053      /**
054       * Returns the bean store used by this builder.
055       *
056       * @return The bean store used by this builder.
057       */
058      public BeanStore beanStore() {
059         return beanStore;
060      }
061
062      /**
063       * Appends the specified rest matcher classes to the list.
064       *
065       * @param values The values to add.
066       *    <br>Must not be <jk>null</jk>.
067       * @return This object.
068       */
069      @SuppressWarnings({
070         "unchecked" // Varargs with generics require unchecked cast
071      })
072      public Builder append(Class<? extends RestMatcher>...values) {
073         for (var v : values)
074            entries.add(BeanInstantiator.of(RestMatcher.class, beanStore).type(v));
075         return this;
076      }
077
078      /**
079       * Appends the specified rest matcher objects to the list.
080       *
081       * @param values The values to add.
082       *    <br>Must not be <jk>null</jk>.
083       * @return This object.
084       */
085      public Builder append(RestMatcher...values) {
086         for (var v : values)
087            entries.add(BeanInstantiator.of(RestMatcher.class, beanStore).impl(v));
088         return this;
089      }
090
091      /**
092       * Builds the list.
093       *
094       * @return A new {@link RestMatcherList}.
095       */
096      public RestMatcherList build() {
097         return new RestMatcherList(this);
098      }
099   }
100
101   /**
102    * Static creator.
103    *
104    * @param beanStore The bean store to use for creating beans.
105    * @return A new builder for this object.
106    */
107   public static Builder create(BeanStore beanStore) {
108      return new Builder(beanStore);
109   }
110
111   private final RestMatcher[] optionalEntries;
112   private final RestMatcher[] requiredEntries;
113
114   /**
115    * Constructor.
116    *
117    * @param builder The builder containing the contents for this list.
118    *    <br>Must not be <jk>null</jk>.
119    */
120   protected RestMatcherList(Builder builder) {
121      List<RestMatcher> l = builder.entries.stream().map(BeanInstantiator.Builder::run).toList();
122      optionalEntries = l.stream().filter(x -> ! x.required()).toArray(RestMatcher[]::new);
123      requiredEntries = l.stream().filter(RestMatcher::required).toArray(RestMatcher[]::new);
124   }
125
126   /**
127    * Returns the entries in this list that are specified as optional.
128    *
129    * @return An unmodifiable list of entries in this list that are specified as optional.
130    */
131   public RestMatcher[] getOptionalEntries() { return cp(optionalEntries); }
132
133   /**
134    * Returns the entries in this list that are specified as required.
135    *
136    * @return An unmodifiable list of entries in this list that are specified as required.
137    */
138   public RestMatcher[] getRequiredEntries() { return cp(requiredEntries); }
139}