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.commons.settings;
018
019import java.util.function.*;
020
021import org.apache.juneau.commons.function.*;
022import org.apache.juneau.commons.runtime.*;
023
024/**
025 * Property source backed by {@link ManifestFile}.
026 */
027public class ManifestFilePropertySource implements PropertySource {
028
029   private final Supplier<ManifestFile> manifestSupplier;
030
031   /**
032    * Constructor.
033    *
034    * <p>
035    * The supplied {@code manifestSupplier} is wrapped in a {@link Memoizer} so the manifest is loaded at most once
036    * per source instance.  Without this, every {@link #get(String)} call would re-scan the classpath, which is very
037    * expensive and shows up as a 2x test-suite regression when this source is registered in {@link Settings}.
038    *
039    * @param manifestSupplier The supplier for manifest file.  Must not be <jk>null</jk>.
040    */
041   public ManifestFilePropertySource(Supplier<ManifestFile> manifestSupplier) {
042      this.manifestSupplier = new Memoizer<>(manifestSupplier);
043   }
044
045   /**
046    * Creates a source with default classloader scanning behavior.
047    *
048    * @return A new source.
049    */
050   public static ManifestFilePropertySource createDefault() {
051      return new ManifestFilePropertySource(() -> {
052         try {
053            return new ManifestFile(ManifestFilePropertySource.class);
054         } catch (@SuppressWarnings("unused") Exception unused) {
055            return null;
056         }
057      });
058   }
059
060   @Override
061   public PropertyLookupResult get(String name) {
062      var mf = manifestSupplier.get();
063      if (mf == null)
064         return PropertyLookupResult.missing();
065      var v = mf.get(name);
066      return v.isPresent() ? PropertyLookupResult.present(v) : PropertyLookupResult.missing();
067   }
068}