001/*
002 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.debug;
024
025import java.io.*;
026import java.util.*;
027
028import com.oracle.graal.debug.internal.*;
029
030public class DelegatingDebugConfig implements DebugConfig {
031
032    protected final DebugConfig delegate;
033
034    /**
035     * The features of a {@link DelegatingDebugConfig} that can be force
036     * {@linkplain DelegatingDebugConfig#enable(Feature) enabled}/
037     * {@linkplain DelegatingDebugConfig#disable(Feature) disabled} or
038     * {@linkplain DelegatingDebugConfig#delegate(Feature) delegated}.
039     */
040    public enum Feature {
041        /**
042         * @see Debug#isLogEnabledForMethod()
043         */
044        LOG_METHOD,
045        /**
046         * @see Debug#isDumpEnabledForMethod()
047         */
048        DUMP_METHOD,
049        /**
050         * @see Debug#isVerifyEnabled()
051         */
052        VERIFY,
053        /**
054         * @see Debug#isVerifyEnabledForMethod()
055         */
056        VERIFY_METHOD,
057        /**
058         * @see Debug#isMeterEnabled()
059         */
060        METER,
061        /**
062         * @see Debug#isMemUseTrackingEnabled()
063         */
064        TRACK_MEM_USE,
065        /**
066         * @see Debug#isTimeEnabled()
067         */
068        TIME,
069        /**
070         * @see DebugConfig#interceptException(Throwable)
071         */
072        INTERCEPT
073    }
074
075    private final Map<Feature, Boolean> featureState = new EnumMap<>(Feature.class);
076
077    /**
078     * The debug levels of a {@link DelegatingDebugConfig} than can be
079     * {@linkplain DelegatingDebugConfig#override(Level, int) overridden} or
080     * {@linkplain DelegatingDebugConfig#delegate(Level) delegated}.
081     */
082    public enum Level {
083        LOG,
084        DUMP
085    }
086
087    private final Map<Level, Integer> levelState = new EnumMap<>(Level.class);
088
089    /**
090     * Creates a config that delegates to the {@link DebugScope#getConfig() current config}.
091     */
092    public DelegatingDebugConfig() {
093        this(DebugScope.getConfig());
094    }
095
096    /**
097     * Creates a config that delegates to a given config.
098     */
099    public DelegatingDebugConfig(DebugConfig delegate) {
100        this.delegate = delegate;
101    }
102
103    public DelegatingDebugConfig enable(Feature feature) {
104        featureState.put(feature, Boolean.TRUE);
105        return this;
106    }
107
108    public DelegatingDebugConfig disable(Feature feature) {
109        featureState.put(feature, Boolean.FALSE);
110        return this;
111    }
112
113    public DelegatingDebugConfig override(Level level, int newLevel) {
114        levelState.put(level, newLevel);
115        return this;
116    }
117
118    public DelegatingDebugConfig delegate(Feature feature) {
119        featureState.put(feature, null);
120        return this;
121    }
122
123    public DelegatingDebugConfig delegate(Level level) {
124        levelState.put(level, null);
125        return this;
126    }
127
128    @Override
129    public int getLogLevel() {
130        Integer ls = levelState.get(Level.LOG);
131        if (ls == null) {
132            return delegate.getLogLevel();
133        }
134        return ls.intValue();
135    }
136
137    public boolean isLogEnabledForMethod() {
138        Boolean fs = featureState.get(Feature.LOG_METHOD);
139        if (fs == null) {
140            return delegate.isLogEnabledForMethod();
141        }
142        return fs.booleanValue();
143    }
144
145    @Override
146    public boolean isMeterEnabled() {
147        Boolean fs = featureState.get(Feature.METER);
148        if (fs == null) {
149            return delegate.isMeterEnabled();
150        }
151        return fs.booleanValue();
152    }
153
154    public boolean isMemUseTrackingEnabled() {
155        Boolean fs = featureState.get(Feature.TRACK_MEM_USE);
156        if (fs == null) {
157            return delegate.isMemUseTrackingEnabled();
158        }
159        return fs.booleanValue();
160    }
161
162    @Override
163    public int getDumpLevel() {
164        Integer ls = levelState.get(Level.DUMP);
165        if (ls == null) {
166            return delegate.getDumpLevel();
167        }
168        return ls.intValue();
169    }
170
171    public boolean isDumpEnabledForMethod() {
172        Boolean fs = featureState.get(Feature.DUMP_METHOD);
173        if (fs == null) {
174            return delegate.isDumpEnabledForMethod();
175        }
176        return fs.booleanValue();
177    }
178
179    @Override
180    public boolean isVerifyEnabled() {
181        Boolean fs = featureState.get(Feature.VERIFY);
182        if (fs == null) {
183            return delegate.isVerifyEnabled();
184        }
185        return fs.booleanValue();
186    }
187
188    public boolean isVerifyEnabledForMethod() {
189        Boolean fs = featureState.get(Feature.VERIFY_METHOD);
190        if (fs == null) {
191            return delegate.isVerifyEnabledForMethod();
192        }
193        return fs.booleanValue();
194    }
195
196    @Override
197    public boolean isTimeEnabled() {
198        Boolean fs = featureState.get(Feature.TIME);
199        if (fs == null) {
200            return delegate.isTimeEnabled();
201        }
202        return fs.booleanValue();
203    }
204
205    @Override
206    public RuntimeException interceptException(Throwable e) {
207        Boolean fs = featureState.get(Feature.INTERCEPT);
208        if (fs == null || fs) {
209            return delegate.interceptException(e);
210        }
211        return null;
212    }
213
214    @Override
215    public Collection<DebugDumpHandler> dumpHandlers() {
216        return delegate.dumpHandlers();
217    }
218
219    @Override
220    public Collection<DebugVerifyHandler> verifyHandlers() {
221        return delegate.verifyHandlers();
222    }
223
224    @Override
225    public PrintStream output() {
226        return delegate.output();
227    }
228
229    @Override
230    public void addToContext(Object o) {
231        delegate.addToContext(o);
232    }
233
234    @Override
235    public void removeFromContext(Object o) {
236        delegate.removeFromContext(o);
237    }
238}