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 private final Map<Key, Object> map = new HashMap<Key, Object>();
028 private boolean readOnly = false;
029
030 @Nullable
031 public <T> T get(@NotNull CompilerConfigurationKey<T> key) {
032 T data = (T) map.get(key.ideaKey);
033 return data == null ? null : unmodifiable(data);
034 }
035
036 @NotNull
037 public <T> T get(@NotNull CompilerConfigurationKey<T> key, @NotNull T defaultValue) {
038 T data = get(key);
039 return data == null ? defaultValue : data;
040 }
041
042 @NotNull
043 public <T> T getNotNull(@NotNull CompilerConfigurationKey<T> key) {
044 T data = get(key);
045 assert data != null : "No value for configuration key: " + key;
046 return data;
047 }
048
049 public boolean getBoolean(@NotNull CompilerConfigurationKey<Boolean> key) {
050 return get(key, false);
051 }
052
053 @NotNull
054 public <T> List<T> getList(@NotNull CompilerConfigurationKey<List<T>> key) {
055 List<T> data = get(key);
056 return data == null ? Collections.<T>emptyList() : data;
057 }
058
059 public <T> void put(@NotNull CompilerConfigurationKey<T> key, @NotNull T value) {
060 checkReadOnly();
061 map.put(key.ideaKey, value);
062 }
063
064 public <T> void add(@NotNull CompilerConfigurationKey<List<T>> key, @NotNull T value) {
065 checkReadOnly();
066 Key<List<T>> ideaKey = key.ideaKey;
067 if (map.get(ideaKey) == null) {
068 map.put(ideaKey, new ArrayList<T>());
069 }
070 List<T> list = (List<T>) map.get(ideaKey);
071 list.add(value);
072 }
073
074 public <T> void addAll(@NotNull CompilerConfigurationKey<List<T>> key, @NotNull Collection<T> values) {
075 checkReadOnly();
076 checkForNullElements(values);
077 Key<List<T>> ideaKey = key.ideaKey;
078 if (map.get(ideaKey) == null) {
079 map.put(ideaKey, new ArrayList<T>());
080 }
081 List<T> list = (List<T>) map.get(ideaKey);
082 list.addAll(values);
083 }
084
085 public CompilerConfiguration copy() {
086 CompilerConfiguration copy = new CompilerConfiguration();
087 copy.map.putAll(map);
088 return copy;
089 }
090
091 private void checkReadOnly() {
092 if (readOnly) {
093 throw new IllegalStateException("CompilerConfiguration is read-only");
094 }
095 }
096
097 public void setReadOnly(boolean readOnly) {
098 if (readOnly != this.readOnly) {
099 this.readOnly = readOnly;
100 }
101 }
102
103 public boolean isReadOnly() {
104 return readOnly;
105 }
106
107 @NotNull
108 private static <T> T unmodifiable(@NotNull T object) {
109 if (object instanceof List) {
110 return (T) Collections.unmodifiableList((List) object);
111 }
112 else if (object instanceof Map) {
113 return (T) Collections.unmodifiableMap((Map) object);
114 }
115 else if (object instanceof Collection) {
116 return (T) Collections.unmodifiableCollection((Collection) object);
117 }
118 else {
119 return object;
120 }
121 }
122
123 @Override
124 public String toString() {
125 return map.toString();
126 }
127
128 private static <T> void checkForNullElements(Collection<T> values) {
129 int index = 0;
130 for (T value : values) {
131 if (value == null) {
132 throw new IllegalArgumentException("Element " + index
133 + " is null, while null values in compiler configuration are not allowed");
134 }
135 index++;
136 }
137 }
138 }