/* * Copyright 2000-2016 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 com.intellij.openapi.editor.colors.impl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import java.awt.Color; /** * This class is intended to read a value from the value element * that is the element, which value is defined in the {@code value} attribute. * Also it may have the following platform-specific attributes: * {@code windows}, {@code mac}, {@code linux}. If one of them is set, * it should be used instead of the default one. * * @author Sergey.Malenkov */ @SuppressWarnings("UseJBColor") class ValueElementReader { @NonNls private static final String VALUE = "value"; @NonNls private static final String MAC = "mac"; @NonNls private static final String LINUX = "linux"; @NonNls private static final String WINDOWS = "windows"; private static final String OS = SystemInfo.isWindows ? WINDOWS : SystemInfo.isMac ? MAC : LINUX; private static final Logger LOG = Logger.getInstance(ValueElementReader.class); private String myAttribute; /** * Initializes the attribute that should be checked before * the {@code value} attribute and before the platform-specific attributes. * * @param attribute the priority attribute */ public void setAttribute(String attribute) { myAttribute = StringUtil.isEmpty(attribute) ? null : attribute; } /** * Reads a value of the specified type from the given element. * * @param type the class that defines the result type * @param element the value element * @param <T> the result type * @return a value or {@code null} if it cannot be read */ @Nullable public <T> T read(Class<T> type, Element element) { T value = null; if (element != null) { if (myAttribute != null) { value = read(type, element, myAttribute); } if (value == null) { value = read(type, element, OS); if (value == null) { value = read(type, element, VALUE); } } } return value; } /** * Reads a value of the specified type * from the specified attribute of the given element. * * @param type the class that defines the result type * @param element the value element * @param attribute the attribute that contains a value * @param <T> the result type * @return a value or {@code null} if it cannot be read */ private <T> T read(Class<T> type, Element element, String attribute) { String value = element.getAttributeValue(attribute); if (value != null) { value = value.trim(); if (value.isEmpty()) { if (LOG.isDebugEnabled()) LOG.debug("empty attribute: " + attribute); } else { try { return convert(type, value); } catch (Exception exception) { if (LOG.isDebugEnabled()) LOG.debug("wrong attribute: " + attribute, exception); } } } return null; } /** * Converts a string value of the specified type * from the specified attribute of the given element. * * @param type the class that defines the result type * @param value a string value to convert * @param <T> the result type */ protected <T> T convert(Class<T> type, String value) { if (String.class.equals(type)) { //noinspection unchecked return (T)value; } if (Integer.class.equals(type)) { //noinspection unchecked return (T)Integer.valueOf(value); } if (Float.class.equals(type)) { //noinspection unchecked return (T)Float.valueOf(value); } if (Color.class.equals(type)) { //noinspection unchecked return (T)toColor(value); } if (Enum.class.isAssignableFrom(type)) { //noinspection unchecked return (T)toEnum((Class<Enum>)type, value); } if (Boolean.class.equals(type)) { //noinspection unchecked return (T)Boolean.valueOf(value); } throw new IllegalArgumentException("unsupported " + type); } private static <T extends Enum> T toEnum(Class<T> type, String value) { for (T field : type.getEnumConstants()) { if (value.equalsIgnoreCase(field.name()) || value.equals(String.valueOf(field.ordinal()))) { return field; } } throw new IllegalArgumentException(value); } private static Color toColor(String value) { int rgb; try { rgb = Integer.parseInt(value, 16); } catch (NumberFormatException ignored) { rgb = Integer.decode(value); } return new Color(rgb); } }