001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.config;
018
019 import com.intellij.openapi.util.Key;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.Nullable;
022
023 import java.util.*;
024
025 @SuppressWarnings("unchecked")
026 public class CompilerConfiguration {
027 public static CompilerConfiguration EMPTY = new CompilerConfiguration();
028
029 private final Map<Key, Object> map = new HashMap<Key, Object>();
030 private boolean readOnly = false;
031
032 static {
033 EMPTY.setReadOnly(true);
034 }
035
036 @Nullable
037 public <T> T get(@NotNull CompilerConfigurationKey<T> key) {
038 T data = (T) map.get(key.ideaKey);
039 return data == null ? null : unmodifiable(data);
040 }
041
042 @NotNull
043 public <T> T get(@NotNull CompilerConfigurationKey<T> key, @NotNull T defaultValue) {
044 T data = get(key);
045 return data == null ? defaultValue : data;
046 }
047
048 @NotNull
049 public <T> T getNotNull(@NotNull CompilerConfigurationKey<T> key) {
050 T data = get(key);
051 assert data != null : "No value for configuration key: " + key;
052 return data;
053 }
054
055 public boolean getBoolean(@NotNull CompilerConfigurationKey<Boolean> key) {
056 return get(key, false);
057 }
058
059 @NotNull
060 public <T> List<T> getList(@NotNull CompilerConfigurationKey<List<T>> key) {
061 List<T> data = get(key);
062 return data == null ? Collections.<T>emptyList() : data;
063 }
064
065 @NotNull
066 public <K, V> Map<K, V> getMap(@NotNull CompilerConfigurationKey<Map<K, V>> key) {
067 Map<K, V> data = get(key);
068 return data == null ? Collections.<K, V>emptyMap() : data;
069 }
070
071 public <T> void put(@NotNull CompilerConfigurationKey<T> key, @NotNull T value) {
072 checkReadOnly();
073 map.put(key.ideaKey, value);
074 }
075
076 public <T> void add(@NotNull CompilerConfigurationKey<List<T>> key, @NotNull T value) {
077 checkReadOnly();
078 Key<List<T>> ideaKey = key.ideaKey;
079 if (map.get(ideaKey) == null) {
080 map.put(ideaKey, new ArrayList<T>());
081 }
082 List<T> list = (List<T>) map.get(ideaKey);
083 list.add(value);
084 }
085
086 public <K, V> void put(@NotNull CompilerConfigurationKey<Map<K, V>> configurationKey, @NotNull K key, @NotNull V value) {
087 checkReadOnly();
088 Key<Map<K, V>> ideaKey = configurationKey.ideaKey;
089 if (map.get(ideaKey) == null) {
090 map.put(ideaKey, new HashMap<K, V>());
091 }
092 Map<K, V> data = (Map<K, V>) map.get(ideaKey);
093 data.put(key, value);
094 }
095
096 public <T> void addAll(@NotNull CompilerConfigurationKey<List<T>> key, @NotNull Collection<T> values) {
097 checkReadOnly();
098 checkForNullElements(values);
099 Key<List<T>> ideaKey = key.ideaKey;
100 if (map.get(ideaKey) == null) {
101 map.put(ideaKey, new ArrayList<T>());
102 }
103 List<T> list = (List<T>) map.get(ideaKey);
104 list.addAll(values);
105 }
106
107 public CompilerConfiguration copy() {
108 CompilerConfiguration copy = new CompilerConfiguration();
109 copy.map.putAll(map);
110 return copy;
111 }
112
113 private void checkReadOnly() {
114 if (readOnly) {
115 throw new IllegalStateException("CompilerConfiguration is read-only");
116 }
117 }
118
119 public void setReadOnly(boolean readOnly) {
120 if (readOnly != this.readOnly) {
121 this.readOnly = readOnly;
122 }
123 }
124
125 public boolean isReadOnly() {
126 return readOnly;
127 }
128
129 @NotNull
130 private static <T> T unmodifiable(@NotNull T object) {
131 if (object instanceof List) {
132 return (T) Collections.unmodifiableList((List) object);
133 }
134 else if (object instanceof Map) {
135 return (T) Collections.unmodifiableMap((Map) object);
136 }
137 else if (object instanceof Collection) {
138 return (T) Collections.unmodifiableCollection((Collection) object);
139 }
140 else {
141 return object;
142 }
143 }
144
145 @Override
146 public String toString() {
147 return map.toString();
148 }
149
150 private static <T> void checkForNullElements(Collection<T> values) {
151 int index = 0;
152 for (T value : values) {
153 if (value == null) {
154 throw new IllegalArgumentException("Element " + index
155 + " is null, while null values in compiler configuration are not allowed");
156 }
157 index++;
158 }
159 }
160 }