/*
* Copyright 2000-2012 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.options.ex;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import consulo.ui.Component;
import consulo.ui.RequiredUIAccess;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
/**
* @author Dmitry Avdeev
* Date: 9/17/12
*/
public class ConfigurableWrapper implements SearchableConfigurable {
private static final ConfigurableWrapper[] EMPTY_ARRAY = new ConfigurableWrapper[0];
private static final NullableFunction<ConfigurableEP<Configurable>, Configurable> CONFIGURABLE_FUNCTION =
new NullableFunction<ConfigurableEP<Configurable>, Configurable>() {
@Override
public Configurable fun(ConfigurableEP<Configurable> ep) {
return wrapConfigurable(ep);
}
};
private static final Logger LOG = Logger.getInstance(ConfigurableWrapper.class);
@Nullable
@SuppressWarnings("unchecked")
public static <T extends UnnamedConfigurable> T wrapConfigurable(ConfigurableEP<T> ep) {
if (ep.displayName != null || ep.key != null) {
return (T)new CompositeWrapper(ep);
}
else {
return ep.createConfigurable();
}
}
public static <T extends UnnamedConfigurable> List<T> createConfigurables(ExtensionPointName<? extends ConfigurableEP<T>> name) {
return ContainerUtil.mapNotNull(Extensions.getExtensions(name), new NullableFunction<ConfigurableEP<T>, T>() {
@Override
public T fun(ConfigurableEP<T> ep) {
return wrapConfigurable(ep);
}
});
}
public static boolean isNoScroll(Configurable configurable) {
return cast(configurable, NoScroll.class) != null;
}
public static boolean isNoMargin(Configurable configurable) {
return cast(configurable, NoMargin.class) != null;
}
public static boolean hasOwnContent(Configurable configurable) {
Parent asParent = cast(configurable, Parent.class);
return asParent != null && asParent.hasOwnContent();
}
public static <T> T cast(Configurable configurable, Class<T> clazz) {
if (configurable == null) {
return null;
}
if (clazz.isInstance(configurable)) {
return clazz.cast(configurable);
}
if (configurable instanceof ConfigurableWrapper) {
UnnamedConfigurable unnamedConfigurable = ((ConfigurableWrapper)configurable).getConfigurable();
if (clazz.isInstance(unnamedConfigurable)) {
return clazz.cast(unnamedConfigurable);
}
}
return null;
}
public static boolean isNonDefaultProject(Configurable configurable) {
if (cast(configurable, NonDefaultProjectConfigurable.class) != null) {
return true;
}
return configurable instanceof ConfigurableWrapper && ((ConfigurableWrapper)configurable).myEp.nonDefaultProject;
}
private final ConfigurableEP myEp;
public ConfigurableWrapper(ConfigurableEP ep) {
myEp = ep;
}
private UnnamedConfigurable myConfigurable;
public UnnamedConfigurable getConfigurable() {
if (myConfigurable == null) {
myConfigurable = myEp.createConfigurable();
if (myConfigurable == null) {
LOG.error("Can't instantiate configurable for " + myEp);
}
}
return myConfigurable;
}
@Nls
@Override
public String getDisplayName() {
return myEp.getDisplayName();
}
@Nullable
@Override
public String getHelpTopic() {
UnnamedConfigurable configurable = getConfigurable();
return configurable instanceof Configurable ? ((Configurable)configurable).getHelpTopic() : null;
}
@Nullable
@Override
public JComponent createComponent() {
return getConfigurable().createComponent();
}
@RequiredUIAccess
@Nullable
@Override
public Component createUIComponent() {
return getConfigurable().createUIComponent();
}
@Override
public boolean isModified() {
return getConfigurable().isModified();
}
@Override
public void apply() throws ConfigurationException {
getConfigurable().apply();
}
@Override
public void reset() {
getConfigurable().reset();
}
@Override
public void disposeUIResources() {
getConfigurable().disposeUIResources();
}
@NotNull
@Override
public String getId() {
return myEp.id == null ? myEp.instanceClass : myEp.id;
}
public String getParentId() {
return myEp.parentId;
}
public ConfigurableWrapper addChild(Configurable configurable) {
return new CompositeWrapper(myEp, configurable);
}
@Override
public String toString() {
return getDisplayName();
}
@Nullable
@Override
public Runnable enableSearch(String option) {
final UnnamedConfigurable configurable = getConfigurable();
return configurable instanceof SearchableConfigurable ? ((SearchableConfigurable)configurable).enableSearch(option) : null;
}
private static class CompositeWrapper extends ConfigurableWrapper implements Configurable.Composite {
private Configurable[] myKids;
public CompositeWrapper(ConfigurableEP ep, Configurable... kids) {
super(ep);
if (ep.dynamic) {
kids = ((Composite)getConfigurable()).getConfigurables();
}
else if (ep.children != null) {
kids = ContainerUtil.mapNotNull(ep.getChildren(), new NullableFunction<ConfigurableEP, ConfigurableWrapper>() {
@Override
public ConfigurableWrapper fun(ConfigurableEP ep) {
return ep.isAvailable() ? (ConfigurableWrapper)wrapConfigurable(ep) : null;
}
}, EMPTY_ARRAY);
}
if (ep.childrenEPName != null) {
ExtensionPoint<Object> childrenEP = Extensions.getArea(ep.getProject()).getExtensionPoint(ep.childrenEPName);
Object[] extensions = childrenEP.getExtensions();
if (extensions.length > 0) {
if (extensions[0] instanceof ConfigurableEP) {
Configurable[] children = ContainerUtil.mapNotNull(((ConfigurableEP<Configurable>[])extensions), CONFIGURABLE_FUNCTION, new Configurable[0]);
kids = ArrayUtil.mergeArrays(kids, children);
}
else {
kids = ArrayUtil.mergeArrays(kids, ((Composite)getConfigurable()).getConfigurables());
}
}
}
myKids = kids;
}
@NotNull
@Override
public Configurable[] getConfigurables() {
return myKids;
}
@Override
public ConfigurableWrapper addChild(Configurable configurable) {
myKids = ArrayUtil.append(myKids, configurable);
return this;
}
}
}