/** * Copyright 2011-2017 Asakusa Framework Team. * * Licensed 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. */ package com.asakusafw.windgate.core; import java.text.MessageFormat; import java.util.Map; import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.asakusafw.windgate.core.util.PropertiesUtil; /** * A core profile for WindGate execution. * @since 0.2.2 * @version 0.2.4 */ public class CoreProfile { static final WindGateLogger WGLOG = new WindGateCoreLogger(CoreProfile.class); static final Logger LOG = LoggerFactory.getLogger(CoreProfile.class); private static final char QUALIFIER = '.'; /** * Prefix of property keys about core. */ public static final String KEY_PREFIX = "core" + QUALIFIER; // //$NON-NLS-1$ /** * The key name of {@link #getMaxProcesses()} (deprecated). * @deprecated use instead {@link #KEY_MAX_PROCESSES} */ @Deprecated public static final String KEY_MAX_THREADS = "maxThreads"; /** * The key name of {@link #getMaxProcesses()}. */ public static final String KEY_MAX_PROCESSES = "maxProcesses"; /** * The default value of {@link #KEY_MAX_PROCESSES}. */ public static final int DEFAULT_MAX_PROCESSES = 1; private final int maxProcesses; /** * Creates a new instance. * @param maxProcesses the number of max threads in core gate processes * @throws IllegalArgumentException if the {@code maxThreads} is less than {@code 1} */ public CoreProfile(int maxProcesses) { if (maxProcesses < 1) { throw new IllegalArgumentException("maxProcesses must be a positive integer"); //$NON-NLS-1$ } this.maxProcesses = maxProcesses; } /** * the number of max threads in core gate processes. * @return the number of max threads */ public int getMaxProcesses() { return maxProcesses; } /** * Loads a core profile from the properties. * @param properties source properties * @param loader class loader to load the provider classes * @return the loaded profile * @throws IllegalArgumentException if properties are invalid, or if any parameter is {@code null} * @deprecated use {@link #loadFrom(Properties, ProfileContext)} instead */ @Deprecated public static CoreProfile loadFrom(Properties properties, ClassLoader loader) { if (properties == null) { throw new IllegalArgumentException("properties must not be null"); //$NON-NLS-1$ } if (loader == null) { throw new IllegalArgumentException("loader must not be null"); //$NON-NLS-1$ } return loadFrom(properties, ProfileContext.system(loader)); } /** * Loads a core profile from the properties. * @param properties source properties * @param context the current profile context * @return the loaded profile * @throws IllegalArgumentException if properties are invalid, or if any parameter is {@code null} * @since 0.2.4 */ public static CoreProfile loadFrom(Properties properties, ProfileContext context) { if (properties == null) { throw new IllegalArgumentException("properties must not be null"); //$NON-NLS-1$ } if (context == null) { throw new IllegalArgumentException("context must not be null"); //$NON-NLS-1$ } LOG.debug("Restoring core profile"); Map<String, String> config = PropertiesUtil.createPrefixMap(properties, KEY_PREFIX); int maxProcesses; if (config.containsKey(KEY_MAX_PROCESSES)) { maxProcesses = getMaxProcesses(config, KEY_MAX_PROCESSES); } else { // for legacy spec maxProcesses = getMaxProcesses(config, KEY_MAX_THREADS); } return new CoreProfile(maxProcesses); } private static int getMaxProcesses(Map<String, String> config, String key) { assert config != null; assert key != null; int maxProcesses = getInt(config, key, DEFAULT_MAX_PROCESSES); if (maxProcesses <= 0) { WGLOG.error("E02003", key, maxProcesses); throw new IllegalArgumentException(MessageFormat.format( "Core profile item \"{0}\" must be > 0: {1}", key, String.valueOf(maxProcesses))); } return maxProcesses; } private static int getInt(Map<String, String> config, String name, int defaultValue) { assert config != null; assert name != null; String value = config.get(name); if (value == null) { LOG.debug("Core profile \"{}\" is not defined, default value \"{}\" will be used.", name, defaultValue); return defaultValue; } try { return Integer.parseInt(value); } catch (NumberFormatException e) { WGLOG.error("E02003", name, value); throw new IllegalArgumentException(MessageFormat.format( "Core profile item \"{0}\" must be an integer: {1}", name, value)); } } /** * Stores this profile into the specified properties. * @param properties target properties object * @throws IllegalArgumentException if target properties already contains keys about this process, * or if any parameter is {@code null} */ public void storeTo(Properties properties) { if (properties == null) { throw new IllegalArgumentException("properties must not be null"); //$NON-NLS-1$ } LOG.debug("Saving core profile"); PropertiesUtil.checkAbsentKeyPrefix(properties, KEY_PREFIX); properties.setProperty(KEY_PREFIX + KEY_MAX_PROCESSES, String.valueOf(getMaxProcesses())); } /** * Removes entries corresponding to process profiles. * @param properties target properties * @throws IllegalArgumentException if any parameter is {@code null} */ public static void removeCorrespondingKeys(Properties properties) { if (properties == null) { throw new IllegalArgumentException("properties must not be null"); //$NON-NLS-1$ } PropertiesUtil.removeKeyPrefix(properties, KEY_PREFIX); } }