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.debug;
018
019import static org.apache.juneau.rest.annotation.RestOpAnnotation.*;
020
021import java.util.*;
022
023import org.apache.juneau.*;
024import org.apache.juneau.common.utils.*;
025import org.apache.juneau.cp.*;
026import org.apache.juneau.reflect.*;
027import org.apache.juneau.rest.*;
028import org.apache.juneau.rest.annotation.*;
029import org.apache.juneau.svl.*;
030
031/**
032 * Default implementation of the {@link DebugEnablement} interface.
033 *
034 * <p>
035 * Enables debug mode based on the following annotations:
036 * <ul>
037 *    <li class='ja'>{@link Rest#debug()}
038 *    <li class='ja'>{@link RestOp#debug()}
039 *    <li class='ja'>{@link Rest#debugOn()}
040 * </ul>
041 *
042 * <h5 class='section'>See Also:</h5><ul>
043 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerLoggingAndDebugging">Logging / Debugging</a>
044 * </ul>
045 */
046public class BasicDebugEnablement extends DebugEnablement {
047
048   /**
049    * Constructor.
050    *
051    * @param beanStore The bean store containing injectable beans for this enablement.
052    */
053   public BasicDebugEnablement(BeanStore beanStore) {
054      super(beanStore);
055   }
056
057   @Override
058   protected Builder init(BeanStore beanStore) {
059      Builder b = super.init(beanStore);
060
061      DefaultSettingsMap defaultSettings = beanStore.getBean(DefaultSettingsMap.class).get();
062      RestContext.Builder builder = beanStore.getBean(RestContext.Builder.class).get();
063      ResourceSupplier resource = beanStore.getBean(ResourceSupplier.class).get();
064      VarResolver varResolver = beanStore.getBean(VarResolver.class).get();
065
066      // Default debug enablement if not overridden at class/method level.
067      Enablement debugDefault = defaultSettings.get(Enablement.class, "RestContext.debugDefault").orElse(builder.isDebug() ? Enablement.ALWAYS : Enablement.NEVER);
068      b.defaultEnable(debugDefault);
069
070      ClassInfo ci = ClassInfo.ofProxy(resource.get());
071
072      // Gather @Rest(debug) settings.
073      ci.forEachAnnotation(
074         Rest.class,
075         x -> true,
076         x -> {
077            String x2 = varResolver.resolve(x.debug());
078            if (! x2.isEmpty())
079               b.enable(Enablement.fromString(x2), ci.getFullName());
080         }
081      );
082
083      // Gather @RestOp(debug) settings.
084      ci.forEachPublicMethod(
085         x -> true,
086         x -> {
087            x.getAnnotationList(REST_OP_GROUP).forEachValue(
088               String.class,
089               "debug",
090               y -> true,
091               y -> {
092                  String y2 = varResolver.resolve(y);
093                  if (! y2.isEmpty())
094                     b.enable(Enablement.fromString(y2), x.getFullName());
095               }
096            );
097         }
098      );
099
100      // Gather @Rest(debugOn) settings.
101      ci.forEachAnnotation(
102         Rest.class,
103         x -> true,
104         x -> {
105            String x2 = varResolver.resolve(x.debugOn());
106            for (Map.Entry<String,String> e : Utils.splitMap(x2, true).entrySet()) {
107               String k = e.getKey(), v = e.getValue();
108               if (v.isEmpty())
109                  v = "ALWAYS";
110               if (! k.isEmpty())
111                  b.enable(Enablement.fromString(v), k);
112            }
113         }
114      );
115
116      return b;
117   }
118}