/* * Copyright 2010-2015 JetBrains s.r.o. * * 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 org.jetbrains.kotlin.test; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import kotlin.Pair; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; public class SettingsConfigurator { public static final String SET_TRUE_DIRECTIVE = "SET_TRUE:"; public static final String SET_FALSE_DIRECTIVE = "SET_FALSE:"; private static final String SET_INT_DIRECTIVE = "SET_INT:"; private final String[] settingsToTrue; private final String[] settingsToFalse; private final Pair<String, Integer>[] settingsToIntValue; private final Object[] objects; public SettingsConfigurator(String fileText, Object... objects) { settingsToTrue = InTextDirectivesUtils.findArrayWithPrefixes(fileText, SET_TRUE_DIRECTIVE); settingsToFalse = InTextDirectivesUtils.findArrayWithPrefixes(fileText, SET_FALSE_DIRECTIVE); //noinspection unchecked settingsToIntValue = ContainerUtil.map2Array( InTextDirectivesUtils.findArrayWithPrefixes(fileText, SET_INT_DIRECTIVE), Pair.class, new Function<String, Pair>() { @SuppressWarnings("unchecked") @Override public Pair fun(String s) { String[] tokens = s.split("="); return new Pair(tokens[0].trim(), Integer.valueOf(tokens[1].trim())); } } ); this.objects = objects; } private static void setSettingValue(String settingName, Object value, Class<?> valueType, Object... objects) { for (Object object : objects) { if (setSettingWithField(settingName, object, value) || setSettingWithMethod(settingName, object, value, valueType)) { return; } } throw new IllegalArgumentException(String.format( "There's no property or method with name '%s' in given objects: %s", settingName, Arrays.toString(objects))); } private static void setBooleanSetting(String setting, Boolean value, Object... objects) { setSettingValue(setting, value, boolean.class, objects); } private static void setIntSetting(String setting, Integer value, Object... objects) { setSettingValue(setting, value, int.class, objects); } public void configureSettings() { for (String trueSetting : settingsToTrue) { setBooleanSetting(trueSetting, true, objects); } for (String falseSetting : settingsToFalse) { setBooleanSetting(falseSetting, false, objects); } for (Pair<String, Integer> setting : settingsToIntValue) { setIntSetting(setting.getFirst(), setting.getSecond(), objects); } } public void configureInvertedSettings() { for (String trueSetting : settingsToTrue) { setBooleanSetting(trueSetting, false, objects); } for (String falseSetting : settingsToFalse) { setBooleanSetting(falseSetting, true, objects); } for (Pair<String, Integer> setting : settingsToIntValue) { setIntSetting(setting.getFirst(), setting.getSecond(), objects); } } private static boolean setSettingWithField(String settingName, Object object, Object value) { try { Field field = object.getClass().getDeclaredField(settingName); field.set(object, value); return true; } catch (IllegalAccessException e) { throw new IllegalArgumentException(String.format("Can't set property with the name %s in object %s", settingName, object)); } catch (NoSuchFieldException e) { // Do nothing - will try other variants } return false; } private static boolean setSettingWithMethod(String setterName, Object object, Object value, Class<?> valueType) { try { Method method = object.getClass().getMethod(setterName, valueType); method.invoke(object, value); return true; } catch (InvocationTargetException e) { throw new IllegalArgumentException(String.format("Can't call method with name %s for object %s", setterName, object)); } catch (IllegalAccessException e) { throw new IllegalArgumentException(String.format("Can't access to method with name %s for object %s", setterName, object)); } catch (NoSuchMethodException e) { // Do nothing - will try other variants } return false; } }